329f8a2109
The time card stayed under an earlier collect question, and the close said to just use a time for now. Keep the card on the delivery turn and present the analysis as this round's result. Co-authored-by: Cursor <cursoragent@cursor.com>
134 lines
4.5 KiB
TypeScript
134 lines
4.5 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
applyLiveCandidateOffer,
|
|
attachOfferResultToTurns,
|
|
persistedOfferFromTurn,
|
|
type TurnQuestion,
|
|
} from "../src/lib/rectification-agentic/v9/turn-question.ts";
|
|
|
|
function collect(status: "active" | "resolved"): TurnQuestion {
|
|
return {
|
|
focus_id: "focus-career",
|
|
question_id: "collect:career:collect_method_evidence",
|
|
kind: "collect_spoken",
|
|
prompt: "工作上呢,还记得哪年入职、换工作,或职责一下子变重吗?",
|
|
options: null,
|
|
status,
|
|
answer_option: null,
|
|
probe_id: null,
|
|
};
|
|
}
|
|
|
|
test("adopt offer skips an unanswered collect question and lands on the later narration", () => {
|
|
const attached = attachOfferResultToTurns([
|
|
{ id: "collect-turn", role: "assistant", question: collect("active") },
|
|
{ id: "user-turn", role: "user", question: null },
|
|
{ id: "adopt-turn", role: "assistant", question: null },
|
|
], {
|
|
resultId: "result-1",
|
|
canAdopt: true,
|
|
acceptedTime: null,
|
|
});
|
|
assert.equal(attached[0]?.offer_result_id, null);
|
|
assert.equal(attached[2]?.offer_result_id, "result-1");
|
|
});
|
|
|
|
test("adopt offer is not pinned onto a live collect question even if it is the only assistant turn", () => {
|
|
const attached = attachOfferResultToTurns([
|
|
{ id: "collect-turn", role: "assistant", question: collect("active") },
|
|
], {
|
|
resultId: "result-1",
|
|
canAdopt: true,
|
|
acceptedTime: null,
|
|
});
|
|
assert.equal(attached[0]?.offer_result_id, null);
|
|
});
|
|
|
|
test("live offer moves off a collect message once the adopt narration exists", () => {
|
|
const next = applyLiveCandidateOffer([
|
|
{
|
|
renderKey: "collect",
|
|
role: "assistant",
|
|
state: "settled",
|
|
text: "工作上呢,还记得哪年入职、换工作,或职责一下子变重吗?",
|
|
question: collect("resolved"),
|
|
candidateOffer: { resultId: "result-1" },
|
|
},
|
|
{
|
|
renderKey: "user",
|
|
role: "user",
|
|
state: "settled",
|
|
text: "2020 年 4 月实习然后 10 月离职",
|
|
},
|
|
{
|
|
renderKey: "adopt",
|
|
role: "assistant",
|
|
state: "settled",
|
|
text: "再问下去也分不出更准的时间了。眼下更站得住的是 05:15。这只是代表性候选,不是已确认的唯一出生分钟。我按你说的经历认真分析过了,下面是这次的结果。",
|
|
},
|
|
], { resultId: "result-1", canOffer: true, adopted: false });
|
|
assert.equal(next[0]?.candidateOffer, undefined);
|
|
assert.deepEqual(next[2]?.candidateOffer, { resultId: "result-1" });
|
|
});
|
|
|
|
test("live offer stays hidden while an unanswered collect question is still on screen", () => {
|
|
const next = applyLiveCandidateOffer([
|
|
{
|
|
renderKey: "collect",
|
|
role: "assistant",
|
|
state: "settled",
|
|
text: "工作上呢,还记得哪年入职、换工作,或职责一下子变重吗?",
|
|
question: collect("active"),
|
|
candidateOffer: { resultId: "result-1" },
|
|
},
|
|
], { resultId: "result-1", canOffer: true, adopted: false });
|
|
assert.equal(next[0]?.candidateOffer, undefined);
|
|
});
|
|
|
|
test("after adopt the offer stays on the original message", () => {
|
|
const next = applyLiveCandidateOffer([
|
|
{
|
|
renderKey: "offer",
|
|
role: "assistant",
|
|
state: "settled",
|
|
text: "我按你说的经历认真分析过了,下面是这次的结果。",
|
|
candidateOffer: { resultId: "result-1" },
|
|
},
|
|
{
|
|
renderKey: "verify",
|
|
role: "assistant",
|
|
state: "settled",
|
|
text: "2021 年前后,有没有家人结婚、添丁或住院?",
|
|
question: {
|
|
focus_id: "verify",
|
|
question_id: "reverse_verify:family:score",
|
|
kind: "reverse_verify",
|
|
prompt: "2021 年前后,有没有家人结婚、添丁或住院?",
|
|
options: null,
|
|
status: "active",
|
|
answer_option: null,
|
|
probe_id: null,
|
|
},
|
|
},
|
|
], { resultId: "result-2", canOffer: true, adopted: true });
|
|
assert.deepEqual(next[0]?.candidateOffer, { resultId: "result-2" });
|
|
assert.equal(next[1]?.candidateOffer, undefined);
|
|
});
|
|
|
|
test("hydrated turns drop a stale client offer when GET says this turn is not the owner", () => {
|
|
assert.equal(
|
|
persistedOfferFromTurn(null, { resultId: "result-1" }, true),
|
|
undefined,
|
|
);
|
|
assert.deepEqual(
|
|
persistedOfferFromTurn("result-2", { resultId: "result-1" }, true),
|
|
{ resultId: "result-2" },
|
|
);
|
|
assert.deepEqual(
|
|
persistedOfferFromTurn(null, { resultId: "result-1" }, false),
|
|
{ resultId: "result-1" },
|
|
);
|
|
});
|