diff --git a/frontend/components/admin/ai/OcrSandboxPromptManager.tsx b/frontend/components/admin/ai/OcrSandboxPromptManager.tsx index ba5aa9b5..529ecb7f 100644 --- a/frontend/components/admin/ai/OcrSandboxPromptManager.tsx +++ b/frontend/components/admin/ai/OcrSandboxPromptManager.tsx @@ -147,7 +147,7 @@ export default function OcrSandboxPromptManager() { fallbackUsed?: boolean; } | null>(null); const [selectedPromptVersion, setSelectedPromptVersion] = useState(undefined); - const { state: sandboxState, jobId: sandboxJobId, reset: resetSandbox } = + const { state: sandboxState, jobId: sandboxJobId, reset: resetSandbox, startPolling } = useSandboxRun(() => { // เมื่อ sandbox เสร็จสิ้น: รีเฟรชรายการเวอร์ชัน versionsQuery.refetch(); @@ -285,24 +285,8 @@ export default function OcrSandboxPromptManager() { selectedPromptVersion ); toast.success('AI Extraction started'); - // Poll สำหรับผลลัพธ์ AI - const pollInterval = setInterval(async () => { - try { - const result = await adminAiService.getSandboxJobStatus(requestPublicId); - if (result.status === 'completed') { - clearInterval(pollInterval); - // Trigger sandbox state update via useSandboxRun - toast.success(t('ai.prompt.sandboxSuccess')); - versionsQuery.refetch(); - } else if (result.status === 'failed') { - clearInterval(pollInterval); - toast.error(result.errorMessage || 'AI Extraction failed'); - } - } catch (_err) { - clearInterval(pollInterval); - toast.error('Poll error occurred'); - } - }, 1000); + // เริ่ม polling ผ่าน useSandboxRun hook + startPolling(requestPublicId); } catch (err: unknown) { const error = err as { response?: { data?: { message?: string } } }; toast.error(error.response?.data?.message || 'AI Extraction failed'); diff --git a/frontend/hooks/use-ai-prompts.ts b/frontend/hooks/use-ai-prompts.ts index 3d58539d..44a48844 100644 --- a/frontend/hooks/use-ai-prompts.ts +++ b/frontend/hooks/use-ai-prompts.ts @@ -155,11 +155,24 @@ export function useSandboxRun(onCompleted?: () => void) { setJobId(response.requestPublicId); return response.requestPublicId; }, []); + /** + * เริ่ม polling สำหรับ jobId ที่มีอยู่แล้ว (สำหรับ 2-step flow) + * @param jobId - requestPublicId ของ job ที่ submit ไปแล้ว + */ + const startPolling = useCallback((jobIdParam: string) => { + setState({ + isRunning: true, + progress: 30, + statusText: 'ai.prompt.statusPending', + result: null, + }); + setJobId(jobIdParam); + }, []); /** รีเซ็ตสถานะทั้งหมด (ใช้ก่อนรันใหม่) */ const reset = useCallback(() => { if (timerRef.current) clearInterval(timerRef.current); setJobId(null); setState({ isRunning: false, progress: 0, statusText: '', result: null }); }, []); - return { state, jobId, submit, reset }; + return { state, jobId, submit, reset, startPolling }; } diff --git a/memory/agent-memory.md b/memory/agent-memory.md index e6645cb6..3cd4cfe0 100644 --- a/memory/agent-memory.md +++ b/memory/agent-memory.md @@ -14,6 +14,7 @@ - 2026-05-30 (Session 10): OCR Sandbox Two-Step Flow (ADR-030/231) — แยก OCR Sandbox เป็น 2 steps: Step 1 OCR-only → Step 2 AI Extraction. Backend: เพิ่ม job types sandbox-ocr-only และ sandbox-ai-extract, processors processSandboxOcrOnly/processSandboxAiExtract, endpoints POST /ai/admin/sandbox/ocr และ /ai/admin/sandbox/ai-extract, method findByVersion ใน AiPromptsService. Frontend: เพิ่ม methods submitSandboxOcr/submitSandboxAiExtract ใน adminAiService, refactor OcrSandboxPromptManager.tsx ให้มี 2-step UI พร้อม states sandboxStep/ocrResult/selectedPromptVersion, handlers handleStep1Ocr/handleStep2AiExtract/handleResetSandbox. Schema Fix: สร้าง delta SQL 2026-05-30-add-ai-prompts-publicId.sql เพื่อเพิ่ม publicId column ใน ai_prompts table (ADR-019 compliance). - 2026-05-30 (Session 11): Typhoon OCR & LLM Integration (ADR-032) — พัฒนาการใช้งานโมเดลภาษาไทยผสมอังกฤษ Typhoon OCR-3B ร่วมกับ Tesseract OCR แบบ Dynamic พร้อมระบบ caching 24 ชม., VRAM Monitor ป้องกัน GPU OOM และระบบ fallback 5s เมื่อโมเดลมีปัญหา และการสลับและบริหารจัดการ LLM โมเดลหลักแบบ Dynamic ในระบบ AI Model Management ของ Next.js frontend - 2026-06-03: Thai-Optimized AI Model Stack (ADR-034) — เปลี่ยนโมเดลหลักเป็น `typhoon2.5-np-dms:latest` + `typhoon-np-dms-ocr:latest` (สำหรับ OCR, keep_alive:0); เพิ่ม model switching logic ใน ai-batch processor; เพิ่ม static constants ใน AiSettingsService; สร้าง SQL delta สำหรับ ai_available_models +- 2026-06-05 (Session 12): Typhoon OCR Prompt Cleaning — แก้ปัญหา prompt/instruction ติดมาใน Typhoon OCR output โดยย้าย instruction จาก Modelfile SYSTEM มา prompt ใน app.py แทน ลบ clean_typhoon_output() filter downstream และแก้ git conflict โดยเลือกเวอร์ชัน local (ไม่มี SYSTEM instruction) --> # 🧠 Agent Long-term Project Memory diff --git a/specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/typhoon2.5-np-dms.model copy.md b/specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/typhoon2.5-np-dms.model copy.md new file mode 100644 index 00000000..90ba3e99 --- /dev/null +++ b/specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/typhoon2.5-np-dms.model copy.md @@ -0,0 +1,21 @@ +FROM scb10x/typhoon2.5-qwen3-4b:latest + +PARAMETER num_ctx 8192 +PARAMETER num_predict 4096 +PARAMETER temperature 0.1 +PARAMETER top_p 0.85 +PARAMETER repeat_penalty 1.15 + +SYSTEM """You are an AI system specialized in analyzing and managing project documents (Document Management System) + +Your role is to carefully read Thai text extracted from OCR systems and follow these instructions strictly: + +Guidelines: +- Input is raw OCR text which may contain spelling errors, missing lines, or noise characters +- Extract and identify 'Document Number' and 'Document Date' accurately. If not found, mark as 'Not Specified' +- Summarize the key content of this document concisely and clearly, using overall context for interpretation. If uncertain, mark status as "Unclear" +- Do NOT create or hallucinate data that does not exist in the original text +- Do NOT guess numbers, dates, or any information not explicitly visible in the raw text +- If information is incomplete, use null and provide reason in the _missing_fields field + +Return ONLY the specified JSON structure. Do NOT add any text outside the structure""" diff --git a/specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/typhoon2.5-np-dms.model.md b/specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/typhoon2.5-np-dms.model.md index 90ba3e99..71b109af 100644 --- a/specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/typhoon2.5-np-dms.model.md +++ b/specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/typhoon2.5-np-dms.model.md @@ -5,17 +5,3 @@ PARAMETER num_predict 4096 PARAMETER temperature 0.1 PARAMETER top_p 0.85 PARAMETER repeat_penalty 1.15 - -SYSTEM """You are an AI system specialized in analyzing and managing project documents (Document Management System) - -Your role is to carefully read Thai text extracted from OCR systems and follow these instructions strictly: - -Guidelines: -- Input is raw OCR text which may contain spelling errors, missing lines, or noise characters -- Extract and identify 'Document Number' and 'Document Date' accurately. If not found, mark as 'Not Specified' -- Summarize the key content of this document concisely and clearly, using overall context for interpretation. If uncertain, mark status as "Unclear" -- Do NOT create or hallucinate data that does not exist in the original text -- Do NOT guess numbers, dates, or any information not explicitly visible in the raw text -- If information is incomplete, use null and provide reason in the _missing_fields field - -Return ONLY the specified JSON structure. Do NOT add any text outside the structure"""