- Remove ALL 231 @ts-ignore annotations (231 → 0) - Fix 237 TypeScript errors with proper typings: - Type 30+ variable declarations as Record<string, any> - Add optional params: model?, provider?, retryAfter?, retryAfterHuman? - Replace @ts-ignore with 'as any' casts for custom Error/Array properties - Add EdgeRuntime global declaration for edge runtime compat - Import fs/path in responsesTransformer.ts - Fix function argument mismatches (resolveComboConfig, unavailableResponse) - Build: tsc --noEmit passes with 0 errors
OmniRoute - Free AI Router
Never stop coding. Auto-route to FREE & cheap AI models with smart fallback.
36+ Providers • Embeddings • Image Generation • Think Tag Parsing
Free AI Provider for OpenClaw.
This project is inspired by and originally forked from 9router by decolua. Thank you for the incredible foundation!
🤔 Why OmniRoute?
Stop wasting money and hitting limits:
- ❌ Subscription quota expires unused every month
- ❌ Rate limits stop you mid-coding
- ❌ Expensive APIs ($20-50/month per provider)
- ❌ Manual switching between providers
OmniRoute solves this:
- ✅ Maximize subscriptions - Track quota, use every bit before reset
- ✅ Auto fallback - Subscription → Cheap → Free, zero downtime
- ✅ Multi-account - Round-robin between accounts per provider
- ✅ Universal - Works with Claude Code, Codex, Gemini CLI, Cursor, Cline, any CLI tool
🔄 How It Works
┌─────────────┐
│ Your CLI │ (Claude Code, Codex, Gemini CLI, OpenClaw, Cursor, Cline...)
│ Tool │
└──────┬──────┘
│ http://localhost:20128/v1
↓
┌─────────────────────────────────────────┐
│ OmniRoute (Smart Router) │
│ • Format translation (OpenAI ↔ Claude) │
│ • Quota tracking + Embeddings + Images │
│ • Auto token refresh │
└──────┬──────────────────────────────────┘
│
├─→ [Tier 1: SUBSCRIPTION] Claude Code, Codex, Gemini CLI
│ ↓ quota exhausted
├─→ [Tier 2: API KEY] DeepSeek, Groq, xAI, Mistral, Together, etc.
│ ↓ budget limit
├─→ [Tier 3: CHEAP] GLM ($0.6/1M), MiniMax ($0.2/1M)
│ ↓ budget limit
└─→ [Tier 4: FREE] iFlow, Qwen, Kiro (unlimited)
Result: Never stop coding, minimal cost
⚡ Quick Start
1. Install globally:
npm install -g omniroute
omniroute
🎉 Dashboard opens at http://localhost:20128
| Command | Description |
|---|---|
omniroute |
Start server (default port 20128) |
omniroute --port 3000 |
Use custom port |
omniroute --no-open |
Don't auto-open browser |
omniroute --help |
Show help |
2. Connect a FREE provider:
Dashboard → Providers → Connect Claude Code or Antigravity → OAuth login → Done!
3. Use in your CLI tool:
Claude Code/Codex/Gemini CLI/OpenClaw/Cursor/Cline Settings:
Endpoint: http://localhost:20128/v1
API Key: [copy from dashboard]
Model: if/kimi-k2-thinking
That's it! Start coding with FREE AI models.
Alternative — run from source:
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
🐳 Docker
OmniRoute is available as a public Docker image on Docker Hub.
Quick run:
docker run -d \
--name omniroute \
--restart unless-stopped \
-p 20128:20128 \
-v omniroute-data:/app/data \
diegosouzapw/omniroute:latest
With environment file:
# Copy and edit .env first
cp .env.example .env
docker run -d \
--name omniroute \
--restart unless-stopped \
--env-file .env \
-p 20128:20128 \
-v omniroute-data:/app/data \
diegosouzapw/omniroute:latest
Using Docker Compose:
# Base profile (no CLI tools)
docker compose --profile base up -d
# CLI profile (Claude Code, Codex, OpenClaw built-in)
docker compose --profile cli up -d
| Image | Tag | Size | Description |
|---|---|---|---|
diegosouzapw/omniroute |
latest |
~250MB | Latest stable release |
diegosouzapw/omniroute |
0.6.0 |
~250MB | Current version |
💡 Key Features
| Feature | What It Does |
|---|---|
| 🎯 Smart 3-Tier Fallback | Auto-route: Subscription → Cheap → Free |
| 📊 Real-Time Quota Tracking | Live token count + reset countdown |
| 🔄 Format Translation | OpenAI ↔ Claude ↔ Gemini seamless |
| 👥 Multi-Account Support | Multiple accounts per provider |
| 🔄 Auto Token Refresh | OAuth tokens refresh automatically |
| 🎨 Custom Combos | Create unlimited model combinations |
| 🧩 Custom Models | Add any model ID to any provider |
| 📝 Request Logging | Debug mode with full request/response logs |
| 💾 Cloud Sync | Sync config across devices |
| 📊 Usage Analytics | Track tokens, cost, trends over time |
| 🌐 Deploy Anywhere | Localhost, VPS, Docker, Cloudflare Workers |
| 🔌 Circuit Breaker | Auto-open/close per-provider with cooldowns |
| 🛡️ Anti-Thundering Herd | Mutex + auto rate-limit for API key providers |
| 🧠 Semantic Cache | Two-tier cache reduces cost & latency |
| ⚡ Request Idempotency | 5s dedup window for duplicate requests |
| 📈 Progress Tracking | Opt-in SSE progress events for streaming |
| 🧪 LLM Evaluations | Golden set testing with 4 match strategies |
🧪 Evaluations (Evals)
OmniRoute includes a built-in evaluation framework to test LLM response quality against a golden set. Access it via Analytics → Evals in the dashboard.
Built-in Golden Set
The pre-loaded "OmniRoute Golden Set" contains 10 test cases covering:
- Greetings, math, geography, code generation
- JSON format compliance, translation, markdown
- Safety refusal (harmful content), counting, boolean logic
How It Works
- Click "Run Eval" on a suite in the dashboard
- Each test case is sent to your proxy endpoint (
/v1/chat/completions) - Real LLM responses are collected and evaluated against expected criteria
- Results show pass/fail status, latency per case, and overall pass rate
Evaluation Strategies
| Strategy | Description | Example |
|---|---|---|
exact |
Output must match exactly | "4" |
contains |
Output must contain substring (case-insensitive) | "Paris" |
regex |
Output must match regex pattern | "1.*2.*3" |
custom |
Custom JS function returns true/false | (output) => output.length > 10 |
API Usage
# List all eval suites
curl http://localhost:20128/api/evals
# Run a suite with pre-collected outputs
curl -X POST http://localhost:20128/api/evals \
-H 'Content-Type: application/json' \
-d '{"suiteId": "golden-set", "outputs": {"gs-01": "Hello there!", "gs-02": "4"}}'
# Get suite details
curl http://localhost:20128/api/evals/golden-set
Custom Suites
Register custom suites programmatically via registerSuite() in src/lib/evals/evalRunner.ts:
registerSuite({
id: "my-suite",
name: "Custom Eval Suite",
cases: [
{
id: "c-01",
name: "API response",
model: "gpt-4o",
input: { messages: [{ role: "user", content: "Say OK" }] },
expected: { strategy: "contains", value: "OK" },
},
],
});
🛠️ Tech Stack
- Runtime: Node.js 20+
- Language: TypeScript 5.9 (src/) + JavaScript (open-sse/)
- Framework: Next.js 16 + React 19 + Tailwind CSS 4
- Database: LowDB (JSON) + SQLite (domain state)
- Streaming: Server-Sent Events (SSE)
- Auth: OAuth 2.0 (PKCE) + JWT + API Keys
- Testing: Node.js test runner (368+ unit tests)
- CI/CD: GitHub Actions (auto npm publish on release)
- Website: omniroute.online
- Package: npmjs.com/package/omniroute
- Docker: hub.docker.com/r/diegosouzapw/omniroute
- Resilience: Circuit breaker, exponential backoff, anti-thundering herd
📖 Documentation
| Document | Description |
|---|---|
| User Guide | Providers, combos, CLI integration, deployment |
| API Reference | All endpoints with examples |
| Troubleshooting | Common problems and solutions |
| Architecture | System architecture and internals |
| Contributing | Development setup and guidelines |
| OpenAPI Spec | OpenAPI 3.0 specification |
| Security Policy | Vulnerability reporting and security practices |
📧 Support
- Website: omniroute.online
- GitHub: github.com/diegosouzapw/OmniRoute
- Issues: github.com/diegosouzapw/OmniRoute/issues
- Original Project: 9router by decolua
👥 Contributors
How to Contribute
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
See CONTRIBUTING.md for detailed guidelines.
Releasing a New Version
# Create a release — npm publish happens automatically
gh release create v0.8.0 --title "v0.8.0" --generate-notes
🙏 Acknowledgments
Special thanks to CLIProxyAPI - the original Go implementation that inspired this JavaScript port.
📄 License
MIT License - see LICENSE for details.
