QMD: use OpenClaw config types

main
Benjamin Jesuiter 2026-02-02 22:34:07 +01:00 committed by Vignesh
parent 3d1c3b78ec
commit 465536e811
5 changed files with 30 additions and 35 deletions

View File

@ -570,7 +570,7 @@ const FIELD_HELP: Record<string, string> = {
"agents.defaults.memorySearch.cache.enabled": "agents.defaults.memorySearch.cache.enabled":
"Cache chunk embeddings in SQLite to speed up reindexing and frequent updates (default: true).", "Cache chunk embeddings in SQLite to speed up reindexing and frequent updates (default: true).",
memory: "Memory backend configuration (global).", memory: "Memory backend configuration (global).",
"memory.backend": 'Memory backend ("builtin" for Moltbot embeddings, "qmd" for QMD sidecar).', "memory.backend": 'Memory backend ("builtin" for OpenClaw embeddings, "qmd" for QMD sidecar).',
"memory.citations": 'Default citation behavior ("auto", "on", or "off").', "memory.citations": 'Default citation behavior ("auto", "on", or "off").',
"memory.qmd.command": "Path to the qmd binary (default: resolves from PATH).", "memory.qmd.command": "Path to the qmd binary (default: resolves from PATH).",
"memory.qmd.includeDefaultMemory": "memory.qmd.includeDefaultMemory":

View File

@ -1,14 +1,12 @@
import path from "node:path"; import path from "node:path";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js"; import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import { resolveMemoryBackendConfig } from "./backend-config.js"; import { resolveMemoryBackendConfig } from "./backend-config.js";
describe("resolveMemoryBackendConfig", () => { describe("resolveMemoryBackendConfig", () => {
it("defaults to builtin backend when config missing", () => { it("defaults to builtin backend when config missing", () => {
const cfg = { agents: { defaults: { workspace: "/tmp/memory-test" } } } as MoltbotConfig; const cfg = { agents: { defaults: { workspace: "/tmp/memory-test" } } } as OpenClawConfig;
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" }); const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
expect(resolved.backend).toBe("builtin"); expect(resolved.backend).toBe("builtin");
expect(resolved.citations).toBe("auto"); expect(resolved.citations).toBe("auto");
@ -22,7 +20,7 @@ describe("resolveMemoryBackendConfig", () => {
backend: "qmd", backend: "qmd",
qmd: {}, qmd: {},
}, },
} as MoltbotConfig; } as OpenClawConfig;
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" }); const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
expect(resolved.backend).toBe("qmd"); expect(resolved.backend).toBe("qmd");
expect(resolved.qmd?.collections.length).toBeGreaterThanOrEqual(3); expect(resolved.qmd?.collections.length).toBeGreaterThanOrEqual(3);
@ -39,7 +37,7 @@ describe("resolveMemoryBackendConfig", () => {
command: '"/Applications/QMD Tools/qmd" --flag', command: '"/Applications/QMD Tools/qmd" --flag',
}, },
}, },
} as MoltbotConfig; } as OpenClawConfig;
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" }); const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
expect(resolved.qmd?.command).toBe("/Applications/QMD Tools/qmd"); expect(resolved.qmd?.command).toBe("/Applications/QMD Tools/qmd");
}); });
@ -62,7 +60,7 @@ describe("resolveMemoryBackendConfig", () => {
], ],
}, },
}, },
} as MoltbotConfig; } as OpenClawConfig;
const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" }); const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" });
const custom = resolved.qmd?.collections.find((c) => c.name.startsWith("custom-notes")); const custom = resolved.qmd?.collections.find((c) => c.name.startsWith("custom-notes"));
expect(custom).toBeDefined(); expect(custom).toBeDefined();

View File

