<!-- Markdown mirror. Canonical: https://empryo.com/docs/recipes/task-router -->

# Use multiple models

> Assign cheap models to exploration and strong models to code edits with Empryo's task router slots, cutting token cost without losing quality on real work.

Assign different models to different tasks. Haiku searches your codebase, Sonnet writes the code, Flash compacts context.

## Let the agent pick by price

Ask for it: *"put the summaries and the tab names on the cheapest model that can do them."*

The agent reads the live catalog with published prices, USD per million tokens, input, output
and both cache legs where the catalog carries them, and writes the slot for you:

```text
haiku · 200k ctx · in $1 / out $5 / cache-r $0.1 / cache-w $1.25
```

Prices come from the provider's own listing or [models.dev](https://models.dev), a model nobody
published a price for simply shows none, and the agent will say so rather than guess. They are
list rates. Your discounts, tax, and subscription seats where tokens are not billed at all are
not in them. The write merges one slot at a time, so the rest of your router is untouched.

## Open the router

```
/router
```

On desktop, the **Routing** button in chat and the top-right toolbar open a side panel.
The panel stays open when you switch tabs. Each tab keeps its own routing draft.

- **Main agent** controls the chat model and Marionette prompt preparation.
- **Dispatch** controls delegated explorers and coders, including their Cleanup and Code review switches.
- Each model has an effort selector when that model supports reasoning effort.
- **Save to this tab** saves the models, efforts, switches and parallel-agent limit to that session. Finish or stop a running turn first.
- **Apply to all tabs** asks before replacing routing in the listed open tabs. It does not change saved defaults or future tabs. Busy tabs are skipped, not queued. Busy and failed tabs remain listed for an explicit retry.

Model routing lives in the tab panel, not Settings. **Settings → Agent behavior**, directly above Genome, holds shared behavior switches, custom-agent defaults and failover chains. A tab-specific routing setup is a snapshot: automatic slots follow its role fallbacks, not later changes to shared defaults.

Parallel agents default to **16**. Choose **Unlimited** to remove Empryo's concurrency cap (`maxConcurrentAgents: 0` in config). Existing explicit limits are preserved. Provider rate limits, available memory and the separate tasks-per-dispatch limit still apply.

Or edit `~/.empryo/config.json`:

```json
{
  "taskRouter": {
    "spark":      "anthropic/claude-haiku-4-5",
    "ember":      "anthropic/claude-sonnet-4-5",
    "explore":    "anthropic/claude-haiku-4-5",
    "webSearch":  "anthropic/claude-haiku-4-5",
    "desloppify": "anthropic/claude-haiku-4-5",
    "verify":     "anthropic/claude-haiku-4-5",
    "goalReview": "anthropic/claude-sonnet-4-5",
    "review":     "anthropic/claude-sonnet-4-5",
    "compact":    "google/gemini-2.5-flash",
    "semantic":   "anthropic/claude-haiku-4-5",
    "default":    null
  }
}
```

## What each slot does

| Slot | Runs when | Good choice |
|------|-----------|-------------|
| `spark` | Dispatched read-only agents explore your code | Fast/cheap (Haiku, Flash) |
| `ember` | Dispatched agents that edit files | Strong coding model (Sonnet, Opus) |
| `explore` | The solo `explore` agent. Unset falls back to `spark` | Fast/cheap |
| `webSearch` | Web search agents. Unset disables the agentic path | Fast/cheap |
| `desloppify` | Cleanup pass after code edits | Fast/cheap |
| `verify` | Adversarial review after code edits | Medium strength |
| `goalReview` | The goal-loop reviewer, with its own clean context | Medium/strong |
| `review` | On-demand `/review`. Unset falls back to `goalReview` | Medium/strong |
| `compact` | Context compaction | Fast/cheap (Flash is ideal) |
| `semantic` | Genome one-line symbol summaries | Fast/cheap |
| `default` | Fallback when no slot matches | - |

Leaving a slot unset is a real choice, not just a blank. `spark` inherits the
model your turn is already using, which means it shares that model's prompt-cache
prefix, routing it to something cheaper can cost you more in cache misses than
it saves per token. Measure before you split it. A slot pointing at a model that
fails to resolve degrades to inherit rather than killing the turn.

## Recommended setups

#### Balanced

Strong code, cheap everything else.
```json
"spark": "anthropic/claude-haiku-4-5",
"ember": "anthropic/claude-sonnet-4-5",
"compact": "google/gemini-2.5-flash"
```

#### Budget

Haiku everywhere. Still very capable for most tasks.
```json
"spark": "anthropic/claude-haiku-4-5",
"ember": "anthropic/claude-haiku-4-5",
"compact": "google/gemini-2.5-flash"
```

#### Max quality

Sonnet for code, Sonnet for exploration too.
```json
"spark": "anthropic/claude-sonnet-4-5",
"ember": "anthropic/claude-sonnet-4-5",
"compact": "google/gemini-2.5-flash"
```

#### One gateway

Same models, one key via LLM Gateway.
```json
"spark": "llmgateway/claude-haiku-4-5",
"ember": "llmgateway/claude-sonnet-4-5"
```

## Why this saves money

Agents spend ~70% of their tokens on exploration (reading files, running greps, navigating the Genome). That work doesn't need an expensive model. Reserve your strong model for the ~30% that's actually writing code.
