7f82428b44
Python and TypeScript now share a four-option probe contract, persist Focus before asking, and pick the highest-value renderable probe instead of preferring low-gain career events over D24. Co-authored-by: Cursor <cursoragent@cursor.com>
82 lines
2.9 KiB
TypeScript
82 lines
2.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
EXISTENCE_STYLE_OPTIONS,
|
|
QUALITY_STYLE_OPTIONS,
|
|
QUESTION_CONTRACT_VERSION,
|
|
completeStyleOptions,
|
|
isRenderableProbe,
|
|
rankDiscriminatorScore,
|
|
} from "../src/lib/rectification-agentic/v9/probe-question-contract.ts";
|
|
|
|
test("existence probes complete to four answer classes without engine style_options", () => {
|
|
const completed = completeStyleOptions({ choiceKind: "existence" });
|
|
assert.deepEqual(completed, [...EXISTENCE_STYLE_OPTIONS]);
|
|
assert.equal(QUESTION_CONTRACT_VERSION, "probe-question-v1");
|
|
});
|
|
|
|
test("event_quality probes use quality labels and still cover unsure", () => {
|
|
const completed = completeStyleOptions({ choiceKind: "event_quality" });
|
|
assert.deepEqual(completed, [...QUALITY_STYLE_OPTIONS]);
|
|
assert.equal(completed?.some((item) => item.answer_class === "unsure"), true);
|
|
});
|
|
|
|
test("varga-style probes stay dynamic and fail closed without two scoring labels", () => {
|
|
assert.equal(completeStyleOptions({
|
|
choiceKind: "varga_style",
|
|
styleOptions: [{ label: "巨蟹相处主动热情", answer_class: "yes" }],
|
|
}), null);
|
|
const completed = completeStyleOptions({
|
|
choiceKind: "varga_style",
|
|
styleOptions: [
|
|
{ label: "巨蟹相处主动热情", answer_class: "yes", sign: "巨蟹" },
|
|
{ label: "狮子独立强势", answer_class: "weak_yes", sign: "狮子" },
|
|
],
|
|
});
|
|
assert.equal(completed?.length, 4);
|
|
assert.equal(completed?.find((item) => item.answer_class === "no")?.label, "都不是这些特质");
|
|
assert.equal(completed?.find((item) => item.answer_class === "unsure")?.label, "这段记不清楚");
|
|
});
|
|
|
|
test("illegal clock or appearance copy cannot become a renderable probe", () => {
|
|
assert.equal(isRenderableProbe({
|
|
informationGain: 1.2,
|
|
candidateIds: ["05:00", "05:04"],
|
|
expectedOutcomeCount: 2,
|
|
choiceKind: "existence",
|
|
styleOptions: [
|
|
{ label: "08:12 左右发生", answer_class: "yes" },
|
|
],
|
|
}), true);
|
|
assert.equal(completeStyleOptions({
|
|
choiceKind: "existence",
|
|
styleOptions: [{ label: "08:12 左右发生", answer_class: "yes" }],
|
|
})?.find((item) => item.answer_class === "yes")?.label, "明确发生且时间吻合");
|
|
assert.equal(isRenderableProbe({
|
|
informationGain: 1.2,
|
|
candidateIds: ["05:00", "05:04"],
|
|
expectedOutcomeCount: 2,
|
|
choiceKind: "varga_style",
|
|
styleOptions: [
|
|
{ label: "外貌更接近第一种", answer_class: "yes" },
|
|
{ label: "相处更独立", answer_class: "weak_yes" },
|
|
],
|
|
}), false);
|
|
});
|
|
|
|
test("asked probes keep a novelty penalty so unused high-gain probes rank first", () => {
|
|
const askedCareer = rankDiscriminatorScore({
|
|
informationGain: 0.56,
|
|
asked: true,
|
|
candidateIds: ["05:00", "05:07"],
|
|
});
|
|
const unusedD24 = rankDiscriminatorScore({
|
|
informationGain: 2.5,
|
|
asked: false,
|
|
candidateIds: ["05:00", "05:07", "05:10"],
|
|
});
|
|
assert.ok(unusedD24 > askedCareer);
|
|
assert.ok(unusedD24 > 0.56);
|
|
});
|