Describe the bug
The bundled Responses SDK (packages/opencode/src/provider/sdk/copilot/responses/) has a providerOptions namespace mismatch that breaks multi-turn conversations when store: false is set.
How it works: When an @ai-sdk/openai-compatible provider is configured with useResponses: true, OpenCode routes it through the bundled copilot Responses SDK (see provider.ts ~line 1238). This SDK is the only built-in Responses API adapter for custom providers — we're not choosing to use it; OpenCode routes us through it automatically.
The bug: The SDK stores reasoning metadata under the "openai" namespace but reads from "copilot":
Write side (openai-responses-language-model.ts ~line 530):
providerMetadata: {
openai: { itemId: part.id, reasoningEncryptedContent: part.encrypted_content }
}
Read side (openai-responses-language-model.ts ~line 197 and convert-to-openai-responses-input.ts ~line 186):
parseProviderOptions({ provider: "copilot", providerOptions, schema })
// looks for providerOptions["copilot"] — but the data is in providerOptions["openai"]
The AI SDK framework passes providerMetadata back as providerOptions verbatim on subsequent turns. So on turn 2, the reasoning data lives at providerOptions["openai"] but the SDK reads from providerOptions["copilot"] → undefined. The reasoning item is dropped, and the server returns:
Item 'msg_...' of type 'message' was provided without its required 'reasoning' item: 'rs_...'
Who's affected:
- Any
@ai-sdk/openai-compatible provider with useResponses: true — the upstream code in provider.ts routes these through the bundled Responses SDK automatically
- GitHub Copilot users with
store: false (e.g. zero-data-retention orgs). With store: true (the default), reasoning replays as item_reference and the namespace path is never hit.
Why it's hidden: Issue #2941 reported this symptom and was closed, but the fix (commit 40836e9) addressed itemId stripping — a different root cause. The namespace mismatch was never fixed.
To reproduce
- Configure an
@ai-sdk/openai-compatible provider with useResponses: true and a model that produces reasoning output (e.g. gpt-5.2)
- Send a message that triggers reasoning
- Send a follow-up message in the same conversation
- Second message fails with:
Item 'msg_...' of type 'message' was provided without its required 'reasoning' item
Minimal fix
Change provider: "copilot" to provider: "openai" in both read-side calls:
openai-responses-language-model.ts ~line 197:
- const openaiOptions = await parseProviderOptions({ provider: "copilot", providerOptions, schema })
+ const openaiOptions = await parseProviderOptions({ provider: "openai", providerOptions, schema })
convert-to-openai-responses-input.ts ~line 186:
- const providerOptions = await parseProviderOptions({ provider: "copilot", providerOptions: part.providerOptions, schema })
+ const providerOptions = await parseProviderOptions({ provider: "openai", providerOptions: part.providerOptions, schema })
This aligns the read namespace with the existing write namespace. The SDK was adapted from @ai-sdk/openai which uses "openai" — the "copilot" on the read side was likely introduced during the fork.
This does not affect GitHub Copilot's default behavior: With store: true, reasoning is replayed as item_reference, so the encrypted_content path (and this namespace) is never exercised.
My agent and I have been running a local build with this fix for several weeks against four gpt-5 models via an Azure OpenAI gateway with useResponses: true. Multi-turn conversations with reasoning models work correctly.
Environment
- OpenCode version: 1.2.27 (bug still present)
- Provider:
@ai-sdk/openai-compatible with useResponses: true
- Models tested: gpt-5-nano, gpt-5-mini, gpt-5.2, gpt-5.2-codex
Disclosure: This issue was drafted with AI assistance and reviewed/edited by a human before posting.
Describe the bug
The bundled Responses SDK (
packages/opencode/src/provider/sdk/copilot/responses/) has a providerOptions namespace mismatch that breaks multi-turn conversations whenstore: falseis set.How it works: When an
@ai-sdk/openai-compatibleprovider is configured withuseResponses: true, OpenCode routes it through the bundled copilot Responses SDK (seeprovider.ts~line 1238). This SDK is the only built-in Responses API adapter for custom providers — we're not choosing to use it; OpenCode routes us through it automatically.The bug: The SDK stores reasoning metadata under the
"openai"namespace but reads from"copilot":Write side (
openai-responses-language-model.ts~line 530):Read side (
openai-responses-language-model.ts~line 197 andconvert-to-openai-responses-input.ts~line 186):The AI SDK framework passes
providerMetadataback asproviderOptionsverbatim on subsequent turns. So on turn 2, the reasoning data lives atproviderOptions["openai"]but the SDK reads fromproviderOptions["copilot"]→undefined. The reasoning item is dropped, and the server returns:Who's affected:
@ai-sdk/openai-compatibleprovider withuseResponses: true— the upstream code inprovider.tsroutes these through the bundled Responses SDK automaticallystore: false(e.g. zero-data-retention orgs). Withstore: true(the default), reasoning replays asitem_referenceand the namespace path is never hit.Why it's hidden: Issue #2941 reported this symptom and was closed, but the fix (commit 40836e9) addressed itemId stripping — a different root cause. The namespace mismatch was never fixed.
To reproduce
@ai-sdk/openai-compatibleprovider withuseResponses: trueand a model that produces reasoning output (e.g. gpt-5.2)Item 'msg_...' of type 'message' was provided without its required 'reasoning' itemMinimal fix
Change
provider: "copilot"toprovider: "openai"in both read-side calls:openai-responses-language-model.ts~line 197:convert-to-openai-responses-input.ts~line 186:This aligns the read namespace with the existing write namespace. The SDK was adapted from
@ai-sdk/openaiwhich uses"openai"— the"copilot"on the read side was likely introduced during the fork.This does not affect GitHub Copilot's default behavior: With
store: true, reasoning is replayed asitem_reference, so theencrypted_contentpath (and this namespace) is never exercised.My agent and I have been running a local build with this fix for several weeks against four gpt-5 models via an Azure OpenAI gateway with
useResponses: true. Multi-turn conversations with reasoning models work correctly.Environment
@ai-sdk/openai-compatiblewithuseResponses: trueDisclosure: This issue was drafted with AI assistance and reviewed/edited by a human before posting.