Files
JARVIS/backend/app/agents/learning/retrospector.py

116 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
)