/**
 * The run's usage account for the model calls made BESIDE the main loop — the compaction summarizer, the permission
 * classifier, a mod's `$.model.complete`: the lanes, what a reply tells the account, the one door a lane books through, and the
 * ONE function behind it. The lane table says which `Stats` line keeps a lane's cost besides `costMicroUsd` (every lane folds
 * into the total — it is the budget coordinate and the reported figure); it is total over the lanes by its fence, so a fourth
 * lane is a row here, not a second accounting function.
 */
import type { AssistantMessageDiagnostic, Model, Usage } from "../../internal/llm.js";
import { type ModelPricing } from "../pricing.js";
import type { AssertAllKeysHandled } from "../ask-origin.js";
import type { RunnerDeps, TaskSpec } from "../types.js";
import type { Stats } from "./assemble-result.js";
/** Whose model call it is: the compaction summarizer, the permission classifier, a mod's `$.model.complete`. */
export type SideCallLane = "compaction" | "classifier" | "mod";
/** The `Stats` line a lane's cost is also kept in: compaction is its own partition line; the classifier and the mods share the side-call line. */
export declare const SIDE_CALL_LANE_TOTAL: {
    readonly compaction: "compactionMicroUsd";
    readonly classifier: "sideCallMicroUsd";
    readonly mod: "sideCallMicroUsd";
};
export type LaneTotalCoversEverySideCallLane = AssertAllKeysHandled<Exclude<SideCallLane, keyof typeof SIDE_CALL_LANE_TOTAL>>;
/** A side call's reply as the account reads it: the provider's usage (absent ⇒ none reported), the marks of what is unknown,
 *  and the diagnostics that say a degrading brain served it from its fallback (the model that ANSWERED is the one priced). */
export interface SideCallReply {
    readonly usage?: Usage;
    readonly usageMissing?: true;
    readonly stopReason?: string;
    readonly diagnostics?: AssistantMessageDiagnostic[];
}
/** The leg's one door onto the run's usage account: every side call's reply is booked through it, once. */
export type SideCallBook = (lane: SideCallLane, model: Model, reply: SideCallReply | undefined) => void;
/** The leg's seats a side call is priced and traced on — everything the call needs that `stats` does not carry. */
export interface SideCallAccount {
    /** The run's telemetry: a call on an unpriced model taints `unpricedSpend`; the trace row goes to its tracer. */
    telemetry: {
        unpricedSpend: boolean;
        readonly tracer: TaskSpec["tracer"];
        readonly taskId: string;
    };
    /** The deployment's price table, read at the call (a swapped deps seat reaches legs already running). */
    pricing: () => RunnerDeps["pricing"];
    /** The telemetry lane's price-table door, consulted for every table a side call adopts. */
    noteUnevaluablePriceTable: (p: ModelPricing) => void;
    /** The deployment's model catalog: where the fallback model of a degraded reply is looked up. */
    catalog: RunnerDeps["models"];
}
/** What one side call tells the account beyond its usage: the model it asked, the marks of what is unknown, and — when a
 *  degrading brain served the reply from another model — that model's id. */
export interface SideCallCall {
    model: Model;
    account: SideCallAccount;
    usageMissing?: true;
    stopReason?: string;
    servedBy?: string;
}
/**
 * THE one place a model call made beside the main loop reaches the run's account: the compaction summarizer, the
 * permission classifier and a mod's `$.model.complete` all land here, each with its lane. The call is accounted exactly
 * like a main-loop call (re-priced in core from the deployment's table and the model's cache family, integer
 * micro-USD, never the brain's own `usage.cost`), so the reported total, the budget gate at the next turn end and the
 * trace agree about what the run spent. Latency and first-token time are not modeled (there are no per-delta hooks here).
 *
 * `usage` absent — the reply reported none — marks the leg's stats `usageMissing` (the totals are then a lower bound:
 * unknown is not free). A reply the brain itself marked `usageMissing` does the same for its zero-filled usage.
 */
export declare function recordSideCallUsage(stats: Stats, usage: Usage | undefined, lane: SideCallLane, call: SideCallCall): void;
/** The leg's door: `recordSideCallUsage` bound to the leg's `stats` and account, reading what the reply itself says (its marks, and who served it). */
export declare function sideCallBookOf(stats: Stats, account: SideCallAccount): SideCallBook;
