Destination
A response-path feature in GoModel that detects old Anthropic-style
<think>...</think> (and known equivalents) embedded in model output
and rewrites them into each API surface's native structured reasoning
field, so clients get reasoning on the right field instead of an XML
blob inside the message content.
End state (one-line acceptance): a model that emits <think>x</think>hi
returns, on the OpenAI chat endpoint, { "message": { "content": "hi", "reasoning_content": "x" } }; on the OpenAI responses API, a
reasoning item with that text; on the Anthropic messages endpoint, a
content block of type: "thinking" carrying that text. Nothing about
requests changes. Streaming partial tags reassemble correctly across
chunks.
Notes
- Scope: response path only. Request side already has GoModel's
compression / guardrails pipeline and is not in scope here.
- Three API surfaces:
/chat/completions, /responses, /messages.
Each has a different native reasoning field shape.
- Skill: consult
writing-for-agents style for PR body, comments,
commit messages; consult grilling and domain-modeling for any
ambiguous decision.
- Worktree:
.worktrees/feat-think-block-translation on branch
feat/think-block-translation. PR target: weselben/GoModel.
Decisions so far
Not yet specified
- 99%-coverage test scope boundaries (draft PR is at 91.8% package coverage)
- Dashboard runtime-settings pattern for per-surface override (referenced by T8)
- Responses reasoning.summary population — deferred
- Per-provider vs canonical-chat hook — awaiting user feedback on Q6
Out of scope
- Request-side
<think> translation (clients send native fields
already; this PR is response-side only).
- Reasoning-effort / model-side reasoning controls.
- Compression / guardrail interactions (separate pipeline).
- Responses API
reasoning.summary field population beyond raw
reasoning text — left as a follow-up if/when needed.
- Fast-path chat passthrough and the native Anthropic messages
passthrough (documented exclusions).
Destination
A response-path feature in GoModel that detects old Anthropic-style
<think>...</think>(and known equivalents) embedded in model outputand rewrites them into each API surface's native structured reasoning
field, so clients get reasoning on the right field instead of an XML
blob inside the message content.
End state (one-line acceptance): a model that emits
<think>x</think>hireturns, on the OpenAI chat endpoint,
{ "message": { "content": "hi", "reasoning_content": "x" } }; on the OpenAI responses API, areasoning item with that text; on the Anthropic messages endpoint, a
content block of
type: "thinking"carrying that text. Nothing aboutrequests changes. Streaming partial tags reassemble correctly across
chunks.
Notes
compression / guardrails pipeline and is not in scope here.
/chat/completions,/responses,/messages.Each has a different native reasoning field shape.
writing-for-agentsstyle for PR body, comments,commit messages; consult
grillinganddomain-modelingfor anyambiguous decision.
.worktrees/feat-think-block-translationon branchfeat/think-block-translation. PR target:weselben/GoModel.Decisions so far
reasoning_contentas the repo-wide canonical field. Client-capability detection is a relabeled research ticket (T38).Statetype ininternal/thinkextract, not a reuse ofstreaming.StreamBuffer.Not yet specified
Out of scope
<think>translation (clients send native fieldsalready; this PR is response-side only).
reasoning.summaryfield population beyond rawreasoning text — left as a follow-up if/when needed.
passthrough (documented exclusions).