From 890a737d1e8493238a26f52fa95eb9cd030d7a71 Mon Sep 17 00:00:00 2001 From: Zhiyuan Zheng Date: Thu, 26 Feb 2026 12:38:05 +0800 Subject: [PATCH] fix(chat-headers): skip x-initiator override for @ai-sdk/github-copilot models MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OpenCode's copilot fetch wrapper already sets x-initiator based on the actual HTTP request body content. When oh-my-opencode's chat.headers hook overrides it with 'agent', the Copilot API detects a mismatch between the header and the request body and rejects the request with 'invalid initiator'. This matches the approach OpenCode's own chat.headers handler uses (copilot.ts:314) — it explicitly skips @ai-sdk/github-copilot models because the fetch wrapper handles x-initiator correctly on its own. --- src/plugin/chat-headers.test.ts | 37 +++++++++++++++++++++++++++++++++ src/plugin/chat-headers.ts | 11 ++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/plugin/chat-headers.test.ts b/src/plugin/chat-headers.test.ts index f2858605d..35de5e006 100644 --- a/src/plugin/chat-headers.test.ts +++ b/src/plugin/chat-headers.test.ts @@ -106,4 +106,41 @@ describe("createChatHeadersHandler", () => { expect(output.headers["x-initiator"]).toBeUndefined() }) + + test("skips x-initiator override when model uses @ai-sdk/github-copilot", async () => { + const handler = createChatHeadersHandler({ + ctx: { + client: { + session: { + message: async () => ({ + data: { + parts: [ + { + type: "text", + text: `notification\n${OMO_INTERNAL_INITIATOR_MARKER}`, + }, + ], + }, + }), + }, + }, + } as never, + }) + const output: { headers: Record } = { headers: {} } + + await handler( + { + sessionID: "ses_4", + provider: { id: "github-copilot" }, + model: { api: { npm: "@ai-sdk/github-copilot" } }, + message: { + id: "msg_4", + role: "user", + }, + }, + output, + ) + + expect(output.headers["x-initiator"]).toBeUndefined() + }) }) diff --git a/src/plugin/chat-headers.ts b/src/plugin/chat-headers.ts index 044ccaf28..9945ac1f1 100644 --- a/src/plugin/chat-headers.ts +++ b/src/plugin/chat-headers.ts @@ -123,6 +123,17 @@ export function createChatHeadersHandler(args: { ctx: PluginContext }): (input: if (!isChatHeadersOutput(output)) return if (!isCopilotProvider(normalizedInput.provider.id)) return + + // Do not override x-initiator when @ai-sdk/github-copilot is active. + // OpenCode's copilot fetch wrapper already sets x-initiator based on + // the actual request body content. Overriding it here causes a mismatch + // that the Copilot API rejects with "invalid initiator". + const model = isRecord(input) && isRecord((input as Record).model) + ? (input as Record).model as Record + : undefined + const api = model && isRecord(model.api) ? model.api as Record : undefined + if (api?.npm === "@ai-sdk/github-copilot") return + if (!(await isOmoInternalMessage(normalizedInput, ctx.client))) return output.headers["x-initiator"] = "agent"