Files
Jyotisha/frontend/tests/rectification-collect-prompt.test.ts
T

134 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
import { composeCollectSpokenAssistantText, detachCollectSpokenAssistantText, stripQuestionSentences, trimEvidenceTurnBody } from "../src/lib/rectification-agentic/v9/collect-prompt.ts";
import { attachQuestionsToTurns } from "../src/lib/rectification-agentic/v9/turn-question.ts";
import { GENERIC_COLLECT_QUESTION, RECTIFICATION_USER_COPY, USER_COLLECT_QUESTION } from "../src/lib/rectification-agentic/user-copy.ts";
import { CASE_ID, FOCUS_ID, TURN_ID } from "./rectification-v9-test-support.ts";
test("composeCollectSpokenAssistantText joins by exact prompt identity", () => {
const greeting = "你好,我是生时校正助手。";
const combined = `${greeting}\n\n${GENERIC_COLLECT_QUESTION}`;
assert.equal(composeCollectSpokenAssistantText(greeting, GENERIC_COLLECT_QUESTION), combined);
assert.equal(composeCollectSpokenAssistantText(combined, GENERIC_COLLECT_QUESTION), combined);
assert.equal(composeCollectSpokenAssistantText("", GENERIC_COLLECT_QUESTION), GENERIC_COLLECT_QUESTION);
assert.equal(composeCollectSpokenAssistantText(GENERIC_COLLECT_QUESTION, GENERIC_COLLECT_QUESTION), GENERIC_COLLECT_QUESTION);
assert.equal(composeCollectSpokenAssistantText(greeting, " "), greeting);
assert.equal(
composeCollectSpokenAssistantText(` ${greeting} `, ` ${GENERIC_COLLECT_QUESTION} `),
combined,
);
});
test("detachCollectSpokenAssistantText removes only an exact trailing stem", () => {
const greeting = "你好,我是生时校正助手。";
const combined = `${greeting}\n\n${GENERIC_COLLECT_QUESTION}`;
assert.equal(detachCollectSpokenAssistantText(combined, GENERIC_COLLECT_QUESTION), greeting);
assert.equal(detachCollectSpokenAssistantText(greeting, GENERIC_COLLECT_QUESTION), greeting);
assert.equal(detachCollectSpokenAssistantText(GENERIC_COLLECT_QUESTION, GENERIC_COLLECT_QUESTION), GENERIC_COLLECT_QUESTION);
assert.equal(detachCollectSpokenAssistantText("", GENERIC_COLLECT_QUESTION), "");
});
test("GET rebuild detaches a legacy composed suffix only when asked_turn_id matches", () => {
const greeting = "你好,我是生时校正助手。";
const combined = composeCollectSpokenAssistantText(greeting, GENERIC_COLLECT_QUESTION);
const turns = [{
id: TURN_ID,
role: "assistant" as const,
text: combined,
status: "completed",
}];
const linked = attachQuestionsToTurns(turns, [{
id: FOCUS_ID,
caseId: CASE_ID,
questionId: "collect:unknown:collect_method_evidence",
intent: "collect_method_evidence",
targetEvidenceId: null,
targetDomain: null,
targetKind: null,
expectedAnswerSchema: { prompt: GENERIC_COLLECT_QUESTION, collect: true },
status: "active",
askedAt: "2026-09-02T00:00:00.000Z",
resolvedAt: null,
askedTurnId: TURN_ID,
}]);
assert.equal(linked[0]?.text, greeting);
assert.equal(linked[0]?.question?.prompt, GENERIC_COLLECT_QUESTION);
const unlinked = attachQuestionsToTurns(turns, [{
id: FOCUS_ID,
caseId: CASE_ID,
questionId: "collect:unknown:collect_method_evidence",
intent: "collect_method_evidence",
targetEvidenceId: null,
targetDomain: null,
targetKind: null,
expectedAnswerSchema: { prompt: GENERIC_COLLECT_QUESTION, collect: true },
status: "active",
askedAt: "2026-09-02T00:00:00.000Z",
resolvedAt: null,
askedTurnId: null,
}]);
assert.equal(unlinked[0]?.text, combined);
assert.equal(unlinked[0]?.question, null);
});
test("composeCollectSpokenAssistantText drops a near-duplicate restatement of the stem", () => {
const stem = USER_COLLECT_QUESTION.education;
const restated = `${stem.slice(0, 12)}还记得大概哪一年吗?`;
const body = `这条记下了。${restated}`;
const composed = composeCollectSpokenAssistantText(body, stem);
assert.equal(composed.includes(restated), false);
assert.equal(composed.split(stem).length - 1, 1);
assert.ok(composed.endsWith(stem));
});
test("runtime no longer composes the stem into assistant_message", () => {
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
const attach = readFileSync(new URL("../src/lib/rectification-agentic/v9/turn-question.ts", import.meta.url), "utf8");
assert.doesNotMatch(agentRun, /composeCollectSpokenAssistantText/);
assert.match(attach, /stripQuestionSentences/);
assert.match(attach, /if \(!focus\.askedTurnId\) continue/);
});
test("stripQuestionSentences drops a rewritten trailing question and its tag", () => {
const body = "范围已经收到,收在 05:00–05:10。你大概哪一年搬过家?有年份就行。";
const stem = "你大概是哪一年搬的家?";
assert.equal(stripQuestionSentences(body, stem), "范围已经收到,收在 05:0005:10。");
});
test("stripQuestionSentences drops a mid-body stem and keeps the surrounding sentences", () => {
const stem = "你大概是哪一年搬的家?";
const body = "记下了。你大概是哪一年搬的家?范围还在 05:00–05:10。";
assert.equal(stripQuestionSentences(body, stem), "记下了。范围还在 05:0005:10。");
});
test("stripQuestionSentences returns empty when the body is only a question", () => {
const stem = "你大概是哪一年搬的家?";
assert.equal(stripQuestionSentences("你大概哪一年搬过家?", stem), "");
assert.equal(RECTIFICATION_USER_COPY.collectHandoff.includes("请回答下面的问题"), false);
});
test("attachQuestionsToTurns leaves body unchanged when the turn has no focus", () => {
const body = "范围收到 05:0005:10。你大概哪一年搬过家?";
const turns = attachQuestionsToTurns([{
id: TURN_ID,
role: "assistant" as const,
text: body,
}], []);
assert.equal(turns[0]?.text, body);
assert.equal(turns[0]?.question, null);
});
test("trimEvidenceTurnBody keeps the first sentence and strips value judgments", () => {
const three = trimEvidenceTurnBody("记下了:2016 年 9 月入学。这对校正很有帮助。接下来我们继续。");
assert.equal(three, "记下了:2016 年 9 月入学。");
assert.doesNotMatch(three, /很有帮助|很有价值|很有分量|特别有用/);
const judged = trimEvidenceTurnBody("记下了:2020 年 6 月毕业,特别有用。");
assert.doesNotMatch(judged, /特别有用/);
const two = trimEvidenceTurnBody("记下了:2016 年 9 月入学。\n\n范围收到 04:5005:10。");
assert.equal(two, "记下了:2016 年 9 月入学。\n\n范围收到 04:5005:10。");
});