Reasoning from OpenAI-compatible providers that inline <think> tags leaks into text content · Issue #43770 · anomalyco/opencode · GitHub
Skip to content

Reasoning from OpenAI-compatible providers that inline <think> tags leaks into text content #43770

Closed as not planned

Description

@23wwwtt

Summary

For OpenAI-compatible providers whose models emit reasoning inline in content wrapped in <think>...</think> tags, opencode stores the raw tagged text verbatim as a text part. The UI then renders the model's chain-of-thought as regular assistant output instead of a collapsible thinking block.

Environment

  • opencode 1.18.19
  • Provider: custom OpenAI-compatible (poolside, endpoint https://inference.poolside.ai/v1)
  • Model: poolside/laguna-s-2.1
  • Model definition declares interleaved reasoning via interleaved: { field: "reasoning_content" }

Observed behavior

  • Many requests correctly populate the separate reasoning channel and are displayed as thinking.
  • Intermittently, a response arrives with the entire reasoning trace inline in content:
<long reasoning monologue ...></think><final answer>

opencode saves this whole string as one text part. The affected message reports reasoning: 0 tokens at message level, while the session total still shows accumulated reasoning tokens — so token accounting is also distorted (reasoning counted as output).

Expected behavior

Inline <think> blocks should be extracted into separate reasoning parts so they render as thinking, not as body text.

Suggested fix

Wrap affected provider/model instances with the AI SDK's extraction middleware, e.g.:

import { wrapLanguageModel, extractReasoningMiddleware } from 'ai'

const model = wrapLanguageModel({
  model: openaiCompatibleModel,
  middleware: extractReasoningMiddleware({ tagName: 'think' }),
})

Options:

  1. Apply extractReasoningMiddleware automatically for providers/models known to inline think tags (similar to how DeepSeek R1 is handled).
  2. Expose a per-model config flag (e.g. reasoning.extract: "think-tags") in the model/provider schema so users can enable it for any OpenAI-compatible endpoint.
  3. A safe fallback could also apply startWithReasoning: true semantics for models that omit the opening tag.

Impact

  • Users cannot review the agent's reasoning process (it appears as unreadable body text mixed with output).
  • Reasoning/output token attribution is wrong on affected messages.

Activity

  1. github-actions commented on Aug 21, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue is specifically about providers that intermittently send reasoning inline in content rather than in a separate reasoning_content field, it may be distinct enough to keep open — please clarify in a comment whether the stream sometimes omits reasoning_content entirely in favor of content with embedded tags, as that detail would distinguish this from the above.

  2. 00kino547 commented on Oct 11, 2026

    @00kino547

    its also happening for me but with opencode zen (big pickle)

  3. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

  4. ashaker20 commented on Oct 11, 2026

    @ashaker20

    Re-filed for OpenCode 2.0 here: #54599. Reproduces on 2.0.25 (macOS and Windows) with opencode/big-pickle via OpenCode Zen — inline </think> reasoning is stored as a text part instead of a reasoning part. 104 of 152 text parts for this model in my session DB contain a literal </think>. Claude models on the same setup are unaffected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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