/** * Provider-neutral reasoning controls discovered for one opaque model id. * * Effort ids deliberately remain strings: providers can add values without a * RouteKit release. Ordering is provider-authored and therefore suitable for * selector presentation and deterministic cross-wire aliases. */ export type ReasoningEffortOption = { id: string; label?: string; description?: string; aliases?: readonly string[]; }; export type ReasoningCapabilityProvenance = "provider" | "config" | "builtin" | "unknown"; export type ReasoningCapabilityStatus = "supported" | "unsupported" | "unknown"; export type ModelReasoningCapabilities = { status: ReasoningCapabilityStatus; efforts?: readonly ReasoningEffortOption[]; defaultEffort?: string; budget?: { minTokens?: number; maxTokens?: number; defaultTokens?: number; }; adaptive?: boolean; /** * Opaque provider-adapter discriminator. Model routing never interprets it; * only the provider source that authored the capability may consume it. */ wireShape?: string; provenance: ReasoningCapabilityProvenance; refreshedAt?: string; }; export type ReasoningSelection = { mode: "auto"; } | { mode: "disabled"; } | { mode: "adaptive"; } | { mode: "effort"; effort: string; } | { mode: "budget"; budgetTokens: number; }; /** * Canonical effort descriptor for picker and catalog projection. * * `label` is always populated (`description ?? label ?? id`) so surfaces do * not reimplement presentation fallbacks. */ export type ReasoningEffortDescriptor = { id: string; label: string; aliases: readonly string[]; }; /** * One served model as seen by a client surface. * * `clientModel` is the surface-specific spelling used for discovery and * launch (for example Claude's `claude-` alias or Cursor's `routekit/` * namespace). Qualification happens against that spelling plus the served * `model` id so both advertised and unsuffixed requests resolve. */ export type ModelEffortVariantEntry = { model: string; clientModel: string; reasoning?: ModelReasoningCapabilities; }; export type ModelEffortVariant = { /** Client-facing model id, including any effort qualification. */ id: string; /** Canonical served model id. */ model: string; selection: ReasoningSelection; effort?: ReasoningEffortDescriptor; }; /** * Surface-specific spelling of effort-qualified model ids. * * A new surface supplies only these callbacks. Filtering, alias normalization, * exact-base precedence, and structured errors stay in contracts. */ export type ModelEffortVariantCodec = { qualify(baseClientModel: string, effort: string): string; /** * When `candidate` is a qualification of `baseClientModel`, return the * opaque effort token. Must not invent tokens for unrelated models. */ effortToken(candidate: string, baseClientModel: string): string | undefined; }; export type ReasoningSelectionErrorCode = "unknown_capability" | "unsupported" | "unsupported_effort" | "unsupported_adaptive" | "unsupported_budget" | "budget_out_of_range" | "invalid_selection"; export type ReasoningSelectionResolution = { ok: true; selection: ReasoningSelection; } | { ok: false; code: ReasoningSelectionErrorCode; message: string; }; export type ModelEffortVariantErrorCode = "unknown_model" | "unsupported_effort" | "collision"; export type ModelEffortVariantResolution = { ok: true; model: string; clientModel: string; selection: ReasoningSelection; } | { ok: false; code: ModelEffortVariantErrorCode; message: string; }; /** Default `:` qualification used by Claude and Cursor pickers. */ export declare const EFFORT_QUALIFIED_MODEL_CODEC: ModelEffortVariantCodec; export declare function resolveReasoningEffort(capabilities: ModelReasoningCapabilities, requested: string): string | undefined; /** * Ordered unique effort descriptors advertised for one model. * * Only `status: "supported"` capabilities contribute. Aliases are retained on * the descriptor for resolution but are never separate picker entries. */ export declare function reasoningEffortDescriptors(capabilities: ModelReasoningCapabilities | undefined): ReasoningEffortDescriptor[]; export declare function parseReasoningSelection(value: unknown): ReasoningSelectionResolution; export declare function reasoningSelectionEquals(left: ReasoningSelection, right: ReasoningSelection): boolean; /** * Validate and canonicalize a selection against discovered capabilities. * * Codex's historical `"none"` → disabled mapping stays at the gateway boundary; * this helper treats `"none"` like any other opaque effort id. */ export declare function resolveReasoningSelection(capabilities: ModelReasoningCapabilities | undefined, selection: ReasoningSelection): ReasoningSelectionResolution; export declare function reasoningSelectionFromEffort(capabilities: ModelReasoningCapabilities | undefined, requested: string): ReasoningSelectionResolution; /** * Expand one served model into the base client id plus one variant per * discovered effort. Aliases are not advertised as separate entries. */ export declare function enumerateModelEffortVariants(entry: ModelEffortVariantEntry, codec?: ModelEffortVariantCodec): ModelEffortVariant[]; /** * Detect generated client ids that collide across distinct served models or * effort selections. Exact base ids always win at resolve time; collisions are * reported so surfaces can refuse to advertise ambiguous catalogs. */ export declare function modelEffortVariantCollisions(entries: readonly ModelEffortVariantEntry[], codec?: ModelEffortVariantCodec): string[]; /** * Resolve a client-facing model id back to its served model and selection. * * Exact served/`clientModel` ids win before qualification. Qualification is * codec-defined against known bases (longest first), never a global delimiter * split, so opaque model ids that themselves contain `:` remain addressable. */ export declare function resolveModelEffortVariant(requested: string, entries: readonly ModelEffortVariantEntry[], codec?: ModelEffortVariantCodec): ModelEffortVariantResolution; /** * Project a launch/session effort selection onto a client model id. * * Surfaces that encode effort in the model name use this helper so launchers, * pickers, and gateway discovery stay aligned. Non-effort selections leave the * base id unchanged. */ export declare function effortQualifiedClientModel(baseClientModel: string, selection: ReasoningSelection | undefined, codec?: ModelEffortVariantCodec): string; /** * Conservative Codex picker heuristic for a model's discovered provenance. * * Codex uses the Responses API, so OpenRouter models are listed only when * their existing reasoning metadata says `supported`. Other providers remain * eligible when capability discovery is absent or inconclusive. This is only * a picker heuristic; it does not guarantee compatibility with encrypted * Responses reasoning state or continuation across models. */ export declare function isCodexPickerEligibleModel(input: { provider?: string; reasoning?: Pick; }): boolean;