70 lines
2.5 KiB
Python
70 lines
2.5 KiB
Python
|
|
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,
|
||
|
|
)
|