Skip to content

feat(responses): translate legacy <think> XML into native reasoning fields #34

Description

@weselben

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions