AI-API-referentie.
DXPR Builder biedt drie AI-routes aan. De browser
roept ze aan en de controllers proxyen het verzoek
via de Drupal AI-module naar de DXPR-provider
(ai_provider_dxpr), zodat de API-sleutel nooit in
de browser komt. Routes zijn gedefinieerd in
dxpr_builder.routing.yml; het gedrag hieronder komt
uit src/Controller/AiChatController.php en
src/Controller/AiImageController.php.

Toegangsvereisten (alle drie routes)
| Vereiste | Bron |
|---|---|
HTTP-methode POST |
methods: [POST] in de route |
Rechten edit with dxpr builder |
_permission |
| Factureerbare gebruiker (geldige licentieplek) | _dxpr_builder_billable_user, gecontroleerd door DxprBuilderBillableUserAccessCheck |
CSRF-token in de token-queryparameter |
_csrf_token: 'TRUE' |
| Ingelogde Drupal-sessiecookie | Drupal-toegangscontroles draaien per gebruiker |
Het token is het route-CSRF-token van Drupal voor het
routepad. DXPR Builder genereert het serverside
en bet het in in drupalSettings.dxprBuilder.aiAgent
als endpointUrl, imageEndpointUrl en
imageEditEndpointUrl (zie
DxprBuilderFormatter). Lees een van die waarden
uit van een pagina waar de editor is geladen om een
werkende URL te krijgen. Een mislukte toegangscontrole geeft het
standaard 403-antwoord van Drupal.
De controllers instantiëren altijd de dxpr-provider;
de provider die is ingesteld op
/admin/config/ai/settings wordt niet gebruikt.
Chat
POST /dxpr_builder/ajax/ai/chat?token=...
Gebruikt door tekstcommando's, paginaopstelling en promptsuggesties.
De controller leest een JSON-body en roept $provider->chat() aan.
Aanvraagbody
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
messages |
array van {role, content} |
ja | role is system, user of assistant |
model |
string | nee | Standaard kavya-m1. Moet op de lijst Allowed models van de provider staan |
stream |
boolean | nee | Standaard true |
prediction |
object | nee | Wordt doorgegeven, bijvoorbeeld {"type":"content","content":"<p>...</p>"} |
providers |
string | nee | Komma-gescheiden provider-ID's, bijvoorbeeld openai,mistral |
allowed_html_tags |
string | nee | Wordt doorgegeven; de builder stuurt Bootstrap 5 HTML |
allowed_html_classes |
string | nee | Wordt doorgegeven; de builder stuurt Bootstrap 5 Classes |
web_search |
boolean | nee | Alleen false wordt doorgestuurd |
response_format |
object | nee | Wordt doorgegeven, bijvoorbeeld een json_schema-object |
De controller voegt altijd jsonrpc: false toe aan de
providerconfiguratie. Vóór de aanroep voegt hij de domeinen uit
AI Output Filtering > Allowed domains samen in het hostnaamfilter van
de AI-module voor de duur van het verzoek (* schakelt het
filter om naar volledig vertrouwen).
Antwoord
Gestreamd (stream true, de standaard):
200, Content-Type: text/event-stream. Elke
event is data: {json} gevolgd door een lege regel,
en de stream eindigt met data: [DONE].
data: {"choices":[{"delta":{"content":"Hello"}}],"id":"...","model":"kavya-m1","usage":{...}}
data: [DONE]
id, object, created, model,
original_model en usage worden gekopieerd uit de
ruwe chunk van de provider wanneer aanwezig.
Niet-gestreamd (stream false): 200,
application/json:
{"choices":[{"message":{"role":"assistant","content":"..."}}]}
Fouten
| Status | Body |
|---|---|
400 |
Platte tekst 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."}} wanneer ai_provider_dxpr is geïnstalleerd en model niet op zijn lijst Allowed models staat |
500 |
{"error":{"message":"The request could not be completed."}} (details in het dxpr_builder-logkanaal) |
Voorbeeld
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);
Afbeeldingsgeneratie
POST /dxpr_builder/ajax/ai/image?token=...
Roept $provider->textToImage() aan.
Aanvraagbody
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
prompt |
string | ja | Tekstbeschrijving van de afbeelding |
model |
string | nee | Standaard kavya-image |
size |
string | nee | De builder stuurt 1024x1024, 1536x1024 of 1024x1536; weggelaten voor Auto |
quality |
string | nee | Ongewijzigd doorgegeven aan de provider |
background |
string | nee | Ongewijzigd doorgegeven aan de provider |
Antwoord
200, application/json. Alleen de eerste afbeelding
wordt teruggegeven, base64-gecodeerd. De DXPR-provider
vraagt webp-output aan.
{"data":[{"b64_json":"UklGRi..."}]}
Fouten
| Status | Body |
|---|---|
400 |
{"error":{"message":"Invalid request: prompt required"}} |
500 |
{"error":{"message":"No image was generated"}} |
500 |
{"error":{"message":"Image generation failed. Please try again."}} |
Voorbeeld
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"}'
Afbeeldingsbewerking
POST /dxpr_builder/ajax/ai/image/edit?token=...
Roept $provider->imageToImage() aan met de
geüploade afbeelding en de prompt.
Aanvraagbody
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
prompt |
string | ja | Bewerkingsinstructie |
image |
string | ja | Base64-afbeeldingsdata zonder data:-prefix; strikte decodering |
mimeType |
string | nee | Standaard image/png; het subtype wordt de bestandsextensie |
model |
string | nee | Standaard kavya-image |
size, quality, background |
string | nee | Zoals bij afbeeldingsgeneratie |
Antwoord
Zelfde vorm als afbeeldingsgeneratie:
{"data":[{"b64_json":"..."}]}.
Fouten
| Status | Body |
|---|---|
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."}} |
Voorbeeld
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();
Een gegenereerde afbeelding opslaan
De routes geven alleen afbeeldingsbytes terug. De builder
converteert b64_json naar een webp-bestand en uploadt het
naar POST /dxpr_builder/ajax/file_upload
(drupalSettings.dxprBuilder.fileUploadUrl, formulierveld
upload[]), dat antwoordt met de url en fid van het bestand.
De prompt wordt de bestandsnaam (eerste 80 tekens) en het alt-attribuut.