spb/khaelor Public
KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.
TypeScript 82.9%
HTML 14.9%
CSS 1.1%
JavaScript 0.7%
1/**2 * KHAELOR3 * File: tests/context/budget.test.ts4 * Description: ContextBudget tests — real-usage accounting, thresholds, config-driven windows.5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import { describe, expect, it } from "vitest";11import {12 ContextBudget,13 DEFAULT_CONTEXT_WINDOW,14 resolveContextWindow,15} from "../../src/context/index.js";1617describe("resolveContextWindow", () => {18 it("falls back to the default window when nothing is configured", () => {19 expect(resolveContextWindow("any-model")).toBe(DEFAULT_CONTEXT_WINDOW);20 });2122 it("uses a configured default window", () => {23 expect(resolveContextWindow("any-model", { defaultWindow: 500_000 })).toBe(500_000);24 });2526 it("prefers an exact per-model override from config", () => {27 const config = { defaultWindow: 200_000, byModel: { "big-model": 1_000_000 } };28 expect(resolveContextWindow("big-model", config)).toBe(1_000_000);29 expect(resolveContextWindow("other-model", config)).toBe(200_000);30 });3132 it("ignores invalid overrides", () => {33 expect(resolveContextWindow("m", { byModel: { m: -5 }, defaultWindow: 0 })).toBe(34 DEFAULT_CONTEXT_WINDOW,35 );36 });37});3839describe("ContextBudget", () => {40 const budget = () =>41 new ContextBudget({42 model: "m",43 reservedOutputTokens: 1_000,44 contextWindow: { defaultWindow: 10_000 },45 compactionBufferTokens: 1_000,46 pruneThresholdRatio: 0.5,47 });4849 it("computes usableWindow = window − reservedOutput − compactionBuffer", () => {50 expect(budget().usableWindow).toBe(8_000);51 });5253 it("starts with no observed usage and zero pressure", () => {54 const b = budget();55 expect(b.hasObservedUsage).toBe(false);56 expect(b.lastTotalTokens).toBe(0);57 expect(b.pressure()).toBe(0);58 expect(b.level()).toBe("ok");59 });6061 it("records real usage including cache reads and writes", () => {62 const b = budget();63 b.onUsage({ inputTokens: 1_000, outputTokens: 500, cacheReadTokens: 6_000, cacheWriteTokens: 1_000 });64 expect(b.lastTotalTokens).toBe(8_500);65 expect(b.hasObservedUsage).toBe(true);66 });6768 it("levels: ok → prune → compact as fake usage crosses thresholds", () => {69 const b = budget();70 b.onUsage({ inputTokens: 3_000, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 });71 expect(b.level()).toBe("ok");72 expect(b.shouldCompact()).toBe(false);7374 b.onUsage({ inputTokens: 4_500, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 });75 expect(b.level()).toBe("prune"); // ≥ 50% of 800076 expect(b.shouldCompact()).toBe(false);7778 b.onUsage({ inputTokens: 8_000, outputTokens: 100, cacheReadTokens: 0, cacheWriteTokens: 0 });79 expect(b.level()).toBe("compact");80 expect(b.shouldCompact()).toBe(true);81 expect(b.pressure()).toBeGreaterThanOrEqual(1);82 });8384 it("tracks only the LAST turn's usage (context footprint, not a running sum)", () => {85 const b = budget();86 b.onUsage({ inputTokens: 7_900, outputTokens: 200, cacheReadTokens: 0, cacheWriteTokens: 0 });87 expect(b.level()).toBe("compact");88 b.onUsage({ inputTokens: 100, outputTokens: 10, cacheReadTokens: 0, cacheWriteTokens: 0 });89 expect(b.level()).toBe("ok");90 });91});92