| 1 | import type { ModelSelection } from "@t3tools/contracts"; |
| 2 | import { |
| 3 | getModelSelectionBooleanOptionValue, |
| 4 | getModelSelectionStringOptionValue, |
| 5 | getProviderOptionDescriptors, |
| 6 | resolvePromptInjectedEffort, |
| 7 | } from "@t3tools/shared/model"; |
| 8 | |
| 9 | import { |
| 10 | BUNDLED_CLAUDE_MODEL_CATALOG, |
| 11 | getClaudeCatalogModelCapabilities, |
| 12 | isClaudeCatalogUltracodeEffort, |
| 13 | normalizeClaudeCatalogEffort, |
| 14 | resolveClaudeCatalogApiModelId, |
| 15 | resolveClaudeCatalogEffort, |
| 16 | type ClaudeModelCatalog, |
| 17 | } from "./provider/ClaudeModelCatalog.ts"; |
| 18 | |
| 19 | export interface CompiledClaudeModelSelection { |
| 20 | readonly apiModelId: string; |
| 21 | readonly effort: string | undefined; |
| 22 | readonly promptEffort: string | undefined; |
| 23 | readonly settings: Readonly<Record<string, boolean>>; |
| 24 | readonly queryIdentity: string; |
| 25 | } |
| 26 | |
| 27 | /** Compile every Claude model option at the provider boundary. */ |
| 28 | export function compileClaudeModelSelection( |
| 29 | selection: ModelSelection, |
| 30 | catalog: ClaudeModelCatalog = BUNDLED_CLAUDE_MODEL_CATALOG, |
| 31 | ): CompiledClaudeModelSelection { |
| 32 | const capabilities = getClaudeCatalogModelCapabilities(catalog, selection.model); |
| 33 | const descriptors = getProviderOptionDescriptors({ caps: capabilities }); |
| 34 | const supportsBoolean = (id: string) => |
| 35 | descriptors.some((descriptor) => descriptor.type === "boolean" && descriptor.id === id); |
| 36 | const rawEffort = getModelSelectionStringOptionValue(selection, "effort"); |
| 37 | const resolvedEffort = resolveClaudeCatalogEffort(catalog, selection.model, rawEffort); |
| 38 | const effort = normalizeClaudeCatalogEffort(catalog, resolvedEffort, selection.model); |
| 39 | const fastMode = supportsBoolean("fastMode") |
| 40 | ? (getModelSelectionBooleanOptionValue(selection, "fastMode") ?? false) |
| 41 | : undefined; |
| 42 | const thinking = supportsBoolean("thinking") |
| 43 | ? getModelSelectionBooleanOptionValue(selection, "thinking") |
| 44 | : undefined; |
| 45 | const settings = { |
| 46 | ...(typeof thinking === "boolean" ? { alwaysThinkingEnabled: thinking } : {}), |
| 47 | ...(typeof fastMode === "boolean" ? { fastMode } : {}), |
| 48 | ...(isClaudeCatalogUltracodeEffort(resolvedEffort) ? { ultracode: true } : {}), |
| 49 | }; |
| 50 | const apiModelId = resolveClaudeCatalogApiModelId(catalog, selection); |
| 51 | const promptEffort = resolvePromptInjectedEffort(capabilities, rawEffort) ?? undefined; |
| 52 | return { |
| 53 | apiModelId, |
| 54 | effort, |
| 55 | promptEffort, |
| 56 | settings, |
| 57 | queryIdentity: JSON.stringify({ apiModelId, effort: effort ?? null, settings }), |
| 58 | }; |
| 59 | } |