Referência da API de IA.
O DXPR Builder expõe três rotas de IA. O navegador
chama-as, e os controladores passam o pedido
através do módulo AI do Drupal para o fornecedor DXPR
(ai_provider_dxpr), por isso a chave de API nunca chega ao
navegador. As rotas definem-se em
dxpr_builder.routing.yml; o comportamento abaixo vem de
src/Controller/AiChatController.php e
src/Controller/AiImageController.php.

Requisitos de acesso (as três rotas)
| Requirement | Source |
|---|---|
Método HTTP POST |
methods: [POST] na rota |
Permissão edit with dxpr builder |
_permission |
| Utilizador faturável (lugar de licença válido) | _dxpr_builder_billable_user, verificado por DxprBuilderBillableUserAccessCheck |
Token CSRF no token, o parâmetro de consulta |
_csrf_token: 'TRUE' |
| Cookie de sessão Drupal com início de sessão | As verificações de acesso do Drupal correm por utilizador |
O token é o token CSRF de rota do Drupal para o
caminho da rota. O DXPR Builder gera-o no servidor
e incorpora-o em drupalSettings.dxprBuilder.aiAgent
como endpointUrl, imageEndpointUrl e
imageEditEndpointUrl (consulte
DxprBuilderFormatter). Leia um desses valores
de uma página onde o editor está carregado para obter um
URL funcional. Uma verificação de acesso falhada devolve o
403 padrão do Drupal.
Os controladores instanciam sempre o fornecedor dxpr;
o fornecedor definido em
/admin/config/ai/settings não é usado.
Conversa
POST /dxpr_builder/ajax/ai/chat?token=...
Usado por comandos de texto, criação de páginas e sugestões
de prompt. O controlador lê um corpo JSON e
chama $provider->chat().
Corpo do pedido
| Field | Type | Required | Notes |
|---|---|---|---|
messages |
array de {role, content} |
yes | role é system, user ou assistant |
model |
string | no | Predefinição kavya-m1. Tem de estar na lista Allowed models do fornecedor |
stream |
boolean | no | Predefinição true |
prediction |
object | no | Passado adiante, por exemplo {"type":"content","content":"<p>...</p>"} |
providers |
string | no | ID de fornecedores separados por vírgulas, por exemplo openai,mistral |
allowed_html_tags |
string | no | Passado adiante; o construtor envia Bootstrap 5 HTML |
allowed_html_classes |
string | no | Passado adiante; o construtor envia Bootstrap 5 Classes |
web_search |
boolean | no | Apenas false é reencaminhado |
response_format |
object | no | Passado adiante; por exemplo json_schema, um objeto |
O controlador adiciona sempre jsonrpc: false à
configuração do fornecedor. Antes da chamada, funde
os domínios de AI Output Filtering > Allowed
domains no filtro de nomes de anfitrião do módulo AI para
a duração do pedido (* muda o
filtro para confiança total).
Resposta
Em fluxo (stream true, a predefinição):
200, Content-Type: text/event-stream. Cada
evento é data: {json} seguido de uma linha em branco,
e o fluxo termina com data: [DONE].
data: {"choices":[{"delta":{"content":"Hello"}}],"id":"...","model":"kavya-m1","usage":{...}}
data: [DONE]
id, object, created, model,
original_model e usage copiam-se do fragmento
bruto do fornecedor quando presentes.
Sem fluxo (stream false): 200,
application/json:
{"choices":[{"message":{"role":"assistant","content":"..."}}]}
Erros
| Status | Body |
|---|---|
400 |
Texto simples 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."}} quando ai_provider_dxpr está instalado e model não está na lista Allowed models |
500 |
{"error":{"message":"The request could not be completed."}} (detalhes no canal de registo dxpr_builder) |
Exemplo
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);
Geração de imagens
POST /dxpr_builder/ajax/ai/image?token=...
Chama $provider->textToImage().
Corpo do pedido
| Field | Type | Required | Notes |
|---|---|---|---|
prompt |
string | yes | Descrição de texto da imagem |
model |
string | no | Predefinição kavya-image |
size |
string | no | O construtor envia 1024x1024, 1536x1024 ou 1024x1536; omitido para Auto |
quality |
string | no | Passado ao fornecedor sem alterações |
background |
string | no | Passado ao fornecedor sem alterações |
Resposta
200, application/json. Apenas a primeira imagem
é devolvida, codificada em base64. O fornecedor DXPR
pede saída webp.
{"data":[{"b64_json":"UklGRi..."}]}
Erros
| 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."}} |
Exemplo
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"}'
Edição de imagens
POST /dxpr_builder/ajax/ai/image/edit?token=...
Chama $provider->imageToImage() com a
imagem carregada e a prompt.
Corpo do pedido
| Field | Type | Required | Notes |
|---|---|---|---|
prompt |
string | yes | Instrução de edição |
image |
string | yes | Dados de imagem em base64 sem prefixo data:; descodificação estrita |
mimeType |
string | no | Predefinição image/png; o subtipo vira a extensão do ficheiro |
model |
string | no | Predefinição kavya-image |
size, quality, background |
string | no | Como na geração de imagens |
Resposta
A mesma forma da geração de imagens:
{"data":[{"b64_json":"..."}]}.
Erros
| 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."}} |
Exemplo
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 uma imagem gerada
As rotas devolvem apenas bytes de imagem. O construtor
converte b64_json num ficheiro webp e carrega-o para
POST /dxpr_builder/ajax/file_upload
(drupalSettings.dxprBuilder.fileUploadUrl, campo de
formulário upload[]), que responde com o url e o fid do ficheiro.
A prompt vira o nome do ficheiro
(primeiros 80 caracteres) e o atributo alt.