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":
"Cache chunk embeddings in SQLite to speed up reindexing and frequent updates (default: true).",
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.qmd.command": "Path to the qmd binary (default: resolves from PATH).",
"memory.qmd.includeDefaultMemory":

View File

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

View File

@ -1,15 +1,14 @@
import path from "node:path";
import { parseDurationMs } from "../cli/parse-duration.js";
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
import type { MoltbotConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/config.js";
import type { SessionSendPolicyConfig } from "../config/types.base.js";
import type {
MemoryBackend,
MemoryCitationsMode,
MemoryQmdConfig,
MemoryQmdIndexPath,
} 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 { splitShellArgs } from "../utils/shell-argv.js";
@ -215,7 +214,7 @@ function resolveDefaultCollections(
}
export function resolveMemoryBackendConfig(params: {
cfg: MoltbotConfig;
cfg: OpenClawConfig;
agentId: string;
}): ResolvedMemoryBackendConfig {
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 os from "node:os";
import path from "node:path";
import { EventEmitter } from "node:events";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("node:child_process", () => {
@ -31,7 +30,7 @@ vi.mock("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 { QmdMemoryManager } from "./qmd-manager.js";
@ -41,7 +40,7 @@ describe("QmdMemoryManager", () => {
let tmpRoot: string;
let workspaceDir: string;
let stateDir: string;
let cfg: MoltbotConfig;
let cfg: OpenClawConfig;
const agentId = "main";
beforeEach(async () => {
@ -64,7 +63,7 @@ describe("QmdMemoryManager", () => {
paths: [{ path: workspaceDir, pattern: "**/*.md", name: "workspace" }],
},
},
} as MoltbotConfig;
} as OpenClawConfig;
});
afterEach(async () => {
@ -111,7 +110,7 @@ describe("QmdMemoryManager", () => {
},
},
},
} as MoltbotConfig;
} as OpenClawConfig;
const resolved = resolveMemoryBackendConfig({ cfg, agentId });
const manager = await QmdMemoryManager.create({ cfg, agentId, resolved });
expect(manager).toBeTruthy();

View File

@ -2,18 +2,7 @@ import { spawn } from "node:child_process";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
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 { OpenClawConfig } from "../config/config.js";
import type {
MemoryEmbeddingProbeResult,
MemoryProviderStatus,
@ -22,6 +11,16 @@ import type {
MemorySource,
MemorySyncProgressUpdate,
} 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;
import type { ResolvedMemoryBackendConfig, ResolvedQmdConfig } from "./backend-config.js";
@ -51,7 +50,7 @@ type SessionExporterConfig = {
export class QmdMemoryManager implements MemorySearchManager {
static async create(params: {
cfg: MoltbotConfig;
cfg: OpenClawConfig;
agentId: string;
resolved: ResolvedMemoryBackendConfig;
}): Promise<QmdMemoryManager | null> {
@ -62,7 +61,7 @@ export class QmdMemoryManager implements MemorySearchManager {
return manager;
}
private readonly cfg: MoltbotConfig;
private readonly cfg: OpenClawConfig;
private readonly agentId: string;
private readonly qmd: ResolvedQmdConfig;
private readonly workspaceDir: string;
@ -88,7 +87,7 @@ export class QmdMemoryManager implements MemorySearchManager {
private lastEmbedAt: number | null = null;
private constructor(params: {
cfg: MoltbotConfig;
cfg: OpenClawConfig;
agentId: string;
resolved: ResolvedQmdConfig;
}) {