Pi
Point Pi at a Tokenmaxer access token.
Before you start
- Pi installed, with
pion your PATH. The setup script configures a harness; it does not install one. Install Pi → - Node.js 18 or newer, which the setup script runs on.
- A Tokenmaxer API key. Create one →
Run the setup script
Run this, pick Pi, and paste your key when it asks. It writes the configuration below for you, backing up anything it touches.
curl -fsSL https://tokenmaxer.dev/setup.sh | bashTo skip the menu, pass the harness: curl -fsSL https://tokenmaxer.dev/setup.sh | bash -s -- pi. Run it again after connecting another provider plan to refresh the available models, or curl -fsSL https://tokenmaxer.dev/setup.sh | bash -s -- --undo to put your files back.
Test it
pi --provider tokenmaxer --model anthropic/claude-sonnet-5-5 -p 'hello'A reply. Both serviceIds live in this one provider, so `--model` also accepts the Codex ids.
Configure it manually
This is what the setup script writes, for anyone who would rather edit the files themselves. Replace<YOUR_KEY> with your Tokenmaxer access token.
Configure adaptive thinking for Claude effort levels
Claude models need `forceAdaptiveThinking` and `thinkingLevelMap`. Otherwise Pi sends a token budget, and the requested effort changes during translation.
Set `sendSessionAffinityHeaders`
It is off by default on this transport, and without it every turn lands on a different seat and re-pays the cache.
Set each model's context and output limits
Pi auto-compacts by default as a session approaches `contextWindow`. The generated `maxTokens` value caps each response; without these model fields, Pi defaults custom models to a smaller context and output budget.
List `input` on every model
Pi decides whether to send an attachment from `model.input`, and a model that omits it is treated as text-only. `downgradeUnsupportedImages` then drops the image and the reply reads `my current model doesn't support image input, so the file was omitted`: the model appears to refuse the file rather than never receiving it. Pi's vocabulary here is `text` and `image` only; it has no document modality, so a PDF is not expressible either way.
Claude models
~/.pi/agent/models.json
Adds Tokenmaxer as a provider alongside whatever Pi already has configured.
{
"providers": {
"tokenmaxer": {
"baseUrl": "https://api.tokenmaxer.dev",
"api": "anthropic-messages",
"apiKey": "<YOUR_KEY>",
"compat": {
"sendSessionAffinityHeaders": true
},
"models": [
{
"id": "anthropic/claude-opus-5-5",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 1000000,
"maxTokens": 128000,
"compat": {
"forceAdaptiveThinking": true
},
"thinkingLevelMap": {
"low": "low",
"medium": "medium",
"high": "high",
"xhigh": "xhigh",
"max": "max"
}
},
{
"id": "anthropic/claude-sonnet-5-5",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 1000000,
"maxTokens": 128000,
"compat": {
"forceAdaptiveThinking": true
},
"thinkingLevelMap": {
"low": "low",
"medium": "medium",
"high": "high",
"xhigh": "xhigh",
"max": "max"
}
},
{
"id": "anthropic/claude-fable-5-1",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 1000000,
"maxTokens": 64000,
"compat": {
"forceAdaptiveThinking": true
},
"thinkingLevelMap": {
"low": "low",
"medium": "medium",
"high": "high",
"xhigh": "xhigh",
"max": "max"
}
},
{
"id": "anthropic/claude-haiku-5-5",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 1000000,
"maxTokens": 128000,
"compat": {
"forceAdaptiveThinking": true
},
"thinkingLevelMap": {
"low": "low",
"medium": "medium",
"high": "high",
"xhigh": "xhigh",
"max": "max"
}
}
]
}
}
}ChatGPT models
~/.pi/agent/models.json
Adds Tokenmaxer as a provider alongside whatever Pi already has configured.
{
"providers": {
"tokenmaxer": {
"baseUrl": "https://api.tokenmaxer.dev",
"api": "anthropic-messages",
"apiKey": "<YOUR_KEY>",
"compat": {
"sendSessionAffinityHeaders": true
},
"models": [
{
"id": "openai/gpt-6.1-sol",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 872000,
"maxTokens": 128000
},
{
"id": "openai/gpt-6-astra",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 872000,
"maxTokens": 128000
},
{
"id": "openai/gpt-6-sol",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 872000,
"maxTokens": 128000
},
{
"id": "openai/gpt-6-luna",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 872000,
"maxTokens": 128000
},
{
"id": "openai/gpt-5.6-terra",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 872000,
"maxTokens": 128000
},
{
"id": "openai/gpt-5.6-luna",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 872000,
"maxTokens": 128000
}
]
}
}
}