Aller au contenu

Router l'IDE d'un développeur vers la passerelle

Un poste de développeur appelle aujourd’hui le fournisseur de modèles directement, et vous voulez que ses appels passent par la passerelle — pour les compter, les plafonner, et pour que la clé du fournisseur ne quitte jamais votre serveur. Cette page décrit la configuration du poste.

Le raisonnement derrière ce détour est ailleurs : Le rôle de la passerelle.

Un modèle de la configuration Lemniscate désigne la passerelle par son apiBase, et s’authentifie auprès d’elle avec la clé du compte du développeur.

Dans ~/.lemniscate/config.yaml :

models:
- name: Claude Sonnet (passerelle)
provider: anthropic
model: any
apiBase: http://passerelle.interne:6001/claude-sonnet/v1
apiKey: sk-lemniscate-<la-clé-du-développeur>
roles:
- chat

Champ par champ, parce que trois d’entre eux ne veulent pas dire ce qu’ils paraissent dire :

  • apiBase porte l’adresse de la passerelle et le nom de l’endpoint : http://<hôte>:<port>/<nom-de-l-endpoint>/v1. Le premier segment du chemin est ce qui désigne l’endpoint ; tout ce qui suit est relayé tel quel au fournisseur.
  • provider ne désigne plus le fournisseur joint, mais le dialecte que l’IDE doit parler — la forme des requêtes et des réponses. C’est l’endpoint, côté passerelle, qui décide du fournisseur réellement appelé.
  • model est ignoré. La passerelle réécrit le modèle du corps de la requête avec celui que l’endpoint désigne. Toute valeur convient ; en mettre une qui ressemble à un vrai nom de modèle induit en erreur le lecteur suivant.
  • apiKey est la clé du compte sur la passerelle, pas une clé du fournisseur. La passerelle retire l’en-tête d’authentification de l’appelant avant de relayer, et y substitue la clé du fournisseur, lue dans une variable d’environnement de son propre conteneur. La clé du fournisseur ne descend jamais sur le poste.
  • roles vaut chat, summarize, apply et edit quand il est absent. Nommez-les si vous voulez restreindre ce modèle à un usage.

Le port 6001 est le défaut d’écoute de la passerelle, redéfinissable par sa variable PORT.

Pour n’appliquer ce routage qu’à un projet plutôt qu’à tout le poste, le même bloc models se pose dans un fichier de .lemniscate/models/ à la racine du dépôt concerné.

La liste complète des clés acceptées par ce fichier est en référence.

C’est la faute la plus fréquente, et la passerelle la rend lisible : un endpoint inconnu reçoit un 404 dont le corps liste les endpoints qui existent.

{
"error": "Unknown endpoint: claude-sonet",
"available": ["claude-sonnet", "gpt-4o"]
}

Les autres refus à reconnaître au premier essai :

Réponse Ce qu’elle veut dire
401 clé absente ou inconnue de la passerelle
403 l’endpoint existe mais est désactivé, ou le compte n’a aucun plan
402 le compte a atteint le plafond mensuel de son plan
500 nommant une variable l’endpoint désigne une clé fournisseur absente de l’environnement de la passerelle

Les codes 402 et 403 se lèvent par des gestes différents : Plafonner la dépense d’un client. Un service qui ne répond pas du tout relève de La passerelle refuse de démarrer.

La passerelle accepte la clé sous Authorization: Bearer <clé> comme sous x-api-key: <clé> — c’est pourquoi les deux familles de dialectes s’authentifient sans réglage supplémentaire.

Deux moitiés du chemin, deux comportements opposés. C’est la source de confusion la plus coûteuse sur ce trajet.

Du poste à la passerelle, l’IDE sait traverser un proxy d’entreprise : la configuration accepte requestOptions avec proxy, noProxy, caBundlePath, clientCertificate et verifySsl, à la racine comme par modèle.

De la passerelle au fournisseur, rien de tel n’existe. L’appel sortant emploie le client HTTP natif de la plateforme : ni HTTP_PROXY, ni HTTPS_PROXY, ni NO_PROXY, ni autorité de certification interne (NODE_EXTRA_CA_CERTS), ni certificat client ne sont pris en compte. Derrière un pare-feu sortant, la passerelle ne joint aucun fournisseur, et aucun réglage ne l’y aide. C’est une limitation connue, sans contournement documenté : la passerelle doit être posée sur un hôte qui atteint le fournisseur directement.

À peser au moment de choisir sur quel réseau poser la passerelle, parce que rien dans le produit ne le compense.

La passerelle sert en HTTP clair. L’apiBase ci-dessus est en http://, et ce n’est pas une simplification d’exemple : le produit ne fournit ni ne documente de terminaison TLS. Entre le poste et la passerelle circulent, sans chiffrement, l’intégralité des prompts et la clé du développeur.

La destination sortante est une donnée, pas une constante. L’URL du fournisseur est lue dans une colonne libre de la base, sans liste blanche ni validation. Qui peut écrire dans la base peut faire sortir les prompts ailleurs, avec la clé du fournisseur injectée. La console qui écrit cette colonne est protégée par un unique jeu d’identifiants partagé, sans rôles ni trace de l’acteur.

La configuration accepte un fournisseur nommé lemniscate-proxy, traité à part dans le schéma, avec ses propres champs orgScopeId et onPremProxyUrl. Ce n’est pas le chemin décrit ici, et ce n’est pas la façon de joindre votre passerelle.

Son implémentation pointe par défaut sur un service hébergé par l’éditeur, dont rien dans le dépôt n’atteste l’existence ni l’exploitation ; l’inventaire des surfaces le classe pour cette raison en état indéterminé. Le mode onPremProxyUrl est, lui, autonome — mais aucun élément du dépôt ne permet aujourd’hui d’en écrire la procédure sans l’inventer. Elle sera écrite quand il y aura de quoi la fonder.

Sur les autres surfaces héritées qui parlent à ce même service non opéré : Ce qui n’existe pas.