Pi

Point Pi at a Tokenmaxer access token.

Before you start

  • Pi installed, with pi on 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.

Terminal
curl -fsSL https://tokenmaxer.dev/setup.sh | bash

To 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

Terminal
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.

~/.pi/agent/models.json
{
  "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.

~/.pi/agent/models.json
{
  "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
        }
      ]
    }
  }
}