from __future__ import annotations from .shared import * class FeishuReplyTemplatesMixin: @staticmethod def _build_butler_decision_reply(capture_result: Dict[str, Any]) -> Optional[str]: if not isinstance(capture_result, dict): return None status = str(capture_result.get("status") or "").strip().lower() if status != "captured": return None results = capture_result.get("results") if not isinstance(results, list) or not results: return None auto_results = [row for row in results if str((row or {}).get("route_status") or "") == "auto_processed"] pending_results = [row for row in results if str((row or {}).get("route_status") or "") == "pending"] classification = str(capture_result.get("classification") or "signal").strip().lower() signal_id = str(capture_result.get("signal_id") or "").strip() linked_project_ids = capture_result.get("linked_project_ids") or [] project_hint = "" if isinstance(linked_project_ids, list) and linked_project_ids: project_hint = f",并关联项目 #{linked_project_ids[0]}" if pending_results: if classification in {"project", "new_project"}: return ( "我已先完成项目候选入队,当前有不确定项需要你确认:" "1) 归属项目/是否新建 2) 优先级 3) 截止时间。" "确认后我会自动继续推进。" ) return ( "我已先完成信号入队,当前判断存在不确定项(多半是项目归属或范围边界)。" "请你补充:归属项目、优先级、期望完成时间,我会立即自动续跑。" ) if auto_results: if classification in {"project", "new_project"}: return ( f"已自动完成项目流处理{project_hint}。" "后续我会继续按管家流程拆解与分派,除非你要求人工接管。" ) if signal_id: return ( f"已自动完成信号流处理(信号#{signal_id}{project_hint})。" "这是明确需求场景,我会继续自动推进后续动作。" ) return "已自动完成信号流处理。后续我会继续自动推进,只有不确定项才会向你确认。" return None @staticmethod def _build_execution_receipt_reply( *, message_content: Optional[str], capture_result: Dict[str, Any], ) -> Optional[str]: """ 对“已执行”场景优先给简短回执,避免 LLM 输出教程式长文或二次处理建议。 """ if not isinstance(capture_result, dict): return None status = str(capture_result.get("status") or "").strip().lower() if status not in {"captured", "ignored"}: return None if status == "ignored": reason = str(capture_result.get("reason") or "").strip().lower() if reason == "duplicate_filtered": return "这条消息我已处理过,未重复入库。" if reason in {"non_requirement_noise", "empty_or_emoji_only"}: return "这条消息不是可执行需求,我没有入库。请直接说要新增什么信号或任务。" return "这条消息已忽略(未入库)。如需执行,请明确目标、对象和动作。" text = str(message_content or "").strip() strict_keywords = ("单独信号源", "单个信号源", "只入库", "仅入库", "不需要二次处理") strict_mode = any(k in text for k in strict_keywords) primary_route_status = "" results = capture_result.get("results") if isinstance(results, list) and results: first = results[0] if isinstance(results[0], dict) else {} primary_route_status = str((first or {}).get("route_status") or "").strip().lower() if primary_route_status == "auto_done" or primary_route_status == "auto_processed": return "已自动处理完成并入库,后续动作已继续自动推进。" if primary_route_status == "confirmed": return "已按确认结果执行并入库。" if primary_route_status in {"queued_for_decision", "pending"}: clarification_message = str(capture_result.get("clarification_message") or "").strip() if clarification_message: return clarification_message return "已完成入库,当前进入待确认队列。" if primary_route_status == "dismissed": return "该消息已记录,但当前标记为忽略,不会继续执行。" if primary_route_status == "failed": return "未执行:受控执行器拒绝了这次动作,请补充缺失字段或检查项目上下文。" if primary_route_status == "undone": return "上一次自动结果已撤销,当前不会继续执行。" signal_id = str(capture_result.get("signal_id") or "").strip() linked_project_ids = capture_result.get("linked_project_ids") project_id: Optional[str] = None if isinstance(linked_project_ids, list) and linked_project_ids: project_id = str(linked_project_ids[0]).strip() or None if not project_id: candidate = capture_result.get("created_project_id") if candidate is not None: project_id = str(candidate).strip() or None if signal_id and project_id: if strict_mode: return f"已按你的要求仅执行入库:信号#{signal_id},项目#{project_id}。" return f"已执行完成:信号#{signal_id} 已入库并关联项目#{project_id}。" if signal_id: if strict_mode: return f"已按你的要求仅执行入库:信号#{signal_id}。" return f"已执行完成:信号#{signal_id} 已入库。" if project_id: if strict_mode: return f"已按你的要求执行:项目#{project_id} 已关联。" return f"已执行完成:已关联项目#{project_id}。" return "已执行完成。"