/** * Per-LLM-round timing metrics (duration / TPS / TTFT) for the agent bridge. * * Pure functions — no bridge state — so the math is unit-testable in * isolation. The bridge stamps wall-clock `Date.now()` values while * translating spectral events to wire frames (spectral's * `AssistantMessageEvent` carries no timing) and feeds them through * {@link computeTpsMetrics} when `token_usage` is emitted. * * Semantics (shared contract with the landing frontend): * - `durationMs` = tEnd(message_end) − tFirstDelta — the generation * window only, excludes time-to-first-token. * - `ttftMs` = tFirstDelta − tStart(message_start). * - `tokensPerSecond` = round(outputTokens / (durationMs / 1000), 1). * * Any metric that cannot be computed from sound inputs is `null` — * consumers must treat these fields as optional/unreliable indicators. */ /** Computed per-round timing metrics; every field may be null. */ export interface TpsMetrics { /** Generation window in ms (message_end − first streamed delta), excluding TTFT. */ durationMs: number | null; /** Output tokens per second across the generation window, rounded to 1 decimal. */ tokensPerSecond: number | null; /** Time-to-first-delta in ms (first streamed delta − message_start). */ ttftMs: number | null; } /** A wall-clock stamp that is either missing or a finite number. */ type Stamp = number | null | undefined; /** * Compute per-round timing metrics from wall-clock stamps and output token * count. Null-safe: missing stamps, negative windows (clock skew) and * non-positive token counts or durations yield `null` for the affected * fields rather than fabricated numbers. */ export declare function computeTpsMetrics(startAt: Stamp, firstDeltaAt: Stamp, endAt: Stamp, outputTokens: number | null | undefined): TpsMetrics; /** Raw per-round sums accumulated over one subagent invocation. */ export interface TpsRoundSums { /** Σ durationMs over LLM rounds with a computable generation window. */ durationMsSum: number; /** Σ outputTokens over TPS-eligible rounds (output > 0 and duration > 0). */ outputTokens: number; /** Σ durationMs over the same TPS-eligible rounds (TPS denominator). */ outputDurationMs: number; /** Σ ttftMs over rounds with a computable TTFT (mean denominator). */ ttftMsSum: number; /** Count of rounds that contributed to `ttftMsSum`. */ ttftRounds: number; /** TPS of the last round with outputTokens > 0. */ lastRoundTps: number | null; } /** Contract-shaped TPS fields derived from raw round sums. */ export interface TpsUsageFields { /** Σ durationMs (ms) over the invocation's LLM rounds. */ durationMs?: number; /** Token-weighted TPS: Σ outputTokens / Σ durationMs × 1000 (1 decimal). */ tokensPerSecond?: number; /** Arithmetic-mean TTFT (ms) across rounds with a computable TTFT. */ ttftMs?: number; /** TPS of the last round with outputTokens > 0. */ lastRoundTps?: number; } /** * Build the contract-shaped TPS fields from raw round sums. Fields that * cannot be derived from sound sums are omitted rather than zero-filled — * consumers must treat these as optional/unreliable indicators. Shared by * the subagent runner (per-result snapshot) and the agent bridge * (`subagent_end.totalUsage` token-weighted aggregation across results). */ export declare function buildTpsUsageFields(sums: TpsRoundSums): TpsUsageFields; export {}; //# sourceMappingURL=tps-metrics.d.ts.map