import { describe, expect, it, vi } from "vitest"; import type { AssistantCloud } from "./AssistantCloud"; import { generateThreadTitle } from "./generateThreadTitle"; const titleStream = (...chunks: { type: string; textDelta?: string }[]) => new ReadableStream({ start(controller) { for (const chunk of chunks) controller.enqueue(chunk); controller.close(); }, }); const createCloud = (stream: ReadableStream) => { const update = vi.fn().mockResolvedValue(undefined); const run = vi.fn().mockResolvedValue(stream); const cloud = { threads: { update }, runs: { stream: run }, } as unknown as AssistantCloud; return { cloud, update, run }; }; describe("generateThreadTitle", () => { it("accumulates text deltas and updates the thread title", async () => { const { cloud, run, update } = createCloud( titleStream( { type: "text-delta", textDelta: "Weather " }, { type: "text-delta", textDelta: "chat" }, ), ); await expect( generateThreadTitle(cloud, { threadId: "thread-1", messages: [ { role: "user", content: [{ type: "text", text: "What is the weather today?" }], }, ], }), ).resolves.toBe("Weather chat"); expect(run).toHaveBeenCalledExactlyOnceWith({ thread_id: "thread-1", assistant_id: "system/thread_title", messages: [ { role: "user", content: [{ type: "text", text: "What is the weather today?" }], }, ], }); expect(update).toHaveBeenCalledExactlyOnceWith("thread-1", { title: "Weather chat", }); }); it("returns null without updating when the stream has no text", async () => { const { cloud, update } = createCloud(titleStream()); await expect( generateThreadTitle(cloud, { threadId: "thread-1", messages: [], }), ).resolves.toBeNull(); expect(update).not.toHaveBeenCalled(); }); it("returns null without updating for a whitespace-only title", async () => { const { cloud, update } = createCloud( titleStream({ type: "text-delta", textDelta: " \n\t" }), ); await expect( generateThreadTitle(cloud, { threadId: "thread-1", messages: [], }), ).resolves.toBeNull(); expect(update).not.toHaveBeenCalled(); }); it("trims surrounding whitespace from a generated title", async () => { const { cloud, update } = createCloud( titleStream({ type: "text-delta", textDelta: " Weather chat \n" }), ); await expect( generateThreadTitle(cloud, { threadId: "thread-1", messages: [], }), ).resolves.toBe("Weather chat"); expect(update).toHaveBeenCalledExactlyOnceWith("thread-1", { title: "Weather chat", }); }); });