Skip to content

Commit c89f6e7

Browse files
committed
add chat.headers hook, adjust codex and copilot plugins to use it
1 parent 17a5f75 commit c89f6e7

4 files changed

Lines changed: 45 additions & 11 deletions

File tree

packages/opencode/src/plugin/codex.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type { Hooks, PluginInput } from "@opencode-ai/plugin"
22
import { Log } from "../util/log"
3-
import { OAUTH_DUMMY_KEY } from "../auth"
4-
import { ProviderTransform } from "../provider/transform"
3+
import { Installation } from "../installation"
4+
import { Auth, OAUTH_DUMMY_KEY } from "../auth"
5+
import os from "os"
56

67
const log = Log.create({ service: "plugin.codex" })
78

@@ -489,5 +490,11 @@ export async function CodexAuthPlugin(input: PluginInput): Promise<Hooks> {
489490
},
490491
],
491492
},
493+
"chat.headers": async (input, output) => {
494+
if (input.model.providerID !== "openai") return
495+
output.headers.originator = "opencode"
496+
output.headers["User-Agent"] = `opencode/${Installation.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`
497+
output.headers.session_id = input.sessionID
498+
},
492499
}
493500
}

packages/opencode/src/plugin/copilot.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const CLIENT_ID = "Ov23li8tweQw6odWQebz"
66
// Add a small safety buffer when polling to avoid hitting the server
77
// slightly too early due to clock skew / timer drift.
88
const OAUTH_POLLING_SAFETY_MARGIN_MS = 3000 // 3 seconds
9-
109
function normalizeDomain(url: string) {
1110
return url.replace(/^https?:\/\//, "").replace(/\/$/, "")
1211
}
@@ -19,6 +18,7 @@ function getUrls(domain: string) {
1918
}
2019

2120
export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
21+
const sdk = input.client
2222
return {
2323
auth: {
2424
provider: "github-copilot",
@@ -83,11 +83,11 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
8383
})
8484

8585
const headers: Record<string, string> = {
86+
"x-initiator": isAgent ? "agent" : "user",
8687
...(init?.headers as Record<string, string>),
8788
"User-Agent": `opencode/${Installation.VERSION}`,
8889
Authorization: `Bearer ${info.refresh}`,
8990
"Openai-Intent": "conversation-edits",
90-
"X-Initiator": isAgent ? "agent" : "user",
9191
}
9292

9393
if (isVision) {
@@ -265,5 +265,19 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
265265
},
266266
],
267267
},
268+
"chat.headers": async (input, output) => {
269+
if (!input.model.providerID.includes("github-copilot")) return
270+
const session = await sdk.session
271+
.get({
272+
path: {
273+
id: input.sessionID,
274+
},
275+
throwOnError: true,
276+
})
277+
.catch(() => undefined)
278+
if (!session || !session.data.parentID) return
279+
// TODO: mark subagent sessions as agent initiated once copilot gives ok
280+
// output.headers["x-initiator"] = "agent"
281+
},
268282
}
269283
}

packages/opencode/src/session/llm.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export namespace LLM {
5353
.tag("sessionID", input.sessionID)
5454
.tag("small", (input.small ?? false).toString())
5555
.tag("agent", input.agent.name)
56+
.tag("mode", input.agent.mode)
5657
l.info("stream", {
5758
modelID: input.model.id,
5859
providerID: input.model.providerID,
@@ -131,6 +132,20 @@ export namespace LLM {
131132
},
132133
)
133134

135+
const { headers } = await Plugin.trigger(
136+
"chat.headers",
137+
{
138+
sessionID: input.sessionID,
139+
agent: input.agent,
140+
model: input.model,
141+
provider,
142+
message: input.user,
143+
},
144+
{
145+
headers: {},
146+
},
147+
)
148+
134149
const maxOutputTokens = isCodex
135150
? undefined
136151
: ProviderTransform.maxOutputTokens(
@@ -198,13 +213,6 @@ export namespace LLM {
198213
maxOutputTokens,
199214
abortSignal: input.abort,
200215
headers: {
201-
...(isCodex
202-
? {
203-
originator: "opencode",
204-
"User-Agent": `opencode/${Installation.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
205-
session_id: input.sessionID,
206-
}
207-
: undefined),
208216
...(input.model.providerID.startsWith("opencode")
209217
? {
210218
"x-opencode-project": Instance.project.id,
@@ -218,6 +226,7 @@ export namespace LLM {
218226
}
219227
: undefined),
220228
...input.model.headers,
229+
...headers,
221230
},
222231
maxRetries: input.retries ?? 0,
223232
messages: [

packages/plugin/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ export interface Hooks {
172172
input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage },
173173
output: { temperature: number; topP: number; topK: number; options: Record<string, any> },
174174
) => Promise<void>
175+
"chat.headers"?: (
176+
input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage },
177+
output: { headers: Record<string, string> },
178+
) => Promise<void>
175179
"permission.ask"?: (input: Permission, output: { status: "ask" | "deny" | "allow" }) => Promise<void>
176180
"command.execute.before"?: (
177181
input: { command: string; sessionID: string; arguments: string },

0 commit comments

Comments
 (0)