/** * Provider budgets — the bridge between the config file and the database. * * See docs/proposals/providers-and-budgets.md. The model-providers file * defines TYPES: what an instance of each offers (backend, models, * capabilities). PROVIDERS are rows in the database, each a credential with * a budget policy, and a session's model reference names one of them: * * azure-prod:gpt-5.4 * └ provider └ model, offered by the provider's TYPE * * Two jobs live here. The first is the one-time deployment seed: a fresh * cluster has no providers at all, and the credentials already sitting in * the config file are the obvious thing to start from. The second is * resolving a reference to a real credential at turn time, for providers * the file has never heard of — anything an administrator or a user created * at runtime. */ import type { ModelProvidersFile, ResolvedProvider } from "./model-providers.js"; import { ModelProviderRegistry } from "./model-providers.js"; import type { DefaultTuple, ProviderCredential, ProviderStore } from "./provider-store.js"; export type RuntimeModelResolutionSource = "explicit" | "user_default" | "cluster_default" | "system_default" | "agent_override" | "first_available"; export interface RuntimeModelSelection extends DefaultTuple { provider: string; model: string; source: RuntimeModelResolutionSource; } export declare class ModelAmbiguousError extends Error { readonly model: string; readonly candidates: string[]; readonly code = "MODEL_AMBIGUOUS"; constructor(model: string, candidates: string[]); } export declare class ModelUnresolvedError extends Error { readonly code = "MODEL_UNRESOLVED"; constructor(message: string); } export interface RuntimeModelDefaultCandidate { tuple: DefaultTuple; source: Exclude; } /** * The type catalog. Every entry survives, credentialed or not: a type is a * template, and whether anything can pay is a question about instances. */ export declare function loadProviderTypes(config: ModelProvidersFile): ModelProviderRegistry; /** * The deployment seed, derived from the config file. * * An entry with a resolvable credential becomes one shared provider named * after the entry — so `azure-openai:gpt-5.4` means the same thing before * and after this feature, and no deployment file has to change. An entry * with no credential seeds nothing: it stays a type people can instantiate * with a key of their own, which is exactly how GitHub Copilot is deployed * on a cluster that holds no shared Copilot key. */ export declare function bootstrapSeedFromConfig(config: ModelProvidersFile): { instances: Array<{ name: string; typeId: string; secretRef: Record; baseUrl: string | null; }>; defaults: DefaultTuple | null; }; /** * The one origin allowed to store a POINTER to a secret rather than a secret. * * `env:AZURE_KEY` is an indirection into the worker's own environment, and * it is safe exactly once: when the deployment's own config file wrote it. * A credential that arrived in a request is a VALUE, never a pointer — * honouring `env:` there let anyone with an account name a variable and have * the worker send that variable's contents to a base URL of their choosing. * ProviderStore.createProvider is what keeps the two apart; this constant is * the marker it refuses to let a caller forge. */ export declare const CONFIG_ORIGIN = "config-file"; /** * Seed a fresh cluster, once. Safe to call at every boot: the claim is * atomic in the database, so several pods starting together seed exactly * once, and a provider an administrator later deleted stays deleted. */ export declare function bootstrapProviders(store: ProviderStore, config: ModelProvidersFile): Promise<{ claimed: boolean; created: number; }>; /** * The catalog a worker actually runs against: one entry per PROVIDER, built * from the types in the file and the instances in the database. * * Every downstream path — normalize(), resolve(), getDescriptor(), the model * summary an agent sees — is keyed by `providerId:model`, and after this the * provider id IS the provider's name. So `carol-ghcp:claude-opus-5` resolves * for exactly the same reason `azure-prod:gpt-5.4` does, and nothing further * down has to learn what a provider instance is. * * This registry holds every provider, personal ones included, because a * worker runs turns for everybody. It is not an access decision and must * never be shown to anyone: what a person may spend from is decided by the * admission gate, which resolves the name in the SESSION OWNER'S namespace * and refuses before a credential is ever reached for. */ export declare function buildRuntimeRegistry(types: ModelProviderRegistry, instances: ProviderCredential[], defaultModel?: string | null): ModelProviderRegistry; export declare function firstRuntimeModel(types: ModelProviderRegistry, instances: ProviderCredential[], eligible: (instance: ProviderCredential) => boolean): DefaultTuple | null; export declare function resolveRuntimeModelSelection(types: ModelProviderRegistry, instances: ProviderCredential[], input: { requestedModel?: string | null; requestedReasoning?: string | null; requestedContext?: string | null; defaults?: RuntimeModelDefaultCandidate[]; eligible: (instance: ProviderCredential) => boolean; }): RuntimeModelSelection; /** * Turn an admitted provider into the credential block the SDK client wants. * * This is the path for providers the config file does not describe: one an * administrator added at runtime, or a personal one somebody created with * their own key. The TYPE still comes from the file (it says which backend * and which models); only the credential and endpoint come from the row. * * Returns null when the type is unknown — a provider whose template was * removed from the config can no longer be run, and saying so is better * than guessing an adapter. */ export declare function resolveProviderCredential(types: ModelProviderRegistry, credential: ProviderCredential, modelName: string): ResolvedProvider | null; //# sourceMappingURL=provider-catalog.d.ts.map