Release God's Eye View as open source

This commit is contained in:
Bilawal Sidhu committed 2026-08-24 17:02:16 -05:00
1 parent a5aaea7e16
commit 880a672b5e
433 files changed
+219893 -23

No files matched your search

@@ -0,0 +1,37 @@
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import test from 'node:test';
const voiceConfig = readFileSync(new URL('../../vite.config.js', import.meta.url), 'utf8');
const realtime = readFileSync(new URL('./gevRealtime.js', import.meta.url), 'utf8');
test('aircraft identity narration acknowledges missing enrichment', () => {
const start = voiceConfig.indexOf("'For \"what is this aircraft?\" answers");
assert.ok(start >= 0, 'aircraft identity honesty instruction is missing');
const text = voiceConfig.slice(start, voiceConfig.indexOf('\n', start));
assert.match(text, /get_entity_context selected\.properties/);
assert.match(text, /callsign, operator, registration, type, and route/);
assert.match(text, /route, routeOrigin, and routeDestination as the only authoritative route fields/);
assert.match(text, /Every aircraft identity answer MUST explicitly cover operator, type, and route/);
assert.match(text, /repeat its endpoint codes exactly/);
assert.match(text, /do not expand airport codes into city names/);
assert.match(text, /"Operator details are unavailable"/);
assert.match(text, /"Aircraft type is unavailable"/);
assert.match(text, /"Route details are unavailable"/);
assert.match(text, /never silently omit missing enrichment/i);
assert.match(text, /never .* infer it from the callsign/i);
const followupStart = realtime.indexOf("if (result?.action === 'get_entity_context')");
const followupEnd = realtime.indexOf("if (result?.action === 'get_current_view_state')", followupStart);
assert.ok(followupStart >= 0 && followupEnd > followupStart, 'entity-context follow-up instruction is missing');
const followup = realtime.slice(followupStart, followupEnd);
assert.match(followup, /selectedLayerId === 'flights' \|\| selectedLayerId === 'military'/);
assert.match(followup, /Begin with the returned callsign and include the returned registration when available/);
assert.match(followup, /explicitly cover operator, aircraft type, and route before finishing/);
assert.match(followup, /selectedProperties\.operator/);
assert.match(followup, /selectedProperties\.type/);
assert.match(followup, /selectedProperties\.route \|\| selectedProperties\.routeOrigin \|\| selectedProperties\.routeDestination/);
assert.match(followup, /Operator details are unavailable/);
assert.match(followup, /Aircraft type is unavailable/);
assert.match(followup, /Route details are unavailable/);
});
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+463
View File
@@ -0,0 +1,463 @@
// src/voice/voiceCost.js
/**
* Voice model registry + Realtime session cost estimation.
*
* Pure module (no DOM, no network, no imports) so it can be shared by three
* callers that cannot share anything else:
* 1. the browser voice UI (`gevRealtime.js`) — live "~$0.42" readout + caps
* 2. the dev-server token endpoint (`vite.config.js` → `/api/realtime/token`)
* 3. unit tests (`voiceCost.test.mjs`)
*
* Two independent concerns live here:
* - MODEL TIERS: 'standard' (default) vs 'mini' (cheaper). The client asks
* for a tier by NAME; only this module maps a tier to an OpenAI model id,
* so an unknown/hostile tier string can never reach the OpenAI API.
* - SPEND GUARD: token usage → USD, with a soft warning and a hard cap.
*
* @module voice/voiceCost
*/
/* ------------------------------------------------------------------ *
* MODEL REGISTRY
* ------------------------------------------------------------------ */
/**
* ⚠️ VERIFY AT RELEASE — MODEL IDS AND PRICES ARE EXTERNAL FACTS THAT DRIFT. ⚠️
*
* Both model ids and every rate below were read from OpenAI's own model +
* pricing pages on 2026-08-18:
* - https://developers.openai.com/api/docs/models/gpt-realtime-2
* - https://developers.openai.com/api/docs/models/gpt-realtime-2.1-mini
* - https://developers.openai.com/api/docs/pricing
*
* Cross-check at release time (a wrong rate silently mis-sizes the spend cap,
* and a wrong model id fails the session at connect time):
* - `standard` MUST stay in sync with OPENAI_REALTIME_MODEL / the
* OPENAI_REALTIME_MODEL_DEFAULT constant in vite.config.js.
* - `mini` has no in-repo history — it is new here. OpenAI publishes both
* `gpt-realtime-2.1-mini` (current, used below) and an older
* `gpt-realtime-mini`; there is NO `gpt-realtime-2-mini`. If the id ever
* moves, override it with OPENAI_REALTIME_MODEL_MINI rather than editing
* code — see .env.example.
*
* Rates are USD per 1,000,000 tokens.
*/
export const VOICE_MODEL_RATES_VERIFIED_ON = '2026-08-18';
/** @typedef {'standard'|'mini'} VoiceModelTier */
export const VOICE_MODELS = Object.freeze({
standard: Object.freeze({
tier: 'standard',
id: 'gpt-realtime-2',
label: 'STANDARD',
/** USD per 1M tokens — gpt-realtime-2. */
rates: Object.freeze({
textInput: 4,
textCachedInput: 0.4,
textOutput: 24,
audioInput: 32,
audioCachedInput: 0.4,
audioOutput: 64,
imageInput: 5,
imageCachedInput: 0.5,
}),
}),
mini: Object.freeze({
tier: 'mini',
id: 'gpt-realtime-2.1-mini',
label: 'MINI',
/** USD per 1M tokens — gpt-realtime-2.1-mini (~3.2× cheaper on audio). */
rates: Object.freeze({
textInput: 0.6,
textCachedInput: 0.06,
textOutput: 2.4,
audioInput: 10,
audioCachedInput: 0.3,
audioOutput: 20,
imageInput: 0.8,
imageCachedInput: 0.08,
}),
}),
});
/** The tier used when nothing (or nonsense) was requested. */
export const DEFAULT_VOICE_TIER = 'standard';
/** Every tier name the UI and the token endpoint accept. */
export const VOICE_TIERS = Object.freeze(Object.keys(VOICE_MODELS));
/**
* Map a requested tier name to its model entry, falling back to `standard`.
*
* Deliberately total: an unknown, empty, non-string, or hostile value resolves
* to the default rather than throwing, so a bad querystring degrades to the
* normal session instead of breaking the mic. Callers that need to know a
* fallback happened compare `entry.tier` to what they asked for.
*
* @param {unknown} tier
* @returns {{tier: VoiceModelTier, id: string, label: string, rates: object}}
*/
export function resolveVoiceModel(tier) {
// Own-property check, NOT `VOICE_MODELS[key] || default`: inherited keys
// ('constructor', 'toString', '__proto__') resolve to truthy Object.prototype
// members, which would sail past a `||` fallback and hand the token endpoint
// a bogus entry whose `.id` is undefined.
return isKnownVoiceTier(tier)
? VOICE_MODELS[String(tier).trim().toLowerCase()]
: VOICE_MODELS[DEFAULT_VOICE_TIER];
}
/** True only for a tier name this build knows (own properties only). */
export function isKnownVoiceTier(tier) {
const key = typeof tier === 'string' ? tier.trim().toLowerCase() : '';
return Object.prototype.hasOwnProperty.call(VOICE_MODELS, key);
}
/**
* The priciest known rate table, derived (not hardcoded) so it stays correct if
* the registry gains a tier. Used as the conservative default whenever we do
* not recognise the model a session is actually running on.
*/
export function mostExpensiveVoiceModel() {
// Rank by audio output — the dominant cost in a speech-to-speech session.
return Object.values(VOICE_MODELS).reduce((worst, entry) =>
entry.rates.audioOutput > worst.rates.audioOutput ? entry : worst
);
}
/**
* Resolve the rate table for the model a session is ACTUALLY running on.
*
* The tier a client asked for is only a request: `OPENAI_REALTIME_MODEL` /
* `OPENAI_REALTIME_MODEL_MINI` can point a tier at any model id, so pricing by
* tier would silently mis-meter (and overrun the cap) whenever an override is
* set. Pricing by the id the server echoes back closes that gap.
*
* An unrecognised id bills at the most expensive known rates rather than
* guessing cheap — under-metering is what lets a cap be overrun.
*
* @param {unknown} modelId
* @returns {{tier: string, id: string, label: string, rates: object, recognized: boolean}}
*/
export function resolveVoiceModelById(modelId) {
const id = typeof modelId === 'string' ? modelId.trim() : '';
for (const entry of Object.values(VOICE_MODELS)) {
if (entry.id === id) return { ...entry, recognized: true };
}
const worst = mostExpensiveVoiceModel();
return {
...worst,
// Report the real model so the UI/diagnostics never claim the wrong one.
id: id || worst.id,
recognized: false,
};
}
/* ------------------------------------------------------------------ *
* SPEND GUARD CONFIG
* ------------------------------------------------------------------ */
/**
* Session spend thresholds, in USD. Deliberately generous — this is a runaway
* guard (a hot mic left open, a feedback loop), not a budget.
*
* `warnUsd`: soft — one visual cue + one console line, session continues.
* `capUsd`: hard — the session is closed through the normal stop path.
*
* Either may be null/0/Infinity to disable that threshold.
*/
export const VOICE_COST_LIMITS = Object.freeze({
warnUsd: 2,
capUsd: 5,
});
/**
* Serialized sentinel for a disabled threshold.
*
* A disabled threshold is Infinity in memory, but `JSON.stringify(Infinity)`
* is `null`, which reads back as "absent" and silently restores the DEFAULT —
* so a deliberately disabled cap would quietly re-arm on the next session.
* Persist this string instead; `normalizeCostLimits` accepts it on the way in.
*/
export const VOICE_COST_LIMIT_OFF = 'off';
/**
* Normalize a partial limits object against the defaults.
*
* Accepted "disabled" spellings: the `'off'` sentinel, Infinity, and a
* 0/negative number. Absent/undefined/null and unparseable values fall back to
* the default — a corrupt entry must never disarm the cap.
*/
export function normalizeCostLimits(limits) {
const clean = (value, fallback) => {
if (typeof value === 'string' && value.trim().toLowerCase() === VOICE_COST_LIMIT_OFF) {
return Infinity;
}
if (value === Infinity) return Infinity;
if (value === null || value === undefined) return fallback;
const n = Number(value);
if (!Number.isFinite(n)) return fallback;
return n > 0 ? n : Infinity; // 0/negative = "no threshold"
};
return Object.freeze({
warnUsd: clean(limits?.warnUsd, VOICE_COST_LIMITS.warnUsd),
capUsd: clean(limits?.capUsd, VOICE_COST_LIMITS.capUsd),
});
}
/** Convert limits to a JSON-safe shape that round-trips a disabled threshold. */
export function serializeCostLimits(limits) {
const normalized = normalizeCostLimits(limits);
const encode = (value) => (Number.isFinite(value) ? value : VOICE_COST_LIMIT_OFF);
return {
warnUsd: encode(normalized.warnUsd),
capUsd: encode(normalized.capUsd),
};
}
/* ------------------------------------------------------------------ *
* USAGE → USD
* ------------------------------------------------------------------ */
const nonNegative = (value) => {
const n = Number(value);
return Number.isFinite(n) && n > 0 ? n : 0;
};
/**
* Split one Realtime `response.done` usage object into billable token buckets.
*
* The Realtime usage shape reports per-modality detail with CACHED TOKENS
* INCLUDED in the modality totals, so uncached = modality − cached(modality).
*
* Older/partial payloads may omit `input_token_details` entirely. In that case
* the whole input is attributed to AUDIO, the most expensive modality. That
* deliberately over-estimates: for a spend cap the safe failure direction is
* stopping early, never billing past the cap because a field was missing.
*
* The same policy applies to PARTIAL detail objects, which are the subtler
* case: if `input_tokens` is 1000 but the only detail present is
* `text_tokens: 100`, the other 900 tokens are real and billed upstream.
* Counting only the named buckets would silently drop them and UNDER-meter —
* exactly the direction that lets a cap be overrun. Any aggregate-minus-details
* residual is therefore attributed to audio rates.
*
* @param {object|null|undefined} usage - `response.usage` from `response.done`.
*/
export function splitUsageTokens(usage) {
const inDetails = usage?.input_token_details || null;
const outDetails = usage?.output_token_details || null;
const cached = inDetails?.cached_tokens_details || null;
const inputTotal = nonNegative(usage?.input_tokens);
const outputTotal = nonNegative(usage?.output_tokens);
let textIn;
let audioIn;
let imageIn;
let textCached;
let audioCached;
let imageCached;
if (inDetails) {
textCached = nonNegative(cached?.text_tokens);
audioCached = nonNegative(cached?.audio_tokens);
imageCached = nonNegative(cached?.image_tokens);
// When only an aggregate `cached_tokens` is present, attribute it to audio
// (dominant modality in a voice session) so cache savings still register.
if (!cached && nonNegative(inDetails.cached_tokens) > 0) {
audioCached = Math.min(
nonNegative(inDetails.cached_tokens),
nonNegative(inDetails.audio_tokens)
);
}
textIn = Math.max(0, nonNegative(inDetails.text_tokens) - textCached);
audioIn = Math.max(0, nonNegative(inDetails.audio_tokens) - audioCached);
imageIn = Math.max(0, nonNegative(inDetails.image_tokens) - imageCached);
} else {
// No detail — conservative all-audio attribution (see note above).
textIn = 0;
audioIn = inputTotal;
imageIn = 0;
textCached = 0;
audioCached = 0;
imageCached = 0;
}
// Residual = billed tokens the detail buckets did not account for. Attributed
// to audio (priciest) so a partial payload over-estimates, never under.
const inputResidual = Math.max(
0,
inputTotal - (textIn + audioIn + imageIn + textCached + audioCached + imageCached)
);
audioIn += inputResidual;
const textOut = outDetails ? nonNegative(outDetails.text_tokens) : 0;
let audioOut = outDetails ? nonNegative(outDetails.audio_tokens) : outputTotal;
const outputResidual = Math.max(0, outputTotal - (textOut + audioOut));
audioOut += outputResidual;
return {
textIn,
audioIn,
imageIn,
textCached,
audioCached,
imageCached,
textOut,
audioOut,
inputTotal,
outputTotal,
};
}
/**
* Estimate the USD cost of one Realtime response's usage.
*
* @param {object|null|undefined} usage - `response.usage` from `response.done`.
* @param {object} rates - a `VOICE_MODELS[tier].rates` table (USD per 1M).
* @returns {number} USD, always finite and >= 0.
*/
export function estimateUsageCostUsd(usage, rates) {
if (!usage || !rates) return 0;
const t = splitUsageTokens(usage);
const usd =
(t.textIn * nonNegative(rates.textInput) +
t.textCached * nonNegative(rates.textCachedInput) +
t.textOut * nonNegative(rates.textOutput) +
t.audioIn * nonNegative(rates.audioInput) +
t.audioCached * nonNegative(rates.audioCachedInput) +
t.audioOut * nonNegative(rates.audioOutput) +
t.imageIn * nonNegative(rates.imageInput) +
t.imageCached * nonNegative(rates.imageCachedInput)) /
1_000_000;
return Number.isFinite(usd) && usd > 0 ? usd : 0;
}
/** Format a running cost for the compact UI readout ("~$0.42"). */
export function formatCostUsd(usd) {
const n = Number.isFinite(Number(usd)) ? Math.max(0, Number(usd)) : 0;
if (n > 0 && n < 0.01) return '~$0.01';
return `~$${n.toFixed(2)}`;
}
/* ------------------------------------------------------------------ *
* SESSION COST TRACKER (state machine)
* ------------------------------------------------------------------ */
/**
* Accumulate per-response usage into a running session cost and latch the two
* threshold crossings.
*
* `response.done` usage is PER RESPONSE, not cumulative, so responses sum.
*
* Both crossings are independent one-shot latches: each fires on the first
* `record()` that carries the total at or past its threshold and never again,
* so one warning line is logged and the cap stop is requested exactly once —
* even though `record()` keeps being called while the session tears down.
*
* The model binding is fixed at construction and never changes: a tracker
* belongs to exactly one session, priced against the model that session is
* actually running on. Pass `modelId` (the id the server echoed back) when it
* is known — it outranks `tier`, because an env override can point a tier at a
* different model. `tier` alone is only used before a session exists.
*
* @param {{tier?: string, modelId?: string,
* limits?: {warnUsd?: number, capUsd?: number}}} [options]
*/
export function createVoiceCostTracker(options = {}) {
const model = options.modelId
? resolveVoiceModelById(options.modelId)
: { ...resolveVoiceModel(options.tier), recognized: true };
const limits = normalizeCostLimits(options.limits);
let totalUsd = 0;
let responses = 0;
let warned = false;
let capped = false;
let incomplete = false;
const snapshot = (warnCrossed = false, capCrossed = false) => ({
tier: model.tier,
modelId: model.id,
/** False when the model was unrecognised and billed at worst-case rates. */
ratesRecognized: model.recognized !== false,
totalUsd,
responses,
warnUsd: limits.warnUsd,
capUsd: limits.capUsd,
/** 'ok' | 'warn' | 'cap' — monotonic; never steps back down. */
level: capped ? 'cap' : warned ? 'warn' : 'ok',
/** True only on the single record() that crossed the soft threshold. */
warnCrossed,
/** True only on the single record() that crossed the hard cap. */
capCrossed,
/** True once the cap is latched — the session must be stopped. */
capReached: capped,
/**
* True when at least one billed response never reported usage (the session
* was torn down mid-response), so the accounting is PARTIAL.
*
* Deliberately not called a lower bound: the estimate can also run high
* (residuals and unknown models bill at worst-case rates, and sub-cent
* totals round up), so the total is neither a guaranteed floor nor a
* guaranteed ceiling — just incomplete. We have no token telemetry for an
* unfinished response and do not invent one.
*/
incomplete,
/** Compact chip text. The '*' is a see-note mark, NOT a direction claim. */
display: formatCostUsd(totalUsd) + (incomplete ? '*' : ''),
/** Prose for the tooltip; null when the accounting is complete. */
note: incomplete
? 'Estimate is incomplete — a response was still in flight when the session ended, so its usage was never reported.'
: null,
});
return {
model,
limits,
/**
* Fold one response's usage into the session total.
* @param {object} usage - `response.usage`
*/
record(usage) {
const usd = estimateUsageCostUsd(usage, model.rates);
if (usd > 0) {
totalUsd += usd;
responses += 1;
}
let warnCrossed = false;
let capCrossed = false;
if (!warned && totalUsd >= limits.warnUsd) {
warned = true;
warnCrossed = true;
}
if (!capped && totalUsd >= limits.capUsd) {
capped = true;
capCrossed = true;
}
return snapshot(warnCrossed, capCrossed);
},
/** Current state without folding in new usage. */
state: () => snapshot(),
/**
* Record that a billed response will never report its usage (torn down
* mid-response). Flags the accounting as incomplete rather than
* fabricating a token count for it.
*/
markIncomplete() {
incomplete = true;
return snapshot();
},
/** Reset for a new session (same model/limits). */
reset() {
totalUsd = 0;
responses = 0;
warned = false;
capped = false;
incomplete = false;
return snapshot();
},
};
}
+614
View File
@@ -0,0 +1,614 @@
// src/voice/voiceCost.test.mjs
// The spend guard is the only thing standing between a hot mic and an
// open-ended bill, so its arithmetic, its threshold latches, and its
// unknown-tier fallback are all pinned here. The tier resolver is also a
// security boundary: it is what stops an arbitrary string reaching the
// OpenAI API as a model id.
import { test } from 'node:test';
import assert from 'node:assert/strict';
import {
DEFAULT_VOICE_TIER,
VOICE_COST_LIMIT_OFF,
VOICE_COST_LIMITS,
VOICE_MODELS,
VOICE_TIERS,
createVoiceCostTracker,
estimateUsageCostUsd,
formatCostUsd,
isKnownVoiceTier,
mostExpensiveVoiceModel,
normalizeCostLimits,
resolveVoiceModel,
resolveVoiceModelById,
serializeCostLimits,
splitUsageTokens,
} from './voiceCost.js';
/** A representative `response.done` usage payload with full modality detail. */
const FULL_USAGE = Object.freeze({
total_tokens: 1500,
input_tokens: 1000,
output_tokens: 500,
input_token_details: {
cached_tokens: 200,
text_tokens: 400,
audio_tokens: 600,
image_tokens: 0,
cached_tokens_details: { text_tokens: 100, audio_tokens: 100, image_tokens: 0 },
},
output_token_details: { text_tokens: 100, audio_tokens: 400 },
});
/**
* Usage worth exactly $`usd` on the STANDARD rate table: audio output is
* $64/1M, so 15,625 audio-output tokens == $1.00 exactly.
*/
const dollarsOfUsage = (usd) => ({
input_tokens: 0,
output_tokens: 15625 * usd,
output_token_details: { text_tokens: 0, audio_tokens: 15625 * usd },
});
/* -------------------------------------------------------------- *
* model registry / tier resolution
* -------------------------------------------------------------- */
test('registry exposes exactly the two tiers the UI offers', () => {
assert.deepEqual([...VOICE_TIERS].sort(), ['mini', 'standard']);
assert.equal(DEFAULT_VOICE_TIER, 'standard');
});
test('standard tier still points at the model vite.config.js defaults to', () => {
// If this fails, the client cost estimate is being computed against a
// different model than the session actually runs on.
assert.equal(VOICE_MODELS.standard.id, 'gpt-realtime-2');
});
test('mini tier uses a published mini model id, not a guessed -2-mini variant', () => {
assert.equal(VOICE_MODELS.mini.id, 'gpt-realtime-2.1-mini');
assert.notEqual(VOICE_MODELS.mini.id, VOICE_MODELS.standard.id);
});
test('mini is cheaper than standard on every single rate', () => {
const std = VOICE_MODELS.standard.rates;
const mini = VOICE_MODELS.mini.rates;
const keys = Object.keys(std);
assert.ok(keys.length >= 8, 'rate table covers text/audio/image in+cached+out');
for (const key of keys) {
assert.ok(
mini[key] < std[key],
`mini.${key} (${mini[key]}) should undercut standard.${key} (${std[key]})`
);
}
});
test('resolveVoiceModel returns the requested tier', () => {
assert.equal(resolveVoiceModel('mini').id, 'gpt-realtime-2.1-mini');
assert.equal(resolveVoiceModel('standard').id, 'gpt-realtime-2');
});
test('resolveVoiceModel tolerates case and whitespace', () => {
assert.equal(resolveVoiceModel(' MINI ').tier, 'mini');
assert.equal(resolveVoiceModel('Standard').tier, 'standard');
});
test('unknown, empty, and hostile tiers fall back to standard rather than throwing', () => {
// This is the guard that keeps an arbitrary querystring out of the OpenAI
// model field. Every one of these must resolve, never throw.
for (const bad of [
undefined,
null,
'',
' ',
'gpt-4o',
'MINI; DROP',
'constructor',
'toString',
'__proto__',
42,
{},
[],
true,
]) {
const resolved = resolveVoiceModel(bad);
assert.equal(resolved.tier, 'standard', `fallback for ${JSON.stringify(bad)}`);
assert.equal(resolved.id, 'gpt-realtime-2');
}
});
test('isKnownVoiceTier separates real tiers from fallbacks', () => {
assert.equal(isKnownVoiceTier('mini'), true);
assert.equal(isKnownVoiceTier('standard'), true);
assert.equal(isKnownVoiceTier('__proto__'), false);
assert.equal(isKnownVoiceTier('turbo'), false);
assert.equal(isKnownVoiceTier(undefined), false);
});
/* -------------------------------------------------------------- *
* usage splitting
* -------------------------------------------------------------- */
test('cached tokens are subtracted out of their modality totals', () => {
const t = splitUsageTokens(FULL_USAGE);
assert.equal(t.textIn, 300); // 400 text - 100 cached text
assert.equal(t.audioIn, 500); // 600 audio - 100 cached audio
assert.equal(t.textCached, 100);
assert.equal(t.audioCached, 100);
assert.equal(t.textOut, 100);
assert.equal(t.audioOut, 400);
});
test('uncached buckets never go negative when cached exceeds the modality total', () => {
const t = splitUsageTokens({
input_tokens: 100,
input_token_details: {
text_tokens: 50,
audio_tokens: 50,
cached_tokens_details: { text_tokens: 999, audio_tokens: 999 },
},
});
assert.equal(t.textIn, 0);
assert.equal(t.audioIn, 0);
});
test('missing input detail attributes input to audio (over-estimate, never under)', () => {
// Safe failure direction: a cap should stop early, not bill past itself
// because a payload field was absent.
const t = splitUsageTokens({ input_tokens: 800, output_tokens: 200 });
assert.equal(t.audioIn, 800);
assert.equal(t.textIn, 0);
assert.equal(t.audioOut, 200);
});
test('an aggregate cached_tokens without per-modality detail still earns the cache rate', () => {
const t = splitUsageTokens({
input_tokens: 1000,
input_token_details: { cached_tokens: 300, text_tokens: 0, audio_tokens: 1000 },
});
assert.equal(t.audioCached, 300);
assert.equal(t.audioIn, 700);
});
test('F2: a partial input detail attributes the unexplained residual to audio', () => {
// input_tokens says 1000; the details only explain 100. The other 900 are
// real and billed upstream — dropping them under-meters, which is the
// direction that lets a cap be overrun.
const t = splitUsageTokens({
input_tokens: 1000,
input_token_details: { text_tokens: 100 },
});
assert.equal(t.textIn, 100);
assert.equal(t.audioIn, 900, 'residual billed at audio rates');
});
test('F2: a partial output detail attributes its residual to audio too', () => {
const t = splitUsageTokens({
output_tokens: 500,
output_token_details: { text_tokens: 50 },
});
assert.equal(t.textOut, 50);
assert.equal(t.audioOut, 450);
});
test('F2: a fully-explained payload gains no phantom residual', () => {
const t = splitUsageTokens(FULL_USAGE);
assert.equal(t.textIn + t.audioIn + t.imageIn + t.textCached + t.audioCached + t.imageCached, 1000);
assert.equal(t.audioIn, 500, 'unchanged — nothing was unexplained');
});
test('F2: every billed token is accounted for across partial fixtures', () => {
const fixtures = [
{ input_tokens: 1000, input_token_details: { text_tokens: 100 } },
{ input_tokens: 800, input_token_details: { audio_tokens: 200 } },
{ input_tokens: 640, input_token_details: { text_tokens: 40, image_tokens: 100 } },
{ input_tokens: 500, input_token_details: { cached_tokens: 100, text_tokens: 50 } },
{ output_tokens: 900, output_token_details: { text_tokens: 100 } },
{ input_tokens: 300, output_tokens: 200 },
];
for (const usage of fixtures) {
const t = splitUsageTokens(usage);
const inputSum = t.textIn + t.audioIn + t.imageIn + t.textCached + t.audioCached + t.imageCached;
const outputSum = t.textOut + t.audioOut;
assert.ok(
inputSum >= (usage.input_tokens || 0),
`input accounted (${inputSum} >= ${usage.input_tokens || 0}) for ${JSON.stringify(usage)}`
);
assert.ok(
outputSum >= (usage.output_tokens || 0),
`output accounted (${outputSum} >= ${usage.output_tokens || 0}) for ${JSON.stringify(usage)}`
);
}
});
test('F2: a partial payload never costs LESS than the same tokens fully described', () => {
// The stated policy is over-estimate-on-uncertainty. Compare a partial
// payload against the cheapest honest reading of the same totals (all text).
const rates = VOICE_MODELS.standard.rates;
const partial = { input_tokens: 1000, input_token_details: { text_tokens: 100 } };
const allTextTruth = {
input_tokens: 1000,
input_token_details: { text_tokens: 1000 },
};
assert.ok(
estimateUsageCostUsd(partial, rates) >= estimateUsageCostUsd(allTextTruth, rates),
'uncertainty resolves upward, never downward'
);
});
test('splitUsageTokens survives junk without throwing', () => {
for (const junk of [null, undefined, {}, { input_tokens: 'abc' }, { input_tokens: -5 }]) {
const t = splitUsageTokens(junk);
for (const value of Object.values(t)) {
assert.ok(Number.isFinite(value) && value >= 0, `finite non-negative: ${value}`);
}
}
});
/* -------------------------------------------------------------- *
* cost arithmetic
* -------------------------------------------------------------- */
test('standard cost is the exact sum of tokens x per-1M rates', () => {
// 300*4 + 100*0.4 + 100*24 + 500*32 + 100*0.4 + 400*64 = 45,280 / 1e6
const usd = estimateUsageCostUsd(FULL_USAGE, VOICE_MODELS.standard.rates);
assert.ok(Math.abs(usd - 0.04528) < 1e-9, `expected 0.04528, got ${usd}`);
});
test('mini cost is the exact sum on the mini table', () => {
// 300*0.6 + 100*0.06 + 100*2.4 + 500*10 + 100*0.3 + 400*20 = 13,456 / 1e6
const usd = estimateUsageCostUsd(FULL_USAGE, VOICE_MODELS.mini.rates);
assert.ok(Math.abs(usd - 0.013456) < 1e-9, `expected 0.013456, got ${usd}`);
});
test('the same session costs materially less on mini', () => {
const std = estimateUsageCostUsd(FULL_USAGE, VOICE_MODELS.standard.rates);
const mini = estimateUsageCostUsd(FULL_USAGE, VOICE_MODELS.mini.rates);
assert.ok(mini < std / 3, `mini ${mini} should be <1/3 of standard ${std}`);
});
test('image input tokens are billed', () => {
// Viewport screenshots are the priciest recurring item; they must not be free.
const withImage = {
input_tokens: 1000,
input_token_details: { text_tokens: 0, audio_tokens: 0, image_tokens: 1000 },
};
const usd = estimateUsageCostUsd(withImage, VOICE_MODELS.standard.rates);
assert.ok(Math.abs(usd - 0.005) < 1e-9, `1000 image tokens @ $5/1M = $0.005, got ${usd}`);
});
test('absent usage or rates cost nothing rather than NaN', () => {
assert.equal(estimateUsageCostUsd(null, VOICE_MODELS.standard.rates), 0);
assert.equal(estimateUsageCostUsd(FULL_USAGE, null), 0);
assert.equal(estimateUsageCostUsd({}, VOICE_MODELS.standard.rates), 0);
});
test('the $1 test fixture really is $1 on standard rates', () => {
const usd = estimateUsageCostUsd(dollarsOfUsage(1), VOICE_MODELS.standard.rates);
assert.ok(Math.abs(usd - 1) < 1e-9, `expected 1, got ${usd}`);
});
/* -------------------------------------------------------------- *
* display formatting
* -------------------------------------------------------------- */
test('cost readout formats to two decimals with a tilde', () => {
assert.equal(formatCostUsd(0), '~$0.00');
assert.equal(formatCostUsd(0.42), '~$0.42');
assert.equal(formatCostUsd(12.5), '~$12.50');
});
test('a nonzero but sub-cent cost never displays as $0.00', () => {
// "$0.00" while tokens are burning reads as broken/free.
assert.equal(formatCostUsd(0.0004), '~$0.01');
});
test('formatCostUsd clamps junk to zero', () => {
assert.equal(formatCostUsd(NaN), '~$0.00');
assert.equal(formatCostUsd(-3), '~$0.00');
assert.equal(formatCostUsd(undefined), '~$0.00');
});
/* -------------------------------------------------------------- *
* limits config
* -------------------------------------------------------------- */
test('default limits are generous and ordered warn < cap', () => {
assert.equal(VOICE_COST_LIMITS.warnUsd, 2);
assert.equal(VOICE_COST_LIMITS.capUsd, 5);
assert.ok(VOICE_COST_LIMITS.warnUsd < VOICE_COST_LIMITS.capUsd);
});
test('normalizeCostLimits fills gaps from the defaults', () => {
assert.deepEqual(normalizeCostLimits({ warnUsd: 1 }), { warnUsd: 1, capUsd: 5 });
assert.deepEqual(normalizeCostLimits({}), { warnUsd: 2, capUsd: 5 });
assert.deepEqual(normalizeCostLimits(null), { warnUsd: 2, capUsd: 5 });
});
test('zero or negative thresholds mean "disabled", not "stop immediately"', () => {
// A stored 0 must never brick the mic by capping at the first token.
const limits = normalizeCostLimits({ warnUsd: 0, capUsd: -1 });
assert.equal(limits.warnUsd, Infinity);
assert.equal(limits.capUsd, Infinity);
const tracker = createVoiceCostTracker({ limits });
const state = tracker.record(dollarsOfUsage(100));
assert.equal(state.capReached, false);
assert.equal(state.level, 'ok');
});
test('unparseable thresholds fall back to defaults', () => {
assert.deepEqual(normalizeCostLimits({ warnUsd: 'abc', capUsd: 'xyz' }), {
warnUsd: 2,
capUsd: 5,
});
});
/* -------------------------------------------------------------- *
* tracker state machine
* -------------------------------------------------------------- */
test('a fresh tracker starts at zero and ok', () => {
const tracker = createVoiceCostTracker({ tier: 'standard' });
const state = tracker.state();
assert.equal(state.totalUsd, 0);
assert.equal(state.level, 'ok');
assert.equal(state.capReached, false);
assert.equal(state.display, '~$0.00');
assert.equal(state.responses, 0);
});
test('per-response usage accumulates across the session', () => {
const tracker = createVoiceCostTracker({ tier: 'standard' });
tracker.record(dollarsOfUsage(1));
const state = tracker.record(dollarsOfUsage(1));
assert.ok(Math.abs(state.totalUsd - 2) < 1e-9);
assert.equal(state.responses, 2);
});
test('the warning fires exactly once, on the crossing record', () => {
const tracker = createVoiceCostTracker({ tier: 'standard', limits: { warnUsd: 2, capUsd: 5 } });
assert.equal(tracker.record(dollarsOfUsage(1)).warnCrossed, false); // $1
const crossing = tracker.record(dollarsOfUsage(1)); // $2 — crosses
assert.equal(crossing.warnCrossed, true);
assert.equal(crossing.level, 'warn');
assert.equal(tracker.record(dollarsOfUsage(1)).warnCrossed, false); // $3 — latched
});
test('the cap fires exactly once and latches capReached', () => {
const tracker = createVoiceCostTracker({ tier: 'standard', limits: { warnUsd: 2, capUsd: 5 } });
for (let i = 0; i < 4; i += 1) {
assert.equal(tracker.record(dollarsOfUsage(1)).capCrossed, false);
}
const crossing = tracker.record(dollarsOfUsage(1)); // $5 — crosses
assert.equal(crossing.capCrossed, true);
assert.equal(crossing.capReached, true);
assert.equal(crossing.level, 'cap');
// Usage keeps arriving while the session tears down; the stop must not
// be requested a second time.
const after = tracker.record(dollarsOfUsage(1));
assert.equal(after.capCrossed, false);
assert.equal(after.capReached, true);
assert.equal(after.level, 'cap');
});
test('one huge response crosses both thresholds on the same record', () => {
const tracker = createVoiceCostTracker({ tier: 'standard', limits: { warnUsd: 2, capUsd: 5 } });
const state = tracker.record(dollarsOfUsage(50));
assert.equal(state.warnCrossed, true);
assert.equal(state.capCrossed, true);
assert.equal(state.level, 'cap');
});
test('level is monotonic — it never steps back down', () => {
const tracker = createVoiceCostTracker({ tier: 'standard', limits: { warnUsd: 2, capUsd: 5 } });
tracker.record(dollarsOfUsage(6));
assert.equal(tracker.state().level, 'cap');
tracker.record({}); // a zero-cost response
assert.equal(tracker.state().level, 'cap');
assert.equal(tracker.state().capReached, true);
});
test('exact-threshold equality counts as crossed', () => {
const tracker = createVoiceCostTracker({ tier: 'standard', limits: { warnUsd: 1, capUsd: 2 } });
assert.equal(tracker.record(dollarsOfUsage(1)).warnCrossed, true);
});
test('zero-cost responses do not advance the response counter', () => {
const tracker = createVoiceCostTracker({ tier: 'standard' });
const state = tracker.record({});
assert.equal(state.responses, 0);
assert.equal(state.totalUsd, 0);
});
test('the mini tracker takes far longer to reach the same cap', () => {
// Concrete statement of the feature's point: same traffic, same cap,
// mini survives where standard trips.
const heavy = FULL_USAGE;
const std = createVoiceCostTracker({ tier: 'standard', limits: { warnUsd: 2, capUsd: 5 } });
const mini = createVoiceCostTracker({ tier: 'mini', limits: { warnUsd: 2, capUsd: 5 } });
let stdTurns = 0;
let miniTurns = 0;
while (!std.state().capReached && stdTurns < 100000) {
std.record(heavy);
stdTurns += 1;
}
while (!mini.state().capReached && miniTurns < 100000) {
mini.record(heavy);
miniTurns += 1;
}
assert.ok(miniTurns > stdTurns * 3, `mini ${miniTurns} turns vs standard ${stdTurns}`);
});
test('the tracker reports the model it is charging against', () => {
const tracker = createVoiceCostTracker({ tier: 'mini' });
const state = tracker.state();
assert.equal(state.tier, 'mini');
assert.equal(state.modelId, 'gpt-realtime-2.1-mini');
});
test('an unknown tier tracks at standard rates rather than free', () => {
// Charging $0 for an unrecognised tier would silently disable the cap.
const tracker = createVoiceCostTracker({ tier: 'nonsense' });
assert.equal(tracker.state().tier, 'standard');
assert.ok(tracker.record(FULL_USAGE).totalUsd > 0);
});
/* -------------------------------------------------------------- *
* F3 — pricing by the model actually served, not the tier requested
* -------------------------------------------------------------- */
test('F3: a known model id resolves to its own rate table', () => {
assert.equal(resolveVoiceModelById('gpt-realtime-2').tier, 'standard');
assert.equal(resolveVoiceModelById('gpt-realtime-2.1-mini').tier, 'mini');
assert.equal(resolveVoiceModelById('gpt-realtime-2').recognized, true);
});
test('F3: an unrecognised model id bills at the most expensive known rates', () => {
const resolved = resolveVoiceModelById('some-future-model');
assert.equal(resolved.recognized, false);
assert.deepEqual(resolved.rates, mostExpensiveVoiceModel().rates);
// The real id is still reported, so diagnostics never claim the wrong model.
assert.equal(resolved.id, 'some-future-model');
});
test('F3: empty/garbage model ids still produce a usable worst-case entry', () => {
for (const bad of [null, undefined, '', ' ', 42, {}]) {
const resolved = resolveVoiceModelById(bad);
assert.equal(resolved.recognized, false);
assert.ok(resolved.rates.audioOutput > 0);
}
});
test('F3: the most expensive model is derived from the registry, not hardcoded', () => {
const worst = mostExpensiveVoiceModel();
for (const entry of Object.values(VOICE_MODELS)) {
assert.ok(entry.rates.audioOutput <= worst.rates.audioOutput);
}
});
test('F3: modelId outranks tier when both are supplied', () => {
// The env override case: tier says mini, the server actually served standard.
const tracker = createVoiceCostTracker({ tier: 'mini', modelId: 'gpt-realtime-2' });
assert.equal(tracker.state().modelId, 'gpt-realtime-2');
assert.equal(tracker.state().tier, 'standard');
});
test('F3: pricing by tier alone would have under-metered an overridden session', () => {
// Concrete statement of the bug: same usage, tier-priced vs actually-served.
const byTier = createVoiceCostTracker({ tier: 'mini' });
const byModel = createVoiceCostTracker({ tier: 'mini', modelId: 'gpt-realtime-2' });
const tierCost = byTier.record(FULL_USAGE).totalUsd;
const realCost = byModel.record(FULL_USAGE).totalUsd;
assert.ok(realCost > tierCost * 3, `real ${realCost} vs tier-assumed ${tierCost}`);
});
/* -------------------------------------------------------------- *
* F6 — disabled thresholds must survive serialization
* -------------------------------------------------------------- */
test('F6: serializeCostLimits encodes a disabled threshold as a sentinel', () => {
const encoded = serializeCostLimits({ warnUsd: 0, capUsd: 0 });
assert.equal(encoded.warnUsd, VOICE_COST_LIMIT_OFF);
assert.equal(encoded.capUsd, VOICE_COST_LIMIT_OFF);
// The whole point: it must survive JSON, unlike Infinity -> null.
assert.equal(JSON.parse(JSON.stringify(encoded)).capUsd, VOICE_COST_LIMIT_OFF);
});
test('F6: the sentinel normalizes back to a disabled threshold', () => {
const limits = normalizeCostLimits({ warnUsd: 'off', capUsd: 'OFF' });
assert.equal(limits.warnUsd, Infinity);
assert.equal(limits.capUsd, Infinity);
});
test('F6: JSON round-trip preserves disabled, live, and mixed limits', () => {
for (const input of [
{ warnUsd: 0, capUsd: 0 },
{ warnUsd: 2, capUsd: 5 },
{ warnUsd: 0, capUsd: 5 },
{ warnUsd: 1.5, capUsd: 0 },
]) {
const expected = normalizeCostLimits(input);
const restored = normalizeCostLimits(
JSON.parse(JSON.stringify(serializeCostLimits(input)))
);
assert.deepEqual(restored, expected, `round-trip of ${JSON.stringify(input)}`);
}
});
test('F6: a raw Infinity (pre-sentinel data) is still honoured on read', () => {
assert.equal(normalizeCostLimits({ capUsd: Infinity }).capUsd, Infinity);
});
test('markIncomplete flags the accounting as partial, without a direction claim', () => {
// A response torn down mid-flight never reports usage. We have no token
// telemetry for it, so we mark the accounting incomplete rather than invent
// a number for a user-visible dollar figure.
const tracker = createVoiceCostTracker({ tier: 'standard' });
tracker.record(dollarsOfUsage(1));
assert.equal(tracker.state().incomplete, false);
assert.equal(tracker.state().display, '~$1.00');
assert.equal(tracker.state().note, null);
tracker.markIncomplete();
assert.equal(tracker.state().incomplete, true);
assert.equal(tracker.state().display, '~$1.00*');
assert.match(tracker.state().note, /incomplete/i);
});
test('the incomplete marker never claims the total is a minimum', () => {
// The estimate can run HIGH too — residuals and unknown models bill at
// worst-case rates, and sub-cent totals round up — so "at least"/floor
// wording would overpromise. Pinned so the copy cannot regress to '+'.
const tracker = createVoiceCostTracker({ tier: 'standard' });
tracker.record(dollarsOfUsage(1));
tracker.markIncomplete();
const { display, note } = tracker.state();
assert.ok(!display.includes('+'), `no floor marker in ${display}`);
assert.doesNotMatch(note, /at least|lower bound|minimum|floor|no less than/i);
});
test('the over-estimate paths that make a floor claim wrong are real', () => {
// Demonstrates the premise: worst-case rates for an unknown model exceed the
// cheapest known model's, so the estimate is not bounded below by truth.
const unknown = createVoiceCostTracker({ modelId: 'not-a-real-model' });
const cheapest = createVoiceCostTracker({ modelId: VOICE_MODELS.mini.id });
assert.ok(
unknown.record(dollarsOfUsage(1)).totalUsd > cheapest.record(dollarsOfUsage(1)).totalUsd,
'an unknown model is billed above the cheapest real one'
);
assert.equal(formatCostUsd(0.0001), '~$0.01', 'sub-cent totals round UP');
});
test('marking incomplete does not change the accrued total', () => {
const tracker = createVoiceCostTracker({ tier: 'standard' });
tracker.record(dollarsOfUsage(2));
tracker.markIncomplete();
assert.ok(Math.abs(tracker.state().totalUsd - 2) < 1e-9);
});
test('an incomplete total still trips the cap on the tokens we did see', () => {
const tracker = createVoiceCostTracker({ tier: 'standard', limits: { warnUsd: 2, capUsd: 5 } });
tracker.markIncomplete();
const state = tracker.record(dollarsOfUsage(6));
assert.equal(state.capReached, true);
assert.equal(state.incomplete, true);
});
test('reset clears the incomplete marker for the next session', () => {
const tracker = createVoiceCostTracker({ tier: 'standard' });
tracker.record(dollarsOfUsage(1));
tracker.markIncomplete();
const cleared = tracker.reset();
assert.equal(cleared.incomplete, false);
assert.equal(cleared.display, '~$0.00');
});
test('reset clears totals and re-arms both latches for a new session', () => {
const tracker = createVoiceCostTracker({ tier: 'standard', limits: { warnUsd: 2, capUsd: 5 } });
tracker.record(dollarsOfUsage(9));
assert.equal(tracker.state().capReached, true);
const cleared = tracker.reset();
assert.equal(cleared.totalUsd, 0);
assert.equal(cleared.level, 'ok');
assert.equal(cleared.capReached, false);
assert.equal(tracker.record(dollarsOfUsage(2)).warnCrossed, true);
});