Преглед на файлове

feat(agentpaas): 展示科研假设与候选验证入口

科研决策材料现已包含证据缺口和候选检查,终端需要区分规划数量与实际执行结果。

- 在工具返回文本和终端卡片中展示假设数、候选检查数与决策产物入口
- 明确候选检查不代表已执行实验或独立验收,保留旧结果兼容性
- 客户端回归 84 项、终端卡片测试 19 项通过,两个包类型检查通过
邵勃源 преди 1 ден
родител
ревизия
2b78dc52ba

+ 2 - 0
.opencode/lib/agentpaas.ts

@@ -398,6 +398,7 @@ export function formatRunResult(agentName: string, run: Record<string, unknown>,
   const synthesis = asRecord(science?.synthesis)
   const synthesis = asRecord(science?.synthesis)
   const researchIR = asRecord(science?.research_ir)
   const researchIR = asRecord(science?.research_ir)
   const observations = asRecord(science?.observations)
   const observations = asRecord(science?.observations)
+  const decisionSupport = asRecord(science?.decision_support)
   const irLabels: Record<string, string> = {
   const irLabels: Record<string, string> = {
     not_executed: "本轮未执行", not_compiled: "尚未编译", plans_only: "仅规划", blocked: "暂不能执行", ready: "可执行",
     not_executed: "本轮未执行", not_compiled: "尚未编译", plans_only: "仅规划", blocked: "暂不能执行", ready: "可执行",
     executed: "实验子程序已执行", reused_observations: "复用观察", failed: "执行失败", cancelled: "已取消",
     executed: "实验子程序已执行", reused_observations: "复用观察", failed: "执行失败", cancelled: "已取消",
@@ -433,6 +434,7 @@ export function formatRunResult(agentName: string, run: Record<string, unknown>,
       ...(asRecord(acceptance?.plan_review)?.status === "not_reassessed" ? ["原方案:本次未重审,原有待修订项继续保留;review-parent-gate.json。"] : []),
       ...(asRecord(acceptance?.plan_review)?.status === "not_reassessed" ? ["原方案:本次未重审,原有待修订项继续保留;review-parent-gate.json。"] : []),
       ...(synthesis ? [`结果综合:${({ reviewed: "模型复核通过", needs_revision: "解释待修订", review_pending: "待复核", uncertain: "存在不确定项" } as Record<string, string>)[getString(synthesis.status)] || "状态待核查"};${synthesis.answered ?? "未报告"}/${synthesis.total ?? "未报告"} 项限定范围回答;不是独立科学验收。详情见 research-synthesis.json。`] : []),
       ...(synthesis ? [`结果综合:${({ reviewed: "模型复核通过", needs_revision: "解释待修订", review_pending: "待复核", uncertain: "存在不确定项" } as Record<string, string>)[getString(synthesis.status)] || "状态待核查"};${synthesis.answered ?? "未报告"}/${synthesis.total ?? "未报告"} 项限定范围回答;不是独立科学验收。详情见 research-synthesis.json。`] : []),
       ...(getString(science?.next_step) ? [`下一步研究:${getString(science?.next_step)}`] : []),
       ...(getString(science?.next_step) ? [`下一步研究:${getString(science?.next_step)}`] : []),
+      ...(decisionSupport ? [`验证选择:${decisionSupport.hypotheses ?? "未报告"} 个假设、${decisionSupport.candidate_checks ?? "未报告"} 项候选检查;依据与缺口见 research-decisions.json,不代表已执行或独立验收。`] : []),
       ...(observations ? [`观察记录:${observations.recorded ?? "未报告"} 份;已解释 ${observations.interpreted ?? "未报告"} 份;模型审阅认可 ${observations.reviewed ?? "未报告"} 份。详情见 observation-ledger.json。`] : []),
       ...(observations ? [`观察记录:${observations.recorded ?? "未报告"} 份;已解释 ${observations.interpreted ?? "未报告"} 份;模型审阅认可 ${observations.reviewed ?? "未报告"} 份。详情见 observation-ledger.json。`] : []),
       ...(researchIR ? [
       ...(researchIR ? [
         `科研 IR:${irLabels[getString(researchIR.status)] || "状态待核查"};本轮已执行 ${researchIR.executed_kernels ?? "未报告"} 个实验子程序。`,
         `科研 IR:${irLabels[getString(researchIR.status)] || "状态待核查"};本轮已执行 ${researchIR.executed_kernels ?? "未报告"} 个实验子程序。`,

+ 11 - 0
packages/opencode/test/tool/agentpaas-research-ir.test.ts

@@ -61,3 +61,14 @@ test("reviewed interpretation remains distinct from unresolved plan checks in to
   expect(result.output).toContain("原方案:本次未重审")
   expect(result.output).toContain("原方案:本次未重审")
   expect(result.output).toContain("research-synthesis.json")
   expect(result.output).toContain("research-synthesis.json")
 })
 })
+
+
+test("decision support is presented as proposed checks rather than completed experiments", () => {
+  const result = formatRunResult("Research67", { status: "completed", research: { science: {
+    status: "needs_revision", decision_support: { hypotheses: 2, candidate_checks: 3, independent_validation: false },
+  } } })
+  expect(result.output).toContain("2 个假设、3 项候选检查")
+  expect(result.output).toContain("不代表已执行或独立验收")
+  expect(result.output).toContain("research-decisions.json")
+  expect(result.output).not.toContain("实验子程序已执行")
+})

+ 2 - 0
packages/tui/src/util/agentpaas.ts

@@ -38,6 +38,7 @@ export function paasCard(metadata: Record<string, unknown>, input: Record<string
   const operation = record(science?.operation)
   const operation = record(science?.operation)
   const researchIR = record(science?.research_ir)
   const researchIR = record(science?.research_ir)
   const observations = record(science?.observations)
   const observations = record(science?.observations)
+  const decisionSupport = record(science?.decision_support)
   const control = record(science?.control)
   const control = record(science?.control)
   const capabilities = record(science?.capabilities)
   const capabilities = record(science?.capabilities)
   const schedule = record(science?.study_schedule)
   const schedule = record(science?.study_schedule)
@@ -79,6 +80,7 @@ export function paasCard(metadata: Record<string, unknown>, input: Record<string
       operation?.operation === "clarify" ? "本次操作:等待说明研究意图;未启动研究或实验" : "",
       operation?.operation === "clarify" ? "本次操作:等待说明研究意图;未启动研究或实验" : "",
       record(acceptance?.plan_review)?.status === "not_reassessed" ? "原方案:本次未重审,原有待修订项继续保留;review-parent-gate.json" : "",
       record(acceptance?.plan_review)?.status === "not_reassessed" ? "原方案:本次未重审,原有待修订项继续保留;review-parent-gate.json" : "",
       text(science?.next_step) ? `下一步研究:${text(science?.next_step)}` : "",
       text(science?.next_step) ? `下一步研究:${text(science?.next_step)}` : "",
+      decisionSupport ? `验证选择:${number(decisionSupport.hypotheses)} 个假设、${number(decisionSupport.candidate_checks)} 项候选检查;未代表执行或独立验收;research-decisions.json 查看依据与缺口` : "",
       control?.continue_automatically === false ? "本次已停止;上述后续建议尚未自动执行,可在当前会话继续补充条件或反馈" : "",
       control?.continue_automatically === false ? "本次已停止;上述后续建议尚未自动执行,可在当前会话继续补充条件或反馈" : "",
       capabilities?.status === "plans_only_no_registered_input" ? "当前可生成研究计划;实际计算需先注册数据或选择模拟器" : "",
       capabilities?.status === "plans_only_no_registered_input" ? "当前可生成研究计划;实际计算需先注册数据或选择模拟器" : "",
       capabilities?.status === "selection_required" ? "已登记多类数据,请选择本项研究要使用的执行器" : "",
       capabilities?.status === "selection_required" ? "已登记多类数据,请选择本项研究要使用的执行器" : "",

+ 11 - 0
packages/tui/test/util/agentpaas.test.ts

@@ -184,3 +184,14 @@ test("result-only followups preserve plan issues and do not advertise a new exec
     expect(text).not.toContain("execution-ir.json 查看范围")
     expect(text).not.toContain("execution-ir.json 查看范围")
   }
   }
 })
 })
+
+
+test("candidate check counts do not imply completed studies", () => {
+  const card = paasCard({ status: "completed", research: { science: {
+    decision_support: { hypotheses: 2, candidate_checks: 1, independent_validation: false },
+    study_schedule: { computed: 0, total: 2 },
+  } } })
+  expect(card.lines.join("\n")).toContain("2 个假设、1 项候选检查")
+  expect(card.lines.join("\n")).toContain("0/2 项计算完成")
+  expect(card.lines.join("\n")).toContain("research-decisions.json 查看依据与缺口")
+})