| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- from __future__ import annotations
- from typing import Any
- from .common import (
- EventLoader,
- decision_context,
- decision_event_refs,
- event_content,
- event_notices,
- event_unit,
- find_branch,
- find_by_id,
- find_detail,
- find_raw_branch,
- integer,
- load_events,
- suffix_int,
- )
- from .schema import field, payload
- def project_implementation_task(
- detail_ref: str,
- round_index: int,
- branch_id: int,
- bundle: dict[str, Any],
- view: dict[str, Any],
- load_event: EventLoader,
- ) -> dict[str, Any]:
- raw = find_raw_branch(bundle, branch_id) or {}
- branch = find_branch(view, round_index, branch_id) or {}
- stage = branch.get("retrievalStage") or {}
- implementer_id = integer(stage.get("implementerEventId"))
- events = load_events(load_event, [implementer_id] if implementer_id else [])
- full_task = _agent_task(events[0]) if events else None
- task_value = full_task or raw.get("impl_task") or raw.get("target")
- task_source = "runtime-event" if full_task else "database"
- task_source_label = "实现 Agent Event Body" if full_task else "script_build_branch(历史回退)"
- task_source_ref = f"event:{implementer_id}" if full_task and implementer_id else detail_ref
- inputs = [
- field(
- f"branch:{branch_id}:task",
- "完整实现任务",
- task_value,
- source_kind=task_source,
- source_label=task_source_label,
- source_ref=task_source_ref,
- field_path="input.content.task" if full_task else "impl_task",
- relation="direct-input",
- completeness="complete" if full_task else "partial" if task_value else "missing",
- ),
- field(
- f"branch:{branch_id}:path-type",
- "实现范围",
- raw.get("path_type"),
- source_kind="database",
- source_label="script_build_branch",
- source_ref=detail_ref,
- field_path="path_type",
- relation="standing-constraint",
- ),
- field(
- f"branch:{branch_id}:target",
- "实现目标",
- raw.get("target"),
- source_kind="database",
- source_label="script_build_branch",
- source_ref=detail_ref,
- field_path="target",
- relation="standing-constraint",
- ),
- ]
- notices = event_notices(events)
- if task_value and not full_task:
- notices.append({"level": "warning", "message": "未找到完整实现 Agent 输入,当前使用 Branch 字段作历史回退。"})
- return payload(
- "implementation-task",
- "single-event" if events else "business-record",
- inputs=inputs,
- units=[event_unit(item, label="实现 Agent") for item in events],
- outputs=[],
- runtime_summary="任务作为实现 Agent 的完整输入执行。" if events else "该历史记录没有可用的实现 Agent Event Body。",
- notices=notices,
- completeness="complete" if full_task else "partial" if task_value else "missing",
- business_modules=[
- # The readable Inspector sections are parsed from the complete
- # implementer task. Keep all six source modules on that exact
- # Event input so the source Inspector can bind every displayed
- # section to a text span. Branch.target remains available to the
- # canvas summary below, but must not masquerade as the section's
- # original source.
- {"id": "scope", "title": "实现范围", "sourceIds": [inputs[0]["id"]]},
- {"id": "method", "title": "实施方法", "sourceIds": [inputs[0]["id"]]},
- {"id": "goal", "title": "完整目标", "sourceIds": [inputs[0]["id"]]},
- {"id": "constraints", "title": "参考依据与约束", "sourceIds": [inputs[0]["id"]]},
- {"id": "avoid", "title": "需要避免", "sourceIds": [inputs[0]["id"]]},
- {"id": "deliverable", "title": "预期交付", "sourceIds": [inputs[0]["id"]]},
- ],
- card_fields=[
- {"key": "scope", "label": "范围", "sourceIds": [inputs[2]["id"]], "transform": "直接使用结构化 target"},
- {"key": "method", "label": "方法", "sourceIds": [inputs[0]["id"]], "transform": "使用任务中的实施方法段"},
- {"key": "target", "label": "目标", "sourceIds": [inputs[2]["id"], inputs[0]["id"]], "transform": "优先结构化 target"},
- ],
- )
- def project_data_decision(
- detail_ref: str,
- bundle: dict[str, Any],
- view: dict[str, Any],
- load_event: EventLoader,
- ) -> dict[str, Any]:
- record_id = suffix_int(detail_ref)
- row = find_by_id(bundle.get("dataDecisions") or [], record_id)
- if row is None:
- raise KeyError(detail_ref)
- node = find_detail(view, detail_ref)
- context = decision_context(node)
- events = load_events(load_event, decision_event_refs(context))
- sources = row.get("sources") if isinstance(row.get("sources"), list) else []
- inputs = [
- field(
- f"data-decision:{record_id}:source:{index}",
- f"参与判断的数据 {index}",
- source,
- source_kind="database",
- source_label="script_build_data_decision.sources",
- source_ref=detail_ref,
- field_path=f"sources[{index - 1}]",
- relation="explicit-basis",
- )
- for index, source in enumerate(sources, 1)
- ]
- outputs = [
- field(f"data-decision:{record_id}:decision", "明确取舍", row.get("decision"), source_kind="database", source_label="script_build_data_decision", source_ref=detail_ref, field_path="decision", relation="persisted-output"),
- field(f"data-decision:{record_id}:reasoning", "取舍理由", row.get("reasoning"), source_kind="database", source_label="script_build_data_decision", source_ref=detail_ref, field_path="reasoning", relation="persisted-output"),
- ]
- return payload(
- "data-decision",
- "business-record",
- inputs=inputs,
- units=[event_unit(item) for item in events],
- outputs=outputs,
- runtime_summary="这是独立落库的业务取舍记录;不伪造一次不存在的 Agent I/O。",
- notices=event_notices(events) + ([] if events else [{"level": "info", "message": "未找到能与该取舍记录一对一安全关联的运行事件。"}]),
- completeness="complete" if row.get("decision") and sources else "partial",
- business_modules=[
- {"id": "sources", "title": "参与判断的数据", "sourceIds": [item["id"] for item in inputs]},
- {"id": "tradeoff", "title": "采用 / 组合 / 舍弃", "sourceIds": [outputs[0]["id"]]},
- {"id": "decision", "title": "明确取舍", "sourceIds": [outputs[0]["id"]]},
- {"id": "reason", "title": "理由", "sourceIds": [outputs[1]["id"]]},
- {"id": "source-completeness", "title": "来源完整性", "sourceIds": [item["id"] for item in inputs]},
- ],
- card_fields=[
- {"key": "conclusion", "label": "取舍结论", "sourceIds": [outputs[0]["id"]], "transform": "直接使用业务记录"},
- {"key": "sourceCount", "label": "来源数", "sourceIds": [item["id"] for item in inputs], "transform": "明确来源数量"},
- {"key": "reason", "label": "核心理由", "sourceIds": [outputs[1]["id"]], "transform": "使用结构化理由"},
- ],
- )
- def project_creative(
- detail_ref: str,
- bundle: dict[str, Any],
- view: dict[str, Any],
- load_event: EventLoader,
- ) -> dict[str, Any]:
- node = find_detail(view, detail_ref)
- if node is None:
- raise KeyError(detail_ref)
- context = decision_context(node)
- seed_id = suffix_int(detail_ref)
- seed = find_by_id(bundle.get("events") or [], seed_id)
- round_index = integer((seed or {}).get("round_index"))
- branch_id = integer((seed or {}).get("branch_id"))
- refs = decision_event_refs(context)
- if seed_id is not None:
- refs.append(f"event:{seed_id}")
- # Explicit round/branch/scope metadata is safe lineage. It also captures
- # script mutation calls omitted by the old think_and_plan-only refs.
- implementer_ids = {
- integer(item.get("id"))
- for item in bundle.get("events") or []
- if item.get("event_name") == "script_implementer"
- and integer(item.get("round_index")) == round_index
- and integer(item.get("branch_id")) == branch_id
- }
- for item in bundle.get("events") or []:
- if integer(item.get("round_index")) != round_index or integer(item.get("branch_id")) != branch_id:
- continue
- if integer(item.get("scope_event_id")) in implementer_ids or integer(item.get("id")) in implementer_ids:
- refs.append(f"event:{item.get('id')}")
- events = load_events(load_event, refs)
- raw_branch = find_raw_branch(bundle, branch_id or -1) or {}
- candidate = raw_branch.get("candidate_snapshot") or {}
- snapshot = candidate.get("snapshot") if isinstance(candidate, dict) else None
- visible_inputs = []
- for index, source in enumerate(context.get("evidence") or context.get("inputs") or [], 1):
- if not isinstance(source, dict):
- continue
- observed = str(source.get("observedRelation") or "")
- relation = "direct-input" if observed == "read-by-actor" else "previous-result" if observed == "returned-to-actor" else "available-upstream"
- visible_inputs.append(field(f"creative:{seed_id}:input:{index}", str(source.get("label") or f"创作依据 {index}"), source.get("summary") or source.get("value"), source_kind="runtime-event" if source.get("detailRef") else "database", source_label="实现过程中可确认的数据", source_ref=source.get("detailRef"), field_path="output.content" if source.get("detailRef") else "", relation=relation))
- explicit_basis = [
- field(
- f"creative:{seed_id}:explicit-basis:{index}",
- str(item.get("label") or f"明确采用的数据取舍 {index}"),
- {"decision": item.get("label"), "reasoning": item.get("value")},
- source_kind="database",
- source_label="script_build_data_decision",
- source_ref=item.get("detailRef"),
- field_path="",
- relation="explicit-basis",
- )
- for index, item in enumerate(context.get("explicitBasis") or [], 1)
- if isinstance(item, dict) and str(item.get("detailRef") or "").startswith("data-decision:")
- ]
- change_fields = [
- field(
- f"creative:{seed_id}:change:{index}",
- str(item.get("label") or f"脚本改动 {index}"),
- {"status": item.get("value"), "note": item.get("note")},
- source_kind="runtime-event",
- source_label="脚本修改运行事件",
- source_ref=item.get("detailRef"),
- field_path="",
- relation="run-output",
- )
- for index, item in enumerate(context.get("runtimeActions") or [], 1)
- if isinstance(item, dict) and str(item.get("detailRef") or "").startswith("event:")
- ]
- outputs = [
- field(f"creative:{seed_id}:snapshot", "产出的候选表", snapshot, source_kind="artifact", source_label="候选分支快照", source_ref=f"artifact:branch:{branch_id}" if branch_id else None, field_path="candidate_snapshot.snapshot", relation="persisted-output", completeness="complete" if snapshot else "missing"),
- field(f"creative:{seed_id}:assessment", "实现者自评", raw_branch.get("self_assessment"), source_kind="database", source_label="script_build_branch", source_ref=f"round:{round_index}:branch:{branch_id}:output", field_path="self_assessment", relation="persisted-output"),
- ]
- notices = event_notices(events)
- if visible_inputs:
- notices.append({"level": "info", "message": "可确认是上游信息,但无法确认是否被本次决策采用。"})
- if not events:
- notices.append({"level": "warning", "message": "候选产出存在,但未保存可安全关联的完整创作过程。"})
- card_kind = "creative" if events else "candidate-output-fallback"
- return payload(
- card_kind,
- "event-sequence" if events else "business-record",
- inputs=[*visible_inputs, *explicit_basis],
- units=[event_unit(item) for item in events],
- outputs=[*outputs, *change_fields],
- runtime_summary=(f"按明确的轮次、分支和实现 Agent scope 串起 {len(events)} 个创作/修改事件。" if events else "只能展示候选快照和实现者自评。"),
- notices=notices,
- completeness="complete" if events and snapshot else "partial" if snapshot or raw_branch.get("self_assessment") else "missing",
- business_modules=[
- {"id": "process", "title": "创作处理", "sourceIds": []},
- {"id": "basis", "title": "明确采用的数据取舍", "sourceIds": [item["id"] for item in explicit_basis]},
- {"id": "available", "title": "可确认的上游信息", "sourceIds": [item["id"] for item in visible_inputs]},
- {"id": "changes", "title": "实际脚本改动", "sourceIds": [item["id"] for item in change_fields]},
- {"id": "candidate", "title": "产出的候选表", "sourceIds": [outputs[0]["id"]]},
- {"id": "uncertainty", "title": "存疑项 / 完整性", "sourceIds": [outputs[1]["id"]]},
- ],
- )
- def project_multipath_decision(
- detail_ref: str,
- bundle: dict[str, Any],
- view: dict[str, Any],
- load_event: EventLoader,
- ) -> dict[str, Any]:
- record_id = suffix_int(detail_ref)
- row = find_by_id(bundle.get("multipathDecisions") or [], record_id)
- if row is None:
- raise KeyError(detail_ref)
- node = find_detail(view, detail_ref)
- context = decision_context(node)
- events = load_events(load_event, decision_event_refs(context))
- branch_ids = row.get("branch_ids") if isinstance(row.get("branch_ids"), list) else []
- inputs = [field(f"multipath:{record_id}:branch:{branch_id}", f"候选方案 {branch_id}", find_raw_branch(bundle, integer(branch_id) or -1), source_kind="database", source_label="script_build_branch", source_ref=f"round:{row.get('round_index')}:branch:{branch_id}", field_path="", relation="available-upstream") for branch_id in branch_ids]
- review_events = [
- item for item in bundle.get("events") or []
- if item.get("event_name") == "script_multipath_evaluator"
- and integer(item.get("round_index")) == integer(row.get("round_index"))
- ]
- attached_ids = {integer(item.get("id")) for item in events}
- unscoped_reviews = [item for item in review_events if integer(item.get("id")) not in attached_ids]
- for item in unscoped_reviews:
- inputs.append(field(f"multipath:{record_id}:review:{item.get('id')}", "同轮多方案评审", item.get("agentOutputData") or item.get("output_preview"), source_kind="runtime-event", source_label="同轮评审事件(候选范围未安全关联)", source_ref=f"event:{item.get('id')}", field_path="output", relation="available-upstream", completeness="partial"))
- outputs = [
- field(f"multipath:{record_id}:decision", "最终决定", row.get("decision"), source_kind="database", source_label="script_build_multipath_decision", source_ref=detail_ref, field_path="decision", relation="persisted-output"),
- field(f"multipath:{record_id}:reasoning", "决策理由", row.get("reasoning"), source_kind="database", source_label="script_build_multipath_decision", source_ref=detail_ref, field_path="reasoning", relation="persisted-output"),
- ]
- notices = event_notices(events)
- notices.append({"level": "info", "message": "候选分支可确认是本次取舍对象;除非有明确评审关联,不宣称其内容已被采用。"})
- if unscoped_reviews:
- notices.append({"level": "warning", "message": "发现同轮评审,但无法安全关联到具体候选。"})
- return payload(
- "multipath-decision",
- "business-record",
- inputs=inputs,
- units=[event_unit(item) for item in events],
- outputs=outputs,
- runtime_summary="主 Agent 多路决策以业务表为最终事实,评审 Event 只在有可靠关联时作为明确依据。",
- notices=notices,
- completeness="complete" if row.get("decision") and branch_ids else "partial",
- business_modules=[
- {"id": "scope", "title": "取舍对象", "sourceIds": [item["id"] for item in inputs if ":branch:" in item["id"]]},
- {"id": "comparison", "title": "评审建议与最终决定", "sourceIds": [item["id"] for item in inputs if ":review:" in item["id"]] + [outputs[0]["id"]]},
- {"id": "outcomes", "title": "逐方案处置", "sourceIds": [item["id"] for item in inputs if ":branch:" in item["id"]]},
- {"id": "reason", "title": "决策理由", "sourceIds": [outputs[1]["id"]]},
- {"id": "strength", "title": "关联强度", "sourceIds": [item["id"] for item in inputs]},
- ],
- )
- def project_branch_output(
- detail_ref: str,
- round_index: int,
- branch_id: int,
- bundle: dict[str, Any],
- view: dict[str, Any],
- ) -> dict[str, Any]:
- raw = find_raw_branch(bundle, branch_id)
- branch = find_branch(view, round_index, branch_id)
- if raw is None or branch is None:
- raise KeyError(detail_ref)
- output = branch.get("output") or {}
- if output.get("type") == "domain-info":
- facts = [
- item for item in bundle.get("domainInfo") or []
- if integer(item.get("branch_id")) == branch_id
- ]
- outputs = [field(f"branch:{branch_id}:facts", "已核实领域事实", facts, source_kind="database", source_label="script_build_domain_info", source_ref=detail_ref, field_path="domainInfo", relation="persisted-output")]
- return payload(
- "domain-facts",
- "aggregate",
- outputs=outputs,
- runtime_summary="按 branch_id 聚合该领域信息方案写入的事实。",
- calculation="只按显式 branch_id 关联,不使用文本相似度。",
- # A successful branch-scoped lookup returning zero rows is a
- # complete empty result, not a missing source record.
- completeness="complete",
- business_modules=[
- {"id": "facts", "title": "已核实事实", "sourceIds": [outputs[0]["id"]]},
- {"id": "verification", "title": "核实说明", "sourceIds": [outputs[0]["id"]]},
- {"id": "sources", "title": "出处", "sourceIds": [outputs[0]["id"]]},
- {"id": "usage", "title": "用途与存疑状态", "sourceIds": [outputs[0]["id"]]},
- ],
- )
- candidate = raw.get("candidate_snapshot") or {}
- snapshot = candidate.get("snapshot") if isinstance(candidate, dict) else None
- outputs = [
- field(f"branch:{branch_id}:candidate", "形成了什么", snapshot, source_kind="artifact", source_label="候选分支快照", source_ref=f"artifact:branch:{branch_id}", field_path="candidate_snapshot.snapshot", relation="persisted-output", completeness="complete" if snapshot else "missing"),
- field(f"branch:{branch_id}:assessment", "实现者自评", raw.get("self_assessment"), source_kind="database", source_label="script_build_branch", source_ref=detail_ref, field_path="self_assessment", relation="persisted-output"),
- ]
- return payload(
- "candidate-output-fallback",
- "business-record",
- outputs=outputs,
- runtime_summary="候选产出回退详情只展示候选快照和自评,不伪造未保存的创作过程。",
- notices=[{"level": "warning", "message": "未保存可安全关联的完整创作过程。"}],
- completeness="partial" if snapshot or raw.get("self_assessment") else "missing",
- business_modules=[
- {"id": "output", "title": "形成了什么", "sourceIds": [outputs[0]["id"]]},
- {"id": "assessment", "title": "实现者自评", "sourceIds": [outputs[1]["id"]]},
- {"id": "missing", "title": "创作过程缺失说明", "sourceIds": [item["id"] for item in outputs]},
- ],
- )
- def project_domain_info(detail_ref: str, bundle: dict[str, Any]) -> dict[str, Any]:
- record_id = suffix_int(detail_ref)
- row = find_by_id(bundle.get("domainInfo") or [], record_id)
- if row is None:
- raise KeyError(detail_ref)
- outputs = [
- field(f"domain:{record_id}:fact", "已核实事实", row.get("content"), source_kind="database", source_label="script_build_domain_info", source_ref=detail_ref, field_path="content", relation="persisted-output"),
- field(f"domain:{record_id}:note", "核实说明", row.get("note"), source_kind="database", source_label="script_build_domain_info", source_ref=detail_ref, field_path="note", relation="persisted-output"),
- field(f"domain:{record_id}:source", "信息出处", row.get("source"), source_kind="database", source_label="script_build_domain_info", source_ref=detail_ref, field_path="source", relation="persisted-output"),
- ]
- return payload(
- "domain-fact",
- "business-record",
- outputs=outputs,
- runtime_summary="这是独立落库的已核实领域事实。",
- completeness="complete" if row.get("content") and row.get("source") else "partial",
- business_modules=[
- {"id": "fact", "title": "已核实事实", "sourceIds": [outputs[0]["id"]]},
- {"id": "verification", "title": "核实说明", "sourceIds": [outputs[1]["id"]]},
- {"id": "source", "title": "出处", "sourceIds": [outputs[2]["id"]]},
- {"id": "usage", "title": "用途与存疑状态", "sourceIds": [item["id"] for item in outputs]},
- ],
- )
- def _agent_task(event: dict[str, Any]) -> Any:
- content = event_content(event.get("input"))
- return content.get("task") if isinstance(content, dict) else content
|