opencode-model-tiers
v0.1.10
Published
OpenCode plugin for resolving named model tiers in project and global config.
Maintainers
Readme
opencode-model-tiers
opencode-model-tiers is an OpenCode plugin that resolves named model tiers in
project and global configuration. This project is community-maintained and
isn't affiliated with or endorsed by OpenCode.
Install
To install and create a registry interactively, run:
npx opencode-model-tiers initWhen testing a local checkout, run the initializer with --local from the
target project. This writes a file:///.../index.js plugin entry instead of
installing the published npm package:
cd /path/to/project
node /path/to/opencode-model-tiers/cli.js init --localOr add the plugin to opencode.json manually:
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"[email protected]"
]
}Start OpenCode:
opencodeOpenCode installs npm plugins automatically at startup. Pin the plugin to a
specific version in opencode.json to avoid loading a newer version
implicitly. The initializer writes the current package version when it creates
a config or adds the plugin to an existing config. It leaves existing plugin
entries unchanged, including entries pinned to another version.
Configure tiers
Use tier:<NAME> anywhere OpenCode accepts a model value:
{
"model": "tier:PLAN",
"small_model": "tier:SMALL",
"agent": {
"reviewer": {
"model": "tier:INVESTIGATION"
}
}
}Agent Markdown frontmatter uses the same syntax:
---
model: tier:INVESTIGATION
---Registry
Create a registry as ./.opencode/model-tiers.json for one project:
{
"options": {
"resetModelsOnStart": false
},
"tiers": {
"PLAN": {
"model": "anthropic/claude-opus-4-1",
"variant": "high"
},
"BUILD": {
"model": "anthropic/claude-sonnet-4-5"
},
"INVESTIGATION": {
"model": "anthropic/claude-sonnet-4-5"
},
"SMALL": {
"model": "anthropic/claude-haiku-4-5"
},
"FREE": {
"model": "opencode/free"
}
}
}For a profile registry, use $OPENCODE_CONFIG_DIR/model-tiers.json. For a
global registry, use $XDG_CONFIG_HOME/opencode/model-tiers.json. When
XDG_CONFIG_HOME is unset, use ~/.config/opencode/model-tiers.json.
Lookup order is project, then OPENCODE_CONFIG_DIR, then the XDG global
registry. The first existing file wins. The plugin doesn't fall back if that
file is malformed.
The initializer writes the registry and installs the plugin in the selected
config directory. When existing model fields or agent files are present, it
asks whether to keep each model or replace it with a selected tier. Applying
the changes updates selected JSON or JSONC model fields and Markdown agent
frontmatter to use tier:<NAME>.
Existing flat registries remain supported for compatibility:
{
"PLAN": {
"model": "anthropic/claude-opus-4-1"
}
}The initializer writes the envelope format and asks whether to enable
resetModelsOnStart.
Options
Registry options configure optional plugin behavior. Set
options.resetModelsOnStart to true when you want the registry to restore
the configured model after every OpenCode restart:
{
"options": {
"resetModelsOnStart": true
},
"tiers": {
"PLAN": {
"model": "anthropic/claude-opus-4-1"
},
"BUILD": {
"model": "anthropic/claude-sonnet-4-5"
},
"INVESTIGATION": {
"model": "anthropic/claude-sonnet-4-5"
},
"SMALL": {
"model": "anthropic/claude-haiku-4-5"
},
"FREE": {
"model": "opencode/free"
}
}
}resetModelsOnStart defaults to false. When enabled, the plugin deletes the
persisted model property, clears persisted variant values, and preserves
other state in $XDG_STATE_HOME/opencode/model.json. When
XDG_STATE_HOME is unset, it uses ~/.local/state/opencode/model.json.
The initializer asks for this option and writes either true or false.
Behavior
The plugin applies these rules during OpenCode startup:
- The
tier:prefix is case-insensitive. - Tier names are trimmed, then matched case-sensitively against registry keys.
- Direct model IDs pass through unchanged.
- Top-level
modelandsmall_modelvalues resolve to the tier'smodel. - Enabled, visible agent models resolve to the tier's
model. - An agent tier with
variantreplaces the agent's existing variant. - An agent tier without
variantclears the agent's existing variant. - Disabled and hidden agents are skipped.
- An unknown tier removes its model override and shows a TUI warning, allowing OpenCode to choose its normal default.
- The old
model_tiersetting isn't supported.
Tier variants apply to agent configuration only. Top-level model fields use the tier's model ID and don't set a top-level variant.
Missing, malformed, or inaccessible state files don't prevent tier resolution. The plugin shows a TUI warning when an enabled reset fails.
Upgrade or remove
To upgrade, restart OpenCode after a newer package version is published. To
remove the plugin, delete its entry from the plugin array and restart
OpenCode.
Troubleshooting
Use these checks when a tier doesn't resolve or an old model selection remains visible.
Tier isn't resolved
Check these conditions:
- The registry path matches the project,
OPENCODE_CONFIG_DIR, or global path described above. - The tier name has the same case as the registry key.
- The registry policy contains a string
modelvalue. - A project registry isn't shadowing the global registry.
OpenCode shows a missing-tier warning
The plugin removed the invalid model override. Add the tier to the active registry, or replace the value with a direct model ID, then restart OpenCode.
Old model or variant still appears
Set options.resetModelsOnStart to true, then restart OpenCode after changing
the registry. If the state file is not writable, use the TUI warning to locate
the problem and remove or edit the stale model or variant entry manually.
Local development
Run checks with Node.js:
node --check index.js
npm test
npm pack --dry-run --json
npm publish --dry-runThe test suite also runs under Bun because OpenCode executes npm plugins with
Bun. The package publishes the plugin entry point, the npx initializer, their
runtime modules, and package documentation. Tests, workflows, local registries,
and other repository files stay out of the npm tarball. The initializer uses
@inquirer/prompts for its interactive picker, and npm installs it as a runtime
dependency when the package is used through npx.
For local plugin development, use a generic file URL in OpenCode config:
{
"plugin": [
"file:///absolute/path/to/opencode-model-tiers/index.js"
]
}Releases
Releases publish automatically through GitHub Actions after every push to
main. npm permits each package version only once, so increment version in
package.json before each release push. Pushes with an already-published
version pass checks and skip publishing.
Publishing uses npm Trusted Publishing with GitHub Actions OIDC. Configure the trusted publisher for this package with these values:
- GitHub user:
dartyuhov - Repository:
opencode-model-tiers - Workflow filename:
publish.yml - Allowed action:
npm publish
The workflow needs no npm token secret. After confirming a successful OIDC
publish, revoke any temporary NPM_TOKEN previously used for the first
release.
Push the version change to main to publish it. Don't run npm publish
locally.
