Skip to content

fix(provider): replay reasoning_content on thinking-enabled gateway tool calls - #7763

Open
innocarpe wants to merge 1 commit into
esengine:main-v2from
innocarpe:contrib/r11-reasoning-400
Open

fix(provider): replay reasoning_content on thinking-enabled gateway tool calls#7763
innocarpe wants to merge 1 commit into
esengine:main-v2from
innocarpe:contrib/r11-reasoning-400

Conversation

@innocarpe

Copy link
Copy Markdown
Contributor

Summary

Fix #7748 (and duplicates #7520/#7648/#7564/#7396): an OpenAI-compatible gateway opted into DeepSeek-style thinking via the thinking=enabled escape hatch (e.g. opencode.ai zen serving DeepSeek models) never replayed reasoning_content on assistant tool_calls turns, so the DeepSeek-flavored upstream 400'd every turn after the first tool call ("The reasoning_content in the thinking mode must be passed back to the API").

Changes in internal/provider/openai/:

  • RequiresToolCallReasoning() now also returns true for generic gateways with thinking=enabled (GLM/Kimi K3 keep their own round-trip policy; thinking=disabled still opts out)
  • buildRequest tool_calls-turn case widened from c.deepseek to (c.deepseek || c.RequiresToolCallReasoning()) — always emits the reasoning_content key (empty included) on tool_calls turns; plain assistant turns still omit it
  • Regression test pins the wire shape: empty-key emission, captured-reasoning replay, and no replay on plain assistant turns

Byte-identical for every existing path (DeepSeek official, thinking off, GLM, Kimi K3); the only new wire output is the generic-gateway + thinking=enabled case.

Issues

Fixes #7748 (Refs #7520 #7648 #7564 #7396)

Verification

  • go test ./internal/provider/... — pass (4 packages)
  • New test: TestBuildRequestThinkingEnabledGatewayRoundTripsToolCallReasoning
  • go vet — clean

Documentation impact

Documentation-impact: none - wire behavior for an opt-in escape hatch; no docs affected.

Cache impact

Cache-impact: medium - internal/provider/* is a listed cache-sensitive path; the change alters request serialization for the thinking=enabled-on-generic-gateway configuration only (byte-identical for all existing configs), so prompt-cache prefixes are unchanged for existing setups.
Cache-guard: go test ./internal/provider/openai/ full suite passes (incl. the existing reasoning-serialization pins); no cache-guard script change needed for an opt-in path.
System-prompt-review: N/A

@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development provider Model providers & selection (internal/provider) labels Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

provider Model providers & selection (internal/provider) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: error: Malformed request (HTTP 400): the request body was rejected. The reasoning_content in the thinking mode must be passed back to the API.

1 participant