from __future__ import annotations from typing import Any from app.agents.schemas.learning import SessionRetrospective def _classify_task_type(query_text: str) -> str: normalized = (query_text or "").lower() if any(token in normalized for token in ("总结", "分析", "对比", "report", "analyze")): return "analysis" if any(token in normalized for token in ("安排", "提醒", "日程", "todo", "task")): return "planning_or_execution" if any(token in normalized for token in ("文档", "资料", "年报", "search", "查")): return "retrieval" return "general" def build_session_retrospective( *, request_id: str, session_id: str, user_query: str, state: dict[str, Any] | None, runtime_context: dict[str, Any] | None = None, ) -> SessionRetrospective: state = state or {} if hasattr(runtime_context, "model_dump"): runtime_context = runtime_context.model_dump(mode="json") runtime_context = runtime_context or {} skill_shortlist = state.get("skill_shortlist") or [] used_skill_names = [ item.get("skill_name") for item in skill_shortlist if isinstance(item, dict) and item.get("skill_name") ] task_refs = [] for task in (state.get("completed_tasks") or [])[:4]: if isinstance(task, dict): task_refs.append( { "task_id": task.get("task_id"), "title": task.get("title"), "status": task.get("status"), } ) event_refs = [] for event in (state.get("event_trace") or [])[:8]: if isinstance(event, dict): event_refs.append( { "event_type": event.get("event_type"), "task_id": event.get("task_id"), "agent_id": event.get("agent_id"), } ) verification_evidence = [] for evidence in (state.get("verification_evidence") or [])[:6]: if isinstance(evidence, dict): verification_evidence.append(evidence) verification_status = state.get("verification_status") execution_mode = state.get("execution_mode") primary_agent = state.get("current_agent") or "master" retrospective_shortlist = state.get("retrospective_shortlist") or [] summary_parts = [ f"本轮请求按 {execution_mode or 'unknown'} 模式处理", f"主要负责 agent 为 {primary_agent}", ] if verification_status: summary_parts.append(f"验证结果为 {verification_status}") if used_skill_names: summary_parts.append(f"命中技能候选 {', '.join(used_skill_names[:3])}") if retrospective_shortlist: summary_parts.append(f"参考了 {len(retrospective_shortlist)} 条历史复盘") final_response = state.get("final_response") outcome = "completed" if final_response else "failed" if not final_response and verification_status == "passed": outcome = "completed" if final_response and verification_status == "skipped": outcome = "partial" return SessionRetrospective( retrospective_id=request_id, user_id=str(runtime_context.get("user_id") or ""), conversation_id=session_id, response_message_id=request_id, query_text=user_query, final_response=final_response, summary=";".join(summary_parts) + "。", task_type=_classify_task_type(user_query), execution_mode=execution_mode, primary_agent=primary_agent, verification_status=verification_status, verification_summary=state.get("verification_summary"), used_skill_names=used_skill_names, evidence_refs=verification_evidence, task_refs=task_refs, event_refs=event_refs, context_snapshot={ "runtime_request_context": runtime_context, "recommended_runtime_mode": runtime_context.get("recommended_runtime_mode"), "parallel_worthiness": state.get("parallel_worthiness"), "retrospective_shortlist_count": len(retrospective_shortlist), "scheduled_subtask_count": len(state.get("scheduled_subtasks") or []), "merge_report": dict(state.get("merge_report") or {}), "verification_report": dict(state.get("verification_report") or {}), }, outcome=outcome, )