import { describe, expect, it } from "vitest"; import type { ClawdbotConfig } from "../config/config.js"; import { CONTEXT_WINDOW_HARD_MIN_TOKENS, CONTEXT_WINDOW_WARN_BELOW_TOKENS, evaluateContextWindowGuard, resolveContextWindowInfo, } from "./context-window-guard.js"; describe("context-window-guard", () => { it("blocks below 16k (model metadata)", () => { const info = resolveContextWindowInfo({ cfg: undefined, provider: "openrouter", modelId: "tiny", modelContextWindow: 8000, defaultTokens: 200_000, }); const guard = evaluateContextWindowGuard({ info }); expect(guard.source).toBe("model"); expect(guard.tokens).toBe(8000); expect(guard.shouldWarn).toBe(true); expect(guard.shouldBlock).toBe(true); }); it("warns below 32k but does not block at 16k+", () => { const info = resolveContextWindowInfo({ cfg: undefined, provider: "openai", modelId: "small", modelContextWindow: 24_000, defaultTokens: 200_000, }); const guard = evaluateContextWindowGuard({ info }); expect(guard.tokens).toBe(24_000); expect(guard.shouldWarn).toBe(true); expect(guard.shouldBlock).toBe(false); }); it("does not warn at 32k+ (model metadata)", () => { const info = resolveContextWindowInfo({ cfg: undefined, provider: "openai", modelId: "ok", modelContextWindow: 64_000, defaultTokens: 200_000, }); const guard = evaluateContextWindowGuard({ info }); expect(guard.shouldWarn).toBe(false); expect(guard.shouldBlock).toBe(false); }); it("uses models.providers.*.models[].contextWindow when present", () => { const cfg = { models: { providers: { openrouter: { baseUrl: "http://localhost", apiKey: "x", models: [ { id: "tiny", name: "tiny", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 12_000, maxTokens: 256, }, ], }, }, }, } satisfies ClawdbotConfig; const info = resolveContextWindowInfo({ cfg, provider: "openrouter", modelId: "tiny", modelContextWindow: undefined, defaultTokens: 200_000, }); const guard = evaluateContextWindowGuard({ info }); expect(info.source).toBe("modelsConfig"); expect(guard.shouldBlock).toBe(true); }); it("falls back to agents.defaults.contextTokens", () => { const cfg = { agents: { defaults: { contextTokens: 20_000 } }, } satisfies ClawdbotConfig; const info = resolveContextWindowInfo({ cfg, provider: "anthropic", modelId: "whatever", modelContextWindow: undefined, defaultTokens: 200_000, }); const guard = evaluateContextWindowGuard({ info }); expect(info.source).toBe("agentContextTokens"); expect(guard.shouldWarn).toBe(true); expect(guard.shouldBlock).toBe(false); }); it("uses default when nothing else is available", () => { const info = resolveContextWindowInfo({ cfg: undefined, provider: "anthropic", modelId: "unknown", modelContextWindow: undefined, defaultTokens: 200_000, }); const guard = evaluateContextWindowGuard({ info }); expect(info.source).toBe("default"); expect(guard.shouldWarn).toBe(false); expect(guard.shouldBlock).toBe(false); }); it("allows overriding thresholds", () => { const info = { tokens: 10_000, source: "model" as const }; const guard = evaluateContextWindowGuard({ info, warnBelowTokens: 12_000, hardMinTokens: 9_000, }); expect(guard.shouldWarn).toBe(true); expect(guard.shouldBlock).toBe(false); }); it("exports thresholds as expected", () => { expect(CONTEXT_WINDOW_HARD_MIN_TOKENS).toBe(16_000); expect(CONTEXT_WINDOW_WARN_BELOW_TOKENS).toBe(32_000); }); });