fix(provider): make small model fallback optional (#27405)

This commit is contained in:
Kit Langton
2026-05-13 20:44:34 -04:00
committed by GitHub
parent 5e41dbbcbf
commit 9818c9e8d0
2 changed files with 28 additions and 5 deletions

View File

@@ -1707,7 +1707,9 @@ const layer = Layer.effect(
if (cfg.small_model) {
const parsed = parseModel(cfg.small_model)
return yield* getModel(parsed.providerID, parsed.modelID).pipe(Effect.orDie)
return yield* getModel(parsed.providerID, parsed.modelID).pipe(
Effect.catchTag("ProviderModelNotFoundError", () => Effect.succeed(undefined)),
)
}
const s = yield* InstanceState.get(state)
@@ -1735,22 +1737,22 @@ const layer = Layer.effect(
const candidates = Object.keys(provider.models).filter((m) => m.includes(item))
const globalMatch = candidates.find((m) => m.startsWith("global."))
if (globalMatch) return yield* getModel(providerID, ModelID.make(globalMatch)).pipe(Effect.orDie)
if (globalMatch) return provider.models[globalMatch]
const region = provider.options?.region
if (region) {
const regionPrefix = region.split("-")[0]
if (regionPrefix === "us" || regionPrefix === "eu") {
const regionalMatch = candidates.find((m) => m.startsWith(`${regionPrefix}.`))
if (regionalMatch) return yield* getModel(providerID, ModelID.make(regionalMatch)).pipe(Effect.orDie)
if (regionalMatch) return provider.models[regionalMatch]
}
}
const unprefixed = candidates.find((m) => !crossRegionPrefixes.some((p) => m.startsWith(p)))
if (unprefixed) return yield* getModel(providerID, ModelID.make(unprefixed)).pipe(Effect.orDie)
if (unprefixed) return provider.models[unprefixed]
} else {
for (const model of Object.keys(provider.models)) {
if (model.includes(item)) return yield* getModel(providerID, ModelID.make(model)).pipe(Effect.orDie)
if (model.includes(item)) return provider.models[model]
}
}
}

View File

@@ -1025,6 +1025,27 @@ test("getSmallModel respects config small_model override", async () => {
})
})
test("getSmallModel ignores invalid config small_model", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
await Bun.write(
path.join(dir, "opencode.json"),
JSON.stringify({
$schema: "https://opencode.ai/config.json",
small_model: "anthropic/not-a-real-model",
}),
)
},
})
await WithInstance.provide({
directory: tmp.path,
fn: async () => {
set("ANTHROPIC_API_KEY", "test-api-key")
expect(await getSmallModel(ProviderID.anthropic)).toBeUndefined()
},
})
})
test("provider.sort prioritizes preferred models", () => {
const models = [
{ id: "random-model", name: "Random" },