fix(agents): preserve prompt cache boundary keys (#126380)

This commit is contained in:
Peter Steinberger
2026-08-19 11:09:57 -07:00
committed by GitHub
parent 0606e31d0e
commit 03a48b5801
2 changed files with 27 additions and 18 deletions
@@ -10,9 +10,12 @@ describe("resolveSessionBoundaryPromptCacheKey", () => {
sessionId: "session-1",
});
expect(resolve(0)).toBe(resolve(0));
expect(resolve(1)).not.toBe(resolve(0));
expect(resolve(2)).not.toBe(resolve(1));
expect([resolve(0), resolve(0), resolve(1), resolve(2)]).toEqual([
"session-1:0",
"session-1:0",
"session-1:1",
"session-1:2",
]);
});
it("preserves an explicit caller cache key", () => {
@@ -26,15 +29,21 @@ describe("resolveSessionBoundaryPromptCacheKey", () => {
).toBe("caller-key");
});
it("clamps derived keys from long internal session ids to OpenAI's 64-char limit", () => {
const longSessionId = `internal-session-effects-session-companion-${"a".repeat(50)}`;
const key = resolveSessionBoundaryPromptCacheKey({
api: "openai-responses",
boundaryCount: 0,
sessionId: longSessionId,
});
expect(key).toBeDefined();
expect(Array.from(key ?? "").length).toBeLessThanOrEqual(64);
expect(key?.startsWith("internal-session-effects-session-companion-")).toBe(true);
it("keeps long Unicode derived keys distinct across boundaries within the 64-char limit", () => {
const longSessionId = `internal-session-effects-${"🦞".repeat(64)}`;
const keys = [0, 1, 2].map((boundaryCount) =>
resolveSessionBoundaryPromptCacheKey({
api: "openai-responses",
boundaryCount,
sessionId: longSessionId,
}),
);
expect(new Set(keys).size).toBe(keys.length);
for (const [boundaryCount, key] of keys.entries()) {
expect(key).toBeDefined();
expect(Array.from(key ?? "").length).toBeLessThanOrEqual(64);
expect(key?.endsWith(`:${boundaryCount}`)).toBe(true);
}
});
});
@@ -1,4 +1,4 @@
import { clampOpenAIPromptCacheKey } from "@openclaw/ai/providers";
import { OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH } from "@openclaw/ai/providers";
export function resolveSessionBoundaryPromptCacheKey(params: {
api: string;
@@ -17,8 +17,8 @@ export function resolveSessionBoundaryPromptCacheKey(params: {
if (!usesOpenAIPromptCacheKey) {
return undefined;
}
// Clamp at derivation, not only in provider param builders: proxy runtimes
// serialize this key verbatim, and long internal-effects session ids
// (companion/btw) otherwise exceed OpenAI's 64-char prompt_cache_key limit.
return clampOpenAIPromptCacheKey(`${params.sessionId}:${params.boundaryCount}`);
// Reserve the lifecycle suffix inside OpenAI's 64-code-point limit for proxy runtimes.
const suffix = `:${params.boundaryCount}`;
const maxSessionIdLength = OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH - suffix.length;
return `${Array.from(params.sessionId).slice(0, maxSessionIdLength).join("")}${suffix}`;
}