diff --git a/packages/core/src/session/runner/llm.ts b/packages/core/src/session/runner/llm.ts index d18351b53e..6a15137c07 100644 --- a/packages/core/src/session/runner/llm.ts +++ b/packages/core/src/session/runner/llm.ts @@ -51,6 +51,7 @@ import { AgentNotFoundError, StepFailedError } from "../error" import { toSessionError } from "../to-session-error" import { SessionRunnerRetry } from "./retry" import { PluginSupervisor } from "../../plugin/supervisor" +import { Flag } from "../../flag/flag" type StepTokens = { readonly input: number @@ -197,6 +198,13 @@ const layer = Layer.effect( const promptCacheKey = /^ses_[0-9a-f]{64}$/.test(session.id) ? session.id.slice(4) : session.id const request = LLM.request({ model, + http: { + headers: { + "x-opencode-project": session.projectID, + "x-opencode-session": session.id, + "x-opencode-client": Flag.OPENCODE_CLIENT, + }, + }, providerOptions: { openai: { promptCacheKey } }, system: [agentInfo.system ? agentInfo.system : SessionRunnerSystemPrompt.provider(model), history.initial] .filter((part): part is string => part !== undefined && part.length > 0) diff --git a/packages/core/test/session-runner.test.ts b/packages/core/test/session-runner.test.ts index 0ff2a86e84..ed1c1b3e21 100644 --- a/packages/core/test/session-runner.test.ts +++ b/packages/core/test/session-runner.test.ts @@ -19,6 +19,7 @@ import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder" import { LayerNodePlatform } from "@opencode-ai/core/effect/app-node-platform" import { LayerNode } from "@opencode-ai/core/effect/layer-node" import { EventV2 } from "@opencode-ai/core/event" +import { Flag } from "@opencode-ai/core/flag/flag" import { PermissionV2 } from "@opencode-ai/core/permission" import { EventTable } from "@opencode-ai/core/event/sql" import { Project } from "@opencode-ai/core/project" @@ -3043,6 +3044,21 @@ describe("SessionRunnerLLM", () => { }), ) + it.effect("adds session correlation headers to model requests", () => + Effect.gen(function* () { + const session = yield* setup + yield* admit(session, "Run correlated request") + + yield* session.resume(sessionID) + + expect(requests[0]?.http?.headers).toEqual({ + "x-opencode-project": Project.ID.global, + "x-opencode-session": sessionID, + "x-opencode-client": Flag.OPENCODE_CLIENT, + }) + }), + ) + it.effect("runs different sessions concurrently", () => Effect.gen(function* () { const session = yield* setup diff --git a/packages/tui/src/context/data.tsx b/packages/tui/src/context/data.tsx index 66ca56fcc9..114da13a1f 100644 --- a/packages/tui/src/context/data.tsx +++ b/packages/tui/src/context/data.tsx @@ -27,7 +27,7 @@ import type { SkillInfo, OpenCodeEvent, } from "@opencode-ai/client" -import type { Data } from "@opencode-ai/plugin/v2/tui/context" +import type { Plugin } from "@opencode-ai/plugin/v2/tui" import { createStore, produce, reconcile } from "solid-js/store" import { createSimpleContext } from "./helper" import { useClient } from "./client" @@ -1108,7 +1108,7 @@ export const { use: useData, provider: DataProvider } = createSimpleContext({ }, }, } - result satisfies Data + result satisfies Plugin.Context["data"] async function bootstrap() { if (bootstrapping) return bootstrapping