4.6 KiB
// File: specs/200-fullstacks/235-ai-runtime-policy-refactor/contracts/create-ai-job.dto.md // Change Log: // - 2026-06-11: API contract for CreateAiJobDto // - 2026-06-11: Option B — backend-determined policy; ลบ executionProfile ออกจาก request // - 2026-06-11: Rename profiles — interactive/standard/quality/deep-analysis; เพิ่ม default values จาก docs/ai-profiles.md
Contract: POST /api/ai/jobs
Request DTO
// PublicJobType — เปิดให้ caller ส่งมาใน API
type PublicJobType = 'auto-fill-document' | 'migrate-document' | 'rag-query';
// InternalJobType — ใช้ภายใน AiPolicyService เท่านั้น ไม่ expose ใน API
type InternalJobType = PublicJobType | 'intent-classify' | 'tool-suggest' | 'ocr-extract';
interface CreateAiJobRequest {
type: PublicJobType;
documentPublicId?: string; // UUIDv7 — ADR-019
attachmentPublicId?: string; // UUIDv7 — ADR-019
// [FORBIDDEN] executionProfile — HTTP 400 if present (backend กำหนดเอง)
// [FORBIDDEN] model.key — HTTP 400 if present
// [FORBIDDEN] temperature, top_p, maxTokens — HTTP 400 if present
}
หมายเหตุ: ไม่มี
executionProfileใน request — backend กำหนด execution policy ทั้งหมดจากjob.typeอัตโนมัติ user ทั่วไปไม่ต้องรู้จัก profile เลยintent-classify,tool-suggest,ocr-extractเป็น internal job types — เกิดภายใน service โดยตรง ไม่ผ่าน API
Validation Rules
| Field | Rule |
|---|---|
type |
Required; enum 'auto-fill-document' | 'migrate-document' | 'rag-query' |
executionProfile |
FORBIDDEN — HTTP 400 ถ้ามีใน payload |
model.* |
FORBIDDEN — ANY model subfield → HTTP 400 |
temperature |
FORBIDDEN — HTTP 400 ถ้ามีใน payload |
top_p |
FORBIDDEN — HTTP 400 ถ้ามีใน payload |
maxTokens |
FORBIDDEN — HTTP 400 ถ้ามีใน payload |
documentPublicId |
Optional; UUIDv7 string (ADR-019) — ห้าม parseInt |
attachmentPublicId |
Optional; UUIDv7 string (ADR-019) — ห้าม parseInt |
Job Type → Effective Profile Mapping (Backend Policy)
job.type |
effectiveProfile |
canonicalModel |
queueName |
|---|---|---|---|
auto-fill-document |
quality |
np-dms-ai |
ai-batch |
migrate-document |
quality |
np-dms-ai |
ai-batch |
rag-query |
standard |
np-dms-ai |
ai-batch |
intent-classify |
interactive |
np-dms-ai |
ai-realtime |
tool-suggest |
interactive |
np-dms-ai |
ai-realtime |
ocr-extract |
(OCR residency policy) | np-dms-ocr |
ai-batch |
sandbox-analysis |
deep-analysis |
np-dms-ai |
ai-batch |
Mapping นี้กำหนดใน
AiPolicyService— ไม่ expose ให้ caller เห็น
Profile Default Parameters (จาก docs/ai-profiles.md)
| Profile | temperature |
top_p |
max_tokens |
num_ctx |
repeat_penalty |
keep_alive |
|---|---|---|---|---|---|---|
interactive |
0.7 | 0.9 | 2048 | 4096 | 1.15 | "5m" |
standard |
0.5 | 0.8 | 4096 | 8192 | 1.15 | "10m" |
quality |
0.1 | 0.95 | 8192 | 8192 | 1.15 | "10m" |
deep-analysis |
0.3 | 0.85 | 8192 | 32768 | 1.15 | "0" |
ค่าเหล่านี้เป็น default — ops/admin calibrate ได้ผ่าน Admin Console และบันทึกใน DB ตาม ADR-029 (Dynamic Prompt Management)
Response DTO
type ExecutionProfile = 'interactive' | 'standard' | 'quality' | 'deep-analysis';
interface AiJobResponse {
jobId: string; // BullMQ job ID
status: 'queued' | 'completed' | 'failed';
modelUsed: 'np-dms-ai' | 'np-dms-ocr'; // Canonical name — never runtime tag
effectiveProfile: ExecutionProfile; // Profile ที่ backend กำหนดจาก job.type
queueName: 'ai-realtime' | 'ai-batch';
}
effectiveProfileใน response คือ read-only informational field สำหรับ admin/developer ดู — ไม่ใช่ input
Error Responses
| Status | When |
|---|---|
| 400 | executionProfile, model.key, หรือ parameter overrides มีใน payload |
| 422 | documentPublicId หรือ attachmentPublicId ไม่พบใน DB |
| 504 | CPU fallback retrieval timeout (/embed หรือ /rerank) |