ADR-0008: Provider-agnostic `ModelTier`
ADR-0008: Provider-agnostic ModelTier
Section titled “ADR-0008: Provider-agnostic ModelTier”Status: Accepted Date: 2026-04-20
Context
Section titled “Context”The platform routes different tasks to different language models — cheap and fast for sub-agents, mid-range for main agents, top-tier for critical decisions. We also plan to use more than one provider: Anthropic for reasoning, OpenAI for image generation and embeddings, possibly others later.
If agent definitions name specific models ("claude-sonnet-4.5", "gpt-5"), every model upgrade requires editing every agent file. Worse, it couples agent configuration to provider identity — a pain point if we ever add a new provider or want to run a silent A/B.
Decision
Section titled “Decision”Agent definitions declare a capability tier, not a model:
export type ModelTier = 'critical' | 'main' | 'sub';The runtime maintains a mapping from ModelTier (and provider) to concrete model identifier. An agent asking for the main tier gets whatever we’ve decided is the right main-tier model at that moment.
Consequences
Section titled “Consequences”- Agent definitions survive model upgrades untouched.
- Swapping providers is a runtime mapping change; agent YAML stays the same.
- Routing logic — tier → model, with optional per-agent overrides and provider selection — lives in one place and is testable on its own.
- We lose the ability to hard-code “this specific agent always uses Haiku.” Acceptable now; if we need fine-grained control later, we can add a per-agent override field without breaking the tier abstraction.
- The three-tier bucket is a deliberately coarse choice. More tiers can be added, but “critical / main / sub” maps cleanly to how we actually reason about agent cost vs capability.
Alternatives considered
Section titled “Alternatives considered”- Direct model names in agent definitions: tight coupling, painful upgrades, fights portability.
- Numeric tiers (
1/2/3): semantically opaque; new contributors have to learn what the numbers mean. - Anthropic-specific tier names (
opus/sonnet/haiku): works today but becomes a lie as soon as we route to OpenAI. The abstraction has to be vendor-neutral to be honest. - No abstraction; use the LLM SDK’s model field directly: same problem as direct model names, with worse ergonomics.