fix(agent-core-v2): make Gemini tool call ids unique across turns#1730
Conversation
🦋 Changeset detectedLatest commit: e1b7a39 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 00066c7445
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // stay unique across the whole session. | ||
| const id_ = (fc['id'] as string) ?? crypto.randomUUID(); | ||
| const toolCallId = `${name}_${id_}`; | ||
| const toolCallId = `${name}_${id_}_${crypto.randomUUID().replaceAll('-', '').slice(0, 8)}`; |
There was a problem hiding this comment.
Preserve the fallback tool-name parser
When the preceding assistant tool call has been compacted away and a standalone tool result reaches messagesToGoogleGenAIContents, toolCallIdToName is the only thing that recovers the Gemini functionResponse.name. This new ${name}_${upstreamId}_${rand} shape is no longer parseable by that fallback because it strips only the final suffix, so an id like AgentSwarm_0_ab12cd34 is sent back as function name AgentSwarm_0 instead of AgentSwarm; please update the encoding/parser together with this id-shape change, including the mirrored kosong provider.
Useful? React with 👍 / 👎.
| const fc = (p['functionCall'] ?? p['function_call']) as Record<string, unknown>; | ||
| const name = fc['name'] as string; | ||
| if (!name) continue; | ||
| // The upstream function-call id is only unique within its own |
There was a problem hiding this comment.
Move this note out of the v2 implementation body
packages/agent-core-v2/AGENTS.md requires comments to live only in the top-of-file /** */ block and says never to place them beside functions, methods, or statements. This newly added inline implementation note violates that package rule; please remove it or fold the necessary responsibility-level context into the file header.
Useful? React with 👍 / 👎.
The orphan tool-message fallback in toolCallIdToName stripped only one
trailing "_<suffix>" segment, so with the new
"{tool_name}_{upstream_id}_{entropy}" id shape it returned
"AgentSwarm_0" instead of "AgentSwarm" once the preceding assistant
call had been compacted away. Strip the fixed 8-hex entropy suffix
first, then the upstream id segment, in both the kosong and
agent-core-v2 providers. Also drop the inline implementation comment
that agent-core-v2 forbids outside the file header.
Related Issue
No issue — found while investigating a duplicated swarm card in the web UI.
Problem
When a Gemini-protocol backend issues small per-response function-call ids (e.g.
0), the provider synthesized tool call ids as${name}_${id}. The sequence restarts every turn, so two AgentSwarm calls in different turns both becameAgentSwarm_0. Tool call ids are the key for tool rows and swarm-member grouping in the web client, so the second card rendered both generations of members — 10 completed + 10 running,10 / 20instead of10 / 10(reproduced from a real session's event journal: 20subagent.spawnedevents across two turns, all withparentToolCallId: "AgentSwarm_0").What changed
google-genai.ts(both the agent-core-v2 and kosong copies): append an 8-hex-char entropy suffix to the synthesized id (${name}_${upstreamId}_${rand}), keeping the upstream id for readability while making ids unique across the whole session. The upstream id was never round-tripped (outbound function calls serialize only the name), so this is behavior-preserving otherwise.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.