Files
ThothII/docs/general/pi-configuration.md
T
Codex 7d32bb1e74
Publish documentation / publish (push) Successful in 43s
docs: publish English public documentation
2026-08-26 10:54:44 +02:00

207 lines
9.5 KiB
Markdown

# Local Pi model configuration
Pi orchestrates the NL-to-SQL workflow and resolves built-in models and OpenAI-compatible providers
declared in the local catalog. ThothII applies a stricter rule than Pi: code in
`harness/.pi/extensions/` cannot register a provider or custom model. Endpoints, protocols,
compatibility settings, and model identifiers belong exclusively in the local files
`deploy/pi/models.json` and `deploy/pi/settings.json`.
> **ThothII operator note:** ThothII runs Pi only in Docker Compose. Paths under
> `~/.pi/agent/` in this document describe Pi's container-side behavior. Operators edit
> `deploy/pi/models.json` and `deploy/pi/settings.json` in the ThothII project root and use
> the protected host credential file selected by `PI_AUTH_FILE`; they do not edit files inside
> the running container.
## Credentials in the backend container
In production, configure one generic source: the `THT_SECRETS_FILE` bundle with the
`THT_MODEL_API_KEY` entry, which is the default for the unified distribution, or
`THT_MODEL_API_KEY_FILE` as an absolute secret-file path. Do not put the key value in `.env`.
For each process, `PiProcessManager` rereads and validates the source, normalizes the selected
provider, and passes only the appropriate native variable to the Pi child
(`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `ZAI_API_KEY`, and so on). It removes the
generic path, keys for unselected providers, and the old `PI_PROVIDER_API_KEY` from the child
environment. For a custom provider, the backend derives the variable name from the declarative
`apiKey` field in `models.json`; a literal value means the catalog is self-contained. Provider-name
exceptions are not compiled into the code. A missing or insecure secret fails before spawn with a
sanitized error.
The generic source supports only single-key providers: `ant-ling`, `anthropic`,
`cerebras`, `deepseek`, `fireworks`, `github-copilot`, `google` (including the `gemini` alias),
`google-vertex` in API-key mode, `groq`, `huggingface`, `kimi-coding`, `minimax`, `minimax-cn`,
`mistral`, `moonshotai`, `moonshotai-cn`, `nvidia`, `openai`, `opencode`, `opencode-go`,
`openrouter`, `together`, `vercel-ai-gateway`, `xai`, the four `xiaomi*` providers, `zai`, and
`zai-coding-cn`.
The composite providers `amazon-bedrock`, `azure-openai-responses`, `cloudflare-workers-ai`, and
`cloudflare-ai-gateway` cannot be represented by one file. Selection fails before spawn, including
when models are listed. AWS, Azure, and Cloudflare environment credentials are still removed. A
future provider-specific configuration will be needed to support these bundles unambiguously.
## Model sources
### 1. Built-in (compiled into Pi)
Pi ships with a list of known models (`models.generated.js` in the `@earendil-works/pi-ai` package):
Anthropic, OpenAI, Google, and third-party providers with well-known public APIs such as DeepSeek.
These require **no configuration** beyond credentials, provided through an environment variable or
`pi auth`.
`deepseek/deepseek-v4-pro` is one of these models. It is included in Pi because `api.deepseek.com`
is a documented public API, not an internal endpoint.
### 2. User-level `models.json` (`~/.pi/agent/models.json`)
For an **OpenAI-compatible** endpoint that is not built in but needs no special transport logic,
declare it with its baseUrl, apiKey, and model list. This file exists **only at user level**; there is
no project-level equivalent, and `./.pi/models.json` is not read.
In ThothII-managed installations, the file must be entirely declarative. ThothII recursively
rejects any JSON value that starts with `!`, including values inside `headers`, `models`,
`modelOverrides`, `compat`, arrays, or fields it does not yet know. Pi 0.80.3 would treat that
prefix as a shell command when making a request, so managed model catalogs do not allow it. The
returned error is fixed and contains no command, path, or secret.
For secrets, use an environment reference such as `"$ZAI_API_KEY"` or `"${ZAI_API_KEY}"`. The
backend can populate the native variable for the selected provider by reading
`THT_MODEL_API_KEY_FILE`, or from the `THT_SECRETS_FILE` bundle (`THT_MODEL_API_KEY`). Credentials
can also come from the protected file mounted through `PI_AUTH_FILE`, with `apiKey` omitted from
`models.json`. There is no direct secret-file reference syntax in `models.json`. With `THT_MODEL_*`
sources, ThothII reads the file and turns it into the Pi child's environment variable; `PI_AUTH_FILE`
is mounted instead as a protected Pi credential store. For a literal leading exclamation mark, Pi's
declarative syntax is `$!`, not `!`.
Real example in use on this machine: GLM (provider `zai`):
```json
{
"providers": {
"zai": {
"baseUrl": "https://api.z.ai/api/coding/paas/v4",
"api": "openai-completions",
"apiKey": "$ZAI_API_KEY",
"models": [
{
"id": "glm-5.2",
"name": "GLM-5.2",
"reasoning": true,
"contextWindow": 200000,
"maxTokens": 131072
}
]
}
}
}
```
Because it is user-level, GLM is visible to **every project**.
### Extension providers: not allowed in ThothII
Pi technically supports providers registered by JavaScript extensions, but ThothII does not use
that capability. Project extensions are reserved for the workflow and gates; they must not contain
`registerProvider(...)`. An endpoint that cannot be described by the OpenAI-compatible catalog is
not supported by this installation until the declarative contract is extended generically.
## Summary table (current machine state)
| Model | Level | Why | Visibility |
|---|---|---|---|
| `deepseek/deepseek-v4-pro` | Built-in Pi | Known public API, already in the build | All projects |
| `zai/glm-5.3` | `deploy/pi/models.json` | Custom OpenAI-compatible endpoint | ThothII installation |
| `local-qwen/qwen3.6-35b-a3b` | `deploy/pi/models.json` | Locally configured OpenAI-compatible endpoint | ThothII installation |
## Choosing the right level for a new model
1. **Is the endpoint a public API already known to Pi?** Enable the exact identifier in `deploy/pi/settings.json`.
2. **Is it OpenAI-compatible but not built in?** Declare it in `deploy/pi/models.json`, then enable it in `deploy/pi/settings.json`.
3. **Does it require provider-specific transport code?** Do not add a provider-specific extension. The provider is unsupported until a generic declarative capability exists.
---
## User versus project scope: general summary
In addition to models, Pi loads other resources from two parallel trees: `~/.pi/agent/` (user) and
`<cwd>/.pi/` (project, resolved from the directory where `pi` is launched).
| File/Directory | Livello utente | Livello progetto | Auto-discovery | Precedenza |
|---|---|---|---|---|
| `models.json` | `~/.pi/agent/models.json` | not supported | no | user only |
| `settings.json` | `~/.pi/agent/settings.json` | `./.pi/settings.json` | no | project overrides user |
| `extensions/` | `~/.pi/agent/extensions/` | `./.pi/extensions/` | yes (`.ts`/`.js`) | merged (project + user) |
| `prompts/` | `~/.pi/agent/prompts/` | `./.pi/prompts/` | yes (`.md`) | merged |
| `themes/` | `~/.pi/agent/themes/` | `./.pi/themes/` | yes (`.json`) | project preferred |
| `skills/` | `~/.pi/agent/skills/` | `./.pi/skills/` | yes (`.md`) | merged |
### Real example: ThothII
```
harness/.pi/
├── extensions/
│ ├── tht-gate.js # human-in-the-loop gate
│ └── gate/
│ ├── core/ # shared gate enforcement and utilities
│ ├── disambiguation/ # F1/F3 policy
│ └── memory/ # F2/F8 policy
├── settings.json # optional override of user settings
└── themes/
└── thothii-mono.json # project theme
```
### Behavior relative to cwd
The directory from which you launch `pi` determines which workflow extensions are found, but not
which models ThothII makes available. The catalog is mounted in the container's Pi agent directory.
```bash
# From harness/: load the project gate and mounted local catalog
cd /path/to/ThothII/harness
pi --model local-qwen/qwen3.6-35b-a3b "..."
```
The ThothII backend always launches Pi with `cwd: harnessDir` for the workflow. Model availability
continues to depend only on `models.json`, `settings.json`, and local credentials.
---
## Auto-discovery trap: `.mjs` is ignored
Pi's extension auto-discovery pattern is **`/\.(ts|js)$/`**; it does not include `.mjs`.
```
.pi/extensions/
├── my-extension.js ✅ auto-loaded
├── my-extension.ts ✅ auto-loaded
├── my-extension.mjs ❌ silently ignored (does not match the pattern)
└── shared-module.mjs ✅ suitable for helper modules (deliberately not loaded as an extension)
```
If an extension imports a shared module, use `.mjs` so Pi does not treat it as an extension on its own.
---
## Verifica
### List models
```bash
pi --list-models
```
This shows built-in models and models declared in `models.json`.
### Check the catalog used by the application
```bash
cd harness # or the project's relevant cwd
pi --mode rpc
# poi: {"type": "get_available_models", "id": "1"}
```
The RPC response must include only built-in models or models declared in the local catalog.
---
## Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| `Model "X/Y" not found` | Provider/model missing from `models.json` or identifier missing from `enabledModels` | Fix the two local files and reload Pi |
| Project settings not applied | Project `settings.json` has a syntax error, or `pi` is launched from the wrong cwd | Validate the JSON and check the cwd |