fix(delegate-task): resolve variant-bearing fallback models during immediate selection
🤖 Generated with [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-openagent)
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
declare const require: (name: string) => any
|
import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test"
|
||||||
const { describe, test, expect, beforeEach, afterEach, spyOn, mock } = require("bun:test")
|
|
||||||
import { resolveModelForDelegateTask } from "./model-selection"
|
import { resolveModelForDelegateTask } from "./model-selection"
|
||||||
import * as connectedProvidersCache from "../../shared/connected-providers-cache"
|
import * as connectedProvidersCache from "../../shared/connected-providers-cache"
|
||||||
|
|
||||||
@@ -105,6 +104,26 @@ describe("resolveModelForDelegateTask", () => {
|
|||||||
expect(result!.model).toBe("anthropic/claude-sonnet-4-6")
|
expect(result!.model).toBe("anthropic/claude-sonnet-4-6")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("#when user fallback models include variant syntax", () => {
|
||||||
|
test("#then resolves a parenthesized variant against the base available model", () => {
|
||||||
|
const result = resolveModelForDelegateTask({
|
||||||
|
userFallbackModels: ["openai/gpt-5.2(high)"],
|
||||||
|
availableModels: new Set(["openai/gpt-5.2"]),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result).toEqual({ model: "openai/gpt-5.2", variant: "high" })
|
||||||
|
})
|
||||||
|
|
||||||
|
test("#then resolves a space-separated variant against the base available model", () => {
|
||||||
|
const result = resolveModelForDelegateTask({
|
||||||
|
userFallbackModels: ["gpt-5.2 medium"],
|
||||||
|
availableModels: new Set(["openai/gpt-5.2"]),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result).toEqual({ model: "openai/gpt-5.2", variant: "medium" })
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#given only connected providers cache exists (no provider-models cache)", () => {
|
describe("#given only connected providers cache exists (no provider-models cache)", () => {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { normalizeModel } from "../../shared/model-normalization"
|
|||||||
import { fuzzyMatchModel } from "../../shared/model-availability"
|
import { fuzzyMatchModel } from "../../shared/model-availability"
|
||||||
import { transformModelForProvider } from "../../shared/provider-model-id-transform"
|
import { transformModelForProvider } from "../../shared/provider-model-id-transform"
|
||||||
import { hasConnectedProvidersCache, hasProviderModelsCache } from "../../shared/connected-providers-cache"
|
import { hasConnectedProvidersCache, hasProviderModelsCache } from "../../shared/connected-providers-cache"
|
||||||
|
import { parseModelString, parseVariantFromModelID } from "./model-string-parser"
|
||||||
|
|
||||||
function isExplicitHighModel(model: string): boolean {
|
function isExplicitHighModel(model: string): boolean {
|
||||||
return /(?:^|\/)[^/]+-high$/.test(model)
|
return /(?:^|\/)[^/]+-high$/.test(model)
|
||||||
@@ -12,6 +13,36 @@ function getExplicitHighBaseModel(model: string): string | null {
|
|||||||
return isExplicitHighModel(model) ? model.replace(/-high$/, "") : null
|
return isExplicitHighModel(model) ? model.replace(/-high$/, "") : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseUserFallbackModel(fallbackModel: string): {
|
||||||
|
baseModel: string
|
||||||
|
providerHint?: string[]
|
||||||
|
variant?: string
|
||||||
|
} | undefined {
|
||||||
|
const normalizedFallback = normalizeModel(fallbackModel)
|
||||||
|
if (!normalizedFallback) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedFullModel = parseModelString(normalizedFallback)
|
||||||
|
if (parsedFullModel) {
|
||||||
|
return {
|
||||||
|
baseModel: `${parsedFullModel.providerID}/${parsedFullModel.modelID}`,
|
||||||
|
providerHint: [parsedFullModel.providerID],
|
||||||
|
variant: parsedFullModel.variant,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedModel = parseVariantFromModelID(normalizedFallback)
|
||||||
|
if (!parsedModel.modelID) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
baseModel: parsedModel.modelID,
|
||||||
|
variant: parsedModel.variant,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function resolveModelForDelegateTask(input: {
|
export function resolveModelForDelegateTask(input: {
|
||||||
userModel?: string
|
userModel?: string
|
||||||
@@ -55,20 +86,18 @@ export function resolveModelForDelegateTask(input: {
|
|||||||
const userFallbackModels = input.userFallbackModels
|
const userFallbackModels = input.userFallbackModels
|
||||||
if (userFallbackModels && userFallbackModels.length > 0) {
|
if (userFallbackModels && userFallbackModels.length > 0) {
|
||||||
if (input.availableModels.size === 0) {
|
if (input.availableModels.size === 0) {
|
||||||
const first = normalizeModel(userFallbackModels[0])
|
const first = userFallbackModels[0] ? parseUserFallbackModel(userFallbackModels[0]) : undefined
|
||||||
if (first) {
|
if (first) {
|
||||||
return { model: first }
|
return { model: first.baseModel, variant: first.variant }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const fallbackModel of userFallbackModels) {
|
for (const fallbackModel of userFallbackModels) {
|
||||||
const normalizedFallback = normalizeModel(fallbackModel)
|
const parsedFallback = parseUserFallbackModel(fallbackModel)
|
||||||
if (!normalizedFallback) continue
|
if (!parsedFallback) continue
|
||||||
|
|
||||||
const parts = normalizedFallback.split("/")
|
const match = fuzzyMatchModel(parsedFallback.baseModel, input.availableModels, parsedFallback.providerHint)
|
||||||
const providerHint = parts.length >= 2 ? [parts[0]] : undefined
|
|
||||||
const match = fuzzyMatchModel(normalizedFallback, input.availableModels, providerHint)
|
|
||||||
if (match) {
|
if (match) {
|
||||||
return { model: match }
|
return { model: match, variant: parsedFallback.variant }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const KNOWN_VARIANTS = new Set([
|
|||||||
"thinking",
|
"thinking",
|
||||||
])
|
])
|
||||||
|
|
||||||
function parseVariantFromModelID(rawModelID: string): { modelID: string; variant?: string } {
|
export function parseVariantFromModelID(rawModelID: string): { modelID: string; variant?: string } {
|
||||||
const trimmedModelID = rawModelID.trim()
|
const trimmedModelID = rawModelID.trim()
|
||||||
if (!trimmedModelID) {
|
if (!trimmedModelID) {
|
||||||
return { modelID: "" }
|
return { modelID: "" }
|
||||||
|
|||||||
Reference in New Issue
Block a user