Skip to content

fix(run_agent): gate reasoning_content re-feed to DeepSeek/Kimi only - #18446

Closed
leon7609 wants to merge 1 commit into
NousResearch:mainfrom
leon7609:fix/run-agent-reasoning-refeed-gate
Closed

fix(run_agent): gate reasoning_content re-feed to DeepSeek/Kimi only#18446
leon7609 wants to merge 1 commit into
NousResearch:mainfrom
leon7609:fix/run-agent-reasoning-refeed-gate

Conversation

@leon7609

@leon7609 leon7609 commented May 1, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Gates step 3 of _copy_reasoning_content_for_api to providers that actually need the reasoningreasoning_content promotion (DeepSeek / Kimi).

Today step 3 promotes msg["reasoning"] to api_msg["reasoning_content"] for any assistant message that carries reasoning text in the unified reasoning field — regardless of provider. This is harmful for at least two cases:

  • Qwen on vLLM (and any compatible custom provider): Qwen's official multi-turn spec explicitly forbids re-feeding reasoning_content from prior turns. In practice this causes (a) context balloon across turns and (b) thinking-mode death loops where the model re-thinks its own prior reasoning back at itself. It's the dominant failure mode on long Qwen-on-vLLM sessions.
  • OpenRouter / Anthropic / OpenAI: these carry reasoning continuity via the separate reasoning_details field (unaffected by this helper). They never relied on step 3's promotion path; dropping it for them is a no-op.

The fix is a one-condition addition: gate step 3 on needs_thinking_pad (already computed at line 8782 via _needs_thinking_reasoning_pad()). DeepSeek / Kimi keep their existing behaviour because they're true under that flag; everyone else falls through to step 5 and has reasoning_content popped from the API replay message.

Related Issue

No existing issue. Diagnosed from a Qwen3.6-27B-FP8 vLLM session that exhibited progressive context inflation and thinking loops; tracing showed the prior turn's <think> text was being re-fed via reasoning_content.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • run_agent.py_copy_reasoning_content_for_api, step 3:
    - if isinstance(normalized_reasoning, str) and normalized_reasoning:
    + if needs_thinking_pad and isinstance(normalized_reasoning, str) and normalized_reasoning:
          api_msg["reasoning_content"] = normalized_reasoning
          return
    Plus a comment block above it documenting the rationale.
  • tests/run_agent/test_reasoning_content_provider_gate.py — 6 new unit tests:
    • Qwen vLLM: reasoning is not promoted.
    • OpenRouter / MiniMax: same.
    • DeepSeek: regression check — reasoning is still promoted.
    • Kimi (Moonshot): regression check — same.
    • Step 1 (explicit reasoning_content) is unaffected by the gate.

The existing tests in tests/run_agent/test_deepseek_reasoning_content_echo.py continue to pass — DeepSeek/Kimi paths are unchanged.

How to Test

  1. Run a multi-turn conversation against a Qwen-on-vLLM endpoint with thinking enabled.
  2. Before this fix: observe the prior turn's reasoning_content re-appearing in the next request payload; on long sessions you'll see context inflate and the model re-reasoning over its own thoughts.
  3. After this fix: reasoning_content is only present on DeepSeek/Kimi turns; Qwen multi-turn behaviour matches the upstream Qwen spec.

Or run the unit tests:

pytest tests/run_agent/test_reasoning_content_provider_gate.py tests/run_agent/test_deepseek_reasoning_content_echo.py -v

Checklist

Code

Documentation & Housekeeping

  • No public API surface changed
  • DeepSeek / Kimi / OpenRouter / Anthropic / OpenAI behaviour unchanged

`_copy_reasoning_content_for_api` step 3 promotes msg["reasoning"]
to api_msg["reasoning_content"] for any provider that has reasoning
text in the unified `reasoning` field.

For Qwen models served via vLLM and any other custom OpenAI-compatible
provider, this re-feed violates the multi-turn spec (Qwen explicitly
forbids re-feeding reasoning_content from prior turns) and produces:

  - context balloon across multi-turn conversations
  - thinking-mode death loops where the model keeps re-thinking
    its own prior reasoning back at itself

Add `needs_thinking_pad and ` to step 3's condition so the promotion
runs only for DeepSeek/Kimi (which require it for tool-call replay,
guarded by `_needs_kimi_tool_reasoning` / `_needs_deepseek_tool_reasoning`).

OpenRouter, Anthropic, and OpenAI carry reasoning continuity via the
separate `reasoning_details` field (untouched by this helper), so
dropping the promotion for them is safe — they were not relying on
this code path.

For Qwen and other custom providers, the helper now falls through to
step 5 and pops reasoning_content from the API replay message.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/qwen Qwen / Alibaba Cloud (OAuth) labels May 1, 2026
@leon7609

leon7609 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Closing as superseded: upstream implemented the equivalent gate natively in 2b3a4f0 ("fix(agent): strip stale reasoning_content when falling back to a strict provider", #50480), first shipped in v0.18.0 (v2026.7.1).

Step 3 of copy_reasoning_content_for_api (now in agent/agent_runtime_helpers.py) gates the reasoningreasoning_content promotion on needs_thinking_pad and pops the field for strict providers otherwise — semantically identical to this PR for both the promote (DeepSeek/Kimi) and drop (Qwen-on-vLLM / custom OpenAI-compatible) cases. Verified on a production deployment running v0.18.0 with a Qwen fallback: no reasoning re-feed, no regression.

Thanks!

@leon7609 leon7609 closed this Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists provider/qwen Qwen / Alibaba Cloud (OAuth) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants