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
70 changes: 70 additions & 0 deletions src/runtime/supervise/coordination-driver.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { describe, expect, it } from 'vitest'
import { validateDriverPromptCache } from './coordination-driver'

describe('validateDriverPromptCache', () => {
it('accepts fractional USD savings — the shape a real router reports', () => {
// The exact evidence that refused an otherwise healthy driver: tangle-router returns
// cache savings in dollars, which are fractional, and the count rule rejected them.
expect(
validateDriverPromptCache({ readTokens: 5888, writeTokens: 0, readSavingsUsd: 0.0034 }),
).toBeUndefined()
})

it('still refuses a fractional TOKEN count', () => {
const error = validateDriverPromptCache({ readTokens: 12.5 })
expect(error?.message).toContain('"readTokens"')
expect(error?.message).toContain('non-negative safe integer')
})

it('refuses a negative USD amount and a non-finite one', () => {
expect(validateDriverPromptCache({ readSavingsUsd: -0.01 })?.message).toContain(
'non-negative finite number of dollars',
)
expect(validateDriverPromptCache({ writeCostUsd: Number.NaN })?.message).toContain(
'non-negative finite number of dollars',
)
expect(validateDriverPromptCache({ writeCostUsd: Number.POSITIVE_INFINITY })).toBeDefined()
})

it('accepts a whole-dollar USD amount and -0, and keeps an absurd one out', () => {
expect(validateDriverPromptCache({ readSavingsUsd: 5 })).toBeUndefined()
expect(validateDriverPromptCache({ readSavingsUsd: -0 })).toBeUndefined()
// The old all-integer rule rejected 1e308 as a side effect; the ceiling keeps that.
expect(validateDriverPromptCache({ readSavingsUsd: 1e308 })?.message).toContain('dollars')
})

it('accepts the full router-reported shape including missTokens', () => {
expect(
validateDriverPromptCache({
readTokens: 5888,
writeTokens: 0,
missTokens: 111,
readSavingsUsd: 0.0034,
status: 'hit',
}),
).toBeUndefined()
})

it('refuses a negative token count and ignores string fields', () => {
expect(validateDriverPromptCache({ readTokens: -1 })?.message).toContain('safe integer')
expect(validateDriverPromptCache({ tier: 'ephemeral-1h' })).toBeUndefined()
})

it('treats absent evidence as acceptable rather than inventing zeroes', () => {
expect(validateDriverPromptCache(undefined)).toBeUndefined()
expect(validateDriverPromptCache({})).toBeUndefined()
})

it('classifies known schema members by what they are, not by their name', () => {
// readSavingsUsd is the schema's only dollar member; the token members stay counts even
// though nothing in their names says so.
expect(validateDriverPromptCache({ missTokens: 12.5 })?.message).toContain('safe integer')
expect(validateDriverPromptCache({ readSavingsUsd: 0.5 })).toBeUndefined()
})

it('falls back to the usd name-suffix convention for unknown pass-through fields', () => {
expect(validateDriverPromptCache({ savingsUSD: 1.25 })).toBeUndefined()
// `usdTokens` is a count despite carrying the substring — the suffix is what decides.
expect(validateDriverPromptCache({ usdTokens: 1.25 })?.message).toContain('safe integer')
})
})
56 changes: 48 additions & 8 deletions src/runtime/supervise/coordination-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,53 @@ function providerAttemptEvidence(model: string | undefined): ProviderModelExecut
)
}

/** The USD-denominated members of {@link PromptCacheUsage} — the schema, not a guess. Every
* other known member (`readTokens`, `writeTokens`, `missTokens`) is a token COUNT. */
const PROMPT_CACHE_USD_FIELDS: ReadonlySet<string> = new Set(['readSavingsUsd'])

/** Dollar amounts above this are provider nonsense, not evidence. The old all-integer rule
* rejected them as a side effect; keeping an explicit ceiling preserves that protection
* without pretending a dollar amount is an integer. */
const MAX_PROMPT_CACHE_USD = 1_000_000

/**
* Validate provider-reported prompt-cache evidence.
*
* Prompt-cache carries two kinds of number and they obey different rules: token COUNTS are
* integers, and USD amounts are fractional by nature. Applying the count rule to a dollar
* field refuses every provider that reports cache savings in dollars — a healthy router
* response carrying `readSavingsUsd: 0.0034` failed the driver outright before this split.
*
* Classification is schema-first: a field named in {@link PromptCacheUsage} is validated by
* what that member IS. `promptCache` is an open record (the sandbox path forwards provider
* fields verbatim), so an unknown field falls back to the `usd` name-suffix convention —
* documented here as the contract a provider must follow to report dollars.
*
* Returns the refusal, or `undefined` when the evidence is acceptable.
*/
export function validateDriverPromptCache(
promptCache: Readonly<Record<string, number | string>> | undefined,
): ValidationError | undefined {
for (const [field, value] of Object.entries(promptCache ?? {})) {
if (typeof value !== 'number') continue
const isUsdField = PROMPT_CACHE_USD_FIELDS.has(field) || /usd$/i.test(field)
if (isUsdField) {
if (!Number.isFinite(value) || value < 0 || value > MAX_PROMPT_CACHE_USD) {
return new ValidationError(
`driverAgent: prompt-cache field ${JSON.stringify(field)} must be a non-negative finite number of dollars`,
)
}
continue
}
if (!Number.isSafeInteger(value) || value < 0) {
return new ValidationError(
`driverAgent: prompt-cache field ${JSON.stringify(field)} must be a non-negative safe integer`,
)
}
}
return undefined
}

/**
* Build the intelligent recursive driver. Its `act` is the LLM tool-loop; spawn it as a
* `driverChild` (`driver-executor.ts`) to run it inside a nested scope, recursively.
Expand Down Expand Up @@ -496,14 +543,7 @@ export function driverAgent(opts: DriverAgentOptions): Agent<unknown, unknown> {
'driverAgent: transportAttempts must be a positive safe integer when reported',
)
}
for (const [field, value] of Object.entries(res.promptCache ?? {})) {
if (typeof value === 'number' && (!Number.isSafeInteger(value) || value < 0)) {
evidenceError = new ValidationError(
`driverAgent: prompt-cache field ${JSON.stringify(field)} must be a non-negative safe integer`,
)
break
}
}
evidenceError = validateDriverPromptCache(res.promptCache) ?? evidenceError
const trustedCost =
res.costProvenance === 'provider-receipt' || res.costProvenance === 'billing-receipt'
const cacheUsage = driverPromptCacheUsage(res.usage?.input, res.promptCache)
Expand Down