2026-02-08 18:03:15 +09:00
|
|
|
import type { FallbackEntry } from "../../shared/model-requirements"
|
2026-03-02 16:38:22 +09:00
|
|
|
import { normalizeModel } from "../../shared/model-normalization"
|
2026-02-08 18:03:15 +09:00
|
|
|
import { fuzzyMatchModel } from "../../shared/model-availability"
|
2026-02-17 22:18:56 +09:00
|
|
|
import { transformModelForProvider } from "../../shared/provider-model-id-transform"
|
2026-02-08 18:03:15 +09:00
|
|
|
|
|
|
|
|
|
|
|
|
|
export function resolveModelForDelegateTask(input: {
|
|
|
|
|
userModel?: string
|
|
|
|
|
categoryDefaultModel?: string
|
|
|
|
|
fallbackChain?: FallbackEntry[]
|
|
|
|
|
availableModels: Set<string>
|
|
|
|
|
systemDefaultModel?: string
|
|
|
|
|
}): { model: string; variant?: string } | undefined {
|
|
|
|
|
const userModel = normalizeModel(input.userModel)
|
|
|
|
|
if (userModel) {
|
|
|
|
|
return { model: userModel }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const categoryDefault = normalizeModel(input.categoryDefaultModel)
|
|
|
|
|
if (categoryDefault) {
|
|
|
|
|
if (input.availableModels.size === 0) {
|
|
|
|
|
return { model: categoryDefault }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const parts = categoryDefault.split("/")
|
|
|
|
|
const providerHint = parts.length >= 2 ? [parts[0]] : undefined
|
|
|
|
|
const match = fuzzyMatchModel(categoryDefault, input.availableModels, providerHint)
|
|
|
|
|
if (match) {
|
|
|
|
|
return { model: match }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const fallbackChain = input.fallbackChain
|
|
|
|
|
if (fallbackChain && fallbackChain.length > 0) {
|
|
|
|
|
if (input.availableModels.size === 0) {
|
|
|
|
|
const first = fallbackChain[0]
|
|
|
|
|
const provider = first?.providers?.[0]
|
|
|
|
|
if (provider) {
|
2026-02-17 22:18:56 +09:00
|
|
|
const transformedModelId = transformModelForProvider(provider, first.model)
|
|
|
|
|
return { model: `${provider}/${transformedModelId}`, variant: first.variant }
|
2026-02-08 18:03:15 +09:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (const entry of fallbackChain) {
|
|
|
|
|
for (const provider of entry.providers) {
|
|
|
|
|
const fullModel = `${provider}/${entry.model}`
|
|
|
|
|
const match = fuzzyMatchModel(fullModel, input.availableModels, [provider])
|
|
|
|
|
if (match) {
|
|
|
|
|
return { model: match, variant: entry.variant }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const crossProviderMatch = fuzzyMatchModel(entry.model, input.availableModels)
|
|
|
|
|
if (crossProviderMatch) {
|
|
|
|
|
return { model: crossProviderMatch, variant: entry.variant }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const systemDefaultModel = normalizeModel(input.systemDefaultModel)
|
|
|
|
|
if (systemDefaultModel) {
|
|
|
|
|
return { model: systemDefaultModel }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return undefined
|
|
|
|
|
}
|