fix: model selection precedence to prefer provider default over agent model (#36)
Fixes #35. The app was selecting claude-sonnet-4-6 (agent default) instead of gpt-5.4 (provider default), causing send_message failures in CI where only Azure provider is available.
This commit is contained in:
50
src/lib/model-selection.test.ts
Normal file
50
src/lib/model-selection.test.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { test } from "node:test"
|
||||
import assert from "node:assert/strict"
|
||||
import { chooseModelSelection } from "./model-selection.ts"
|
||||
|
||||
const providers = [
|
||||
{
|
||||
id: "azure",
|
||||
models: [{ id: "gpt-5.4" }, { id: "gpt-5.2" }],
|
||||
},
|
||||
]
|
||||
|
||||
test("keeps existing selection when still available", () => {
|
||||
const selected = chooseModelSelection({
|
||||
providers,
|
||||
defaults: { azure: "gpt-5.4" },
|
||||
existing: { providerID: "azure", modelID: "gpt-5.2" },
|
||||
agentModel: { providerID: "azure", modelID: "claude-sonnet-4-6" },
|
||||
})
|
||||
assert.deepEqual(selected, { providerID: "azure", modelID: "gpt-5.2" })
|
||||
})
|
||||
|
||||
test("prefers provider default over unavailable agent model", () => {
|
||||
const selected = chooseModelSelection({
|
||||
providers,
|
||||
defaults: { azure: "gpt-5.4" },
|
||||
existing: null,
|
||||
agentModel: { providerID: "azure", modelID: "claude-sonnet-4-6" },
|
||||
})
|
||||
assert.deepEqual(selected, { providerID: "azure", modelID: "gpt-5.4" })
|
||||
})
|
||||
|
||||
test("falls back to first connected provider model when default missing", () => {
|
||||
const selected = chooseModelSelection({
|
||||
providers,
|
||||
defaults: {},
|
||||
existing: null,
|
||||
agentModel: null,
|
||||
})
|
||||
assert.deepEqual(selected, { providerID: "azure", modelID: "gpt-5.4" })
|
||||
})
|
||||
|
||||
test("returns null when no connected providers", () => {
|
||||
const selected = chooseModelSelection({
|
||||
providers: [],
|
||||
defaults: {},
|
||||
existing: null,
|
||||
agentModel: null,
|
||||
})
|
||||
assert.equal(selected, null)
|
||||
})
|
||||
50
src/lib/model-selection.ts
Normal file
50
src/lib/model-selection.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
export interface ProviderModelRef {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface ProviderRef {
|
||||
id: string
|
||||
models: ProviderModelRef[]
|
||||
}
|
||||
|
||||
export interface ModelSelection {
|
||||
providerID: string
|
||||
modelID: string
|
||||
}
|
||||
|
||||
export function isModelAvailable(
|
||||
providers: ProviderRef[],
|
||||
selection: ModelSelection | null | undefined,
|
||||
): selection is ModelSelection {
|
||||
if (!selection) return false
|
||||
const provider = providers.find((p) => p.id === selection.providerID)
|
||||
if (!provider) return false
|
||||
return provider.models.some((m) => m.id === selection.modelID)
|
||||
}
|
||||
|
||||
export function chooseModelSelection(params: {
|
||||
providers: ProviderRef[]
|
||||
defaults: Record<string, string>
|
||||
existing: ModelSelection | null
|
||||
agentModel: ModelSelection | null
|
||||
}): ModelSelection | null {
|
||||
const { providers, defaults, existing, agentModel } = params
|
||||
|
||||
if (isModelAvailable(providers, existing)) return existing
|
||||
|
||||
for (const provider of providers) {
|
||||
const defaultModelID = defaults[provider.id]
|
||||
if (!defaultModelID) continue
|
||||
if (provider.models.some((m) => m.id === defaultModelID)) {
|
||||
return { providerID: provider.id, modelID: defaultModelID }
|
||||
}
|
||||
}
|
||||
|
||||
if (providers.length > 0 && providers[0].models.length > 0) {
|
||||
return { providerID: providers[0].id, modelID: providers[0].models[0].id }
|
||||
}
|
||||
|
||||
if (isModelAvailable(providers, agentModel)) return agentModel
|
||||
|
||||
return null
|
||||
}
|
||||
Reference in New Issue
Block a user