anomalyco / anomalyco/opencode
opencode-go kimi-k3 intermittently emits raw <|...|> chat-template delimiters and pathological parallel tool-call bursts
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
Environment
- opencode build: 0.0.0-dev-202608271917 (and later dev builds) (own fork with own bug fixes and features, however, the issue is not in the opencode client, but upstream in the servers hosting the Kimi K3 model)
- model: kimi-k3, provider: opencode-go
- runtime: ai-sdk, llm.runtime=ai-sdk
- observed over long autonomous "build" runs (multiple hours), context kept small via compaction (~17k–200k tokens)
Summary
On long-running sessions, kimi-k3 (served through opencode-go) periodically produces malformed responses in two ways that both look like the model "glitching," and both seem to stem from the model's thinking→answer→tool-call structure markers being mishandled.
Symptom 1 — raw template delimiters leak into visible output, then the stream truncates
Reasoning parts intermittently end with literal delimiter tokens instead of a real answer or tool call, e.g.:
reasoning| ... via images:<|close|>response<|sep|><|open|>tools<|sep|><|open|>call t…
<|close|>, <|open|>, <|sep|>, plus the response / tools / call markers, appear to be the model's internal separators for thinking → response → tool-call. They leak as raw text and the stream dies mid-token (cut off at call t…). Result: a turn that ends finish="stop" with reasoning but no answer and no tool call — to the client it looks like "the model thought and then just stopped." We've also captured turns that are literally finish="stop", tokens.output=0, tokens.reasoning in the thousands (pure thinking, zero output).
Symptom 2 — pathological burst of identical parallel tool calls
In one assistant message the model emitted 100 identical tool calls (tessera_get_session_id), and in the next message 97 more — same tool, empty input, all in parallel (callID values like tessera_get_session_id_93, _94, …). A total of ~193 calls landed in a ~2-minute window. The model then reportedly self-detected ("I'm doing this 100 times") but relapsed into another burst. One such message carried 100 tool parts; the next 97.
Why this matters
- Symptom 1 makes long runs silently lose turns (the model appears to halt after thinking).
- Symptom 2 burns a large number of tokens/context per message and forces the user to add client-side loop detection to survive autonomous runs.
Suspected root cause
Both symptoms are consistent with opencode-go's kimi-k3 adapter (or the upstream served template) not consuming/parsing the model's <|open|>/<|close|>/<|sep|> structured-output delimiters correctly — the tokens leak into the text stream and the generation terminates abnormally (empty finish → "unknown"/"stop", or runaway repeated tool calls).
Requested
- Confirm whether kimi-k3 over opencode-go is expected to emit these delimiters, and whether the served chat template should be stripping them.
- Any known fix/workaround (template version, model revision, stop-token config) for kimi-k3 structured output.
Plugins
No response
OpenCode version
not about the opencode software version, it's about your servers
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The report names no repository file, test, or entry point and attributes the behavior to opencode-go servers hosting kimi-k3 rather than the client. Start by determining whether the adapter or served chat template owns delimiter parsing, using the captured raw delimiters and repeated tool-call messages. Done means confirming ownership and documenting a verified fix or workaround.
Written by the indexing model from the issue text.
Assessment
- Domain
- ai
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100