fe87a9ecdb
Mastra intermediate text-delta was published as answer.delta, then set-focus domain errors reset the attempt and replayed evidence. Publish only the terminal no-tool step, persist the next probe on the server, and ground batch quotes in the source turn. Co-authored-by: Cursor <cursoragent@cursor.com>
112 lines
3.7 KiB
TypeScript
112 lines
3.7 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
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 { fakeAccounting, CASE_ID, FOCUS_ID, USER_ID, activeFocusFixture } from "./rectification-v9-test-support.ts";
|
|
|
|
function discriminatorFollowup(overrides: Partial<MethodFollowup> = {}): MethodFollowup {
|
|
const 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: "高考或重要考试发挥明显失常",
|
|
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",
|
|
}],
|
|
});
|
|
return {
|
|
method_id: "dasha_events",
|
|
intent: "distinguish_candidates",
|
|
ask_theme: "dated_event",
|
|
domain: "education",
|
|
kind_hint: null,
|
|
user_prompt_hint: "ask",
|
|
must_not_label: false,
|
|
choice_frame: frame,
|
|
source: "event_probe",
|
|
information_gain: 0.4,
|
|
semantic_key: "education:2016",
|
|
probe_year: 2016,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
test("does not ask an already-answered discriminator probe again", async () => {
|
|
const followup = discriminatorFollowup();
|
|
const active = activeFocusFixture({
|
|
expectedAnswerSchema: { probe_id: "education:2016", choice: serverOwnedChoiceCopy(followup.choice_frame!) },
|
|
});
|
|
const accounting = fakeAccounting({
|
|
set_agentic_rectification_conversation_focus: () => {
|
|
throw new Error("should not create a second focus");
|
|
},
|
|
});
|
|
const result = await persistServerOwnedFocus({
|
|
accounting: accounting.client,
|
|
userId: USER_ID,
|
|
caseId: CASE_ID,
|
|
activeFocus: {
|
|
...active,
|
|
id: FOCUS_ID,
|
|
caseId: CASE_ID,
|
|
questionId: stableFollowupQuestionId(followup),
|
|
intent: "distinguish_candidates",
|
|
targetEvidenceId: null,
|
|
targetDomain: "education",
|
|
targetKind: null,
|
|
expectedAnswerSchema: { probe_id: "education:2016" },
|
|
status: "active",
|
|
askedAt: "2026-08-24T00:00:00.000Z",
|
|
resolvedAt: null,
|
|
},
|
|
decisionReceipt: {
|
|
inference_state: {
|
|
answered_probes: [{ probe_id: "education:2016", semantic_key: "education:2016", answer_class: "yes" }],
|
|
probes: [],
|
|
},
|
|
},
|
|
followup,
|
|
});
|
|
assert.equal(result.status, "probe_already_answered");
|
|
assert.equal(accounting.calls.length, 0);
|
|
});
|
|
|
|
test("zero information gain does not open a discriminator", () => {
|
|
assert.equal(
|
|
shouldSkipDiscriminatorFollowup(discriminatorFollowup({ information_gain: 0 })),
|
|
"zero_information_gain",
|
|
);
|
|
});
|
|
|
|
test("duplicate focus conflict does not throw", async () => {
|
|
const followup = discriminatorFollowup({ source: "precision_stage", information_gain: 0.2 });
|
|
const accounting = fakeAccounting({
|
|
set_agentic_rectification_conversation_focus: () => {
|
|
throw new Error("agentic_rectification_focus_idempotency_conflict");
|
|
},
|
|
});
|
|
const result = await persistServerOwnedFocus({
|
|
accounting: accounting.client,
|
|
userId: USER_ID,
|
|
caseId: CASE_ID,
|
|
activeFocus: null,
|
|
decisionReceipt: null,
|
|
followup,
|
|
});
|
|
assert.equal(result.status, "duplicate_focus");
|
|
});
|