awrouter — Aither World Router
The stateless LLM routing plane: given a model id and a request, decide which backend should serve it right now — capability filter, then a policy-weighted cost/latency score, then failover through health probes — fit the context window, and stream the completion over the OpenAI wire shape.
OpenRouter for your own fleet. Standalone, OpenAI-compatible, no platform dependencies: the registry is a plain dict, auth is a pluggable callable, and the stateful scheduler plane (queues, budgets, heartbeats) belongs to whoever consumes this package, not to it.
Install
pip install awrouter # core: stdlib-only
pip install "awrouter[serve]" # + the OpenAI wire server (fastapi/uvicorn)
Use
from awrouter import Backend, ModelSpec, ResolutionPolicy, Resolver, Registry
registry = Registry()
registry.register(Backend(
id="fast",
base_url="http://127.0.0.1:9000",
aliases=["quick-model"],
capabilities={"chat", "tools"},
context_window=8192,
))
resolver = Resolver(registry, ResolutionPolicy(cost_weight=1.0, latency_weight=0.5))
# Resolve, or raise Refusal with the reason — never a silent downgrade.
resolution = resolver.resolve("quick-model", prompt_chars=2_000)
print(resolution.backend.id)
CLI
awrouter resolve quick-model # -> fast
awrouter resolve big-model --tier free # refused: not allowed on tier 'free'
awrouter fit --prompt-chars 50000 --window 8192 # refused: context overflow
awrouter backends --json # the registry inventory
awrouter serve --port 8240 # /v1/models + /v1/chat/completions
awrouter self-test # prove the refusals can fire (exit 1 on any silent pass)
The contract
- Refuse, never guess. Unknown model, capability gap, tier block,
thinking model with no thinking backend, context overflow, all-dead
backends — each is a
Refusalwith the reason. Nothing is truncated, downgraded, or silently re-routed. - Stateless. The resolver holds no queue, no budget, no in-flight state. Scale it horizontally; the state lives in the caller.
- Pluggable seams. Backend discovery, auth, token counting, and health probes are injectable; the shipped defaults are honest stand-ins (the token estimate is a chars-per-token ratio, declared as such).
License
Apache-2.0.
Metadata
Release files for awrouter 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| awrouter-0.1.0.tar.gz | 17.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| awrouter-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.7 kB
Release files / awrouter-0.1.0.tar.gz
| Download URL | awrouter-0.1.0.tar.gz |
|---|---|
| Size | 17.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
edff67a215682e2f359018987912f4f1aa0f03f3fa8158e9c1b9f16a3d109314
|
|
BLAKE2b-256 checksum How to use checksums |
b6cd5b8885574ea3e3c30cc12a304877050ee908907cdd6e0eb506e00a84b66a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / awrouter-0.1.0-py3-none-any.whl
| Download URL | awrouter-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0ef6b6a8e53c6829e700597b61af45f826f37d41b9bafc7928802a5d350e9fbb
|
|
BLAKE2b-256 checksum How to use checksums |
68e1f6ad4a0ae15202882325a7661fbc28304ef1b78be24ad8bf0864c36dea03
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|