Référence de l’API IA.

Apprendre DXPR BuilderÉtendreArchitecture et API

DXPR Builder expose trois routes IA. Le navigateur les appelle, et les contrôleurs transmettent la requête via le module AI de Drupal au fournisseur DXPR (ai_provider_dxpr), pour que la clé API ne parvienne jamais au navigateur. Les routes sont définies dans dxpr_builder.routing.yml ; le comportement ci-dessous vient de src/Controller/AiChatController.php et src/Controller/AiImageController.php.

Panneau Generate content avec le prompt Add a paragraph with 3 feature boxes, les liens Enhance prompt et Chat mode, un bouton Generate content et les boutons Choose a template et Add Elements

Conditions d’accès (les trois routes)

Exigence Source
Méthode HTTP POST methods: [POST] dans la route
Permission edit with dxpr builder _permission
Utilisateur facturable (place de licence valide) _dxpr_builder_billable_user, vérifié par DxprBuilderBillableUserAccessCheck
Jeton CSRF dans le paramètre token de la requête _csrf_token: 'TRUE'
Cookie de session Drupal connecté Les vérifications d’accès Drupal tournent par utilisateur

Le jeton est le jeton CSRF de route de Drupal pour le chemin de la route. DXPR Builder le génère côté serveur et l’intègre dans drupalSettings.dxprBuilder.aiAgent comme endpointUrl, imageEndpointUrl et imageEditEndpointUrl (voir DxprBuilderFormatter). Lisez l’une de ces valeurs depuis une page où l’éditeur est chargé pour obtenir une URL fonctionnelle. Une vérification d’accès ratée renvoie la réponse 403 standard de Drupal.

Les contrôleurs instancient toujours le fournisseur dxpr ; le fournisseur défini sous /admin/config/ai/settings n’est pas utilisé.

Chat

POST /dxpr_builder/ajax/ai/chat?token=...

Utilisé par les commandes de texte, la création de pages et les suggestions de prompt. Le contrôleur lit un corps JSON et appelle $provider->chat().

Corps de la requête

Champ Type Requis Notes
messages tableau de {role, content} oui role vaut system, user ou assistant
model chaîne non Défaut : kavya-m1. Doit figurer dans la liste Allowed models du fournisseur
stream booléen non Défaut : true
prediction objet non Transmis tel quel, par exemple {"type":"content","content":"<p>...</p>"}
providers chaîne non Identifiants de fournisseurs séparés par des virgules, par exemple openai,mistral
allowed_html_tags chaîne non Transmis tel quel ; le builder envoie Bootstrap 5 HTML
allowed_html_classes chaîne non Transmis tel quel ; le builder envoie Bootstrap 5 Classes
web_search booléen non Seul false est transmis
response_format objet non Transmis tel quel ; un objet json_schema par exemple

Le contrôleur ajoute toujours jsonrpc: false à la configuration du fournisseur. Avant l’appel, il fusionne les domaines de AI Output Filtering > Allowed domains dans le filtre de noms d’hôte du module AI pour la durée de la requête (* fait passer le filtre en confiance totale).

Réponse

En continu (stream vrai, le défaut) : 200, Content-Type: text/event-stream. Chaque événement est data: {json} suivi d’une ligne vide, et le flux se termine par data: [DONE].

data: {"choices":[{"delta":{"content":"Hello"}}],"id":"...","model":"kavya-m1","usage":{...}}

data: [DONE]

id, object, created, model, original_model et usage sont copiés depuis le morceau brut du fournisseur quand ils sont présents.

Non continu (stream faux) : 200, application/json :

{"choices":[{"message":{"role":"assistant","content":"..."}}]}

Erreurs

Statut Corps
400 Texte brut Invalid request: messages required
403 {"error":{"code":"model_not_allowed","message":"The selected model is not allowed. Please refresh the page to update your model options."}} quand ai_provider_dxpr est installé et que model n’est pas dans sa liste Allowed models
500 {"error":{"message":"The request could not be completed."}} (détails dans le canal de log dxpr_builder)

Exemple

const url = drupalSettings.dxprBuilder.aiAgent.endpointUrl;
const res = await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    model: "kavya-m1",
    stream: false,
    messages: [
      { role: "system", content: "You are a copywriter." },
      { role: "user", content: "Shorten: <p>Our team ...</p>" }
    ]
  })
});
const data = await res.json();
console.log(data.choices[0].message.content);

Génération d’images

POST /dxpr_builder/ajax/ai/image?token=...

Appelle $provider->textToImage().

Corps de la requête

Champ Type Requis Notes
prompt chaîne oui Description textuelle de l’image
model chaîne non Défaut : kavya-image
size chaîne non Le builder envoie 1024x1024, 1536x1024 ou 1024x1536 ; omis pour Auto
quality chaîne non Transmis au fournisseur sans changement
background chaîne non Transmis au fournisseur sans changement

Réponse

200, application/json. Seule la première image est renvoyée, encodée en base64. Le fournisseur DXPR demande une sortie webp.

{"data":[{"b64_json":"UklGRi..."}]}

Erreurs

Statut Corps
400 {"error":{"message":"Invalid request: prompt required"}}
500 {"error":{"message":"No image was generated"}}
500 {"error":{"message":"Image generation failed. Please try again."}}

Exemple

curl -X POST "https://example.com/dxpr_builder/ajax/ai/image?token=TOKEN" \
  -H "Content-Type: application/json" \
  -H "Cookie: SESSxxx=..." \
  -d '{"prompt":"Flat illustration of a rocket","size":"1536x1024"}'

Modification d’images

POST /dxpr_builder/ajax/ai/image/edit?token=...

Appelle $provider->imageToImage() avec l’image téléversée et le prompt.

Corps de la requête

Champ Type Requis Notes
prompt chaîne oui Instruction de modification
image chaîne oui Données d’image Base64 sans préfixe data: ; décodage strict
mimeType chaîne non Défaut : image/png ; le sous-type devient l’extension du fichier
model chaîne non Défaut : kavya-image
size, quality, background chaîne non Comme pour la génération d’images

Réponse

Même forme que la génération d’images : {"data":[{"b64_json":"..."}]}.

Erreurs

Statut Corps
400 {"error":{"message":"Invalid request: prompt and image required"}}
400 {"error":{"message":"Invalid image data: base64 decode failed"}}
500 {"error":{"message":"No image was generated"}}
500 {"error":{"message":"Image editing failed. Please try again."}}

Exemple

const url = drupalSettings.dxprBuilder.aiAgent.imageEditEndpointUrl;
const res = await fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    prompt: "Remove the background",
    image: base64String,
    mimeType: "image/jpeg"
  })
});
const { data } = await res.json();

Stocker une image générée

Les routes ne renvoient que les octets de l’image. Le builder convertit b64_json en fichier webp et le téléverse vers POST /dxpr_builder/ajax/file_upload (drupalSettings.dxprBuilder.fileUploadUrl, champ de formulaire upload[]), qui répond avec l’url et le fid du fichier. Le prompt devient le nom du fichier (80 premiers caractères) et l’attribut alt.

Et ensuite ?