AI API 레퍼런스.
DXPR Builder는 세 가지 AI 경로를 제공합니다. 브라우저가 호출하면 컨트롤러가
Drupal AI 모듈을 통해 DXPR 공급자(ai_provider_dxpr)로 요청을 프록시하므로 API
키가 브라우저에 전달되지 않습니다. 경로는 dxpr_builder.routing.yml에
정의되어 있습니다. 아래 동작은 src/Controller/AiChatController.php와
src/Controller/AiImageController.php에서 가져온 것입니다.

접근 요구 사항(세 경로 공통)
| 요구 사항 | 출처 |
|---|---|
HTTP 메서드 POST |
methods: [POST](경로에 있음) |
권한 edit with dxpr builder |
_permission |
| 과금 사용자(유효한 라이선스 시트) | _dxpr_builder_billable_user. 검사 주체: DxprBuilderBillableUserAccessCheck |
쿼리 매개변수 token의 CSRF 토큰 |
_csrf_token: 'TRUE' |
| 로그인된 Drupal 세션 쿠키 | 사용자별로 실행되는 Drupal 접근 검사 |
토큰은 경로의 Drupal 경로 CSRF 토큰입니다. DXPR Builder가 서버에서 생성하여
drupalSettings.dxprBuilder.aiAgent에
endpointUrl, imageEndpointUrl,
imageEditEndpointUrl로 삽입합니다(DxprBuilderFormatter 참고). 에디터가
불러와진 페이지에서 해당 값 중 하나를 읽으면 작동하는 URL을 얻습니다. 접근
검사에 실패하면 Drupal 표준 403 응답이 반환됩니다.
컨트롤러는 항상 dxpr
공급자를 인스턴스화합니다. /admin/config/ai/settings에 설정된 공급자는
사용되지 않습니다.
채팅
POST /dxpr_builder/ajax/ai/chat?token=...
텍스트 명령, 페이지 생성, 프롬프트 제안에 사용합니다. 컨트롤러는 JSON 본문을
읽고 $provider->chat()(을)를 호출합니다.
요청 본문
| 필드 | 유형 | 필수 여부 | 참고 |
|---|---|---|---|
messages |
다음의 배열: {role, content} |
예 | role(은)는 다음 중 하나: system, user, assistant |
model |
string | 아니요 | 기본값: kavya-m1. 공급자의 Allowed models 목록에 있어야 함 |
stream |
boolean | 아니요 | 기본값: true |
prediction |
object | 아니요 | 그대로 전달. 예: {"type":"content","content":"<p>...</p>"} |
providers |
string | 아니요 | 쉼표로 구분된 공급자 ID. 예: openai,mistral |
allowed_html_tags |
string | 아니요 | 그대로 전달. 빌더가 전송: Bootstrap 5 HTML |
allowed_html_classes |
string | 아니요 | 그대로 전달. 빌더가 전송: Bootstrap 5 Classes |
web_search |
boolean | 아니요 | 다음만 전달됩니다: false. |
response_format |
object | 아니요 | 그대로 전달. 예: json_schema 객체 |
컨트롤러는 항상 공급자 설정에 jsonrpc: false(을)를 추가합니다. 호출 전에
AI Output Filtering > Allowed
domains의 도메인을 요청 기간 동안 AI 모듈의 호스트 이름 필터에 병합합니다(*(은)는
필터를 완전 신뢰로 전환).
응답
스트리밍(stream true, 기본값):
200, Content-Type: text/event-stream. 각
이벤트는 빈 줄이 뒤따르는 data: {json}이며,
스트림은 data: [DONE](으)로 끝납니다.
data: {"choices":[{"delta":{"content":"Hello"}}],"id":"...","model":"kavya-m1","usage":{...}}
data: [DONE]
id, object, created, model,
original_model, usage(은)는 제공된 경우 공급자의 원시 청크에서 복사됩니다.
비스트리밍(stream false): 200,
application/json:
{"choices":[{"message":{"role":"assistant","content":"..."}}]}
오류
| 상태 | 본문 |
|---|---|
400 |
일반 텍스트 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."}}. ai_provider_dxpr(이)가 설치되어 있고 model(이)가 허용 모델 목록에 없을 때 반환됨 |
500 |
{"error":{"message":"The request could not be completed."}} (dxpr_builder 로그 채널에 자세한 내용 있음) |
예시
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);
이미지 생성
POST /dxpr_builder/ajax/ai/image?token=...
다음을 호출합니다: $provider->textToImage().
요청 본문
| 필드 | 유형 | 필수 여부 | 참고 |
|---|---|---|---|
prompt |
string | 예 | 이미지의 텍스트 설명 |
model |
string | 아니요 | 기본값: kavya-image |
size |
string | 아니요 | 빌더는 1024x1024, 1536x1024, 1024x1536 중 전송. Auto에서는 생략 |
quality |
string | 아니요 | 공급자에 그대로 전달됨 |
background |
string | 아니요 | 공급자에 그대로 전달됨 |
응답
200, application/json. 첫 번째 이미지만
base64로 인코딩되어 반환됩니다. DXPR 공급자는
webp 출력을 요청합니다.
{"data":[{"b64_json":"UklGRi..."}]}
오류
| 상태 | 본문 |
|---|---|
400 |
{"error":{"message":"Invalid request: prompt required"}} |
500 |
{"error":{"message":"No image was generated"}} |
500 |
{"error":{"message":"Image generation failed. Please try again."}} |
예시
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"}'
이미지 편집
POST /dxpr_builder/ajax/ai/image/edit?token=...
다음을 호출합니다: $provider->imageToImage()(업로드된 이미지 및 프롬프트와 함께).
요청 본문
| 필드 | 유형 | 필수 여부 | 참고 |
|---|---|---|---|
prompt |
string | 예 | 편집 지시 |
image |
string | 예 | 접두사 없는 Base64 이미지 데이터: data:. 엄격한 디코딩 |
mimeType |
string | 아니요 | 기본값: image/png. 서브타입이 파일 확장자가 됨 |
model |
string | 아니요 | 기본값: kavya-image |
size, quality, background |
string | 아니요 | 이미지 생성과 동일 |
응답
이미지 생성과 같은 형태:
{"data":[{"b64_json":"..."}]}.
오류
| 상태 | 본문 |
|---|---|
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."}} |
예시
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();
생성된 이미지 저장
경로는 이미지 바이트만 반환합니다. 빌더는
b64_json(을)를 webp 파일로 변환하여
POST /dxpr_builder/ajax/file_upload
(drupalSettings.dxprBuilder.fileUploadUrl, 폼
필드 upload[])에 업로드합니다. 파일
url과 fid(으)로 응답합니다. 프롬프트는 파일 이름(앞 80자)과 alt
속성이 됩니다.