import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import { composeHostFallbackNarration, publicWriteToolCompleted, } from "../src/lib/rectification-agentic/v9/host-fallback.ts"; test("host fallback recap uses only batch return lines", () => { assert.equal(composeHostFallbackNarration(null), null); assert.equal(composeHostFallbackNarration({}), "记下了。"); assert.equal( composeHostFallbackNarration({ accepted_recaps: [ { display_date_label: "2016年9月", event_phrase: "入学" }, { display_date_label: "2020年6月", event_phrase: "毕业" }, ], }), "记下了:2016年9月 入学、2020年6月 毕业。", ); assert.equal( composeHostFallbackNarration({ items: [ { outcome: "accepted", display_date_label: "2018年7月", event_phrase: "入职" }, { outcome: "rejected", display_date_label: "1999年", event_phrase: "不该出现" }, ], }), "记下了:2018年7月 入职。", ); }); test("write-tool completion is limited to batch, set-focus and compare", () => { const none = new Map([ ["rectification-read-case", "completed"], ]); assert.equal(publicWriteToolCompleted(none), false); const batch = new Map([ ["rectification-record-evidence-batch", "completed"], ]); assert.equal(publicWriteToolCompleted(batch), true); const failedBatch = new Map([ ["rectification-record-evidence-batch", "failed"], ]); assert.equal(publicWriteToolCompleted(failedBatch), false); }); test("case snapshot receipts expose host_fallback origin from the durable phase", () => { const route = readFileSync( new URL("../src/app/api/rectification/cases/[caseId]/route.ts", import.meta.url), "utf8", ); assert.match(route, /answer_origin: "host_fallback"/); assert.match(route, /answer\.host_fallback/); });