|
|
@@ -1,6 +1,66 @@
|
|
|
import { expect, test } from "bun:test"
|
|
|
import { paasCard } from "../../src/util/agentpaas"
|
|
|
|
|
|
+test("reviewed synthesis is distinguished from computation and scientific acceptance", () => {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ status: "needs_evidence", synthesis: { status: "reviewed", answered: 1, total: 2 },
|
|
|
+ study_schedule: { computed: 1, total: 2, units: [
|
|
|
+ { study_id: "T1", status: "computed", interpretation_status: "reviewed", finding: "answered_within_scope", depends_on: [] },
|
|
|
+ { study_id: "T2", status: "ready_to_plan", interpretation_status: "reviewed", finding: "inconclusive", depends_on: ["T1"] },
|
|
|
+ ] },
|
|
|
+ } } })
|
|
|
+ const lines = card.lines.join("\n")
|
|
|
+ expect(lines).toContain("T1 · 已形成限定范围回答")
|
|
|
+ expect(lines).toContain("T2 · 结果尚不足以判断")
|
|
|
+ expect(lines).toContain("1/2 项限定范围回答;不是独立科学验收")
|
|
|
+ expect(lines).toContain("needs_evidence")
|
|
|
+ expect(lines).not.toContain("待解释")
|
|
|
+})
|
|
|
+
|
|
|
+test("study schedule shows dependency readiness separately from scientific success", () => {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ capabilities: { status: "per_round_selection" },
|
|
|
+ study_schedule: { computed: 1, total: 3, units: [
|
|
|
+ { study_id: "T1", status: "computed", depends_on: [] },
|
|
|
+ { study_id: "T2", status: "ready_to_plan", depends_on: ["T1"] },
|
|
|
+ { study_id: "T3", status: "waiting_prerequisite", depends_on: ["T2"] },
|
|
|
+ ] },
|
|
|
+ } } })
|
|
|
+ expect(card.lines.join("\n")).toContain("1/3 项计算完成(不等于科学结论成立)")
|
|
|
+ expect(card.lines.join("\n")).toContain("T2 · 待规划;依赖 T1")
|
|
|
+ expect(card.lines.join("\n")).toContain("T3 · 等待前置计算;依赖 T2")
|
|
|
+ expect(card.lines.join("\n")).toContain("逐轮选择已注册执行器")
|
|
|
+})
|
|
|
+
|
|
|
+test("stopped research recommendations are not displayed as automatically running", () => {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ next_step: "补充定义后继续推导", control: { continue_automatically: false },
|
|
|
+ capabilities: { status: "plans_only_no_registered_input" },
|
|
|
+ } } })
|
|
|
+ expect(card.lines.join("\n")).toContain("上述后续建议尚未自动执行")
|
|
|
+ expect(card.lines.join("\n")).toContain("实际计算需先注册数据")
|
|
|
+})
|
|
|
+
|
|
|
+test("research card displays next research action and observation review separately", () => {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ status: "needs_evidence", next_step: "补充模型适用性证据", observations: { recorded: 2, interpreted: 1, reviewed: 0 },
|
|
|
+ } } })
|
|
|
+ expect(card.lines.join("\n")).toContain("下一步研究:补充模型适用性证据")
|
|
|
+ expect(card.lines.join("\n")).toContain("观察 2 份 · 已解释 1 份 · 模型审阅认可 0 份")
|
|
|
+})
|
|
|
+
|
|
|
+test("scientific card separates planned actions, executed kernels and reused observations", () => {
|
|
|
+ for (const status of ["plans_only", "blocked", "reused_observations", "executed"]) {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ status: "needs_evidence", research_ir: { status, planned_actions: 7,
|
|
|
+ executed_kernels: status === "executed" ? 1 : 0, engine: status === "executed" ? "lambda_cek" : null },
|
|
|
+ } } })
|
|
|
+ expect(card.lines.join("\n")).toContain("needs_evidence")
|
|
|
+ expect(card.lines.join("\n")).toContain("研究计划 7 项行动,不代表全部已执行")
|
|
|
+ expect(card.lines.join("\n")).toContain(`本轮执行 ${status === "executed" ? 1 : 0} 个实验子程序`)
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
test("a completed client tool can display a running backend task and unknown billing", () => {
|
|
|
const card = paasCard({ status: "running", run_id: "run_long", agent_name: "Data67" })
|
|
|
expect(card.title).toBe("Data67 · 运行中")
|
|
|
@@ -55,3 +115,72 @@ test("explicitly complete usage is distinguished from missing completeness", ()
|
|
|
test("a stale confirmation cannot hide a terminal backend state", () => {
|
|
|
expect(paasCard({ status: "cancelled", pending_confirmation: { status: "pending" } }).title).toContain("已取消")
|
|
|
})
|
|
|
+
|
|
|
+test("resource gaps and missing independent evaluation stay visible after completion", () => {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ resources: { methods: [{ method: "randomized_trial", status: "no_registered_operation", executors: [] }] },
|
|
|
+ acceptance: { dimensions: { independent_scientific_evaluation: { status: "not_run" }, remote_or_instrument_acceptance: { status: "not_verified" } } },
|
|
|
+ } } })
|
|
|
+ expect(card.lines.join("\n")).toContain("缺少执行适配器")
|
|
|
+ expect(card.lines.join("\n")).toContain("独立科学评价:未开展")
|
|
|
+ expect(card.lines.join("\n")).toContain("不折算科学总分")
|
|
|
+})
|
|
|
+
|
|
|
+test("dataset inventory is not presented as completed scientific execution", () => {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ resources: { datasets: [{ id: "water", profile: { kind: "table", row_count: 7, malformed_rows: 0 } },
|
|
|
+ { id: "protocol", profile: { kind: "finite_graph", state_count: 4, transition_count: 4 } }] },
|
|
|
+ research_ir: { status: "plans_only", planned_actions: 2, executed_kernels: 0 },
|
|
|
+ } } })
|
|
|
+ const lines = card.lines.join("\n")
|
|
|
+ expect(lines).toContain("输入概况:water · 7 行")
|
|
|
+ expect(lines).toContain("4 个状态 · 4 条转移;不是实验结果")
|
|
|
+ expect(lines).toContain("本轮执行 0 个实验子程序")
|
|
|
+})
|
|
|
+
|
|
|
+test("numeric checks expose extracted scope without declaring complete verification", () => {
|
|
|
+ for (const count of [0, 3]) {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ synthesis: { status: "reviewed", answered: 1, total: 1, numeric_check: { status: "checked", quantity_claims: count } },
|
|
|
+ } } })
|
|
|
+ expect(card.lines.join("\n")).toContain(`提取 ${count} 条;不代表已覆盖全部表述`)
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+test("numeric coverage reports unlinked occurrences separately from claim correctness", () => {
|
|
|
+ const card = paasCard({ status: "completed", research: { science: {
|
|
|
+ synthesis: { status: "reviewed", answered: 1, total: 1, numeric_check: {
|
|
|
+ status: "checked", quantity_claims: 4, artifact: "study-synthesis-1-numbers-checks.json",
|
|
|
+ coverage: { candidate_mentions: 7, linked_mentions: 4, unlinked_mentions: 3 },
|
|
|
+ } },
|
|
|
+ } } })
|
|
|
+ expect(card.lines.join("\n")).toContain("4/7 已关联;3 未关联(可能包含计划值或标识)")
|
|
|
+ expect(card.lines.join("\n")).toContain("study-synthesis-1-numbers-checks.json,不是语义核验覆盖率")
|
|
|
+})
|
|
|
+
|
|
|
+test("supplemental numeric extraction distinguishes recovered, excluded and unfinished checks", () => {
|
|
|
+ const completed = paasCard({ status: "completed", research: { science: { synthesis: {
|
|
|
+ numeric_check: { status: "checked", quantity_claims: 1, followup: { status: "completed",
|
|
|
+ recovered_mentions: 1, not_result_mentions: 2, unresolved_mentions: 3, artifact: "numbers-unlinked.json" } },
|
|
|
+ } } } })
|
|
|
+ expect(completed.lines.join("\n")).toContain("恢复 1 处 · 模型判断非结果 2 处 · 暂无法对应 3 处")
|
|
|
+ const pending = paasCard({ status: "completed", research: { science: { synthesis: {
|
|
|
+ numeric_check: { status: "checked", quantity_claims: 0, followup: { status: "pending" } },
|
|
|
+ } } } })
|
|
|
+ expect(pending.lines.join("\n")).toContain("遗漏补查尚未完成;保留首次核对与未关联项,不表示全文通过")
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+test("result-only followups preserve plan issues and do not advertise a new execution IR", () => {
|
|
|
+ for (const operation of ["review_results", "clarify"]) {
|
|
|
+ const card = paasCard({status:"completed", research:{science:{
|
|
|
+ operation: {operation}, research_ir: {status:"not_executed",executed_kernels:0,planned_actions:0},
|
|
|
+ acceptance:{dimensions:{plan_review:{status:"not_reassessed"}}},
|
|
|
+ }}})
|
|
|
+ const text = card.lines.join("\n")
|
|
|
+ expect(text).toContain(operation==="review_results" ? "复核已有结果" : "等待说明研究意图")
|
|
|
+ expect(text).toContain("原有待修订项继续保留")
|
|
|
+ expect(text).toContain("本轮执行 0 个实验子程序")
|
|
|
+ expect(text).not.toContain("execution-ir.json 查看范围")
|
|
|
+ }
|
|
|
+})
|