feat(rectification): 删掉年月录入卡,年月阶段打字回答且不被追问覆盖
This commit is contained in:
@@ -464,8 +464,8 @@ test("skill version is 10.0.26 after the targeted-collect-cards bump", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
test("revision 5 with uncovered relatives asks the dated family collect, not a yearless D12 card", () => {
|
||||
|
||||
@@ -365,8 +365,8 @@ test("holdout not_ready forbids unique-minute copy and still blocks confirm", as
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
|
||||
const accounting = fakeAccounting({
|
||||
...receiptHandlers,
|
||||
|
||||
@@ -258,15 +258,15 @@ test("skill 10.0.26 forbids computing varga signs from transition times", () =>
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
// 原值: "10.0.25"
|
||||
// 原值: "10.0.26"
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: /^version: 10\.0\.27$/ / 新值: /^version: 10\.0\.28$/ / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.match(skill, /^version: 10\.0\.28$/m);
|
||||
// 原值: /^version: 10\.0\.28$/ / 新值: /^version: 10\.0\.29$/ / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.match(skill, /^version: 10\.0\.29$/m);
|
||||
assert.match(skill, new RegExp(SKILL_SIGN_SENTENCE.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));
|
||||
assert.match(comparison, new RegExp(SKILL_SIGN_SENTENCE.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));
|
||||
});
|
||||
|
||||
@@ -1454,8 +1454,8 @@ test("public tool surface stays at 14 and new cases bind 10.0.26", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
const deprecated = resolveExactSkillPackage(
|
||||
"jyotish-birth-time-rectification",
|
||||
"10.0.2",
|
||||
|
||||
@@ -602,8 +602,8 @@ test("skill version is 10.0.26 after the targeted-collect-cards bump", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
test("USER_COLLECT_QUESTION no longer has an other fallback", () => {
|
||||
|
||||
@@ -9,11 +9,12 @@ import {
|
||||
guidedAnyExamples,
|
||||
TARGETED_EXISTENCE_PROMPT,
|
||||
TARGETED_EXISTENCE_PROMPT_RETRY,
|
||||
TARGETED_YEAR_PROMPT,
|
||||
guidedCollectExhausted,
|
||||
guidedRetryPool,
|
||||
guidedWindowPool,
|
||||
guidedWindowPrompt,
|
||||
parseYearEntryQuestionId,
|
||||
parseGuidedWindowQuestionId,
|
||||
targetedCollectPool,
|
||||
rangeNarrowHint,
|
||||
remainingGuidedLine,
|
||||
@@ -26,11 +27,6 @@ import {
|
||||
GUIDED_WINDOW_OPTION_B,
|
||||
} from "../src/lib/rectification-agentic/v9/choice-card.ts";
|
||||
import { RECTIFICATION_USER_COPY } from "../src/lib/rectification-agentic/user-copy.ts";
|
||||
import {
|
||||
eventDateYearRange,
|
||||
formatEventDateEntryMessage,
|
||||
resolveEntryDomain,
|
||||
} from "../src/components/event-date-entry-card.tsx";
|
||||
|
||||
const WINDOWS: readonly GuidedCollectWindow[] = [
|
||||
{ year: 2018, month_lo: 3, month_hi: 6, domain: "career", split: { left: 2, right: 3 } },
|
||||
@@ -64,7 +60,7 @@ test("guided pool order is windows, skip retry, then uncovered domains", () => {
|
||||
assert.equal(followup?.collection_key, windows[0]?.key);
|
||||
});
|
||||
|
||||
test("A on a window yields a year-entry card, B/C close only that window", () => {
|
||||
test("A on a window yields a typed year question, B/C close only that window", () => {
|
||||
const evidence: CollectionEvidence[] = [];
|
||||
const afterYes = [
|
||||
{
|
||||
@@ -75,11 +71,17 @@ test("A on a window yields a year-entry card, B/C close only that window", () =>
|
||||
target_kind: "guided:window:career",
|
||||
},
|
||||
];
|
||||
const year = parseYearEntryQuestionId("collect:guided:window:2018:3:6:career:year");
|
||||
// 原值: parseYearEntryQuestionId + EventDateEntryCard
|
||||
// 新值: 年月阶段是口述题「大概哪年几月?」
|
||||
// 原因: T0 产品删除录入卡
|
||||
const year = parseGuidedWindowQuestionId("collect:guided:window:2018:3:6:career:year");
|
||||
assert.equal(year?.domain, "career");
|
||||
assert.equal(year?.year, 2018);
|
||||
assert.equal(year?.stage, "year");
|
||||
const pending = targetedCollectFollowup([], evidence, afterYes, null, 5, ["04:51", "05:11"], WINDOWS);
|
||||
assert.equal(pending?.collection_key?.endsWith(":year"), true);
|
||||
assert.equal(pending?.spoken_prompt, TARGETED_YEAR_PROMPT);
|
||||
assert.equal(pending?.choice_frame, null);
|
||||
|
||||
const afterNo = [
|
||||
{
|
||||
@@ -196,23 +198,7 @@ test("window prompt uses oral phrases, not server labels", () => {
|
||||
assert.doesNotMatch(prompt, /event_family|career_entry/);
|
||||
});
|
||||
|
||||
test("date entry submit walks the dated evidence path as year-month text", () => {
|
||||
// 原值: "2018 年 3 月,开始认真关系、分手或结婚"
|
||||
// 新值: "2018 年 3 月,感情方面有一件事"
|
||||
// 原因: F6/BUG-750——提交文本不得是选项列表,账本 summary 不得含「或」
|
||||
assert.equal(
|
||||
formatEventDateEntryMessage({ domain: "relationship", year: 2018, month: 3, day: null }),
|
||||
"2018 年 3 月,感情方面有一件事",
|
||||
);
|
||||
assert.doesNotMatch(
|
||||
formatEventDateEntryMessage({ domain: "relationship", year: 2018, month: 3, day: 12 }),
|
||||
/或/,
|
||||
);
|
||||
assert.equal(
|
||||
formatEventDateEntryMessage({ domain: "family", year: 2019, month: 1, day: 5 }),
|
||||
"2019 年 1 月 5 日,家人方面有一件事",
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
test("open windows ask without a domain and list open-domain orals", () => {
|
||||
const open = guidedWindowPrompt({
|
||||
@@ -250,9 +236,10 @@ test("an open window keeps its question id and is asked once for any domain", ()
|
||||
assert.equal(asked.length, 0);
|
||||
});
|
||||
|
||||
test("the entry card opens on the first still-open domain for an open window", () => {
|
||||
assert.equal(resolveEntryDomain(GUIDED_ANY_DOMAIN, ["finance", "family"]), "finance");
|
||||
assert.equal(resolveEntryDomain("relationship", ["finance", "family"]), "relationship");
|
||||
test("open windows still rank remaining collect kinds without an entry card", () => {
|
||||
// 原值: resolveEntryDomain + EventDateEntryCard 默认芯片
|
||||
// 新值: 只保留 firstOpenCollectKind 表驱动排序
|
||||
// 原因: T0 删除录入卡
|
||||
assert.equal(
|
||||
firstOpenCollectKind(
|
||||
[{ status: "confirmed", domain: "education", datePrecision: "month", occurredFrom: "2014-09-01", occurredTo: "2014-09-01" }],
|
||||
@@ -262,11 +249,6 @@ test("the entry card opens on the first still-open domain for an open window", (
|
||||
);
|
||||
});
|
||||
|
||||
test("date picker year range is birth year through this year", () => {
|
||||
assert.deepEqual(eventDateYearRange(1961, 2026), { minYear: 1961, maxYear: 2026 });
|
||||
assert.deepEqual(eventDateYearRange(null, 2026), { minYear: 1946, maxYear: 2026 });
|
||||
});
|
||||
|
||||
test("guided collect is not exhausted while a window remains", () => {
|
||||
assert.equal(guidedCollectExhausted([], [], [], WINDOWS, ["04:51", "05:11"], 5), false);
|
||||
assert.equal(guidedCollectExhausted(["d9", "d10", "d4", "d5", "d7", "d2", "d30"], [
|
||||
|
||||
@@ -219,15 +219,15 @@ test("new-case skill identity is 10.0.26 and the prompt prefers batch ingest", (
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
// 原值: "10.0.25"
|
||||
// 原值: "10.0.26"
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: /^version: 10\.0\.27$/ / 新值: /^version: 10\.0\.28$/ / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.match(skill, /^version: 10\.0\.28$/m);
|
||||
// 原值: /^version: 10\.0\.28$/ / 新值: /^version: 10\.0\.29$/ / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.match(skill, /^version: 10\.0\.29$/m);
|
||||
assert.match(skill, /不要对同一句用户消息里的多件事件逐条 propose\+confirm/);
|
||||
assert.match(agentSource, /新事件走 rectification-record-evidence-batch/);
|
||||
assert.doesNotMatch(agentSource, /分别调用 rectification-propose-evidence 和 rectification-confirm-evidence/);
|
||||
|
||||
@@ -190,8 +190,8 @@ test("skill version is 10.0.26 after the targeted-collect-cards bump", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
test("nineteen-row ledger opens the training gate with four scoreable domains", () => {
|
||||
|
||||
@@ -430,8 +430,8 @@ test("skill version is 10.0.26 after the targeted-collect-cards bump", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
test("pre-fix dual-exit constant is gone; range narration carries numbers and the disclaimer", () => {
|
||||
|
||||
@@ -463,8 +463,8 @@ test("skill version is 10.0.26", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
test("two education events do not spawn birth-year reverse questions", () => {
|
||||
|
||||
@@ -100,8 +100,8 @@ test("skill version is 10.0.26 after the targeted-collect-cards bump", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
test("cases current_question remains the submit contract, not a visual slot", () => {
|
||||
|
||||
@@ -196,8 +196,8 @@ test("click path does not surface 409 copy; round continue is opt-in only", () =
|
||||
test("Skill 10.0.26 lists the fourth targeted-collect skip option", () => {
|
||||
const skill = readFileSync(new URL("../../skills/jyotish-birth-time-rectification/SKILL.md", import.meta.url), "utf8");
|
||||
const strategy = readFileSync(new URL("../../skills/jyotish-birth-time-rectification/references/conversation-strategy.md", import.meta.url), "utf8");
|
||||
// 原值: /^version: 10\.0\.27$/ / 新值: /^version: 10\.0\.28$/ / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.match(skill, /^version: 10\.0\.28$/m);
|
||||
// 原值: /^version: 10\.0\.28$/ / 新值: /^version: 10\.0\.29$/ / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.match(skill, /^version: 10\.0\.29$/m);
|
||||
assert.match(skill, /已拒绝(没有发生过 \/ 这类事都没有过)的目标不得换词重问;跳过的按服务器计划最多重问一次/);
|
||||
assert.match(strategy, /跳过的线按服务器计划最多换一种问法再问一次/);
|
||||
});
|
||||
|
||||
@@ -103,8 +103,8 @@ test("agent pins the dedicated rectification skill and its fixed version", () =>
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.ok(RECTIFICATION_V9_PACKAGE_PATH.endsWith("skills/jyotish-birth-time-rectification/versions/10.0.28"));
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.ok(RECTIFICATION_V9_PACKAGE_PATH.endsWith("skills/jyotish-birth-time-rectification/versions/10.0.29"));
|
||||
assert.notEqual(RECTIFICATION_V9_SKILL_PATH, RECTIFICATION_V9_PACKAGE_PATH);
|
||||
assert.equal(realpathSync(RECTIFICATION_V9_SKILL_PATH), RECTIFICATION_V9_PACKAGE_PATH);
|
||||
assert.equal(RECTIFICATION_SKILL_NAME, "jyotish-birth-time-rectification");
|
||||
@@ -113,8 +113,8 @@ test("agent pins the dedicated rectification skill and its fixed version", () =>
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
test("step budgets are bounded per action with a hard ceiling", () => {
|
||||
|
||||
@@ -100,16 +100,16 @@ test("the active rectification skill pins the v10 identity and lives in the righ
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
assert.match(skill, /^---\nname: jyotish-birth-time-rectification/m);
|
||||
// 原值: "10.0.25"
|
||||
// 原值: "10.0.26"
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: /^version: 10\.0\.27$/ / 新值: /^version: 10\.0\.28$/ / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.match(skill, /^version: 10\.0\.28$/m);
|
||||
// 原值: /^version: 10\.0\.28$/ / 新值: /^version: 10\.0\.29$/ / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.match(skill, /^version: 10\.0\.29$/m);
|
||||
assert.match(skill, /至多一个主问题且唯一来源:[\s\S]*不得自行提出、复述、改写或预告问题/);
|
||||
for (const reference of references) {
|
||||
const content = readFileSync(`${skillDirectory}/references/${reference}`, "utf8");
|
||||
|
||||
@@ -210,8 +210,8 @@ test("open RPC passes the pinned skill and server-derived baseline only", async
|
||||
status: "draft",
|
||||
should_start_opening: true,
|
||||
// 原值: "10.0.25";新值: "10.0.26";原因: BUG-668 新案绑定现行 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
skill_version: "10.0.28",
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
skill_version: "10.0.29",
|
||||
};
|
||||
}
|
||||
return null;
|
||||
@@ -254,8 +254,8 @@ test("open RPC passes the pinned skill and server-derived baseline only", async
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(response.skillVersion, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(response.skillVersion, "10.0.29");
|
||||
const openCall = accounting.calls.find((call) => call.fn === "open_agentic_rectification_case_v2");
|
||||
assert.ok(openCall);
|
||||
assert.equal(openCall.args.p_skill_name, "jyotish-birth-time-rectification");
|
||||
@@ -264,8 +264,8 @@ test("open RPC passes the pinned skill and server-derived baseline only", async
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(openCall.args.p_skill_version, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(openCall.args.p_skill_version, "10.0.29");
|
||||
assert.equal(openCall.args.p_user_id, "user-1");
|
||||
// The server derives the baseline; the request never carries it from the browser.
|
||||
assert.equal("birth_date" in openCall.args, false);
|
||||
|
||||
@@ -91,6 +91,6 @@ test("agent body cannot verbally accept a spoken birth window", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
|
||||
import { withSpokenPrompt } from "../src/lib/rectification-agentic/v9/spoken-prompt.ts";
|
||||
import { projectCurrentQuestion } from "../src/lib/rectification-agentic/v9/turn-decision.ts";
|
||||
import {
|
||||
TARGETED_YEAR_PROMPT,
|
||||
isYearStageQuestionId,
|
||||
pendingTargetedYearDomain,
|
||||
} from "../src/lib/rectification-agentic/v9/collection-question-pool.ts";
|
||||
import {
|
||||
collectFocusSchema,
|
||||
isCollectFocusSchema,
|
||||
persistServerOwnedFocus,
|
||||
shouldResolveCollectFocusAfterEvidence,
|
||||
} from "../src/lib/rectification-agentic/v9/server-focus.ts";
|
||||
import { shouldHostReaskYearEntry, userMessageHasYear } from "../src/lib/rectification-agentic/v9/year-entry-host.ts";
|
||||
import { TARGETED_COLLECT_OPTION_A } from "../src/lib/rectification-agentic/v9/choice-card.ts";
|
||||
import { targetedCollectYearFollowup as yearFollowup } from "../src/lib/rectification-agentic/v9/method-followup.ts";
|
||||
import {
|
||||
CASE_ID,
|
||||
FOCUS_ID,
|
||||
USER_ID,
|
||||
fakeAccounting,
|
||||
} from "./rectification-v9-test-support.ts";
|
||||
|
||||
const YEAR_Q = "collect:targeted:health_pressure:year";
|
||||
const SERVER_PROMPT = TARGETED_YEAR_PROMPT;
|
||||
const FOLLOWUP = "2019年3月这次手术,是你本人做的吗?";
|
||||
|
||||
test("year-stage set-focus overlay keeps the server prompt (BUG-908)", () => {
|
||||
const schema = {
|
||||
collect: true,
|
||||
prompt: SERVER_PROMPT,
|
||||
};
|
||||
const next = withSpokenPrompt(schema, FOLLOWUP, YEAR_Q);
|
||||
assert.equal(next.prompt, SERVER_PROMPT);
|
||||
assert.equal(next.spoken_prompt, FOLLOWUP);
|
||||
const question = projectCurrentQuestion({
|
||||
id: FOCUS_ID,
|
||||
questionId: YEAR_Q,
|
||||
intent: "collect_method_evidence",
|
||||
targetDomain: "health_pressure",
|
||||
expectedAnswerSchema: next,
|
||||
});
|
||||
assert.equal(question?.prompt, SERVER_PROMPT);
|
||||
assert.equal(question?.kind, "collect_spoken");
|
||||
});
|
||||
|
||||
test("year-stage questions are typed collect, not an entry card (T0)", () => {
|
||||
assert.equal(isYearStageQuestionId(YEAR_Q), true);
|
||||
assert.equal(isYearStageQuestionId("collect:targeted:health_pressure"), false);
|
||||
assert.equal(TARGETED_COLLECT_OPTION_A, "有,我来说");
|
||||
const chat = readFileSync(new URL("../src/components/rectification-agentic-chat.tsx", import.meta.url), "utf8");
|
||||
assert.doesNotMatch(chat, /EventDateEntryCard|event_date_entry/);
|
||||
const followup = yearFollowup("health_pressure");
|
||||
const schema = collectFocusSchema(followup);
|
||||
assert.ok(isCollectFocusSchema(schema));
|
||||
assert.equal(schema?.event_date_entry, undefined);
|
||||
assert.equal(followup.spoken_prompt, TARGETED_YEAR_PROMPT);
|
||||
});
|
||||
|
||||
test("batch and propose-evidence share the same collect-focus resolve (BUG-909)", () => {
|
||||
const tools = readFileSync(new URL("../src/mastra/rectification-v9-tools.ts", import.meta.url), "utf8");
|
||||
const first = tools.indexOf("await resolveActiveCollectFocusAfterEvidence(");
|
||||
const second = tools.indexOf("await resolveActiveCollectFocusAfterEvidence(", first + 1);
|
||||
assert.ok(first > 0 && second > first);
|
||||
assert.equal(tools.indexOf("await resolveActiveCollectFocusAfterEvidence(", second + 1), -1);
|
||||
});
|
||||
|
||||
test("dated evidence closes the year stage for that domain (BUG-909)", () => {
|
||||
const topics = [{
|
||||
questionId: "collect:targeted:health_pressure",
|
||||
target_domain: "health_pressure",
|
||||
status: "resolved",
|
||||
intent: "collect_method_evidence",
|
||||
}];
|
||||
assert.equal(pendingTargetedYearDomain(topics, []), "health_pressure");
|
||||
assert.equal(pendingTargetedYearDomain(topics, [{
|
||||
status: "confirmed",
|
||||
domain: "health",
|
||||
datePrecision: "month",
|
||||
occurredFrom: "2019-03-01",
|
||||
occurredTo: "2019-03-01",
|
||||
}]), null);
|
||||
const schema = collectFocusSchema(yearFollowup("health_pressure"));
|
||||
assert.equal(shouldResolveCollectFocusAfterEvidence({
|
||||
intent: "collect_method_evidence",
|
||||
questionId: YEAR_Q,
|
||||
expectedAnswerSchema: schema ?? { collect: true, prompt: SERVER_PROMPT },
|
||||
}), true);
|
||||
});
|
||||
|
||||
test("persist year followup writes a collect schema that batch can resolve (BUG-909 a)", async () => {
|
||||
const accounting = fakeAccounting({
|
||||
set_agentic_rectification_conversation_focus: (_fn, args) => ({
|
||||
focus: {
|
||||
id: FOCUS_ID,
|
||||
case_id: CASE_ID,
|
||||
question_id: args.p_question_id,
|
||||
intent: args.p_intent,
|
||||
target_domain: args.p_target_domain,
|
||||
expected_answer_schema: args.p_expected_answer_schema,
|
||||
status: "active",
|
||||
asked_at: "2026-09-16T00:00:00.000Z",
|
||||
},
|
||||
idempotent: false,
|
||||
}),
|
||||
});
|
||||
const result = await persistServerOwnedFocus({
|
||||
accounting: accounting.client,
|
||||
userId: USER_ID,
|
||||
caseId: CASE_ID,
|
||||
activeFocus: null,
|
||||
decisionReceipt: null,
|
||||
followup: yearFollowup("health_pressure"),
|
||||
});
|
||||
assert.equal(result.status, "created");
|
||||
assert.equal(isCollectFocusSchema(result.focus?.expectedAnswerSchema ?? null), true);
|
||||
assert.equal(result.focus?.expectedAnswerSchema.prompt, TARGETED_YEAR_PROMPT);
|
||||
assert.equal(result.focus?.expectedAnswerSchema.event_date_entry, undefined);
|
||||
});
|
||||
|
||||
test("yearless short replies are held by the host pre-step (BUG-910)", () => {
|
||||
assert.equal(userMessageHasYear("是"), false);
|
||||
assert.equal(userMessageHasYear("不是本人"), false);
|
||||
assert.equal(userMessageHasYear("2019年3月做过手术"), true);
|
||||
assert.equal(userMessageHasYear("2020 年住院"), true);
|
||||
const focus = {
|
||||
questionId: YEAR_Q,
|
||||
expectedAnswerSchema: { collect: true, prompt: SERVER_PROMPT },
|
||||
};
|
||||
assert.equal(shouldHostReaskYearEntry(focus, "是"), SERVER_PROMPT);
|
||||
assert.equal(shouldHostReaskYearEntry(focus, "2019年3月做过手术"), null);
|
||||
const agentRun = readFileSync(new URL("../src/lib/rectification-agentic/v9/agent-run.ts", import.meta.url), "utf8");
|
||||
const reliability = agentRun.indexOf("classifyDateReliabilityUtterance");
|
||||
const yearHost = agentRun.indexOf("shouldHostReaskYearEntry");
|
||||
const reserve = agentRun.indexOf("billing.reserve");
|
||||
assert.ok(reliability > 0 && yearHost > reliability && reserve > yearHost);
|
||||
});
|
||||
|
||||
test("standalone persisted question shares the assistant inset (BUG-911)", () => {
|
||||
const styles = readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8");
|
||||
assert.match(
|
||||
styles,
|
||||
/\.rectification-message-question\.is-standalone \{[\s\S]*margin-inline-start: var\(--assistant-content-inset\)/,
|
||||
);
|
||||
assert.match(
|
||||
styles,
|
||||
/\.rectification-message-question\.is-standalone \.rectification-choice-card\.is-embedded \{[\s\S]*margin-inline-start: 0/,
|
||||
);
|
||||
assert.doesNotMatch(styles, /\.rectification-event-entry \{/);
|
||||
});
|
||||
@@ -166,8 +166,8 @@ test("SCORE_DELTA stays ±2/±1 and yearless weight is half", () => {
|
||||
// 新值: "10.0.27"
|
||||
// 原因: 出卡精度门槛 + 引导式补经历
|
||||
// 原因: BUG-668 定向补事第四选项写进 Skill
|
||||
// 原值: "10.0.27" / 新值: "10.0.28" / 原因: D6 改写出卡句后 Skill bump
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.28");
|
||||
// 原值: "10.0.28" / 新值: "10.0.29" / 原因: 年月阶段改口述并禁止追问本人
|
||||
assert.equal(RECTIFICATION_SKILL_VERSION, "10.0.29");
|
||||
});
|
||||
|
||||
test("D9 answer B moves scores by ±1 and does not count toward elimination", () => {
|
||||
|
||||
@@ -85,11 +85,11 @@ test("checked-in registry verifies hashed product packages and leaves consult on
|
||||
[
|
||||
{
|
||||
name: "jyotish-birth-time-rectification",
|
||||
// 原值: 10.0.27 / 7e541741…f020
|
||||
// 新值: 10.0.28 / f0bb8295…cffe
|
||||
// 原因: D6 改写 §流程出卡句(门槛只是必要条件),Skill 随之 bump
|
||||
version: "10.0.28",
|
||||
sha256: "f0bb8295f3ba029992fad141e90a56931bf6a0867c827ff4e37a24452e87cffe",
|
||||
// 原值: 10.0.28 / f0bb8295…cffe
|
||||
// 新值: 10.0.29 / 750a0d58…724c
|
||||
// 原因: 年月阶段改口述、禁止追问本人
|
||||
version: "10.0.29",
|
||||
sha256: "750a0d58c6731c0dbdeb5c785cea1bf8a3f73aaf94a560a86397805b7037724c",
|
||||
},
|
||||
{
|
||||
name: "jyotish-personal-report",
|
||||
|
||||
Reference in New Issue
Block a user