fix(rectification): share decideFromDossier across projections and treat a sole candidate as a close, not a tie
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
} from "../src/lib/rectification-agentic/v9/varga-observations.ts";
|
||||
import { WINDOW_SCAN_DISPLAY_LAYER_ORDER } from "../src/lib/rectification-agentic/v9/refinement-packet.ts";
|
||||
import { RECTIFICATION_SKILL_VERSION } from "../src/lib/rectification-agentic/v9/case-status.ts";
|
||||
import { decideRectification } from "../src/lib/rectification-agentic/core/rectification-decision.ts";
|
||||
import { readVedastroMinuteSensitiveStatus } from "../src/lib/rectification-agentic/v9/confirmation-gate.ts";
|
||||
import { authoritativeCandidateProjection } from "../src/lib/rectification-agentic/v9/inference-adapter.ts";
|
||||
import { createRectificationV9Tools, latestResultToolProjection } from "../src/mastra/rectification-v9-tools.ts";
|
||||
@@ -49,6 +50,14 @@ const FAMILY_ID = "44444444-4444-4444-8444-444444444443";
|
||||
const CAREER_ID = "44444444-4444-4444-8444-444444444444";
|
||||
const UNIQUE_MINUTE_COPY = /±5 分钟确定性/;
|
||||
|
||||
function collectDecision(candidates: readonly { time: string; relativeSupport?: number }[]) {
|
||||
return decideRectification({
|
||||
methodCoverageAll: false,
|
||||
trainingGateOpen: false,
|
||||
candidateScores: candidates.map((item) => ({ time: item.time, score: item.relativeSupport ?? 0 })),
|
||||
});
|
||||
}
|
||||
|
||||
const DYNAMIC_STYLE_OPTIONS = [
|
||||
{ label: "明确发生且时间吻合", answer_class: "yes" as const },
|
||||
{ label: "发生过但程度较弱", answer_class: "weak_yes" as const },
|
||||
@@ -864,7 +873,7 @@ test("read-case follows method plan and keeps D9/D10 type tables when SQL missin
|
||||
confirmation_allowed: boolean;
|
||||
indistinguishable_width_minutes: number;
|
||||
window_scan: { d9_candidates_differ: boolean } | null;
|
||||
session_outcome: { kind: string };
|
||||
session_outcome: string;
|
||||
};
|
||||
}>;
|
||||
}).execute({ caseId: CASE_ID, projection: "full_diagnostics" });
|
||||
@@ -881,7 +890,7 @@ test("read-case follows method plan and keeps D9/D10 type tables when SQL missin
|
||||
(projection as { next_user_action?: { on_user_stop?: { id?: string } } }).next_user_action?.on_user_stop?.id,
|
||||
"offer_provisional_range",
|
||||
);
|
||||
assert.equal(projection.latest_result.session_outcome.kind, "collect_evidence");
|
||||
assert.equal(projection.latest_result.session_outcome, "collect_evidence");
|
||||
assert.equal(projection.internal_observations.find((item) => item.layer === "d9")?.ask_theme, "relationship_style");
|
||||
assert.equal(projection.latest_result.confirmation_allowed, false);
|
||||
assert.ok(projection.latest_result.indistinguishable_width_minutes >= 25);
|
||||
@@ -1316,26 +1325,27 @@ test("public tool surface stays at 14 and new cases bind 10.0.13", () => {
|
||||
"8d7aa2d4bea0414e9a89ef908ccbc8c708c98f79f5b78ae4f7dc229b5f7dbb30",
|
||||
);
|
||||
assert.equal(deprecated.status, "deprecated");
|
||||
const plateau = latestResultToolProjection({
|
||||
resultId: RESULT_ID,
|
||||
candidates: [
|
||||
const plateauCandidates = [
|
||||
{ candidateId: CANDIDATE_ID, time: "04:45", rank: 1, relativeSupport: 40, tiedMinuteCount: 25 },
|
||||
{ candidateId: SECOND_CANDIDATE_ID, time: "04:46", rank: 2, relativeSupport: 35, tiedMinuteCount: 25 },
|
||||
{ candidateId: THIRD_CANDIDATE_ID, time: "04:47", rank: 3, relativeSupport: 25, tiedMinuteCount: 25 },
|
||||
],
|
||||
];
|
||||
const plateau = latestResultToolProjection({
|
||||
resultId: RESULT_ID,
|
||||
candidates: plateauCandidates,
|
||||
selectionAllowed: true,
|
||||
confirmationAllowed: true,
|
||||
representativeTime: "04:45",
|
||||
selectedTime: null,
|
||||
selectionKind: null,
|
||||
algorithmVersion: "rectification-v5",
|
||||
});
|
||||
}, collectDecision(plateauCandidates));
|
||||
assert.equal(plateau.confirmation_allowed, false);
|
||||
assert.equal(plateau.unique_minute_claim, false);
|
||||
assert.match(String(plateau.skill_verification_report), /Dasha \+ Gochara/);
|
||||
assert.match(String(plateau.skill_verification_report), /candidate_range_not_birth_time_truth/);
|
||||
assert.doesNotMatch(String(plateau.skill_verification_report), UNIQUE_MINUTE_COPY);
|
||||
assert.equal((plateau.session_outcome as { kind: string }).kind, "collect_evidence");
|
||||
assert.equal(plateau.session_outcome, "collect_evidence");
|
||||
const skill = readFileSync(new URL("../../skills/jyotish-birth-time-rectification/SKILL.md", import.meta.url), "utf8");
|
||||
assert.match(skill, /method_followup_plan/);
|
||||
assert.match(skill, /感情 → 事业 → 家人 → 职业 → 占问/);
|
||||
@@ -1383,14 +1393,14 @@ test("Mastra hides active candidates when the receipt range excludes one of them
|
||||
algorithmVersion: "rectification-v5",
|
||||
decisionReceipt: { inference_state: inferenceState },
|
||||
};
|
||||
const session = {
|
||||
methods: buildMethodFollowupPlan({ evidence: CLASSIC_COVERAGE }).methods,
|
||||
const session = decideRectification({
|
||||
methodCoverageAll: true,
|
||||
userStopped: true,
|
||||
candidateScores: candidates.map((item) => ({ time: item.time, score: item.relativeSupport })),
|
||||
holdoutValidation: "passed" as const,
|
||||
holdoutValidation: "passed",
|
||||
snapshotCurrent: true,
|
||||
trainingGateOpen: true,
|
||||
};
|
||||
});
|
||||
const valid = latestResultToolProjection(latest, session);
|
||||
assert.deepEqual((valid.candidates as typeof candidates).map((item) => item.time), ["05:00", "05:07"]);
|
||||
assert.equal(valid.selection_allowed, true);
|
||||
@@ -2836,9 +2846,9 @@ test("paused case with selection_allowed may offer the escape hatch", async () =
|
||||
accounting: accounting.client as never,
|
||||
});
|
||||
const projection = await (tools["rectification-offer-candidates"] as unknown as {
|
||||
execute(input: unknown): Promise<{ session_outcome: { kind: string } }>;
|
||||
execute(input: unknown): Promise<{ session_outcome: string }>;
|
||||
}).execute({ caseId: CASE_ID });
|
||||
assert.equal(projection.session_outcome.kind, "provisional_range_user_stopped");
|
||||
assert.equal(projection.session_outcome, "provisional_range_user_stopped");
|
||||
assert.equal(
|
||||
accounting.calls.some((call) =>
|
||||
call.fn === "transition_agentic_rectification_case_status"
|
||||
@@ -2949,9 +2959,9 @@ test("offer-candidates allows a 34/33/33 tie after method coverage when remainin
|
||||
accounting: accounting.client as never,
|
||||
});
|
||||
const projection = await (tools["rectification-offer-candidates"] as unknown as {
|
||||
execute(input: unknown): Promise<{ session_outcome: { kind: string } }>;
|
||||
execute(input: unknown): Promise<{ session_outcome: string }>;
|
||||
}).execute({ caseId: CASE_ID });
|
||||
assert.equal(projection.session_outcome.kind, "provisional_range");
|
||||
assert.equal(projection.session_outcome, "provisional_range");
|
||||
assert.equal(
|
||||
accounting.calls.some((call) =>
|
||||
call.fn === "transition_agentic_rectification_case_status"
|
||||
|
||||
Reference in New Issue
Block a user