| 1 | import { describe, expect, it } from "vite-plus/test"; |
| 2 | import { formatThreadTitleContext, limitTitleMessage } from "./threadTitleContext.ts"; |
| 3 | |
| 4 | describe("thread title context", () => { |
| 5 | it("keeps a user's scope change despite long assistant output", () => { |
| 6 | const result = formatThreadTitleContext([ |
| 7 | { role: "user", text: "Review QR sharing" }, |
| 8 | { role: "assistant", text: "Old findings. ".repeat(2_000) }, |
| 9 | { role: "user", text: "Focus on pairing expiry instead. Keep remote access working." }, |
| 10 | { role: "assistant", text: "Implementation details. ".repeat(2_000) }, |
| 11 | { role: "user", text: "Merge it when green." }, |
| 12 | ]); |
| 13 | expect(result.message.length).toBeLessThanOrEqual(8_000); |
| 14 | expect(result.message).toContain("USER:\nReview QR sharing"); |
| 15 | expect(result.message).toContain( |
| 16 | "USER:\nFocus on pairing expiry instead. Keep remote access working.", |
| 17 | ); |
| 18 | expect(result.message).toContain("USER:\nMerge it when green."); |
| 19 | expect(result.message).toContain("ASSISTANT:\nImplementation details."); |
| 20 | }); |
| 21 | |
| 22 | it("retains both ends and role labels in long user messages", () => { |
| 23 | const result = formatThreadTitleContext([ |
| 24 | { role: "system", text: "System instructions" }, |
| 25 | { role: "user", text: `Fix Android pairing. ${"logs ".repeat(3_000)}Keep iOS behavior.` }, |
| 26 | { role: "assistant", text: "Found the cause." }, |
| 27 | ]); |
| 28 | expect(result.message).toContain("USER:\nFix Android pairing."); |
| 29 | expect(result.message).toContain("Keep iOS behavior."); |
| 30 | expect(result.message).toContain("ASSISTANT:\nFound the cause."); |
| 31 | expect(result.message).not.toContain("System instructions"); |
| 32 | expect(result.message.match(/USER:/g)).toHaveLength(1); |
| 33 | }); |
| 34 | |
| 35 | it("preserves short conversations unchanged and handles tiny budgets", () => { |
| 36 | expect( |
| 37 | formatThreadTitleContext([ |
| 38 | { role: "user", text: "Fix pairing" }, |
| 39 | { role: "assistant", text: "The QR token expired." }, |
| 40 | ]).message, |
| 41 | ).toBe("USER:\nFix pairing\n\nASSISTANT:\nThe QR token expired."); |
| 42 | expect(limitTitleMessage("x".repeat(100), 0)).toBe(""); |
| 43 | for (let budget = 1; budget < 40; budget++) { |
| 44 | expect(limitTitleMessage("x".repeat(100), budget).length).toBeLessThanOrEqual(budget); |
| 45 | } |
| 46 | expect(formatThreadTitleContext([])).toEqual({ message: "", attachments: [] }); |
| 47 | }); |
| 48 | |
| 49 | it("omits reasoning traces from generated titles", () => { |
| 50 | expect( |
| 51 | formatThreadTitleContext([ |
| 52 | { role: "user", text: "Fix pairing" }, |
| 53 | { role: "reasoning", text: "Consider token expiry, then the QR payload." }, |
| 54 | { role: "assistant", text: "The QR token expired." }, |
| 55 | ]).message, |
| 56 | ).toBe("USER:\nFix pairing\n\nASSISTANT:\nThe QR token expired."); |
| 57 | }); |
| 58 | }); |