feat(ai-runtime): complete ai runtime policy refactor (ADR-035)
CI / CD Pipeline / build (push) Successful in 4m16s
CI / CD Pipeline / deploy (push) Successful in 11m51s

This commit is contained in:
2026-06-12 08:07:15 +07:00
parent 71c5e88181
commit 0227b7b982
63 changed files with 3566 additions and 451 deletions
+2 -1
View File
@@ -16,4 +16,5 @@
| 2026-06-05 | v1.9.8 | RAG Pipeline Enhancements (Spec 234 / ADR-035) — BGE-M3 + BGE-Reranker + Hybrid Qdrant (Session 14/15) | ✅ Complete |
| 2026-06-06 | v1.9.9 | LLM JSON Parse Failure & VRAM Fix (ADR-035-135) — retry logic + keep_alive=0 + ESLint heap fix | ✅ Complete |
| 2026-06-08 | v1.9.10 | LLM JSON Response Truncation Fix — ขยาย num_ctx: 16384 (Session 16 โดย AGY Gemini 3.5 Flash (Medium)) | ✅ Complete |
| 2026-06-11 | v1.9.10 | AI Runtime Policy Refactor (Feature-235) — Canonical names (`np-dms-ai`/`np-dms-ocr`), Adaptive OCR Residency, CPU Fallback Retrieval, Queue Policy (ai-realtime concurrency=2) — targeted verification 27/27 tests ✅ ESLint + tsc clean | ⏳ Pending T032 Manual Gate + Merge |
| 2026-06-11 | v1.9.10 | Feature-235 validation follow-up — validation-report.md = PARTIAL, cutover-validation checklist added, targeted verification 27/27 | ⏳ Pending T032 execution |
@@ -4,11 +4,11 @@
- Reorganize โครงสร้างโฟลเดอร์ `specs/` สำเร็จ (`100-Infrastructures`, `200-fullstacks`, `300-others`)
- อัปเดตกฎ `AGENTS.md` และ `GEMINI.md` ให้ตรงกับมาตรฐานใหม่
- ริเริ่มระบบ `memory/agent-memory.md`
- ริเริ่มระบบ `memory/project-memory-override.md`
## ไฟล์ที่แก้ไข
- `specs/` folder structure reorganization
- `AGENTS.md` update
- `GEMINI.md` update
- `memory/agent-memory.md` initial creation
- `memory/project-memory-override.md` initial creation
@@ -0,0 +1,64 @@
# Session 17 — 2026-06-11 (AI Runtime Policy Refactor — Feature-235)
## Summary
Implement Feature-235 AI Runtime Policy Refactor ตาม spec.md และ plan.md บน branch `235-ai-runtime-policy-refactor` — เปลี่ยน API contract ให้ caller ส่ง job type เท่านั้น (ไม่มี `model.key` / parameter overrides), เพิ่ม backend policy mapping layer (`AiPolicyService`), adaptive OCR residency, CPU fallback retrieval, และ BullMQ queue policy — จบด้วย test suite 23/23 ผ่านครบ, ESLint + tsc clean.
## ปัญหาที่พบ (Root Cause)
| ปัญหา | สาเหตุ | การแก้ไข |
|---|---|---|
| `VramStatus` / `getVramStatus()` / `invalidateCache()` หาย | refactor ก่อนหน้าลบออก แต่ controller ยังใช้ | Restore เมธอดใน `vram-monitor.service.ts` |
| TS2367 ใน `ai-policy.service.ts` | compare `ExecutionProfile` กับ `'ocr-extract'` ผิด type | แก้ compare เป็น `'np-dms-ai'` |
| TS1272 `import type` ใน DTO | import ประกอบ class ด้วย `import type` ไม่ได้ | เปลี่ยนเป็น regular import |
| `any` types ใน `ai-batch.processor.ts` | `snapshotParams` / `effectiveProfile` ไม่มี typed | กำหนด interface `AiBatchJobData` runtime metadata |
| NestJS DI error ใน `ai.controller.spec.ts` | ขาด mock `'default_IORedisModuleConnectionToken'` | เพิ่ม mock provider ใน test module providers |
## การแก้ไข (Fix)
| ไฟล์ | การเปลี่ยนแปลง |
|---|---|
| `backend/src/modules/ai/services/vram-monitor.service.ts` | Restore `VramStatus`, `getVramStatus()`, `invalidateCache()` |
| `backend/src/modules/ai/services/ai-policy.service.ts` | แก้ TS2367 type comparison; เพิ่ม `getProfileForJobType()`, `createJobPayload()` |
| `backend/src/modules/ai/interfaces/execution-policy.interface.ts` | สร้างใหม่ — `ExecutionProfile`, `RuntimePolicy`, `AiJobPayload`, `VramHeadroom` |
| `backend/src/modules/ai/interfaces/ocr-residency.interface.ts` | สร้างใหม่ — `OcrResidencyDecision` |
| `backend/src/modules/ai/dto/create-ai-job.dto.ts` | ลบ `model.key`, `executionProfile`, `temperature`, `top_p`, `maxTokens`; เพิ่ม forbidden field validators |
| `backend/src/modules/ai/dto/ai-job-response.dto.ts` | เพิ่ม `modelUsed`, `effectiveProfile` fields |
| `backend/src/modules/ai/ai.service.ts` | inject `AiPolicyService`; กำหนด `effectiveProfile` จาก job type อัตโนมัติ |
| `backend/src/modules/ai/processors/ai-realtime.processor.ts` | เพิ่ม lightweight job classification; redirect heavy jobs ไป ai-batch |
| `backend/src/modules/ai/processors/ai-batch.processor.ts` | type-safe runtime policy metadata; log `retrievalDevice`; canonical `ocrUsed` |
| `backend/src/modules/ai/services/ocr.service.ts` | inject `VramMonitorService`; `calculateOcrResidency()` dynamic keep_alive |
| `backend/src/config/bullmq.config.ts` | เพิ่ม `REALTIME_CONCURRENCY` env (default 2) |
| `backend/src/modules/ai/ai.module.ts` | register `AiPolicyService`, `VramMonitorService` |
| `backend/src/modules/ai/guards/execution-profile.guard.ts` | สร้างใหม่ (สำรองไว้; ไม่ใช้ใน option B) |
| `backend/src/modules/ai/tests/ai-policy.service.spec.ts` | สร้างใหม่ — 7 tests ผ่าน |
| `backend/src/modules/ai/tests/ocr-residency.spec.ts` | สร้างใหม่ — 5 tests ผ่าน |
| `backend/src/modules/ai/tests/queue-policy.spec.ts` | สร้างใหม่ — 2 tests ผ่าน |
| `backend/src/modules/ai/tests/vram-monitor.service.spec.ts` | สร้างใหม่ — 5 tests ผ่าน |
| `backend/src/modules/ai/tests/ai.controller.spec.ts` | สร้างใหม่ — 4 integration tests ผ่าน; เพิ่ม Redis mock |
| `frontend/types/ai.ts` | ลบ `model` field; เพิ่ม `executionProfile?`, `modelUsed?` |
| `frontend/lib/services/admin-ai.service.ts` | อัปเดต types ตาม DTO ใหม่ |
| `frontend/components/admin/ai/OcrSandboxPromptManager.tsx` | แสดง `np-dms-ai` / `np-dms-ocr` แทน runtime names |
| `frontend/app/(admin)/admin/ai/page.tsx` | แสดง canonical names ใน System Health panel |
| `frontend/public/locales/en/ai.json` | เพิ่ม `ai_runtime_policy` namespace |
| `frontend/public/locales/th/ai.json` | เพิ่ม `ai_runtime_policy` namespace |
| `backend/.env.example` | เพิ่ม `AI_OCR_RESIDENCY_WINDOW_SECONDS` |
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/.env.template` | สร้างใหม่ — VRAM + residency + concurrency vars |
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/app.py` | adaptive `keep_alive` param; CPU fallback บน `/embed` + `/rerank` |
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/services/vram_monitor.py` | สร้างใหม่ — query Ollama `/api/ps` |
| `specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/services/residency_policy.py` | สร้างใหม่ — keep_alive calculation |
| `CONTEXT.md` | เพิ่ม Feature-235 ใน System Readiness + ADR-034 ใน ADRs table |
## กฎที่ Lock แล้ว
- **Option B (Policy-Only)**: Caller ไม่มี `executionProfile` field ใน `CreateAiJobDto` — backend กำหนด profile จาก `job.type` เท่านั้น (ไม่รับ caller input)
- **Canonical Model Identity**: `np-dms-ai` (LLM) / `np-dms-ocr` (OCR) ทุก layer ที่ผู้ใช้เห็น — ชื่อ runtime (`typhoon*`) ใช้เฉพาะ ops internals
- **Redis mock token**: ทุก test ที่ bootstrap `AiController` ต้องเพิ่ม `'default_IORedisModuleConnectionToken'` ใน providers
- **Lightweight Realtime Jobs**: เฉพาะ `intent-classify`, `tool-suggest` — ห้าม `rag-query` อยู่ใน ai-realtime
## Verification
- [x] `npx jest src/modules/ai/tests/` — 23/23 tests ผ่าน (5 suites)
- [x] `npx tsc --noEmit` — ไม่มี error
- [x] `npx eslint src/modules/ai/ --max-warnings=0` — ไม่มี warning
- [ ] T032: Manual validation Gate 14 ตาม `quickstart.md` (ต้องรันบน environment จริง)
@@ -0,0 +1,35 @@
# Session 18 — 2026-06-11 (Feature-235 Validation & Memory Save)
## Summary
สรุปผล validation ของ Feature-235, บันทึกรายงาน `validation-report.md`, และสร้าง cutover checklist สำหรับปิด T032 / sidecar pytest โดยยึด contract ปัจจุบันของ `/api/ai/jobs` ที่เป็น Option B.
## ปัญหาที่พบ (Root Cause)
| ปัญหา | สาเหตุ | การแก้ไข |
|---|---|---|
| Validation ยังไม่ขึ้น `PASS` | ยังขาด manual Gate 14 และ sidecar pytest ใน environment จริง | สร้าง `checklists/cutover-validation.md` เพื่อใช้ปิดงานอย่างเป็นระบบ |
| `quickstart.md` เดิมไม่สอดคล้องกับ contract ปัจจุบัน | ตัวอย่างเก่ายังส่ง `executionProfile` / `large-context` จาก caller | เก็บ evidence ใน validation report และทำ checklist ใหม่ตาม implementation ปัจจุบัน |
| Project memory ยังสะท้อน test count เก่า | รอบ verification ล่าสุดได้ targeted tests 27/27 แล้ว | อัปเดต `memory/project-memory-override.md` ให้ตรงกับสถานะล่าสุด |
## การแก้ไข (Fix)
| ไฟล์ | การเปลี่ยนแปลง |
|---|---|
| `specs/200-fullstacks/235-ai-runtime-policy-refactor/validation-report.md` | บันทึกผล validation เป็น `PARTIAL` พร้อม requirement matrix, gaps, และ recommendations |
| `specs/200-fullstacks/235-ai-runtime-policy-refactor/checklists/cutover-validation.md` | สร้าง runbook สำหรับ T032, backend tests, backend build, และ sidecar pytest |
| `specs/88-logs/rollouts.md` | เพิ่ม entry สำหรับ validation follow-up ของ Feature-235 |
| `memory/project-memory-override.md` | อัปเดตสถานะ Feature-235, test count ล่าสุด, และชี้ไปยัง cutover checklist |
## กฎที่ Lock แล้ว
- ใช้ `checklists/cutover-validation.md` เป็น runbook หลักสำหรับปิด T032
- Validation target ของ `/api/ai/jobs` ต้องยึด Option B ปัจจุบัน ไม่ใช้ caller-driven `executionProfile`
- ถ้าต้องบันทึกผล verification ต่อ ให้แนบ evidence จริงจาก backend / sidecar environment
## Verification
- [x] `pnpm --filter backend test -- --runInBand --testPathPatterns="ai.service.spec.ts|queue-policy.spec.ts|ai.controller.spec.ts"` = 27/27 ผ่าน
- [x] `pnpm --filter backend build` = ผ่าน
- [x] `validation-report.md` ถูกสร้างและเก็บผลว่า `PARTIAL`
- [x] `cutover-validation.md` ถูกสร้างเพื่อใช้ปิด T032