Pi
Pi is a minimal, extensible terminal coding agent.
LowRouter has a provider package for it,
@lowrouter/pi-provider.
Without the package, Pi also takes LowRouter as a custom provider in
models.json.
Install the package
The package needs Pi 1.3.0 or later, which needs Node.js 22.19 or later.
npm install -g @earendil-works/pi-coding-agent@latest
pi install npm:@lowrouter/pi-providerAdd your key in one of two ways. You can export it:
export LOWROUTER_API_KEY=sk-lr-...Or store it in Pi: run /login in a session and pick LowRouter.
Then pick a model:
pi --list-models lowrouter
pi --model lowrouter/auto/mistralai/mistral-large-2512You can also switch with /model in a session.
What the package does:
- It reads the model list from LowRouter when Pi starts, when the
/modelpicker refreshes, and onpi update --models. A new model shows up without a package update. Pi keeps the last list for offline starts. - It lists
auto/chat models with function calling, plus your account’salias/models. Context windows and output limits come from the same list, so you don’t set them yourself. - Pi shows costs in US dollars. The package uses the price of each model’s most expensive route, so Pi’s estimate is an upper bound. You are billed in euros, for the route that served the request.
Jurisdiction-scoped IDs such as auto/mistralai/mistral-large-2512/eu
and pinned routes are not in the list. To use one, add it to
models.json as shown below.
The package’s source and release notes are on GitHub.
Without the package
Verified against Pi 1.3.0. The config below is re-run against that release every week, including a tool call round trip.
Configure
Add LowRouter as a provider in ~/.pi/agent/models.json:
{
"providers": {
"lowrouter": {
"name": "LowRouter",
"baseUrl": "https://api.lowrouter.ai/v1",
"api": "openai-completions",
"apiKey": "$LOWROUTER_API_KEY",
"compat": { "supportsDeveloperRole": false, "supportsStore": false },
"models": [
{
"id": "auto/mistralai/mistral-large-2512",
"name": "Mistral Large (LowRouter)",
"input": ["text", "image"],
"contextWindow": 256000,
"maxTokens": 8192
}
]
}
}
}$LOWROUTER_API_KEY is read from the environment, so the key stays out
of the file:
export LOWROUTER_API_KEY=sk-lr-...
pi --model lowrouter/auto/mistralai/mistral-large-2512Details of this config:
- The model reference is
lowrouter/followed by the LowRouter model ID. Pi splits on the first slash only, so the slashes inside the ID are fine. baseUrlends in/v1. Pi appends/chat/completions.contextWindowis what Pi plans compaction around, andmaxTokenscaps the answer length it asks for. Without them Pi assumes 128,000 and 16,384, which some models reject. Take both from the model browser.compatturns off thedeveloperrole and thestorefield. Some of the upstream hosts LowRouter routes to reject them.- Each additional model is another entry in
models. A scoped ID such asauto/mistralai/mistral-large-2512/euor a pinned route goes in the same list. - If the package is installed too, entries in
models.jsonadd to the package’s list or replace entries that have the same ID.
Picking a model
Pi works through tools: it reads, edits and writes files and runs commands. Pick a model with the function-calling tag; the model browser filtered to them lists every one.
The example uses auto/mistralai/mistral-large-2512, served from the
EU (256k context). Other models we have run through Pi’s tool loop:
auto/mistralai/mistral-small-2603, a smaller, cheaper Mistral model served from the EU (256k context).auto/openai/gpt-5.5(1M context).
Recommended setup
- Use a dedicated key, so Pi’s spend shows separately and can be revoked on its own.
- Without the package, give each model its real
contextWindowand amaxTokenswithin the model’s output limit. The package reads both from LowRouter.
Troubleshooting
- “No models available”: Pi lists a provider’s models only once it has
a key. Export
LOWROUTER_API_KEYor run/login, then try again. pi installfails, or the package never loads: checknode --version. Pi needs 22.19 or later.pi -pin a script prints nothing and never exits: print mode reads piped stdin. Close it with</dev/null.- A
401naming a malformed key: the key was cut off when copied. Copy it again in full, or create a new one at /app/keys. - A
400about output tokens: the model’s output limit is lower thanmaxTokens(or the 16,384 default). LowermaxTokensfor that model entry. - Something else is off: run
pi -neto start without extensions and rule out a conflict with another package.-nealso turns off the LowRouter package, so LowRouter models are then available only frommodels.json.
