Pi
Pi (pi-mono) tutorial โ A minimal, highly extensible terminal coding framework. Add EasyRouter as a custom provider via its config file.
Project Introduction
Pi (pi-mono) is a minimal, highly extensible terminal coding framework. It ships with TypeScript extensions, skills, prompt templates, themes, a tree-structured session model, and 15+ built-in providers. Adding EasyRouter as a custom OpenAI-compatible provider is a single config edit away.
๐ฆ Prerequisites
What you'll need
- Pi (pi-mono) installed
- An EasyRouter endpoint (use
https://easyrouter.io/v1as usual) - An EasyRouter API key (generated in the console)
- A model ID exactly matching one exposed by your EasyRouter console (e.g.
claude-sonnet-4-6,gemini-2.5-flash)
๐ Step 1: Set the API key env var
export EASYROUTER_API_KEY="your-easyrouter-api-key"๐ง Step 2: Edit the Pi config file
Add EasyRouter as a provider in Pi's config file:
{
"providers": {
"easyrouter": {
"baseUrl": "https://easyrouter.io/v1",
"api": "openai-completions",
"apiKey": "$EASYROUTER_API_KEY",
"models": [
{
"id": "claude-sonnet-4-6",
"name": "Claude Sonnet 4.6",
"contextWindow": 200000,
"maxTokens": 128000,
"input": ["text"],
"reasoning": true,
"compat": {
"requiresReasoningContentOnAssistantMessages": true,
"thinkingFormat": "anthropic",
"reasoningEffortMap": {
"minimal": "low",
"low": "low",
"medium": "medium",
"high": "high",
"xhigh": "max"
}
}
},
{
"id": "gemini-2.5-flash",
"name": "Gemini 2.5 Flash",
"contextWindow": 1000000,
"maxTokens": 65536,
"input": ["text"],
"reasoning": false
}
]
}
}
}Field notes
baseUrluses the standard EasyRouter endpointhttps://easyrouter.io/v1apiis alwaysopenai-completionsapiKeyuses the$EASYROUTER_API_KEYvariable referencecompat.requiresReasoningContentOnAssistantMessages: truekeeps reasoning content on historical messages when thinking mode is activereasoningEffortMapmaps Pi's effort levels to the target model's supported levels; you can omit this block for non-reasoning models
โ Step 3: Launch & verify
Launch Pi, pick easyrouter in the provider selector, then pick a model. Send a test message โ a normal response means you're set.
โ Troubleshooting
| Issue | Fix |
|---|---|
| easyrouter not in the provider list | Check the config file path and JSON format |
| 401 Unauthorized | Make sure EASYROUTER_API_KEY is exported in the current shell |
| Reasoning model acts weird | Verify requiresReasoningContentOnAssistantMessages and thinkingFormat match the model |
| Model not found | Confirm models[].id matches your EasyRouter console |