fix(core): prioritize preferred free OpenCode models when signed out (#55972)

This commit is contained in:
Aiden Cline
2026-10-16 01:09:50 -05:00
committed by GitHub
Unverified
parent ccc6a3fd59
commit 4cce6aef4e
2 changed files with 21 additions and 15 deletions
+13 -9
View File
@@ -222,10 +222,7 @@ const layer = Layer.effect(
const all = Array.from(byProvider.values())
.flatMap((models) => Array.from(models.values()))
.sort((left, right) => right.time.released - left.time.released)
cached = freeze(
{ data, all, available: preferBigPickle(all.filter((model) => model.enabled)), byProvider },
true,
)
cached = freeze({ data, all, available: preferFree(all.filter((model) => model.enabled)), byProvider }, true)
return cached
}
})
@@ -290,14 +287,21 @@ const layer = Layer.effect(
export const node = makeLocationNode({ service: Service, layer, deps: [Provider.node, Bus.node, Location.node] })
// Signed out, only free OpenCode models are enabled. Clients default to the first available model, so keep
// big-pickle ahead of each new free launch instead of letting release order pick it.
function preferBigPickle(models: Info[]) {
// these free models ahead of each new free launch instead of letting release order pick the default.
const PREFERRED_FREE = [
"big-pickle",
"deepseek-v4.1-flash-free",
"glm-5.3-flash-free",
"muse-spark-1.3-contributor-free",
]
function preferFree(models: Info[]) {
const freeOnly = models.every(
(model) => model.providerID === Provider.ID.opencode && !model.cost.some((cost) => cost.input > 0),
)
const pick = freeOnly ? models.find((model) => model.id === "big-pickle") : undefined
if (!pick) return models
return [pick, ...models.filter((model) => model !== pick)]
if (!freeOnly) return models
const picks = PREFERRED_FREE.flatMap((id) => models.find((model) => model.id === id) ?? [])
return [...picks, ...models.filter((model) => !picks.includes(model))]
}
export function supportsText(model: Pick<Info, "capabilities">) {
+8 -6
View File
@@ -576,16 +576,18 @@ describe("Provider and Model", () => {
const models = yield* Model.Service
yield* providers.transform((editor) => {
editor.update(Provider.ID.opencode, () => {})
editor.models.update(Provider.ID.opencode, Model.ID.make("big-pickle"), (model) => {
model.time.released = 1000
})
editor.models.update(Provider.ID.opencode, Model.ID.make("new-free"), (model) => {
model.time.released = 2000
})
;["muse-spark-1.3-contributor-free", "new-free", "deepseek-v4.1-flash-free", "big-pickle"].forEach(
(id, index) =>
editor.models.update(Provider.ID.opencode, Model.ID.make(id), (model) => {
model.time.released = 4000 - index * 1000
}),
)
})
expect((yield* models.available()).map((model) => model.id)).toEqual([
Model.ID.make("big-pickle"),
Model.ID.make("deepseek-v4.1-flash-free"),
Model.ID.make("muse-spark-1.3-contributor-free"),
Model.ID.make("new-free"),
])
expect((yield* models.default())?.id).toBe(Model.ID.make("big-pickle"))