/** * kosha-discovery — Base discoverer abstraction. * * Provides shared HTTP fetching, timeout handling, and {@link ModelCard} * construction logic that every concrete provider discoverer inherits. * @module */ import type { CredentialResult, ModelCard, ProviderDiscoverer } from "../types.js"; /** Safety cap for paginated model listing. */ export declare const MAX_MODELS_PER_PROVIDER = 10000; /** * Default User-Agent sent on every discovery request. Some provider APIs * throttle or block requests with no User-Agent more aggressively, so we * always identify ourselves. Callers can override by passing their own * `user-agent` header. */ export declare const KOSHA_USER_AGENT = "kosha-discovery (+https://github.com/sriinnu/kosha-discovery)"; /** * Abstract base class for all provider discoverers. * * Subclasses only need to implement {@link discover} and set the three * readonly identity fields; the base class supplies `fetchJSON` for * HTTP calls and `makeCard` for building uniform {@link ModelCard} objects. */ export declare abstract class BaseDiscoverer implements ProviderDiscoverer { abstract readonly providerId: string; abstract readonly providerName: string; abstract readonly baseUrl: string; /** * Query the provider's API and return a list of normalized model cards. * @param credential - Resolved credential for authentication. * @param options - Optional per-request timeout override. */ abstract discover(credential: CredentialResult, options?: { timeout?: number; }): Promise; /** * Fetch JSON from a URL with timeout and automatic retry on transient errors. * * Retries up to {@link maxRetries} times with exponential backoff on: * - Network failures (fetch throws) * - Timeout / abort errors * - Server errors (HTTP 5xx) * * Client errors (4xx) are thrown immediately without retry. */ protected fetchJSON(url: string, headers?: Record, timeoutMs?: number): Promise; /** * Create a ModelCard with sensible defaults for missing fields. * * - `originProvider` defaults to `partial.provider` when not explicitly set, * which is correct for first-party providers (e.g. "anthropic" serving its * own Claude models). Aggregators like openrouter or managed services like * bedrock/vertex should pass an explicit `originProvider` to distinguish * the serving layer from the original model creator. * - `region` and `projectId` are passed through unchanged when present * (used by Bedrock and Vertex AI respectively). */ /** Validate and normalise a timeout value. Returns defaultMs when invalid. */ protected validateTimeout(timeout: number | undefined, defaultMs?: number): number; /** * Union API discovery results with the public seed for this provider. * * Merge rules per (providerId, modelId): * - **Identity wins from API.** If the API returned the model, the API * entry's metadata (name, capabilities, mode, context window) is the * authoritative description of "what this model is for this account". * - **Pricing falls back to the seed.** Native list endpoints * (`/v1/models` on Anthropic, OpenAI, Google) return *no pricing*. * The seed (models.dev primary, LiteLLM filler) does. So when the * API stub has no pricing and the seed entry does, we lift the seed's * pricing onto the API entry. * - **Seed-only models survive as filler.** Preview tiers, deprecated- * but-still-priced SKUs, region-gated entries that the API doesn't * list — keep them so consumers can still resolve historical IDs. * * Why this matters: without the pricing fallback, the same model can flip * between two different prices depending on whether `/v1/models` was * reachable when `kosha update` ran. That's a same-day-instability bug * for any downstream that locks pricing at midnight (tokmeter et al). * * Failures in fetching the seed are swallowed — the API result still * stands on its own. Pricing-degraded fallback is layered on at the * registry-runtime merge step. */ protected mergeWithPublicSeed(apiCards: ModelCard[]): Promise; protected makeCard(partial: Partial & { id: string; provider: string; }): ModelCard; } //# sourceMappingURL=base.d.ts.map