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 Helmcode 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".
Configuration
1. Declare the provider
In ~/.pi/agent/models.json:
{
"providers": {
"helmcode": {
"baseUrl": "https://api.helmcode.com/v1",
"api": "openai-completions",
"apiKey": "sk-your-key-here",
"compat": { "supportsDeveloperRole": true },
"models": [
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 1048576,
"maxTokens": 32768
},
{
"id": "glm5.3",
"name": "GLM 5.3",
"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.6",
"name": "Qwen 3.6",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 262144,
"maxTokens": 32768
},
{
"id": "gemma4",
"name": "Gemma 4",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 262144,
"maxTokens": 32768
}
]
}
}
}
api: "openai-completions" is what tells Pi which format to speak. maxTokens is the ceiling for one answer, not the context — the same figure the OpenCode block publishes as limit.output, because it answers the same question.
2. Make it the default
In ~/.pi/agent/settings.json:
{
"defaultProvider": "helmcode",
"defaultModel": "glm5.3-flash"
}
An interactive session needs a default model and says so. Without defaultModel, the first thing Pi tells you after you connect is:
Error: Saved API key for helmcode, but no default model is configured for
provider "helmcode". Use /model to select a model.
You can obey that and pick with /model every session, or write it here once. Pi does not persist your pick: the settings.json it writes on its own carries the theme and nothing else.
Headless is the exception — pi -p resolves a model without this file. And if you declare a second provider without setting defaultProvider, Pi chooses for you; in our test it took the other one and failed against it.
3. Keep the key out of the file, if you prefer
This one runs after step 1, not instead of it: /login offers the providers declared in models.json, so if helmcode is not on the list, that file has not landed. Nothing says so — the entry is simply absent.
Instead of the apiKey field above, start a session and run:
/login
Paste the key when it asks. Pi writes ~/.pi/agent/auth.json with mode 600, so your models.json carries no secret and can be synced between machines freely. Do not write that file by hand: the credential is typed ("type": "api_key") and a plausible guess at the shape is accepted in silence and then does not authenticate.
Either way, this confirms the provider is usable before you ask it anything:
pi auth check --provider helmcode
It prints ready.
4. Try it
pi
Ask it for something short. If it answers, it is going out through Helmcode. You can switch models mid-session without leaving the agent.
Recommended model
glm5.3-flash for coding work: a 1M window, and it counts against the same monthly quota as deepseek-v4-flash, which is the other 1M model on every plan. qwen3.6 for everything that is bounded and wants an answer now.
Known issues
- An error about a
ByteStringis a broken key, not a broken model. If a request fails withCannot convert argument to a ByteString because the character at index 7 has a value of …, the key has a non-ASCII character in it. Index 7 is the first character afterBearer, so it is naming the first character of your credential. It happens when the key is copied out of a framed terminal UI and a box-drawing character comes along: the message mentions neither the key nor the header, so there is nothing to connect it to. Keys start withsk-hke_and are ASCII throughout, which makes it quick to confirm. - The key is written in the file, unless you used
/login.models.jsonlives 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. maxTokensis 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 API what is available: it shows whatever is on the list.