Referencia de la API de IA.

Aprende DXPR BuilderExtenderArquitectura y API

DXPR Builder expone tres rutas de IA. El navegador las llama, y los controladores pasan la petición por el módulo Drupal AI hasta el proveedor de DXPR (ai_provider_dxpr), así que la clave de API nunca llega al navegador. Las rutas se definen en dxpr_builder.routing.yml; el comportamiento de abajo viene de src/Controller/AiChatController.php y src/Controller/AiImageController.php.

Panel Generate content con el prompt Add a paragraph with 3 feature boxes, los enlaces Enhance prompt y Chat mode, un botón Generate content y los botones Choose a template y Add Elements

Requisitos de acceso (las tres rutas)

Requisito Origen
Método HTTP POST methods: [POST] en la ruta
Permiso edit with dxpr builder _permission
Persona facturable (licencia válida) _dxpr_builder_billable_user, comprobado por DxprBuilderBillableUserAccessCheck
Parámetro de consulta token con el token CSRF _csrf_token: 'TRUE'
Cookie de sesión Drupal con sesión iniciada Las comprobaciones de acceso de Drupal se ejecutan por persona

El token es el token CSRF de ruta de Drupal para la ruta. DXPR Builder lo genera en el servidor y lo incrusta en drupalSettings.dxprBuilder.aiAgent como endpointUrl, imageEndpointUrl e imageEditEndpointUrl (consulta DxprBuilderFormatter). Lee uno de esos valores en una página donde el editor está cargado para obtener una URL válida. Una comprobación de acceso fallida devuelve la respuesta 403 estándar de Drupal.

Los controladores siempre instancian el proveedor dxpr; el proveedor fijado en /admin/config/ai/settings no se usa.

Chat

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

Usado por comandos de texto, creación de páginas y sugerencias de prompts. El controlador lee un cuerpo JSON y llama a $provider->chat().

Cuerpo de la petición

Campo Tipo Obligatorio Notas
messages array de {role, content} sí role es system, user o assistant
model string no Predeterminado: kavya-m1. Debe estar en la lista Allowed models del proveedor
stream boolean no Predeterminado: true
prediction object no Se pasa tal cual, por ejemplo {"type":"content","content":"<p>...</p>"}
providers string no ID de proveedor separados por comas, por ejemplo openai,mistral
allowed_html_tags string no Se pasa tal cual; el constructor envía Bootstrap 5 HTML
allowed_html_classes string no Se pasa tal cual; el constructor envía Bootstrap 5 Classes
web_search boolean no Solo false se reenvía
response_format object no Se pasa tal cual, por ejemplo un json_schema en forma de objeto

El controlador siempre añade jsonrpc: false a la configuración del proveedor. Antes de la llamada fusiona los dominios de AI Output Filtering > Allowed domains en el filtro de nombres de host del módulo de IA durante la petición (* cambia el filtro a confianza total).

Respuesta

En streaming (stream true, el valor predeterminado): 200, Content-Type: text/event-stream. Cada evento es data: {json} seguido de una línea en blanco, y el flujo termina con data: [DONE].

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

data: [DONE]

id, object, created, model, original_model y usage se copian del fragmento crudo del proveedor cuando existen.

Sin streaming (stream false): 200, application/json:

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

Errores

Estado Cuerpo
400 Texto simple 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."}} cuando ai_provider_dxpr está instalado y model no está en su lista Allowed models
500 {"error":{"message":"The request could not be completed."}} (detalles en el canal de registro dxpr_builder)

Ejemplo

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

Generación de imágenes

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

Llama a $provider->textToImage().

Cuerpo de la petición

Campo Tipo Obligatorio Notas
prompt string sí Descripción en texto de la imagen
model string no Predeterminado: kavya-image
size string no El constructor envía 1024x1024, 1536x1024 o 1024x1536; omitido para Auto
quality string no Se pasa al proveedor sin cambios
background string no Se pasa al proveedor sin cambios

Respuesta

200, application/json. Solo se devuelve la primera imagen, codificada en base64. El proveedor de DXPR pide salida webp.

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

Errores

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

Ejemplo

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

Edición de imágenes

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

Llama a $provider->imageToImage() con la imagen subida y el prompt.

Cuerpo de la petición

Campo Tipo Obligatorio Notas
prompt string sí Instrucción de edición
image string sí Datos de imagen en Base64 sin prefijo data:; decodificación estricta
mimeType string no Predeterminado: image/png; el subtipo pasa a ser la extensión del archivo
model string no Predeterminado: kavya-image
size, quality, background string no Como en la generación de imágenes

Respuesta

Misma forma que la generación de imágenes: {"data":[{"b64_json":"..."}]}.

Errores

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

Ejemplo

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

Guardar una imagen generada

Las rutas solo devuelven bytes de imagen. El constructor convierte b64_json a un archivo webp y lo sube a POST /dxpr_builder/ajax/file_upload (drupalSettings.dxprBuilder.fileUploadUrl, campo de formulario upload[]), que responde con la url y el fid del archivo. El prompt pasa a ser el nombre del archivo (primeros 80 caracteres) y el atributo alt.

¿Qué sigue?