
























1+import type { StreamFn } from "@earendil-works/pi-agent-core";
2+import type { Context, Model } from "@earendil-works/pi-ai";
3+import { describe, expect, it } from "vitest";
4+import { createDeepInfraAnthropicCacheWrapper } from "./cache-wrapper.js";
5+6+function capturePayload(params: {
7+modelId: string;
8+initialPayload: Record<string, unknown>;
9+}): { captured: Record<string, unknown>; baseCalls: number } {
10+let captured: Record<string, unknown> = {};
11+let baseCalls = 0;
12+const baseStreamFn: StreamFn = (_model, _context, options) => {
13+baseCalls += 1;
14+const payload = structuredClone(params.initialPayload);
15+options?.onPayload?.(payload, _model);
16+captured = payload;
17+return {} as ReturnType<StreamFn>;
18+};
19+20+const wrapped = createDeepInfraAnthropicCacheWrapper(baseStreamFn);
21+void wrapped(
22+{
23+api: "openai-completions",
24+provider: "deepinfra",
25+id: params.modelId,
26+reasoning: false,
27+} as Model<"openai-completions">,
28+{ messages: [] } as Context,
29+{} as never,
30+);
31+32+return { captured, baseCalls };
33+}
34+35+describe("createDeepInfraAnthropicCacheWrapper", () => {
36+it("injects ephemeral cache_control markers on the system message for anthropic/* models", () => {
37+const { captured, baseCalls } = capturePayload({
38+modelId: "anthropic/claude-sonnet-4-6",
39+initialPayload: {
40+messages: [
41+{ role: "system", content: "You are a helpful assistant." },
42+{ role: "user", content: "Hi" },
43+],
44+},
45+});
46+47+expect(baseCalls).toBe(1);
48+expect(captured.messages).toEqual([
49+{
50+role: "system",
51+content: [
52+{
53+type: "text",
54+text: "You are a helpful assistant.",
55+cache_control: { type: "ephemeral" },
56+},
57+],
58+},
59+{ role: "user", content: "Hi" },
60+]);
61+});
62+63+it("tags the last block of an array-shaped system message", () => {
64+const { captured } = capturePayload({
65+modelId: "anthropic/claude-haiku-4-5",
66+initialPayload: {
67+messages: [
68+{
69+role: "system",
70+content: [
71+{ type: "text", text: "Block one" },
72+{ type: "text", text: "Block two" },
73+],
74+},
75+{ role: "user", content: "Hi" },
76+],
77+},
78+});
79+80+const messages = captured.messages as Array<{ role: string; content: unknown }>;
81+expect(messages[0]?.content).toEqual([
82+{ type: "text", text: "Block one" },
83+{
84+type: "text",
85+text: "Block two",
86+cache_control: { type: "ephemeral" },
87+},
88+]);
89+});
90+91+it("matches the anthropic/ prefix case-insensitively", () => {
92+const { captured } = capturePayload({
93+modelId: "Anthropic/Claude-Sonnet-4-6",
94+initialPayload: {
95+messages: [{ role: "system", content: "sys" }],
96+},
97+});
98+99+const messages = captured.messages as Array<{ content: unknown }>;
100+expect(messages[0]?.content).toEqual([
101+{ type: "text", text: "sys", cache_control: { type: "ephemeral" } },
102+]);
103+});
104+105+it("does not mutate payloads for non-anthropic model ids", () => {
106+const initialPayload = {
107+messages: [
108+{ role: "system", content: "sys" },
109+{ role: "user", content: "Hi" },
110+],
111+};
112+const { captured, baseCalls } = capturePayload({
113+modelId: "deepseek-ai/DeepSeek-V4-Flash",
114+ initialPayload,
115+});
116+117+expect(baseCalls).toBe(1);
118+expect(captured).toEqual(initialPayload);
119+});
120+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。