Files
Jyotisha/frontend/tests/rectification-spoken-answer.test.ts
T
Jesse_Chen f03a2706b4 fix(web): split rectification process talk from the spoken reply
Keep provider thinking off, classify CoT as 思考, and stop remounted sessions from firing a second opening.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-23 10:14:35 +08:00

75 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from "node:assert/strict";
import test from "node:test";
import {
finalizeRectificationSpokenAndThinking,
nextStableChannelDelta,
splitRectificationSpokenAndThinking,
} from "../src/lib/rectification-agentic/v9/spoken-answer.ts";
test("a plain spoken follow-up stays on the answer channel", () => {
const spoken = [
"记下了,大约六岁入学小学。",
"接下来你大概哪一年上的初中?说个大概年份或范围就行。",
].join("\n\n");
assert.deepEqual(splitRectificationSpokenAndThinking(spoken), {
thinking: "",
spoken,
});
});
test("process self-talk leaves the spoken conclusion on the answer channel", () => {
const processTalk = [
"用户提到先给了一个很晚的年份,后又改口说六岁入学。这里有个明显的内部矛盾。",
"但按 skill 规则,日期精度真实保留,不得猜补。datePrecision 用 yearoccurredFrom 只能按用户原话来。",
"我决定先按六岁入学记下来,再在正文里确认那句晚年份是不是口误。",
"让我调用 batch 写入 education_start。",
].join("\n\n");
const spoken = [
"入学小学这条先按大约六岁记下。你第一句提到的那个很晚的年份,我理解是口误对吗?",
"接下来你大概哪一年上的初中?说个大概年份或范围就行。",
].join("\n\n");
assert.deepEqual(splitRectificationSpokenAndThinking(`${processTalk}\n\n${spoken}`), {
thinking: processTalk,
spoken,
});
});
test("English process talk is classified as thinking, not the spoken answer", () => {
const split = splitRectificationSpokenAndThinking([
"The proposedKind value was rejected. Retrying with education_start.",
"记下了,那年九月上大学。",
].join("\n\n"));
assert.match(split.thinking, /proposedKind/);
assert.equal(split.spoken, "记下了,那年九月上大学。");
});
test("stable channel deltas only emit the newly classified suffix", () => {
assert.equal(nextStableChannelDelta("", "先核对升学年份。"), "先核对升学年份。");
assert.equal(
nextStableChannelDelta("先核对升学年份。", "先核对升学年份。\n\n再问初中。"),
"\n\n再问初中。",
);
assert.equal(nextStableChannelDelta("先核对升学年份。", "另一段"), "");
});
test("a lone process paragraph stays in thinking until a spoken conclusion arrives", () => {
const processTalk = "用户提到先给了一个很晚的年份。这里有个明显的内部矛盾。";
assert.deepEqual(splitRectificationSpokenAndThinking(`${processTalk}\n\n`), {
thinking: processTalk,
spoken: "",
});
});
test("all-process text keeps a spoken fallback only when the turn is finalized", () => {
const first = "用户提到先给了一个很晚的年份。这里有个明显的内部矛盾。";
const last = "但按 skill 规则,日期精度真实保留,不得猜补。";
assert.deepEqual(finalizeRectificationSpokenAndThinking(`${first}\n\n${last}`), {
thinking: first,
spoken: last,
});
});