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, )