From 64b78df100e9812eb1b6b49468b02468b461ce88 Mon Sep 17 00:00:00 2001 From: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Date: Thu, 27 Aug 2026 02:35:27 -0300 Subject: [PATCH] test(video): expose response-derived cache retention --- .../chatcore-extracted-modules-3821.test.ts | 27 +++++++++++++++++++ .../chatcore-semantic-cache-store.test.ts | 15 +++++++++++ tests/unit/chatcore-semantic-cache.test.ts | 23 ++++++++++++++++ .../chatcore-streaming-cache-store.test.ts | 14 ++++++++++ tests/unit/reasoning-cache.test.ts | 18 +++++++++++++ 5 files changed, 97 insertions(+) diff --git a/tests/unit/chatcore-extracted-modules-3821.test.ts b/tests/unit/chatcore-extracted-modules-3821.test.ts index b49a1adc56..69ec222f71 100644 --- a/tests/unit/chatcore-extracted-modules-3821.test.ts +++ b/tests/unit/chatcore-extracted-modules-3821.test.ts @@ -80,6 +80,7 @@ test("checkIdempotencyCache returns { hit:null, idempotencyKey } on a miss", asy effectiveServiceTier: undefined, startTime: 0, log: undefined, + videoTranscriptSensitive: false, }); assert.equal(result.hit, null); // #6558: the raw header key is now namespaced by provider/model + a messages @@ -115,6 +116,7 @@ test("checkIdempotencyCache returns a hit Response reusing the same key after a effectiveServiceTier: undefined, startTime: 0, log: undefined, + videoTranscriptSensitive: false, }); assert.equal(result.idempotencyKey, key, "the resolved key is returned for the save site to reuse"); @@ -122,6 +124,30 @@ test("checkIdempotencyCache returns a hit Response reusing the same key after a assert.equal(result.hit!.response.headers.get("X-OmniRoute-Idempotent"), "true"); }); +test("checkIdempotencyCache bypasses an existing transcript-sensitive entry", async () => { + const rawKey = "idem-private-video-3821"; + const key = composeIdempotencyKey({ + rawKey, + provider: "openai", + model: "gpt-4.1", + messages: undefined, + })!; + saveIdempotency(key, { content: "PRIVATE_IDEMPOTENCY_TRANSCRIPT_SENTINEL" }, 200); + + const result = await checkIdempotencyCache({ + clientRawRequest: { headers: new Headers({ "idempotency-key": rawKey }) }, + provider: "openai", + model: "gpt-4.1", + effectiveServiceTier: undefined, + startTime: 0, + log: undefined, + videoTranscriptSensitive: true, + }); + + assert.equal(result.hit, null); + assert.equal(result.idempotencyKey, null); +}); + test("checkIdempotencyCache resolves a null key when no idempotency headers are present", async () => { const result = await checkIdempotencyCache({ clientRawRequest: { headers: new Headers() }, @@ -130,6 +156,7 @@ test("checkIdempotencyCache resolves a null key when no idempotency headers are effectiveServiceTier: undefined, startTime: 0, log: undefined, + videoTranscriptSensitive: false, }); assert.equal(result.hit, null); assert.equal(result.idempotencyKey, null); diff --git a/tests/unit/chatcore-semantic-cache-store.test.ts b/tests/unit/chatcore-semantic-cache-store.test.ts index a39d039400..8629dd1b0f 100644 --- a/tests/unit/chatcore-semantic-cache-store.test.ts +++ b/tests/unit/chatcore-semantic-cache-store.test.ts @@ -94,6 +94,21 @@ test("disabled → no store, no gate calls past enabled", () => { assert.equal(calls.cacheable, 0); }); +test("transcript-sensitive responses never enter the durable semantic cache", () => { + const sentinel = "PRIVATE_NONSTREAM_SEMANTIC_CACHE_SENTINEL"; + const { deps, stored, calls } = makeDeps(); + storeSemanticCacheResponse( + baseArgs({ + translatedResponse: { choices: [{ message: { content: sentinel } }] }, + videoTranscriptSensitive: true, + }), + deps + ); + + assert.equal(stored.length, 0); + assert.equal(calls.cacheable, 0); +}); + test("not cacheable-for-write → no store", () => { const { deps, stored } = makeDeps({ isCacheableForWrite: () => false }); storeSemanticCacheResponse(baseArgs(), deps); diff --git a/tests/unit/chatcore-semantic-cache.test.ts b/tests/unit/chatcore-semantic-cache.test.ts index 032bfcf9f9..c8a123f90c 100644 --- a/tests/unit/chatcore-semantic-cache.test.ts +++ b/tests/unit/chatcore-semantic-cache.test.ts @@ -53,6 +53,7 @@ function makeBaseArgs(overrides: Record = {}) { persistCalls.push(a); }, apiKeyId: null as string | null, + videoTranscriptSensitive: false, ...overrides, }; return { args, persistCalls }; @@ -173,6 +174,7 @@ function makeHitArgs(overrides: Record = {}) { persistCalls.push(a as Record); }, apiKeyId: null as string | null, + videoTranscriptSensitive: false, ...overrides, }; return { args, persistCalls, convertedCalls, debugCalls }; @@ -191,6 +193,27 @@ function seedHit(args: ReturnType["args"], response: unknown return signature; } +test("checkSemanticCache bypasses an existing sensitive cache entry", async () => { + clearCache(); + const sentinel = "PRIVATE_SEMANTIC_CACHE_HIT_TRANSCRIPT_SENTINEL"; + const { args, persistCalls, convertedCalls, debugCalls } = makeHitArgs({ + body: { + model: "gpt-4o", + messages: [{ role: "user", content: "sensitive cached query" }], + temperature: 0, + }, + videoTranscriptSensitive: true, + }); + seedHit(args, { choices: [{ message: { content: sentinel } }] }); + + const result = await checkSemanticCache(args as Parameters[0]); + + assert.equal(result, null); + assert.equal(persistCalls.length, 0); + assert.equal(convertedCalls.length, 0); + assert.equal(debugCalls.length, 0); +}); + test("checkSemanticCache returns a non-streaming JSON HIT with cache headers + logging side effects", async () => { clearCache(); const cached = { diff --git a/tests/unit/chatcore-streaming-cache-store.test.ts b/tests/unit/chatcore-streaming-cache-store.test.ts index d66986f361..e05aee45b9 100644 --- a/tests/unit/chatcore-streaming-cache-store.test.ts +++ b/tests/unit/chatcore-streaming-cache-store.test.ts @@ -95,6 +95,20 @@ test("disabled → no store", () => { assert.equal(stored.length, 0); }); +test("transcript-sensitive streams never enter the durable semantic cache", () => { + const sentinel = "PRIVATE_STREAM_SEMANTIC_CACHE_SENTINEL"; + const { deps, stored } = makeDeps(); + storeStreamingSemanticCacheResponse( + baseArgs({ + streamResponseBody: { choices: [{ message: { content: sentinel } }] }, + videoTranscriptSensitive: true, + }), + deps + ); + + assert.equal(stored.length, 0); +}); + test("missing response body → no store", () => { const { deps, stored } = makeDeps(); storeStreamingSemanticCacheResponse(baseArgs({ streamResponseBody: null }), deps); diff --git a/tests/unit/reasoning-cache.test.ts b/tests/unit/reasoning-cache.test.ts index db538a8031..e2cfc089b5 100644 --- a/tests/unit/reasoning-cache.test.ts +++ b/tests/unit/reasoning-cache.test.ts @@ -182,6 +182,24 @@ describe("Reasoning Replay Cache — Service Layer", () => { assert.equal(lookupReasoning("call_capture_2"), "Captured assistant reasoning"); }); + it("should never cache reasoning echoed by a transcript-sensitive response", () => { + clearReasoningCacheAll(); + const sentinel = "PRIVATE_REASONING_CACHE_TRANSCRIPT_SENTINEL"; + const cached = cacheReasoningFromAssistantMessage( + { + role: "assistant", + reasoning_content: sentinel, + tool_calls: [{ id: "call_private_video_reasoning" }], + }, + "deepseek", + "deepseek-reasoner", + { videoTranscriptSensitive: true } + ); + + assert.equal(cached, 0); + assert.equal(lookupReasoning("call_private_video_reasoning"), null); + }); + it("should keep request message cache keys stable when tool call IDs change", () => { clearReasoningCacheAll();