import { ClaudeModelInfo } from "./types.js"; /** * The complete server-side model catalog. Keep this separate from the Claude * verification cache: the former is a client-facing snapshot for every * provider, whereas the latter records evidence from individual probes. */ export declare const MODEL_CATALOG_CACHE_KEY = "model-catalog-v1"; interface ModelCacheStorage { getConfigValue(key: string): string | null; setConfigValue(key: string, value: string): void; } interface ModelCommandOptions { env: NodeJS.ProcessEnv; timeout: number; } interface ModelCommandResult { stdout: string; stderr: string; } export type ModelCommandRunner = (file: string, args: string[], options: ModelCommandOptions) => Promise; interface ClaudeModelsApiEntry { id: string; display_name?: string; } interface ClaudeModelsApi { list(): AsyncIterable; } export interface ModelRefreshOptions { storage?: ModelCacheStorage; configuredClaudeModels?: readonly (string | null | undefined)[]; inheritEnv?: boolean; env?: NodeJS.ProcessEnv; apiKey?: string; commandRunner?: ModelCommandRunner; modelsApi?: ClaudeModelsApi; verifyClaudeCandidates?: boolean; now?: () => Date; } export interface ModelCache { models: ClaudeModelInfo[]; codexModels: ClaudeModelInfo[]; opencodeModels: ClaudeModelInfo[]; grokModels: ClaudeModelInfo[]; qoderModels: ClaudeModelInfo[]; piModels: ClaudeModelInfo[]; claudeVersion: string | null; opencodeVersion: string | null; refreshedAt: string; } /** Immutable-looking snapshot returned to API clients. */ export interface ModelCatalogSnapshot extends ModelCache { /** SHA-256 of the catalog excluding `refreshedAt`. Changes only with content. */ revision: string; } export interface ModelCatalogRefreshResult extends ModelCatalogSnapshot { /** True only when the persisted catalog content changed (or was first saved). */ changed: boolean; /** Time this server-side refresh check ran; it is deliberately not persisted. */ checkedAt: string; } export interface ModelCatalogRefreshRequest { /** Administrator-triggered refreshes may also validate Claude candidates. */ verifyClaudeCandidates?: boolean; } /** * Parse `grok models` human-readable output: * * Default model: grok-4.5 * Available models: * * grok-4.5 (default) */ export declare function parseGrokModels(stdout: string): ClaudeModelInfo[]; /** * Parse `qodercli --list-models`. * * Qoder has used both provider-qualified custom IDs (`zhipu/glm5.2-cp`) and * plain tier/frontier IDs (`glm51`). The CLI's human-readable rows put the * selectable value in the final parentheses; some versions also emit a bare * safe ID below the `MODEL` header. */ export declare function parseQoderModels(stdout: string): ClaudeModelInfo[]; /** Parse `opencode models`, whose stable machine-friendly output is one provider/model id per line. */ export declare function parseOpenCodeModels(stdout: string): ClaudeModelInfo[]; /** Parse the machine-readable model registry emitted by the installed Codex CLI. */ export declare function parseCodexModels(stdout: string): ClaudeModelInfo[]; /** * Server-owned, persisted model directory. * * It deliberately has a tiny surface: clients read `snapshot`; only server * jobs and an administrator route may call `refresh`. Each service instance * owns its cache and single-flight lock, so test servers and multiple hosts in * the same Node process cannot leak a catalog into one another. */ export declare class ModelCatalogService { private readonly getOptions; private cache; private revision; private hasPersistedSnapshot; private refreshPromise; private inFlightIncludesVerification; constructor(getOptions: () => ModelRefreshOptions); snapshot(): ModelCatalogSnapshot; refresh(request?: ModelCatalogRefreshRequest): Promise; private performRefresh; } /** * Compatibility helper for direct callers and unit tests. Server code should * use `ModelCatalogService` so the result is persisted and diffed. */ export declare function refreshModels(options?: ModelRefreshOptions): Promise; export {};