A model router on your own machine
Easy requests go to your cheap models. Hard ones go to your strong ones.
Your app sends its requests to delegation-kit instead of to one provider. A decider you pick rates how hard each request is, and the cheapest of your models that can handle it answers. Every answer says which model wrote it, and why.
Get started → How you use it ↓
Free and open source under MIT. Runs on your Mac, with your own keys.
| You send | Decider’s rating | Answered by |
|---|---|---|
| Translate this paragraph into French | Rated 1 of 4 · no minimum | Answered by DeepSeek Flash, or GPT-6 Luna (max), or DeepSeek Flash, or GPT-6 Luna (max) |
| Summarise this contract | Rated 2 of 4 · min 38.4 | Answered by GPT-6.1 Terra, or GPT-6.1 Terra, or GPT-6.1 Terra, or Claude Opus 5.5 |
| Find the race condition in this scheduler | Rated 3 of 4 · code · min 50.4 | Answered by Claude Opus 5.5, or Claude Sonnet 5.5 (max), or GPT-6.1 Sol (max), or Claude Opus 5.5 |
How you use it
Three steps. In your app, only the address and the model name change.
-
Install it
On macOS, with Node.js, jq, git and python3. It sets up the models it knows (Claude and GPT through Claude Code and Codex, Meta Muse through Muse Code or its API, DeepSeek, Qwen, GLM, Kimi, Grok, MiniMax). Keys go in
~/.config/delegation-kit/.env, a file only you can read. Any other model with an API compatible with OpenAI's can be added, a local one too.Terminal
npx delegation-kit delegation-config show # your models -
Choose your models and the decider
Name the models the router may pick from, the decider that rates each request, and the model that answers when the decider can't. Here: GPT-6.1 Terra, DeepSeek Flash and Claude Opus 5.5.
~/.config/delegation-kit/config.json, next to “profiles”
"router": { "decider": { "kind": "llm", "profile": "deepseek-flash" }, "pool": ["terra-builder", "deepseek-flash", "opus-reviewer"], "default": "deepseek-flash" } -
Start it and point your app at it
Anything that uses OpenAI's Chat Completions API works: set the base URL to the router and the model to
"auto". The answer comes back as usual; itsX-Router-Modelheader names the model. An agent loop that sendsX-Router-Conversationstays on the model its first request got. Claude Code and Codex speak other formats: they can't send their requests here, but the router can pick them to answer.Terminal
delegation-router serveYour app (Python, OpenAI SDK)
from openai import OpenAI client = OpenAI(base_url="http://127.0.0.1:4141/v1", api_key="unused") reply = client.chat.completions.create( model="auto", messages=[{"role": "user", "content": "Rename foo to bar in utils.py"}], )
How it picks a model
-
Measured efforts get a score
Artificial Analysis publishes a versioned set of model tests. Unmeasured efforts stay unknown. Within 8 points of the day's best: frontier. Within 20: mid. The rest: small.
-
Your decider rates the request
It reads an excerpt, never your keys or your list of models, and answers: how hard is this, 0 to 4, half points allowed? Code, math, rare knowledge?
-
The cheapest one strong enough answers
The rating sets a minimum score: none for 0–1, 38.4 for 2, 50.4 for 3–4, in between for half points. Math or rare knowledge: 38.4 at least. The cheapest of your models above it answers; none above? Your strongest. No rating? Your default.
Intelligence Index v5.0 · 2026-10-28
21 models plotted; glm-5.3-flash, mistral-medium-3.5, mistral-small-2603, muse-spark-1.3-contributor, qwen3.8-flash have no score yet.
Ringed dots use the efforts in this example; other dots use each model's best measured setting. Unmeasured results stay off the chart. The amber line is a request's minimum score: the cheapest ringed model at or above it answers. Refresh the scores with your own Artificial Analysis key, or set any model's tier yourself.
With your three models
| You send | Decider’s rating | Answered by | Why |
|---|---|---|---|
| Translate this paragraph into French | Rated 1 of 4 · no minimum | Answered by DeepSeek Flash small ~$0.0013 a request | Why No minimum: the cheapest of your models, DeepSeek Flash. |
| Summarise this contract | Rated 2 of 4 · min 38.4 | Answered by GPT-6.1 Terra mid ~$0.0054 a request | Why Minimum 38.4: Terra (42.3) clears it and is the cheapest that does. |
| Find the race condition in this scheduler | Rated 3 of 4 · code · min 50.4 | Answered by Claude Opus 5.5 frontier ~$0.0217 a request | Why Minimum 50.4: only Opus 5.5 (58.4) reaches it. |
| Rename foo to bar in utils.py | Rated 1 of 4 · code · no minimum | Answered by DeepSeek Flash small ~$0.0013 a request | Why No minimum: the cheapest code-capable model in this pool, DeepSeek Flash. |
| What is 17% of 2,340? | Rated 1 of 4 · math · min 38.4 | Answered by GPT-6.1 Terra mid ~$0.0054 a request | Why Easy, but math raises the minimum to 38.4: Terra (42.3) still clears it. |
| Any request, when the decider times out | Rated no rating | Answered by DeepSeek Flash small ~$0.0013 a request | Why No rating: your default model answers, and the response says so. |