Documentation

Documentation

Pi

Pi — l’agent de programmation en terminal d’Earendil, et non le chatbot d’Inflection ou la cryptomonnaie — accepte un fournisseur personnalisé sous la forme d’un bloc dans models.json : baseUrl, api, key et les identifiants des modèles souhaités. Quatre champs suffisent pour communiquer avec Claude et GPT à l’aide d’une seule clé.

Un bloc fournisseur personnalisé dans ~/.pi/agent/models.json — baseUrl, api et identifiants des modèles — place l’agent de codage terminal Pi d’Earendil sur Claude et GPT avec une seule clé.

~/.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
        }
      ]
    }
  }
}
Conservez le /v1 pour un fournisseur openai-completions. L’exemple d’endpoint compatible sur la page des modèles de Pi associe cette valeur à http://localhost:11434/v1, et, avant la réécriture de la documentation le 22 septembre, ses exemples OpenRouter, Vercel AI Gateway et llama.cpp utilisaient le même chemin de version. Aucune phrase n’énonce explicitement la règle : ce sont donc les exemples qui permettent de trancher. Une URL de base sans le suffixe renvoie une 404, et non une erreur d’authentification.
Le cost d’un modèle personnalisé est nul par défaut — cette valeur par défaut figure dans le code source de Pi (v0.99.2), mais la documentation ne la précise plus. Le fournisseur que vous venez d’ajouter affiche donc $0 dans le pied de page et dans /session jusqu’à ce que vous saisissiez les tarifs vous-même. Les deux valeurs par défaut silencieuses qui suivent sont plus problématiques : contextWindow est remplacé par 128000, et maxTokens par 16384. Un modèle laissé sans ces valeurs sera donc compacté et tronqué bien en deçà de sa capacité réelle. Le bloc ci-dessus définit les deux à partir du catalogue ; faites de même pour tout identifiant ajouté depuis le tableau ci-dessous.
Voici dans quel ordre Pi cherche la clé. La page des modèles de Pi indique que, lorsque plusieurs sources sont configurées, le client utilise « d’abord un --api-key à l’exécution, puis un identifiant d’accès auth.json enregistré, un apiKey provenant de models.json, et enfin les variables d’environnement du fournisseur ». Une clé obsolète enregistrée par /login l’emporte donc sur celle de votre fichier, ce qui explique généralement pourquoi un bloc fraîchement modifié s’authentifie encore avec une autre clé. La même page ajoute que les modèles personnalisés « peuvent être chargés depuis models.json, mais restent indisponibles dans /model tant que Pi ne peut pas résoudre les identifiants d’accès ». Si un modèle n’apparaît pas dans le sélecteur, le problème vient des identifiants d’accès, et non de la syntaxe.
Ce bloc a été établi à partir de la documentation propre à Pi à la date indiquée ci-dessous. Pour ce que cette documentation a cessé de préciser le 22 septembre — les noms de champs, les valeurs par défaut des modèles personnalisés et les valeurs api — il a été établi à partir du code source de Pi en v0.99.2, le même jour. Kunavo n’a pas exécuté Pi avec son point de terminaison : ni session, ni tour en streaming, ni aller-retour avec un outil, ni vérification du modèle effectivement utilisé pour une requête. Une page de configuration publiée est une référence de configuration, pas un test de compatibilité ; rien ici ne doit être interprété comme tel. Le curl ci-dessous est la partie que vous pouvez régler en dix secondes ; le comportement du client dépend de vous et de Pi.
Pas encore de clé ? Créez un compte Kunavo, créez une clé (elle commence par sk-kn-) et ajoutez un crédit à partir de 10 $ — les appels sont payés sur ce solde et les appels échoués ne sont pas facturés. Le tableau de bord s’ouvre ensuite sur la configuration Pi.

Étape par étape

  1. Créez une clé sur /app/keys et copiez-la — elle n’est affichée qu’une seule fois.
  2. Définissez-la dans l’environnement sous la forme KUNAVO_API_KEY. Pi résout "$NAME" ou "${NAME}" dans le champ apiKey, ainsi qu’une valeur littérale ou une commande commençant par !command. Utilisez la forme entre accolades lorsqu’un texte littéral suit le nom de la variable.
  3. Créez ou modifiez ~/.pi/agent/models.json et collez-y le bloc ci-dessus. Un fournisseur qui n’est pas intégré doit avoir baseUrl et une valeur api au niveau du fournisseur ou du modèle — le code source de Pi refuse de charger le modèle sans ces éléments — et tout le reste est facultatif. L’ouverture de /model recharge le fichier.
  4. Lancez pi, exécutez /model et choisissez l’un des identifiants que vous avez déclarés. S’ils ne figurent pas dans la liste, vérifiez la clé avant le JSON — consultez la remarque ci-dessus sur l’ordre de résolution.
  5. Donnez-lui une tâche qui lit et modifie un vrai fichier. Pi s’appuie sur les appels d’outils pour presque tout ce qu’il fait ; un premier essai qui touche au système de fichiers vous en apprend donc bien plus qu’une salutation. C’est aussi lors de cet essai qu’apparaîtrait une incompatibilité de streaming ou de schéma d’outil, précisément le type de problème que Kunavo n’a pas testé pour vous.

