You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Intermittent pseudo [tool_call: ...] narration emitted as text before real tool event #18074
opencode serve intermittently emits a plain text narration that looks like a tool call before it emits the real structured tool event.
In the affected turns, the stream first contains text like:
I'll gather the requested information about the working directory and git branches.
[tool_call: bash for 'pwd && git branch' because I need to identify the absolute path and list all local branches]
Then, shortly afterwards, opencode serve emits the actual structured tool part for the same bash command.
This is not deterministic. The same workflow sometimes behaves correctly and emits the real tool event without the extra pseudo [tool_call: ...] narration.
Environment
provider/model: google/gemini-3.1-pro-preview
launched with opencode serve
Why this looks like an opencode serve issue
We verified the downstream consumer logs.
For the affected turn, the downstream bridge received two different upstream events:
a text part containing the pseudo tool-call narration
a later tool part for the real bash invocation
The downstream bridge classified them correctly:
the narration stayed text
the real tool invocation became tool_call
So this does not look like a downstream rendering/classification bug. It looks like opencode serve itself is sometimes streaming an extra natural-language tool narration before the real structured tool event.
Actual Behavior
For one turn, the stream looks like this:
text narration about gathering the requested information
plain text pseudo marker: [tool_call: bash for 'pwd && git branch' because ...]
real structured bash tool event
final normal text answer
This creates duplicated and confusing output for clients, because users see both:
a fake textual tool-call marker
the real tool call event
Expected Behavior
If a tool call is going to happen, opencode serve should emit only the structured tool event, not a pseudo [tool_call: ...] marker inside normal text.
Minimal Reproduction Pattern
This happens intermittently when asking for information that requires a bash tool call, for example:
current working directory
current git branch
local branch list
A representative command is:
pwd&& git branch
Evidence
From downstream logs, the affected turn clearly shows:
first: message.part.delta / message.part.updated for a text part containing the pseudo [tool_call: ...] narration
later: a separate message.part.updated with part.type=tool for the actual bash execution
So the extra narration is already present in the opencode serve stream output.
This issue might be a duplicate of an existing issue. Please check:
fix(provider): Copilot Gemini models fail to produce structured tool calls #15315: Copilot Gemini models fail to produce structured tool calls — describes the same symptom where Gemini models emit plain-text [tool_call: ...] narration instead of structured tool call events. The root cause identified there is that sanitizeGemini schema transforms are incorrectly applied to Copilot-proxied Gemini models, but a similar schema transform issue may also affect google/gemini-3.1-pro-preview via opencode serve.
If your issue is distinct (e.g. it occurs with the native Google provider rather than GitHub Copilot, or you've confirmed the schema transforms are not involved), please clarify and this note can be removed.
Thanks. This looks related to #15315, but based on our logs it does not appear to be the same failure mode.
What we observed on our side:
provider: google
reproduced model in the captured logs: gemini-3-flash-preview
this is intermittent, not deterministic
The important difference is that in our case OpenCode does eventually emit the real structured tool part.
From the captured stream:
OpenCode first emits a text part containing a pseudo narration like:
I'll gather the requested information about the working directory and git branches.
[tool_call: bash for 'pwd && git branch' because I need to identify the absolute path and list all local branches]
Later in the same turn, OpenCode emits a real tool part for the bash call.
So the behavior we are seeing is:
extra plain-text pseudo tool-call narration first
real structured tool event afterwards
That is why we suspect this issue is related to Gemini tool-calling / transform logic, but not necessarily a duplicate of #15315, which describes a case where structured tool calls are not produced.
If helpful, we can provide a sanitized event sequence showing:
message.part.updated with part.type=text
later message.part.updated with part.type=tool
So at this point the strongest statement we can make is:
One clarification in case it helps narrow the symptom:
In the affected turns, we are not only seeing text that contains a pseudo [tool_call: ...] marker.
We also do see a real structured tool call afterwards in the same turn.
So the observed sequence is specifically:
a text part whose content includes [tool_call: ...]
then an actual structured tool part is emitted and the tool call really happens
So this is not just "tool call collapsed into text".
It is "textual pseudo tool-call narration appears first, while the real tool call still happens afterwards".
Activity
github-actions commentedon Mar 18, 2026
This issue might be a duplicate of an existing issue. Please check:
[tool_call: ...]narration instead of structured tool call events. The root cause identified there is thatsanitizeGeminischema transforms are incorrectly applied to Copilot-proxied Gemini models, but a similar schema transform issue may also affectgoogle/gemini-3.1-pro-previewviaopencode serve.If your issue is distinct (e.g. it occurs with the native Google provider rather than GitHub Copilot, or you've confirmed the schema transforms are not involved), please clarify and this note can be removed.
liujuanjuan1984 commentedon Mar 18, 2026
Thanks. This looks related to #15315, but based on our logs it does not appear to be the same failure mode.
What we observed on our side:
googlegemini-3-flash-previewThe important difference is that in our case OpenCode does eventually emit the real structured tool part.
From the captured stream:
textpart containing a pseudo narration like:toolpart for thebashcall.So the behavior we are seeing is:
That is why we suspect this issue is related to Gemini tool-calling / transform logic, but not necessarily a duplicate of #15315, which describes a case where structured tool calls are not produced.
If helpful, we can provide a sanitized event sequence showing:
message.part.updatedwithpart.type=textmessage.part.updatedwithpart.type=toolSo at this point the strongest statement we can make is:
liujuanjuan1984 commentedon Mar 18, 2026
One clarification in case it helps narrow the symptom:
In the affected turns, we are not only seeing text that contains a pseudo
[tool_call: ...]marker.We also do see a real structured tool call afterwards in the same turn.
So the observed sequence is specifically:
textpart whose content includes[tool_call: ...]toolpart is emitted and the tool call really happensSo this is not just "tool call collapsed into text".
It is "textual pseudo tool-call narration appears first, while the real tool call still happens afterwards".
github-actions commentedon Jul 3, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.