SOTA LLM router — 98% accuracy, OpenAI + Anthropic compatible, <1ms local routing
Project description
UncommonRoute
SOTA LLM Router — 98% accuracy, <1ms local routing
Route every LLM request to the optimal model.
Step-aware agentic routing, 39-feature cascade classifier, session persistence, spend control.
Pure local — no external API calls for routing decisions.
Quick Navigation
| Section | Description |
|---|---|
| Quick Start | Install and choose your client |
| Usage Modes | CLI, SDK, Proxy, Claude Code, Codex, OpenClaw |
| Dashboard | Web UI for monitoring and management |
| How It Works | Cascade classifier architecture |
| Model Mapping | Automatic upstream model discovery |
| Routing Tiers | SIMPLE → MEDIUM → COMPLEX → REASONING |
| Step-Aware Routing | Per-step model selection for agent workflows |
| Session Management | Smart sessions, auto-escalation |
| Spend Control | Per-request, hourly, daily limits |
| Diagnostics | doctor, logs, background mode |
| Models & Pricing | Supported models and costs |
| Configuration | Upstream, env vars, BYOK |
| Benchmarks | Accuracy & latency results |
Quick Start
pip install uncommon-route
Choose your client:
| Client | Setup command |
|---|---|
| CLI / Python SDK | No config needed — uncommon-route route "hello" |
| Claude Code | uncommon-route setup claude-code |
| OpenAI Codex | uncommon-route setup codex |
| OpenAI SDK / Cursor | uncommon-route setup openai |
| OpenClaw | openclaw plugins install @anjieyang/uncommon-route |
Each setup command prints the exact environment variables for your shell.
Manual setup (all clients)
# 1. Configure upstream (any OpenAI-compatible API)
export UNCOMMON_ROUTE_UPSTREAM="https://api.commonstack.ai/v1"
export UNCOMMON_ROUTE_API_KEY="csk-..."
# 2. Start the proxy
uncommon-route serve
# 3. Check everything works
uncommon-route doctor
One-line installer
curl -fsSL https://anjieyang.github.io/uncommon-route/install | bash
Usage Modes
1. CLI
uncommon-route route "what is 2+2"
# Model: moonshot/kimi-k2.5 Tier: SIMPLE Savings: 97%
uncommon-route route --json "design a distributed database"
# Full JSON with model, tier, confidence, cost, fallback chain
uncommon-route debug "explain quicksort"
# Per-dimension scoring breakdown (structural + keyword + unicode)
uncommon-route doctor
# Check Python version, upstream, API key, model discovery, BYOK keys
uncommon-route serve --daemon # Run proxy in background
uncommon-route stop # Stop background proxy
uncommon-route logs --follow # Tail background proxy log
2. Python SDK
from uncommon_route import route, classify
decision = route("explain the Byzantine Generals Problem")
print(decision.model) # google/gemini-3.1-pro
print(decision.tier) # COMPLEX
print(decision.confidence) # 0.87
print(decision.savings) # 0.76
# Classification only (no model selection)
result = classify("hello")
print(result.tier) # SIMPLE
print(result.signals) # ['short_prompt', 'greeting_pattern']
3. HTTP Proxy (OpenAI-compatible)
uncommon-route serve --port 8403
Works with any OpenAI SDK client:
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:8403/v1",
api_key="your-upstream-key",
)
response = client.chat.completions.create(
model="uncommon-route/auto", # smart routing
messages=[{"role": "user", "content": "hello"}],
)
| Endpoint | Method | Format | Description |
|---|---|---|---|
/v1/chat/completions |
POST | OpenAI | Chat with smart routing |
/v1/messages |
POST | Anthropic | Chat with smart routing (auto-routes all requests) |
/v1/models |
GET | OpenAI | Available models |
/v1/models/mapping |
GET | — | Model name mapping (internal → upstream) |
/v1/spend |
GET/POST | — | Spend control |
/v1/sessions |
GET | — | Active sessions |
/v1/stats |
GET/POST | — | Routing analytics |
/v1/feedback |
GET/POST | — | Online learning feedback |
/health |
GET | — | Health + status |
/dashboard |
GET | — | Web management UI |
4. Claude Code
uncommon-route setup claude-code # prints env vars for your shell
Claude Code connects via the Anthropic Messages API (/v1/messages). All requests are automatically smart-routed — the proxy converts between Anthropic and OpenAI formats transparently.
# Terminal 1
uncommon-route serve
# Terminal 2
export ANTHROPIC_BASE_URL="http://localhost:8403"
export ANTHROPIC_API_KEY="not-needed"
claude
5. OpenAI Codex
uncommon-route setup codex # prints env vars for your shell
Codex connects via the OpenAI Chat Completions API (/v1/chat/completions). Use model="uncommon-route/auto" for smart routing.
# Terminal 1
uncommon-route serve
# Terminal 2
export OPENAI_BASE_URL="http://localhost:8403/v1"
export OPENAI_API_KEY="not-needed"
codex
6. OpenClaw Plugin
openclaw plugins install @anjieyang/uncommon-route
The plugin auto-installs Python dependencies, starts the proxy, and registers everything. Available commands in OpenClaw:
| Command | Description |
|---|---|
/route <prompt> |
Preview routing decision |
/spend status |
View spending limits |
/spend set hourly 5.00 |
Set hourly limit |
/sessions |
View active sessions |
Dashboard
UncommonRoute includes a built-in web dashboard for monitoring and management. After starting the proxy, visit:
http://127.0.0.1:8403/dashboard/
| Tab | What it shows |
|---|---|
| Overview | KPI cards (requests, savings, latency, sessions, cost), tier distribution chart, top models |
| Routing | Breakdown by tier, model, and routing method |
| Models | Upstream model discovery status, full internal → resolved mapping table |
| Sessions | Active sessions with model, tier, request count, age |
| Spend | Current limits, set/clear limits, spending history |
Data auto-refreshes every 5 seconds. Built with React + Tremor + Tailwind CSS.
Model Mapping
Different upstream providers use different model IDs for the same model. For example, UncommonRoute internally uses moonshot/kimi-k2.5, but Commonstack expects moonshotai/kimi-k2.5.
UncommonRoute handles this automatically:
- On startup, the proxy fetches
/v1/modelsfrom the upstream to discover available models - Fuzzy matching maps internal names to upstream names — handles provider prefix differences (
xai/↔x-ai/), version format changes (4.6↔4-6), and suffix additions (-preview) - Gateway detection — gateways (Commonstack, OpenRouter) receive the full
provider/modelformat; direct provider APIs receive only the model name - Fallback retry — if the upstream rejects a model, the proxy automatically tries the next model in the fallback chain
Check the mapping status:
uncommon-route doctor # Shows model discovery status
curl localhost:8403/v1/models/mapping # Full mapping table as JSON
How It Works
UncommonRoute uses a cascade classifier with three levels:
Input Prompt
│
▼
┌─────────────────────┐
│ 1. Trivial Override │ greeting / empty / very long → instant decision
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ 2. Learned Model │ Averaged Perceptron on 39 features
│ (356µs avg) │ 12 structural + 15 unicode + 12 keyword
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ 3. Rule Fallback │ hand-tuned weights when model unavailable
└─────────┬───────────┘
│
▼
Tier + Model + Cost
Feature Groups (39 total)
Structural (12): normalized_length, enumeration_density, sentence_count, code_markers, math_symbols, nesting_depth, vocabulary_diversity, avg_word_length, alphabetic_ratio, functional_intent, unique_concept_density, requirement_phrases
Unicode (15): basic_latin, latin_ext, cyrillic, arabic, devanagari, thai, hangul_jamo, cjk_unified, hiragana, katakana, hangul_syllables, punctuation, digits, symbols_math
Keyword (12): code_presence, reasoning_markers, technical_terms, creative_markers, simple_indicators, imperative_verbs, constraint_count, output_format, domain_specificity, agentic_task, analytical_verbs, multi_step_patterns
Routing Tiers
The router classifies each prompt and selects the cheapest model that can handle it. Default primary models are chosen for cost efficiency — all models (including OpenAI, Claude) are accessible through the upstream provider.
| Tier | When | Default Primary | Fallback Chain | Example |
|---|---|---|---|---|
| SIMPLE | Greetings, lookups, translations | moonshot/kimi-k2.5 | gemini-2.5-flash-lite, deepseek-chat | "what is 2+2" |
| MEDIUM | Code tasks, explanations, summaries | moonshot/kimi-k2.5 | deepseek-chat, gemini-2.5-flash-lite | "explain quicksort" |
| COMPLEX | Multi-requirement system design | google/gemini-3.1-pro | gemini-2.5-pro, gpt-5.2, claude-sonnet-4.6 | "design a distributed DB with 5 requirements..." |
| REASONING | Formal proofs, mathematical derivations | xai/grok-4-1-fast-reasoning | deepseek-reasoner, o4-mini, o3 | "prove sqrt(2) is irrational" |
Note: OpenAI and Claude models appear in COMPLEX/REASONING fallback chains. To make them the preferred choice across all tiers, use BYOK provider configuration.
Step-Aware Routing
In agentic workflows (OpenClaw, LangChain, etc.), different steps within a single task need different model capabilities. UncommonRoute detects the step type from the request body and routes accordingly:
| Step Type | Detection | Routing Behavior |
|---|---|---|
| Tool-result followup | Last message role: "tool" |
Classifier decides freely — allows cheap model for processing tool output |
| Tool selection | tools present + last message from user |
Normal session logic |
| General | No agentic signals | Normal session logic |
Before (blind session pin): Agent session pinned to $25/M model for all 200 requests — including "I read this file" steps.
After (step-aware): Tool-result steps automatically use $0.40-2.50/M models. Only steps that need reasoning use expensive models.
The step type is visible in the x-uncommon-route-step response header.
Session Management
Sessions prevent unnecessary model switching mid-task while allowing cost optimization:
- Always re-route — every request gets a fresh classification based on content
- Only upgrade, never downgrade — if the classifier says COMPLEX and the session is MEDIUM, upgrade; if it says SIMPLE, hold the session model
- Lightweight exception — tool-result steps bypass session hold and use the classifier's recommendation directly
- 30-minute timeout — sessions auto-expire after inactivity
- Three-strike escalation — 3 identical requests → auto-upgrade to next tier (skipped for tool-result steps)
# Sessions work via header
headers = {"X-Session-ID": "my-task-123"}
# OpenClaw's x-openclaw-session-key also supported
# Or auto-derived from first user message
Spend Control
Set spending limits to prevent runaway costs:
uncommon-route spend set per_request 0.10 # max $0.10 per call
uncommon-route spend set hourly 5.00 # max $5/hour
uncommon-route spend set daily 20.00 # max $20/day
uncommon-route spend set session 3.00 # max $3/session
uncommon-route spend status # view current spending
uncommon-route spend history # recent records
When a limit is hit, the proxy returns HTTP 429 with reset_in_seconds.
Data persists at ~/.uncommon-route/spending.json.
Diagnostics
Health Check
uncommon-route doctor
Checks Python version, upstream connectivity, API key validity, model discovery, BYOK provider status, and daemon state. Run this first when something isn't working.
Background Mode
uncommon-route serve --daemon # Start in background, logs to ~/.uncommon-route/serve.log
uncommon-route stop # Stop the background instance
uncommon-route logs # Show last 50 lines of log
uncommon-route logs --follow # Stream logs in real-time (Ctrl+C to stop)
uncommon-route logs --limit 100 # Show last 100 lines
PID file: ~/.uncommon-route/serve.pid. Log file: ~/.uncommon-route/serve.log.
Models & Pricing
The router selects models by tier to minimize cost. Availability depends on your upstream provider — multi-provider gateways (OpenRouter, Commonstack) expose all of these; direct provider APIs expose only their own models.
| Model | Input ($/1M) | Output ($/1M) | Role |
|---|---|---|---|
| nvidia/gpt-oss-120b | $0.00 | $0.00 | SIMPLE fallback |
| google/gemini-2.5-flash-lite | $0.10 | $0.40 | SIMPLE/MEDIUM fallback |
| deepseek/deepseek-chat | $0.28 | $0.42 | MEDIUM fallback |
| xai/grok-4-1-fast-reasoning | $0.20 | $0.50 | REASONING primary |
| moonshot/kimi-k2.5 | $0.60 | $3.00 | SIMPLE/MEDIUM primary |
| google/gemini-3.1-pro | $2.00 | $12.00 | COMPLEX primary |
| openai/gpt-5.2 | $1.75 | $14.00 | COMPLEX fallback |
| anthropic/claude-sonnet-4.6 | $3.00 | $15.00 | COMPLEX fallback |
Baseline comparison: anthropic/claude-opus-4.6 at $5.00/$25.00 per 1M tokens.
Why these defaults? The primary models for SIMPLE/MEDIUM tiers (kimi-k2.5, gemini-flash-lite) are 5–37× cheaper than OpenAI/Claude per output token. For most prompts classified as simple or medium, these models produce equivalent results at a fraction of the cost. Complex prompts still route to frontier models (gemini-3.1-pro, with gpt-5.2 and claude-sonnet-4.6 in the fallback chain).
Configuration
Upstream Provider
UncommonRoute is a routing layer only — it does not host models. It forwards requests to an upstream OpenAI-compatible API that you configure.
# OpenAI direct
export UNCOMMON_ROUTE_UPSTREAM="https://api.openai.com/v1"
export UNCOMMON_ROUTE_API_KEY="sk-..."
# OpenRouter (100+ models, single key)
export UNCOMMON_ROUTE_UPSTREAM="https://openrouter.ai/api/v1"
export UNCOMMON_ROUTE_API_KEY="sk-or-..."
# Commonstack (multi-provider gateway)
export UNCOMMON_ROUTE_UPSTREAM="https://api.commonstack.ai/v1"
export UNCOMMON_ROUTE_API_KEY="csk-..."
# Local (Ollama, vLLM, etc.) — no key needed
export UNCOMMON_ROUTE_UPSTREAM="http://127.0.0.1:11434/v1"
Tip: Multi-provider gateways like OpenRouter or Commonstack work well with UncommonRoute because they expose all models (OpenAI, Claude, Gemini, DeepSeek, etc.) behind a single API key — the router can select across providers without extra configuration.
Environment Variables
| Variable | Default | Description |
|---|---|---|
UNCOMMON_ROUTE_UPSTREAM |
— | Upstream OpenAI-compatible API URL (required for proxy) |
UNCOMMON_ROUTE_API_KEY |
— | API key for the upstream provider |
UNCOMMON_ROUTE_PORT |
8403 |
Proxy port |
UNCOMMON_ROUTE_DISABLED |
false |
Disable routing (passthrough) |
Bring Your Own Key (BYOK)
If you have API keys for specific providers and want the router to prefer those models, register them with the BYOK system:
uncommon-route provider add openai sk-your-openai-key
# Key verified: 47 models available ← auto-validates on add
uncommon-route provider add anthropic sk-ant-your-key
uncommon-route provider list
When a BYOK provider is registered, the router will prefer your keyed models whenever they appear in a tier's candidate list. For example, adding an OpenAI key means COMPLEX-tier prompts will prefer openai/gpt-5.2 over the default google/gemini-3.1-pro.
Keys are automatically verified on add. If verification fails, the key is still saved but a warning is shown. Use uncommon-route doctor to re-check all provider connections.
Provider config is stored at ~/.uncommon-route/providers.json.
OpenClaw Plugin Config
plugins:
entries:
"@anjieyang/uncommon-route":
port: 8403
upstream: "https://openrouter.ai/api/v1" # or any OpenAI-compatible API
spendLimits:
hourly: 5.00
daily: 20.00
Benchmarks
Evaluated on 2000+ multilingual prompts across 10 languages (EN, ZH, KO, JA, ES, PT, AR, RU, DE, HI):
| Metric | Value |
|---|---|
| Overall Accuracy | 98.4% |
| Average Latency | 356µs |
| Features | 39 (structural + unicode + keyword) |
| Learning | Averaged Perceptron |
| External API Calls | None (pure local) |
Per-Tier F1 Scores
| Tier | F1 |
|---|---|
| SIMPLE | 0.988 |
| MEDIUM | 0.968 |
| COMPLEX | 0.987 |
| REASONING | 1.000 |
Run the benchmark suite yourself:
cd bench && python run.py
Project Structure
├── uncommon_route/ # Core package
│ ├── router/ # Cascade classifier + model selection
│ │ ├── classifier.py # Three-level cascade
│ │ ├── learned.py # Averaged Perceptron (ScriptAgnosticClassifier)
│ │ ├── structural.py # 12 structural + 15 unicode features
│ │ ├── keywords.py # 12 keyword features
│ │ ├── selector.py # Tier → model + fallback chain
│ │ └── model.json # Trained weights
│ ├── proxy.py # ASGI proxy (OpenAI + Anthropic endpoints)
│ ├── anthropic_compat.py # Anthropic ↔ OpenAI format conversion
│ ├── model_map.py # Dynamic upstream model discovery + fuzzy matching
│ ├── session.py # Session persistence + escalation
│ ├── spend_control.py # Time-windowed spending limits
│ ├── providers.py # BYOK provider management (with key verification)
│ ├── openclaw.py # OpenClaw config integration
│ ├── cli.py # CLI entry point (route/serve/setup/doctor/logs)
│ └── static/ # Built dashboard assets (React + Tremor)
├── frontend/dashboard/ # Dashboard source (Vite + React + TypeScript)
├── openclaw-plugin/ # JS bridge for OpenClaw
├── tests/ # 169 tests (unit + integration + E2E)
├── bench/ # Benchmarking suite + datasets
├── scripts/install.sh # One-line installer
└── pyproject.toml # PyPI-ready packaging
Development
git clone https://github.com/anjieyang/UncommonRoute.git
cd UncommonRoute
pip install -e ".[dev]"
python -m pytest tests/ -v
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file uncommon_route-0.2.0.tar.gz.
File metadata
- Download URL: uncommon_route-0.2.0.tar.gz
- Upload date:
- Size: 807.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9938bc323010dcfda810c341a0370d88777c6c6d7fe7a92d60cbbb36df41147
|
|
| MD5 |
ebb9395dd71a6d668665f15149924253
|
|
| BLAKE2b-256 |
542c163f11820765ecfd60046b7b33a6367ffede8a491e6ab01bdc49528820bd
|
File details
Details for the file uncommon_route-0.2.0-py3-none-any.whl.
File metadata
- Download URL: uncommon_route-0.2.0-py3-none-any.whl
- Upload date:
- Size: 793.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d2ed5cd386c1f7bce095600c5cb52e0cd1e09ac3488bee8fb31da56ff418da2
|
|
| MD5 |
2a826a84150517d5019284cecd9026d0
|
|
| BLAKE2b-256 |
c14eb1a7dd790226b990dfda56014d0c628e88d87e0d1149d694d2fc28d830cf
|