Docs

Pi.

Pi is a deliberately small terminal agent: a minimal shell that adapts to how you work instead of imposing how it works. It speaks the OpenAI format, so NaN goes in as one more provider.

It installs with curl -fsSL https://pi.dev/install.sh | sh, or on Windows with powershell -c "irm https://pi.dev/install.ps1 | iex".

You can skip all of this

The NaN CLI writes this configuration for you: Setup tab, e to paste your key, space to mark Pi, c to apply.

Configuration

Declare the provider

In ~/.pi/agent/models.json:

{
  "providers": {
    "nan": {
      "baseUrl": "https://api.nan.builders/v1",
      "api": "openai-completions",
      "apiKey": "sk-your-key",
      "compat": { "supportsDeveloperRole": true },
      "models": [
        {
          "id": "deepseek-v4-flash",
          "name": "DeepSeek V4 Flash",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 1048576,
          "maxTokens": 32768
        },
        {
          "id": "glm5.3-flash",
          "name": "GLM 5.3 Flash",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 1048576,
          "maxTokens": 32768
        },
        {
          "id": "qwen3.8-flash",
          "name": "Qwen 3.8 Flash",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 1048576,
          "maxTokens": 32768
        },
        {
          "id": "mimo-v2.6-flash",
          "name": "Xiaomi MiMo V2.6 Flash",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 1048576,
          "maxTokens": 32768
        },
        {
          "id": "gemma4",
          "name": "Gemma 4",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 262144,
          "maxTokens": 65536
        },
        {
          "id": "qwen3.6",
          "name": "Qwen 3.6",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 262144,
          "maxTokens": 65536
        },
        {
          "id": "glm5.3",
          "name": "GLM 5.3 (premium)",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 1048576,
          "maxTokens": 32768
        }
      ]
    }
  }
}

This is the config for the 7 LLM models NaN serves: deepseek-v4-flash, glm5.3-flash, qwen3.8-flash, mimo-v2.6-flash, gemma4, qwen3.6 and glm5.3. It is the same set the NaN CLI writes, and the same one the OpenCode page publishes.

api: "openai-completions" is what tells Pi which format to speak. maxTokens is the ceiling for one answer, not the context. It is the same figure the OpenCode block publishes as limit.output, because it answers the same question.

Make it the default

In ~/.pi/agent/settings.json:

{
  "defaultProvider": "nan",
  "defaultModel": "glm5.3-flash"
}

This step is not optional

Without defaultProvider and defaultModel, Pi keeps using its factory provider and what you get is a 401. It is the most common failure when connecting it, and the error message does not say this file is the problem.

Try it

pi

Ask it for something short. If it answers, it is going out through the cluster. You can switch models mid-session without leaving the agent.

glm5.3-flash for coding work. deepseek-v4-flash for everything else, which also has the widest quota on the cluster.

Known issues
  • The key is written in the file. models.json lives in your home directory, so it does not usually end up in a repository, but keep it in mind if you sync your configuration between machines.
  • maxTokens is not the context. It is the ceiling for each answer. Reasoning comes out of that same budget, so if you ask for long reasoned answers, raise it.
  • The models you declare are the ones you get. Pi does not ask the cluster what is available: it shows whatever is on the list.
  • mimo-v2.6-flash goes in without its audio, and glm5.3 without its audio and video. Pi’s schema accepts "text" and "image" for input and nothing else, and a third value does not fail that one model: Pi refuses the whole file, every other provider in it included. Both models still take them through the API, just not from inside Pi.
  • glm5.3 needs a key on the premium tier. It is on the list so that a member who has it can see it. Without that tier the answer is a 401, which is explained in Choose your model.
nan.builders © 2026
Copied to clipboard