@@ -504,6 +504,9 @@ function scanForToolErrors(logContent) {
504504 * @returns {Map<string, string> } Map from tool_call_id to tool output content string
505505 */
506506function extractWireRequestToolResults ( lines ) {
507+ // Maximum number of lines to look ahead within a tool entry for tool_call_id / content
508+ const MAX_TOOL_RESULT_SCAN_LINES = 5 ;
509+
507510 const toolResultMap = new Map ( ) ;
508511 let inWireBlock = false ;
509512
@@ -529,15 +532,27 @@ function extractWireRequestToolResults(lines) {
529532 let contentValue = null ;
530533
531534 // The next few lines contain tool_call_id and content in order
532- for ( let j = i + 1 ; j < Math . min ( i + 5 , lines . length ) ; j ++ ) {
535+ for ( let j = i + 1 ; j < Math . min ( i + MAX_TOOL_RESULT_SCAN_LINES , lines . length ) ; j ++ ) {
533536 const nextLine = lines [ j ] ;
534537
535538 // Stop if we hit a timestamp line (end of wire block)
536539 if ( / ^ \d { 4 } - \d { 2 } - \d { 2 } T [ \d : . ] + Z / . test ( nextLine ) ) break ;
537540
538541 if ( toolCallId === null ) {
539- const idMatch = nextLine . match ( / " t o o l _ c a l l _ i d " : \s * " ( [ ^ " \\ ] * ) " / ) ;
540- if ( idMatch ) toolCallId = idMatch [ 1 ] ;
542+ const toolCallIdIdx = nextLine . indexOf ( '"tool_call_id":' ) ;
543+ if ( toolCallIdIdx >= 0 ) {
544+ // Use JSON.parse to correctly handle any escape sequences in the ID value
545+ const rest = nextLine
546+ . slice ( toolCallIdIdx + '"tool_call_id":' . length )
547+ . trim ( )
548+ . replace ( / , \s * $ / , "" ) ;
549+ try {
550+ const parsed = JSON . parse ( rest ) ;
551+ if ( typeof parsed === "string" ) toolCallId = parsed ;
552+ } catch ( e ) {
553+ // Skip unparseable ID
554+ }
555+ }
541556 }
542557
543558 if ( contentValue === null ) {
0 commit comments