claude-code-llm-router 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_code_llm_router-0.2.0/.claude-plugin/marketplace.json +17 -0
- claude_code_llm_router-0.2.0/.claude-plugin/plugin.json +11 -0
- claude_code_llm_router-0.2.0/.env.example +27 -0
- claude_code_llm_router-0.2.0/.github/workflows/ci.yml +41 -0
- claude_code_llm_router-0.2.0/.gitignore +8 -0
- claude_code_llm_router-0.2.0/.mcp.json +8 -0
- claude_code_llm_router-0.2.0/CHANGELOG.md +48 -0
- claude_code_llm_router-0.2.0/CONTRIBUTING.md +84 -0
- claude_code_llm_router-0.2.0/LICENSE +21 -0
- claude_code_llm_router-0.2.0/PKG-INFO +516 -0
- claude_code_llm_router-0.2.0/README.md +482 -0
- claude_code_llm_router-0.2.0/ROADMAP.md +176 -0
- claude_code_llm_router-0.2.0/agents/llm-orchestrator.md +84 -0
- claude_code_llm_router-0.2.0/docs/PROVIDERS.md +207 -0
- claude_code_llm_router-0.2.0/docs/images/architecture.svg +1 -0
- claude_code_llm_router-0.2.0/docs/images/orchestration.svg +1 -0
- claude_code_llm_router-0.2.0/docs/images/profiles.svg +1 -0
- claude_code_llm_router-0.2.0/docs/images/quickstart.svg +1 -0
- claude_code_llm_router-0.2.0/docs/images/routing-flow.svg +1 -0
- claude_code_llm_router-0.2.0/docs/images/savings.svg +1 -0
- claude_code_llm_router-0.2.0/docs/logo.svg +27 -0
- claude_code_llm_router-0.2.0/pyproject.toml +62 -0
- claude_code_llm_router-0.2.0/scripts/demo_routing.py +309 -0
- claude_code_llm_router-0.2.0/scripts/install.sh +82 -0
- claude_code_llm_router-0.2.0/skills/route/SKILL.md +53 -0
- claude_code_llm_router-0.2.0/src/llm_router/__init__.py +3 -0
- claude_code_llm_router-0.2.0/src/llm_router/classifier.py +145 -0
- claude_code_llm_router-0.2.0/src/llm_router/claude_usage.py +303 -0
- claude_code_llm_router-0.2.0/src/llm_router/codex_agent.py +117 -0
- claude_code_llm_router-0.2.0/src/llm_router/config.py +111 -0
- claude_code_llm_router-0.2.0/src/llm_router/cost.py +300 -0
- claude_code_llm_router-0.2.0/src/llm_router/health.py +84 -0
- claude_code_llm_router-0.2.0/src/llm_router/media.py +375 -0
- claude_code_llm_router-0.2.0/src/llm_router/model_selector.py +98 -0
- claude_code_llm_router-0.2.0/src/llm_router/onboard.py +124 -0
- claude_code_llm_router-0.2.0/src/llm_router/orchestrator.py +210 -0
- claude_code_llm_router-0.2.0/src/llm_router/profiles.py +184 -0
- claude_code_llm_router-0.2.0/src/llm_router/provider_budget.py +168 -0
- claude_code_llm_router-0.2.0/src/llm_router/providers.py +80 -0
- claude_code_llm_router-0.2.0/src/llm_router/router.py +177 -0
- claude_code_llm_router-0.2.0/src/llm_router/server.py +1389 -0
- claude_code_llm_router-0.2.0/src/llm_router/types.py +242 -0
- claude_code_llm_router-0.2.0/tests/__init__.py +0 -0
- claude_code_llm_router-0.2.0/tests/conftest.py +68 -0
- claude_code_llm_router-0.2.0/tests/test_classifier.py +146 -0
- claude_code_llm_router-0.2.0/tests/test_claude_usage.py +228 -0
- claude_code_llm_router-0.2.0/tests/test_cost.py +60 -0
- claude_code_llm_router-0.2.0/tests/test_freemium.py +126 -0
- claude_code_llm_router-0.2.0/tests/test_health.py +67 -0
- claude_code_llm_router-0.2.0/tests/test_integration.py +73 -0
- claude_code_llm_router-0.2.0/tests/test_model_selector.py +189 -0
- claude_code_llm_router-0.2.0/tests/test_orchestrator.py +126 -0
- claude_code_llm_router-0.2.0/tests/test_profiles.py +39 -0
- claude_code_llm_router-0.2.0/tests/test_route.py +167 -0
- claude_code_llm_router-0.2.0/tests/test_router.py +87 -0
- claude_code_llm_router-0.2.0/tests/test_savings.py +106 -0
- claude_code_llm_router-0.2.0/tests/test_server.py +58 -0
- claude_code_llm_router-0.2.0/tests/test_setup.py +109 -0
- claude_code_llm_router-0.2.0/uv.lock +2045 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ypollak2",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "Yali Pollak"
|
|
5
|
+
},
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "llm-router",
|
|
9
|
+
"description": "Route text, image, video, and audio tasks to 20+ AI providers with smart routing, budget control, and multi-step orchestration",
|
|
10
|
+
"version": "0.1.0",
|
|
11
|
+
"source": {
|
|
12
|
+
"source": "github",
|
|
13
|
+
"repo": "ypollak2/llm-router"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "llm-router",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Smart LLM routing with Claude subscription monitoring, Codex desktop integration, complexity-first model selection, and 20+ AI providers",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "ypollak2"
|
|
7
|
+
},
|
|
8
|
+
"homepage": "https://github.com/ypollak2/llm-router",
|
|
9
|
+
"repository": "https://github.com/ypollak2/llm-router",
|
|
10
|
+
"license": "MIT"
|
|
11
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# LLM Router — API Keys
|
|
2
|
+
# Copy to .env and fill in keys. Run `llm-router-onboard` for interactive setup.
|
|
3
|
+
# Start with Gemini's free tier: https://aistudio.google.com/apikey
|
|
4
|
+
|
|
5
|
+
# ── Text LLM Providers ──
|
|
6
|
+
OPENAI_API_KEY= # https://platform.openai.com/api-keys
|
|
7
|
+
GEMINI_API_KEY= # https://aistudio.google.com/apikey (FREE tier available!)
|
|
8
|
+
PERPLEXITY_API_KEY= # https://www.perplexity.ai/settings/api
|
|
9
|
+
ANTHROPIC_API_KEY= # https://console.anthropic.com/settings/keys
|
|
10
|
+
MISTRAL_API_KEY= # https://console.mistral.ai/api-keys
|
|
11
|
+
DEEPSEEK_API_KEY= # https://platform.deepseek.com/api_keys
|
|
12
|
+
GROQ_API_KEY= # https://console.groq.com/keys (FREE tier!)
|
|
13
|
+
TOGETHER_API_KEY= # https://api.together.xyz/settings/api-keys
|
|
14
|
+
XAI_API_KEY= # https://console.x.ai/
|
|
15
|
+
COHERE_API_KEY= # https://dashboard.cohere.com/api-keys
|
|
16
|
+
|
|
17
|
+
# ── Media Providers ──
|
|
18
|
+
FAL_KEY= # https://fal.ai/dashboard/keys (Flux, Kling, etc.)
|
|
19
|
+
STABILITY_API_KEY= # https://platform.stability.ai/account/keys
|
|
20
|
+
ELEVENLABS_API_KEY= # https://elevenlabs.io/app/settings/api-keys
|
|
21
|
+
RUNWAY_API_KEY= # https://dev.runwayml.com/
|
|
22
|
+
REPLICATE_API_TOKEN= # https://replicate.com/account/api-tokens
|
|
23
|
+
|
|
24
|
+
# ── Router Config ──
|
|
25
|
+
LLM_ROUTER_PROFILE=balanced # budget | balanced | premium
|
|
26
|
+
LLM_ROUTER_MONTHLY_BUDGET=0 # USD monthly limit (0 = unlimited)
|
|
27
|
+
LLM_ROUTER_TIER=free # free | pro | team
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
run: uv python install ${{ matrix.python-version }}
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: uv sync --extra dev
|
|
27
|
+
|
|
28
|
+
- name: Lint
|
|
29
|
+
run: uv run ruff check src/
|
|
30
|
+
|
|
31
|
+
- name: Run tests
|
|
32
|
+
run: uv run pytest tests/ -v --ignore=tests/test_integration.py
|
|
33
|
+
|
|
34
|
+
lint:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: astral-sh/setup-uv@v4
|
|
39
|
+
- run: uv python install 3.11
|
|
40
|
+
- run: uv sync --extra dev
|
|
41
|
+
- run: uv run ruff check src/ tests/
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v0.2.0 — Intelligence Layer (2026-03-29)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Complexity-first routing** — simple tasks → haiku, moderate → sonnet, complex → opus. Budget downshifting is now a late safety net at 85%+, not the primary mechanism.
|
|
8
|
+
- **Live Claude subscription monitoring** — fetches session/weekly usage from claude.ai internal JSON API via Playwright `browser_evaluate(fetch(...))`.
|
|
9
|
+
- **Time-aware budget pressure** — `effective_pressure` reduces downshift urgency when session reset is imminent (< 30 min away).
|
|
10
|
+
- **Codex desktop integration** — routes tasks to local Codex CLI (`/Applications/Codex.app`), free via OpenAI subscription.
|
|
11
|
+
- **Unified usage dashboard** (`llm_usage`) — single view of Claude subscription %, Codex status, API spend per provider, and routing savings.
|
|
12
|
+
- **`llm_setup` tool** — discover existing API keys on the laptop, add new providers with validation, view setup guides. All operations local-only with key masking and `.gitignore` checks.
|
|
13
|
+
- **Per-provider budget limits** — `LLM_ROUTER_BUDGET_OPENAI`, `LLM_ROUTER_BUDGET_GEMINI`, etc.
|
|
14
|
+
- **Gemini media routing** — Imagen 3 (images) and Veo 2 (video) added to all routing profiles.
|
|
15
|
+
- **`llm_classify` tool** — classify task complexity and see the routing recommendation with model/cost details.
|
|
16
|
+
- **`llm_check_usage` / `llm_update_usage`** — fetch and store Claude subscription data for routing decisions.
|
|
17
|
+
- **`llm_track_usage`** — record usage for a specific provider.
|
|
18
|
+
- **External fallback ranking** — when Claude quota is tight, rank available external models by quality (descending) and cost (ascending).
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Dashboard output switched to **ASCII box-drawing** (`+`, `-`, `|`, `=`, `.`) for reliable rendering in Claude Code's MCP output.
|
|
23
|
+
- Pressure thresholds updated from 50%/80% to **85%/95%** safety net — complexity routing handles the rest.
|
|
24
|
+
- Classification headers use text tags (`[S]`, `[M]`, `[C]`) instead of emoji.
|
|
25
|
+
- Budget bars use ASCII (`[====........]`) instead of Unicode blocks.
|
|
26
|
+
- Tool count increased from 17 to 20.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- MCP tool output rendering issues (Unicode blocks, markdown, emoji all garbled in collapsed JSON view).
|
|
31
|
+
- f-string backslash errors in dashboard formatting code.
|
|
32
|
+
|
|
33
|
+
## v0.1.0 — Foundation (2026-03-15)
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Text LLM routing via LiteLLM (10 providers)
|
|
38
|
+
- Three routing profiles: budget, balanced, premium
|
|
39
|
+
- Cost tracking with SQLite
|
|
40
|
+
- Health checks with circuit breaker pattern
|
|
41
|
+
- Image generation (DALL-E, Flux, Stable Diffusion)
|
|
42
|
+
- Video generation (Runway, Kling, minimax)
|
|
43
|
+
- Audio/voice routing (ElevenLabs, OpenAI TTS)
|
|
44
|
+
- Monthly budget enforcement with hard limits
|
|
45
|
+
- Multi-step orchestration with pipeline templates
|
|
46
|
+
- Claude Code plugin with `/route` skill
|
|
47
|
+
- Freemium tier gating (free / pro)
|
|
48
|
+
- CI with GitHub Actions
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Contributing to LLM Router
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing! Here's how to get started.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/ypollak2/llm-router.git
|
|
9
|
+
cd llm-router
|
|
10
|
+
uv sync --extra dev
|
|
11
|
+
cp .env.example .env
|
|
12
|
+
# Add at least one API key to .env
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Running Tests
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Unit tests (no API keys needed)
|
|
19
|
+
uv run pytest tests/ -v --ignore=tests/test_integration.py
|
|
20
|
+
|
|
21
|
+
# Integration tests (requires API keys in .env)
|
|
22
|
+
uv run pytest tests/test_integration.py -v
|
|
23
|
+
|
|
24
|
+
# Full suite
|
|
25
|
+
uv run pytest -v
|
|
26
|
+
|
|
27
|
+
# Lint
|
|
28
|
+
uv run ruff check src/
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Adding a New Provider
|
|
32
|
+
|
|
33
|
+
1. Add the model mapping to `src/llm_router/profiles.py`
|
|
34
|
+
2. Add the provider's API key to `src/llm_router/config.py`
|
|
35
|
+
3. Add the provider to `_PROVIDER_REGISTRY` in `src/llm_router/server.py` (for `llm_setup`)
|
|
36
|
+
4. Update the onboarding wizard in `src/llm_router/onboard.py`
|
|
37
|
+
5. Add integration tests in `tests/test_integration.py`
|
|
38
|
+
6. Update `docs/PROVIDERS.md` with setup instructions
|
|
39
|
+
|
|
40
|
+
Most providers work through LiteLLM with zero custom code — just add the model string and key.
|
|
41
|
+
|
|
42
|
+
## Key Modules
|
|
43
|
+
|
|
44
|
+
| Module | Purpose |
|
|
45
|
+
|--------|---------|
|
|
46
|
+
| `server.py` | MCP tool definitions (20 tools), `llm_setup` provider registry |
|
|
47
|
+
| `router.py` | Complexity classification and model selection logic |
|
|
48
|
+
| `profiles.py` | Model lists per routing profile (budget/balanced/premium) |
|
|
49
|
+
| `config.py` | Environment-based configuration, provider detection |
|
|
50
|
+
| `claude_usage.py` | Claude subscription usage parsing, time-aware pressure |
|
|
51
|
+
| `codex_agent.py` | Codex desktop CLI integration (local, free via OpenAI sub) |
|
|
52
|
+
| `provider_budget.py` | Per-provider budget tracking and enforcement |
|
|
53
|
+
| `orchestrator.py` | Multi-step pipeline execution across providers |
|
|
54
|
+
| `cost_tracker.py` | SQLite-based cost and token tracking |
|
|
55
|
+
| `health.py` | Provider health checks with circuit breaker pattern |
|
|
56
|
+
|
|
57
|
+
## Pull Request Guidelines
|
|
58
|
+
|
|
59
|
+
- One concern per PR
|
|
60
|
+
- Include tests for new functionality
|
|
61
|
+
- Run `uv run ruff check src/` before submitting
|
|
62
|
+
- Follow existing code style (Pydantic models, async/await, type hints)
|
|
63
|
+
- Update the README if adding user-facing features
|
|
64
|
+
|
|
65
|
+
## Code Style
|
|
66
|
+
|
|
67
|
+
- Python 3.10+ with type hints
|
|
68
|
+
- `snake_case` for functions/variables, `PascalCase` for classes
|
|
69
|
+
- Pydantic for config and external data
|
|
70
|
+
- Async/await throughout (MCP server is async)
|
|
71
|
+
- Keep files under 400 lines
|
|
72
|
+
|
|
73
|
+
## Commit Messages
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
feat: add Runway video generation support
|
|
77
|
+
fix: circuit breaker not resetting after cooldown
|
|
78
|
+
docs: add ElevenLabs setup guide
|
|
79
|
+
test: add integration tests for image routing
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 LLM Router Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|