Drop-in hybrid local/remote LLM routing for token-efficient AI apps
Project description
voxrouter
Drop-in hybrid local/remote LLM routing. Send every prompt to the cheapest model that can actually handle it — free local models for simple tasks, remote models only when needed.
pip install voxrouter
Quick start
import asyncio
from voxrouter import route
async def main():
result = await route("What is the capital of France?")
print(result.answer) # "Paris"
print(result.route) # "local"
print(result.cost_usd) # 0.0
asyncio.run(main())
Complex prompts automatically go remote:
result = await route(
"Design a rate limiter for an API gateway handling 50,000 req/s",
gemini_api_key="your-key-here",
)
print(result.route) # "remote"
print(result.model_used) # "gemini/gemini-2.5-flash-lite"
Setup
VoxRouter needs two things to actually run tasks:
-
A local model via Ollama for cheap/simple tasks:
ollama serve ollama pull llama3.2:1b ollama pull qwen2.5:3b ollama pull phi3.5:3.8b
-
A Gemini API key for complex tasks — get one free at aistudio.google.com/apikey:
export GEMINI_API_KEY=your-key-here
Without Ollama running, local-routed calls will raise ConnectionError. Without a Gemini key, remote-routed calls will raise ValueError. Both are intentional — see Error handling below.
Class-based usage
For repeated calls with the same configuration:
from voxrouter import VoxRouter
vr = VoxRouter(gemini_api_key="your-key", ollama_host="http://localhost:11434")
result1 = await vr.route("Is 17 a prime number?")
result2 = await vr.route("Explain how transformers use attention")
Forcing a route
# Skip escalation — answer locally no matter what
result = await route(prompt, force_local=True)
# Skip local entirely — always use the remote model
result = await route(prompt, force_remote=True)
Task type hints
Giving a hint improves routing accuracy for ambiguous prompts:
result = await route(
"What's the time complexity here?",
task_type="factual", # nudges toward local
)
Valid values: factual, boolean, classification, extraction, reasoning, generation, code, math_proof.
How routing works
- The prompt is classified into a complexity tier (1–5) using pattern matching, structural analysis, and vocabulary entropy.
- Tiers 1–2 go to a local Ollama model. Tiers 3–5 go to Gemini.
- If a local answer comes back with confidence below
confidence_threshold(default0.72), it's automatically escalated to remote — you get the better answer without needing to detect the failure yourself.
RouteResult fields
result.answer # the model's response
result.route # "local" | "remote"
result.model_used # e.g. "local/qwen2.5:3b" or "gemini/gemini-2.5-flash-lite"
result.complexity_score # 1-5
result.complexity_label # "trivial" | "simple" | "moderate" | "complex" | "expert"
result.tokens_used # total tokens for this call
result.cost_usd # 0.0 for local, real cost for remote
result.latency_ms # end-to-end latency
result.confidence # 0.0-1.0
result.escalated # True if it started local and moved to remote
result.escalation_reason # why, if escalated
Error handling
try:
result = await route(prompt, force_local=True)
except ConnectionError:
print("Ollama isn't running — start it with `ollama serve`")
try:
result = await route(prompt, force_remote=True)
except ValueError:
print("No Gemini API key configured")
License
MIT — see LICENSE. If VoxRouter saves you money in production, a star or a mention is appreciated but never required.
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 voxroutersho-0.1.0.tar.gz.
File metadata
- Download URL: voxroutersho-0.1.0.tar.gz
- Upload date:
- Size: 9.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a61232d5a671e55a1ab2f85079965692879380781ccc71964cf812dabc31882
|
|
| MD5 |
e567335e861279a427ed59f9e2e9ff7c
|
|
| BLAKE2b-256 |
d9c619403e16b86b8481dd1f17e8fb03e801cbb7253ed4bc1372d6424a10f5fc
|
File details
Details for the file voxroutersho-0.1.0-py3-none-any.whl.
File metadata
- Download URL: voxroutersho-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d449bfe26f38850ae0bd18dc432b02fde11d5b000c9008d80eb4180dcee8b490
|
|
| MD5 |
d47b6085956d95997f04747997404295
|
|
| BLAKE2b-256 |
06d0d3d2344a05c195c5c3858747b5724045cdcc06bf1ac75a58209b770dd636
|