import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import { generateSessionTitle, sanitizeSessionTitle, shouldGenerateSessionTitle, } from "../src/lib/session-title-agent.ts"; import { consultationAgentPublicEventSchema } from "../src/lib/consultation-agent-events.ts"; test("sanitizeSessionTitle strips quotes and trailing punctuation", () => { assert.equal(sanitizeSessionTitle("「半年内换工作时机」。"), "半年内换工作时机"); assert.equal(sanitizeSessionTitle("\"半年内换工作时机\""), "半年内换工作时机"); }); test("sanitizeSessionTitle clips titles longer than 14 characters", () => { assert.equal(sanitizeSessionTitle("今年下半年要不要换工作以及去哪座城市"), "今年下半年要不要换工作以及去"); }); test("sanitizeSessionTitle rejects short, wrapped, generic, or birth-stamped titles", () => { assert.equal(sanitizeSessionTitle("问"), null); assert.equal(sanitizeSessionTitle("换工作\n时机"), null); assert.equal(sanitizeSessionTitle("新对话"), null); assert.equal(sanitizeSessionTitle("1990年3月换工作"), null); assert.equal(sanitizeSessionTitle("凌晨 04:50 的节奏"), null); }); test("sanitizeSessionTitle keeps a valid summary", () => { assert.equal(sanitizeSessionTitle("半年内换工作时机"), "半年内换工作时机"); }); test("shouldGenerateSessionTitle only runs on a first-round auto title", () => { assert.equal(shouldGenerateSessionTitle({ title: "新对话", sessionType: "consultation" }, []), true); assert.equal(shouldGenerateSessionTitle({ title: "我想问一下最近半年换工…", sessionType: "consultation" }, []), true); assert.equal(shouldGenerateSessionTitle({ title: "新对话", sessionType: "consultation" }, [{ role: "user" }]), false); assert.equal(shouldGenerateSessionTitle({ title: "新对话", sessionType: "birth_time_rectification" }, []), false); assert.equal(shouldGenerateSessionTitle({ title: "9月6日 · 今日节奏", sessionType: "consultation" }, []), false); assert.equal(shouldGenerateSessionTitle({ title: "半年内换工作时机", sessionType: "consultation" }, []), false); }); test("generateSessionTitle times out to null and keeps the timer ref'd", async () => { const source = readFileSync(new URL("../src/lib/session-title-agent.ts", import.meta.url), "utf8"); assert.doesNotMatch(source, /AbortSignal\.timeout/); assert.doesNotMatch(source, /\.unref\(/); assert.match(source, /clearTimeout/); const pending = new Set(); let created = 0; const realSetTimeout = globalThis.setTimeout; const realClearTimeout = globalThis.clearTimeout; globalThis.setTimeout = ((handler: TimerHandler, delay?: number, ...args: unknown[]) => { created += 1; const id = realSetTimeout(handler, delay, ...args); pending.add(id); return id; }) as typeof setTimeout; globalThis.clearTimeout = ((id?: ReturnType) => { pending.delete(id); realClearTimeout(id); }) as typeof clearTimeout; try { const title = await generateSessionTitle({ question: "我想问一下最近半年换工作的时机", timeoutMs: 20, generateText: () => new Promise(() => {}), }); assert.equal(title, null); assert.ok(created >= 1); assert.equal(pending.size, 0); } finally { globalThis.setTimeout = realSetTimeout; globalThis.clearTimeout = realClearTimeout; } }); test("consultation public events include session.title", () => { const parsed = consultationAgentPublicEventSchema.parse({ type: "session.title", title: "半年内换工作时机", }); assert.equal(parsed.type, "session.title"); assert.equal(parsed.title, "半年内换工作时机"); });