Open History to see the last commit
1import type { ModelSelection } from "@t3tools/contracts";
2import {
3 getModelSelectionBooleanOptionValue,
4 getModelSelectionStringOptionValue,
5 getProviderOptionDescriptors,
6 resolvePromptInjectedEffort,
7} from "@t3tools/shared/model";
8
9import {
10 BUNDLED_CLAUDE_MODEL_CATALOG,
11 getClaudeCatalogModelCapabilities,
12 normalizeClaudeCatalogEffort,
13 resolveClaudeCatalogApiModelId,
14 resolveClaudeCatalogEffort,
15 resolveClaudeCatalogModel,
16 resolveClaudeModelSlug,
17 type ClaudeModelCatalog,
18} from "./provider/ClaudeModelCatalog.ts";
19
20const CLAUDE_CODE_MODEL_ALIASES = new Set(["opus", "sonnet", "haiku", "fable"]);
21
22export interface CompiledClaudeModelSelection {
23 readonly apiModelId: string;
24 readonly effort: string | undefined;
25 readonly promptEffort: string | undefined;
26 readonly settings: Readonly<Record<string, boolean>>;
27 /** The alias of a custom model named like one, which Claude Code would otherwise expand. */
28 readonly pinnedAlias: string | undefined;
29 readonly queryIdentity: string;
30}
31
32export function compileClaudeModelSelection(
33 selection: ModelSelection,
34 catalog: ClaudeModelCatalog = BUNDLED_CLAUDE_MODEL_CATALOG,
35): CompiledClaudeModelSelection {
36 const capabilities = getClaudeCatalogModelCapabilities(catalog, selection.model);
37 const descriptors = getProviderOptionDescriptors({
38 caps: capabilities,
39 selections: selection.options,
40 });
41 const supportsBoolean = (id: string) =>
42 descriptors.some((descriptor) => descriptor.type === "boolean" && descriptor.id === id);
43 const rawEffort = getModelSelectionStringOptionValue(selection, "effort");
44 const resolvedEffort = resolveClaudeCatalogEffort(catalog, selection.model, rawEffort);
45 const effort = normalizeClaudeCatalogEffort(catalog, resolvedEffort, selection.model);
46 const fastMode = supportsBoolean("fastMode")
47 ? (getModelSelectionBooleanOptionValue(selection, "fastMode") ?? false)
48 : undefined;
49 const inCatalog = resolveClaudeCatalogModel(catalog, selection.model) !== undefined;
50 const thinking =
51 !inCatalog || supportsBoolean("thinking")
52 ? getModelSelectionBooleanOptionValue(selection, "thinking")
53 : undefined;
54 const ultracode = descriptors.find((descriptor) => descriptor.id === "ultracode")?.currentValue;
55 const settings = {
56 ...(typeof thinking === "boolean" ? { alwaysThinkingEnabled: thinking } : {}),
57 ...(typeof fastMode === "boolean" ? { fastMode } : {}),
58 ...(typeof ultracode === "boolean" ? { ultracode } : {}),
59 };
60 const apiModelId = resolveClaudeCatalogApiModelId(catalog, selection);
61 const promptEffort = resolvePromptInjectedEffort(capabilities, rawEffort) ?? undefined;
62 // An alias the catalog routes a built-in model to is Claude Code's own and is not pinned.
63 const pinnedAlias =
64 CLAUDE_CODE_MODEL_ALIASES.has(apiModelId) &&
65 resolveClaudeModelSlug(catalog, selection.model) === apiModelId
66 ? apiModelId
67 : undefined;
68 return {
69 apiModelId,
70 effort,
71 promptEffort,
72 settings,
73 pinnedAlias,
74 queryIdentity: JSON.stringify({
75 apiModelId,
76 effort: effort ?? null,
77 settings,
78 pinnedAlias: pinnedAlias ?? null,
79 }),
80 };
81}