Preview, pin, or force a tier
Run /bifrost preview before sending. Pin your active
model, or prefix one prompt with frontier to override
routing once without editing config.
Model routing for Pi
Bifrost is an extension for the Pi coding agent. It chooses from models you configure before each prompt: fast or low-cost models for routine work, stronger models for hard code, without changing Pi's model by hand.
summarize this file
use a faster model
debug this race condition
use a stronger model
Routing does more than choose a tier. It changes Pi's actual active model before generation, carries model health across restarts, and avoids repeating work that may already have side effects.
The prompt enters the classification pipeline. Bifrost first checks its fuzzy Jaccard cache for a similar prompt, then optionally runs an LLM classifier. Regex rules serve as a fallback between the classifier and the default tier.
Automation stays in Pi, under your configuration and control.
Run /bifrost preview before sending. Pin your active
model, or prefix one prompt with frontier to override
routing once without editing config.
/bifrost init probes supported models available through
Pi and proposes tier lists from successful results. Review proposal
before it writes config.
Use cost, context, order, or random selection per tier. Your own Pi registry and configuration determine candidates.
Optional local JSONL debug logs record routing reason, selected tier/model, and timing, not prompt bodies. They are local files, not a hosted observability service.
After configured repeated failures, Bifrost temporarily skips a model and later allows one recovery trial. It does not replay a failed prompt automatically.
Install package, then let Pi-Bifrost propose a config from models available in Pi. It writes only after your confirmation.
pi install npm:pi-bifrost
/bifrost init
.pi/bifrost-cache.jsonl. Debug logs contain routing
metadata, timings, and prompt length, not the prompt body.
endpoint is treated as an unauthenticated
OpenAI-compatible endpoint.
Bifrost caches routing decisions locally, keeps provider caching in the provider layer, and never silently replays your work.
Pi-Bifrost maintains a local routing-classification cache. After a successful classifier result, it saves a normalized prompt and selected tier. Similar future prompts can skip the classifier call and route immediately. It does not store model answers.
The project-local file is .pi/bifrost-cache.jsonl.
By default it keeps up to 500 entries, checks exact matches first,
then uses token-set similarity, and evicts least-recently-used
entries. Use /bifrost cache stats to inspect it or
/bifrost cache clear to remove it.
No. One healthy configured model is enough to start. Multiple models
and tiers let Pi-Bifrost choose different candidates for routine,
general, and demanding work. /bifrost init shows its
proposed configuration before it writes anything.
No. Your failed prompt is never silently replayed, so Bifrost does not repeat edits, commands, or external side effects. Files, tool output, branch, and user intent can change even when prompt text looks the same.
When a model fails, Pi-Bifrost records it and routes future prompts to healthy candidates instead of silently rerunning your work.
Provider prompt or prefix caching belongs to Pi and the selected provider. Pi-Bifrost routes before the turn; it does not claim a universal provider-cache implementation or alter provider billing behavior.
Classification-cache entries contain lowercased, punctuation-stripped,
sorted prompt words, selected tier, last-use timestamp, and hit count.
They can still contain sensitive terms. Disable caching for sensitive
projects with "cache": { "enabled": false }, or choose
a different location with cache.path.
Clear the cache after substantial tier or rule changes when you want every prompt classified fresh.
Pi-Bifrost persists probe, model-activation, and settled stream
failures in .pi/bifrost-reliability.json. Repeated
failures open a circuit, so unhealthy candidates are skipped on
later prompts. After cooldown, one half-open trial can prove a
model recovered.
A tier is a key in models, such as
frontier. A route rule uses the property
model: its value can be a tier name or an exact
provider/id. There is no tier property on
a route rule.
{
"enabled": true,
"default": "general",
"strategy": "first",
"categoryStrategies": {
"quick": "cheapest",
"general": "first",
"frontier": "first"
},
"models": {
"quick": [
"ollama/qwen2.5-coder:latest"
],
"general": [
"lmstudio/openai/gpt-oss-20b"
],
"frontier": [
"openai-codex/gpt-5.4",
"opencode-go/kimi-k3"
]
},
"rules": [
{
"pattern": "\\b(debug|fix|race condition)\\b",
"model": "frontier"
}
],
"classifier": {
"enabled": true,
"model": "opencode/deepseek-v4-flash-free",
"method": "auto"
},
"reliability": {
"enabled": true,
"failureThreshold": 3,
"windowMinutes": 5,
"cooldownMinutes": 60
}
}
| Name | Behavior |
|---|---|
cheapest |
Lowest combined input and output cost |
cheapest_input |
Lowest input cost |
cheapest_output |
Lowest output cost |
largest_context |
Largest context window |
random |
Random available candidate |
first |
First available candidate in list order |
fastest |
Alias for first; uses init's one-time
probe-sorted list, not live latency measurement
|
/bifrost preview <prompt>/bifrost pin / unpin/bifrost classifier off/bifrost probe/bifrost reload/bifrost debug