import type { Api, Model } from "@gajae-code/ai/core"; /** * Effective credential provenance for a provider, derived from credential * surfaces (never from token shape). * * - `"oauth"`: requests are authenticated with an OAuth-provisioned credential, * including OAuth flows whose access tokens happen to look like API keys * (e.g. GitHub Copilot `ghu_` tokens). * - `"key"`: a manual or configured API key (stored `api_key`, CLI `--api-key` * runtime override, `models.yml` `apiKey`/`apiKeyEnv`, or environment key). * - `"keyless"`: no credential is required (local servers, `auth: none`). * - `"unknown"`: no credential surface is present. */ export type EffectiveProviderAuth = "oauth" | "key" | "keyless" | "unknown"; export interface ProviderSelectionPolicyInput { /** Explicit `modelProviderOrder` from settings; trimmed and case-insensitive. */ explicitProviderOrder: readonly string[]; /** Effective auth provenance per lowercased provider id. */ effectiveAuth: ReadonlyMap; /** Registry catalog provider ids, lowercased, first-wins catalog order. */ catalogProviders: readonly string[]; /** Registry catalog model selectors ("provider/id"), lowercased, first-wins catalog order. */ catalogModels: readonly string[]; } export interface ProviderSelectionPolicy { /** * Total-order rank for a provider: explicit providers `0..n-1`, omitted * effective-OAuth providers `n`, omitted non-OAuth/unknown/keyless providers * `n+1`. Unknown providers that were never cataloged still receive the * non-OAuth rank unless their effective auth is OAuth. */ rank(provider: string): number; /** Lowercased explicit provider ids, in explicit order (deduped). */ explicitProviders(): readonly string[]; /** Whether a provider was listed explicitly. */ isExplicit(provider: string): boolean; /** Ordered distinct provider ids: explicit order first, then catalog order. */ orderedProviders(): readonly string[]; /** Stable catalog index per lowercased provider id (registry-owned tie data). */ providerCatalogIndex(provider: string): number; /** Stable catalog index per lowercased model selector (registry-owned tie data). */ modelCatalogIndex(selector: string): number; } /** * Build a pure provider selection policy over explicit user order, effective * credential provenance, and registry-owned catalog tie data. The policy never * reads settings, auth storage, or the model catalog itself — callers pass the * current values in so ranking stays deterministic and testable. */ export declare function createProviderSelectionPolicy(input: ProviderSelectionPolicyInput): ProviderSelectionPolicy; /** * Project the deterministic provider order: normalized explicit order first, then * first-wins catalog order for everything else. * * This is the single implementation of that ordering. It reads no credentials and * takes no auth input at all, so any consumer that only needs "which providers, in * what priority" cannot accidentally acquire auth sensitivity. Auth-aware banding * lives exclusively in {@link ProviderSelectionPolicy.rank}. */ export declare function projectProviderOrder(explicitProviderOrder: readonly string[], catalogProviders: readonly string[]): string[]; export interface ProviderSelectionCatalog { /** Lowercased provider ids in first-wins registry catalog order. */ readonly catalogProviders: readonly string[]; /** Lowercased model selectors in first-wins registry catalog order. */ readonly catalogModels: readonly string[]; } /** * Derive stable provider/model tie data from the registry catalog order, not * from a caller-supplied candidate array. First occurrence wins so reordering * candidates never changes ranking. */ export declare function buildProviderSelectionCatalog(models: readonly Model[]): ProviderSelectionCatalog; /** * Deterministic provider priority for a catalog, returned in the catalog's own * spelling. * * Ordering and de-duplication run on normalized ids, but the result restores each * provider's first-seen catalog spelling because the autorouting generator matches * provider prefixes with case-sensitive exact strings — a lowercased id would * silently empty that provider's tiers. Providers absent from the catalog are * dropped so a dead declaration cannot pollute a generated declarationFingerprint. * * Reads no credentials: it takes a catalog and an explicit order, nothing else. */ export declare function projectCatalogProviderOrder(explicitProviderOrder: readonly string[], models: readonly Model[]): string[];