From 13ae1ae056d79e6bda1b1e966b09b9070de8f15d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 17 Feb 2026 00:58:48 +0000 Subject: [PATCH] fix(memory): tighten embedding manager inheritance types --- src/memory/manager-embedding-ops.ts | 21 +++++++++++++++------ src/memory/manager-sync-ops.ts | 12 ++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/memory/manager-embedding-ops.ts b/src/memory/manager-embedding-ops.ts index 849014feda4..45ebd5626c8 100644 --- a/src/memory/manager-embedding-ops.ts +++ b/src/memory/manager-embedding-ops.ts @@ -1,6 +1,4 @@ import fs from "node:fs/promises"; -import type { SessionFileEntry } from "./session-files.js"; -import type { MemorySource } from "./types.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { runGeminiEmbeddingBatches, type GeminiBatchRequest } from "./batch-gemini.js"; import { @@ -20,6 +18,8 @@ import { type MemoryFileEntry, } from "./internal.js"; import { MemoryManagerSyncOps } from "./manager-sync-ops.js"; +import type { SessionFileEntry } from "./session-files.js"; +import type { MemorySource } from "./types.js"; const VECTOR_TABLE = "chunks_vec"; const FTS_TABLE = "chunks_fts"; @@ -40,7 +40,12 @@ const vectorToBlob = (embedding: number[]): Buffer => const log = createSubsystemLogger("memory"); -export class MemoryManagerEmbeddingOps extends MemoryManagerSyncOps { +export abstract class MemoryManagerEmbeddingOps extends MemoryManagerSyncOps { + protected abstract batchFailureCount: number; + protected abstract batchFailureLastError?: string; + protected abstract batchFailureLastProvider?: string; + protected abstract batchFailureLock: Promise; + private buildEmbeddingBatches(chunks: MemoryChunk[]): MemoryChunk[][] { const batches: MemoryChunk[][] = []; let current: MemoryChunk[] = []; @@ -337,13 +342,13 @@ export class MemoryManagerEmbeddingOps extends MemoryManagerSyncOps { chunks: MemoryChunk[]; source: MemorySource; }): { - agentId: string | undefined; + agentId: string; requests: TRequest[]; wait: boolean; concurrency: number; pollIntervalMs: number; timeoutMs: number; - debug: (message: string, data: Record) => void; + debug: (message: string, data?: Record) => void; } { const { requests, chunks, source } = params; return { @@ -353,7 +358,11 @@ export class MemoryManagerEmbeddingOps extends MemoryManagerSyncOps { concurrency: this.batch.concurrency, pollIntervalMs: this.batch.pollIntervalMs, timeoutMs: this.batch.timeoutMs, - debug: (message, data) => log.debug(message, { ...data, source, chunks: chunks.length }), + debug: (message, data) => + log.debug( + message, + data ? { ...data, source, chunks: chunks.length } : { source, chunks: chunks.length }, + ), }; } diff --git a/src/memory/manager-sync-ops.ts b/src/memory/manager-sync-ops.ts index 005eed31e5e..c5c1d71a2e5 100644 --- a/src/memory/manager-sync-ops.ts +++ b/src/memory/manager-sync-ops.ts @@ -1,11 +1,9 @@ -import type { DatabaseSync } from "node:sqlite"; -import chokidar, { FSWatcher } from "chokidar"; import { randomUUID } from "node:crypto"; import fsSync from "node:fs"; import fs from "node:fs/promises"; import path from "node:path"; -import type { SessionFileEntry } from "./session-files.js"; -import type { MemorySource, MemorySyncProgressUpdate } from "./types.js"; +import type { DatabaseSync } from "node:sqlite"; +import chokidar, { FSWatcher } from "chokidar"; import { resolveAgentDir } from "../agents/agent-scope.js"; import { ResolvedMemorySearchConfig } from "../agents/memory-search.js"; import { type OpenClawConfig } from "../config/config.js"; @@ -32,6 +30,7 @@ import { } from "./internal.js"; import { type MemoryFileEntry } from "./internal.js"; import { ensureMemoryIndexSchema } from "./memory-schema.js"; +import type { SessionFileEntry } from "./session-files.js"; import { buildSessionEntry, listSessionFilesForAgent, @@ -39,6 +38,7 @@ import { } from "./session-files.js"; import { loadSqliteVecExtension } from "./sqlite-vec.js"; import { requireNodeSqlite } from "./sqlite.js"; +import type { MemorySource, MemorySyncProgressUpdate } from "./types.js"; type MemoryIndexMeta = { model: string; @@ -392,7 +392,7 @@ export abstract class MemoryManagerSyncOps { this.watcher.on("unlink", markDirty); } - private ensureSessionListener() { + protected ensureSessionListener() { if (!this.sources.has("sessions") || this.sessionUnsubscribe) { return; } @@ -827,7 +827,7 @@ export abstract class MemoryManagerSyncOps { return state; } - private async runSync(params?: { + protected async runSync(params?: { reason?: string; force?: boolean; progress?: (update: MemorySyncProgressUpdate) => void;