Skip to content

Multi-Adapter Model Routing

Route different LLM models to different pipeline steps for cost optimization and provider resilience.

Model Tier System

Wave classifies pipeline steps into three complexity tiers based on persona and step characteristics:

TierIntentUse Case
cheapestCost-optimizedNavigation, summarization, scanning
balancedLatency-optimizedBalanced speed/cost for standard tasks
strongestCapability-optimizedComplex reasoning, code generation

Adapter Tier Models

Each adapter can define tier-specific model mappings:

yaml
adapters:
  claude:
    binary: claude
    default_model: sonnet
    tier_models:
      cheapest: haiku
      balanced: ""
      strongest: opus
  opencode:
    binary: opencode
    default_model: opencode/big-pickle
    tier_models:
      cheapest: opencode/big-pickle
      balanced: opencode/big-pickle
      strongest: opencode/big-pickle

When auto_route: true is enabled, Wave uses these tier mappings to select models automatically.

Auto-Routing

Enable automatic model selection based on step complexity:

yaml
routing:
  auto_route: true
  complexity_map:
    cheapest: haiku
    balanced: ""
    strongest: opus

Override specific tiers in wave.yaml routing section, or use adapter-level tier_models for per-adapter mappings.

Per-Step Model Assignment

yaml
steps:
  - id: analyze
    persona: navigator
    model: haiku          # explicit override

  - id: implement
    persona: craftsman
    # no model — uses adapter tier model based on complexity

  - id: review
    persona: reviewer
    model: haiku          # cheap model for review

Adapter Resolution (strongest to weakest)

PrioritySourceScopeExample
1CLI --adapter flagEntire runwave run impl-issue --adapter opencode
2Step-level adapter:Single stepadapter: codex in pipeline YAML
3Persona-level adapter:Steps using that personaadapter: claude in persona definition
4Adapter defaultSteps with no overrideFalls back to first configured adapter
yaml
adapters:
  claude:
    binary: claude
    mode: headless
  opencode:
    binary: opencode
    mode: headless
  codex:
    binary: codex
    mode: headless
  gemini:
    binary: gemini
    mode: headless

CLI Adapter Override

Use --adapter <name> to override the adapter for all steps in a run:

bash
wave run ops-hello-world --adapter opencode --model "zai-coding-plan/glm-5-turbo"

Override per step in pipeline YAML:

yaml
- id: implement
  adapter: codex              # use OpenAI Codex for this step
  model: gpt-4o

Model Format Differences

Each adapter uses a different model identifier format:

AdapterFormatExamples
claudeShort namessonnet, haiku, opus
opencodeprovider/modelzai-coding-plan/glm-5-turbo, anthropic/claude-sonnet-4-20250514
geminiPlain namesgemini-2.0-pro, gemini-2.5-flash
codexOpenAI identifiersgpt-4o, o3

Fallback Chains

When a provider fails, try alternatives:

yaml
runtime:
  fallbacks:
    anthropic: [openai, gemini]
    openai: [anthropic]

Fallback only triggers on transient failures (rate limits, timeouts). Permanent failures (auth errors, missing binary) do not fallback.

Persona-Level Defaults

Personas can declare a preferred model, overridable at step level:

yaml
# .wave/personas/analyst.yaml
name: analyst
model: haiku
adapter: claude

Released under the MIT License.