Pi
Point Pi at a Tokenmaxer key.
Install and initialize Ren
Install the Ren CLI, then pair it with your account before configuring this harness.
npm install -g @renai-labs/cliren initComplete the browser pairing flow, then return here to continue.
Connect Pi to Tokenmaxer
Writes the configuration, backs up anything it touches, and adds only the models available from the providers you’ve configured in Tokenmaxer. Run it again after connecting another plan and it adds what is new.
ren inference setup piTest it
pi --provider ren --model anthropic/claude-sonnet-5 -p 'hello'A reply. Both pools live in this one provider, so `--model` also accepts the Codex ids.
Configure it manually
Replace <YOUR_KEY> with your key.
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 Ren as a provider alongside whatever Pi already has configured.
{
"providers": {
"ren": {
"baseUrl": "https://llm.useren.ai",
"api": "anthropic-messages",
"apiKey": "<YOUR_KEY>",
"compat": {
"sendSessionAffinityHeaders": true
},
"models": [
{
"id": "anthropic/claude-opus-5",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 1000000,
"maxTokens": 64000
},
{
"id": "anthropic/claude-sonnet-5",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 1000000,
"maxTokens": 64000
},
{
"id": "anthropic/claude-fable-5-1",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 1000000,
"maxTokens": 64000
},
{
"id": "anthropic/claude-haiku-4-5",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 200000,
"maxTokens": 64000
}
]
}
}
}ChatGPT models
~/.pi/agent/models.json
Adds Ren as a provider alongside whatever Pi already has configured.
{
"providers": {
"ren": {
"baseUrl": "https://llm.useren.ai",
"api": "anthropic-messages",
"apiKey": "<YOUR_KEY>",
"compat": {
"sendSessionAffinityHeaders": true
},
"models": [
{
"id": "openai/gpt-6-astra",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 272000,
"maxTokens": 64000
},
{
"id": "openai/gpt-5.6-sol",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 272000,
"maxTokens": 64000
},
{
"id": "openai/gpt-5.6-terra",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 272000,
"maxTokens": 64000
},
{
"id": "openai/gpt-5.6-luna",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 272000,
"maxTokens": 64000
},
{
"id": "openai/gpt-5.5",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 272000,
"maxTokens": 64000
},
{
"id": "openai/gpt-5.4",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 272000,
"maxTokens": 64000
},
{
"id": "openai/gpt-5.4-mini",
"reasoning": true,
"input": [
"text",
"image"
],
"contextWindow": 272000,
"maxTokens": 64000
},
{
"id": "openai/gpt-5.3-codex-spark",
"reasoning": true,
"input": [
"text"
],
"contextWindow": 128000,
"maxTokens": 64000
}
]
}
}
}