feat(memory): allow QMD searches via mcporter keep-alive (openclaw#19617) thanks @vignesh07

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: vignesh07 <1436853+vignesh07@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
Vignesh
2026-02-21 16:54:33 -08:00
committed by GitHub
parent 2e8e357bf7
commit 3317b49d3b
10 changed files with 482 additions and 8 deletions

View File

@@ -236,6 +236,13 @@ export const FIELD_HELP: Record<string, string> = {
"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.mcporter":
"Optional: route QMD searches through mcporter (MCP runtime) instead of spawning `qmd` per query. Intended to avoid per-search cold starts when QMD models are large.",
"memory.qmd.mcporter.enabled": "Enable mcporter-backed QMD searches (default: false).",
"memory.qmd.mcporter.serverName":
"mcporter server name to call (default: qmd). Server should run `qmd mcp` with lifecycle keep-alive.",
"memory.qmd.mcporter.startDaemon":
"Start `mcporter daemon start` automatically when enabled (default: true).",
"memory.qmd.includeDefaultMemory":
"Whether to automatically index MEMORY.md + memory/**/*.md (default: true).",
"memory.qmd.paths":

View File

@@ -12,6 +12,7 @@ export type MemoryConfig = {
export type MemoryQmdConfig = {
command?: string;
mcporter?: MemoryQmdMcporterConfig;
searchMode?: MemoryQmdSearchMode;
includeDefaultMemory?: boolean;
paths?: MemoryQmdIndexPath[];
@@ -21,6 +22,20 @@ export type MemoryQmdConfig = {
scope?: SessionSendPolicyConfig;
};
export type MemoryQmdMcporterConfig = {
/**
* Route QMD searches through mcporter (MCP runtime) instead of spawning `qmd` per query.
* Requires:
* - `mcporter` installed and on PATH
* - A configured mcporter server that runs `qmd mcp` with `lifecycle: keep-alive`
*/
enabled?: boolean;
/** mcporter server name (defaults to "qmd") */
serverName?: string;
/** Start the mcporter daemon automatically (defaults to true when enabled). */
startDaemon?: boolean;
};
export type MemoryQmdIndexPath = {
path: string;
name?: string;

View File

@@ -72,9 +72,18 @@ const MemoryQmdLimitsSchema = z
})
.strict();
const MemoryQmdMcporterSchema = z
.object({
enabled: z.boolean().optional(),
serverName: z.string().optional(),
startDaemon: z.boolean().optional(),
})
.strict();
const MemoryQmdSchema = z
.object({
command: z.string().optional(),
mcporter: MemoryQmdMcporterSchema.optional(),
searchMode: z.union([z.literal("query"), z.literal("search"), z.literal("vsearch")]).optional(),
includeDefaultMemory: z.boolean().optional(),
paths: z.array(MemoryQmdPathSchema).optional(),