Skip to content

fix(adk): preserve streamed tool call order in Anthropic responses - #3301

Open
halcyon-r wants to merge 1 commit into
kagent-dev:mainfrom
halcyon-r:fix/anthropic-stream-tool-call-order
Open

halcyon-r wants to merge 1 commit into
kagent-dev:mainfrom
halcyon-r:fix/anthropic-stream-tool-call-order

Conversation

@halcyon-r

Copy link
Copy Markdown

runAnthropicStreaming collects tool_use blocks in a map keyed by
content-block index and assembles the final response by ranging over the map,
so when one streamed response carries multiple parallel tool calls, the
resulting parts — and the FunctionCalls the agent loop executes — come out in
randomized order instead of the order the provider emitted them. Same class of
bug as #2988, which fixed randomized map iteration for Ollama argument order.

Tool results are matched by call ID, so nothing mispairs. The nondeterminism
shows up everywhere the parts travel: session history and replay, traces and UI
rendering, and any serial runner that executes the calls in part order. The
non-streaming path iterates message.Content in order, so streaming and
non-streaming disagreed for the same response shape.

  • Assemble the final response by iterating the collected indices in sorted
    order (slices.Sorted(maps.Keys(...))), matching the non-streaming path.
  • Collection and delta handling are unchanged; the text-before-tool-call part
    layout is unchanged.

Testing: TestAnthropicStreamingKeepsParallelToolCallOrder streams one text
block plus three tool calls (including one with no input deltas) and asserts
part order. It fails without the fix and loops 20× because map iteration order
is randomized and a single run can pass by chance. go test ./adk/pkg/models/
(run from go/) passes and go vet is clean.

@github-actions github-actions Bot added the bug Something isn't working label Oct 21, 2026
@halcyon-r

Copy link
Copy Markdown
Author

Hi @supreme-gg-gg @dimetron, could you take a look at this PR when you get a chance? It's a related fix to #3289 in the same Anthropic adapter, so it may be easier to review them together. The CI workflows are also waiting for maintainer approval to run. Thanks!

@github-actions

Copy link
Copy Markdown

This pull request has been marked as stale because of no activity in the last 15 days. It will be closed in the next 5 days unless it is tagged "no stalebot" or other activity occurs.

@github-actions github-actions Bot added the stale This issue or PR has become stale label Nov 10, 2026
runAnthropicStreaming collected tool_use blocks in a map keyed by content-block index and assembled the final response by ranging over the map, so multiple parallel tool calls in one streamed response were emitted in randomized order. Iterate the indices in sorted order instead, matching the non-streaming path and the order the provider emitted the blocks.

Signed-off-by: hairuiyang <hairuiyang@deeproute.ai>
@halcyon-r
halcyon-r force-pushed the fix/anthropic-stream-tool-call-order branch from f940e0c to 48d76b4 Compare November 10, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working stale This issue or PR has become stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant