Files
Jyotisha/frontend/tests/agent-reply.test.ts
T
Jesse_Chen 59559d4b24 fix(web): persist thinking, title sessions distinctly, and send follow-ups from the answer
Thinking disappeared on failure and never reached session storage. Keep the
sanitized chain on disk and on errors, and regroup the sidebar around reports,
charts, favorites, and dated history titles.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-22 09:10:47 +08:00

100 lines
3.6 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import { parseAgentReply, resolveSessionTitle } from "../src/lib/agent-reply.ts";
test("extracts a model-generated session title without exposing hidden metadata", () => {
// Given
const response = [
"你目前更适合先验证新的职业方向。",
'<!--AYANAM_SUGGESTIONS:["什么时候行动?","适合什么方向?","有哪些风险?"]-->',
"<!--AYANAM_TITLE:未来半年职业转型-->",
].join("\n");
// When
const reply = parseAgentReply(response);
// Then
assert.equal(reply.text, "你目前更适合先验证新的职业方向。");
assert.equal(reply.title, "未来半年职业转型");
});
test("rejects an overlong model-generated session title", () => {
// Given
const response = "回答正文\n<!--AYANAM_TITLE:这是一个明显超过合理长度并且不适合作为会话标题的模型输出标题-->";
// When
const reply = parseAgentReply(response);
// Then
assert.equal(reply.text, "回答正文");
assert.equal(reply.title, undefined);
});
test("accepts a concise English model-generated session title", () => {
// Given
const response = "Your next step is to test the market first.\n<!--AYANAM_TITLE:Career Change Timing-->";
// When
const reply = parseAgentReply(response);
// Then
assert.equal(reply.title, "Career Change Timing");
});
test("hides an incomplete metadata block while a reply is streaming", () => {
// Given
const response = "回答正文\n<!--AYANAM_TITLE:未来半年";
// When
const reply = parseAgentReply(response);
// Then
assert.equal(reply.text, "回答正文");
});
test("general no-birth-time replies keep a question-specific session title", () => {
assert.equal(resolveSessionTitle("工作变化的重点是什么?", "一般占星咨询"), "工作变化的重点是什么");
assert.equal(resolveSessionTitle("如何理解印度占星里的行星关系?"), "如何理解印度占星里的行星关系");
assert.equal(resolveSessionTitle("工作变化的重点是什么?", "事业方向与工作变化"), "事业方向与工作变化");
});
test("daily and topic consultations get distinct dated or domain titles", () => {
const at = new Date(2026, 7, 22, 8, 36);
assert.equal(
resolveSessionTitle("深入看今日", undefined, { entrypoint: "daily_starlanguage", at }),
"8月22日 · 今日节奏",
);
assert.equal(
resolveSessionTitle("深入看今日", undefined, {
entrypoint: "daily_starlanguage",
at,
existingTitles: ["8月22日 · 今日节奏"],
}),
"8月22日 · 今日节奏 08:36",
);
assert.equal(
resolveSessionTitle("请帮我梳理目前的事业方向和下一步重点。", undefined, { theme: "career", at }),
"事业 · 请帮我梳理目前的事业…",
);
assert.equal(
resolveSessionTitle("请用刚才采用的代表性出生时间看盘。", undefined, {
entrypoint: "birth_time_rectification",
at,
}),
"8月22日 · 生时校正",
);
});
test("a stored legacy suggestion block is stripped and never becomes suggested questions", () => {
// Answers written before the follow-up chips were removed still carry this block, and
// parsing must neither surface it as text nor revive it as a suggestion field.
const reply = parseAgentReply([
"可以先采用 05:07 作为当前排盘时间。",
'<!--AYANAM_SUGGESTIONS:["问题一","问题二","问题三"]-->',
].join("\n"));
assert.deepEqual(reply, { text: "可以先采用 05:07 作为当前排盘时间。", title: undefined });
assert.deepEqual(Object.keys(reply), ["text", "title"]);
});