Gateway
API OpenResponses
Le Gateway peut fournir un endpoint POST /v1/responses compatible avec OpenResponses. Il est désactivé par défaut et partage son port avec le Gateway (multiplexage WS + HTTP) : http://<gateway-host>:<port>/v1/responses.
Les requêtes s’exécutent comme une exécution normale d’agent du Gateway (même chemin de code que openclaw agent) ; le routage, les autorisations et la configuration correspondent donc à ceux de votre Gateway.
Activez-le ou désactivez-le avec gateway.http.endpoints.responses.enabled. Lorsqu’elle est activée, la même surface de compatibilité fournit également GET /v1/models, GET /v1/models/{id}, POST /v1/embeddings et POST /v1/chat/completions.
Authentification, sécurité et routage
Le comportement opérationnel correspond à celui de OpenAI Chat Completions :
- Le chemin d’authentification correspond à
gateway.auth.mode: le secret partagé (token/password) utiliseAuthorization: Bearer <token-or-password>; le proxy de confiance utilise les en-têtes du proxy tenant compte de l’identité (les proxys local loopback sur le même hôte nécessitentgateway.auth.trustedProxy.allowLoopback = true, avec un repli direct sur le même hôte viagateway.auth.password/OPENCLAW_GATEWAY_PASSWORDlorsqu’aucun en-têteForwarded/X-Forwarded-*/X-Real-IPn’est présent) ;nonesur une entrée privée ne nécessite aucun en-tête d’authentification. Consultez Authentification par proxy de confiance. - Considérez cet endpoint comme donnant un accès opérateur complet à l’instance du Gateway.
- Les modes d’authentification par secret partagé ignorent un
x-openclaw-scopesdéclaré dans le jeton porteur qui serait plus restrictif et rétablissent l’ensemble complet des portées opérateur par défaut :operator.admin,operator.approvals,operator.pairing,operator.read,operator.talk.secrets,operator.write. Les tours de conversation sur cet endpoint sont traités comme des tours envoyés par le propriétaire. - Les modes HTTP de confiance porteurs d’identité (proxy de confiance ou
gateway.auth.mode="none") respectentx-openclaw-scopeslorsqu’il est présent ; sinon, ils utilisent l’ensemble des portées opérateur par défaut. La sémantique de propriétaire n’est perdue que lorsque l’appelant restreint explicitement les portées et ometoperator.admin. - Sélectionnez les agents avec
model: "openclaw","openclaw/default","openclaw/<agentId>"ou l’en-têtex-openclaw-agent-id. - Utilisez
x-openclaw-modelpour remplacer le modèle backend de l’agent sélectionné (nécessiteoperator.adminsur les chemins d’authentification porteurs d’identité). - Utilisez
x-openclaw-session-keypour un routage explicite de session (rejeté avec400 invalid_request_errors’il utilise un espace de noms réservé :subagent:,cron:,acp:). - Utilisez
x-openclaw-message-channelpour un contexte de canal d’entrée synthétique différent de celui par défaut.
Pour l’explication canonique des modèles ciblant les agents, de openclaw/default, de la transmission directe des embeddings et des remplacements de modèle backend, consultez OpenAI Chat Completions.
Consultez Portées opérateur et Sécurité.
Comportement des sessions
Par défaut, l’endpoint est sans état pour chaque requête (une nouvelle clé de session est générée à chaque appel).
Si la requête contient une chaîne OpenResponses user, le Gateway en dérive une clé de session stable afin que les appels répétés puissent partager une session d’agent.
previous_response_id réutilise la session de la réponse précédente lorsque la requête reste dans la même portée d’agent, d’utilisateur et de session demandée (correspondance selon le sujet d’authentification, l’identifiant de l’agent et x-openclaw-session-key).
Structure de la requête
| Champ | Prise en charge |
|---|---|
input |
Chaîne ou tableau d’objets d’élément. |
instructions |
Fusionné dans le prompt système. |
tools |
Définitions des outils du client (outils de fonction). |
tool_choice |
"auto", "none", "required" ou { "type": "function", "name": "..." } pour filtrer ou imposer les outils du client. |
stream |
Active la diffusion en continu SSE. |
max_output_tokens |
Limite de sortie appliquée au mieux (selon le fournisseur). |
temperature |
Température d’échantillonnage appliquée au mieux. Ignorée par le backend Codex Responses fondé sur ChatGPT, qui utilise un échantillonnage fixe côté serveur. |
top_p |
Échantillonnage par noyau appliqué au mieux. Même réserve relative à Codex Responses que pour temperature. |
user |
Routage stable des sessions. |
previous_response_id |
Continuité de session (voir ci-dessus). |
max_tool_calls, reasoning, metadata, store, truncation |
Acceptés, mais actuellement ignorés. |
Éléments (input)
message
Rôles : system, developer, user, assistant.
systemetdevelopersont ajoutés au prompt système.- L’élément
useroufunction_call_outputle plus récent devient le « message actuel ». - Les messages antérieurs de l’utilisateur et de l’assistant sont inclus dans l’historique afin de fournir le contexte.
function_call_output (outils par tour)
Renvoyez les résultats des outils au modèle :
{ "type": "function_call_output", "call_id": "call_123", "output": "{\"temperature\": \"72F\"}"}reasoning et item_reference
Acceptés pour assurer la compatibilité du schéma, mais ignorés lors de la construction du prompt.
Outils (outils de fonction côté client)
Fournissez les outils avec tools: [{ type: "function", name, description?, parameters? }].
Si l’agent appelle un outil, la réponse renvoie un élément de sortie function_call. Envoyez une requête de suivi avec function_call_output pour poursuivre le tour.
Pour tool_choice: "required" et un tool_choice fixé sur une fonction, l’endpoint restreint l’ensemble des outils de fonction du client exposés, demande à l’environnement d’exécution d’appeler un outil du client avant de répondre et rejette le tour s’il ne contient pas d’appel structuré correspondant à un outil du client, conformément au contrat de /v1/chat/completions. Les requêtes sans diffusion en continu renvoient 502 avec une api_error ; les requêtes avec diffusion en continu émettent un événement response.failed.
Images (input_image)
Prend en charge les sources en base64 ou par URL :
{ "type": "input_image", "source": { "type": "url", "url": "https://example.com/image.png" }}Types MIME autorisés (par défaut) : image/jpeg, image/png, image/gif, image/webp, image/heic, image/heif. Taille maximale (par défaut) : 10 Mo.
Fichiers (input_file)
Prend en charge les sources en base64 ou par URL :
{ "type": "input_file", "source": { "type": "base64", "media_type": "text/plain", "data": "SGVsbG8gV29ybGQh", "filename": "hello.txt" }}Types MIME autorisés (par défaut) : text/plain, text/markdown, text/html, text/csv, application/json, application/pdf. Taille maximale (par défaut) : 5 Mo.
Comportement actuel :
- Le contenu du fichier est décodé et ajouté au prompt système, et non au message de l’utilisateur ; il reste donc éphémère (il n’est pas conservé dans l’historique de la session).
- Le texte décodé du fichier est encapsulé en tant que contenu externe non fiable avant d’être ajouté, afin que les octets du fichier soient traités comme des données et non comme des instructions fiables. Le bloc injecté utilise des marqueurs de délimitation explicites (
<<<EXTERNAL_UNTRUSTED_CONTENT id="...">>>/<<<END_EXTERNAL_UNTRUSTED_CONTENT id="...">>>) et une ligne de métadonnéesSource: External. Il omet volontairement la longue bannièreSECURITY NOTICE:afin de préserver le budget du prompt ; les marqueurs de délimitation et les métadonnées restent applicables. - Le texte des PDF est d’abord extrait. Si peu de texte est trouvé, les premières pages sont rastérisées en images et transmises au modèle, et le bloc de fichier injecté utilise l’espace réservé
[PDF content rendered to images].
L’analyse des PDF est assurée par le Plugin document-extract fourni, qui utilise clawpdf et son environnement d’exécution PDFium WebAssembly inclus pour l’extraction du texte et le rendu des pages.
Valeurs par défaut de la récupération par URL :
files.allowUrl:trueimages.allowUrl:truemaxUrlParts:8(nombre total de partiesinput_file+input_imagefondées sur une URL par requête)- Les requêtes sont protégées (résolution DNS, blocage des adresses IP privées, limites de redirection, délais d’expiration).
- Des listes facultatives d’hôtes autorisés sont prises en charge pour chaque type d’entrée (
files.urlAllowlist,images.urlAllowlist) : hôte exact ("cdn.example.com") ou sous-domaines génériques ("*.assets.example.com", ne correspond pas au domaine racine). Une liste vide ou omise signifie qu’aucune restriction par liste d’hôtes autorisés ne s’applique. - Pour désactiver entièrement les récupérations par URL, définissez
files.allowUrl: falseet/ouimages.allowUrl: false.
Limites des fichiers et des images (configuration)
Les valeurs par défaut peuvent être ajustées sous gateway.http.endpoints.responses :
{ gateway: { http: { endpoints: { responses: { enabled: true, maxBodyBytes: 20000000, maxUrlParts: 8, files: { allowUrl: true, urlAllowlist: ["cdn.example.com", "*.assets.example.com"], allowedMimes: [ "text/plain", "text/markdown", "text/html", "text/csv", "application/json", "application/pdf", ], maxBytes: 5242880, maxChars: 60000, maxRedirects: 3, timeoutMs: 10000, pdf: { maxPages: 4, maxPixels: 4000000, minTextChars: 200, }, }, images: { allowUrl: true, urlAllowlist: ["images.example.com"], allowedMimes: [ "image/jpeg", "image/png", "image/gif", "image/webp", "image/heic", "image/heif", ], maxBytes: 10485760, maxRedirects: 3, timeoutMs: 10000, }, }, }, }, },}Valeurs par défaut en cas d’omission :
| Clé | Valeur par défaut |
|---|---|
maxBodyBytes |
20 Mo |
maxUrlParts |
8 |
files.maxBytes |
5 Mo |
files.maxChars |
60 k |
files.maxRedirects |
3 |
files.timeoutMs |
10 s |
files.pdf.maxPages |
4 |
files.pdf.maxPixels |
4 000 000 |
files.pdf.minTextChars |
200 |
images.maxBytes |
10 Mo |
images.maxRedirects |
3 |
images.timeoutMs |
10 s |
Les sources input_image HEIC/HEIF sont normalisées au format JPEG avant leur transmission au fournisseur par le processeur d’images partagé d’OpenClaw (Rastermill), qui se replie sur un convertisseur système (sips, ImageMagick, GraphicsMagick ou ffmpeg) pour les formats nécessitant la prise en charge d’un codec externe.
Remarque de sécurité : les listes d’URL autorisées sont appliquées avant la récupération et à chaque redirection. L’autorisation d’un nom d’hôte ne contourne pas le blocage des adresses IP privées ou internes. Pour les Gateway exposés à Internet, appliquez des contrôles de sortie réseau en plus des protections au niveau de l’application. Consultez Sécurité.
Diffusion en continu (SSE)
Définissez stream: true pour recevoir des événements envoyés par le serveur :
Content-Type: text/event-stream- Chaque ligne d’événement est au format
event: <type>etdata: <json> - Le flux se termine par
data: [DONE]
Types d’événements actuellement émis : response.created, response.in_progress, response.output_item.added, response.content_part.added, response.output_text.delta, response.output_text.done, response.content_part.done, response.output_item.done, response.completed, response.failed (en cas d’erreur).
Utilisation
usage est renseigné lorsque le fournisseur sous-jacent communique le nombre de jetons. OpenClaw normalise les alias courants de style OpenAI avant que ces compteurs n’atteignent les surfaces d’état et de session en aval, notamment input_tokens / output_tokens et prompt_tokens / completion_tokens.
Erreurs
Les erreurs utilisent un objet JSON tel que :
{ "error": { "message": "...", "type": "invalid_request_error" } }Cas courants : 400 corps de requête non valide, 401 authentification absente ou non valide, 403 portée d’opérateur manquante, 405 méthode incorrecte, 429 trop nombreuses tentatives d’authentification échouées (avec Retry-After).
Exemples
Sans diffusion en continu :
curl -sS http://127.0.0.1:18789/v1/responses \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -H 'x-openclaw-agent-id: main' \ -d '{ "model": "openclaw", "input": "hi" }'Avec diffusion en continu :
curl -N http://127.0.0.1:18789/v1/responses \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -H 'x-openclaw-agent-id: main' \ -d '{ "model": "openclaw", "stream": true, "input": "hi" }'