Intelligent routing layer for pi (coding agent) with multi-level failover and observability.
English | 简体中文
- Features
- Quick Start
- Commands
- How It Works
- Configuration Reference
- Performance
- Uninstall
- Architecture
- Further Reading
- License
- Auto Router mode — select
router/autoand let pi-router handle all routing automatically - Channel failover for the same model across different providers
- Model fallback with context transfer
- Smart routing by latency, capability, cost, or manual order
- Circuit breaker and cooldown protection
- Persistent sticky routing — remembers the last successful channel across restarts
- Decision logging, latency tracking, and health monitoring
- Footer status showing the active provider channel
- Interactive menus and tab completion for all commands
- Interactive configuration wizard
- Fast startup with lazy loading and caching
# From npm (after publication)
pi install npm:pi-router
# Or from GitHub
pi install git:github.com/jiangjilin/pi-router
# Or from local directory (for development)
pi install /path/to/pi-routerSee INSTALL.md for detailed installation options.
Recommended: run the interactive wizard.
/router config wizardThe wizard walks through:
- Routing strategy (
channelFirst/custom) - Sort strategy (
latency/capabilityFirst/cost/manual) - Auto-sync (
enable/disable) - Health probe (
10 minutes/disabled) - Sticky mode (
enable/disable) - Optional channel order adjustment
Channel Classification: The wizard automatically classifies channels into three categories:
- 🔵 OAuth (Official) - Official API endpoints from AI providers (e.g.,
api.anthropic.com,api.deepseek.com) - 🟡 Aggregator (Third-party) - Third-party aggregation services
- 🟢 Free (Local) - Local deployments and free services
Classification is based on:
auth.jsonOAuth markers (type: "oauth")- Official domain whitelist (40+ providers including Anthropic, OpenAI, Google, DeepSeek, Qwen, GLM, Kimi, and more)
- Local URL detection (
localhost,127.0.0.1)
Configuration is stored at:
~/.pi/agent/pi-router.json
Advanced users can edit the file directly. A companion file is also generated:
~/.pi/agent/pi-router.README.md
A reference example is available at examples/router.config.json.
In pi, select the Auto Router model:
/model router/auto
This routes all requests through pi-router automatically, using your configured strategy and model chain.
You can also select a specific model with routing:
/model router/your-model-id
pi-router will then:
- try channels in order (based on strategy)
- fail over on errors
- apply circuit breaker and cooldown rules
- optionally fall back to another model
- record health and latency information
- display the active channel in the footer (e.g.,
via anthropic) - remember the last successful route for next time (sticky mode)
Run /router without arguments to open an interactive menu, or use tab completion.
/router config wizard # Interactive configuration wizard
/router config order # Adjust existing model/channel order only
/router config show # Show current configuration
/router config reset # Reset to default configuration
Shortcuts:
/router config w # = wizard
/router config o # = order
/router config s # = show
/router config r # = reset
/router status # Show config summary
/router list # List configured router models
/router explain # Show failures, latency, health, circuits
/router decisions # Show recent routing decisions
/router probes # Show background health probe results
/router pricing # Show per-channel pricing breakdown
/router sticky # Show current sticky routing records
/router sticky clear # Clear all sticky records (re-route from beginning)
/router sticky clear <m> # Clear sticky record for a specific model
/router sync # Check models.json changes
/router sync accept # Apply detected changes
/router diff # Preview config differences
When you select router/auto, pi-router manages the full model chain:
User Request: router/auto
↓
Check sticky record → found "model-X@channel-Y"?
↓ yes ↓ no
Try sticky first Follow strategy order
↓ fail ↓
Clear sticky, fall back to strategy order
↓
channelFirst: Model-A[ch1,ch2,ch3] → Model-B[ch1,ch2] → ...
custom: explicit model@channel order from customOrder
↓
On success: update sticky record, stream response
↓
Footer shows: via <channel-name>
Example:
Try channels: Provider-A -> Provider-B -> Provider-C
Typical flow:
User Request: router/example-model
↓
Router intercepts
↓
Try Provider-A -> Provider-B -> Provider-C
- check cooldown
- check circuit breaker
- forward to real provider
- on error: record failure, try next
↓
If all channels fail, try fallback model
↓
Stream events back to user
Sticky mode remembers the last successful route and tries it first on next request:
Request 1: Provider-A succeeds → sticky = Provider-A
Request 2: Provider-A tried first → succeeds
Request 3: Provider-A fails → clear sticky, try Provider-B → succeeds → sticky = Provider-B
Request 4: Provider-B tried first
...
(Persists across pi restarts)
Use /router sticky clear to reset and re-route from the beginning.
Failures: 0 -> 1 -> 2 -> 3 -> 4 -> 5 (open)
↓
Block requests for a cooldown window
↓
Half-open: allow a test request
↓
Success -> closed
Failure -> open again
When switching models:
summarymode: summarize the conversation- sanitize incompatible context fields if needed
- forward the adapted context to the fallback model
~/.pi/agent/pi-router.json
{
"strategy": "channelFirst",
"sortBy": "latency",
"autoSync": true,
"sticky": true,
"healthProbe": {
"enabled": false
},
"models": [
{
"id": "example-model",
"channels": ["Provider-A", "Provider-B", "Provider-C"]
}
]
}{
"strategy": "channelFirst",
"auto": true,
"sortBy": "latency",
"autoSync": true,
"sticky": true,
"request": {
"timeoutMs": 120000,
"maxRetries": 0,
"maxRetryDelayMs": 1000,
"maxTokens": 32768
},
"footer": {
"rightAlignRoute": true,
"statusLine": true
},
"contextTransfer": "summary",
"summaryModel": "optional-summary-model",
"summaryPrompt": "optional custom prompt",
"summaryMaxTokens": 2000,
"failover": {
"cooldownMs": 60000
},
"healthProbe": {
"enabled": true,
"intervalMs": 600000,
"timeoutMs": 10000,
"probeMessage": "ping"
}
}Footer defaults:
footer.rightAlignRoutedefaults totrue: while router status is active, pi-router replaces pi's footer so route status can be right-aligned- set
footer.rightAlignRoutetofalseto keep pi's built-in footer layout footer.statusLinedefaults totrue: when the replacement footer is disabled, pi-router still shows a short built-in status item- set
footer.statusLinetofalseto suppress that fallback status item
Default behavior:
summaryModelis not required- if the current context still fits inside the selected target model's context window, pi-router skips summary generation and forwards the full context
- when a summary is needed and
summaryModelis unset, pi-router first uses the target model for summary generation - if AI summary generation fails, pi-router falls back to a plain text non-AI summary path
summaryMaxTokensdefaults to2000
Optional dedicated summary AI configuration:
{
"contextTransfer": "summary",
"summaryModel": "cheap-summary-model",
"summaryPrompt": "Summarize the conversation for model handoff.",
"summaryMaxTokens": 2000
}summaryModel supports either:
model-idmodel-id@provider
{
"id": "example-model",
"channels": ["Provider-A", "Provider-B"],
"sticky": true,
"sortBy": "latency",
"contextTransfer": "summary",
"fallbackModels": [
{
"id": "fallback-model",
"channels": ["Provider-A", "Provider-B"]
}
],
"failover": {
"cooldownMs": 30000
}
}You can edit ~/.pi/agent/pi-router.json directly.
After editing:
/reload
or restart pi.
pi-router is optimized for fast startup with minimal overhead.
- smart file hash caching
- lazy loading of
models.json - deferred health probe startup
- reduced duplicate file I/O
| Scenario | Before | After | Improvement |
|---|---|---|---|
| Hot cache | ~50-80ms | ~5-15ms | ~80% |
| Cold cache | ~50-80ms | ~30-50ms | ~40% |
| autoSync disabled | ~30-50ms | ~5-10ms | ~80% |
| healthProbe disabled | ~40-60ms | ~5-15ms | ~75% |
See PERFORMANCE_OPTIMIZATION.md for details.
# npm install
pi remove npm:pi-router
# git install
pi remove git:github.com/jiangjilin/pi-router
# local install
pi remove /path/to/pi-routerConfiguration files are not removed automatically.
rm -f ~/.pi/agent/pi-router.json ~/.pi/agent/pi-router.README.mdSee ARCHITECTURE.md for detailed design documentation.
MIT
Built with the pi coding agent extension API.