@ -1,15 +1,14 @@
import path from "node:path"; import path from "node:path";
import type { OpenClawConfig } from "../config/config.js";
import { parseDurationMs } from "../cli/parse-duration.js"; import type { SessionSendPolicyConfig } from "../config/types.base.js";
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import type { MoltbotConfig } from "../config/config.js";
import type { import type {
MemoryBackend, MemoryBackend,
MemoryCitationsMode, MemoryCitationsMode,
MemoryQmdConfig, MemoryQmdConfig,
MemoryQmdIndexPath, MemoryQmdIndexPath,
} from "../config/types.memory.js"; } from "../config/types.memory.js";
import type { SessionSendPolicyConfig } from "../config/types.base.js"; import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import { parseDurationMs } from "../cli/parse-duration.js";
import { resolveUserPath } from "../utils.js"; import { resolveUserPath } from "../utils.js";
import { splitShellArgs } from "../utils/shell-argv.js"; import { splitShellArgs } from "../utils/shell-argv.js";
@ -215,7 +214,7 @@ function resolveDefaultCollections(
} }
export function resolveMemoryBackendConfig(params: { export function resolveMemoryBackendConfig(params: {
cfg: MoltbotConfig; cfg: OpenClawConfig;
agentId: string; agentId: string;
}): ResolvedMemoryBackendConfig { }): ResolvedMemoryBackendConfig {
const backend = params.cfg.memory?.backend ?? DEFAULT_BACKEND; const backend = params.cfg.memory?.backend ?? DEFAULT_BACKEND;

View File

@ -1,8 +1,7 @@
import { EventEmitter } from "node:events";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import { EventEmitter } from "node:events";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("node:child_process", () => { vi.mock("node:child_process", () => {
@ -31,7 +30,7 @@ vi.mock("node:child_process", () => {
}); });
import { spawn as mockedSpawn } from "node:child_process"; import { spawn as mockedSpawn } from "node:child_process";
import type { MoltbotConfig } from "../config/config.js"; import type { OpenClawConfig } from "../config/config.js";
import { resolveMemoryBackendConfig } from "./backend-config.js"; import { resolveMemoryBackendConfig } from "./backend-config.js";
import { QmdMemoryManager } from "./qmd-manager.js"; import { QmdMemoryManager } from "./qmd-manager.js";
@ -41,7 +40,7 @@ describe("QmdMemoryManager", () => {
let tmpRoot: string; let tmpRoot: string;
let workspaceDir: string; let workspaceDir: string;
let stateDir: string; let stateDir: string;
let cfg: MoltbotConfig; let cfg: OpenClawConfig;
const agentId = "main"; const agentId = "main";
beforeEach(async () => { beforeEach(async () => {
@ -64,7 +63,7 @@ describe("QmdMemoryManager", () => {
paths: [{ path: workspaceDir, pattern: "**/*.md", name: "workspace" }], paths: [{ path: workspaceDir, pattern: "**/*.md", name: "workspace" }],
}, },
}, },
} as MoltbotConfig; } as OpenClawConfig;
}); });
afterEach(async () => { afterEach(async () => {
@ -111,7 +110,7 @@ describe("QmdMemoryManager", () => {
}, },
}, },
}, },
} as MoltbotConfig; } as OpenClawConfig;
const resolved = resolveMemoryBackendConfig({ cfg, agentId }); const resolved = resolveMemoryBackendConfig({ cfg, agentId });
const manager = await QmdMemoryManager.create({ cfg, agentId, resolved }); const manager = await QmdMemoryManager.create({ cfg, agentId, resolved });
expect(manager).toBeTruthy(); expect(manager).toBeTruthy();

View File

@ -2,18 +2,7 @@ import { spawn } from "node:child_process";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import type { OpenClawConfig } from "../config/config.js";
import type { MoltbotConfig } from "../config/config.js";
import { resolveStateDir } from "../config/paths.js";
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import {
listSessionFilesForAgent,
buildSessionEntry,
type SessionFileEntry,
} from "./session-files.js";
import { parseAgentSessionKey } from "../sessions/session-key-utils.js";
import { requireNodeSqlite } from "./sqlite.js";
import type { import type {
MemoryEmbeddingProbeResult, MemoryEmbeddingProbeResult,
MemoryProviderStatus, MemoryProviderStatus,
@ -22,6 +11,16 @@ import type {
MemorySource, MemorySource,
MemorySyncProgressUpdate, MemorySyncProgressUpdate,
} from "./types.js"; } from "./types.js";
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import { resolveStateDir } from "../config/paths.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { parseAgentSessionKey } from "../sessions/session-key-utils.js";
import {
listSessionFilesForAgent,
buildSessionEntry,
type SessionFileEntry,
} from "./session-files.js";
import { requireNodeSqlite } from "./sqlite.js";
type SqliteDatabase = import("node:sqlite").DatabaseSync; type SqliteDatabase = import("node:sqlite").DatabaseSync;
import type { ResolvedMemoryBackendConfig, ResolvedQmdConfig } from "./backend-config.js"; import type { ResolvedMemoryBackendConfig, ResolvedQmdConfig } from "./backend-config.js";
@ -51,7 +50,7 @@ type SessionExporterConfig = {
export class QmdMemoryManager implements MemorySearchManager { export class QmdMemoryManager implements MemorySearchManager {
static async create(params: { static async create(params: {
cfg: MoltbotConfig; cfg: OpenClawConfig;
agentId: string; agentId: string;
resolved: ResolvedMemoryBackendConfig; resolved: ResolvedMemoryBackendConfig;
}): Promise<QmdMemoryManager | null> { }): Promise<QmdMemoryManager | null> {
@ -62,7 +61,7 @@ export class QmdMemoryManager implements MemorySearchManager {
return manager; return manager;
} }
private readonly cfg: MoltbotConfig; private readonly cfg: OpenClawConfig;
private readonly agentId: string; private readonly agentId: string;
private readonly qmd: ResolvedQmdConfig; private readonly qmd: ResolvedQmdConfig;
private readonly workspaceDir: string; private readonly workspaceDir: string;
@ -88,7 +87,7 @@ export class QmdMemoryManager implements MemorySearchManager {
private lastEmbedAt: number | null = null; private lastEmbedAt: number | null = null;
private constructor(params: { private constructor(params: {
cfg: MoltbotConfig; cfg: OpenClawConfig;
agentId: string; agentId: string;
resolved: ResolvedQmdConfig; resolved: ResolvedQmdConfig;
}) { }) {