Repository navigation
Description
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-compatibleprovider withuseResponses: true— the upstream code inprovider.tsroutes these through the bundled Responses SDK automatically - GitHub Copilot users with
store: 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
- Configure an
@ai-sdk/openai-compatibleprovider withuseResponses: trueand 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-compatiblewithuseResponses: 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.
Activity
fix(provider): align providerOptions namespace in bundled Responses SDK
Dulani commentedon Apr 2, 2026
Update from the author — the fix described above is wrong (or at least, not the right layer)
After living with the copilot SDK namespace fix for a while, my agent and I realized we were patching the wrong layer. The "Minimal fix" section above changes vendored code inside the bundled copilot Responses SDK — it works, but it's fragile and misidentifies the root problem.
What we actually ship now: a ~10-line bun patch on
@ai-sdk/azureitself, plus two small routing changes inprovider.ts. Zero modifications to the copilot SDK.The
@ai-sdk/azurepatch (patches/@ai-sdk%2Fazure@3.0.49.patch)(Same change in
dist/index.mjs.)This teaches
@ai-sdk/azureto respect a custombaseURLwithout forcing deployment-based URL paths or appending?api-version=. Our Azure API gateway (and likely others like LiteLLM, Azure API Management, or Cloudflare AI Gateway) handles versioning and routing itself.The
provider.tsrouting changeWith this routing, Azure models go through
@ai-sdk/azure's own.responses()method — which handles the"openai"namespace correctly — instead of being routed through the bundled copilot SDK (which uses"copilot").Note on AI SDK v6
In v6,
@ai-sdk/azurechanged its providerOptions key from"openai"to"azure"(migration guide). The original fix above ("copilot"→"openai") would be wrong in v6. Using the native.responses()path means the SDK handles its own namespace — we don't have to.Tracking the permanent fix
Our
@ai-sdk/azurepatch is a workaround until the SDK supports custombaseURLnatively:@ai-sdk/azure: baseURL mode appends /v1 and api-version — breaks custom gateways(open, unassigned)@ai-sdk/openai headers not forwarded to HTTP requests when using Responses API with APIM(open)Once vercel/ai #13956 lands, the bun patch goes away and only the
provider.tsrouting change remains.Who this applies to
Anyone routing
@ai-sdk/azurethrough a non-standard base URL (API gateways, proxies, APIM) who hits thers_/ reasoning item errors. The copilot SDK fix from the original issue still works for@ai-sdk/openai-compatiblewithuseResponses: trueon AI SDK v5, but if you're using@ai-sdk/azuredirectly, this is the cleaner path.I should have caught this before filing. The copilot SDK analysis was correct but led to the wrong fix location. Leaving the original issue body intact for reference.
Disclosure: This update was drafted with AI assistance and reviewed/edited by a human before posting.
Dulani commentedon Apr 6, 2026
Verified fixed in upstream v1.3.17
The namespace mismatch has been resolved in the upstream codebase between v1.3.7 and v1.3.17.
Verification:
packages/opencode/src/provider/sdk/copilot/responses/openai-responses-language-model.tsline 197:provider: "openai"packages/opencode/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.tsline 187:provider: "openai"Both locations now consistently use the
"openai"namespace, which resolves the multi-turn conversation failure whenstore: false.Tested with RAND-patched build
1.3.17-rand-patch- multi-turn conversations with reasoning models now work correctly.Closing as resolved. ✅