import { vi } from "vitest"; export type SearchImpl = () => Promise; export type MemoryReadParams = { relPath: string; from?: number; lines?: number }; export type MemoryReadResult = { text: string; path: string }; type MemoryBackend = "builtin" | "qmd"; let backend: MemoryBackend = "builtin"; let searchImpl: SearchImpl = async () => []; let readFileImpl: (params: MemoryReadParams) => Promise = async (params) => ({ text: "", path: params.relPath, }); const stubManager = { search: vi.fn(async () => await searchImpl()), readFile: vi.fn(async (params: MemoryReadParams) => await readFileImpl(params)), 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(), }; const getMemorySearchManagerMock = vi.fn(async () => ({ manager: stubManager })); const readAgentMemoryFileMock = vi.fn( async (params: MemoryReadParams) => await readFileImpl(params), ); const { memoryIndexModuleId, memoryToolsRuntimeModuleId } = vi.hoisted(() => ({ memoryIndexModuleId: "../../extensions/memory-core/src/memory/index.js", memoryToolsRuntimeModuleId: "../../extensions/memory-core/src/tools.runtime.js", })); vi.mock(memoryIndexModuleId, () => ({ getMemorySearchManager: getMemorySearchManagerMock, })); vi.mock("../../packages/memory-host-sdk/src/host/read-file.js", () => ({ readAgentMemoryFile: readAgentMemoryFileMock, })); vi.mock(memoryToolsRuntimeModuleId, () => ({ resolveMemoryBackendConfig: ({ cfg, }: { cfg?: { memory?: { backend?: string; qmd?: unknown } }; }) => ({ backend, qmd: cfg?.memory?.qmd, }), getMemorySearchManager: getMemorySearchManagerMock, readAgentMemoryFile: readAgentMemoryFileMock, })); export function setMemoryBackend(next: MemoryBackend): void { backend = next; } export function setMemorySearchImpl(next: SearchImpl): void { searchImpl = next; } export function setMemoryReadFileImpl( next: (params: MemoryReadParams) => Promise, ): void { readFileImpl = next; } export function resetMemoryToolMockState(overrides?: { backend?: MemoryBackend; searchImpl?: SearchImpl; readFileImpl?: (params: MemoryReadParams) => Promise; }): void { backend = overrides?.backend ?? "builtin"; searchImpl = overrides?.searchImpl ?? (async () => []); readFileImpl = overrides?.readFileImpl ?? (async (params: MemoryReadParams) => ({ text: "", path: params.relPath })); vi.clearAllMocks(); } export function getMemorySearchManagerMockCalls(): number { return getMemorySearchManagerMock.mock.calls.length; } export function getReadAgentMemoryFileMockCalls(): number { return readAgentMemoryFileMock.mock.calls.length; }