fix(rectification): bind quality cards to the followup probe
Graduation no longer gets the college-experience question, and identical D24 splits only ask once. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -100,6 +100,7 @@ export type ChoiceCardFollowup = Readonly<{
|
||||
choice_kind?: EventProbeChoiceKind;
|
||||
style_options?: readonly EventProbeStyleOption[];
|
||||
semantic_key?: string;
|
||||
probe_id?: string;
|
||||
}>;
|
||||
|
||||
export type ChoiceCardEvidence = Readonly<{
|
||||
@@ -230,12 +231,28 @@ function followupDomain(followup: ChoiceCardFollowup): string | null {
|
||||
return THEME_DOMAIN[followup.ask_theme] ?? null;
|
||||
}
|
||||
|
||||
function probeMatchesId(item: DiscriminatingEventProbe, probeId: string): boolean {
|
||||
return item.semantic_key === probeId;
|
||||
}
|
||||
|
||||
function pickProbe(
|
||||
probes: readonly DiscriminatingEventProbe[] | undefined,
|
||||
domain: string | null,
|
||||
followup?: ChoiceCardFollowup,
|
||||
): DiscriminatingEventProbe | null {
|
||||
if (!probes?.length) return null;
|
||||
const probeId = followup?.probe_id?.trim() ?? "";
|
||||
const semanticKey = followup?.semantic_key?.trim() ?? "";
|
||||
const hasKey = Boolean(probeId || semanticKey);
|
||||
if (probeId) {
|
||||
const byId = probes.find((item) => probeMatchesId(item, probeId));
|
||||
if (byId) return byId;
|
||||
}
|
||||
if (semanticKey) {
|
||||
const keyed = probes.find((item) => item.semantic_key === semanticKey);
|
||||
if (keyed) return keyed;
|
||||
}
|
||||
if (hasKey) return null;
|
||||
const inDomain = domain ? probes.filter((item) => item.domain === domain) : [...probes];
|
||||
const pool = inDomain.length > 0 ? inDomain : probes;
|
||||
if (followup?.choice_kind === "event_quality") {
|
||||
@@ -244,10 +261,6 @@ function pickProbe(
|
||||
);
|
||||
if (quality) return quality;
|
||||
}
|
||||
if (followup?.semantic_key) {
|
||||
const keyed = pool.find((item) => item.semantic_key === followup.semantic_key);
|
||||
if (keyed) return keyed;
|
||||
}
|
||||
return pool[0] ?? probes[0] ?? null;
|
||||
}
|
||||
|
||||
@@ -386,8 +399,10 @@ export function buildChoiceFrame(
|
||||
const skipQuestion = skipThisProbe
|
||||
|| followup.intent === "out_of_sample_check"
|
||||
|| followup.source === "oos_blind";
|
||||
const probeKey = followup.semantic_key?.trim() || followup.probe_id?.trim() || "";
|
||||
const questionBase = `${followup.method_id}:${followup.ask_theme}:${scoring ? "score" : "holdout"}`;
|
||||
return {
|
||||
question_id: `${followup.method_id}:${followup.ask_theme}:${scoring ? "score" : "holdout"}`,
|
||||
question_id: probeKey ? `${questionBase}:${probeKey}` : questionBase,
|
||||
method_id: followup.method_id,
|
||||
period: periodFor(input.evidence, domain, input.probes, input.birthDate, followup),
|
||||
prompt: hypothesis.prompt,
|
||||
|
||||
@@ -1666,3 +1666,130 @@ test("GET does not mint a tap card from an out-of-sample spoken collect focus",
|
||||
});
|
||||
assert.equal(card, null);
|
||||
});
|
||||
|
||||
const EDUCATION_QUALITY_OPTIONS = [
|
||||
{ label: "发挥明显失常", answer_class: "yes" },
|
||||
{ label: "只是将就调剂", answer_class: "weak_yes" },
|
||||
{ label: "基本如愿录取", answer_class: "no" },
|
||||
{ label: "当时说不清楚", answer_class: "unsure" },
|
||||
] as const;
|
||||
|
||||
const QUALITY_SPLIT_OUTCOMES = [
|
||||
{ answer_class: "yes", supports: ["05:00", "05:01"], conflicts: ["05:10", "05:11"] },
|
||||
{ answer_class: "weak_yes", supports: ["05:00", "05:01"], conflicts: ["05:10", "05:11"] },
|
||||
{ answer_class: "no", supports: ["05:10", "05:11"], conflicts: ["05:00", "05:01"] },
|
||||
{ answer_class: "unsure", supports: [], conflicts: [] },
|
||||
] as const;
|
||||
|
||||
function educationQualityProbe(input: {
|
||||
semanticKey: string;
|
||||
evidenceId: string;
|
||||
year: number;
|
||||
month: number;
|
||||
meaning: string;
|
||||
dateLabel: string;
|
||||
}): DiscriminatingEventProbe {
|
||||
return {
|
||||
year: input.year,
|
||||
month: input.month,
|
||||
year_label: `${input.year} 年 ${input.month} 月前后`,
|
||||
domain: "education",
|
||||
event_family: "学业或考试发挥失常、压力特别大",
|
||||
source: "known_event_quality",
|
||||
tracks: ["vimshottari", "narayana"],
|
||||
tracks_agree: true,
|
||||
unique_minute_claim: false,
|
||||
user_meaning: input.meaning,
|
||||
role: "distinguish",
|
||||
phase: "candidate_discriminator",
|
||||
information_gain: 0.5,
|
||||
semantic_key: input.semanticKey,
|
||||
candidate_split_hash: `${input.semanticKey}:split`,
|
||||
target_evidence_id: input.evidenceId,
|
||||
display_date_label: input.dateLabel,
|
||||
choice_kind: "event_quality",
|
||||
style_options: EDUCATION_QUALITY_OPTIONS,
|
||||
expected_outcomes: QUALITY_SPLIT_OUTCOMES,
|
||||
candidate_ids: ["05:00", "05:01", "05:10", "05:11"],
|
||||
};
|
||||
}
|
||||
|
||||
test("event_quality cards bind to the followup probe, not the first same-kind probe", () => {
|
||||
const startProbe = educationQualityProbe({
|
||||
semanticKey: "education.2014.known_event_quality",
|
||||
evidenceId: "11111111-1111-4111-8111-111111111111",
|
||||
year: 2014,
|
||||
month: 9,
|
||||
dateLabel: "2014 年 9 月",
|
||||
meaning: "2014 年 9 月那次上大学,更接近如愿、将就调剂、发挥失常还是说不清。只问那次经历的实际体验,不得改时间范围。",
|
||||
});
|
||||
const laterProbe = educationQualityProbe({
|
||||
semanticKey: "education.2018.known_event_quality",
|
||||
evidenceId: "22222222-2222-4222-8222-222222222222",
|
||||
year: 2018,
|
||||
month: 6,
|
||||
dateLabel: "2018 年 6 月",
|
||||
meaning: "2018 年 6 月那次上大学,更接近如愿、将就调剂、发挥失常还是说不清。只问那次经历的实际体验,不得改时间范围。",
|
||||
});
|
||||
const probes = [startProbe, laterProbe];
|
||||
const laterFrame = buildChoiceFrame({
|
||||
method_id: "d5_education",
|
||||
ask_theme: "education_style",
|
||||
domain: "education",
|
||||
user_prompt_hint: "unused",
|
||||
intent: "distinguish_candidates",
|
||||
choice_kind: "event_quality",
|
||||
semantic_key: laterProbe.semantic_key,
|
||||
probe_id: laterProbe.semantic_key,
|
||||
style_options: EDUCATION_QUALITY_OPTIONS,
|
||||
}, { probes });
|
||||
assert.ok(laterFrame);
|
||||
assert.match(laterFrame.question_id, /education\.2018\.known_event_quality/);
|
||||
assert.doesNotMatch(laterFrame.question_id, /education\.2014\.known_event_quality/);
|
||||
assert.match(laterFrame.period, /2018 年 6 月/);
|
||||
assert.doesNotMatch(laterFrame.period, /2014/);
|
||||
assert.match(laterFrame.prompt, /2018 年 6 月那次上大学/);
|
||||
assert.doesNotMatch(laterFrame.prompt, /2014/);
|
||||
assert.match(laterFrame.why, /2018 年 6 月那次上大学/);
|
||||
assert.doesNotMatch(laterFrame.why, /2014/);
|
||||
|
||||
const startFrame = buildChoiceFrame({
|
||||
method_id: "d5_education",
|
||||
ask_theme: "education_style",
|
||||
domain: "education",
|
||||
user_prompt_hint: "unused",
|
||||
intent: "distinguish_candidates",
|
||||
choice_kind: "event_quality",
|
||||
semantic_key: startProbe.semantic_key,
|
||||
probe_id: startProbe.semantic_key,
|
||||
style_options: EDUCATION_QUALITY_OPTIONS,
|
||||
}, { probes });
|
||||
assert.ok(startFrame);
|
||||
assert.match(startFrame.question_id, /education\.2014\.known_event_quality/);
|
||||
assert.match(startFrame.period, /2014 年 9 月/);
|
||||
assert.match(startFrame.prompt, /2014 年 9 月那次上大学/);
|
||||
assert.match(startFrame.why, /2014 年 9 月那次上大学/);
|
||||
assert.doesNotMatch(startFrame.prompt, /2018/);
|
||||
});
|
||||
|
||||
test("event_quality followup with a missing probe key does not fall back to another quality probe", () => {
|
||||
const startProbe = educationQualityProbe({
|
||||
semanticKey: "education.2014.known_event_quality",
|
||||
evidenceId: "11111111-1111-4111-8111-111111111111",
|
||||
year: 2014,
|
||||
month: 9,
|
||||
dateLabel: "2014 年 9 月",
|
||||
meaning: "2014 年 9 月那次上大学,更接近如愿、将就调剂、发挥失常还是说不清。只问那次经历的实际体验,不得改时间范围。",
|
||||
});
|
||||
const frame = buildChoiceFrame({
|
||||
method_id: "d5_education",
|
||||
ask_theme: "education_style",
|
||||
domain: "education",
|
||||
user_prompt_hint: "unused",
|
||||
choice_kind: "event_quality",
|
||||
semantic_key: "education.2018.known_event_quality",
|
||||
probe_id: "education.2018.known_event_quality",
|
||||
style_options: EDUCATION_QUALITY_OPTIONS,
|
||||
}, { probes: [startProbe] });
|
||||
assert.equal(frame, null);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user