/** * execution-poll-cost.ts — the bill on an execution report's poll block. * * A transport states what the provider charged as `VideoExecutionPollResult. * actualCost`; this module carries it onto `report.poll` unchanged, and for a * per-scene candidate poll sums the scenes' bills into one — stated only when * EVERY completed scene stated one in ONE currency, because a partial sum * would read as the whole bill. Extracted from execution-status.ts (which sits * at the module-size ceiling) so the rule lives in one small, testable place. */ import type { VideoExecutionPollResult, VideoExecutionReport } from './types.js'; export type ExecutionBill = NonNullable; export interface JobCostAggregate { /** * Record a COMPLETED provider JOB's poll, once per job. A transport's * `actualCost` is the whole job's bill (every scene it carried), so a job * shared by several scenes is added once, never once per scene. A poll * without a bill still counts as a completed job. */ add(poll: Pick): void; /** The summed bill, or undefined when any completed job stated none or the currencies differ. */ total(): ExecutionBill | undefined; /** Why `total()` is undefined although at least one bill was stated; undefined when nothing was dropped. */ droppedReason(): string | undefined; } export declare function createJobCostAggregate(): JobCostAggregate; /** * Poll a provider job at most once per pass. Several scenes can share one job * (execute.ts gives every task of a submission the same externalJobId), and a * transport's `actualCost` is that whole job's bill, so the second scene reuses * the first scene's answer instead of asking the provider again and counting * the bill twice. A failed poll is memoised too, so every scene on that job * reports the same failure. On the first sight of a completed job its bill is * added to `costs`. */ export declare function pollJobOnce(memo: Map, jobId: string, costs: JobCostAggregate, poll: () => Promise): Promise<{ result: VideoExecutionPollResult | Error; first: boolean; }>; /** * True when this status check would only repeat what the report already * recorded: the same job, already terminal with the same status. A repeated * `execute-status` on a finished job must not append another telemetry event * carrying the same bill — the preview portal sums `cost.usd` across events. * * Invariant this leans on: `execute.ts` builds a FRESH report for every * submission and never carries a previous `poll` block forward, so a * non-pending `previous` always belongs to `previousJobId`. A front door that * ever preserved `poll` across submissions would have to stamp the job id into * the block, or this guard would suppress a second job's first bill. */ export declare function pollTelemetryAlreadyRecorded(previous: VideoExecutionReport['poll'] | undefined, previousJobId: string | null | undefined, next: { status: VideoExecutionPollResult['status']; externalJobId: string | null; }): boolean; /** The report's poll block from a poll result: status, issues, ingested count, raw result, and the bill when stated. */ export declare function reportPollBlock(input: { lastCheckedAt: string; status: VideoExecutionPollResult['status']; issues: string[]; outputsIngested?: number; rawResult: unknown; actualCost?: ExecutionBill; }): NonNullable; //# sourceMappingURL=execution-poll-cost.d.ts.map