Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/currency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ async function getExchangeRate(code: string): Promise<number> {
const cached = await loadCachedRate(code)
if (cached) return cached

// Test-only escape hatch, set for the whole suite in
// tests/setup/env-isolation.ts: skip the live Frankfurter fetch so a real FX
// move can't shift assertions. Same fallback an unreachable network gets.
if (process.env['CODEBURN_FX_NO_FETCH']) return 1

let rate: number
try {
rate = await fetchRate(code)
Expand Down
25 changes: 17 additions & 8 deletions src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,21 +225,30 @@ function mergeSnapshotFallbacks(pricing: Map<string, ModelCosts>): Map<string, M
return applyBuiltinPriceOverrides(pricing)
}

function setPricingCache(pricing: Map<string, ModelCosts>): void {
pricingCache = pricing
sortedPricingKeys = null
lowercasePricingIndex = null
knownNamespaces = null
}

export async function loadPricing(): Promise<void> {
const cached = await loadCachedPricing()
if (cached) {
pricingCache = mergeSnapshotFallbacks(cached)
sortedPricingKeys = null
lowercasePricingIndex = null
knownNamespaces = null
setPricingCache(mergeSnapshotFallbacks(cached))
return
}

// Test-only escape hatch, set for the whole suite in
// tests/setup/env-isolation.ts: skip the live LiteLLM fetch and price purely
// off the bundled snapshot, so an upstream reprice can't turn tests red.
if (process.env['CODEBURN_PRICING_SNAPSHOT_ONLY']) {
setPricingCache(mergeSnapshotFallbacks(new Map()))
return
}

try {
pricingCache = mergeSnapshotFallbacks(await fetchAndCachePricing())
sortedPricingKeys = null
lowercasePricingIndex = null
knownNamespaces = null
setPricingCache(mergeSnapshotFallbacks(await fetchAndCachePricing()))
} catch {
// snapshot already loaded at init; nothing more to do
}
Expand Down
7 changes: 7 additions & 0 deletions tests/setup/env-isolation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ function applyIsolation(): void {
if (original === undefined) delete process.env[key]
else process.env[key] = original
}
// Price off the bundled LiteLLM snapshot only. Without this, loadPricing()
// fetches the live upstream table, so a mid-week reprice by a provider turns
// pricing assertions red with no local change.
process.env['CODEBURN_PRICING_SNAPSHOT_ONLY'] = '1'
// Same for FX: skip the live Frankfurter fetch and fall back to the
// USD-equivalent rate unless a test seeds its own exchange-rate.json cache.
process.env['CODEBURN_FX_NO_FETCH'] = '1'
// Pin the timezone so date grouping is deterministic regardless of the dev's
// shell TZ. Clearing it is not enough (Node falls back to the OS zone); a
// non-UTC TZ would otherwise shift day buckets versus a clean CI runner. A
Expand Down
Loading