Files
oh-my-opencode/src/tools/delegate-task/model-selection.ts
T
YeonGyu-Kim 77670cb46f feat(delegate-task): use explicit high variant for unspecified-high category
- Update DEFAULT_CATEGORIES to use 'openai/gpt-5.4-high' directly instead of separate model + variant
- Add helper functions (isExplicitHighModel, getExplicitHighBaseModel) to preserve explicit high models during fuzzy matching
- Update category resolver to avoid collapsing explicit high models to base model + variant pair
- Update tests to verify explicit high model handling in both background and sync modes
- Update documentation examples to reflect new configuration

🤖 Generated with OhMyOpenCode assistance
2026-03-08 01:41:45 +09:00

89 lines
3.1 KiB
TypeScript

import type { FallbackEntry } from "../../shared/model-requirements"
import { normalizeModel } from "../../shared/model-normalization"
import { fuzzyMatchModel } from "../../shared/model-availability"
import { transformModelForProvider } from "../../shared/provider-model-id-transform"
function isExplicitHighModel(model: string): boolean {
return /(?:^|\/)[^/]+-high$/.test(model)
}
function getExplicitHighBaseModel(model: string): string | null {
return isExplicitHighModel(model) ? model.replace(/-high$/, "") : null
}
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)
const explicitHighBaseModel = categoryDefault ? getExplicitHighBaseModel(categoryDefault) : null
const explicitHighModel = explicitHighBaseModel ? categoryDefault : undefined
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) {
if (isExplicitHighModel(categoryDefault) && match !== categoryDefault) {
return { model: categoryDefault }
}
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) {
const transformedModelId = transformModelForProvider(provider, first.model)
return { model: `${provider}/${transformedModelId}`, variant: first.variant }
}
} 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) {
if (explicitHighModel && entry.variant === "high" && match === explicitHighBaseModel) {
return { model: explicitHighModel }
}
return { model: match, variant: entry.variant }
}
}
const crossProviderMatch = fuzzyMatchModel(entry.model, input.availableModels)
if (crossProviderMatch) {
if (explicitHighModel && entry.variant === "high" && crossProviderMatch === explicitHighBaseModel) {
return { model: explicitHighModel }
}
return { model: crossProviderMatch, variant: entry.variant }
}
}
}
}
const systemDefaultModel = normalizeModel(input.systemDefaultModel)
if (systemDefaultModel) {
return { model: systemDefaultModel }
}
return undefined
}