Documentazione

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.

~/.pi/agent/models.json
{
  "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
        }
      ]
    }
  }
}
Mantieni /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.
Il valore predefinito di 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.
Dove Pi cerca la chiave e in quale ordine. La pagina dei modelli di Pi spiega che, se sono configurate più fonti, usa «prima un valore --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.
Questo blocco è stato ricavato dalla documentazione ufficiale di Pi nella data indicata qui sotto; ciò che quella documentazione ha smesso di specificare il 22 settembre — i nomi dei campi, i valori predefiniti dei modelli personalizzati e i valori 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.
Non hai ancora una chiave? Crea un account Kunavo, genera una chiave (inizia con 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

  1. Crea una chiave su /app/keys e copiala: viene mostrata una sola volta.
  2. Impostalo come variabile d'ambiente KUNAVO_API_KEY. Nel campo apiKey, 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.
  3. Crea o modifica ~/.pi/agent/models.json e incolla il blocco qui sopra. Un provider non integrato richiede baseUrl e un valore api a livello di provider o di modello: il codice sorgente di Pi rifiuta di caricare il modello senza questi valori; tutto il resto è facoltativo. Aprendo /model il file viene ricaricato.
  4. Avvia pi, esegui /model e 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.
  5. 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.

Questa è la versione breve. La guida completa, con scelta del modello, costo di una sessione reale e modalità di errore, è in quanto costa davvero eseguire Pi, per ogni route.

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 modelloKunavo ingresso / uscitaDove si inserisce in Pi
claude-sonnet-5$1.40 / $7.00il modello di lavoro predefinito per le sessioni che modificano file
claude-opus-5$3.50 / $17.50pianificare una modifica che sarebbe costosa se andasse male
claude-haiku-4-5$0.70 / $3.50turni economici: triage, riepiloghi, il ciclo che gira tutto il giorno
gpt-5-6-sol$2.00 / $12.00un secondo parere da un'altra famiglia, con la stessa chiave e lo stesso baseUrl
La fatturazione è per token, usando un saldo prepagato senza canone mensile: vedi billing. In presenza di contesto ripetuto, che costituisce la maggior parte di ciò che invia un editor o un client di chat, prompt caching incide sulla spesa più della scelta del modello.

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».

  1. compat.supportsEagerToolInputStreaming — per un backend che rifiuta lo streaming anticipato dell'input per ogni strumento.
  2. 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.
  3. 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.