from __future__ import annotations from collections import Counter from typing import Any from .common import ( EventLoader, decision_context, decision_event_refs, event_notices, event_unit, find_round, load_events, ) from .schema import field, payload def project_round_result( detail_ref: str, round_index: int, bundle: dict[str, Any], view: dict[str, Any], load_event: EventLoader, ) -> dict[str, Any]: round_ = find_round(view, round_index) if round_ is None: raise KeyError(detail_ref) branches = round_.get("branches") or [] result = round_.get("result") or {} evaluation = round_.get("overallEvaluation") or {} events = load_events(load_event, decision_event_refs(decision_context(evaluation))) domain_rows = [ item for item in bundle.get("domainInfo") or [] if int(item.get("round_index") or 0) == round_index ] statuses = Counter(str(item.get("status") or "unknown") for item in branches) inputs = [ field(f"round:{round_index}:result:goal", "本轮目标", ((round_.get("goal") or {}).get("card") or {}).get("primary", {}).get("value"), source_kind="database", source_label="script_build_round", source_ref=f"round:{round_index}:goal", field_path="goal", relation="standing-constraint"), field(f"round:{round_index}:result:review", "整体评审", evaluation, source_kind="runtime-event", source_label="整体评审运行事件", source_ref=evaluation.get("detailRef"), relation="explicit-basis", completeness="complete" if evaluation.get("detailRef") else "partial"), ] outputs = [ field(f"round:{round_index}:result:summary", "本轮目标完成情况", (result.get("card") or {}).get("primary", {}).get("value"), source_kind="calculation", source_label="本轮业务记录聚合", source_ref=detail_ref, field_path="result.card.primary", relation="persisted-output"), field(f"round:{round_index}:result:dispositions", "方案处置", dict(statuses), source_kind="calculation", source_label="分支状态统计", source_ref=detail_ref, field_path="branches.status", relation="persisted-output"), field(f"round:{round_index}:result:domain", "领域事实", domain_rows, source_kind="calculation", source_label="按 round_index 筛选 script_build_domain_info", source_ref=detail_ref, field_path="", relation="persisted-output", completeness="complete"), field(f"round:{round_index}:result:changes", "主脚本变化", [item.get("output") for item in branches if item.get("output")], source_kind="calculation", source_label="候选处置与当前产物聚合", source_ref=f"artifact:round:{round_index}", field_path="branches[].output", relation="persisted-output"), field(f"round:{round_index}:result:next", "下一步", next((item.get("value") for item in (result.get("card") or {}).get("secondary") or [] if item.get("key") == "next"), None), source_kind="calculation", source_label="本轮状态与下一轮记录", source_ref=detail_ref, field_path="result.card.secondary.next", relation="persisted-output"), ] same_round_reviews = [ item for item in bundle.get("events") or [] if item.get("event_name") == "script_evaluator" and int(item.get("round_index") or 0) == round_index ] notices = event_notices(events) if not events and same_round_reviews: notices.append({"level": "warning", "message": "发现同轮评审,但无法安全关联到具体候选。"}) return payload( "round-result", "calculated", inputs=inputs, units=[event_unit(item) for item in events], outputs=outputs, runtime_summary="本轮产出由候选分支处置、领域事实、整体评审和下一轮状态计算聚合。", calculation="按 round_index 聚合 Branch、DomainInfo、Evaluation 和下一轮记录;不伪造独立 Agent I/O。", notices=notices, completeness="complete" if outputs[0]["value"] else "partial", business_modules=[ {"id": "completion", "title": "本轮目标完成情况", "sourceIds": [inputs[0]["id"], outputs[0]["id"]]}, {"id": "dispositions", "title": "方案处置", "sourceIds": [outputs[1]["id"]]}, {"id": "domain", "title": "领域事实", "sourceIds": [outputs[2]["id"]]}, {"id": "review", "title": "整体评审", "sourceIds": [inputs[1]["id"]]}, {"id": "changes", "title": "主脚本变化", "sourceIds": [outputs[3]["id"]]}, {"id": "next", "title": "下一步", "sourceIds": [outputs[4]["id"]]}, ], card_fields=[ {"key": "status", "label": "状态", "sourceIds": [outputs[0]["id"]], "transform": "使用轮次业务状态"}, {"key": "accepted", "label": "采用数", "sourceIds": [outputs[1]["id"]], "transform": "merged 计数"}, {"key": "next", "label": "下一步", "sourceIds": [outputs[4]["id"]], "transform": "直接使用结构化下一步"}, ], ) def project_final_result( detail_ref: str, bundle: dict[str, Any], view: dict[str, Any] ) -> dict[str, Any]: record = bundle.get("record") or {} final = view.get("finalResult") or {} artifact = bundle.get("currentArtifact") or {} paragraphs = artifact.get("paragraphs") or [] elements = artifact.get("elements") or [] links = artifact.get("paragraphElements") or artifact.get("paragraph_elements") or [] branches = bundle.get("branches") or [] status_counts = Counter(str(item.get("status") or "unknown") for item in branches) outputs = [ field("final:status", "构建结论", record.get("status"), source_kind="database", source_label="script_build_record", source_ref=detail_ref, field_path="status", relation="persisted-output"), field("final:summary", "摘要", record.get("summary") or record.get("error_message"), source_kind="database", source_label="script_build_record", source_ref=detail_ref, field_path="summary" if record.get("summary") else "error_message", relation="persisted-output"), field("final:rounds", "轮次与方案统计", {"roundCount": len(bundle.get("rounds") or []), "branchCounts": dict(status_counts)}, source_kind="calculation", source_label="Round / Branch 记录计数", source_ref=detail_ref, field_path="rounds / branches", relation="persisted-output"), field("final:artifact-scale", "最终脚本规模", {"paragraphs": len(paragraphs), "elements": len(elements), "links": len(links)}, source_kind="artifact", source_label="当前主脚本", source_ref="artifact:base:current", field_path="recordCounts", relation="persisted-output"), field("final:artifact", "主脚本入口", "artifact:base:current", source_kind="artifact", source_label="当前主脚本", source_ref="artifact:base:current", field_path="snapshotRef", relation="persisted-output"), field("final:version", "版本说明", "当前保存的最终主脚本,不是历史轮次快照。", source_kind="calculation", source_label="产物精度规则", source_ref="artifact:base:current", field_path="historicalVersion", relation="persisted-output"), ] return payload( "final-result", "calculated", inputs=[], units=[], outputs=outputs, runtime_summary="最终结果是 Run 记录、全部轮次/分支和当前主脚本的计算聚合。", calculation="直接读取 Run 状态与摘要,对 Round / Branch / Artifact 做确定性计数。", notices=[] if artifact else [{"level": "warning", "message": "未找到当前主脚本产物。"}], completeness="complete" if record and artifact else "partial" if record else "missing", business_modules=[ {"id": "conclusion", "title": "构建结论", "sourceIds": [outputs[0]["id"]]}, {"id": "summary", "title": "摘要或失败原因", "sourceIds": [outputs[1]["id"]]}, {"id": "stats", "title": "轮次与方案统计", "sourceIds": [outputs[2]["id"]]}, {"id": "scale", "title": "最终脚本规模", "sourceIds": [outputs[3]["id"]]}, {"id": "artifact", "title": "主脚本入口", "sourceIds": [outputs[4]["id"]]}, {"id": "version", "title": "版本说明", "sourceIds": [outputs[5]["id"]]}, ], card_fields=[ {"key": "status", "label": "状态", "sourceIds": [outputs[0]["id"]], "transform": "直接使用 Run 状态"}, {"key": "summary", "label": "摘要", "sourceIds": [outputs[1]["id"]], "transform": "优先 summary,失败时使用 error_message"}, {"key": "scriptScale", "label": "脚本规模", "sourceIds": [outputs[3]["id"]], "transform": "段落/元素/关联计数"}, ], )