API compatible OpenAI : Stratégies de déploiement pour /v1/chat/completions et /v1/responses
Vous utiliserez cette API compatible OpenAI pour connecter directement les SDK/clients OpenAI existants à la passerelle locale des outils Antigravity. L'objectif principal est de faire fonctionner /v1/chat/completions et /v1/responses, et d'apprendre à résoudre les problèmes rapidement grâce aux en-têtes de réponse.
Ce que vous pourrez faire après ce cours
- Connecter le SDK OpenAI (ou curl) directement à la passerelle locale des outils Antigravity
- Faire fonctionner
/v1/chat/completions(avecstream: true) et/v1/responses - Comprendre la liste des modèles de
/v1/modelset l'en-tête de réponseX-Mapped-Model - Savoir quoi vérifier en priorité en cas d'erreurs 401/404/429
Votre situation actuelle
De nombreux clients/SDK ne reconnaissent que la forme des interfaces OpenAI : des URL fixes, des champs JSON fixes et un format de flux SSE fixe. L'objectif des outils Antigravity n'est pas de vous faire modifier vos clients, mais de faire croire aux clients qu'ils communiquent avec OpenAI, tout en convertissant les requêtes en appels en amont internes, puis en reconvertissant les résultats au format OpenAI.
Quand utiliser cette approche
- Vous disposez déjà d'un ensemble d'outils ne supportant que OpenAI (plugins IDE, scripts, bots, SDK) et vous ne souhaitez pas écrire une nouvelle intégration pour chacun
- Vous souhaitez utiliser un
base_urlunique pour diriger les requêtes vers une passerelle locale (ou réseau local), la passerelle gérant ensuite la planification des comptes, les nouvelles tentatives et la surveillance
🎒 Préparatifs avant de commencer
Conditions préalables
- Vous avez déjà démarré le service de proxy inverse dans la page "API Proxy" d'Antigravity Tools et avez noté le port (par exemple
8045) - Vous avez ajouté au moins un compte disponible, sinon le proxy ne peut pas obtenir de jeton en amont
Comment transmettre l'authentification ?
Lorsque vous activez proxy.auth_mode et configurez proxy.api_key, la requête doit inclure une API Key.
Le middleware des outils Antigravity lit d'abord Authorization, et est également compatible avec x-api-key et x-goog-api-key. (Implémentation dans src-tauri/src/proxy/middleware/auth.rs)
Qu'est-ce que l'API compatible OpenAI ?
L'API compatible OpenAI est un ensemble de routes HTTP et de protocoles JSON/SSE qui "ressemblent à OpenAI". Les clients envoient des requêtes au format OpenAI vers la passerelle locale, qui convertit ensuite les requêtes en appels en amont internes et reconvertit les réponses en amont au format de réponse OpenAI, permettant aux SDK OpenAI existants de fonctionner sans modification majeure.
Aperçu des points de terminaison compatibles (liés à ce cours)
| Point de terminaison | Utilisation | Preuve dans le code |
|---|---|---|
POST /v1/chat/completions | Chat Completions (avec flux) | Enregistrement de route dans src-tauri/src/proxy/server.rs ; src-tauri/src/proxy/handlers/openai.rs |
POST /v1/completions | Completions héritées (réutilisation du même gestionnaire) | Enregistrement de route dans src-tauri/src/proxy/server.rs |
POST /v1/responses | Compatibilité Responses/Codex CLI (réutilisation du même gestionnaire) | Enregistrement de route dans src-tauri/src/proxy/server.rs (commentaire : compatibilité Codex CLI) |
GET /v1/models | Retourne la liste des modèles (avec mappage personnalisé + génération dynamique) | src-tauri/src/proxy/handlers/openai.rs + src-tauri/src/proxy/common/model_mapping.rs |
Suivez les étapes
Étape 1 : Vérifiez que le service fonctionne avec curl (/healthz + /v1/models)
Pourquoi Éliminez d'abord les problèmes élémentaires comme "service non démarré/port incorrect/bloqué par le pare-feu".
# 1) Vérification de santé
curl -s http://127.0.0.1:8045/healthz
# 2) Récupération de la liste des modèles
curl -s http://127.0.0.1:8045/v1/modelsCe que vous devriez voir : /healthz retourne quelque chose comme {"status":"ok"} ; /v1/models retourne {"object":"list","data":[...]}.
Étape 2 : Appelez /v1/chat/completions avec le SDK OpenAI Python
Pourquoi Cette étape prouve que toute la chaîne "SDK OpenAI → passerelle locale → en amont → conversion de réponse OpenAI" fonctionne.
import openai
client = openai.OpenAI(
api_key="sk-antigravity",
base_url="http://127.0.0.1:8045/v1",
)
response = client.chat.completions.create(
model="gemini-3-flash",
messages=[{"role": "user", "content": "Bonjour, présentez-vous"}],
)
print(response.choices[0].message.content)Ce que vous devriez voir : Le terminal affiche un texte de réponse du modèle.
Étape 3 : Activez le flux pour confirmer le retour SSE
Pourquoi De nombreux clients dépendent du protocole SSE d'OpenAI (Content-Type: text/event-stream). Cette étape confirme que le flux et le format des événements sont disponibles.
curl -N http://127.0.0.1:8045/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3-flash",
"stream": true,
"messages": [
{"role": "user", "content": "Expliquez en trois phrases ce qu'est un proxy inverse local"}
]
}'Ce que vous devriez voir : Le terminal affiche en continu des lignes commençant par data: { ... }, se terminant par data: [DONE].
Étape 4 : Utilisez /v1/responses (style Codex/Responses) pour une requête
Pourquoi Certains outils utilisent /v1/responses ou des champs comme instructions et input dans le corps de la requête. Ce projet "normalise" ce type de requête en messages puis réutilise la même logique de conversion. (Gestionnaire dans src-tauri/src/proxy/handlers/openai.rs)
curl -s http://127.0.0.1:8045/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3-flash",
"instructions": "Vous êtes un réviseur de code rigoureux.",
"input": "Indiquez le bug le plus probable dans le code suivant :\n\nfunction add(a, b) { return a - b }"
}'Ce que vous devriez voir : Le corps de la réponse est un objet au format OpenAI (ce projet convertira la réponse Gemini en choices[].message.content d'OpenAI).
Étape 5 : Vérifiez que le routage des modèles fonctionne (voir l'en-tête X-Mapped-Model)
Pourquoi Le model que vous écrivez dans le client n'est pas nécessairement le "modèle physique" réellement appelé. La passerelle effectue d'abord un mappage de modèles (incluant le mappage personnalisé/les caractères génériques, voir Routage des modèles : mappage personnalisé, priorité des caractères génériques et stratégies prédéfinies), puis place le résultat final dans l'en-tête de réponse pour faciliter le dépannage.
curl -i http://127.0.0.1:8045/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "salut"}]
}'Ce que vous devriez voir : L'en-tête de réponse contient X-Mapped-Model: ... (par exemple mappé vers gemini-2.5-flash), et peut également contenir X-Account-Email: ....
Point de contrôle ✅
GET /healthzretourne{"status":"ok"}(ou JSON équivalent)GET /v1/modelsretourneobject=listetdataest un tableau- La requête non flux
/v1/chat/completionspeut obtenirchoices[0].message.content - Avec
stream: true, vous recevez SSE, se terminant par[DONE] curl -ipeut voir l'en-tête de réponseX-Mapped-Model
Pièges à éviter
1) Base URL incorrect entraîne 404 (le plus courant)
- Dans les exemples du SDK OpenAI,
base_urldoit se terminer par/v1(voir l'exemple Python du README du projet). - Certains clients "empilent les chemins". Par exemple, le README mentionne explicitement : Kilo Code en mode OpenAI peut construire des chemins non standards comme
/v1/chat/completions/responses, déclenchant ainsi une erreur 404.
2) 401 : ce n'est pas que l'en amont est en panne, c'est que vous n'avez pas fourni de clé ou que le mode est incorrect
Lorsque le "mode valide" de la stratégie d'authentification n'est pas off, le middleware vérifie les en-têtes de requête : Authorization: Bearer <proxy.api_key>, et est également compatible avec x-api-key et x-goog-api-key. (Implémentation dans src-tauri/src/proxy/middleware/auth.rs)
Indication sur le mode d'authentification
Avec auth_mode = auto, la décision est automatique selon allow_lan_access :
allow_lan_access = true→ mode valide =all_except_health(authentification requise sauf pour/healthz)allow_lan_access = false→ mode valide =off(pas d'authentification pour l'accès local)
3) 429/503/529 : le proxy fait des nouvelles tentatives + rotation de comptes, mais le "pool peut être épuisé"
Le gestionnaire OpenAI intègre jusqu'à 3 tentatives (et est limité par la taille du pool de comptes), en cas de certaines erreurs il attend/rotate les comptes pour réessayer. (Implémentation dans src-tauri/src/proxy/handlers/openai.rs)
Résumé du cours
/v1/chat/completionsest le point d'intégration le plus universel,stream: trueutilise SSE/v1/responseset/v1/completionsutilisent le même gestionnaire de compatibilité, la clé est de normaliser d'abord la requête enmessagesX-Mapped-Modelvous aide à confirmer le résultat du mappage "nom du modèle client → modèle physique final"
Prochain cours
Dans le prochain cours, nous continuerons avec API compatible Anthropic : /v1/messages et les contrats clés de Claude Code (chapitre correspondant :
platforms-anthropic).
Annexe : Références du code source
Cliquez pour voir les emplacements du code source
Dernière mise à jour : 2026-01-23
| Fonctionnalité | Chemin du fichier | Lignes |
|---|---|---|
| Enregistrement des routes OpenAI (incluant /v1/responses) | src-tauri/src/proxy/server.rs | 120-194 |
| Gestionnaire Chat Completions (incluant la détection du format Responses) | src-tauri/src/proxy/handlers/openai.rs | 70-462 |
| Gestionnaire /v1/completions et /v1/responses (normalisation Codex/Responses + nouvelles tentatives/rotation) | src-tauri/src/proxy/handlers/openai.rs | 464-1080 |
| Retour de /v1/models (liste dynamique de modèles) | src-tauri/src/proxy/handlers/openai.rs | 1082-1102 |
| Structure de données de requête OpenAI (messages/instructions/input/size/quality) | src-tauri/src/proxy/mappers/openai/models.rs | 7-38 |
| --- | --- | --- |
| --- | --- | --- |
| Mappage de modèles et priorité des caractères génériques (exact > générique > défaut) | src-tauri/src/proxy/common/model_mapping.rs | 180-228 |
| --- | --- | --- |
Constantes clés :
MAX_RETRY_ATTEMPTS = 3: nombre maximum de tentatives pour le protocole OpenAI (incluant la rotation) (voirsrc-tauri/src/proxy/handlers/openai.rs)
Fonctions clés :
transform_openai_request(...): convertit le corps de la requête OpenAI en requête en amont interne (voirsrc-tauri/src/proxy/mappers/openai/request.rs)transform_openai_response(...): convertit la réponse en amont enchoices/usaged'OpenAI (voirsrc-tauri/src/proxy/mappers/openai/response.rs)