Skip to content

Bug: stale reasoning reused when current turn has no reasoning_content #17052

@happy5318

Description

@happy5318

Bug Description

The last_reasoning extraction in run_conversation() walks backwards through the entire message history to find any assistant message with a truthy reasoning field. When the current turn produces no reasoning (e.g. the model returns reasoning_content: null for a simple prompt), the loop skips the current message and matches an older assistant message, displaying its reasoning as if it belonged to the current response.

Steps to Reproduce

  1. Use a model that returns reasoning_content for some turns but null for others (e.g. GLM-5, which outputs reasoning for complex prompts but returns null for simple ones like "hello")
  2. Send a complex message → model returns reasoning → reasoning is displayed correctly
  3. Send a simple message → model returns reasoning_content: nullthe previous turn's reasoning is incorrectly displayed again

Expected Behavior

If the current turn produced no reasoning, no reasoning should be displayed. The display should reflect the current turn's output, not a stale reasoning from a previous turn.

Root Cause

# Current code (run_agent.py ~L13108)
last_reasoning = None
for msg in reversed(messages):
    if msg.get("role") == "assistant" and msg.get("reasoning"):  # ← skips current msg when reasoning=None
        last_reasoning = msg["reasoning"]                        # ← matches older msg instead
        break

The and msg.get("reasoning") condition causes the loop to skip the last assistant message when its reasoning is None/falsy, continuing backwards until it finds any older message that has reasoning.

Fix

Stop at the last assistant message regardless of whether its reasoning field is populated:

last_reasoning = None
for msg in reversed(messages):
    if msg.get("role") == "assistant":
        last_reasoning = msg.get("reasoning")  # None is the correct result when no reasoning
        break

Impact

  • Affects all models that occasionally return reasoning_content: null (GLM-5, some DeepSeek/Qwen configurations, etc.)
  • Users see confusing/misleading reasoning that does not correspond to the current response
  • No crash or data loss, but degraded UX when reasoning display is enabled (show_reasoning: true)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/agentCore agent loop, run_agent.py, prompt buildertype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions