2026-01-22 22:43:27 +09:00
|
|
|
import type { FallbackEntry } from "./model-requirements"
|
2026-01-31 15:46:14 +09:00
|
|
|
import { resolveModelPipeline } from "./model-resolution-pipeline"
|
2026-01-22 22:43:27 +09:00
|
|
|
|
2026-01-17 12:51:03 -05:00
|
|
|
export type ModelResolutionInput = {
|
2026-01-22 22:43:27 +09:00
|
|
|
userModel?: string
|
|
|
|
|
inheritedModel?: string
|
2026-01-26 17:01:08 +09:00
|
|
|
systemDefault?: string
|
2026-01-22 22:43:27 +09:00
|
|
|
}
|
|
|
|
|
|
2026-02-05 23:15:31 +09:00
|
|
|
/**
|
|
|
|
|
* Normalizes fallback_models to an array.
|
|
|
|
|
* Handles single string or array input, returns undefined for falsy values.
|
|
|
|
|
*/
|
|
|
|
|
export function normalizeFallbackModels(
|
|
|
|
|
fallbackModels: string | string[] | undefined | null
|
|
|
|
|
): string[] | undefined {
|
|
|
|
|
if (!fallbackModels) return undefined
|
|
|
|
|
return Array.isArray(fallbackModels) ? fallbackModels : [fallbackModels]
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-22 22:43:27 +09:00
|
|
|
export type ModelSource =
|
|
|
|
|
| "override"
|
2026-01-30 14:05:47 +09:00
|
|
|
| "category-default"
|
2026-01-22 22:43:27 +09:00
|
|
|
| "provider-fallback"
|
|
|
|
|
| "system-default"
|
|
|
|
|
|
|
|
|
|
export type ModelResolutionResult = {
|
|
|
|
|
model: string
|
|
|
|
|
source: ModelSource
|
2026-01-23 02:20:32 +09:00
|
|
|
variant?: string
|
2026-01-22 22:43:27 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type ExtendedModelResolutionInput = {
|
2026-01-29 09:30:35 +09:00
|
|
|
uiSelectedModel?: string
|
2026-01-22 22:43:27 +09:00
|
|
|
userModel?: string
|
2026-02-03 12:18:52 +09:00
|
|
|
userFallbackModels?: string[]
|
2026-01-30 14:05:47 +09:00
|
|
|
categoryDefaultModel?: string
|
2026-01-22 22:43:27 +09:00
|
|
|
fallbackChain?: FallbackEntry[]
|
|
|
|
|
availableModels: Set<string>
|
2026-01-26 17:01:08 +09:00
|
|
|
systemDefaultModel?: string
|
2026-01-22 22:43:27 +09:00
|
|
|
}
|
|
|
|
|
|
2026-01-17 12:51:03 -05:00
|
|
|
function normalizeModel(model?: string): string | undefined {
|
2026-01-22 22:43:27 +09:00
|
|
|
const trimmed = model?.trim()
|
|
|
|
|
return trimmed || undefined
|
2026-01-17 12:51:03 -05:00
|
|
|
}
|
|
|
|
|
|
2026-01-26 17:01:08 +09:00
|
|
|
export function resolveModel(input: ModelResolutionInput): string | undefined {
|
2026-01-22 22:43:27 +09:00
|
|
|
return (
|
|
|
|
|
normalizeModel(input.userModel) ??
|
|
|
|
|
normalizeModel(input.inheritedModel) ??
|
|
|
|
|
input.systemDefault
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function resolveModelWithFallback(
|
|
|
|
|
input: ExtendedModelResolutionInput,
|
2026-01-26 17:01:08 +09:00
|
|
|
): ModelResolutionResult | undefined {
|
2026-02-03 12:18:52 +09:00
|
|
|
const { uiSelectedModel, userModel, userFallbackModels, categoryDefaultModel, fallbackChain, availableModels, systemDefaultModel } = input
|
2026-01-31 15:46:14 +09:00
|
|
|
const resolved = resolveModelPipeline({
|
2026-02-03 12:18:52 +09:00
|
|
|
intent: { uiSelectedModel, userModel, userFallbackModels, categoryDefaultModel },
|
2026-01-31 15:46:14 +09:00
|
|
|
constraints: { availableModels },
|
|
|
|
|
policy: { fallbackChain, systemDefaultModel },
|
|
|
|
|
})
|
2026-01-22 22:43:27 +09:00
|
|
|
|
2026-01-31 15:46:14 +09:00
|
|
|
if (!resolved) {
|
2026-01-26 17:01:08 +09:00
|
|
|
return undefined
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-31 15:46:14 +09:00
|
|
|
return {
|
|
|
|
|
model: resolved.model,
|
|
|
|
|
source: resolved.provenance,
|
|
|
|
|
variant: resolved.variant,
|
|
|
|
|
}
|
2026-01-17 12:51:03 -05:00
|
|
|
}
|