/** One provider's health, as tracked from real calls. */ export interface ProviderHealthSnapshot { /** The provider. */ providerName: string; /** True when it is under the failure threshold and at or above the minimum score. */ healthy: boolean; /** Successful calls recorded. */ successes: number; /** Failed calls recorded. */ failures: number; /** Failures in a row. */ consecutiveFailures: number; /** Moving average of latency, in milliseconds. */ avgLatencyMs: number; /** The most recent error, as text. */ lastError?: string; /** ISO-8601 time of the last recorded call. */ lastCheckedAt?: string; /** * From 0 to 100: 100, less 20 per consecutive failure up to 60, less 1 per second of average * latency up to 30. */ score: number; /** * `unknown` with no recent calls to judge by, `unhealthy` past the failure threshold or under the * minimum score, `degraded` when calls are failing or slow but not enough to stop routing to it, * and `healthy` otherwise. Always set by `ProviderHealthMonitor`; optional so a hand-built snapshot * still type-checks. */ status?: ProviderHealthStatus; /** True when the last call is older than `observationTtlMs`, so the figures above are old news. */ stale?: boolean; } /** Where a provider stands, by what its recent calls say. */ export type ProviderHealthStatus = 'healthy' | 'degraded' | 'unhealthy' | 'unknown'; /** Health tracking for providers, used to route around unhealthy ones. */ export interface HealthConfig { /** Turns tracking on. Off by default, and then nothing is recorded. */ enabled?: boolean; /** Consecutive failures that mark a provider unhealthy. Defaults to 3. */ failureThreshold?: number; /** Score below which a provider is unhealthy. Defaults to 20. */ minScore?: number; /** * How long a call's outcome counts, in milliseconds. A provider whose last call is older is * `unknown`, and is routed to as a provider never seen is, rather than kept down for a failure * hours ago or kept up for a success days ago. `checkProviders({ staleOnly: true })` refreshes it. * Defaults to never expiring, as before. */ observationTtlMs?: number; /** Replaces the system clock, for tests. */ now?: () => Date; } /** Tracks provider health from call outcomes and scores each provider for routing. */ export declare class ProviderHealthMonitor { private config; private states; constructor(config?: HealthConfig); private nowDate; /** Records a successful call and its latency. */ recordSuccess(providerName: string, latencyMs: number): void; /** Records a failed call. */ recordFailure(providerName: string, error: unknown): void; /** Every provider's health, or one provider's. */ snapshot(providerName?: string): ProviderHealthSnapshot[]; /** A provider's score, from 0 to 100. */ score(providerName: string): number; /** Whether a provider is healthy. */ isHealthy(providerName: string): boolean; /** Whether a provider's figures are too old to judge by, or there are none. */ isUnknown(providerName: string): boolean; private isStale; private snapshotOne; private state; }