KI-API-Referenz.

DXPR Builder lernenErweiternArchitektur und APIs

DXPR Builder stellt drei KI-Routen bereit. Der Browser ruft sie auf, und die Controller leiten die Anfrage über das Drupal-KI-Modul an den DXPR-Anbieter (ai_provider_dxpr) weiter, sodass der API-Schlüssel den Browser nie erreicht. Routen sind in dxpr_builder.routing.yml definiert; das Verhalten unten stammt aus src/Controller/AiChatController.php und src/Controller/AiImageController.php.

Panel „Generate content“ mit dem Prompt „Add a paragraph with 3 feature boxes“, den Links „Enhance prompt“ und „Chat mode“, einer Schaltfläche „Generate content“ sowie den Schaltflächen „Choose a template“ und „Add Elements“

Zugangsvoraussetzungen (alle drei Routen)

Voraussetzung Quelle
HTTP-Methode POST methods: [POST] in der Route
Berechtigung edit with dxpr builder _permission
Abrechenbares Konto (gültiger Lizenzplatz) _dxpr_builder_billable_user, geprüft von DxprBuilderBillableUserAccessCheck
CSRF-Token im token-Abfrageparameter _csrf_token: 'TRUE'
Eingeloggtes Drupal-Sitzungscookie Drupal-Zugangsprüfungen laufen pro Konto

Das Token ist Drupals Routen-CSRF-Token für den Routenpfad. DXPR Builder erzeugt es serverseitig und bettet es in drupalSettings.dxprBuilder.aiAgent als endpointUrl, imageEndpointUrl und imageEditEndpointUrl ein (siehe DxprBuilderFormatter). Lesen Sie einen dieser Werte von einer Seite aus, auf der der Editor geladen ist, um eine funktionierende URL zu erhalten. Eine fehlgeschlagene Zugangsprüfung liefert Drupals Standardantwort 403.

Die Controller instanziieren immer den Anbieter dxpr; der unter /admin/config/ai/settings eingestellte Anbieter wird nicht genutzt.

Chat

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

Genutzt von Textbefehlen, Seitenerstellung und Eingabevorschlägen. Der Controller liest einen JSON-Body und ruft $provider->chat() auf.

Anfrage-Body

Feld Typ Erforderlich Hinweise
messages Array aus {role, content} ja role ist system, user oder assistant
model string nein Standard ist kavya-m1. Muss auf der Liste erlaubter Modelle des Anbieters stehen
stream boolean nein Standard ist true
prediction object nein Wird durchgereicht, zum Beispiel {"type":"content","content":"<p>...</p>"}
providers string nein Kommagetrennte Anbieter-IDs, zum Beispiel openai,mistral
allowed_html_tags string nein Wird durchgereicht; der Builder sendet Bootstrap 5 HTML
allowed_html_classes string nein Wird durchgereicht; der Builder sendet Bootstrap 5 Classes
web_search boolean nein Nur false wird weitergeleitet
response_format object nein Wird durchgereicht, zum Beispiel ein json_schema-Objekt

Der Controller fügt der Anbieterkonfiguration immer jsonrpc: false hinzu. Vor dem Aufruf mischt er die Domains aus AI Output Filtering > Allowed domains für die Dauer der Anfrage in den Hostnamenfilter des KI-Moduls (* schaltet den Filter auf volles Vertrauen).

Antwort

Gestreamt (stream true, die Standardeinstellung): 200, Content-Type: text/event-stream. Jedes Ereignis ist data: {json} gefolgt von einer Leerzeile, und der Strom endet mit data: [DONE].

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

data: [DONE]

id, object, created, model, original_model und usage werden aus dem rohen Chunk des Anbieters kopiert, wenn vorhanden.

Nicht gestreamt (stream false): 200, application/json:

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

Fehler

Status Body
400 Klartext 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."}}, wenn ai_provider_dxpr installiert ist und model nicht auf seiner Liste erlaubter Modelle steht
500 {"error":{"message":"The request could not be completed."}} (Details im Protokollkanal dxpr_builder)

Beispiel

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);

Bilderzeugung

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

Ruft $provider->textToImage() auf.

Anfrage-Body

Feld Typ Erforderlich Hinweise
prompt string ja Textbeschreibung des Bildes
model string nein Standard ist kavya-image
size string nein Der Builder sendet 1024x1024, 1536x1024 oder 1024x1536; weggelassen für Auto
quality string nein Unverändert an den Anbieter durchgereicht
background string nein Unverändert an den Anbieter durchgereicht

Antwort

200, application/json. Nur das erste Bild wird zurückgegeben, base64-codiert. Der DXPR-Anbieter fordert webp-Ausgabe an.

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

Fehler

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."}}

Beispiel

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"}'

Bildbearbeitung

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

Ruft $provider->imageToImage() mit dem hochgeladenen Bild und dem Prompt auf.

Anfrage-Body

Feld Typ Erforderlich Hinweise
prompt string ja Bearbeitungsanweisung
image string ja Base64-Bilddaten ohne data:-Präfix; striktes Decodieren
mimeType string nein Standard ist image/png; der Subtyp wird zur Dateiendung
model string nein Standard ist kavya-image
size, quality, background string nein Wie bei der Bilderzeugung

Antwort

Dieselbe Form wie bei der Bilderzeugung: {"data":[{"b64_json":"..."}]}.

Fehler

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."}}

Beispiel

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();

Generiertes Bild speichern

Die Routen liefern nur Bild-Bytes. Der Builder wandelt b64_json in eine webp-Datei um und lädt sie auf POST /dxpr_builder/ajax/file_upload (drupalSettings.dxprBuilder.fileUploadUrl, Formularfeld upload[]) hoch, das mit der Datei-url und -fid antwortet. Der Prompt wird zum Dateinamen (erste 80 Zeichen) und zum Alt-Attribut.

Wie geht es weiter?