Description
The reasoning.exclude option in providerOptions for OpenRouter/Codebuff providers is completely non-functional. Setting providerOptions.openrouter.reasoning.exclude = true does not suppress reasoning tokens from the stream.
Root Cause
In sdk/src/impl/llm.ts (around line 534), the continue statement targets the inner for loop over providers, not the outer stream processing:
if (chunkValue.type === 'reasoning-delta') {
for (const provider of ['openrouter', 'codebuff'] as const) {
if (
(params.providerOptions?.[provider] as OpenRouterProviderOptions | undefined)
?.reasoning?.exclude
) {
continue // ← only skips to next provider iteration, not the yield
}
}
yield { type: 'reasoning', text: chunkValue.text } // ← always reached
}
After the for loop completes (whether continue was hit or not), the yield on the next line is unconditionally reached.
Impact
Users who set reasoning.exclude = true to suppress reasoning tokens from the stream will receive them anyway.
Suggested Fix
if (chunkValue.type === 'reasoning-delta') {
const excluded = (['openrouter', 'codebuff'] as const).some(
(p) =>
(params.providerOptions?.[p] as OpenRouterProviderOptions | undefined)
?.reasoning?.exclude,
)
if (!excluded) {
yield { type: 'reasoning', text: chunkValue.text }
}
}
Description
The
reasoning.excludeoption inproviderOptionsfor OpenRouter/Codebuff providers is completely non-functional. SettingproviderOptions.openrouter.reasoning.exclude = truedoes not suppress reasoning tokens from the stream.Root Cause
In
sdk/src/impl/llm.ts(around line 534), thecontinuestatement targets the innerforloop over providers, not the outer stream processing:After the
forloop completes (whethercontinuewas hit or not), theyieldon the next line is unconditionally reached.Impact
Users who set
reasoning.exclude = trueto suppress reasoning tokens from the stream will receive them anyway.Suggested Fix