| 1 | /** |
| 2 | * Ask's model picker (Integrations → Your AI providers → Ask g1t): Auto |
| 3 | * first and chosen by default, then each model the provider listed. Pure, |
| 4 | * so it is tested on its own (ask-model.test.ts). |
| 5 | */ |
| 6 | import type { ASK_AUTO_MODEL as AutoModel, AskSetup, Connection } from "@g1t/contracts"; |
| 7 | |
| 8 | /** `ASK_AUTO_MODEL`: the model name that chooses Auto. */ |
| 9 | const ASK_AUTO_MODEL: typeof AutoModel = "auto"; |
| 10 | |
| 11 | export type ModelOption = { value: string; label: string; description?: string }; |
| 12 | |
| 13 | /** Whether Auto can choose on a connection: it lists its models, and it is not an Azure deployment. */ |
| 14 | export function autoOffered(connection: Pick<Connection, "provider" | "models"> | null): boolean { |
| 15 | return connection != null && connection.provider !== "azure_openai" && connection.models.length > 0; |
| 16 | } |
| 17 | |
| 18 | /** The picker's options for a connection: Auto, then its models. */ |
| 19 | export function modelOptions(connection: Pick<Connection, "provider" | "models">): ModelOption[] { |
| 20 | const models = connection.models.map((model) => ({ value: model, label: model })); |
| 21 | if (!autoOffered(connection)) return models; |
| 22 | return [{ value: ASK_AUTO_MODEL, label: "Auto", description: "A fast model for lookups, a stronger one when a question needs it" }, ...models]; |
| 23 | } |
| 24 | |
| 25 | /** |
| 26 | * What the picker starts at: for the connection Ask uses, what was chosen |
| 27 | * (Auto unless a model was); for another, Auto where it is offered, else |
| 28 | * the connection's own model or the first it lists. |
| 29 | */ |
| 30 | export function defaultModel( |
| 31 | connection: Pick<Connection, "id" | "provider" | "models" | "config"> | null, |
| 32 | setup: Pick<AskSetup, "connection_id" | "model" | "auto"> | null, |
| 33 | ): string { |
| 34 | if (!connection) return ""; |
| 35 | const offered = autoOffered(connection); |
| 36 | if (setup && connection.id === setup.connection_id) { |
| 37 | if (setup.auto && offered) return ASK_AUTO_MODEL; |
| 38 | if (setup.model && (!offered || connection.models.includes(setup.model))) return setup.model; |
| 39 | } |
| 40 | if (offered) return ASK_AUTO_MODEL; |
| 41 | return connection.config.model ?? connection.models[0] ?? ""; |
| 42 | } |
| 43 | |
| 44 | /** How the chosen model reads: "Auto", or the model's name. */ |
| 45 | export function modelLabel(setup: Pick<AskSetup, "model" | "auto"> | null): string { |
| 46 | if (setup?.auto) return setup.model ? `Auto · ${setup.model}` : "Auto"; |
| 47 | return setup?.model ?? ""; |
| 48 | } |