"""Prompt templates for DIFY AI report generation Contains the prompt construction logic for building the user query sent to DIFY Chat API. """ from typing import List, Dict, Any from datetime import datetime INCIDENT_TYPE_MAP = { "equipment_failure": "設備故障", "material_shortage": "物料短缺", "quality_issue": "品質問題", "other": "其他", } SEVERITY_MAP = { "low": "低", "medium": "中", "high": "高", "critical": "緊急", } STATUS_MAP = { "active": "處理中", "resolved": "已解決", "archived": "已封存", } MEMBER_ROLE_MAP = { "owner": "建立者", "editor": "編輯者", "viewer": "檢視者", } def build_report_prompt( room_data: Dict[str, Any], messages: List[Dict[str, Any]], members: List[Dict[str, Any]], files: List[Dict[str, Any]], ) -> str: """Build the complete prompt for DIFY report generation Args: room_data: Room metadata (title, type, severity, status, etc.) messages: List of messages with sender_name, content, created_at members: List of members with display_name, role files: List of files with filename, file_type, uploaded_at, uploader_name Returns: Formatted prompt string for DIFY API """ sections = [] # Section 1: Event Information sections.append(_format_room_info(room_data)) # Section 2: Participants sections.append(_format_members(members)) # Section 3: Message Timeline sections.append(_format_messages(messages)) # Section 4: File Attachments sections.append(_format_files(files)) # Section 5: Instructions sections.append(_format_instructions()) return "\n\n".join(sections) def _format_room_info(room_data: Dict[str, Any]) -> str: """Format room metadata section""" incident_type = INCIDENT_TYPE_MAP.get( room_data.get("incident_type"), room_data.get("incident_type") ) severity = SEVERITY_MAP.get(room_data.get("severity"), room_data.get("severity")) status = STATUS_MAP.get(room_data.get("status"), room_data.get("status")) created_at = room_data.get("created_at") if isinstance(created_at, datetime): created_at = created_at.strftime("%Y-%m-%d %H:%M") resolved_at = room_data.get("resolved_at") if isinstance(resolved_at, datetime): resolved_at = resolved_at.strftime("%Y-%m-%d %H:%M") elif resolved_at is None: resolved_at = "尚未解決" # Format LOT batch numbers lots = room_data.get('lots', []) lots_str = ", ".join(lots) if lots else "無" lines = [ "## 事件資訊", f"- 標題: {room_data.get('title', '未命名')}", f"- 類型: {incident_type}", f"- 嚴重程度: {severity}", f"- 目前狀態: {status}", f"- 發生地點: {room_data.get('location', '未指定')}", f"- 影響批號 (LOT): {lots_str}", f"- 建立時間: {created_at}", f"- 解決時間: {resolved_at}", ] if room_data.get("description"): lines.append(f"- 事件描述: {room_data['description']}") if room_data.get("resolution_notes"): lines.append(f"- 解決備註: {room_data['resolution_notes']}") return "\n".join(lines) def _format_members(members: List[Dict[str, Any]]) -> str: """Format participants section""" lines = ["## 參與人員"] if not members: lines.append("無參與人員記錄") return "\n".join(lines) for member in members: display_name = member.get("display_name") or member.get("user_id", "未知") role = MEMBER_ROLE_MAP.get(member.get("role"), member.get("role", "成員")) lines.append(f"- {display_name} ({role})") return "\n".join(lines) def _format_messages(messages: List[Dict[str, Any]]) -> str: """Format message timeline section""" lines = ["## 對話記錄"] if not messages: lines.append("無對話記錄") return "\n".join(lines) for msg in messages: sender = msg.get("sender_name") or msg.get("sender_id", "未知") content = msg.get("content", "") msg_type = msg.get("message_type", "text") created_at = msg.get("created_at") if isinstance(created_at, datetime): time_str = created_at.strftime("%Y-%m-%d %H:%M") else: time_str = str(created_at) if created_at else "未知時間" # Handle different message types if msg_type == "file": file_name = msg.get("file_name", "附件") lines.append(f"[{time_str}] {sender}: [上傳檔案: {file_name}]") elif msg_type == "image": lines.append(f"[{time_str}] {sender}: [上傳圖片]") elif msg_type == "system": lines.append(f"[{time_str}] [系統]: {content}") else: lines.append(f"[{time_str}] {sender}: {content}") return "\n".join(lines) def _format_files(files: List[Dict[str, Any]]) -> str: """Format file attachments section""" lines = ["## 附件清單"] if not files: lines.append("無附件") return "\n".join(lines) for f in files: filename = f.get("filename", "未命名檔案") file_type = f.get("file_type", "file") uploader = f.get("uploader_name") or f.get("uploaded_by", "未知") uploaded_at = f.get("uploaded_at") if isinstance(uploaded_at, datetime): time_str = uploaded_at.strftime("%Y-%m-%d %H:%M") else: time_str = str(uploaded_at) if uploaded_at else "" type_label = "圖片" if file_type == "image" else "檔案" lines.append(f"- [{type_label}] {filename} (由 {uploader} 於 {time_str} 上傳)") return "\n".join(lines) def _format_instructions() -> str: """Format generation instructions""" return """## 報告生成指示 請根據以上資料,生成一份結構化的事件報告。報告必須為 JSON 格式,包含以下欄位: 1. **summary**: 事件摘要 (50-300字) 2. **timeline**: 按時間順序的事件時間軸 3. **participants**: 參與人員及其角色 4. **resolution_process**: 詳細的處理過程描述 5. **current_status**: 目前狀態說明 6. **final_resolution**: 最終處置結果(若已解決) 請直接輸出 JSON,不要包含其他說明文字。"""