2026-01-27 21:57:15 -08:00
|
|
|
import path from "node:path";
|
|
|
|
|
import { describe, expect, it } from "vitest";
|
2026-02-16 23:20:16 -05:00
|
|
|
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
|
2026-02-17 13:36:48 +09:00
|
|
|
import type { OpenClawConfig } from "../config/config.js";
|
2026-01-27 21:57:15 -08:00
|
|
|
import { resolveMemoryBackendConfig } from "./backend-config.js";
|
|
|
|
|
|
|
|
|
|
describe("resolveMemoryBackendConfig", () => {
|
|
|
|
|
it("defaults to builtin backend when config missing", () => {
|
2026-02-02 22:34:07 +01:00
|
|
|
const cfg = { agents: { defaults: { workspace: "/tmp/memory-test" } } } as OpenClawConfig;
|
2026-01-27 21:57:15 -08:00
|
|
|
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
|
|
|
|
|
expect(resolved.backend).toBe("builtin");
|
|
|
|
|
expect(resolved.citations).toBe("auto");
|
|
|
|
|
expect(resolved.qmd).toBeUndefined();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("resolves qmd backend with default collections", () => {
|
|
|
|
|
const cfg = {
|
|
|
|
|
agents: { defaults: { workspace: "/tmp/memory-test" } },
|
|
|
|
|
memory: {
|
|
|
|
|
backend: "qmd",
|
|
|
|
|
qmd: {},
|
|
|
|
|
},
|
2026-02-02 22:34:07 +01:00
|
|
|
} as OpenClawConfig;
|
2026-01-27 21:57:15 -08:00
|
|
|
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
|
|
|
|
|
expect(resolved.backend).toBe("qmd");
|
|
|
|
|
expect(resolved.qmd?.collections.length).toBeGreaterThanOrEqual(3);
|
|
|
|
|
expect(resolved.qmd?.command).toBe("qmd");
|
2026-02-13 22:44:56 -08:00
|
|
|
expect(resolved.qmd?.searchMode).toBe("search");
|
2026-01-27 21:57:15 -08:00
|
|
|
expect(resolved.qmd?.update.intervalMs).toBeGreaterThan(0);
|
2026-02-07 16:04:40 -08:00
|
|
|
expect(resolved.qmd?.update.waitForBootSync).toBe(false);
|
|
|
|
|
expect(resolved.qmd?.update.commandTimeoutMs).toBe(30_000);
|
|
|
|
|
expect(resolved.qmd?.update.updateTimeoutMs).toBe(120_000);
|
|
|
|
|
expect(resolved.qmd?.update.embedTimeoutMs).toBe(120_000);
|
2026-02-15 20:14:37 -08:00
|
|
|
const names = new Set((resolved.qmd?.collections ?? []).map((collection) => collection.name));
|
|
|
|
|
expect(names.has("memory-root-main")).toBe(true);
|
|
|
|
|
expect(names.has("memory-alt-main")).toBe(true);
|
|
|
|
|
expect(names.has("memory-dir-main")).toBe(true);
|
2026-01-27 21:57:15 -08:00
|
|
|
});
|
|
|
|
|
|
2026-02-02 18:57:16 +01:00
|
|
|
it("parses quoted qmd command paths", () => {
|
|
|
|
|
const cfg = {
|
|
|
|
|
agents: { defaults: { workspace: "/tmp/memory-test" } },
|
|
|
|
|
memory: {
|
|
|
|
|
backend: "qmd",
|
|
|
|
|
qmd: {
|
|
|
|
|
command: '"/Applications/QMD Tools/qmd" --flag',
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-02-02 22:34:07 +01:00
|
|
|
} as OpenClawConfig;
|
2026-02-02 18:57:16 +01:00
|
|
|
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
|
|
|
|
|
expect(resolved.qmd?.command).toBe("/Applications/QMD Tools/qmd");
|
|
|
|
|
});
|
|
|
|
|
|
2026-01-27 21:57:15 -08:00
|
|
|
it("resolves custom paths relative to workspace", () => {
|
|
|
|
|
const cfg = {
|
|
|
|
|
agents: {
|
|
|
|
|
defaults: { workspace: "/workspace/root" },
|
|
|
|
|
list: [{ id: "main", workspace: "/workspace/root" }],
|
|
|
|
|
},
|
|
|
|
|
memory: {
|
|
|
|
|
backend: "qmd",
|
|
|
|
|
qmd: {
|
|
|
|
|
paths: [
|
|
|
|
|
{
|
|
|
|
|
path: "notes",
|
|
|
|
|
name: "custom-notes",
|
|
|
|
|
pattern: "**/*.md",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-02-02 22:34:07 +01:00
|
|
|
} as OpenClawConfig;
|
2026-01-27 21:57:15 -08:00
|
|
|
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
|
|
|
|
|
const custom = resolved.qmd?.collections.find((c) => c.name.startsWith("custom-notes"));
|
|
|
|
|
expect(custom).toBeDefined();
|
|
|
|
|
const workspaceRoot = resolveAgentWorkspaceDir(cfg, "main");
|
|
|
|
|
expect(custom?.path).toBe(path.resolve(workspaceRoot, "notes"));
|
|
|
|
|
});
|
2026-02-07 16:04:40 -08:00
|
|
|
|
2026-02-15 20:14:37 -08:00
|
|
|
it("scopes qmd collection names per agent", () => {
|
|
|
|
|
const cfg = {
|
|
|
|
|
agents: {
|
|
|
|
|
defaults: { workspace: "/workspace/root" },
|
|
|
|
|
list: [
|
|
|
|
|
{ id: "main", default: true, workspace: "/workspace/root" },
|
|
|
|
|
{ id: "dev", workspace: "/workspace/dev" },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
memory: {
|
|
|
|
|
backend: "qmd",
|
|
|
|
|
qmd: {
|
|
|
|
|
includeDefaultMemory: true,
|
|
|
|
|
paths: [{ path: "notes", name: "workspace", pattern: "**/*.md" }],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
} as OpenClawConfig;
|
|
|
|
|
const mainResolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
|
|
|
|
|
const devResolved = resolveMemoryBackendConfig({ cfg, agentId: "dev" });
|
2026-02-16 05:32:35 +01:00
|
|
|
const mainNames = new Set(
|
|
|
|
|
(mainResolved.qmd?.collections ?? []).map((collection) => collection.name),
|
|
|
|
|
);
|
|
|
|
|
const devNames = new Set(
|
|
|
|
|
(devResolved.qmd?.collections ?? []).map((collection) => collection.name),
|
|
|
|
|
);
|
2026-02-15 20:14:37 -08:00
|
|
|
expect(mainNames.has("memory-dir-main")).toBe(true);
|
|
|
|
|
expect(devNames.has("memory-dir-dev")).toBe(true);
|
|
|
|
|
expect(mainNames.has("workspace-main")).toBe(true);
|
|
|
|
|
expect(devNames.has("workspace-dev")).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
2026-02-07 16:04:40 -08:00
|
|
|
it("resolves qmd update timeout overrides", () => {
|
|
|
|
|
const cfg = {
|
|
|
|
|
agents: { defaults: { workspace: "/tmp/memory-test" } },
|
|
|
|
|
memory: {
|
|
|
|
|
backend: "qmd",
|
|
|
|
|
qmd: {
|
|
|
|
|
update: {
|
|
|
|
|
waitForBootSync: true,
|
|
|
|
|
commandTimeoutMs: 12_000,
|
|
|
|
|
updateTimeoutMs: 480_000,
|
|
|
|
|
embedTimeoutMs: 360_000,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
} as OpenClawConfig;
|
|
|
|
|
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
|
|
|
|
|
expect(resolved.qmd?.update.waitForBootSync).toBe(true);
|
|
|
|
|
expect(resolved.qmd?.update.commandTimeoutMs).toBe(12_000);
|
|
|
|
|
expect(resolved.qmd?.update.updateTimeoutMs).toBe(480_000);
|
|
|
|
|
expect(resolved.qmd?.update.embedTimeoutMs).toBe(360_000);
|
|
|
|
|
});
|
2026-02-07 19:48:03 -08:00
|
|
|
|
|
|
|
|
it("resolves qmd search mode override", () => {
|
|
|
|
|
const cfg = {
|
|
|
|
|
agents: { defaults: { workspace: "/tmp/memory-test" } },
|
|
|
|
|
memory: {
|
|
|
|
|
backend: "qmd",
|
|
|
|
|
qmd: {
|
|
|
|
|
searchMode: "vsearch",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
} as OpenClawConfig;
|
|
|
|
|
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
|
|
|
|
|
expect(resolved.qmd?.searchMode).toBe("vsearch");
|
|
|
|
|
});
|
2026-01-27 21:57:15 -08:00
|
|
|
});
|