Vérifié avec Documentation de Pi : choisir un modèle le 1 octobre 2026. Les paramètres tiers évoluent ; si le nom d’un champ ne correspond plus à ce que vous voyez ici, cette page fait autorité, pas celle-ci.

Voici la version courte. Le guide complet — choix du modèle, coût d’une session réelle et modes d’échec — se trouve dans ce que coûte réellement l’exécution de Pi, selon la route.

Vérifiez avant de déboguer le client

Une requête suffit à déterminer si l’échec vient de l’endpoint, de la clé ou du fichier de configuration. Si cette requête renvoie du JSON, la même URL de base et la même clé fonctionnent dans 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-..."

Quel identifiant de modèle saisir dans le champ

Tous les modèles textuels sont accessibles sous forme d’identifiant de modèle — la liste à jour se trouve sur GET /v1/models, et le catalogue avec les prix sur la page des modèles. Les tarifs sont en USD par million de tokens, entrée / sortie.

Identifiant du modèleEntrée / sortie sur KunavoOù cela s’intègre dans Pi
claude-sonnet-5$1.40 / $7.00le modèle de travail par défaut pour les sessions qui modifient des fichiers
claude-opus-5$3.50 / $17.50planifier une modification dont une erreur coûterait cher
claude-haiku-4-5$0.70 / $3.50requêtes économiques — triage, résumés, boucle qui tourne toute la journée
gpt-5-6-sol$2.00 / $12.00un deuxième avis d’une autre famille, avec la même clé et le même baseUrl
La facturation se fait au token à partir d’un solde prépayé, sans frais mensuels — consultez la facturation. Avec un contexte répété — ce qu’envoient la plupart des éditeurs et clients de chat — la mise en cache des prompts influe davantage sur la facture que le choix du modèle.

L’autre option : anthropic-messages

Jusqu’à la mise à jour de sa documentation du 22 septembre 2026, Pi documentait quatre valeurs pour le champ api d’un fournisseur personnalisé : openai-completions, openai-responses, anthropic-messages et google-generative-ai. La page actualisée sur les modèles n’en répertorie aucune : elle affiche openai-completions dans un exemple et décrit le cas comme « un point de terminaison compatible avec OpenAI, Anthropic ou Google ». Le code source de Pi en v0.99.2 définit ce champ comme une chaîne libre et l’envoie à l’une des dix implémentations intégrées correspondantes : les quatre précédentes, plus openai-codex-responses, azure-openai-responses, google-vertex, mistral-conversations, bedrock-converse-stream et pi-messages. Seules les quatre premières ont jamais été documentées pour un fournisseur personnalisé, et aucune des six autres n’a été testée ici ; rien sur cette page n’affirme qu’elles fonctionnent avec un point de terminaison tiers.

anthropic-messages fait partie des quatre valeurs documentées, et Kunavo prend en charge l’interface Anthropic Messages ainsi que l’interface compatible avec OpenAI. Cette route peut donc être configurée. Cette page n’inscrira toutefois pas de base URL dans un bloc prêt à coller : la documentation de Pi n’a jamais établi cette valeur pour cette api. Jusqu’au 22 septembre, elle la présentait de deux manières — https://proxy.example.com/v1 dans un exemple, https://proxy.example.com sans préfixe dans un autre — puis la mise à jour a supprimé les deux sans trancher. Si vous choisissez cette route, faites un essai ; si le premier appel renvoie 404 plutôt que 401, c’est cette ligne qu’il faut modifier.

Trois champs du schéma compat de Pi pour cette api méritent d’être connus avant d’y arriver (source, v0.99.2). La seule règle de la documentation qui s’applique aux trois mérite d’être citée d’abord : les paramètres de compatibilité « doivent décrire des différences vérifiées dans le comportement des requêtes ou des réponses du point de terminaison. Ne les activez pas uniquement parce qu’un point de terminaison annonce une compatibilité avec OpenAI ou Anthropic ».

  1. compat.supportsEagerToolInputStreaming — pour un backend qui refuse le streaming anticipé des entrées par outil.
  2. compat.supportsStrictTools — indique si le point de terminaison accepte les définitions d’outils au format JSON Schema strict ; un modèle personnalisé n’hérite pas de ce qu’un modèle Anthropic intégré déclare.
  3. compat.supportsMidConvoEffort — modification du niveau d’effort de raisonnement en cours de conversation. La prise en charge par ce point de terminaison est une question d’exécution ; Kunavo ne l’a pas vérifiée en lançant quoi que ce soit.

