Expand description
Separating a model’s reasoning from its content.
Thinking models (Nemotron with detailed thinking on, DeepSeek-R1, Qwen3, …)
emit their chain-of-thought inline in the content stream, wrapped in
<think>…</think> tags — distinct from the Ollama/OpenAI separate reasoning
field the loop already detects. Left in place, that reasoning leaks into the
reply shown to the user and into the content the agentic loop parses (issue
#385). This module strips it.
It’s a split, not just a strip: split_reasoning returns
(content, reasoning) so the reasoning can be captured (the plan_mode
technique, docs/design/thinking-effort-and-plan-mode.md) rather than thrown
away — today every caller discards the reasoning half, matching prior behavior.
Two surfaces:
split_reasoning— batch, for a fully-assembled reply (the non-streaming completion paths).ThinkFilter— incremental, for the streaming path, where a<think>block spans token boundaries (<thi/nk>…</thi/nk>) and must be suppressed live without ever printing a partial tag.
Structs§
- Think
Filter - An incremental filter that suppresses
<think>…</think>spans from a streamed content sequence, emitting only the clean (non-reasoning) text — even when a tag is split across feeds.
Functions§
- emits_
leading_ reasoning - Whether a model streams its chain-of-thought as a lone leading closer
(
reasoning</think>answer, with no opening<think>) — the shape Nemotron (detailed thinking on), DeepSeek-R1, and Qwen3 emit. Such models needThinkFilter::with_leading_reasoningso the streamed reasoning (and the bare</think>) is suppressed rather than printed into the reply. - split_
reasoning - Split inline
<think>…</think>reasoning out ofcontent, returning(clean_content, reasoning).