diff options
| author | Aiden Cline <[email protected]> | 2026-01-21 15:09:56 -0600 |
|---|---|---|
| committer | Aiden Cline <[email protected]> | 2026-01-21 15:10:08 -0600 |
| commit | c89f6e7ac61e0dd5404888df87555627efce6087 (patch) | |
| tree | ec91cad94ac94ab931bf2f441b483ddd316adb82 /packages | |
| parent | 17a5f75b543b2a6f30fecc87b3c5444e9264d239 (diff) | |
| download | opencode-c89f6e7ac61e0dd5404888df87555627efce6087.tar.gz opencode-c89f6e7ac61e0dd5404888df87555627efce6087.zip | |
add chat.headers hook, adjust codex and copilot plugins to use it
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/opencode/src/plugin/codex.ts | 11 | ||||
| -rw-r--r-- | packages/opencode/src/plugin/copilot.ts | 18 | ||||
| -rw-r--r-- | packages/opencode/src/session/llm.ts | 23 | ||||
| -rw-r--r-- | packages/plugin/src/index.ts | 4 |
4 files changed, 45 insertions, 11 deletions
diff --git a/packages/opencode/src/plugin/codex.ts b/packages/opencode/src/plugin/codex.ts index fc172dad9..3e31c6ce4 100644 --- a/packages/opencode/src/plugin/codex.ts +++ b/packages/opencode/src/plugin/codex.ts @@ -1,7 +1,8 @@ import type { Hooks, PluginInput } from "@opencode-ai/plugin" import { Log } from "../util/log" -import { OAUTH_DUMMY_KEY } from "../auth" -import { ProviderTransform } from "../provider/transform" +import { Installation } from "../installation" +import { Auth, OAUTH_DUMMY_KEY } from "../auth" +import os from "os" const log = Log.create({ service: "plugin.codex" }) @@ -489,5 +490,11 @@ export async function CodexAuthPlugin(input: PluginInput): Promise<Hooks> { }, ], }, + "chat.headers": async (input, output) => { + if (input.model.providerID !== "openai") return + output.headers.originator = "opencode" + output.headers["User-Agent"] = `opencode/${Installation.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})` + output.headers.session_id = input.sessionID + }, } } diff --git a/packages/opencode/src/plugin/copilot.ts b/packages/opencode/src/plugin/copilot.ts index 932b3fd6a..bf0f91dcd 100644 --- a/packages/opencode/src/plugin/copilot.ts +++ b/packages/opencode/src/plugin/copilot.ts @@ -6,7 +6,6 @@ const CLIENT_ID = "Ov23li8tweQw6odWQebz" // Add a small safety buffer when polling to avoid hitting the server // slightly too early due to clock skew / timer drift. const OAUTH_POLLING_SAFETY_MARGIN_MS = 3000 // 3 seconds - function normalizeDomain(url: string) { return url.replace(/^https?:\/\//, "").replace(/\/$/, "") } @@ -19,6 +18,7 @@ function getUrls(domain: string) { } export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> { + const sdk = input.client return { auth: { provider: "github-copilot", @@ -83,11 +83,11 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> { }) const headers: Record<string, string> = { + "x-initiator": isAgent ? "agent" : "user", ...(init?.headers as Record<string, string>), "User-Agent": `opencode/${Installation.VERSION}`, Authorization: `Bearer ${info.refresh}`, "Openai-Intent": "conversation-edits", - "X-Initiator": isAgent ? "agent" : "user", } if (isVision) { @@ -265,5 +265,19 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> { }, ], }, + "chat.headers": async (input, output) => { + if (!input.model.providerID.includes("github-copilot")) return + const session = await sdk.session + .get({ + path: { + id: input.sessionID, + }, + throwOnError: true, + }) + .catch(() => undefined) + if (!session || !session.data.parentID) return + // TODO: mark subagent sessions as agent initiated once copilot gives ok + // output.headers["x-initiator"] = "agent" + }, } } diff --git a/packages/opencode/src/session/llm.ts b/packages/opencode/src/session/llm.ts index 1029b45ea..e73f20403 100644 --- a/packages/opencode/src/session/llm.ts +++ b/packages/opencode/src/session/llm.ts @@ -53,6 +53,7 @@ export namespace LLM { .tag("sessionID", input.sessionID) .tag("small", (input.small ?? false).toString()) .tag("agent", input.agent.name) + .tag("mode", input.agent.mode) l.info("stream", { modelID: input.model.id, providerID: input.model.providerID, @@ -131,6 +132,20 @@ export namespace LLM { }, ) + const { headers } = await Plugin.trigger( + "chat.headers", + { + sessionID: input.sessionID, + agent: input.agent, + model: input.model, + provider, + message: input.user, + }, + { + headers: {}, + }, + ) + const maxOutputTokens = isCodex ? undefined : ProviderTransform.maxOutputTokens( @@ -198,13 +213,6 @@ export namespace LLM { maxOutputTokens, abortSignal: input.abort, headers: { - ...(isCodex - ? { - originator: "opencode", - "User-Agent": `opencode/${Installation.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`, - session_id: input.sessionID, - } - : undefined), ...(input.model.providerID.startsWith("opencode") ? { "x-opencode-project": Instance.project.id, @@ -218,6 +226,7 @@ export namespace LLM { } : undefined), ...input.model.headers, + ...headers, }, maxRetries: input.retries ?? 0, messages: [ diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index 36a4657d7..d02c8bfe5 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -172,6 +172,10 @@ export interface Hooks { input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage }, output: { temperature: number; topP: number; topK: number; options: Record<string, any> }, ) => Promise<void> + "chat.headers"?: ( + input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage }, + output: { headers: Record<string, string> }, + ) => Promise<void> "permission.ask"?: (input: Permission, output: { status: "ask" | "deny" | "allow" }) => Promise<void> "command.execute.before"?: ( input: { command: string; sessionID: string; arguments: string }, |