Le bloc openai-completions en haut de cette page évite ces trois paramètres ; c’est pour cette raison, en toute transparence, qu’il vaut mieux commencer par là — et non parce qu’il serait prétendument plus performant.

Questions fréquentes

Comment configurer le fournisseur d’API personnalisé de l’agent de codage Pi ?

Ajoutez un bloc de fournisseur à ~/.pi/agent/models.json. La page des modèles de Pi indique d’utiliser models.json « lorsqu’un point de terminaison parle déjà une API prise en charge par Pi », et son schéma (source, v0.99.2) accepte au niveau du fournisseur baseUrl, apiKey, api, headers, authHeader, models et modelOverrides. Un fournisseur qui n’est pas intégré doit avoir baseUrl et une valeur api au niveau du fournisseur ou du modèle. Le schéma définit api comme une chaîne libre, et non comme une liste : jusqu’à la mise à jour de sa documentation du 22 septembre 2026, Pi documentait quatre valeurs pour un fournisseur personnalisé — openai-completions, openai-responses, anthropic-messages et google-generative-ai — et son code source en v0.99.2 transmet le champ à l’une de dix implémentations intégrées ; les six autres n’ont jamais été documentées pour cet usage et n’ont pas été testées ici. Pour un point de terminaison compatible avec OpenAI, openai-completions est la valeur que la documentation actualisée affiche encore. Chaque entrée de models doit comporter au minimum un id, transmis tel quel au point de terminaison ; la même structure convient donc à une passerelle, à un serveur Ollama ou vLLM local, ainsi qu’à tout autre hôte compatible.

Où l’agent de codage Pi récupère-t-il sa clé API ?

À l’un de quatre emplacements, selon l’ordre publié sur la page des modèles de Pi : d’abord un argument d’exécution --api-key, puis un identifiant enregistré dans auth.json, ensuite un apiKey défini dans models.json et enfin les variables d’environnement du fournisseur. Une clé enregistrée auparavant avec /login a donc priorité sur celle que vous venez de modifier dans models.json. Le champ apiKey accepte l’interpolation de variables d’environnement (« $NAME » ou « ${NAME} »), une valeur littérale ou la sortie d’une commande shell précédée de « ! » ; le secret n’a donc pas besoin de figurer dans le fichier. Sans identifiants utilisables, la documentation indique que les modèles personnalisés sont chargés depuis models.json, mais restent indisponibles dans /model.

Le baseUrl de Pi doit-il se terminer par /v1 ?

Pour un fournisseur openai-completions, oui. La documentation de Pi n’énonce jamais cette règle dans une phrase, mais son exemple de point de terminaison compatible utilise http://localhost:11434/v1 pour Ollama ; avant la mise à jour du 22 septembre 2026, ses exemples pour OpenRouter, Vercel AI Gateway et llama.cpp comportaient le même chemin de version. La valeur à utiliser pour un point de terminaison compatible avec OpenAI est donc la racine /v1, par exemple https://api.kunavo.com/v1. Le cas anthropic-messages reste réellement indéterminé : l’ancienne documentation le présentait avec et sans /v1, et la mise à jour a supprimé les deux exemples sans trancher.

Pourquoi mon fournisseur personnalisé Pi affiche-t-il 0 $ dans le pied de page ?

Parce que Pi attribue par défaut un coût nul à tous les postes de coût d’un modèle personnalisé (source, v0.99.2), et que le pied de page affiche les valeurs du catalogue, pas les frais facturés par le point de terminaison. Rien n’est gratuit ; ce chiffre n’a simplement aucune source tant que vous n’avez pas renseigné les tarifs par million de jetons en entrée et en sortie, ainsi que ceux de cacheRead et cacheWrite, y compris les éventuels paliers, à partir de la grille tarifaire de votre fournisseur. Deux valeurs par défaut voisines méritent la même attention pendant que vous êtes dans le fichier : contextWindow est défini par défaut sur 128000 et maxTokens sur 16384. Un modèle disposant d’une fenêtre plus grande sera donc compacté prématurément et ses réponses écourtées, sauf si vous définissez explicitement ces deux valeurs.

Kunavo a-t-il testé l’agent de codage Pi ?

Non. La configuration de cette page a été tirée de la documentation propre à Pi et, lorsque la mise à jour du 22 septembre a supprimé un détail, du code source publié par Pi, à la date indiquée. Toutefois, aucune session, aucun tour en streaming, aucun aller-retour avec un outil ni aucune vérification du routage des modèles n’a été effectué avec ce client et ce point de terminaison — et il en va de même pour tous les clients de cette section. Considérez le bloc de configuration comme une référence indiquant ce qu’accepte le schéma de Pi, vérifiez le point de terminaison et la clé avec la commande curl ci-dessus, et gardez une route fonctionnelle à disposition pendant vos essais.