Files
JARVIS/backend/app/agents/orchestration/result_merge.py

70 lines
2.5 KiB
Python
Raw Normal View History

from __future__ import annotations
from app.agents.schemas.orchestration import MergeReport
from app.agents.verifier import normalize_task_result
def merge_task_results(task_results: list[dict] | list[object]) -> MergeReport:
normalized = [normalize_task_result(item) for item in (task_results or [])]
completed = [item for item in normalized if item.status == "completed"]
failed_or_blocked = [item for item in normalized if item.status in {"failed", "blocked"}]
evidence_union: list[dict] = []
summaries = []
for item in normalized:
evidence_union.extend(list(item.evidence or []))
if item.summary:
summaries.append(item.summary.strip())
unique_summaries = list(dict.fromkeys(summary for summary in summaries if summary))
conflict_flags: list[str] = []
status = "merged"
fallback_used = False
if failed_or_blocked:
status = "fallback"
fallback_used = True
conflict_flags.append(
"failed_or_blocked_tasks:" + ",".join(item.task_id for item in failed_or_blocked)
)
resolution_strategy = "serial_recovery"
resolved_summary = (
completed[-1].summary
if completed and completed[-1].summary
else None
)
elif len(unique_summaries) > 1 and len(completed) > 1:
status = "conflicted"
conflict_flags.append("multiple_distinct_completed_summaries")
resolution_strategy = "rank_by_evidence_count"
ranked = sorted(
completed,
key=lambda item: (len(item.evidence or []), bool(item.summary)),
reverse=True,
)
resolved_summary = ranked[0].summary if ranked and ranked[0].summary else None
else:
resolution_strategy = "evidence_union"
resolved_summary = unique_summaries[-1] if unique_summaries else None
if status == "merged":
summary = (
unique_summaries[-1]
if unique_summaries
else f"已收敛 {len(normalized)} 个子任务结果。"
)
elif status == "conflicted":
summary = "并行子任务摘要存在冲突,需要 verifier 或串行收敛。"
else:
summary = "存在失败或阻塞子任务,需要回退到更保守的收敛路径。"
return MergeReport(
status=status,
summary=summary,
evidence_union=evidence_union,
conflict_flags=conflict_flags,
resolution_strategy=resolution_strategy,
resolved_summary=resolved_summary,
fallback_used=fallback_used,
)