@shawnmandel/openclaw-tier-router
v2.2.0
Published
Rules-based complexity routing across model tiers for OpenClaw
Downloads
34
Maintainers
Readme
Tier Router — OpenClaw Plugin
Rules-based complexity routing across model tiers. Routes simple tasks to cheap/fast local models and complex tasks to capable cloud models, with deterministic classification — no LLM needed for routing decisions.
Why
OpenClaw's native fallback system is failure-recovery only — it tries the next model when the current one fails. This plugin adds pre-routing: every inbound message is classified by complexity and routed to the appropriate model tier before inference begins.
How It Works
The plugin hooks into before_model_resolve — the first hook in OpenClaw's pipeline. It extracts the user's message text, classifies it using deterministic regex patterns, and returns modelOverride + providerOverride to route to the correct tier.
No tokens are consumed for routing. Classification is instant (~1ms).
Routing Rules
Priority order (first match wins):
| Rule | Routes To | Examples |
|---|---|---|
| Manual override keywords | Specified tier | "use opus", "use groq", "use local" |
| File paths detected | Tier 3 | /home/user/config.json, ~/project/ |
| Skill patterns | Tier 3 | "generate image", "run command", "web search" |
| Complex patterns | Tier 2 (short) or Tier 3 (50+ words) | "debug", "architect", "plan", "reason" |
| Debug patterns | Tier 2 | "fix this broken", "not working", "crashed" |
| Moderate patterns | Tier 1 | "code", "script", "install", "git" |
| Long unmatched (80+ words) | Tier 2 | Any long message without keyword matches |
| System messages | Tier 1 | Session startup, heartbeats |
| Everything else | Tier 1 | Default — cheapest model |
Manual Overrides
Include these phrases anywhere in your message to force a specific tier:
- Tier 1: "use local", "use ollama", "use qwen", "use tier1"
- Tier 2: "use groq", "use tier2"
- Tier 3: "use opus", "use claude", "use anthropic", "use tier3"
Installation
Copy the tier-router/ directory into your OpenClaw extensions folder:
~/.openclaw/extensions/tier-router/
├── openclaw.plugin.json
├── index.ts
└── README.mdConfiguration
Add to your openclaw.json:
{
"plugins": {
"allow": ["tier-router"],
"entries": {
"tier-router": {
"enabled": true,
"config": {
"tier1": { "model": "your-local-model", "provider": "ollama" },
"tier2": { "model": "your-mid-model", "provider": "groq" },
"tier3": { "model": "your-best-model", "provider": "anthropic" },
"complexWordThreshold": 50,
"longPromptThreshold": 80
}
}
}
}
}Config Fields
| Field | Type | Default | Description |
|---|---|---|---|
| tier1.model | string | required | Model ID for simple/moderate tasks |
| tier1.provider | string | required | Provider name for Tier 1 |
| tier2.model | string | required | Model ID for complex tasks |
| tier2.provider | string | required | Provider name for Tier 2 |
| tier3.model | string | required | Model ID for skills/tool-calling/deep reasoning |
| tier3.provider | string | required | Provider name for Tier 3 |
| complexWordThreshold | number | 50 | Word count above which complex matches escalate to Tier 3 |
| longPromptThreshold | number | 80 | Word count above which unmatched messages route to Tier 2 |
If no config is provided, the plugin falls back to built-in defaults. For production use, always provide explicit config.
Logs
The plugin logs every routing decision to stdout with the [TIER-ROUTER] prefix:
[TIER-ROUTER] === ROUTING DECISION ===
[TIER-ROUTER] user text: "Debug this config issue"
[TIER-ROUTER] classification: TIER2-COMPLEX
[TIER-ROUTER] model: groq/llama-3.3-70b-versatile
[TIER-ROUTER] reason: complex keyword: "Debug"Filter logs: docker logs <container> --since 5m 2>&1 | grep "TIER-ROUTER"
Known Limitations
- Groq/Llama models cannot do tool-calling in OpenClaw (bug #17598). Skill patterns route to Tier 3 for this reason.
- extractUserText relies on OpenClaw's prompt envelope format. If the format changes, classification may degrade.
- File path detection may false-positive on casual path mentions. URLs are excluded.
/newsession label shows the config default model, not the router override. This is cosmetic — actual inference uses the routed tier.
Requirements
- OpenClaw v2026.3.x or later
configSchemasupport in plugin manifests
License
MIT
