Files
diegosouzapw--omniroute/tests/unit/anthropic-cache-fingerprint.test.ts
2026-07-13 13:39:12 +08:00

75 lines
3.4 KiB
TypeScript

/**
* Tests for Anthropic billing header fingerprint stability (#1638).
*
* Validates that the billing header fingerprint is stable across different
* messages within the same day, preventing prompt-cache prefix invalidation.
*/
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { createHash } from "node:crypto";
// Replicate the stabilized fingerprint logic from base.ts
function computeStableFingerprint(ccVersion: string): string {
const dayStamp = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
return createHash("sha256").update(`${dayStamp}${ccVersion}`).digest("hex").slice(0, 3);
}
// The old implementation for comparison
function computeOldFingerprint(firstUserMessageText: string, version: string): string {
const FINGERPRINT_SALT = "59cf53e54c78";
const indices = [4, 7, 20];
const chars = indices.map((i) => firstUserMessageText[i] || "0").join("");
const input = `${FINGERPRINT_SALT}${chars}${version}`;
return createHash("sha256").update(input).digest("hex").slice(0, 3);
}
describe("Anthropic billing header fingerprint (#1638)", () => {
const ccVersion = "2.1.137";
it("should produce the same fingerprint for different messages (stable)", () => {
const fp1 = computeStableFingerprint(ccVersion);
const fp2 = computeStableFingerprint(ccVersion);
assert.equal(fp1, fp2, "Same-day fingerprints should be identical");
});
it("should produce a 3-character hex fingerprint", () => {
const fp = computeStableFingerprint(ccVersion);
assert.equal(fp.length, 3, "Fingerprint should be 3 chars");
assert.ok(/^[a-f0-9]{3}$/.test(fp), `Fingerprint '${fp}' should be lowercase hex`);
});
it("old implementation produces DIFFERENT fingerprints for different messages", () => {
const msg1 = "Hello, how can I help you with your code?";
const msg2 = "Please fix the bug in my application";
const fp1 = computeOldFingerprint(msg1, ccVersion);
const fp2 = computeOldFingerprint(msg2, ccVersion);
assert.notEqual(fp1, fp2, "Old method should differ per message — this was the bug");
});
it("new implementation produces SAME fingerprint regardless of message content", () => {
// The new implementation doesn't use message content at all
const fp1 = computeStableFingerprint(ccVersion);
const fp2 = computeStableFingerprint(ccVersion);
const fp3 = computeStableFingerprint(ccVersion);
assert.equal(fp1, fp2);
assert.equal(fp2, fp3);
});
it("billing header line should be deterministic within the same day", () => {
const fp = computeStableFingerprint(ccVersion);
const billingLine1 = `x-anthropic-billing-header: cc_version=${ccVersion}.${fp}; cc_entrypoint=cli; cch=00000;`;
const billingLine2 = `x-anthropic-billing-header: cc_version=${ccVersion}.${fp}; cc_entrypoint=cli; cch=00000;`;
assert.equal(billingLine1, billingLine2, "Billing lines should be byte-identical");
});
it("should produce different fingerprints for different days", () => {
// Simulate different days by computing manually
const day1 = "2026-04-27";
const day2 = "2026-04-28";
const fp1 = createHash("sha256").update(`${day1}${ccVersion}`).digest("hex").slice(0, 3);
const fp2 = createHash("sha256").update(`${day2}${ccVersion}`).digest("hex").slice(0, 3);
// They should be different (extremely high probability with SHA-256)
assert.notEqual(fp1, fp2, "Different days should produce different fingerprints");
});
});