Spaces:
Paused
Paused
| import { beforeEach, describe, expect, it, vi } from "vitest"; | |
| let backend: "builtin" | "qmd" = "builtin"; | |
| const stubManager = { | |
| search: vi.fn(async () => [ | |
| { | |
| path: "MEMORY.md", | |
| startLine: 5, | |
| endLine: 7, | |
| score: 0.9, | |
| snippet: "@@ -5,3 @@\nAssistant: noted", | |
| source: "memory" as const, | |
| }, | |
| ]), | |
| readFile: vi.fn(), | |
| status: () => ({ | |
| backend, | |
| files: 1, | |
| chunks: 1, | |
| dirty: false, | |
| workspaceDir: "/workspace", | |
| dbPath: "/workspace/.memory/index.sqlite", | |
| provider: "builtin", | |
| model: "builtin", | |
| requestedProvider: "builtin", | |
| sources: ["memory" as const], | |
| sourceCounts: [{ source: "memory" as const, files: 1, chunks: 1 }], | |
| }), | |
| sync: vi.fn(), | |
| probeVectorAvailability: vi.fn(async () => true), | |
| close: vi.fn(), | |
| }; | |
| vi.mock("../../memory/index.js", () => { | |
| return { | |
| getMemorySearchManager: async () => ({ manager: stubManager }), | |
| }; | |
| }); | |
| import { createMemorySearchTool } from "./memory-tool.js"; | |
| beforeEach(() => { | |
| vi.clearAllMocks(); | |
| }); | |
| describe("memory search citations", () => { | |
| it("appends source information when citations are enabled", async () => { | |
| backend = "builtin"; | |
| const cfg = { memory: { citations: "on" }, agents: { list: [{ id: "main", default: true }] } }; | |
| const tool = createMemorySearchTool({ config: cfg }); | |
| if (!tool) { | |
| throw new Error("tool missing"); | |
| } | |
| const result = await tool.execute("call_citations_on", { query: "notes" }); | |
| const details = result.details as { results: Array<{ snippet: string; citation?: string }> }; | |
| expect(details.results[0]?.snippet).toMatch(/Source: MEMORY.md#L5-L7/); | |
| expect(details.results[0]?.citation).toBe("MEMORY.md#L5-L7"); | |
| }); | |
| it("leaves snippet untouched when citations are off", async () => { | |
| backend = "builtin"; | |
| const cfg = { memory: { citations: "off" }, agents: { list: [{ id: "main", default: true }] } }; | |
| const tool = createMemorySearchTool({ config: cfg }); | |
| if (!tool) { | |
| throw new Error("tool missing"); | |
| } | |
| const result = await tool.execute("call_citations_off", { query: "notes" }); | |
| const details = result.details as { results: Array<{ snippet: string; citation?: string }> }; | |
| expect(details.results[0]?.snippet).not.toMatch(/Source:/); | |
| expect(details.results[0]?.citation).toBeUndefined(); | |
| }); | |
| it("clamps decorated snippets to qmd injected budget", async () => { | |
| backend = "qmd"; | |
| const cfg = { | |
| memory: { citations: "on", backend: "qmd", qmd: { limits: { maxInjectedChars: 20 } } }, | |
| agents: { list: [{ id: "main", default: true }] }, | |
| }; | |
| const tool = createMemorySearchTool({ config: cfg }); | |
| if (!tool) { | |
| throw new Error("tool missing"); | |
| } | |
| const result = await tool.execute("call_citations_qmd", { query: "notes" }); | |
| const details = result.details as { results: Array<{ snippet: string; citation?: string }> }; | |
| expect(details.results[0]?.snippet.length).toBeLessThanOrEqual(20); | |
| }); | |
| it("honors auto mode for direct chats", async () => { | |
| backend = "builtin"; | |
| const cfg = { | |
| memory: { citations: "auto" }, | |
| agents: { list: [{ id: "main", default: true }] }, | |
| }; | |
| const tool = createMemorySearchTool({ | |
| config: cfg, | |
| agentSessionKey: "agent:main:discord:dm:u123", | |
| }); | |
| if (!tool) { | |
| throw new Error("tool missing"); | |
| } | |
| const result = await tool.execute("auto_mode_direct", { query: "notes" }); | |
| const details = result.details as { results: Array<{ snippet: string }> }; | |
| expect(details.results[0]?.snippet).toMatch(/Source:/); | |
| }); | |
| it("suppresses citations for auto mode in group chats", async () => { | |
| backend = "builtin"; | |
| const cfg = { | |
| memory: { citations: "auto" }, | |
| agents: { list: [{ id: "main", default: true }] }, | |
| }; | |
| const tool = createMemorySearchTool({ | |
| config: cfg, | |
| agentSessionKey: "agent:main:discord:group:c123", | |
| }); | |
| if (!tool) { | |
| throw new Error("tool missing"); | |
| } | |
| const result = await tool.execute("auto_mode_group", { query: "notes" }); | |
| const details = result.details as { results: Array<{ snippet: string }> }; | |
| expect(details.results[0]?.snippet).not.toMatch(/Source:/); | |
| }); | |
| }); | |