import type { RouteCandidate, RoutePlan } from "./plan.js"; import { type InferenceAttemptError, type RouteAttemptCursor } from "./errors.js"; import type { RouteCircuitBreaker } from "./circuit-breaker.js"; export type AttemptOutcome = Readonly<{ kind: "success"; value: T; }> | Readonly<{ kind: "failure"; error: InferenceAttemptError; /** * This attempt already put output somewhere the caller cannot take it * back — tokens forwarded to a live view, or a provider-side effect a * replay would repeat. The executor then **withholds all traversal** and * propagates, because retrying re-renders a turn the user has partly seen. * * Omitted means replayable, which is right for a transport that buffers * the whole completion before returning — it has shown nobody anything * yet. Set it from the transport, at the point the first byte leaves: * a boolean the transport flips when it forwards its first delta. */ producedOutput?: boolean; }>; /** * One provider request. The host's transport adapter performs the network * call, measures duration, and classifies any failure into * `InferenceAttemptError` (transports classify facts; the executor owns * route order — PRD §7.1). */ export type AttemptFn = (candidate: RouteCandidate, cursor: RouteAttemptCursor) => Promise>; export type FallbackKind = "none" | "provider" | "model" | "provider_and_model"; export interface ExecutePlanOptions { readonly plan: RoutePlan; readonly attempt: AttemptFn; /** Stamped into cursors; the caller owns structured-output retry loops. */ readonly structuredOutputAttempt?: number; /** Same-endpoint retry budget for completion defects. Default 2 (PRD §5.2). */ readonly completionDefectRetries?: number; /** Optional per-endpoint circuit breaker (PRD §7.2). */ readonly breaker?: RouteCircuitBreaker | null; } export type RouteExecutionResult = Readonly<{ ok: true; value: T; served: RouteCandidate; cursor: RouteAttemptCursor; fallbackKind: FallbackKind; attemptCount: number; failures: readonly InferenceAttemptError[]; }> | Readonly<{ ok: false; reason: "no_viable_endpoints"; attemptCount: 0; failures: readonly []; }> | Readonly<{ ok: false; reason: "attempts_exhausted"; error: InferenceAttemptError; attemptCount: number; failures: readonly InferenceAttemptError[]; }>; /** * Drive one structured-output attempt over a frozen route plan with the * normative loop nesting (PRD §5.2): model stage → provider candidate → * same-endpoint retry. Pure with respect to I/O — every request goes through * `attempt`, every clock read through the injected breaker. */ export declare function executeRoutePlan(options: ExecutePlanOptions): Promise>; /** * Derive the fallback classification from an attempt cursor — the single * shared derivation for hosts that attribute per-attempt (e.g. inference * logging inside a transport adapter) before the executor returns. */ export declare function fallbackKindOfCursor(cursor: { readonly stageIndex: number; readonly candidateIndex: number; }): FallbackKind;