Repository navigation
feat(core): add OPENCODE_DISABLE_FREE_MODELS to hide free models - #57478
Conversation
There was a problem hiding this comment.
This works as described, and I found no blocking issues. I ran opencode models --standalone from source while signed out. Before the change, the 10 free opencode/* models stay listed even with OPENCODE_DISABLE_FREE_MODELS=1. With the change and the flag, none are listed. With OPENCODE_API_KEY set as well, the 74 paid opencode/* models remain. run --model opencode/big-pickle fails with Model unavailable: opencode/big-pickle. The new and existing model tests pass, and typecheck passes in core, server and cli.
The filter is applied when the catalog is read, after plugin changes, so get/all/available/default all respect it and a plugin or config entry can't bring a free model back. Moving the plugin's gating to Model.isFree doesn't change behaviour.
Public API changes, all backwards compatible:
- New environment variable
OPENCODE_DISABLE_FREE_MODELS. ServerOptions.modelsgains an optionalfree: boolean.@opencode/core/modeladds the exportsOptions,configured(options)andisFree.Model.nodeis unchanged (configured()).
Related: #55150
Issue for this PR
N/A
Type of change
What does this PR do?
Adds the env-only
OPENCODE_DISABLE_FREE_MODELS=1(ortrue). Models with no input price are removed from theopencodeandopencode-gocatalogs, defaults and fallbacks. Explicit selection returns the existingModel unavailableerror. Signed out,opencodeis absent; a Console login or API key restores its paid models. Flag-off behavior is unchanged.The runtime diff is just +8/-1 across two files: capture the boolean at each owner's initialization, filter the final model snapshot, and skip signed-out public-key activation. Filtering after transforms prevents model config from recreating free models.
preferFreestays unchanged for flag-off ordering.Removed the server option,
Model.configured, service field, helper, fixture extension and five unrelated fake-service edits. Total PR: 6 files, +173/-1, down from 15 files, +466/-203.Go coverage costs one loop line and matters: with an API key, its zero-cost model otherwise became the default. Explicit provider config can still activate the provider; preserving that existing override avoids adding another activation policy. Free models remain filtered.
How did you verify your code works?
bun run check: passed (34 typecheck tasks; existing lint warnings, zero errors).check:generatedand build/link validation passed.opencode serve, isolated HOME/config, bundled catalog,/api/provider,/api/modeland/api/model/default:opencodeopencode/big-pickle1, signed outtrue+ API keyopencode,opencode-goopencode-go/gemini-4-argon-contributorThe manual API key was synthetic; these checks exercise catalog activation, not paid inference.
Screenshots / recordings
N/A
Checklist
— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