/** * model-routes.ts * * HTTP route handlers for model catalog discovery and global model selection. * * Routes: * GET /api/models , list all providers + models with configured flags * GET /api/models/current , return current model + configured status * PATCH /api/models/current , switch current model live * * All routes require the existing daemon bearer-token auth (enforced by the * caller, DaemonHttpRouter.handleRequest validates auth before dispatching). */ import type { ProviderRegistry } from '../../providers/registry.js'; import type { ConfigManager } from '../../config/manager.js'; import type { RuntimeEventBus } from '../../runtime/events/index.js'; import type { SecretsManager } from '../../config/secrets.js'; import type { ProviderAuthRouteDescriptor } from '../../providers/interface.js'; import { type ReasoningEffortSource } from '../../providers/reasoning-effort.js'; export interface ProviderModelRef { readonly registryKey: string; readonly provider: string; readonly id: string; } /** The reasoning levels one model actually offers, and which source resolved them. */ export interface ModelReasoningOptions { readonly levels: string[]; readonly source: ReasoningEffortSource; } export interface ProviderModelEntry { readonly id: string; readonly registryKey: string; readonly provider: string; readonly label?: string | undefined; readonly contextWindow?: number | undefined; /** Absent when the model does not reason at all. */ readonly reasoningOptions?: ModelReasoningOptions | undefined; } export type ConfiguredVia = 'env' | 'secrets' | 'subscription' | 'anonymous'; export interface ModelRouteProviderRecord { readonly id: string; readonly label: string; readonly configured: boolean; readonly configuredVia?: ConfiguredVia | undefined; readonly envVars: string[]; readonly routes?: readonly ProviderAuthRouteDescriptor[] | undefined; readonly models: ProviderModelEntry[]; } export interface ListProviderModelsResponse { readonly providers: ModelRouteProviderRecord[]; readonly currentModel: ProviderModelRef | null; /** * `true` when the secrets manager was unavailable for this response. * `false` when secrets resolution was attempted. */ readonly secretsResolutionSkipped: boolean; } export interface CurrentModelResponse { readonly model: ProviderModelRef | null; readonly configured: boolean; readonly configuredVia?: ConfiguredVia | undefined; readonly routes?: readonly ProviderAuthRouteDescriptor[] | undefined; /** The persisted reasoning level, null when none has been set explicitly. */ readonly effort: string | null; } export interface PatchCurrentModelResponse extends CurrentModelResponse { readonly persisted: boolean; } export interface ModelRouteContext { readonly providerRegistry: ProviderRegistry; readonly configManager: ConfigManager; readonly runtimeBus: RuntimeEventBus; readonly parseJsonBody: (req: Request) => Promise | Response>; readonly secretsManager?: Pick | null | undefined; } /** * The paths this sub-router serves, and the method-catalog verb each one is. * * Exported because it is READ by the capability-route reconcile * (control-plane/method-catalog-route-reconcile.ts): router.ts dispatches this * sub-router before the shared route table, so the reconcile's probe cannot see * these paths and used to skip them by prefix, which is how three verbs stayed * outside the catalog with nothing noticing. The dispatch below is driven off * this same table, so the two cannot drift. */ export declare const MODEL_ROUTES: readonly { readonly method: string; readonly path: string; readonly methodId: string; }[]; export declare function dispatchModelRoutes(req: Request, context: ModelRouteContext): Promise; //# sourceMappingURL=model-routes.d.ts.map