Files
cleveragents-core/.opencode/models/models.yaml
T
drew 6178be3aa7 feat(models): single-source model registry via models.yaml + sync_models.py
.opencode/models/models.yaml is now the ONE file humans edit to assign a
model to an agent. tools/sync_models.py regenerates every derived surface
— the .opencode/models/*.txt files, opencode.json's `agent` block, and
each non-tier agent's .md `model:` frontmatter — so an assignment cannot
drift across surfaces. `--check` verifies with no writes and is enforced
in CI by test_model_registry_in_sync_with_manifest.

Hardened after adversarial review:
- Deletes orphan <agent>.txt files left behind when an override is
  dropped from the manifest. The dispatcher's resolver reads
  <agent>.txt before default.txt, so a stale file would silently pin
  the old model. Tier .txt files are left to sync_tier_models.py.
- Rejects a manifest key that does not name a real agent (no matching
  .opencode/agents/<name>.md) instead of silently appending a bogus
  opencode.json entry and leaving the real agent on the default model.
- Validates the regenerated opencode.json BEFORE writing it, so a bad
  render aborts cleanly instead of corrupting the file on disk.

Tier-ladder agents (task-implementor-tier-*) remain governed separately
by tiers.yaml + sync_tier_models.py and are passed through untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 07:33:18 -04:00

40 lines
1.8 KiB
YAML

# Model registry — single source of truth for per-agent LLM model
# assignment.
#
# Humans edit ONLY this file. `tools/sync_models.py` regenerates every
# derived artifact so a model assignment can never drift across surfaces:
#
# - .opencode/models/<agent>.txt — read by the dispatcher's resolver
# (_opencode_worker._resolve_role_model)
# - .opencode/models/default.txt — the fallback model
# - the `agent` block of opencode.json — read by OpenCode at startup
# (the channel that drives generation)
#
# opencode.json points each agent at `{file:.../<agent>.txt}`, so both
# consumers read the SAME generated file — the generation model and the
# dispatcher's recorded model cannot disagree.
#
# The pipeline launcher runs `tools/sync_models.py` at every startup
# (before OpenCode caches opencode.json), so editing this file + relaunch
# is all an operator needs. Run `python3 tools/sync_models.py` by hand to
# apply immediately, or `--check` to verify with no writes.
#
# Tier-ladder agents (task-implementor-tier-*) are governed separately by
# tiers.yaml + tools/sync_tier_models.py; sync_models.py leaves their
# opencode.json entries untouched.
#
# Every value is `providerID/modelID`; the provider MUST be declared in
# opencode.json's `provider` block.
# Fallback model for every agent not listed under `agents:` below.
default: local-claude/claude-haiku-4-5
# Per-agent overrides. Only agents that need a NON-default model appear
# here; every other agent resolves to `default` above.
agents:
conflict-resolver-worker: local-claude/claude-opus-4-6
estimator-implementation: local-claude/claude-sonnet-4-6
pr-review-worker: local-claude/claude-sonnet-4-6
pr-review-worker-dispute: local-claude/claude-opus-4-6
ca-test-infra-improver: google/gemini-2.5-pro