@@ -68,14 +68,17 @@ describe("BudgetGuard.advisory", () => {
6868
6969 it ( "expectedCost is the costlier of the last LLM and tool call" , ( ) => {
7070 // Parity with the Python suite: a cheap tool after an expensive LLM call
71- // must not shrink the estimate — the max wins (conservative).
71+ // must not shrink the estimate — the max wins (conservative). A ManualPrice
72+ // literal keeps the LLM cost deterministic (no dependency on cost_map.json,
73+ // which drifts when refreshed).
7274 const g = new BudgetGuard ( 1.0 ) ;
73- g . record ( "gpt-4o" , 1_000 , 1_000 ) ; // $0.0125 LLM
74- g . recordTool ( "exa.search" , 0.001 ) ; // cheaper tool, spent = $0.0135
75- const a = g . advisory ( ) ;
76- expect ( a . expectedCost ) . toBeCloseTo ( 0.0125 , 9 ) ; // LLM side, not the cheaper tool
77- // floor((1.0 - 0.0135) / 0.0125) = floor(78.92) = 78
78- expect ( a . estCallsRemaining ) . toBe ( 78 ) ;
75+ g . record ( "m" , 1_000 , 0 , {
76+ price : { inputCostPerToken : 2e-4 , outputCostPerToken : 0.0 } ,
77+ } ) ; // $0.20 LLM (costlier)
78+ g . recordTool ( "db.query" , 0.05 ) ; // $0.05 tool (cheaper), spent = $0.25
79+ const a = g . advisory ( ) ; // remaining 0.75
80+ expect ( a . expectedCost ) . toBeCloseTo ( 0.2 , 9 ) ; // LLM side, not the cheaper tool
81+ expect ( a . estCallsRemaining ) . toBe ( 3 ) ; // floor(0.75 / 0.20)
7982 } ) ;
8083
8184 it ( "rejects an out-of-range or non-integer nearLimitBps" , ( ) => {
0 commit comments