fix: let server decide model when no user selection exists (#37)
Registry defaults unreliable for deployed models; return null so server uses its configured model. Fixes #35.
This commit is contained in:
@@ -5,7 +5,7 @@ import { chooseModelSelection } from "./model-selection.ts"
|
||||
const providers = [
|
||||
{
|
||||
id: "azure",
|
||||
models: [{ id: "gpt-5.4" }, { id: "gpt-5.2" }],
|
||||
models: [{ id: "gpt-5.4" }, { id: "gpt-5.2" }, { id: "claude-sonnet-4-6" }],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -14,29 +14,31 @@ test("keeps existing selection when still available", () => {
|
||||
providers,
|
||||
defaults: { azure: "gpt-5.4" },
|
||||
existing: { providerID: "azure", modelID: "gpt-5.2" },
|
||||
agentModel: { providerID: "azure", modelID: "claude-sonnet-4-6" },
|
||||
agentModel: null,
|
||||
})
|
||||
assert.deepEqual(selected, { providerID: "azure", modelID: "gpt-5.2" })
|
||||
})
|
||||
|
||||
test("prefers provider default over unavailable agent model", () => {
|
||||
test("returns null when no existing selection (let server decide)", () => {
|
||||
// Even though defaults and providers exist, we return null to let
|
||||
// the server use its own configured model from opencode.json
|
||||
const selected = chooseModelSelection({
|
||||
providers,
|
||||
defaults: { azure: "gpt-5.4" },
|
||||
defaults: { azure: "claude-sonnet-4-6" },
|
||||
existing: null,
|
||||
agentModel: { providerID: "azure", modelID: "claude-sonnet-4-6" },
|
||||
})
|
||||
assert.deepEqual(selected, { providerID: "azure", modelID: "gpt-5.4" })
|
||||
assert.equal(selected, null)
|
||||
})
|
||||
|
||||
test("falls back to first connected provider model when default missing", () => {
|
||||
test("returns null when existing selection no longer available", () => {
|
||||
const selected = chooseModelSelection({
|
||||
providers,
|
||||
defaults: {},
|
||||
existing: null,
|
||||
defaults: { azure: "gpt-5.4" },
|
||||
existing: { providerID: "azure", modelID: "nonexistent-model" },
|
||||
agentModel: null,
|
||||
})
|
||||
assert.deepEqual(selected, { providerID: "azure", modelID: "gpt-5.4" })
|
||||
assert.equal(selected, null)
|
||||
})
|
||||
|
||||
test("returns null when no connected providers", () => {
|
||||
|
||||
@@ -22,29 +22,31 @@ export function isModelAvailable(
|
||||
return provider.models.some((m) => m.id === selection.modelID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses a model selection for the session.
|
||||
*
|
||||
* Returns `null` when there is no prior user-explicit choice. A null model
|
||||
* means the server's configured default (opencode.json `"model"` field) will
|
||||
* be used — which is the correct behavior for first-launch and CI where the
|
||||
* provider registry's "default" model may not be deployed on the user's
|
||||
* resource.
|
||||
*
|
||||
* Only returns a non-null value when the user previously made an explicit
|
||||
* selection that is still valid (model available on a connected provider).
|
||||
*/
|
||||
export function chooseModelSelection(params: {
|
||||
providers: ProviderRef[]
|
||||
defaults: Record<string, string>
|
||||
existing: ModelSelection | null
|
||||
agentModel: ModelSelection | null
|
||||
}): ModelSelection | null {
|
||||
const { providers, defaults, existing, agentModel } = params
|
||||
const { providers, existing } = params
|
||||
|
||||
// Keep existing user-chosen selection if it's still reachable
|
||||
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
|
||||
|
||||
// Otherwise return null — let the server decide via its own config.
|
||||
// The provider registry's "defaults" map is unreliable (it lists the
|
||||
// upstream registry default, not what's deployed on the user's resource).
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user