downshift
Health Warn
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Deterministic open-source model router — right-sized LLMs per workload. Agent hooks, catalog policy, shadow mode, outcome benchmarks.
Deterministic model routing for coding-agent subagents. No LLM in the routing loop.
Install · Docs · Harness support · Contributing
Beta. Whether a rewrite is applied depends on the harness and plan, not only on Downshift. Read plan compatibility before installing, and see Harness support for what has been verified.
What it is
Downshift is a single Go binary that runs as a hook in your coding harness. When the harness is about to spawn a subagent (a child task), Downshift scores the task text, picks a tier (small / mid / frontier) and a reasoning effort, and rewrites only that subagent's model to a right-sized one from your session's available models. The parent session model never changes. Same input, same decision. No network calls, no API keys.
Example: Your session runs Claude Sonnet 5.5. You spawn 3 subagents — Downshift may route them to Haiku, Sonnet, and Opus respectively, based on task complexity. Billing and token usage happen at the subagent tier, not the session.
What it is not: an HTTP gateway or proxy (that is LiteLLM's job), a hosted model marketplace (OpenRouter), or an LLM-based classifier (Downshift uses deterministic signals + optional local MiniLM semantic scoring). It only acts on subagent spawns inside harnesses that expose a pre-tool hook. Comparison: docs/when-to-use.md.
How it works
Session model stays fixed. Subagent models get routed.
Parent (e.g. Claude Sonnet 5.5) spawns 3 tasks:
Task 1: "rename a variable" → trivial → Haiku (¢ cheaper)
Task 2: "refactor a module" → normal → Sonnet (same tier)
Task 3: "design a new algorithm" → complex → Opus ($ more capable)
Billing and token usage happen at the subagent tier, not the session.
The routing loop:
- Intercept. The harness fires a
PreToolUsehook when a subagent is about to start. Downshift reads the task text in memory only; prompts are never stored. - Classify. Deterministic signals (
internal/core) + optional local MiniLM semantic scoring map the task to a complexity level: trivial, normal, review, or preserved. - Choose. Policy picks a tier. The target must come from the session's model list, ordered least to most capable (session-models.md).
- Rewrite or stay out. Downshift returns the new model in
updatedInput. If anything is unknown or fails, it does nothing and the spawn runs unchanged (fail-open).
Internals: docs/architecture.md. The full runtime routing diagram is here (dark).
Quickstart (Claude Code)
1. Install (macOS / Linux; see install.md for go install and Windows):
curl -fsSL https://raw.githubusercontent.com/tiagovilasboas/downshift/main/install.sh | sh
2. Tell Downshift which models your session can use. Without this the hook never rewrites anything. List the model ids from your picker, least to most capable, in ~/.downshift/session-models.json (or point DOWNSHIFT_SESSION_MODELS at a file):
{
"claude-code": ["claude-haiku-4-5", "claude-sonnet-5-5", "claude-opus-5-5"]
}
Use the ids your account really offers; the file is yours to maintain. Details and per-session lists: session-models.md.
3. Add the hook to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{ "matcher": "Task", "hooks": [{ "type": "command", "command": "downshift claude-code" }] }
]
}
}
Claude Code's Task schema accepts only family names (haiku, sonnet, opus, fable) in model. Downshift writes the catalog's family name for you and leaves the spawn alone when a model has none.
4. Verify.
downshift doctor # version, state dir, catalog source
downshift try "rename the userId variable" claude-code # classification and recommended model
Then spawn a trivial subagent in Claude Code; stderr shows a line like downshift: TRIVIAL task → downshift to …. That proves the hook ran. To confirm the harness applied the rewrite, follow Verify the rewrite was honored. Other harnesses (Cursor, Codex, Antigravity, KiroCrew, Grok) are in install.md.
Harness support
| Harness | Subagent tool | Mechanism | Rewrite honored (evidence) |
|---|---|---|---|
| Claude Code | Task / Agent, paid plans |
PreToolUse → updatedInput.model |
Yes, observed 2026-10-06 (write-up) |
| Codex | spawn_agent (multi_agent_v2) |
PreToolUse → model + reasoning_effort |
Inferred, not observed, 2026-10-02 (write-up) |
| Cursor | Task |
preToolUse → updated_input.model |
Unconfirmed; discarded on Free and legacy Pro plans |
| Antigravity | invoke_subagent |
PreToolUse overwrite |
Not yet observed on a real spawn |
| KiroCrew | spawn_run / spawn_sub_agents |
preToolUse policy (exit 0/2); postToolUse wired for compliance observation |
Policy mode (no rewrite channel); compliance observer in labs |
| Grok CLI | spawn_subagent |
Config in config.toml, not a hook |
No hook rewrite |
Adapters ship for all of the above; the table reports evidence, not just code. Plans, caveats and revalidation rules: harness-matrix.md.
Cost and metrics
- Estimated, not billed.
downshift stats --days=7reports savings estimated from routing decisions. They are not a provider invoice, and no billing-period comparison has been published yet. - Real usage on Claude Code (optional). Add a
SubagentStophook runningdownshift claude-code-subagent-stopto record tokens and cost per subagent from its own transcript. Setup and limits: session-models.md. - Local only. Events go to a local
events.jsonlin the state directory; prompts are not stored. Export format: stats-export.md. - Classifier numbers. Published tier accuracy and outcome-eval results, with their dates and caveats, are in benchmark/REPORT.md. Tune the classifier with
downshift tryand docs/contrib/classifier.md.
Documentation
INSTALL · CONFIG · session models · ARCHITECTURE · HARNESS-MATRIX · WHEN-TO-USE · examples · full index · Português
Project: ROADMAP · GOVERNANCE · beta exit criteria
For AI agents: start with docs/install.md, AGENTS.md and llms.txt.
Contributing
The most valuable contribution is a misrouted prompt: open an issue with the downshift try output and the tier you expected. Evidence that a rewrite was (or was not) honored on your harness and plan is just as welcome. See CONTRIBUTING.md.
Status
Beta. The adapters ship, but the limiting factor is often harness or plan support rather than the router. Exit criteria are tracked in docs/beta-exit.md.
License
Apache License 2.0. See LICENSE, NOTICE and docs/relicense.md.
Downshift by Tiago de Carvalho Vilas Boas · https://github.com/tiagovilasboas/downshift
Conceptual backbone: Harness engineering (Fowler).
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found