fix(rectification): remove static interview fallbacks
This commit is contained in:
@@ -5,8 +5,16 @@ import { buildInferenceState } from "../src/lib/rectification-agentic/core/build
|
||||
import { persistServerOwnedFocus, shouldSkipDiscriminatorFollowup, stableFollowupQuestionId } from "../src/lib/rectification-agentic/v9/server-focus.ts";
|
||||
import { buildChoiceFrame, serverOwnedChoiceCopy } from "../src/lib/rectification-agentic/v9/choice-card.ts";
|
||||
import type { MethodFollowup } from "../src/lib/rectification-agentic/v9/method-followup.ts";
|
||||
import type { EventProbeStyleOption } from "../src/lib/rectification-agentic/v9/refinement-packet.ts";
|
||||
import { fakeAccounting, CASE_ID, FOCUS_ID, USER_ID, activeFocusFixture } from "./rectification-v9-test-support.ts";
|
||||
|
||||
const DYNAMIC_STYLE_OPTIONS = [
|
||||
{ label: "明确发生且时间吻合", answer_class: "yes" },
|
||||
{ label: "发生过但程度较弱", answer_class: "weak_yes" },
|
||||
{ label: "明确没有发生", answer_class: "no" },
|
||||
{ label: "这段记不清楚", answer_class: "unsure" },
|
||||
] as const;
|
||||
|
||||
function discriminatorFollowup(overrides: Partial<MethodFollowup> = {}): MethodFollowup {
|
||||
const frame = buildChoiceFrame({
|
||||
method_id: "dasha_events",
|
||||
@@ -18,17 +26,19 @@ function discriminatorFollowup(overrides: Partial<MethodFollowup> = {}): MethodF
|
||||
year: 2016,
|
||||
year_label: "2016 年前后",
|
||||
domain: "education",
|
||||
event_family: "高考或重要考试发挥明显失常",
|
||||
event_family: "升学结果或学习环境出现明显变化",
|
||||
source: "dasha_activation",
|
||||
tracks: ["vimshottari", "narayana"],
|
||||
tracks_agree: true,
|
||||
unique_minute_claim: false,
|
||||
user_meaning: "2016 年前后高考或重要考试发挥明显失常",
|
||||
user_meaning: "2016 年前后升学结果或学习环境出现明显变化",
|
||||
role: "distinguish",
|
||||
information_gain: 0.4,
|
||||
semantic_key: "education:2016",
|
||||
style_options: DYNAMIC_STYLE_OPTIONS,
|
||||
}],
|
||||
});
|
||||
assert.ok(frame);
|
||||
return {
|
||||
method_id: "dasha_events",
|
||||
intent: "distinguish_candidates",
|
||||
@@ -51,6 +61,107 @@ function discriminatorFollowup(overrides: Partial<MethodFollowup> = {}): MethodF
|
||||
};
|
||||
}
|
||||
|
||||
function invalidStyleFollowup(
|
||||
styleOptions: readonly EventProbeStyleOption[] | undefined,
|
||||
eventFamily = "升学结果或学习环境出现明显变化",
|
||||
): MethodFollowup {
|
||||
const valid = discriminatorFollowup();
|
||||
return {
|
||||
...valid,
|
||||
choice_frame: buildChoiceFrame({
|
||||
method_id: "dasha_events",
|
||||
ask_theme: "dated_event",
|
||||
domain: "education",
|
||||
user_prompt_hint: "ask",
|
||||
}, {
|
||||
probes: [{
|
||||
year: 2016,
|
||||
year_label: "2016 年前后",
|
||||
domain: "education",
|
||||
event_family: eventFamily,
|
||||
source: "dasha_activation",
|
||||
tracks: ["vimshottari", "narayana"],
|
||||
tracks_agree: true,
|
||||
unique_minute_claim: false,
|
||||
user_meaning: "2016 年前后升学结果或学习环境出现明显变化",
|
||||
role: "distinguish",
|
||||
information_gain: 0.4,
|
||||
semantic_key: "education:2016",
|
||||
style_options: styleOptions,
|
||||
}],
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
async function assertInvalidChoiceSkipped(followup: MethodFollowup) {
|
||||
const accounting = fakeAccounting({}, {
|
||||
fallback: () => {
|
||||
throw new Error("invalid choice frame must not call the database");
|
||||
},
|
||||
});
|
||||
const result = await persistServerOwnedFocus({
|
||||
accounting: accounting.client,
|
||||
userId: USER_ID,
|
||||
caseId: CASE_ID,
|
||||
activeFocus: null,
|
||||
decisionReceipt: null,
|
||||
followup,
|
||||
});
|
||||
assert.equal(result.status, "skipped");
|
||||
assert.equal(accounting.calls.length, 0);
|
||||
}
|
||||
|
||||
test("complete dynamic event options persist a server-owned focus", async () => {
|
||||
const followup = discriminatorFollowup({ source: "precision_stage", information_gain: 0.2 });
|
||||
const accounting = fakeAccounting({
|
||||
set_agentic_rectification_conversation_focus: (_fn, args) => ({
|
||||
id: FOCUS_ID,
|
||||
case_id: CASE_ID,
|
||||
question_id: args.p_question_id,
|
||||
intent: args.p_intent,
|
||||
target_evidence_id: null,
|
||||
target_domain: args.p_target_domain,
|
||||
target_kind: args.p_target_kind,
|
||||
expected_answer_schema: args.p_expected_answer_schema,
|
||||
status: "active",
|
||||
asked_at: "2026-08-27T00:00:00.000Z",
|
||||
resolved_at: null,
|
||||
idempotent: false,
|
||||
}),
|
||||
});
|
||||
const result = await persistServerOwnedFocus({
|
||||
accounting: accounting.client,
|
||||
userId: USER_ID,
|
||||
caseId: CASE_ID,
|
||||
activeFocus: null,
|
||||
decisionReceipt: null,
|
||||
followup,
|
||||
});
|
||||
assert.equal(result.status, "created");
|
||||
assert.equal(accounting.calls.length, 1);
|
||||
assert.deepEqual(result.focus?.expectedAnswerSchema.choice, {
|
||||
prompt: "2016 年前后 · 升学结果或学习环境出现明显变化",
|
||||
option_a: DYNAMIC_STYLE_OPTIONS[0].label,
|
||||
option_b: DYNAMIC_STYLE_OPTIONS[1].label,
|
||||
option_c: DYNAMIC_STYLE_OPTIONS[2].label,
|
||||
option_d: DYNAMIC_STYLE_OPTIONS[3].label,
|
||||
});
|
||||
});
|
||||
|
||||
test("missing, duplicate, incomplete, or illegal dynamic options skip focus persistence", async () => {
|
||||
await assertInvalidChoiceSkipped(invalidStyleFollowup(undefined));
|
||||
await assertInvalidChoiceSkipped(invalidStyleFollowup(DYNAMIC_STYLE_OPTIONS.slice(0, 3)));
|
||||
await assertInvalidChoiceSkipped(invalidStyleFollowup([
|
||||
...DYNAMIC_STYLE_OPTIONS,
|
||||
{ label: "另一种明确发生", answer_class: "yes" },
|
||||
]));
|
||||
await assertInvalidChoiceSkipped(invalidStyleFollowup([
|
||||
{ ...DYNAMIC_STYLE_OPTIONS[0], label: "08:12 左右发生" },
|
||||
...DYNAMIC_STYLE_OPTIONS.slice(1),
|
||||
]));
|
||||
await assertInvalidChoiceSkipped(invalidStyleFollowup(DYNAMIC_STYLE_OPTIONS, " "));
|
||||
});
|
||||
|
||||
test("does not ask an already-answered discriminator probe again", async () => {
|
||||
const followup = discriminatorFollowup();
|
||||
const active = activeFocusFixture({
|
||||
|
||||
Reference in New Issue
Block a user