From 1e20babcf7eb8c8d7db9814f0c7996434568a0c8 Mon Sep 17 00:00:00 2001 From: YueZhang <69956021+zhangyue19921010@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:01:51 +0800 Subject: [PATCH] fix(memory-lancedb): get memory records through ltm list command (#67952) * fix(mem-lancedb): get memory records through ltm list command * code review --------- Co-authored-by: zhangyue19921010 --- extensions/memory-lancedb/index.ts | 53 ++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/extensions/memory-lancedb/index.ts b/extensions/memory-lancedb/index.ts index 3de07bc9682..f9e9421f575 100644 --- a/extensions/memory-lancedb/index.ts +++ b/extensions/memory-lancedb/index.ts @@ -48,6 +48,12 @@ type MemoryEntry = { createdAt: number; }; +type MemoryListEntry = Omit; + +type MemoryListOptions = { + orderByCreatedAt?: boolean; +}; + type MemorySearchResult = { entry: MemoryEntry; score: number; @@ -151,6 +157,17 @@ function resolveAutoCaptureStartIndex( const TABLE_NAME = "memories"; const DEFAULT_AUTO_RECALL_TIMEOUT_MS = 15_000; +function parsePositiveIntegerOption(value: string | undefined, flag: string): number | undefined { + if (value === undefined) { + return undefined; + } + const parsed = Number(value); + if (!Number.isInteger(parsed) || parsed < 1) { + throw new Error(`${flag} must be a positive integer`); + } + return parsed; +} + class MemoryDB { private db: LanceDB.Connection | null = null; private table: LanceDB.Table | null = null; @@ -241,6 +258,31 @@ class MemoryDB { return mapped.filter((r) => r.score >= minScore); } + async list(limit?: number, options: MemoryListOptions = {}): Promise { + await this.ensureInitialized(); + + let query = this.table!.query().select(["id", "text", "importance", "category", "createdAt"]); + // Push limit to LanceDB only when we don't need to sort in-memory. + if (!options.orderByCreatedAt && limit !== undefined) { + query = query.limit(limit); + } + + const rows = await query.toArray(); + + const entries = rows.map((row) => ({ + id: row.id as string, + text: row.text as string, + importance: row.importance as number, + category: row.category as MemoryEntry["category"], + createdAt: row.createdAt as number, + })); + if (options.orderByCreatedAt) { + entries.sort((a, b) => b.createdAt - a.createdAt); + } + + return limit === undefined ? entries : entries.slice(0, limit); + } + async delete(id: string): Promise { await this.ensureInitialized(); // Validate UUID format to prevent injection @@ -797,9 +839,14 @@ export default definePluginEntry({ memory .command("list") .description("List memories") - .action(async () => { - const count = await db.count(); - console.log(`Total memories: ${count}`); + .option("--limit ", "Max results") + .option("--order-by-created-at", "Order memories by createdAt descending", false) + .action(async (opts) => { + const limit = parsePositiveIntegerOption(opts.limit, "--limit"); + const entries = await db.list(limit, { + orderByCreatedAt: Boolean(opts.orderByCreatedAt), + }); + console.log(JSON.stringify(entries, null, 2)); }); memory