cost.test.ts
1 import assert from 'node:assert/strict' 2 import { test } from 'node:test' 3 import type { Agent } from '@/types' 4 import { checkAgentBudgetLimits, getAgentSpendWindows } from './cost' 5 6 function buildNowTs(): number { 7 const d = new Date() 8 d.setFullYear(2026, 2, 15) 9 d.setHours(12, 0, 0, 0) 10 return d.getTime() 11 } 12 13 test('getAgentSpendWindows aggregates hourly/daily/monthly windows', () => { 14 const now = buildNowTs() 15 const previousMonth = new Date(2026, 1, 20, 12, 0, 0, 0).getTime() 16 17 const sessions = { 18 s1: { agentId: 'agent-a' }, 19 s2: { agentId: 'agent-b' }, 20 } 21 const usage = { 22 s1: [ 23 { timestamp: now - 20 * 60_000, estimatedCost: 1.25 }, // within hour 24 { timestamp: now - 3 * 60 * 60_000, estimatedCost: 0.5 }, // today 25 { timestamp: now - 26 * 60 * 60_000, estimatedCost: 2.0 }, // yesterday 26 { timestamp: previousMonth, estimatedCost: 4.0 }, // previous month 27 ], 28 s2: [ 29 { timestamp: now - 5 * 60_000, estimatedCost: 99 }, // different agent 30 ], 31 } 32 33 const spend = getAgentSpendWindows('agent-a', now, { sessions, usage }) 34 assert.equal(spend.hourly, 1.25) 35 assert.equal(spend.daily, 1.75) 36 assert.equal(spend.monthly, 3.75) 37 }) 38 39 test('checkAgentBudgetLimits reports exceeded and warning windows', () => { 40 const now = buildNowTs() 41 const sessions = { s1: { agentId: 'agent-a' } } 42 const usage = { 43 s1: [ 44 { timestamp: now - 15 * 60_000, estimatedCost: 1.25 }, // hourly over 45 { timestamp: now - 4 * 60 * 60_000, estimatedCost: 0.5 }, // daily near 46 { timestamp: now - 26 * 60 * 60_000, estimatedCost: 2.0 }, // monthly near 47 ], 48 } 49 const agent = { 50 id: 'agent-a', 51 name: 'Agent A', 52 hourlyBudget: 1.0, 53 dailyBudget: 2.0, 54 monthlyBudget: 4.0, 55 } as Agent 56 57 const result = checkAgentBudgetLimits(agent, now, { sessions, usage }) 58 assert.equal(result.ok, false) 59 assert.deepEqual(result.exceeded.map((x) => x.window), ['hourly']) 60 assert.deepEqual(result.warnings.map((x) => x.window), ['daily', 'monthly']) 61 }) 62 63 test('checkAgentBudgetLimits is ok when no caps are configured', () => { 64 const now = buildNowTs() 65 const sessions = { s1: { agentId: 'agent-a' } } 66 const usage = { s1: [{ timestamp: now - 10 * 60_000, estimatedCost: 10 }] } 67 const agent = { id: 'agent-a', name: 'Agent A' } as Agent 68 69 const result = checkAgentBudgetLimits(agent, now, { sessions, usage }) 70 assert.equal(result.ok, true) 71 assert.equal(result.exceeded.length, 0) 72 assert.equal(result.warnings.length, 0) 73 })