diff --git a/packages/ai/src/providers/faux.ts b/packages/ai/src/providers/faux.ts index c3771cc2c..0f4188e60 100644 --- a/packages/ai/src/providers/faux.ts +++ b/packages/ai/src/providers/faux.ts @@ -263,11 +263,12 @@ function withUsageEstimate( if (previousPrompt) { const cachedChars = commonPromptPrefixLength(previousPrompt, prompt); cacheRead = Math.ceil(cachedChars / 4); - cacheWrite = Math.ceil((promptLength - cachedChars) / 4); - input = Math.max(0, promptTokens - cacheRead); + cacheWrite = Math.max(0, promptTokens - cacheRead); } else { cacheWrite = promptTokens; } + // Every prompt token is either read from or written to the simulated cache. + input = 0; promptCache.set(sessionId, prompt); } diff --git a/packages/ai/test/faux-provider.test.ts b/packages/ai/test/faux-provider.test.ts index 6f4178111..ad23ed938 100644 --- a/packages/ai/test/faux-provider.test.ts +++ b/packages/ai/test/faux-provider.test.ts @@ -332,17 +332,18 @@ describe("faux provider", () => { const user = (content: string) => ({ role: "user" as const, content, timestamp: 1 }); // Prompt texts: "user:hello world" (16 characters), then 16 + 2 + "user:next" (9) = 27. - await complete(registration.getModel(), { messages: [user("hello world")] }, options); + const first = await complete(registration.getModel(), { messages: [user("hello world")] }, options); + expect(first.usage).toMatchObject({ input: 0, cacheRead: 0, cacheWrite: 4 }); const extended = await complete( registration.getModel(), { messages: [user("hello world"), user("next")] }, options, ); - expect(extended.usage).toMatchObject({ input: 3, cacheRead: 4, cacheWrite: 3 }); + expect(extended.usage).toMatchObject({ input: 0, cacheRead: 4, cacheWrite: 3 }); // The first message now differs after "user:hello w" (12 characters): "user:hello wide" + 2 + 9 = 26. const edited = await complete(registration.getModel(), { messages: [user("hello wide"), user("next")] }, options); - expect(edited.usage).toMatchObject({ input: 4, cacheRead: 3, cacheWrite: 4 }); + expect(edited.usage).toMatchObject({ input: 0, cacheRead: 3, cacheWrite: 4 }); }); it("does not simulate caching when cacheRetention is none", async () => {