@@ -357,33 +357,51 @@ export class ClaudeRepository implements ILlmGateway {
357357 while ( messages . length > 0 && messages [ messages . length - 1 ] . role === "assistant" ) {
358358 messages . pop ( )
359359 }
360- // Index tool_results by tool_use_id for lookup
360+
361+ // Pre-scan: collect all tool_use IDs that exist in assistant messages
362+ const knownToolUseIds = new Set < string > ( )
363+ for ( const msg of messages ) {
364+ if ( msg . role === "assistant" && Array . isArray ( msg . content ) ) {
365+ for ( const block of msg . content as Array < { type : string } > ) {
366+ if ( block . type === "tool_use" ) {
367+ knownToolUseIds . add ( ( block as Anthropic . ToolUseBlock ) . id )
368+ }
369+ }
370+ }
371+ }
372+
373+ // Index tool_results by tool_use_id for lookup (only those with a matching tool_use)
361374 const resultIndex = new Map < string , Anthropic . ToolResultBlockParam > ( )
362375 for ( const msg of messages ) {
363376 if ( msg . role === "user" && Array . isArray ( msg . content ) ) {
364377 for ( const block of msg . content as Array < { type : string } > ) {
365378 if ( block . type === "tool_result" ) {
366379 const b = block as Anthropic . ToolResultBlockParam
367- resultIndex . set ( b . tool_use_id , b )
380+ if ( knownToolUseIds . has ( b . tool_use_id ) ) {
381+ resultIndex . set ( b . tool_use_id , b )
382+ }
368383 }
369384 }
370385 }
371386 }
372387
373- // Track which tool_use_ids have been placed
388+ // Track which tool_use_ids have been placed as results
374389 const placed = new Set < string > ( )
375390 const result : Anthropic . MessageParam [ ] = [ ]
376391
377392 for ( const msg of messages ) {
378- // Skip user messages that are purely orphan tool_results
393+ // Filter user messages: remove tool_results that are orphans or already placed
379394 if ( msg . role === "user" && Array . isArray ( msg . content ) ) {
380- const nonOrphan = ( msg . content as Array < { type : string } > ) . filter ( b => {
395+ const filtered = ( msg . content as Array < { type : string } > ) . filter ( b => {
381396 if ( b . type !== "tool_result" ) return true
382397 const id = ( b as Anthropic . ToolResultBlockParam ) . tool_use_id
383- return ! placed . has ( id ) // keep only if not already placed
398+ // Drop if no matching tool_use exists, or if already placed inline
399+ if ( ! knownToolUseIds . has ( id ) ) return false
400+ if ( placed . has ( id ) ) return false
401+ return true
384402 } )
385- if ( nonOrphan . length === 0 ) continue
386- result . push ( { role : "user" , content : nonOrphan as Anthropic . ContentBlockParam [ ] } )
403+ if ( filtered . length === 0 ) continue
404+ result . push ( { role : "user" , content : filtered as Anthropic . ContentBlockParam [ ] } )
387405 continue
388406 }
389407
0 commit comments