diff --git a/packages/core/src/session/runner/llm.ts b/packages/core/src/session/runner/llm.ts index 07f50385092f..d07d878e3704 100644 --- a/packages/core/src/session/runner/llm.ts +++ b/packages/core/src/session/runner/llm.ts @@ -211,9 +211,10 @@ export const layer = Layer.effect( const model = yield* models.resolve(session) const entries = yield* SessionHistory.entriesForRunner(db, session.id, system.baselineSeq) const context = entries.map((entry) => entry.message) + const promptCacheKey = /^ses_[0-9a-f]{64}$/.test(session.id) ? session.id.slice(4) : session.id const request = LLM.request({ model, - providerOptions: { openai: { promptCacheKey: session.id } }, + providerOptions: { openai: { promptCacheKey } }, system: [agent.info?.system, system.baseline] .filter((part): part is string => part !== undefined && part.length > 0) .map(SystemPart.make), diff --git a/packages/core/test/session-runner.test.ts b/packages/core/test/session-runner.test.ts index 7df44617b768..61a13a427e33 100644 --- a/packages/core/test/session-runner.test.ts +++ b/packages/core/test/session-runner.test.ts @@ -2824,6 +2824,42 @@ describe("SessionRunnerLLM", () => { }), ) + it.effect("bounds external session prompt cache keys", () => + Effect.gen(function* () { + yield* setup + const externalSessionID = SessionV2.ID.fromExternal({ + namespace: "discord", + key: "thread-one", + }) + const otherExternalSessionID = SessionV2.ID.fromExternal({ + namespace: "discord", + key: "thread-two", + }) + yield* insertSession(externalSessionID) + yield* insertSession(otherExternalSessionID) + const session = yield* SessionV2.Service + yield* session.prompt({ + sessionID: externalSessionID, + prompt: new Prompt({ text: "Run external session" }), + resume: false, + }) + yield* session.prompt({ + sessionID: otherExternalSessionID, + prompt: new Prompt({ text: "Run other external session" }), + resume: false, + }) + + requests.length = 0 + yield* session.resume(externalSessionID) + yield* session.resume(otherExternalSessionID) + + const keys = requests.map((request) => request.providerOptions?.openai?.promptCacheKey) + expect(keys).toEqual([externalSessionID.slice(4), otherExternalSessionID.slice(4)]) + expect(keys.every((key) => typeof key === "string" && key.length === 64)).toBe(true) + expect(keys[0]).not.toBe(keys[1]) + }), + ) + it.effect("fans out one failed run and allows a later retry", () => Effect.gen(function* () { yield* setup