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 <zhangyue.1010@bytedance.com>
This commit is contained in:
YueZhang
2026-04-30 16:01:51 +08:00
committed by GitHub
parent 53dff569b8
commit 1e20babcf7

View File

@@ -48,6 +48,12 @@ type MemoryEntry = {
createdAt: number; createdAt: number;
}; };
type MemoryListEntry = Omit<MemoryEntry, "vector">;
type MemoryListOptions = {
orderByCreatedAt?: boolean;
};
type MemorySearchResult = { type MemorySearchResult = {
entry: MemoryEntry; entry: MemoryEntry;
score: number; score: number;
@@ -151,6 +157,17 @@ function resolveAutoCaptureStartIndex(
const TABLE_NAME = "memories"; const TABLE_NAME = "memories";
const DEFAULT_AUTO_RECALL_TIMEOUT_MS = 15_000; 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 { class MemoryDB {
private db: LanceDB.Connection | null = null; private db: LanceDB.Connection | null = null;
private table: LanceDB.Table | null = null; private table: LanceDB.Table | null = null;
@@ -241,6 +258,31 @@ class MemoryDB {
return mapped.filter((r) => r.score >= minScore); return mapped.filter((r) => r.score >= minScore);
} }
async list(limit?: number, options: MemoryListOptions = {}): Promise<MemoryListEntry[]> {
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<boolean> { async delete(id: string): Promise<boolean> {
await this.ensureInitialized(); await this.ensureInitialized();
// Validate UUID format to prevent injection // Validate UUID format to prevent injection
@@ -797,9 +839,14 @@ export default definePluginEntry({
memory memory
.command("list") .command("list")
.description("List memories") .description("List memories")
.action(async () => { .option("--limit <n>", "Max results")
const count = await db.count(); .option("--order-by-created-at", "Order memories by createdAt descending", false)
console.log(`Total memories: ${count}`); .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 memory