Documentazione
Pi
Pi — l’agente di programmazione da terminale di Earendil, non il chatbot di Inflection né la criptovaluta — accetta un provider personalizzato come singolo blocco in models.json: un baseUrl, un api, una chiave e gli ID dei modelli da usare. Bastano quattro campi per collegarlo a Claude e GPT con un’unica chiave.
Un blocco provider personalizzato in ~/.pi/agent/models.json — baseUrl, api e gli ID dei modelli — porta l'agente di programmazione da terminale Pi di Earendil su Claude e GPT tramite una sola chiave.
{
"providers": {
"kunavo": {
"baseUrl": "https://api.kunavo.com/v1",
"api": "openai-completions",
"apiKey": "$KUNAVO_API_KEY",
"models": [
{
"id": "claude-sonnet-5",
"name": "Claude Sonnet 5",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 1000000,
"maxTokens": 128000
},
{
"id": "claude-haiku-4-5",
"name": "Claude Haiku 4.5",
"input": ["text", "image"],
"contextWindow": 200000,
"maxTokens": 64000
}
]
}
}
}/v1 in un provider openai-completions. L’esempio di endpoint compatibile nella pagina dei modelli di Pi abbina quel valore a http://localhost:11434/v1 e, prima della riscrittura della documentazione il 22 settembre, anche gli esempi per OpenRouter, Vercel AI Gateway e llama.cpp riportavano lo stesso percorso di versione. Nessuna frase enuncia esplicitamente la regola, quindi sono gli esempi a chiarirla. Se l’URL di base non ha il suffisso, si ottiene 404, non un errore di autenticazione.cost per un modello personalizzato è tutto zero: è impostato così nel codice sorgente di Pi (v0.99.2), ma la documentazione non lo specifica più. Di conseguenza, il provider appena aggiunto mostra $0 nel piè di pagina e in /session, finché non inserisci manualmente le tariffe. I due valori predefiniti nascosti sottostanti hanno un impatto maggiore: contextWindow assume il valore 128000 e maxTokens il valore 16384, quindi un modello lasciato senza valori viene compattato e troncato ben al di sotto della sua capacità effettiva. Il blocco qui sopra imposta entrambi in base al catalogo; fai lo stesso per ogni ID aggiunto dalla tabella qui sotto.--api-key di runtime, poi una credenziale auth.json salvata, un apiKey da models.json e infine le variabili d’ambiente del provider». Una chiave obsoleta salvata da /login ha quindi la precedenza su quella nel tuo file; è il motivo più comune per cui un blocco appena modificato continua ad autenticarsi con un’altra chiave. La stessa pagina aggiunge che i modelli personalizzati «possono essere caricati da models.json, ma restano non disponibili in /model finché Pi non riesce a risolvere le credenziali». Se un modello non compare nel selettore, si tratta di un problema con le credenziali, non di sintassi.api — è stato ricavato lo stesso giorno dal codice sorgente di Pi alla versione v0.99.2. Kunavo non ha eseguito Pi sul proprio endpoint: né una sessione, né un turno in streaming, né un ciclo completo di chiamata agli strumenti, né una verifica del modello a cui è stata indirizzata una richiesta. Una pagina di configurazione pubblicata è un riferimento per la configurazione, non un test di compatibilità: non va interpretata come tale. La parte che segue, curl, è quella che puoi verificare in dieci secondi; il comportamento del client è una questione tra te e Pi.sk-kn-) e aggiungi credito da $10: le chiamate vengono pagate con quel saldo e le chiamate non riuscite non vengono addebitate. La dashboard si apre quindi sulla configurazione Pi.Passo dopo passo
- Crea una chiave su
/app/keyse copiala: viene mostrata una sola volta. - Impostalo come variabile d'ambiente
KUNAVO_API_KEY. Nel campoapiKey, Pi risolve"$NAME"o"${NAME}", oltre ad accettare un valore letterale o un prefisso!command. Usa la forma con parentesi graffe quando dopo il nome della variabile c'è del testo letterale. - Crea o modifica
~/.pi/agent/models.jsone incolla il blocco qui sopra. Un provider non integrato richiedebaseUrle un valoreapia livello di provider o di modello: il codice sorgente di Pi rifiuta di caricare il modello senza questi valori; tutto il resto è facoltativo. Aprendo/modelil file viene ricaricato. - Avvia
pi, esegui/modele scegli uno degli ID che hai dichiarato. Se non compaiono nell'elenco, controlla la chiave prima di intervenire sul JSON: consulta la nota sull'ordine di risoluzione qui sopra. - Assegnagli un'attività che legga e modifichi un file reale. Pi si affida quasi sempre alle chiamate agli strumenti, quindi una prima esecuzione che interagisce con il filesystem ti dirà molto più di un saluto e farà emergere eventuali incompatibilità nello streaming o nello schema degli strumenti: è proprio questa la categoria che Kunavo non ha testato per te.
Verificato rispetto a La documentazione di Pi: Choose a Model il 1 ottobre 2026. Le impostazioni di terze parti cambiano; se il nome di un campo qui non corrisponde più a quello visualizzato, fa fede quella pagina, non questa.
Verifica prima di eseguire il debug del client
Una sola richiesta stabilisce se il problema riguarda l'endpoint, la chiave o il file di configurazione. Se restituisce JSON, lo stesso base URL e la stessa chiave funzionano in Pi.
# Settles whether a failure is the endpoint, the key, or the client.
curl -sS https://api.kunavo.com/v1/models \
-H "Authorization: Bearer sk-kn-..."Quale model id inserire nel campo
Ogni modello di testo è raggiungibile come model id: l'elenco aggiornato è GET /v1/models e il catalogo con i prezzi è nella pagina dei modelli. Le tariffe sono in USD per 1M di token, input / output.
| ID del modello | Kunavo ingresso / uscita | Dove si inserisce in Pi |
|---|---|---|
claude-sonnet-5 | $1.40 / $7.00 | il modello di lavoro predefinito per le sessioni che modificano file |
claude-opus-5 | $3.50 / $17.50 | pianificare una modifica che sarebbe costosa se andasse male |
claude-haiku-4-5 | $0.70 / $3.50 | turni economici: triage, riepiloghi, il ciclo che gira tutto il giorno |
gpt-5-6-sol | $2.00 / $12.00 | un secondo parere da un'altra famiglia, con la stessa chiave e lo stesso baseUrl |
L’altra opzione: anthropic-messages
Fino all'aggiornamento della documentazione del 22 settembre 2026, Pi documentava quattro valori per api di un provider personalizzato: openai-completions, openai-responses, anthropic-messages e google-generative-ai. La pagina aggiornata sui modelli non ne elenca nessuno: mostra openai-completions in un esempio e descrive il caso come «Un endpoint compatibile con OpenAI, Anthropic o Google». Nel codice sorgente di Pi alla versione v0.99.2 il campo è tipizzato come stringa libera e viene inoltrato a una delle dieci implementazioni integrate corrispondenti: le quattro precedenti, più openai-codex-responses, azure-openai-responses, google-vertex, mistral-conversations, bedrock-converse-stream e pi-messages. Solo i primi quattro sono mai stati documentati per un provider personalizzato; nessuno degli altri sei è stato testato qui e questa pagina non afferma che funzionino con endpoint di terze parti.
anthropic-messages è uno dei quattro valori documentati e Kunavo risponde sia all'interfaccia Anthropic Messages sia a quella compatibile con OpenAI. Quindi è possibile configurare questa route. Questa pagina non inserisce però nel blocco da incollare un URL di base per tale route: la documentazione di Pi non ha mai definito quel campo in modo univoco per questa api. Fino al 22 settembre veniva mostrato in due modi: https://proxy.example.com/v1 in un esempio e https://proxy.example.com senza parentesi in un altro. L'aggiornamento della documentazione di quel giorno ha rimosso entrambe le forme senza sceglierne una. Se scegli questa route, prova una delle due; se la prima chiamata restituisce 404 invece di 401, è quella la riga da modificare.
Nello schema compat di Pi ci sono tre campi per questa api che è utile conoscere prima di arrivarci (codice sorgente, v0.99.2). Prima, però, è bene citare la regola della documentazione che li riguarda tutti: le impostazioni di compatibilità «devono descrivere differenze verificate nel comportamento di richiesta o risposta dell'endpoint. Non abilitarle basandosi soltanto sul fatto che un endpoint dichiari la compatibilità con OpenAI o Anthropic».
compat.supportsEagerToolInputStreaming— per un backend che rifiuta lo streaming anticipato dell'input per ogni strumento.compat.supportsStrictTools— indica se l'endpoint accetta definizioni degli strumenti con schema JSON rigoroso; un modello personalizzato non eredita l'impostazione dichiarata da un modello Anthropic integrato.compat.supportsMidConvoEffort— modifica il livello di ragionamento nel corso della conversazione. Stabilire se questo endpoint è idoneo è una questione da verificare in esecuzione, e Kunavo non l'ha fatto eseguendo alcuna prova.
Il blocco openai-completions in cima a questa pagina non usa nessuna delle tre impostazioni: è questo il motivo concreto per cui conviene partire da lì, non la pretesa che funzioni meglio.
Domande frequenti
Come posso indirizzare l'agente di coding Pi a un provider API personalizzato?
Aggiungi un blocco provider a ~/.pi/agent/models.json. La pagina dei modelli di Pi consiglia di usare models.json «quando un endpoint espone un'API già supportata da Pi» e lo schema (codice sorgente, v0.99.2) accetta baseUrl, apiKey, api, headers, authHeader, models e modelOverrides a livello di provider. Un provider non integrato richiede baseUrl e un valore api a livello di provider o di modello. Lo schema definisce api come stringa libera, non come elenco: fino all'aggiornamento della documentazione del 22 settembre 2026, Pi documentava quattro valori per un provider personalizzato — openai-completions, openai-responses, anthropic-messages e google-generative-ai — e il codice sorgente alla versione v0.99.2 inoltra il campo a una qualsiasi delle dieci implementazioni integrate; gli altri sei non sono mai stati documentati per questo uso e qui non sono stati testati. Per un endpoint compatibile con OpenAI, il valore che la documentazione aggiornata continua a mostrare è openai-completions. Ogni voce in models deve includere almeno un id, che viene passato direttamente all'endpoint: la stessa struttura è quindi adatta a un gateway, a un server Ollama o vLLM locale e a qualsiasi altro host compatibile.
Da dove prende la chiave API l'agente di coding Pi?
Da una di quattro fonti, nell'ordine indicato nella pagina dei modelli di Pi: prima un valore --api-key passato in esecuzione, poi una credenziale salvata in auth.json, quindi un apiKey da models.json e infine le variabili d'ambiente del provider. Una chiave salvata in precedenza con /login ha quindi la precedenza su quella appena inserita in models.json. Il campo apiKey accetta l'interpolazione di variabili d'ambiente — "$NAME" o "${NAME}" — un valore letterale oppure l'output di un comando shell preceduto da "!", quindi non è necessario conservare il segreto nel file. Se non sono disponibili credenziali valide, la documentazione indica che i modelli personalizzati vengono caricati da models.json, ma restano indisponibili in /model.
Il baseUrl di Pi deve terminare con /v1?
Per un provider openai-completions, sì. La documentazione di Pi non enuncia mai la regola in una frase, ma l'esempio di endpoint compatibile usa http://localhost:11434/v1 per Ollama e, prima dell'aggiornamento del 22 settembre 2026, gli esempi di OpenRouter, Vercel AI Gateway e llama.cpp riportavano lo stesso percorso di versione. Per un endpoint compatibile con OpenAI, quindi, il valore è la radice /v1, per esempio https://api.kunavo.com/v1. Il caso anthropic-messages resta davvero irrisolto: la vecchia documentazione lo mostrava sia con /v1 sia senza, e l'aggiornamento ha rimosso entrambi gli esempi senza scegliere.
Perché il mio provider personalizzato di Pi mostra $0 nel piè di pagina?
Perché Pi imposta per impostazione predefinita a zero tutte le voci dell'oggetto costi di un modello personalizzato (codice sorgente, v0.99.2) e il piè di pagina mostra i dati del catalogo, non il costo applicato dall'endpoint. Nulla è gratuito: quel numero non ha una fonte finché non inserisci le tariffe per milione di token di input, output, cacheRead e cacheWrite, oltre alle eventuali fasce, prendendole dal listino prezzi del tuo provider. Mentre modifichi il file, fai attenzione anche ai due valori predefiniti adiacenti: contextWindow è impostato su 128000 e maxTokens su 16384. Di conseguenza, un modello con una finestra più ampia viene compattato in anticipo e le sue risposte vengono troncate, a meno che entrambi i valori non siano impostati esplicitamente.
Kunavo ha testato l'agente di coding Pi?
No. La configurazione in questa pagina è stata ricavata dalla documentazione ufficiale di Pi e, per i dettagli rimossi nell'aggiornamento del 22 settembre, dal codice sorgente rilasciato da Pi, nella data indicata. Tuttavia, non è stata eseguita su questo endpoint alcuna sessione, turno in streaming, ciclo completo di chiamata agli strumenti o verifica dell'instradamento del modello con questo client; lo stesso vale per tutti i client di questa sezione. Considera il blocco di configurazione un riferimento ai valori accettati dallo schema di Pi, verifica l'endpoint e la chiave con il comando curl qui sopra e tieni disponibile una route funzionante mentre provi quella nuova.