Files
Jyotisha/frontend/tests/rectification-spoken-prompt.test.ts
T
Jesse_Chen 3847e9c91d
Independent Staging Quality Gate / validate (push) Failing after 8m39s
Independent Staging Quality Gate / publish (push) Has been skipped
fix(rectification): collect a dated third event before OOS and occupation
Holdout stays closed until the training gate opens and skips declined domains.
Dated collect order is shared with exhaustion; spoken prompts must name the domain; progress copy uses collection_progress only.

BUG-527 through BUG-530.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 18:17:17 +08:00

182 lines
6.9 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 test from "node:test";
import { parseAgentChoiceCopy } from "../src/lib/rectification-agentic/v9/choice-card.ts";
import { validateSpokenPrompt, withSpokenPrompt } from "../src/lib/rectification-agentic/v9/spoken-prompt.ts";
import { MACHINE_VOICE_LEXICON } from "../src/lib/rectification-agentic/v9/agent-voice-lexicon.ts";
import type { MethodFollowup } from "../src/lib/rectification-agentic/v9/method-followup.ts";
function followup(overrides: Partial<MethodFollowup> = {}): MethodFollowup {
return {
method_id: "d9_relationship",
intent: "distinguish_candidates",
ask_theme: "relationship_style",
domain: "relationship",
kind_hint: "relationship_change",
user_prompt_hint: "probe",
must_not_label: false,
choice_frame: {
question_id: "d9:relationship:2023",
method_id: "d9_relationship",
period: "2023 年前后",
prompt: "2023 年前后,你有没有一段认真开始或结束的关系?",
varga: "D9",
why: "区分",
option_a_hint: "明确发生且时间吻合",
option_b_hint: "发生过但时间偏了",
neither_label: "没有这回事",
unsure_label: "记不清",
option_a_answer_class: "yes",
option_b_answer_class: "weak_yes",
option_c_answer_class: "no",
option_d_answer_class: "unsure",
choice_mode: "A/B/C/D",
stop_label: "先这样,先看当前范围",
stop_message: "先这样",
scoring: true,
},
source: "event_probe",
probe_year: 2023,
...overrides,
};
}
test("spokenPrompt rejects length, option literals, unique-minute claims, and machine voice", () => {
assert.equal(validateSpokenPrompt({ spokenPrompt: "太短了" }).ok, false);
const optionLiteral = validateSpokenPrompt({
spokenPrompt: "2023 年这段感情,选项怎么选你还记得吗?",
});
assert.equal(optionLiteral.ok, false);
assert.equal(optionLiteral.ok ? null : optionLiteral.reason, "option_literal");
const uniqueMinute = validateSpokenPrompt({
spokenPrompt: "这能定下唯一的出生分钟吗,你还记得医院的钟点?",
});
assert.equal(uniqueMinute.ok, false);
assert.equal(uniqueMinute.ok ? null : uniqueMinute.reason, "unique_minute");
assert.equal(validateSpokenPrompt({
spokenPrompt: MACHINE_VOICE_LEXICON[3],
}).ok, false);
});
test("spokenPrompt rejects a different year or domain than the server probe", () => {
const probe = followup();
const yearMismatch = validateSpokenPrompt({
spokenPrompt: "2018 年前后,你有没有一段认真开始或结束的关系?",
followup: probe,
targetDomain: "relationship",
questionId: "d9_relationship:relationship:2023",
});
assert.equal(yearMismatch.ok ? null : yearMismatch.reason, "year_mismatch");
const yearMissing = validateSpokenPrompt({
spokenPrompt: "你有没有一段认真开始或结束的关系?",
followup: probe,
targetDomain: "relationship",
questionId: "d9_relationship:relationship:2023",
});
assert.equal(yearMissing.ok ? null : yearMissing.reason, "year_missing");
const domainMismatch = validateSpokenPrompt({
spokenPrompt: "2023 年前后,你有没有换过工作?",
followup: probe,
targetDomain: "career",
questionId: "d9_relationship:relationship:2023",
});
assert.equal(domainMismatch.ok ? null : domainMismatch.reason, "domain_mismatch");
assert.equal(validateSpokenPrompt({
spokenPrompt: "工作记下了。2023 年前后,有没有一段认真开始或结束的关系?",
followup: probe,
targetDomain: "relationship",
questionId: "d9_relationship:relationship:2023",
}).ok, true);
});
test("collect spokenPrompt must name the server domain; distinguish and OOS stay year-only", () => {
const educationCollect: MethodFollowup = {
method_id: "d5_education",
intent: "collect_method_evidence",
ask_theme: "education_style",
domain: "education",
kind_hint: "education_milestone",
user_prompt_hint: "collect",
must_not_label: false,
choice_frame: null,
source: "method_coverage",
};
const missing = validateSpokenPrompt({
spokenPrompt: "除了工作,还有哪件事记得年份?",
followup: educationCollect,
targetDomain: "education",
});
assert.equal(missing.ok, false);
assert.equal(missing.ok ? null : missing.reason, "domain_missing");
assert.equal(validateSpokenPrompt({
spokenPrompt: "上学那会儿,哪年升学或大考还记得吗?",
followup: educationCollect,
targetDomain: "education",
}).ok, true);
const oos: MethodFollowup = {
...educationCollect,
intent: "out_of_sample_check",
source: "oos_blind",
domain: "education",
};
assert.equal(validateSpokenPrompt({
spokenPrompt: "除了工作,还有哪件事记得年份?",
followup: oos,
targetDomain: "education",
}).ok, true);
});
test("spokenPrompt requires each year in a period when probe_year is empty", () => {
const ranged = followup({
probe_year: undefined,
choice_frame: {
...followup().choice_frame!,
period: "20142016 年前后",
},
});
const questionId = "d9:relationship:2023";
const missing = validateSpokenPrompt({
spokenPrompt: "你有没有升学或换过学习环境?",
followup: ranged,
questionId,
});
assert.equal(missing.ok ? null : missing.reason, "year_missing");
assert.equal(validateSpokenPrompt({
spokenPrompt: "2014 到 2016 年前后,有没有升学或换过学习环境?",
followup: ranged,
questionId,
}).ok, true);
const collect = followup({ choice_frame: null, probe_year: 2023 });
assert.equal(validateSpokenPrompt({
spokenPrompt: "你还记得哪年入的职吗?",
followup: collect,
targetDomain: "relationship",
}).ok, true);
});
test("withSpokenPrompt keeps a parseable choice prompt when spoken copy includes a clock time", () => {
const schema = {
choice: {
prompt: "2016 年前后,升学结果或学习环境有没有明显变化?",
option_a: "明确发生且时间吻合",
option_b: "发生过但程度较弱",
option_c: "明确没有发生",
option_d: "这段记不清楚",
options: [
{ key: "A", label: "明确发生且时间吻合", answer_class: "yes" },
{ key: "B", label: "发生过但程度较弱", answer_class: "weak_yes" },
{ key: "C", label: "明确没有发生", answer_class: "no" },
{ key: "D", label: "这段记不清楚", answer_class: "unsure" },
],
},
};
const next = withSpokenPrompt(
schema,
"已按 05:06 采用。现在核对:2016 年前后升学或学习环境有没有明显变化?",
);
const copy = parseAgentChoiceCopy(next);
assert.equal(copy?.options.length, 4);
assert.equal(copy?.prompt, "2016 年前后,升学结果或学习环境有没有明显变化?");
assert.equal(next.prompt, "已按 05:06 采用。现在核对:2016 年前后升学或学习环境有没有明显变化?");
});