/** * Interactive model picker for Franklin. * Shows categorized model list, supports shortcuts and arrow-key selection. */ import { type GatewayModel } from '../gateway-models.js'; export declare const MODEL_SHORTCUTS: Record; /** * Resolve a model name — supports shortcuts. Returns the canonical model id. * * If the input matches a shortcut, the shortcut's target is returned. If the * input is already a fully-qualified `provider/model` id (contains a `/`), it * is returned verbatim so the gateway can validate it. Bare, unknown aliases * (e.g. `llama3`, `foo`) resolve to themselves too, but the gateway will * reject them — callers that care about a clean error should branch on * {@link resolveModelStrict} instead. */ export declare function resolveModel(input: string): string; /** * Strict variant of {@link resolveModel} — used by the `/model` handler so * an unknown bare alias surfaces a clean error in the UI instead of * forwarding `llama` to the gateway and getting back `HTTP 400: Unknown * model: llama` two turns later. * * Recognised: * - Any entry in {@link MODEL_SHORTCUTS} (case-insensitive). * - Any id of the form `provider/model` (e.g. `anthropic/claude-sonnet-4.6`). */ export declare function resolveModelStrict(input: string): { ok: true; id: string; viaShortcut: boolean; } | { ok: false; suggestion: string; }; export interface ModelEntry { id: string; shortcut: string; label: string; price: string; highlight?: boolean; } export interface ModelCategory { category: string; models: ModelEntry[]; } /** * Single source of truth for the /model picker. * ~30 models across 6 categories. Every ID here is present in src/pricing.ts * and every shortcut is in MODEL_SHORTCUTS above. * * Both the Ink UI picker (src/ui/app.tsx) and the readline picker * (pickModel() below) import from this array. To add or remove models, * edit this one place. */ export declare const PICKER_CATEGORIES: ModelCategory[]; /** Flat list of all picker models (for index-based navigation). */ export declare const PICKER_MODELS_FLAT: ModelEntry[]; export interface HydratedPicker { categories: ModelCategory[]; /** Chat models live on the gateway that aren't curated into the picker. */ moreCount: number; /** False when the gateway was unreachable and this is the static fallback. */ live: boolean; } /** * The picker list, reconciled against the live gateway catalog. * * {@link PICKER_CATEGORIES} stays the editorial layer — which models are worth * featuring, in what order, under which heading, with which shortcut. The * gateway is the source of truth for everything factual: whether a model still * exists and its price. Ctrl+A uses {@link getExpandedPickerCategories} when the * user explicitly wants the full gateway chat catalog. * * Reconciliation rules: * - Curated row present in the catalog → keep its label/shortcut/highlight and * refresh its price from the gateway. * - Curated row absent → drop it. This is the self-healing half: an id the * gateway retired (the `claude-haiku-4.5-20251001` case) stops being * offered without waiting on a Franklin release. Its MODEL_SHORTCUTS alias * survives, matching the long-standing "hide the row, keep the shortcut" * pattern. * - Gateway unreachable → serve the static list verbatim (`live: false`). * An offline picker showing a slightly stale list beats an empty one. * * Note the catalog hides some models that still resolve (grok-3 and the xAI * fast family, for instance). Hidden-but-working ids are therefore dropped from * the *visible* list while remaining reachable by typing the shortcut — which * is the intended behavior, not a bug. */ export declare function getPickerCategories(): Promise; /** * Pure reconciliation step behind {@link getPickerCategories} — exported so the * rules can be tested against a synthetic catalog without touching the network. */ export declare function reconcilePicker(catalog: GatewayModel[]): HydratedPicker; export declare function getExpandedPickerCategories(): Promise; export declare function reconcileExpandedPicker(catalog: GatewayModel[]): HydratedPicker; /** * Show interactive model picker. Returns the selected model ID. * Falls back to text input if terminal doesn't support raw mode. */ export declare function pickModel(currentModel?: string): Promise;