This commit is contained in:
Oleg Maslov
2026-09-02 10:14:22 +02:00
parent 0c3e2ead3b
commit b20b138fe4
771 changed files with 161561 additions and 9027 deletions

View File

@@ -1,5 +1,11 @@
import { describe, it, expect, vi, afterEach } from 'vitest';
import { CostTracker, DEFAULT_MODEL_PRICING, type ModelPricing } from '../src/cost-tracker.js';
import {
BudgetExceededError,
BudgetPricingUnavailableError,
CostTracker,
DEFAULT_MODEL_PRICING,
type ModelPricing,
} from '../src/cost-tracker.js';
describe('CostTracker', () => {
const pricing: Record<string, ModelPricing> = {
@@ -58,6 +64,18 @@ describe('CostTracker', () => {
expect(DEFAULT_MODEL_PRICING['claude-haiku-4-5']).toBeDefined();
});
it('uses provider rates for the live Gemini and Codex acceptance models', () => {
expect(DEFAULT_MODEL_PRICING['google/gemini-2.5-flash'])
.toEqual({ inputPer1k: 0.0003, outputPer1k: 0.0025 });
expect(DEFAULT_MODEL_PRICING['openrouter/openai/gpt-5.3-codex'])
.toEqual({ inputPer1k: 0.00175, outputPer1k: 0.014 });
const tracker = new CostTracker();
tracker.addUsage('google/gemini-2.5-flash', 1000, 1000);
tracker.addUsage('openrouter/openai/gpt-5.3-codex', 1000, 1000);
expect(tracker.getStats().estimatedCost).toBeCloseTo(0.01855, 6);
});
it('warns once and uses family-aware fallback for an unknown Opus id', () => {
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
const tracker = new CostTracker();
@@ -83,13 +101,217 @@ describe('CostTracker', () => {
});
describe('getDailyTotal', () => {
it('returns total cost across all models for current session', () => {
it('adds persisted carryover to in-process usage without double-seeding', () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2026-07-21T12:00:00.000Z'));
const tracker = new CostTracker();
tracker.addUsage('claude-sonnet-4-6', 1000, 500);
tracker.addUsage('claude-sonnet-4-6', 2000, 1000);
const total = tracker.getDailyTotal();
expect(total).toBeGreaterThan(0);
expect(total).toBe(tracker.getStats().estimatedCost);
try {
tracker.initializeDailyCarryover('2026-07-21', 6);
tracker.initializeDailyCarryover('2026-07-21', 8);
tracker.addUsage('claude-sonnet-4-6', 1000, 1000);
expect(tracker.hasDailyCarryover('2026-07-21')).toBe(true);
expect(tracker.getDailyTotal()).toBeCloseTo(6.018, 6);
} finally {
vi.useRealTimers();
}
});
it('resets carryover and in-process usage at the next UTC day', () => {
vi.useFakeTimers();
const tracker = new CostTracker();
try {
vi.setSystemTime(new Date('2026-07-20T23:59:00.000Z'));
tracker.initializeDailyCarryover('2026-07-20', 6);
tracker.addUsage('claude-sonnet-4-6', 1000, 1000);
vi.setSystemTime(new Date('2026-07-21T00:01:00.000Z'));
expect(tracker.getDailyTotal()).toBe(0);
expect(tracker.hasDailyCarryover('2026-07-21')).toBe(false);
tracker.initializeDailyCarryover('2026-07-21', 2);
tracker.addUsage('claude-sonnet-4-6', 2000, 1000);
expect(tracker.getDailyTotal()).toBeCloseTo(2.021, 6);
} finally {
vi.useRealTimers();
}
});
});
});
describe('hard daily spend reservations', () => {
const pricing: Record<string, ModelPricing> = {
paid: { inputPer1k: 1, outputPer1k: 1 },
};
it('atomically prevents concurrent reservations from sharing the same capacity', async () => {
const tracker = new CostTracker(pricing);
tracker.setBudget(1, 'hard');
const attempts = await Promise.allSettled([
Promise.resolve().then(() => tracker.reserveModelSpend({
model: 'paid', inputTokens: 400, maxOutputTokens: 200,
})),
Promise.resolve().then(() => tracker.reserveModelSpend({
model: 'paid', inputTokens: 400, maxOutputTokens: 200,
})),
]);
expect(attempts.filter(result => result.status === 'fulfilled')).toHaveLength(1);
expect(attempts.find(result => result.status === 'rejected')).toMatchObject({
reason: expect.any(BudgetExceededError),
});
expect(tracker.getReservedDailyTotal()).toBeCloseTo(0.6, 6);
});
it('reconciles a conservative reservation to actual usage exactly once', () => {
const tracker = new CostTracker(pricing);
tracker.setBudget(1, 'hard');
const reservation = tracker.reserveModelSpend({
model: 'paid', inputTokens: 400, maxOutputTokens: 400, workspaceId: 'workspace-a',
});
tracker.reconcileModelSpend(reservation, { inputTokens: 100, outputTokens: 100 });
tracker.reconcileModelSpend(reservation, { inputTokens: 900, outputTokens: 900 });
expect(tracker.getReservedDailyTotal()).toBe(0);
expect(tracker.getDailyTotal()).toBeCloseTo(0.2, 6);
expect(tracker.getWorkspaceCost('workspace-a')).toBeCloseTo(0.2, 6);
expect(() => tracker.reserveModelSpend({
model: 'paid', inputTokens: 400, maxOutputTokens: 400,
})).not.toThrow();
});
it('retains the conservative reservation after ambiguous provider failure', () => {
const tracker = new CostTracker(pricing);
tracker.setBudget(1, 'hard');
const reservation = tracker.reserveModelSpend({
model: 'paid', inputTokens: 500, maxOutputTokens: 500,
});
tracker.commitReservedModelSpend(reservation);
expect(tracker.getReservedDailyTotal()).toBe(0);
expect(tracker.getDailyTotal()).toBeCloseTo(1, 6);
expect(() => tracker.reserveModelSpend({
model: 'paid', inputTokens: 1, maxOutputTokens: 1,
})).toThrow(BudgetExceededError);
});
it('allows explicitly verified free execution after the paid cap is exhausted', () => {
const tracker = new CostTracker(pricing);
tracker.setBudget(1, 'hard');
const paid = tracker.reserveModelSpend({
model: 'paid', inputTokens: 500, maxOutputTokens: 500,
});
tracker.commitReservedModelSpend(paid);
const local = tracker.reserveModelSpend({
model: 'unpriced-local-model',
inputTokens: 10_000,
maxOutputTokens: 10_000,
billingClass: 'free',
});
tracker.reconcileModelSpend(local, { inputTokens: 10_000, outputTokens: 10_000 });
expect(tracker.getDailyTotal()).toBeCloseTo(1, 6);
});
it('normalizes zero to disabled and rejects negative budgets', () => {
const tracker = new CostTracker(pricing);
tracker.setBudget(0, 'hard');
expect(tracker.getBudget()).toEqual({ dailyBudgetUsd: null, mode: 'hard' });
expect(() => tracker.setBudget(-1, 'hard')).toThrow(/non-negative finite/i);
});
it('preserves an explicit priced classification for ollama-prefixed routes', () => {
const tracker = new CostTracker({
'ollama/remote-paid': { inputPer1k: 1, outputPer1k: 1 },
});
tracker.setBudget(1, 'hard');
const reservation = tracker.reserveModelSpend({
model: 'ollama/remote-paid', inputTokens: 300, maxOutputTokens: 300,
billingClass: 'priced',
});
tracker.reconcileModelSpend(reservation, { inputTokens: 100, outputTokens: 100 });
expect(tracker.getDailyTotal()).toBeCloseTo(0.2, 6);
});
it('commits the reservation when provider usage is non-finite', () => {
const tracker = new CostTracker(pricing);
tracker.setBudget(1, 'hard');
const reservation = tracker.reserveModelSpend({
model: 'paid', inputTokens: 400, maxOutputTokens: 400,
});
tracker.reconcileModelSpend(reservation, { inputTokens: Number.NaN, outputTokens: 0 });
expect(tracker.getDailyTotal()).toBeCloseTo(0.8, 6);
expect(() => tracker.reserveModelSpend({
model: 'paid', inputTokens: 200, maxOutputTokens: 1,
})).toThrow(BudgetExceededError);
});
it('rejects non-finite direct usage before it can poison the ledger', () => {
const tracker = new CostTracker(pricing);
expect(() => tracker.addUsage('paid', Number.NaN, 0)).toThrow(/finite/i);
expect(tracker.getDailyTotal()).toBe(0);
});
it('fails closed when hard mode lacks trusted pricing for a paid route', () => {
const tracker = new CostTracker();
tracker.setBudget(1, 'hard');
expect(() => tracker.reserveModelSpend({
model: 'openrouter/auto', inputTokens: 1, maxOutputTokens: 1,
billingClass: 'priced',
})).toThrow(BudgetPricingUnavailableError);
});
it('prices provider-wrapped model IDs only through a trusted catalog suffix', () => {
const tracker = new CostTracker();
tracker.setBudget(1, 'hard');
const reservation = tracker.reserveModelSpend({
model: 'anthropic/claude-sonnet-4-6',
inputTokens: 1_000,
maxOutputTokens: 1_000,
billingClass: 'priced',
});
tracker.reconcileModelSpend(reservation, { inputTokens: 1_000, outputTokens: 1_000 });
expect(tracker.getDailyTotal()).toBeCloseTo(0.018, 6);
expect(() => tracker.reserveModelSpend({
model: 'anthropic/untrusted-custom-model',
inputTokens: 1,
maxOutputTokens: 1,
billingClass: 'priced',
})).toThrow(BudgetPricingUnavailableError);
});
it('honors explicit paid versus free billing for Ollama-routed reservations', () => {
const tracker = new CostTracker();
const paid = tracker.reserveModelSpend({
model: 'ollama/minimax-m2.7:cloud',
inputTokens: 1_000,
maxOutputTokens: 1_000,
billingClass: 'priced',
});
tracker.reconcileModelSpend(paid, { inputTokens: 1_000, outputTokens: 1_000 });
const local = tracker.reserveModelSpend({
model: 'ollama/qwen2.5:1.5b',
inputTokens: 1_000,
maxOutputTokens: 1_000,
billingClass: 'free',
});
tracker.reconcileModelSpend(local, { inputTokens: 1_000, outputTokens: 1_000 });
expect(tracker.getDailyTotal()).toBeCloseTo(0.018, 6);
});
});