Skip to content

fix: prevent duplicate tool results on provider disconnect/fallback#42

Open
alfep wants to merge 1 commit into
freecodexyz:mainfrom
alfep:fix-duplicate-tool-results
Open

fix: prevent duplicate tool results on provider disconnect/fallback#42
alfep wants to merge 1 commit into
freecodexyz:mainfrom
alfep:fix-duplicate-tool-results

Conversation

@alfep

@alfep alfep commented Jul 4, 2026

Copy link
Copy Markdown

Summary

This PR fixes duplicate tool results when provider disconnects mid-response and reconnects, addressing issues #37 and #38.

Changes

  • Add deduplication check in StreamingToolExecutor.addTool() to prevent duplicate tool additions when provider reconnects and resends tool_use blocks
  • Add deduplication in yieldMissingToolResultBlocks() to prevent duplicate tool_result blocks during model fallback recovery

Test plan

Fixes #37, Fixes #38

- Add deduplication check in StreamingToolExecutor.addTool() to prevent
  duplicate tool additions when provider reconnects and resends tool_use blocks
- Add deduplication in yieldMissingToolResultBlocks() to prevent duplicate
  tool_result blocks during model fallback recovery

Fixes freecodexyz#37 and freecodexyz#38
Copilot AI review requested due to automatic review settings July 4, 2026 08:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets a reliability issue in the tool execution/recovery pipeline: when a provider disconnects/reconnects (or fallback/retry paths run), the same tool_use_id can be observed more than once, leading to duplicate tool executions and/or duplicate tool_result emission.

Changes:

  • Add an ID-based dedupe guard in StreamingToolExecutor.addTool() to avoid re-queueing a tool when the same tool_use block is replayed.
  • Add deduplication in yieldMissingToolResultBlocks() to reduce duplicate “missing tool_result” emission during recovery paths.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/services/tools/StreamingToolExecutor.ts Skips adding a tool if a tracked tool with the same tool_use_id already exists.
src/query.ts Attempts to dedupe tool-use blocks before emitting synthetic/missing tool_result blocks during fallback/error recovery.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/query.ts
Comment on lines +139 to 143
for (const assistantMessage of uniqueAssistantMessages) {
// Extract all tool use blocks from this assistant message
const toolUseBlocks = assistantMessage.message.content.filter(
content => content.type === 'tool_use',
) as ToolUseBlock[]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Free Code resubmits a tool result after a post-tool provider disconnect [BUG] free-code repeats completed shell tool results

2 participants