runtimerouter 0.1.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.
Files changed (43) hide show
  1. runtimerouter-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +44 -0
  2. runtimerouter-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +34 -0
  3. runtimerouter-0.1.0/.github/workflows/ci.yml +43 -0
  4. runtimerouter-0.1.0/.github/workflows/publish.yml +30 -0
  5. runtimerouter-0.1.0/.gitignore +50 -0
  6. runtimerouter-0.1.0/CONTRIBUTING.md +128 -0
  7. runtimerouter-0.1.0/LICENSE +21 -0
  8. runtimerouter-0.1.0/PKG-INFO +246 -0
  9. runtimerouter-0.1.0/README.md +209 -0
  10. runtimerouter-0.1.0/ROADMAP.md +91 -0
  11. runtimerouter-0.1.0/docs/api.md +127 -0
  12. runtimerouter-0.1.0/docs/architecture.md +178 -0
  13. runtimerouter-0.1.0/docs/index.md +15 -0
  14. runtimerouter-0.1.0/examples/__init__.py +1 -0
  15. runtimerouter-0.1.0/examples/basic_autollm.py +22 -0
  16. runtimerouter-0.1.0/examples/custom_policy.py +35 -0
  17. runtimerouter-0.1.0/examples/litellm_integration.py +35 -0
  18. runtimerouter-0.1.0/pyproject.toml +82 -0
  19. runtimerouter-0.1.0/runtimerouter/__init__.py +28 -0
  20. runtimerouter-0.1.0/runtimerouter/autollm.py +110 -0
  21. runtimerouter-0.1.0/runtimerouter/classifier.py +62 -0
  22. runtimerouter-0.1.0/runtimerouter/config.py +38 -0
  23. runtimerouter-0.1.0/runtimerouter/exceptions.py +25 -0
  24. runtimerouter-0.1.0/runtimerouter/integrations/__init__.py +10 -0
  25. runtimerouter-0.1.0/runtimerouter/integrations/litellm.py +74 -0
  26. runtimerouter-0.1.0/runtimerouter/policies/__init__.py +17 -0
  27. runtimerouter-0.1.0/runtimerouter/policies/base.py +40 -0
  28. runtimerouter-0.1.0/runtimerouter/policies/complexity.py +47 -0
  29. runtimerouter-0.1.0/runtimerouter/policies/cost.py +41 -0
  30. runtimerouter-0.1.0/runtimerouter/providers/__init__.py +15 -0
  31. runtimerouter-0.1.0/runtimerouter/providers/base.py +28 -0
  32. runtimerouter-0.1.0/runtimerouter/providers/registry.py +74 -0
  33. runtimerouter-0.1.0/runtimerouter/router.py +104 -0
  34. runtimerouter-0.1.0/runtimerouter/types.py +79 -0
  35. runtimerouter-0.1.0/tests/__init__.py +1 -0
  36. runtimerouter-0.1.0/tests/conftest.py +33 -0
  37. runtimerouter-0.1.0/tests/test_autollm.py +17 -0
  38. runtimerouter-0.1.0/tests/test_classifier.py +19 -0
  39. runtimerouter-0.1.0/tests/test_policies/__init__.py +1 -0
  40. runtimerouter-0.1.0/tests/test_policies/test_base.py +27 -0
  41. runtimerouter-0.1.0/tests/test_providers.py +20 -0
  42. runtimerouter-0.1.0/tests/test_router.py +50 -0
  43. runtimerouter-0.1.0/tests/test_types.py +29 -0
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: Bug Report
3
+ about: Report a bug in RuntimeRouter
4
+ title: "[Bug] "
5
+ labels: bug
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Description
10
+
11
+ A clear description of the bug.
12
+
13
+ ## Steps to Reproduce
14
+
15
+ 1.
16
+ 2.
17
+ 3.
18
+
19
+ ## Expected Behavior
20
+
21
+ What you expected to happen.
22
+
23
+ ## Actual Behavior
24
+
25
+ What actually happened.
26
+
27
+ ## Environment
28
+
29
+ - RuntimeRouter version:
30
+ - Python version:
31
+ - OS:
32
+ - LiteLLM version (if applicable):
33
+
34
+ ## Minimal Reproduction
35
+
36
+ ```python
37
+ from runtimerouter import AutoLLM
38
+
39
+ # your code here
40
+ ```
41
+
42
+ ## Additional Context
43
+
44
+ Logs, stack traces, or screenshots.
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: Feature Request
3
+ about: Suggest a new feature or enhancement
4
+ title: "[Feature] "
5
+ labels: enhancement
6
+ assignees: ""
7
+ ---
8
+
9
+ ## Problem
10
+
11
+ What problem does this feature solve?
12
+
13
+ ## Proposed Solution
14
+
15
+ Describe the feature you'd like to see.
16
+
17
+ ## Alternatives Considered
18
+
19
+ Any alternative approaches you've thought about.
20
+
21
+ ## Version Target
22
+
23
+ Which roadmap version does this fit?
24
+
25
+ - [ ] v0.1
26
+ - [ ] v0.2
27
+ - [ ] v0.3
28
+ - [ ] v0.4
29
+ - [ ] v0.5
30
+ - [ ] Future
31
+
32
+ ## Additional Context
33
+
34
+ Links, mockups, or related issues.
@@ -0,0 +1,43 @@
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.10", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ pip install -e ".[dev]"
28
+
29
+ - name: Lint with ruff
30
+ run: ruff check runtimerouter tests
31
+
32
+ - name: Type check with mypy
33
+ run: mypy runtimerouter
34
+
35
+ - name: Run tests
36
+ run: pytest --cov=runtimerouter --cov-report=xml
37
+
38
+ - name: Upload coverage
39
+ if: matrix.python-version == '3.12'
40
+ uses: codecov/codecov-action@v4
41
+ with:
42
+ file: ./coverage.xml
43
+ fail_ci_if_error: false
@@ -0,0 +1,30 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ id-token: write
9
+
10
+ jobs:
11
+ publish:
12
+ runs-on: ubuntu-latest
13
+ environment: pypi
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.12"
22
+
23
+ - name: Install build tools
24
+ run: pip install build twine
25
+
26
+ - name: Build package
27
+ run: python -m build
28
+
29
+ - name: Publish to PyPI
30
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,50 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+
28
+ # Testing & coverage
29
+ .pytest_cache/
30
+ .coverage
31
+ htmlcov/
32
+ .mypy_cache/
33
+ .ruff_cache/
34
+
35
+ # IDE
36
+ .idea/
37
+ .vscode/
38
+ *.swp
39
+ *.swo
40
+
41
+ # Environment
42
+ .env
43
+ .env.*
44
+
45
+ # Docs build
46
+ site/
47
+
48
+ # OS
49
+ .DS_Store
50
+ Thumbs.db
@@ -0,0 +1,128 @@
1
+ # Contributing to RuntimeRouter
2
+
3
+ Thank you for your interest in contributing! RuntimeRouter is an open-source Python library, and we welcome contributions of all sizes.
4
+
5
+ ## Getting Started
6
+
7
+ ### Prerequisites
8
+
9
+ - Python 3.10+
10
+ - git
11
+
12
+ ### Setup
13
+
14
+ ```bash
15
+ git clone https://github.com/chenyu-dev25/RuntimeRouter.git
16
+ cd RuntimeRouter
17
+ python -m venv .venv
18
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
19
+ pip install -e ".[dev]"
20
+ ```
21
+
22
+ ### Run tests
23
+
24
+ ```bash
25
+ pytest
26
+ pytest --cov=runtimerouter --cov-report=term-missing
27
+ ```
28
+
29
+ ### Lint & type check
30
+
31
+ ```bash
32
+ ruff check runtimerouter tests
33
+ ruff format runtimerouter tests
34
+ mypy runtimerouter
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Project Structure
40
+
41
+ ```
42
+ runtimerouter/
43
+ ├── autollm.py # User-facing API — keep minimal
44
+ ├── router.py # Pipeline orchestrator — no policy logic here
45
+ ├── classifier.py # Task classification — complexity & tokens
46
+ ├── policies/ # One file per policy, extend RoutingPolicy
47
+ ├── providers/ # Model catalog metadata
48
+ └── integrations/ # LiteLLM, future framework adapters
49
+ ```
50
+
51
+ ### Module boundaries (important)
52
+
53
+ | Module | Responsibility | Must NOT contain |
54
+ |--------|---------------|------------------|
55
+ | `autollm.py` | Orchestrate route + invoke | Policy logic |
56
+ | `router.py` | Run policy chain in order | Classification heuristics |
57
+ | `classifier.py` | Enrich RouteContext | Model selection |
58
+ | `policies/*` | Filter/rank candidates | LiteLLM calls |
59
+ | `integrations/*` | Execute completions | Routing decisions |
60
+
61
+ ---
62
+
63
+ ## Adding a new Policy
64
+
65
+ 1. Create `runtimerouter/policies/your_policy.py`
66
+ 2. Subclass `RoutingPolicy` and implement `apply()`
67
+ 3. Register in `Router._POLICY_REGISTRY`
68
+ 4. Add tests in `tests/test_policies/`
69
+ 5. Document in `docs/architecture.md`
70
+
71
+ Example skeleton:
72
+
73
+ ```python
74
+ from runtimerouter.policies.base import RoutingPolicy
75
+ from runtimerouter.types import ModelCandidate, RouteContext
76
+
77
+ class MyPolicy(RoutingPolicy):
78
+ name = "my_policy"
79
+
80
+ def apply(
81
+ self,
82
+ context: RouteContext,
83
+ candidates: list[ModelCandidate],
84
+ ) -> list[ModelCandidate]:
85
+ # filter or reorder candidates
86
+ return candidates
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Pull Request Guidelines
92
+
93
+ 1. **One concern per PR** — don't mix unrelated changes
94
+ 2. **Add tests** for new behavior
95
+ 3. **Update docs** if you change public API
96
+ 4. **Follow existing style** — ruff + mypy must pass
97
+ 5. **Write a clear PR description** — what, why, how to test
98
+
99
+ ### Commit messages
100
+
101
+ Use conventional style:
102
+
103
+ ```
104
+ feat: add budget-aware cost policy filtering
105
+ fix: handle empty candidate list in Router
106
+ docs: update Quick Start with async example
107
+ test: add complexity policy unit tests
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Reporting Issues
113
+
114
+ - **Bug reports:** use the Bug Report issue template
115
+ - **Feature requests:** use the Feature Request issue template
116
+ - Include Python version, runtimerouter version, and minimal reproduction code
117
+
118
+ ---
119
+
120
+ ## Code of Conduct
121
+
122
+ Be respectful and constructive. We're building infrastructure for the community.
123
+
124
+ ---
125
+
126
+ ## License
127
+
128
+ By contributing, you agree that your contributions will be licensed under the [MIT License](LICENSE).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 RuntimeRouter 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.
@@ -0,0 +1,246 @@
1
+ Metadata-Version: 2.4
2
+ Name: runtimerouter
3
+ Version: 0.1.0
4
+ Summary: Optimize the entire AI session, not just the next model call.
5
+ Project-URL: Homepage, https://github.com/chenyu-dev25/RuntimeRouter
6
+ Project-URL: Documentation, https://github.com/chenyu-dev25/RuntimeRouter#readme
7
+ Project-URL: Repository, https://github.com/chenyu-dev25/RuntimeRouter
8
+ Project-URL: Issues, https://github.com/chenyu-dev25/RuntimeRouter/issues
9
+ Project-URL: Changelog, https://github.com/chenyu-dev25/RuntimeRouter/blob/main/ROADMAP.md
10
+ Author: RuntimeRouter Contributors
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: agent,langgraph,litellm,llm,model-selection,pydantic-ai,routing
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.10
26
+ Requires-Dist: litellm>=1.40.0
27
+ Requires-Dist: pydantic>=2.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: mypy>=1.10; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.4; extra == 'dev'
33
+ Provides-Extra: docs
34
+ Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
35
+ Requires-Dist: mkdocs>=1.6; extra == 'docs'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # RuntimeRouter
39
+
40
+ > **Optimize the entire AI session, not just the next model call.**
41
+
42
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
44
+ [![PyPI version](https://img.shields.io/pypi/v/runtimerouter.svg)](https://pypi.org/project/runtimerouter/)
45
+
46
+ RuntimeRouter is a **Python-first LLM routing library** for the AI ecosystem. It sits **above** agent frameworks — LangGraph, PydanticAI, CrewAI, AutoGen — as a **Runtime Router**, not a replacement for them.
47
+
48
+ You write agents with your favorite framework. RuntimeRouter decides **which model** to call, **when**, and **why** — across the full session lifecycle.
49
+
50
+ ---
51
+
52
+ ## Vision
53
+
54
+ Traditional routers optimize a single inference call: given a prompt, pick the cheapest or fastest model.
55
+
56
+ RuntimeRouter's long-term goal is different: **optimize the entire AI session** — model selection, cost, latency, context, caching, and privacy — as a unified runtime decision layer.
57
+
58
+ ```
59
+ ┌─────────────────────────────────────────────────────────┐
60
+ │ Your Agent Framework (LangGraph / PydanticAI / …) │
61
+ ├─────────────────────────────────────────────────────────┤
62
+ │ RuntimeRouter ← session-aware routing (this library) │
63
+ ├─────────────────────────────────────────────────────────┤
64
+ │ LiteLLM / Provider APIs (OpenAI, Anthropic, …) │
65
+ └─────────────────────────────────────────────────────────┘
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Why RuntimeRouter?
71
+
72
+ | Problem | RuntimeRouter approach |
73
+ |---------|------------------------|
74
+ | Hard-coding `model="gpt-4o"` everywhere | `AutoLLM()` picks the right model per request |
75
+ | Simple tasks burning frontier-model budget | Complexity routing sends easy tasks to cheap models |
76
+ | No visibility into routing decisions | Every call returns a `RouteDecision` with reason |
77
+ | Framework lock-in | Framework-agnostic; works with any LiteLLM-compatible stack |
78
+ | Proxy-only routers | Designed for **session-level** optimization (roadmap) |
79
+
80
+ ---
81
+
82
+ ## vs OpenRouter
83
+
84
+ | | **OpenRouter** | **RuntimeRouter** |
85
+ |---|----------------|-------------------|
86
+ | **What it is** | Unified API proxy to 100+ models | Python routing **library** embedded in your app |
87
+ | **Scope** | Single HTTP request → model | Entire AI **session** (roadmap) |
88
+ | **Integration** | Replace your API base URL | Drop-in `AutoLLM()` or `Router` in Python code |
89
+ | **Policies** | Provider-side routing rules | Pluggable Python **Policy** classes you own |
90
+ | **Framework** | Language-agnostic HTTP | **Python-first**, native LangGraph/PydanticAI hooks (v0.2+) |
91
+
92
+ OpenRouter is excellent as a model gateway. RuntimeRouter is a **runtime decision engine** you control in-process.
93
+
94
+ ---
95
+
96
+ ## vs Not Diamond
97
+
98
+ | | **Not Diamond** | **RuntimeRouter** |
99
+ |---|-----------------|-------------------|
100
+ | **What it is** | Managed routing SaaS | Open-source Python library |
101
+ | **Deployment** | Cloud API | In-process, self-hosted |
102
+ | **Customization** | Platform-configured | Full **plugin Policy** architecture |
103
+ | **Session scope** | Per-call model selection | Session-aware optimization (roadmap) |
104
+ | **Cost** | SaaS pricing | Free & open (MIT) |
105
+
106
+ Not Diamond provides intelligent routing as a service. RuntimeRouter gives you the same **concept** as extensible, auditable Python code.
107
+
108
+ ---
109
+
110
+ ## Quick Start
111
+
112
+ ### Install
113
+
114
+ ```bash
115
+ pip install runtimerouter
116
+ ```
117
+
118
+ ### Basic usage
119
+
120
+ ```python
121
+ from runtimerouter import AutoLLM
122
+
123
+ llm = AutoLLM()
124
+
125
+ # RuntimeRouter automatically selects Claude, Gemini, DeepSeek, OpenAI, etc.
126
+ response = llm.invoke("帮我分析整个代码仓库")
127
+
128
+ print(response.choices[0].message.content)
129
+ ```
130
+
131
+ ### Inspect routing decisions
132
+
133
+ ```python
134
+ decision = llm.route_only("Summarize this paragraph in one sentence.")
135
+ print(decision.selected_model) # e.g. "gpt-4o-mini"
136
+ print(decision.reason) # why this model was chosen
137
+ print(decision.complexity) # e.g. ComplexityLevel.SIMPLE
138
+ ```
139
+
140
+ ### Configure policies
141
+
142
+ ```python
143
+ from runtimerouter import AutoLLM, RouterConfig
144
+
145
+ config = RouterConfig(
146
+ enable_complexity_routing=True,
147
+ enable_cost_routing=True,
148
+ fallback_model="gpt-4o-mini",
149
+ policy_order=["complexity", "cost"],
150
+ )
151
+
152
+ llm = AutoLLM(config=config)
153
+ ```
154
+
155
+ ### Use Router directly (without invoking)
156
+
157
+ ```python
158
+ from runtimerouter import Router, RouteContext
159
+
160
+ router = Router()
161
+ decision = router.route(RouteContext(prompt="Explain quantum entanglement"))
162
+ print(decision.selected_model)
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Architecture
168
+
169
+ ```
170
+ runtimerouter/
171
+ ├── autollm.py # User-facing entry point
172
+ ├── router.py # Routing pipeline orchestrator
173
+ ├── classifier.py # Task complexity & token estimation
174
+ ├── types.py # Shared data contracts (Pydantic models)
175
+ ├── config.py # Config loading utilities
176
+ ├── policies/ # Pluggable routing policies
177
+ │ ├── base.py # RoutingPolicy ABC
178
+ │ ├── complexity.py # Complexity-based routing
179
+ │ └── cost.py # Cost-based routing
180
+ ├── providers/ # Model catalog & provider metadata
181
+ │ ├── base.py # ModelProvider ABC
182
+ │ └── registry.py # ModelRegistry (default model catalog)
183
+ └── integrations/ # External execution layers
184
+ └── litellm.py # LiteLLM completion wrapper
185
+ ```
186
+
187
+ **Routing pipeline (v0.1):**
188
+
189
+ ```
190
+ User prompt
191
+
192
+
193
+ TaskClassifier.enrich() ← complexity, token estimate
194
+
195
+
196
+ Policy chain (ordered) ← complexity → cost
197
+
198
+
199
+ RouteDecision ← selected model + reason
200
+
201
+
202
+ LiteLLMIntegration ← execute completion
203
+ ```
204
+
205
+ See [docs/architecture.md](docs/architecture.md) for module boundaries and extension points.
206
+
207
+ ---
208
+
209
+ ## Roadmap
210
+
211
+ | Version | Focus |
212
+ |---------|-------|
213
+ | **v0.1** *(current)* | Auto Model Selection, Complexity Routing, Cost Routing, LiteLLM Integration |
214
+ | **v0.2** | LangGraph Integration, PydanticAI Integration |
215
+ | **v0.3** | Cache-aware Routing |
216
+ | **v0.4** | Context-aware Routing |
217
+ | **v0.5** | Session-aware Optimization |
218
+
219
+ Full details: [ROADMAP.md](ROADMAP.md)
220
+
221
+ ---
222
+
223
+ ## Contributing
224
+
225
+ We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md).
226
+
227
+ ```bash
228
+ git clone https://github.com/chenyu-dev25/RuntimeRouter.git
229
+ cd RuntimeRouter
230
+ python -m venv .venv && source .venv/bin/activate
231
+ pip install -e ".[dev]"
232
+ pytest
233
+ ```
234
+
235
+ ---
236
+
237
+ ## License
238
+
239
+ MIT — see [LICENSE](LICENSE).
240
+
241
+ ---
242
+
243
+ <p align="center">
244
+ <strong>RuntimeRouter</strong><br>
245
+ Optimize the entire AI session, not just the next model call.
246
+ </p>