Skip to content

fix(ai): ignore a repeat TOOL_CALL_START for an already-tracked toolCallId - #1197

Open
citizen204 wants to merge 3 commits into
TanStack:mainfrom
citizen204:fix-1187-tool-call-manager-repeat-start
Open

fix(ai): ignore a repeat TOOL_CALL_START for an already-tracked toolCallId#1197
citizen204 wants to merge 3 commits into
TanStack:mainfrom
citizen204:fix-1187-tool-call-manager-repeat-start

Conversation

@citizen204

@citizen204 citizen204 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

ToolCallManager.addToolCallStartEvent keyed its internal map by index (event.index ?? map.size), but AG-UI's TOOL_CALL_START carries no index. A non-first-party or malformed producer sending a second START for a toolCallId already being tracked could either wipe accumulated TOOL_CALL_ARGS (same index — overwrites the slot, resetting arguments to '') or insert a duplicate row (missing/different index — getToolCalls() then returns the id twice and the engine runs the tool twice). First-party adapters emit START only once per call and are unaffected.

Fixes #1187

Changes

  • packages/ai/src/activities/chat/tools/tool-calls.ts: addToolCallStartEvent now skips the event if a tool call with the same toolCallId is already tracked.
  • packages/ai/tests/tool-call-manager.test.ts: two regression tests — a repeat START with the same explicit index (accumulated arguments must survive) and a repeat START with no index (must not duplicate the row).
  • .changeset/tool-call-manager-repeat-start.md: patch changeset.

Ran vitest run tests/tool-call-manager.test.ts in packages/ai — 31 passed (29 existing + 2 new).

Summary by CodeRabbit

  • Bug Fixes

    • Prevented repeated tool-call start events from creating duplicate calls.
    • Preserved accumulated tool-call arguments when duplicate start events are received.
  • Tests

    • Added coverage for repeated tool-call events with and without an explicit index.

@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: eecbdd50-15dd-492d-a233-4a919dec2f9e

📥 Commits

Reviewing files that changed from the base of the PR and between 2eecfc8 and cf97e4a.

📒 Files selected for processing (1)
  • packages/ai/tests/tool-call-manager.test.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

ToolCallManager now ignores repeated TOOL_CALL_START events for tracked tool-call IDs. Regression tests verify argument preservation and prevention of duplicate calls. A patch changeset documents the fix.

Changes

Repeated tool-call start handling

Layer / File(s) Summary
Guard repeated starts and validate behavior
packages/ai/src/activities/chat/tools/tool-calls.ts, packages/ai/tests/tool-call-manager.test.ts, .changeset/tool-call-manager-repeat-start.md
addToolCallStartEvent ignores tracked tool-call IDs. Tests cover repeated starts with and without an index. The changeset documents the patch.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to cf97e

The change ignores duplicate tool-call start events while preserving accumulated arguments and preventing duplicate execution; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers: alemtuzlak, kolaworld

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the fix for repeated TOOL_CALL_START events on an already-tracked toolCallId.
Description check ✅ Passed The description explains the problem, implementation, tests, changeset, and issue link, but omits the template checklist and release impact sections.
Linked Issues check ✅ Passed The implementation skips repeated TOOL_CALL_START events and adds regression tests for argument loss and duplicate entries, satisfying issue #1187.
Out of Scope Changes check ✅ Passed The code, tests, and changeset are directly related to preventing repeated TOOL_CALL_START events from corrupting tool-call tracking.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2 files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the waiting-on: maintainer The ball is in the maintainers’ court label Aug 22, 2026
…allId

AG-UI's TOOL_CALL_START carries no index, and a non-first-party or
malformed producer can send a second START for a toolCallId that is
already being tracked by ToolCallManager. Without a guard:
- a repeat with the same index overwrites the slot, wiping any
  TOOL_CALL_ARGS already accumulated (arguments reset to '')
- a repeat with a missing/different index inserts a duplicate map row,
  so getToolCalls() returns the id twice and the engine runs the tool
  twice

Skip the repeat instead. First-party adapters emit START only once per
call, so this only changes behavior for custom/malformed streams.

Fixes TanStack#1187
@tombeckenham
tombeckenham force-pushed the fix-1187-tool-call-manager-repeat-start branch from 2eecfc8 to 8f93f0b Compare August 22, 2026 21:25
@nx-cloud

nx-cloud Bot commented Aug 22, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 8f93f0b


☁️ Nx Cloud last updated this comment at 2026-08-22 21:37:26 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on: maintainer The ball is in the maintainers’ court

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ToolCallManager can run the same tool call twice on a repeat TOOL_CALL_START

1 participant