| import type { StreamFn } from "@mariozechner/pi-agent-core"; |
| import type { Context, Model } from "@mariozechner/pi-ai"; |
| import { createAssistantMessageEventStream } from "@mariozechner/pi-ai"; |
| import { describe, expect, it } from "vitest"; |
| import { applyExtraParamsToAgent } from "./extra-params.js"; |
|
|
| type StreamPayload = { |
| messages: Array<{ |
| role: string; |
| content: unknown; |
| }>; |
| }; |
|
|
| function runOpenRouterPayload(payload: StreamPayload, modelId: string) { |
| const baseStreamFn: StreamFn = (model, _context, options) => { |
| options?.onPayload?.(payload, model); |
| return createAssistantMessageEventStream(); |
| }; |
| const agent = { streamFn: baseStreamFn }; |
|
|
| applyExtraParamsToAgent(agent, undefined, "openrouter", modelId); |
|
|
| const model = { |
| api: "openai-completions", |
| provider: "openrouter", |
| id: modelId, |
| } as Model<"openai-completions">; |
| const context: Context = { messages: [] }; |
|
|
| void agent.streamFn?.(model, context, {}); |
| } |
|
|
| describe("extra-params: OpenRouter Anthropic cache_control", () => { |
| it("injects cache_control into system message for OpenRouter Anthropic models", () => { |
| const payload = { |
| messages: [ |
| { role: "system", content: "You are a helpful assistant." }, |
| { role: "user", content: "Hello" }, |
| ], |
| }; |
|
|
| runOpenRouterPayload(payload, "anthropic/claude-opus-4-6"); |
|
|
| expect(payload.messages[0].content).toEqual([ |
| { type: "text", text: "You are a helpful assistant.", cache_control: { type: "ephemeral" } }, |
| ]); |
| expect(payload.messages[1].content).toBe("Hello"); |
| }); |
|
|
| it("adds cache_control to last content block when system message is already array", () => { |
| const payload = { |
| messages: [ |
| { |
| role: "system", |
| content: [ |
| { type: "text", text: "Part 1" }, |
| { type: "text", text: "Part 2" }, |
| ], |
| }, |
| ], |
| }; |
|
|
| runOpenRouterPayload(payload, "anthropic/claude-opus-4-6"); |
|
|
| const content = payload.messages[0].content as Array<Record<string, unknown>>; |
| expect(content[0]).toEqual({ type: "text", text: "Part 1" }); |
| expect(content[1]).toEqual({ |
| type: "text", |
| text: "Part 2", |
| cache_control: { type: "ephemeral" }, |
| }); |
| }); |
|
|
| it("does not inject cache_control for OpenRouter non-Anthropic models", () => { |
| const payload = { |
| messages: [{ role: "system", content: "You are a helpful assistant." }], |
| }; |
|
|
| runOpenRouterPayload(payload, "google/gemini-3-pro"); |
|
|
| expect(payload.messages[0].content).toBe("You are a helpful assistant."); |
| }); |
|
|
| it("leaves payload unchanged when no system message exists", () => { |
| const payload = { |
| messages: [{ role: "user", content: "Hello" }], |
| }; |
|
|
| runOpenRouterPayload(payload, "anthropic/claude-opus-4-6"); |
|
|
| expect(payload.messages[0].content).toBe("Hello"); |
| }); |
| }); |
|
|