Skip to content

DeepSeek thinking mode still drops reasoning_content on v0.1.11 when model is missing from litellm's model map (deepseek/deepseek-v4-flash) #297

Description

@fatinghenji

Summary

#89 fixed the Curator/history-trimmer projection stripping reasoning_content, and that fix is confirmed present in v0.1.11 (curator.py:319, history_trimmer.py:43-44 allowlists). However, the same DeepSeek error still reproduces on latest main (v0.1.11, 9e2079b) when the configured model is not in litellm's model map — in our case deepseek/deepseek-v4-flash.

Error calling LLM: litellm.BadRequestError: DeepseekException -
{"error":{"message":"The reasoning_content in the thinking mode must be passed back to the API.","type":"invalid_request_error","param":null,"code":"invalid_request_error"}}

Reproduction (4 crashes in one evening, 2026-08-11)

  1. Configure Raven with deepseek/deepseek-v4-flash (thinking enabled server-side by DeepSeek).
  2. Run any tool-heavy agent task (raven agent -m "...").
  3. The loop dies mid-task with the error above. Observed:
    • mid-session, after ~10 min of tool calls (fresh session, first user turn)
    • twice more after resuming with -c
    • once on the first LLM call of a brand-new CLI session in the same workspace (prior-session assistant history in context)

Verified the #89 fix is in the running tree:

# raven/context_engine/segments/curator.py:319
allowed = {"role", "content", "tool_calls", "tool_call_id", "name", "reasoning_content", "thinking_blocks"}
# raven/context_engine/history_trimmer.py:43-44 -> "reasoning_content", "thinking_blocks"

and git rev-list --count 9e2079b..origin/main = 0 (nothing newer upstream).

Root-cause lead: litellm doesn't know this model is reasoning-capable

>>> import litellm  # litellm 1.85.0 (Raven's pinned dependency)
>>> litellm.get_model_info("deepseek/deepseek-v4-flash")
Exception: This model isn't mapped yet. model=deepseek/deepseek-v4-flash, custom_llm_provider=deepseek.
>>> litellm.get_model_info("deepseek/deepseek-reasoner").get("supports_reasoning")
True

DeepSeek serves deepseek-v4-flash with thinking on and requires reasoning_content echoed back on follow-up turns. Because litellm has no mapping for this model, its reasoning-aware paths never engage (capture/sanitization/replay), so reasoning_content is lost on the round trip even though Raven's own projection layers now preserve it. #89 fixed Raven's side; the residual hole is the litellm model-map miss for new/renamed DeepSeek models.

Suggested fix directions

  • User-declared capability override: let model_overrides (or provider config) mark a model as reasoning-capable, forcing reasoning_content preservation/replay regardless of litellm's model map.
  • Preserve-when-present default: if a stored assistant message carries reasoning_content, replay it verbatim for any OpenAI-compatible provider instead of depending on model recognition. Dropping an unknown-but-present field is what makes this class of bug recur with every new reasoning model.
  • Optionally: upstream the model entry to litellm's map (works today, breaks again with the next renamed model).

Environment

  • OS: CachyOS Linux (kernel 7.1.6), Python 3.14.6 via uv tool (editable install)
  • Raven: v0.1.11 (9e2079b, latest main at time of report)
  • litellm: 1.85.0
  • Provider/model: deepseek/deepseek-v4-flash

Workaround notes for anyone hitting this

Point the config at a model litellm recognizes as reasoning-capable (e.g. deepseek/deepseek-reasoner), or disable server-side thinking for the model if the provider allows it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions