/** * kosha-discovery — Health-aware route ranking. * * The cheapest-model query ranks purely on price. This module layers the * runtime signal kosha already collects — per-provider circuit-breaker state * and rolling latency/timeout observations — on top of that price ranking so * callers can route by `fastest`, `reliable`, or a `balanced` blend, not just * `cheapest`. It is pure: it reads {@link RegistryState} and returns a ranked * projection, mutating nothing (in particular it never calls * `breaker.canExecute()`, which would transition open → half-open). * @module */ import type { CircuitState } from "./resilience.js"; import type { ProviderObservation, RegistryState } from "./registry-state.js"; import type { CheapestModelMatch, ModelCard } from "./types.js"; /** Selection strategy applied on top of the price-filtered candidate set. */ export type RouteStrategy = "cheapest" | "fastest" | "reliable" | "balanced"; /** All known strategies, for validation at the edges (CLI/proxy/MCP). */ export declare const ROUTE_STRATEGIES: readonly RouteStrategy[]; /** Per-provider runtime health derived from observations + breaker state. */ export interface RouteHealth { providerId: string; /** Circuit-breaker state at read time. */ breakerState: CircuitState; /** False when the breaker is open (requests are being rejected). */ available: boolean; /** 95th-percentile latency over the rolling sample window, or null. */ p95LatencyMs: number | null; /** Mean latency over the rolling sample window, or null. */ avgLatencyMs: number | null; /** Fraction of recent attempts that timed out (0..1). */ timeoutRate: number; /** Composite reliability in [0,1]; higher is better. */ reliabilityScore: number; /** Number of latency samples backing the percentile/mean. */ samples: number; /** Last normalized error class observed, if any. */ lastErrorType: ProviderObservation["lastErrorType"]; } /** A candidate route annotated with price + health + a strategy-specific score. */ export interface RankedRoute { model: ModelCard; providerId: string; /** Price score (lower is cheaper); null when the model has no usable pricing. */ price: number | null; health: RouteHealth; /** Strategy-specific rank key — lower is better. */ compositeScore: number; } /** * Compute a read-only health snapshot for one provider from the rolling * observation window and the circuit breaker. Never mutates breaker state. */ export declare function providerRouteHealth(state: RegistryState, providerId: string): RouteHealth; /** * Re-rank a price-sorted candidate set by the requested strategy. * * `cheapest` preserves the incoming price order. The other strategies fold in * per-provider health. Unavailable providers (open breaker) are always sorted * last regardless of strategy, so failover naturally prefers live providers. */ export declare function rankCandidatesByStrategy(state: RegistryState, matches: CheapestModelMatch[], strategy: RouteStrategy): RankedRoute[]; /** Parse a strategy token; returns undefined for anything unrecognized. */ export declare function parseRouteStrategy(value: string | undefined | null): RouteStrategy | undefined; //# sourceMappingURL=registry-routing.d.ts.map