From e332a717a8d118680d7b3bc0f2ba981a28952980 Mon Sep 17 00:00:00 2001 From: Benjamin Jesuiter Date: Mon, 2 Feb 2026 22:56:20 +0100 Subject: [PATCH] Lint: add braces for single-line ifs --- docs/concepts/memory.md | 4 + .../tools/memory-tool.citations.test.ts | 12 +- src/agents/tools/memory-tool.ts | 32 ++- src/memory/backend-config.ts | 28 ++- src/memory/qmd-manager.test.ts | 12 +- src/memory/qmd-manager.ts | 211 +++++++++++++----- src/memory/search-manager.ts | 4 +- 7 files changed, 227 insertions(+), 76 deletions(-) diff --git a/docs/concepts/memory.md b/docs/concepts/memory.md index 882b424ba3..d3a1a64dd7 100644 --- a/docs/concepts/memory.md +++ b/docs/concepts/memory.md @@ -104,6 +104,7 @@ BM25 + vectors + reranking. Markdown stays the source of truth; Moltbot shells out to QMD for retrieval. Key points: **Prereqs** + - Disabled by default. Opt in per-config (`memory.backend = "qmd"`). - Install the QMD CLI separately (`bun install -g github.com/tobi/qmd` or grab a release) and make sure the `qmd` binary is on the gateway’s `PATH`. @@ -118,6 +119,7 @@ out to QMD for retrieval. Key points: installed. Windows is best supported via WSL2. **How the sidecar runs** + - The gateway writes a self-contained QMD home under `~/.openclaw/agents//qmd/` (config + cache + sqlite DB). - Collections are rewritten from `memory.qmd.paths` (plus default workspace @@ -160,6 +162,7 @@ out to QMD for retrieval. Key points: ``` **Config surface (`memory.qmd.*`)** + - `command` (default `qmd`): override the executable path. - `includeDefaultMemory` (default `true`): auto-index `MEMORY.md` + `memory/**/*.md`. - `paths[]`: add extra directories/files (`path`, optional `pattern`, optional @@ -207,6 +210,7 @@ memory: { ``` **Citations & fallback** + - `memory.citations` applies regardless of backend (`auto`/`on`/`off`). - When `qmd` runs, we tag `status().backend = "qmd"` so diagnostics show which engine served the results. If the QMD subprocess exits or JSON output can’t be diff --git a/src/agents/tools/memory-tool.citations.test.ts b/src/agents/tools/memory-tool.citations.test.ts index a57290f731..3a1b4c590f 100644 --- a/src/agents/tools/memory-tool.citations.test.ts +++ b/src/agents/tools/memory-tool.citations.test.ts @@ -48,7 +48,9 @@ describe("memory search citations", () => { backend = "builtin"; const cfg = { memory: { citations: "on" }, agents: { list: [{ id: "main", default: true }] } }; const tool = createMemorySearchTool({ config: cfg }); - if (!tool) throw new Error("tool missing"); + if (!tool) { + throw new Error("tool missing"); + } const result = await tool.execute("call_citations_on", { query: "notes" }); const details = result.details as { results: Array<{ snippet: string; citation?: string }> }; expect(details.results[0]?.snippet).toMatch(/Source: MEMORY.md#L5-L7/); @@ -59,7 +61,9 @@ describe("memory search citations", () => { backend = "builtin"; const cfg = { memory: { citations: "off" }, agents: { list: [{ id: "main", default: true }] } }; const tool = createMemorySearchTool({ config: cfg }); - if (!tool) throw new Error("tool missing"); + if (!tool) { + throw new Error("tool missing"); + } const result = await tool.execute("call_citations_off", { query: "notes" }); const details = result.details as { results: Array<{ snippet: string; citation?: string }> }; expect(details.results[0]?.snippet).not.toMatch(/Source:/); @@ -73,7 +77,9 @@ describe("memory search citations", () => { agents: { list: [{ id: "main", default: true }] }, }; const tool = createMemorySearchTool({ config: cfg }); - if (!tool) throw new Error("tool missing"); + if (!tool) { + throw new Error("tool missing"); + } const result = await tool.execute("call_citations_qmd", { query: "notes" }); const details = result.details as { results: Array<{ snippet: string; citation?: string }> }; expect(details.results[0]?.snippet.length).toBeLessThanOrEqual(20); diff --git a/src/agents/tools/memory-tool.ts b/src/agents/tools/memory-tool.ts index b9c5d8d068..e9499e5f86 100644 --- a/src/agents/tools/memory-tool.ts +++ b/src/agents/tools/memory-tool.ts @@ -128,7 +128,9 @@ export function createMemoryGetTool(options: { function resolveMemoryCitationsMode(cfg: MoltbotConfig): MemoryCitationsMode { const mode = cfg.memory?.citations; - if (mode === "on" || mode === "off" || mode === "auto") return mode; + if (mode === "on" || mode === "off" || mode === "auto") { + return mode; + } return "auto"; } @@ -155,11 +157,15 @@ function clampResultsByInjectedChars( results: MemorySearchResult[], budget?: number, ): MemorySearchResult[] { - if (!budget || budget <= 0) return results; + if (!budget || budget <= 0) { + return results; + } let remaining = budget; const clamped: MemorySearchResult[] = []; for (const entry of results) { - if (remaining <= 0) break; + if (remaining <= 0) { + break; + } const snippet = entry.snippet ?? ""; if (snippet.length <= remaining) { clamped.push(entry); @@ -177,16 +183,26 @@ function shouldIncludeCitations(params: { mode: MemoryCitationsMode; sessionKey?: string; }): boolean { - if (params.mode === "on") return true; - if (params.mode === "off") return false; + if (params.mode === "on") { + return true; + } + if (params.mode === "off") { + return false; + } // auto: show citations in direct chats; suppress in groups/channels by default. const chatType = deriveChatTypeFromSessionKey(params.sessionKey); return chatType === "direct"; } function deriveChatTypeFromSessionKey(sessionKey?: string): "direct" | "group" | "channel" { - if (!sessionKey) return "direct"; - if (sessionKey.includes(":group:")) return "group"; - if (sessionKey.includes(":channel:")) return "channel"; + if (!sessionKey) { + return "direct"; + } + if (sessionKey.includes(":group:")) { + return "group"; + } + if (sessionKey.includes(":channel:")) { + return "channel"; + } return "direct"; } diff --git a/src/memory/backend-config.ts b/src/memory/backend-config.ts index 24aab952f7..375398f0ea 100644 --- a/src/memory/backend-config.ts +++ b/src/memory/backend-config.ts @@ -100,7 +100,9 @@ function ensureUniqueName(base: string, existing: Set): string { function resolvePath(raw: string, workspaceDir: string): string { const trimmed = raw.trim(); - if (!trimmed) throw new Error("path required"); + if (!trimmed) { + throw new Error("path required"); + } if (trimmed.startsWith("~") || path.isAbsolute(trimmed)) { return path.normalize(resolveUserPath(trimmed)); } @@ -109,7 +111,9 @@ function resolvePath(raw: string, workspaceDir: string): string { function resolveIntervalMs(raw: string | undefined): number { const value = raw?.trim(); - if (!value) return parseDurationMs(DEFAULT_QMD_INTERVAL, { defaultUnit: "m" }); + if (!value) { + return parseDurationMs(DEFAULT_QMD_INTERVAL, { defaultUnit: "m" }); + } try { return parseDurationMs(value, { defaultUnit: "m" }); } catch { @@ -119,7 +123,9 @@ function resolveIntervalMs(raw: string | undefined): number { function resolveEmbedIntervalMs(raw: string | undefined): number { const value = raw?.trim(); - if (!value) return parseDurationMs(DEFAULT_QMD_EMBED_INTERVAL, { defaultUnit: "m" }); + if (!value) { + return parseDurationMs(DEFAULT_QMD_EMBED_INTERVAL, { defaultUnit: "m" }); + } try { return parseDurationMs(value, { defaultUnit: "m" }); } catch { @@ -136,7 +142,9 @@ function resolveDebounceMs(raw: number | undefined): number { function resolveLimits(raw?: MemoryQmdConfig["limits"]): ResolvedQmdLimitsConfig { const parsed: ResolvedQmdLimitsConfig = { ...DEFAULT_QMD_LIMITS }; - if (raw?.maxResults && raw.maxResults > 0) parsed.maxResults = Math.floor(raw.maxResults); + if (raw?.maxResults && raw.maxResults > 0) { + parsed.maxResults = Math.floor(raw.maxResults); + } if (raw?.maxSnippetChars && raw.maxSnippetChars > 0) { parsed.maxSnippetChars = Math.floor(raw.maxSnippetChars); } @@ -170,11 +178,15 @@ function resolveCustomPaths( workspaceDir: string, existing: Set, ): ResolvedQmdCollection[] { - if (!rawPaths?.length) return []; + if (!rawPaths?.length) { + return []; + } const collections: ResolvedQmdCollection[] = []; rawPaths.forEach((entry, index) => { const trimmedPath = entry?.path?.trim(); - if (!trimmedPath) return; + if (!trimmedPath) { + return; + } let resolved: string; try { resolved = resolvePath(trimmedPath, workspaceDir); @@ -199,7 +211,9 @@ function resolveDefaultCollections( workspaceDir: string, existing: Set, ): ResolvedQmdCollection[] { - if (!include) return []; + if (!include) { + return []; + } const entries: Array<{ path: string; pattern: string; base: string }> = [ { path: workspaceDir, pattern: "MEMORY.md", base: "memory-root" }, { path: workspaceDir, pattern: "memory.md", base: "memory-alt" }, diff --git a/src/memory/qmd-manager.test.ts b/src/memory/qmd-manager.test.ts index b2c92ff569..9ed61914a6 100644 --- a/src/memory/qmd-manager.test.ts +++ b/src/memory/qmd-manager.test.ts @@ -75,7 +75,9 @@ describe("QmdMemoryManager", () => { const resolved = resolveMemoryBackendConfig({ cfg, agentId }); const manager = await QmdMemoryManager.create({ cfg, agentId, resolved }); expect(manager).toBeTruthy(); - if (!manager) throw new Error("manager missing"); + if (!manager) { + throw new Error("manager missing"); + } const baselineCalls = spawnMock.mock.calls.length; @@ -114,7 +116,9 @@ describe("QmdMemoryManager", () => { const resolved = resolveMemoryBackendConfig({ cfg, agentId }); const manager = await QmdMemoryManager.create({ cfg, agentId, resolved }); expect(manager).toBeTruthy(); - if (!manager) throw new Error("manager missing"); + if (!manager) { + throw new Error("manager missing"); + } const isAllowed = (key?: string) => (manager as unknown as { isScopeAllowed: (key?: string) => boolean }).isScopeAllowed(key); @@ -128,7 +132,9 @@ describe("QmdMemoryManager", () => { const resolved = resolveMemoryBackendConfig({ cfg, agentId }); const manager = await QmdMemoryManager.create({ cfg, agentId, resolved }); expect(manager).toBeTruthy(); - if (!manager) throw new Error("manager missing"); + if (!manager) { + throw new Error("manager missing"); + } const textPath = path.join(workspaceDir, "secret.txt"); await fs.writeFile(textPath, "nope", "utf-8"); diff --git a/src/memory/qmd-manager.ts b/src/memory/qmd-manager.ts index 82476af9b4..4d315564d5 100644 --- a/src/memory/qmd-manager.ts +++ b/src/memory/qmd-manager.ts @@ -55,7 +55,9 @@ export class QmdMemoryManager implements MemorySearchManager { resolved: ResolvedMemoryBackendConfig; }): Promise { const resolved = params.resolved.qmd; - if (!resolved) return null; + if (!resolved) { + return null; + } const manager = new QmdMemoryManager({ cfg: params.cfg, agentId: params.agentId, resolved }); await manager.initialize(); return manager; @@ -174,10 +176,13 @@ export class QmdMemoryManager implements MemorySearchManager { const parsed = JSON.parse(result.stdout) as unknown; if (Array.isArray(parsed)) { for (const entry of parsed) { - if (typeof entry === "string") existing.add(entry); - else if (entry && typeof entry === "object") { + if (typeof entry === "string") { + existing.add(entry); + } else if (entry && typeof entry === "object") { const name = (entry as { name?: unknown }).name; - if (typeof name === "string") existing.add(name); + if (typeof name === "string") { + existing.add(name); + } } } } @@ -186,7 +191,9 @@ export class QmdMemoryManager implements MemorySearchManager { } for (const collection of this.qmd.collections) { - if (existing.has(collection.name)) continue; + if (existing.has(collection.name)) { + continue; + } try { await this.runQmd([ "collection", @@ -200,8 +207,12 @@ export class QmdMemoryManager implements MemorySearchManager { } catch (err) { const message = err instanceof Error ? err.message : String(err); // Idempotency: qmd exits non-zero if the collection name already exists. - if (message.toLowerCase().includes("already exists")) continue; - if (message.toLowerCase().includes("exists")) continue; + if (message.toLowerCase().includes("already exists")) { + continue; + } + if (message.toLowerCase().includes("exists")) { + continue; + } log.warn(`qmd collection add failed for ${collection.name}: ${message}`); } } @@ -211,9 +222,13 @@ export class QmdMemoryManager implements MemorySearchManager { query: string, opts?: { maxResults?: number; minScore?: number; sessionKey?: string }, ): Promise { - if (!this.isScopeAllowed(opts?.sessionKey)) return []; + if (!this.isScopeAllowed(opts?.sessionKey)) { + return []; + } const trimmed = query.trim(); - if (!trimmed) return []; + if (!trimmed) { + return []; + } await this.pendingUpdate?.catch(() => undefined); const limit = Math.min( this.qmd.limits.maxResults, @@ -234,17 +249,21 @@ export class QmdMemoryManager implements MemorySearchManager { } catch (err) { const message = err instanceof Error ? err.message : String(err); log.warn(`qmd query returned invalid JSON: ${message}`); - throw new Error(`qmd query returned invalid JSON: ${message}`); + throw new Error(`qmd query returned invalid JSON: ${message}`, { cause: err }); } const results: MemorySearchResult[] = []; for (const entry of parsed) { const doc = await this.resolveDocLocation(entry.docid); - if (!doc) continue; + if (!doc) { + continue; + } const snippet = entry.snippet?.slice(0, this.qmd.limits.maxSnippetChars) ?? ""; const lines = this.extractSnippetLines(snippet); const score = typeof entry.score === "number" ? entry.score : 0; const minScore = opts?.minScore ?? 0; - if (score < minScore) continue; + if (score < minScore) { + continue; + } results.push({ path: doc.rel, startLine: lines.startLine, @@ -277,7 +296,9 @@ export class QmdMemoryManager implements MemorySearchManager { lines?: number; }): Promise<{ text: string; path: string }> { const relPath = params.relPath?.trim(); - if (!relPath) throw new Error("path required"); + if (!relPath) { + throw new Error("path required"); + } const absPath = this.resolveReadPath(relPath); if (!absPath.endsWith(".md")) { throw new Error("path required"); @@ -339,7 +360,9 @@ export class QmdMemoryManager implements MemorySearchManager { } async close(): Promise { - if (this.closed) return; + if (this.closed) { + return; + } this.closed = true; if (this.updateTimer) { clearInterval(this.updateTimer); @@ -353,7 +376,9 @@ export class QmdMemoryManager implements MemorySearchManager { } private async runUpdate(reason: string, force?: boolean): Promise { - if (this.pendingUpdate && !force) return this.pendingUpdate; + if (this.pendingUpdate && !force) { + return this.pendingUpdate; + } if (this.shouldSkipUpdate(force)) { return; } @@ -408,11 +433,15 @@ export class QmdMemoryManager implements MemorySearchManager { stderr += data.toString(); }); child.on("error", (err) => { - if (timer) clearTimeout(timer); + if (timer) { + clearTimeout(timer); + } reject(err); }); child.on("close", (code) => { - if (timer) clearTimeout(timer); + if (timer) { + clearTimeout(timer); + } if (code === 0) { resolve({ stdout, stderr }); } else { @@ -423,14 +452,18 @@ export class QmdMemoryManager implements MemorySearchManager { } private ensureDb(): SqliteDatabase { - if (this.db) return this.db; + if (this.db) { + return this.db; + } const { DatabaseSync } = requireNodeSqlite(); this.db = new DatabaseSync(this.indexPath, { readOnly: true }); return this.db; } private async exportSessions(): Promise { - if (!this.sessionExporter) return; + if (!this.sessionExporter) { + return; + } const exportDir = this.sessionExporter.dir; await fs.mkdir(exportDir, { recursive: true }); const files = await listSessionFilesForAgent(this.agentId); @@ -440,15 +473,21 @@ export class QmdMemoryManager implements MemorySearchManager { : null; for (const sessionFile of files) { const entry = await buildSessionEntry(sessionFile); - if (!entry) continue; - if (cutoff && entry.mtimeMs < cutoff) continue; + if (!entry) { + continue; + } + if (cutoff && entry.mtimeMs < cutoff) { + continue; + } const target = path.join(exportDir, `${path.basename(sessionFile, ".jsonl")}.md`); await fs.writeFile(target, this.renderSessionMarkdown(entry), "utf-8"); keep.add(target); } const exported = await fs.readdir(exportDir).catch(() => []); for (const name of exported) { - if (!name.endsWith(".md")) continue; + if (!name.endsWith(".md")) { + continue; + } const full = path.join(exportDir, name); if (!keep.has(full)) { await fs.rm(full, { force: true }); @@ -464,7 +503,9 @@ export class QmdMemoryManager implements MemorySearchManager { private pickSessionCollectionName(): string { const existing = new Set(this.qmd.collections.map((collection) => collection.name)); - if (!existing.has("sessions")) return "sessions"; + if (!existing.has("sessions")) { + return "sessions"; + } let counter = 2; let candidate = `sessions-${counter}`; while (existing.has(candidate)) { @@ -477,18 +518,28 @@ export class QmdMemoryManager implements MemorySearchManager { private async resolveDocLocation( docid?: string, ): Promise<{ rel: string; abs: string; source: MemorySource } | null> { - if (!docid) return null; + if (!docid) { + return null; + } const normalized = docid.startsWith("#") ? docid.slice(1) : docid; - if (!normalized) return null; + if (!normalized) { + return null; + } const cached = this.docPathCache.get(normalized); - if (cached) return cached; + if (cached) { + return cached; + } const db = this.ensureDb(); const row = db .prepare("SELECT collection, path FROM documents WHERE hash LIKE ? AND active = 1 LIMIT 1") .get(`${normalized}%`) as { collection: string; path: string } | undefined; - if (!row) return null; + if (!row) { + return null; + } const location = this.toDocLocation(row.collection, row.path); - if (!location) return null; + if (!location) { + return null; + } this.docPathCache.set(normalized, location); return location; } @@ -550,16 +601,26 @@ export class QmdMemoryManager implements MemorySearchManager { private isScopeAllowed(sessionKey?: string): boolean { const scope = this.qmd.scope; - if (!scope) return true; + if (!scope) { + return true; + } const channel = this.deriveChannelFromKey(sessionKey); const chatType = this.deriveChatTypeFromKey(sessionKey); const normalizedKey = sessionKey ?? ""; for (const rule of scope.rules ?? []) { - if (!rule) continue; + if (!rule) { + continue; + } const match = rule.match ?? {}; - if (match.channel && match.channel !== channel) continue; - if (match.chatType && match.chatType !== chatType) continue; - if (match.keyPrefix && !normalizedKey.startsWith(match.keyPrefix)) continue; + if (match.channel && match.channel !== channel) { + continue; + } + if (match.chatType && match.chatType !== chatType) { + continue; + } + if (match.keyPrefix && !normalizedKey.startsWith(match.keyPrefix)) { + continue; + } return rule.action === "allow"; } const fallback = scope.default ?? "allow"; @@ -567,9 +628,13 @@ export class QmdMemoryManager implements MemorySearchManager { } private deriveChannelFromKey(key?: string) { - if (!key) return undefined; + if (!key) { + return undefined; + } const normalized = this.normalizeSessionKey(key); - if (!normalized) return undefined; + if (!normalized) { + return undefined; + } const parts = normalized.split(":").filter(Boolean); if ( parts.length >= 2 && @@ -581,20 +646,32 @@ export class QmdMemoryManager implements MemorySearchManager { } private deriveChatTypeFromKey(key?: string) { - if (!key) return undefined; + if (!key) { + return undefined; + } const normalized = this.normalizeSessionKey(key); - if (!normalized) return undefined; - if (normalized.includes(":group:")) return "group"; - if (normalized.includes(":channel:")) return "channel"; + if (!normalized) { + return undefined; + } + if (normalized.includes(":group:")) { + return "group"; + } + if (normalized.includes(":channel:")) { + return "channel"; + } return "direct"; } private normalizeSessionKey(key: string): string | undefined { const trimmed = key.trim(); - if (!trimmed) return undefined; + if (!trimmed) { + return undefined; + } const parsed = parseAgentSessionKey(trimmed); const normalized = (parsed?.rest ?? trimmed).toLowerCase(); - if (normalized.startsWith("subagent:")) return undefined; + if (normalized.startsWith("subagent:")) { + return undefined; + } return normalized; } @@ -603,7 +680,9 @@ export class QmdMemoryManager implements MemorySearchManager { collectionRelativePath: string, ): { rel: string; abs: string; source: MemorySource } | null { const root = this.collectionRoots.get(collection); - if (!root) return null; + if (!root) { + return null; + } const normalizedRelative = collectionRelativePath.replace(/\\/g, "/"); const absPath = path.normalize(path.resolve(root.path, collectionRelativePath)); const relativeToWorkspace = path.relative(this.workspaceDir, absPath); @@ -625,7 +704,9 @@ export class QmdMemoryManager implements MemorySearchManager { const insideWorkspace = this.isInsideWorkspace(relativeToWorkspace); if (insideWorkspace) { const normalized = relativeToWorkspace.replace(/\\/g, "/"); - if (!normalized) return path.basename(absPath); + if (!normalized) { + return path.basename(absPath); + } return normalized; } const sanitized = collectionRelativePath.replace(/^\/+/, ""); @@ -633,9 +714,15 @@ export class QmdMemoryManager implements MemorySearchManager { } private isInsideWorkspace(relativePath: string): boolean { - if (!relativePath) return true; - if (relativePath.startsWith("..")) return false; - if (relativePath.startsWith(`..${path.sep}`)) return false; + if (!relativePath) { + return true; + } + if (relativePath.startsWith("..")) { + return false; + } + if (relativePath.startsWith(`..${path.sep}`)) { + return false; + } return !path.isAbsolute(relativePath); } @@ -646,7 +733,9 @@ export class QmdMemoryManager implements MemorySearchManager { throw new Error("invalid qmd path"); } const root = this.collectionRoots.get(collection); - if (!root) throw new Error(`unknown qmd collection: ${collection}`); + if (!root) { + throw new Error(`unknown qmd collection: ${collection}`); + } const joined = rest.join("/"); const resolved = path.resolve(root.path, joined); if (!this.isWithinRoot(root.path, resolved)) { @@ -665,25 +754,33 @@ export class QmdMemoryManager implements MemorySearchManager { const normalizedWorkspace = this.workspaceDir.endsWith(path.sep) ? this.workspaceDir : `${this.workspaceDir}${path.sep}`; - if (absPath === this.workspaceDir) return true; + if (absPath === this.workspaceDir) { + return true; + } const candidate = absPath.endsWith(path.sep) ? absPath : `${absPath}${path.sep}`; return candidate.startsWith(normalizedWorkspace); } private isWithinRoot(root: string, candidate: string): boolean { const normalizedRoot = root.endsWith(path.sep) ? root : `${root}${path.sep}`; - if (candidate === root) return true; + if (candidate === root) { + return true; + } const next = candidate.endsWith(path.sep) ? candidate : `${candidate}${path.sep}`; return next.startsWith(normalizedRoot); } private clampResultsByInjectedChars(results: MemorySearchResult[]): MemorySearchResult[] { const budget = this.qmd.limits.maxInjectedChars; - if (!budget || budget <= 0) return results; + if (!budget || budget <= 0) { + return results; + } let remaining = budget; const clamped: MemorySearchResult[] = []; for (const entry of results) { - if (remaining <= 0) break; + if (remaining <= 0) { + break; + } const snippet = entry.snippet ?? ""; if (snippet.length <= remaining) { clamped.push(entry); @@ -698,10 +795,16 @@ export class QmdMemoryManager implements MemorySearchManager { } private shouldSkipUpdate(force?: boolean): boolean { - if (force) return false; + if (force) { + return false; + } const debounceMs = this.qmd.update.debounceMs; - if (debounceMs <= 0) return false; - if (!this.lastUpdateAt) return false; + if (debounceMs <= 0) { + return false; + } + if (!this.lastUpdateAt) { + return false; + } return Date.now() - this.lastUpdateAt < debounceMs; } } diff --git a/src/memory/search-manager.ts b/src/memory/search-manager.ts index afd3926739..bdde26a720 100644 --- a/src/memory/search-manager.ts +++ b/src/memory/search-manager.ts @@ -177,7 +177,9 @@ class FallbackMemoryManager implements MemorySearchManager { } private async ensureFallback(): Promise { - if (this.fallback) return this.fallback; + if (this.fallback) { + return this.fallback; + } const fallback = await this.deps.fallbackFactory(); if (!fallback) { log.warn("memory fallback requested but builtin index is unavailable");