import type { EmbedResult, ImageGenResult, PromptResult } from "smoltalk"; import type { RuntimeContext } from "./state/context.js"; import type { StateStack } from "./state/stateStack.js"; import type { GraphState } from "./types.js"; type SmoltalkCost = NonNullable; type SmoltalkTokens = NonNullable; export type ProviderUsageKind = "completion" | "embedding" | "image" | "transcription" | "speech" | "decision"; export type UsageKind = ProviderUsageKind | "manual"; export type CostBreakdown = { inputCost: number; outputCost: number; cachedInputCost: number; cacheCreationInputCost: number; hostedToolsCost: number; totalCost: number; currency: "USD"; }; export type TokenBreakdown = { inputTokens: number; outputTokens: number; cachedInputTokens: number; cacheCreationInputTokens: number; totalTokens: number; }; export type UsageEntry = { kind: UsageKind; model: string; cost: CostBreakdown; tokens: TokenBreakdown; }; export type RunUsage = { /** Authoritative total. The entries are best-effort attribution. */ cost: CostBreakdown; tokens: TokenBreakdown; /** One per (kind, model). */ entries: UsageEntry[]; /** False when this figure is a trusted LOWER BOUND: a subprocess died, or a * delta arrived with its attribution lost. Separate from pricing: a * complete figure can still contain unpriced calls. */ complete: boolean; /** Calls dispatched to a provider that never resolved to a priced result. */ unpricedCallCount: number; }; export type UsageObservation = { type: "provider"; kind: ProviderUsageKind; reportedModel?: string | null; configuredModel?: string | null; cost?: SmoltalkCost | null; tokens?: SmoltalkTokens | null; } | { type: "attempt"; kind: ProviderUsageKind; } | { type: "manual"; amount: number; }; export type NormalizedDelta = { entry?: UsageEntry; cost: CostBreakdown; tokens: TokenBreakdown; unpricedCallCount: number; attributionLost: boolean; }; export type ServedInvocationOutcome = { status: "returned"; value: T; traceId: string; usage: RunUsage; debugOwner?: boolean; } | { status: "threw"; error: unknown; traceId: string; usage: RunUsage; debugOwner?: boolean; }; export type InvocationAccountingTarget = { ctx: RuntimeContext; stack: StateStack; }; /** Reconciliation tolerance for the best-effort attribution vs. the authoritative * total (relative+absolute; float ulp drift scales with magnitude). Reconciled * only when telemetry is complete; the flat total is always authoritative. */ export declare const USAGE_RECONCILE_ABS_USD = 1e-9; export declare const USAGE_RECONCILE_REL = 1e-9; export declare function usageReconcileTolerance(total: number): number; /** * The ONE closed projection of a provider's raw token usage. Every consumer of a * completion/audio usage — the invocation meter (via `recordUsage`), the branch * total (`stack.localTokens`), the global token stats, and every statelog payload * — must run raw usage through this before using it, so they all agree on the * total and none of them serialize an undeclared audio-token field. Wraps the * same `buildTokens` normalization the meter uses, so the numbers are identical * by construction. `attributionLost` is true when the total is only a lower bound * (audio counters present, no authoritative `totalTokens`). */ export declare function projectProviderTokenUsage(raw: unknown, kind?: UsageKind): { usage: TokenBreakdown; attributionLost: boolean; }; /** Turn a trusted domain observation into a normalized delta (the four * provider outcomes + manual). `attributionLost` is set only by token * malformation/saturation — never by pricing (which uses unpricedCallCount). */ export declare function normalizeObservation(observation: UsageObservation): NormalizedDelta; /** Recover a normalized delta from UNTRUSTED IPC input. Never drops * independently-valid money; a message carrying real value it cannot fully * attribute preserves the authoritative totals, omits the entry, and sets * `attributionLost` (which degrades `complete`). Returns null only when the * whole message is unusable (not an object). */ export declare function normalizeIpcUsageDelta(raw: unknown): NormalizedDelta | null; /** The accumulator for one run. A fresh run starts it at zero, and every * restore sets it to what the restored checkpoint saved (`resumeFrom`). Buckets attribution * by (kind, model) via a nested null-prototype index into `entries` (first-seen * order); keeps authoritative call-order flat totals with checked-add saturation. */ export declare class InvocationUsageMeter { private cost; private tokens; private unpricedCallCount; private complete; private entries; private index; /** Set the meter to the usage a checkpoint saved. Cost is part of a run's * state: it continues across a resume and goes back with a `restore()`, so * the figure never depends on whether the run was resumed or rewound, and it * always agrees with `getCost()`. Spend on a path that was rewound away is * not in it; a program that wants that total reads the cost before it * rewinds. The checkpoint comes back from the host, so it is recovered like * any other untrusted input: every valid figure is kept and anything * unusable makes the total a lower bound. A checkpoint with no saved usage * says nothing about what the run spent before it, which is a lower bound * too. */ resumeFrom(saved: unknown): void; /** True when every saved entry was recovered intact. */ private resumeEntries; /** Accumulate one delta. Returns true only when THIS merge newly makes usage * incomplete (via a count-overflow transition). */ merge(delta: NormalizedDelta): boolean; private entryFor; private addCostInto; private addTokensInto; /** Mark telemetry delivery no longer guaranteed complete. Idempotent; returns * true only on the first complete → incomplete transition, so a caller relays * a single upward marker. */ markIncomplete(): boolean; snapshot(): RunUsage; } /** A run's totals in the shape statelog's `agentEnd` event takes. */ export declare function tokenStatsOf(usage: RunUsage): { usage: TokenBreakdown; cost: CostBreakdown; }; /** Take a run core's outcome back to a raw value-or-throw, preserving the exact * thrown value's identity (strings, frozen objects, anything). */ export declare function unwrapServedInvocationOutcome(outcome: ServedInvocationOutcome): T; /** Unwrap like `unwrapServedInvocationOutcome`, and put the run's usage and * trace id on the returned value. A thrown outcome still throws the exact original error; its * usage does not travel with it. */ export declare function unwrapWithUsage(outcome: ServedInvocationOutcome): T & { usage: RunUsage; traceId: string; }; export {};