Repository navigation
Description
Description
The Zen Go OpenAI-compatible endpoint (https://opencode.ai/zen/go/v1/chat/completions) strips usage.completion_tokens_details.reasoning_tokens from responses for deepseek-v4-flash, while the official DeepSeek API (https://api.deepseek.com/chat/completions) reports it for the same model id, same prompt, same request shape.
The thinking text itself is forwarded (choices[0].message.reasoning_content is populated), so the model clearly engages reasoning through the gateway — only the token accounting for it disappears. Two additional DeepSeek-native usage fields (prompt_cache_hit_tokens, prompt_cache_miss_tokens) are likewise absent, and usage. prompt_tokens_details arrives hollowed ({} even when populated upstream).
This is a provider-specific gap in the gateway's normalization layer rather than a model-behavior difference: on this exact endpoint/harness/prompt combination, a kimi-k2.6 request returns a fully-populated details block minutes apart from a deepseek-v4-flash request that returns none.
Expected Behavior
Per the official DeepSeek API docs, the response usage should include:
"usage": {
"completion_tokens": 0,
"prompt_tokens": 0,
"prompt_cache_hit_tokens": 0,
"prompt_cache_miss_tokens": 0,
"total_tokens": 0,
"completion_tokens_details": {
"reasoning_tokens": 0
}and per the OpenAI chat-completions convention that Zen's own normalization code follows (see PR #24441), completion_tokens_details.reasoning_tokens is part of the standard
usage shape the gateway is expected to forward.
Actual Behavior
"usage": {
"prompt_tokens": 124,
"completion_tokens": 198,
"total_tokens": 322,
"prompt_tokens_details": {}
}usage.completion_tokens_detailsis absent entirely on every Zen Go response fordeepseek-v4-flash(12+ attempts over two days, at different hours, trivial and reasoning-
forcing prompts), whilemessage.reasoning_contentis delivered.usage.prompt_tokens_detailsarrives as{}(hollowed) instead of the populated shape the official API sends.prompt_cache_hit_tokens/prompt_cache_miss_tokensare dropped, masking whether DeepSeek prefix caching engaged per request.- The same harness seconds apart returns a fully-populated details block for
kimi-k2.6— so the gateway is capable of forwarding it; the gap is specific to the DeepSeek path.
Plugins
No response
OpenCode version
1.18.23
Steps to reproduce
The strip is deterministic across 12+ requests spanning two days, trivial and forcing
prompts, stream=false, at different hours.
- Send the identical request body to both endpoints (fixed combinatorial prompt that forces reasoning):
FIXED='Solve step by step internally, then respond ONLY with valid JSON {"count": <int>}. How many distinct arrangements of the letters in "MISSISSIPPI" have no two S characters adjacent?'
BODY='{"model":"deepseek-v4-flash","messages":[{"role":"user","content":"'"$FIXED"'"}],"max_tokens":8000,"response_format":{"type":"json_object"},"stream":false}'
# Zen Go — completion_tokens_details MISSING
curl -s https://opencode.ai/zen/go/v1/chat/completions \
-H "Authorization: Bearer $OPENCODE_GO_API_KEY" \
-H "Content-Type: application/json" -d "$BODY" | jq '.usage'
# Official DeepSeek — completion_tokens_details.reasoning_tokens present
curl -s https://api.deepseek.com/chat/completions \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
-H "Content-Type: application/json" -d "$BODY" | jq '.usage'- Zen Go result (capture F1, cf-ray
a31b27150f0aa330-SEA,2026-08-27 12:41:52 GMT):
{"prompt_tokens": 124, "completion_tokens": 198, "total_tokens": 322,
"prompt_tokens_details": {}}choices[0].message.reasoning_content is populated (~500 chars of thinking) — the model reasoned; only the accounting vanished.
- Official result minutes later (capture D2,
2026-08-27 11:33:14 GMT), same model id + prompt:
{"prompt_tokens": 144, "completion_tokens": 221, "total_tokens": 365,
"prompt_tokens_details": {"cached_tokens": 0},
"completion_tokens_details": {"reasoning_tokens": 214},
"prompt_cache_hit_tokens": 0, "prompt_cache_miss_tokens": 144}- Positive control through the same gateway, same harness/prompt, minutes apart (capture F2, cf-ray
a31b2b91ef3390db-SEA,2026-08-27 12:45:43 GMT) —kimi-k2.6returns
the full OpenAI details shape:
"prompt_tokens_details": {"audio_tokens": 0, "cached_tokens": 47, "cache_write_tokens": 0},
"completion_tokens_details": {"audio_tokens": 0, "reasoning_tokens": 1757}Captures were made with plain httpx/curl POSTs (no SDK, no OpenCode client parsing) — this rules out client-side field stripping
Screenshot and/or share link
No response
Operating System
macOS 14.5.0, arm64
Terminal
Ghostty
Activity
github-actions commentedon Aug 27, 2026
This issue might be a duplicate of existing issues. Please check:
prompt_cache_hit_tokens/prompt_cache_miss_tokensfields in the Zen Go endpoint responses for DeepSeek models — overlaps with the dropped usage fields described here.If your issue is specifically about the
completion_tokens_details.reasoning_tokensbeing stripped (rather than caching behavior), it may still be a distinct problem worth tracking separately.[-]Zen Go /v1/chat/completions strips usage.completion_tokens_details for deepseek-v4-flash - official DeepSeek API sends it[/-][+][Bug] Zen Go /v1/chat/completions strips usage.completion_tokens_details for deepseek-v4-flash - official DeepSeek API sends it[/+]shashwatx commentedon Aug 28, 2026
Thanks for the triaging.
The issues highlighted in the comment above are related but different.
prompt_cache_hit_tokens/prompt_cache_miss_tokens) on this endpoint — which I also observe (that's the hollowedprompt_tokens_details: {}in my captures).usage.completion_tokens_details.reasoning_tokensbeing stripped — same gateway, different field; neither thread tracks it.One data point that may help triage all three: a positive control through the same endpoint, harness, and fixed prompt shows the gateway does forward the complete
completion_tokens_details+ a populatedprompt_tokens_detailsforkimi-k2.6(reasoning_tokens: 1757), minutes apart from adeepseek-v4-flashresponse where the block is absent entirely. So this looks like a per-provider gap in the gateway's usage normalization (cf. theoaCompatHelper.normalizeUsagesurface in #24441) rather than a gateway-wide or model-behavior issue — plausibly one root cause feeding all three threads.thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