Problem
Many reasoning models (MiniMax-M2.5, DeepSeek R1, QwQ, etc.) return <think>...</think> blocks in their content field when called via OpenAI-compatible API. This causes:
- Structured output failure —
generateObject tries to JSON.parse response text that starts with <think>, fails every retry, times out
- Tool calling failure — Agent ReAct loop may not parse tool results correctly
- Dirty output — Users see raw thinking process mixed with the actual response
Example raw response from MiniMax-M2.5:
{
"content": "<think>\nThe user wants me to...\n</think>\n\nActual response here"
}
Solution
In the OpenAI adapter layer (openai-adapter.ts), auto-detect and strip <think>...</think> tags from response content.
Requirements
- Strip
<think>...</think> from response.text in both generate() and generateWithTools()
- Preserve the thinking content in a separate field (e.g.,
response.reasoning) for observability
- Handle streaming mode: buffer and strip thinking tokens from the stream
- Handle edge cases: multiple think blocks, unclosed tags, nested tags
- Regex pattern:
/^<think>[\s\S]*?<\/think>\s*/ (greedy match from start)
Affected code
packages/ai/src/adapters/openai-adapter.ts — core parsing logic
packages/ai/src/stream.ts — streaming mode handling
Acceptance Criteria
Priority
P1 — Blocks real API validation of examples and E2E tests
Problem
Many reasoning models (MiniMax-M2.5, DeepSeek R1, QwQ, etc.) return
<think>...</think>blocks in theircontentfield when called via OpenAI-compatible API. This causes:generateObjecttries to JSON.parse response text that starts with<think>, fails every retry, times outExample raw response from MiniMax-M2.5:
{ "content": "<think>\nThe user wants me to...\n</think>\n\nActual response here" }Solution
In the OpenAI adapter layer (
openai-adapter.ts), auto-detect and strip<think>...</think>tags from response content.Requirements
<think>...</think>fromresponse.textin bothgenerate()andgenerateWithTools()response.reasoning) for observability/^<think>[\s\S]*?<\/think>\s*/(greedy match from start)Affected code
packages/ai/src/adapters/openai-adapter.ts— core parsing logicpackages/ai/src/stream.ts— streaming mode handlingAcceptance Criteria
response.textis clean (no<think>tags) for all generate methodsresponse.reasoning(optional field)generateObject(structured output) works with reasoning modelsPriority
P1 — Blocks real API validation of examples and E2E tests