import { describe, expect, it } from "vitest"; import { describeSettings, resolveAgentSettings } from "../src/index.ts"; import { compactionFromSettings, resolveModelFromSettings } from "../src/pi/model.ts"; describe("AgentSettings → pi-ai", () => { it("anthropic:baseUrl 去掉 /v1,上下文预算即 contextWindow,apiKey 只在 resolve 时给出", async () => { const s = resolveAgentSettings({ provider: "anthropic", baseUrl: "https://proxy.local/v1/", apiKey: "sk-ant-secret-value", model: "claude-sonnet-4-5", thinkingLevel: "high", contextBudgetTokens: 100_000, }); const { models, model } = resolveModelFromSettings(s); expect(model).toMatchObject({ api: "anthropic-messages", baseUrl: "https://proxy.local", id: "claude-sonnet-4-5", contextWindow: 100_000, reasoning: true, }); expect(JSON.stringify(model)).not.toContain("sk-ant-secret-value"); const auth = await models.getAuth(model); expect(JSON.stringify(auth)).toContain("sk-ant-secret-value"); expect(JSON.stringify(describeSettings(s))).not.toContain("sk-ant-secret-value"); expect(s.subagentsEnabled).toBe(false); }); it("openai-compatible 需要带 /v1 的 baseUrl;压缩模式映射", () => { const base = { provider: "openai-compatible" as const, apiKey: "k", model: "qwen3" }; expect(() => resolveModelFromSettings(resolveAgentSettings(base))).toThrow(/baseUrl/); const s = resolveAgentSettings({ ...base, baseUrl: "http://llm.local/v1", contextBudgetTokens: 32_000, compaction: { mode: "threshold", threshold: 0.75 }, }); const { model } = resolveModelFromSettings(s); expect(model).toMatchObject({ api: "openai-completions", baseUrl: "http://llm.local/v1", reasoning: false }); expect(compactionFromSettings(s, 32_000)).toEqual({ enabled: true, reserveTokens: 8000, keepRecentTokens: 8000, backgroundTokens: 0, }); const manual = resolveAgentSettings({ ...s, compaction: { mode: "manual", threshold: 0.8 } }); expect(compactionFromSettings(manual, 32_000).enabled).toBe(false); expect(() => resolveAgentSettings({ ...base, model: "" })).toThrow(); }); });