Summary
When using deepseek/deepseek-v4-flash through the CommandCode Provider API, requests whose conversation ends with a tool result message (i.e. a tool-loop continuation) return 0 reasoning tokens — but only sometimes. Identical payloads flip between ~0 and ~20 reasoning tokens on consecutive calls, and the behavior is independent of the thinking parameter (also fails with thinking: {type: "enabled"}).
This is distinct from #697: that issue is about thinking: {type: "disabled"} being ignored (model reasons when you asked it not to). Our issue is the opposite — the model stops reasoning on tool-loop continuations even when thinking is explicitly enabled.
Repro
POST https://api.commandcode.ai/provider/v1/chat/completions, model deepseek/deepseek-v4-flash, with:
{
"model": "deepseek/deepseek-v4-flash",
"thinking": { "type": "enabled" },
"reasoning_effort": "high",
"max_tokens": 250,
"stream": false,
"messages": [
{ "role": "system", "content": "You are an agentic coding assistant. After a tool result comes back, continue by reasoning about it and then take the next action." },
{ "role": "user", "content": "What is the weather?" },
{ "role": "assistant", "content": "", "tool_calls": [{ "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{}" } }] },
{ "role": "tool", "tool_call_id": "call_1", "content": "{\"temp\":72,\"sunny\":true}" }
],
"tools": [{ "type": "function", "function": { "name": "get_weather", "description": "Get weather", "parameters": { "type": "object", "properties": {} } } }]
}
The last message is the tool result — no trailing user turn. This is the standard shape an agent harness sends to continue after a tool call.
Observed behavior
Run the same body twice, direct to the Provider API, and twice via an intermediate OpenAI-compatible proxy (byte-identical forwarding):
| Run |
Direct to Provider API |
Via proxy |
| 1 |
reasoning tokens: 0 |
reasoning tokens: 10 |
| 2 |
reasoning tokens: 19 |
reasoning tokens: 0 |
- Single-turn chat (no tools): reasons reliably (123 reasoning tokens).
- Tool-loop continuation (last msg = tool result): reasoning tokens flip between 0 and ~20 on identical payloads.
- Same result with
thinking: {type: "disabled"}, thinking: {type: "enabled"}, or no thinking key at all.
- Observed on
deepseek/deepseek-v4-flash, poolside/laguna-s-2.1-free (drops to 0), and heavily reduced on deepseek/deepseek-v4-pro and xiaomi/mimo-v2.5-pro. Control: same conversation shape via a different provider (Z.ai) reasons normally.
Expected behavior
Reasoning (or its absence) should be deterministic for a given request shape and controlled by the documented parameters — not flip randomly between calls on identical payloads.
Notes
- The nondeterminism is confirmed upstream: the same byte-identical payload behaves differently when sent direct vs. via a transparent proxy, and differently across identical repeat calls.
- We spent roughly five hours debugging this on our side (routers, proxies, client adapters) and burning API credits before isolating it to the Provider API's handling of tool-loop continuations — wanted to share the repro so others don't repeat that.
Related
Summary
When using
deepseek/deepseek-v4-flashthrough the CommandCode Provider API, requests whose conversation ends with a tool result message (i.e. a tool-loop continuation) return 0 reasoning tokens — but only sometimes. Identical payloads flip between ~0 and ~20 reasoning tokens on consecutive calls, and the behavior is independent of thethinkingparameter (also fails withthinking: {type: "enabled"}).This is distinct from #697: that issue is about
thinking: {type: "disabled"}being ignored (model reasons when you asked it not to). Our issue is the opposite — the model stops reasoning on tool-loop continuations even when thinking is explicitly enabled.Repro
POST https://api.commandcode.ai/provider/v1/chat/completions, modeldeepseek/deepseek-v4-flash, with:{ "model": "deepseek/deepseek-v4-flash", "thinking": { "type": "enabled" }, "reasoning_effort": "high", "max_tokens": 250, "stream": false, "messages": [ { "role": "system", "content": "You are an agentic coding assistant. After a tool result comes back, continue by reasoning about it and then take the next action." }, { "role": "user", "content": "What is the weather?" }, { "role": "assistant", "content": "", "tool_calls": [{ "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{}" } }] }, { "role": "tool", "tool_call_id": "call_1", "content": "{\"temp\":72,\"sunny\":true}" } ], "tools": [{ "type": "function", "function": { "name": "get_weather", "description": "Get weather", "parameters": { "type": "object", "properties": {} } } }] }The last message is the tool result — no trailing user turn. This is the standard shape an agent harness sends to continue after a tool call.
Observed behavior
Run the same body twice, direct to the Provider API, and twice via an intermediate OpenAI-compatible proxy (byte-identical forwarding):
thinking: {type: "disabled"},thinking: {type: "enabled"}, or nothinkingkey at all.deepseek/deepseek-v4-flash,poolside/laguna-s-2.1-free(drops to 0), and heavily reduced ondeepseek/deepseek-v4-proandxiaomi/mimo-v2.5-pro. Control: same conversation shape via a different provider (Z.ai) reasons normally.Expected behavior
Reasoning (or its absence) should be deterministic for a given request shape and controlled by the documented parameters — not flip randomly between calls on identical payloads.
Notes
Related