10 KiB
Configurazione locale dei modelli Pi
Pi, l'agente che orchestra il workflow NL→SQL, risolve i modelli integrati e i provider
OpenAI-compatible dichiarati nel catalogo locale. ThothII applica una regola più stretta di Pi:
un provider o un modello custom non può essere registrato da codice in harness/.pi/extensions/.
Endpoint, protocollo, compatibilità e identificatori dei modelli appartengono esclusivamente ai file
locali deploy/pi/models.json e 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 editdeploy/pi/models.jsonanddeploy/pi/settings.jsonin the ThothII project root and use the protected host credential file selected byPI_AUTH_FILE; they do not edit files inside the running container.
Credenziali nel backend container
In produzione configurare una sola sorgente generica: il bundle THT_SECRETS_FILE con la voce
THT_MODEL_API_KEY (predefinito della distribuzione unificata), oppure
THT_MODEL_API_KEY_FILE come secret file assoluto. Non mettere il valore della chiave in .env.
PiProcessManager rilegge e valida la sorgente per ogni processo, normalizza il provider
selezionato e passa al solo child Pi la variabile nativa appropriata
(ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, ZAI_API_KEY, ecc.). Il percorso generico,
le chiavi di provider non selezionati e il vecchio PI_PROVIDER_API_KEY vengono rimossi dall'ambiente
del child. Per un provider custom, il backend deriva il nome della variabile dal campo dichiarativo
apiKey di models.json; un valore letterale indica che il catalogo è autosufficiente. Non esistono
eccezioni per nomi di provider compilate nel codice. Un secret mancante o non sicuro fallisce prima
dello spawn con errore sanitizzato.
La sorgente generica supporta soltanto provider con una singola chiave: ant-ling, anthropic,
cerebras, deepseek, fireworks, github-copilot, google (anche tramite alias gemini),
google-vertex in modalità API key, groq, huggingface, kimi-coding, minimax, minimax-cn,
mistral, moonshotai, moonshotai-cn, nvidia, openai, opencode, opencode-go,
openrouter, together, vercel-ai-gateway, xai, i quattro provider xiaomi*, zai e
zai-coding-cn.
I provider composti amazon-bedrock, azure-openai-responses, cloudflare-workers-ai e
cloudflare-ai-gateway non sono rappresentabili da un solo file. La selezione fallisce prima
dello spawn (anche durante l'elenco modelli); tutte le credenziali ambientali AWS, Azure e
Cloudflare restano comunque rimosse. Servirà una futura configurazione dedicata per provider per
supportare questi bundle senza ambiguità.
Le fonti di un modello
1. Built-in (compilato dentro Pi)
Pi viene distribuito con un elenco di modelli già noti (models.generated.js dentro il pacchetto @earendil-works/pi-ai): Anthropic, OpenAI, Google, e anche provider di terze parti con API pubblica ben nota come DeepSeek. Per questi non serve alcuna configurazione: bastano le credenziali (env var o pi auth).
deepseek/deepseek-v4-pro è così: è nella build di Pi perché api.deepseek.com è un'API pubblica documentata, non un endpoint interno.
2. models.json a livello utente (~/.pi/agent/models.json)
Per un endpoint OpenAI-compatible che non è tra i built-in — ma che non richiede nessuna logica di trasporto speciale — basta dichiararlo: baseUrl, apiKey, lista modelli. Questo file esiste solo a livello utente: non c'è un equivalente project-level (un ./.pi/models.json non viene letto).
Nelle installazioni gestite da ThothII il file deve essere interamente dichiarativo. ThothII
rifiuta ricorsivamente qualsiasi valore JSON che inizi con !, anche dentro headers, models,
modelOverrides, compat, array o campi non ancora conosciuti. Pi 0.80.3 tratterebbe quel prefisso
come un comando shell al momento della richiesta; questa forma non è ammessa dall'elenco gestito
dei modelli. L'errore restituito è fisso e non include comando, percorso o
secret.
Per i secret usare un riferimento ambiente come "$ZAI_API_KEY" o "${ZAI_API_KEY}". Il backend
può popolare la variabile nativa del solo provider selezionato leggendo
THT_MODEL_API_KEY_FILE, oppure dal bundle THT_SECRETS_FILE (THT_MODEL_API_KEY); in alternativa
le credenziali possono arrivare dal file protetto montato con PI_AUTH_FILE, omettendo apiKey da
models.json. Non esiste una sintassi di riferimento diretto a un secret file dentro
models.json: con le sorgenti THT_MODEL_* il file viene letto da ThothII e trasformato nella
variabile ambiente del child Pi; PI_AUTH_FILE viene invece montato come archivio credenziali Pi
protetto. Per un punto esclamativo letterale iniziale, la sintassi Pi dichiarativa è $!, non !.
Esempio reale in uso su questa macchina — GLM (provider zai):
{
"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
}
]
}
}
}
Essendo a livello utente, GLM è visibile da qualsiasi progetto.
Provider da estensione: non ammessi in ThothII
Pi supporta tecnicamente provider registrati da estensioni JavaScript, ma ThothII non usa questa
possibilità. Le estensioni di progetto sono riservate al workflow e ai gate; non devono contenere
registerProvider(...). Un endpoint che non può essere descritto dal catalogo OpenAI-compatible
non è un provider supportato da questa installazione finché il contratto dichiarativo non viene
esteso in modo generico.
Tabella riassuntiva (stato attuale di questa macchina)
| Modello | Livello | Perché | Visibilità |
|---|---|---|---|
deepseek/deepseek-v4-pro |
Built-in Pi | API pubblica nota, già nella build | Tutti i progetti |
zai/glm-5.3 |
deploy/pi/models.json |
Endpoint OpenAI-compatible custom | Installazione ThothII |
local-qwen/qwen3.6-35b-a3b |
deploy/pi/models.json |
Endpoint OpenAI-compatible configurato localmente | Installazione ThothII |
Come scegliere il livello giusto per un nuovo modello
- L'endpoint è un'API pubblica già nota a Pi? → abilita l'identificatore esatto in
deploy/pi/settings.json. - È OpenAI-compatible ma non built-in? → dichiaralo in
deploy/pi/models.json, poi abilitalo indeploy/pi/settings.json. - Richiede codice di trasporto specifico del provider? → non aggiungere un'estensione specifica; il provider non è supportato finché manca una capacità dichiarativa generica.
Ambito utente vs. progetto — riepilogo generale
Oltre ai modelli, Pi carica altre risorse da due alberi paralleli: ~/.pi/agent/ (utente) e <cwd>/.pi/ (progetto, risolto in base alla directory da cui viene lanciato pi).
| File/Directory | Livello utente | Livello progetto | Auto-discovery | Precedenza |
|---|---|---|---|---|
models.json |
~/.pi/agent/models.json |
non supportato | no | solo utente |
settings.json |
~/.pi/agent/settings.json |
./.pi/settings.json |
no | progetto sovrascrive utente |
extensions/ |
~/.pi/agent/extensions/ |
./.pi/extensions/ |
sì (.ts/.js) |
uniti (progetto + utente) |
prompts/ |
~/.pi/agent/prompts/ |
./.pi/prompts/ |
sì (.md) |
uniti |
themes/ |
~/.pi/agent/themes/ |
./.pi/themes/ |
sì (.json) |
progetto preferito |
skills/ |
~/.pi/agent/skills/ |
./.pi/skills/ |
sì (.md) |
uniti |
Esempio reale: ThothII
harness/.pi/
├── extensions/
│ ├── tht-gate.js ← gate human-in-the-loop
│ └── gate/
│ ├── core/ ← enforcement e utility condivise del gate
│ ├── disambiguation/ ← policy F1/F3
│ └── memory/ ← policy F2/F8
├── settings.json ← (opzionale) override delle impostazioni utente
└── themes/
└── thothii-mono.json ← tema del progetto
Comportamento rispetto alla cwd
La directory da cui lanci pi determina quali estensioni del workflow vengono trovate, ma non
quali modelli ThothII rende disponibili: il catalogo è montato nel Pi agent directory del container.
# Da harness/ — carica il gate di progetto e il catalogo locale montato
cd /path/to/ThothII/harness
pi --model local-qwen/qwen3.6-35b-a3b "..."
Il backend di ThothII lancia sempre Pi con cwd: harnessDir per il workflow; la disponibilità del
modello continua a dipendere soltanto da models.json, settings.json e dalle credenziali locali.
Trappola nell'auto-discovery: .mjs viene ignorato
Il pattern di auto-discovery delle estensioni in Pi è /\.(ts|js)$/ — non include .mjs.
.pi/extensions/
├── my-extension.js ✅ auto-caricata
├── my-extension.ts ✅ auto-caricata
├── my-extension.mjs ❌ ignorata silenziosamente (non combacia col pattern)
└── shared-module.mjs ✅ va bene per moduli helper (deliberatamente non caricato come estensione)
Se serve un modulo condiviso importato da un'estensione, usa .mjs proprio per evitare che venga trattato come estensione a sé.
Verifica
Elenco modelli
pi --list-models
Mostra i built-in e i modelli dichiarati in models.json.
Verifica il catalogo usato dall'applicazione
cd harness # o la cwd rilevante per il progetto
pi --mode rpc
# poi: {"type": "get_available_models", "id": "1"}
La risposta RPC deve includere soltanto modelli built-in o dichiarati nel catalogo locale.
Troubleshooting
| Problema | Causa | Soluzione |
|---|---|---|
Model "X/Y" not found |
Provider/modello assente da models.json oppure identificatore assente da enabledModels |
Correggi i due file locali e ricarica Pi |
| Impostazioni di progetto non applicate | settings.json di progetto ha errori di sintassi, o si sta lanciando pi dalla cwd sbagliata |
Valida il JSON, controlla la cwd |