Skip to content

[Bug] Bundled Responses SDK namespace mismatch breaks multi-turn conversations when store: false #17926

@Dulani

Description

@Dulani

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:

  1. Any @ai-sdk/openai-compatible provider with useResponses: true — the upstream code in provider.ts routes these through the bundled Responses SDK automatically
  2. 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

  1. Configure an @ai-sdk/openai-compatible provider with useResponses: true and a model that produces reasoning output (e.g. gpt-5.2)
  2. Send a message that triggers reasoning
  3. Send a follow-up message in the same conversation
  4. 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.

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions