mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:20:43 +00:00
feat(memory-lancedb): support query cmd for llm CLI (#71112)
* feat(memory-lancedb): support query cmd for llm CLI * address review comments * address review comments * trigger ci
This commit is contained in:
@@ -256,6 +256,11 @@ class MemoryDB {
|
||||
await this.ensureInitialized();
|
||||
return this.table!.countRows();
|
||||
}
|
||||
|
||||
async getTable(): Promise<LanceDB.Table> {
|
||||
await this.ensureInitialized();
|
||||
return this.table!;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -815,6 +820,74 @@ export default definePluginEntry({
|
||||
console.log(JSON.stringify(output, null, 2));
|
||||
});
|
||||
|
||||
memory
|
||||
.command("query")
|
||||
.description("Query memories (non-vector search)")
|
||||
.option("--cols <columns>", "Columns to select, comma-separated")
|
||||
.option("--filter <condition>", "Filter condition")
|
||||
.option("--limit <n>", "Limit number of results", "10")
|
||||
.option("--order-by <order>", "Order by column and direction (e.g., createdAt:desc)")
|
||||
.action(async (opts) => {
|
||||
const table = await db.getTable();
|
||||
let query = table.query();
|
||||
let sortColAdded = false;
|
||||
let sortColName: string | undefined;
|
||||
if (opts.cols) {
|
||||
const columns = (opts.cols as string).split(",").map((c: string) => c.trim());
|
||||
if (opts.orderBy) {
|
||||
const [sortCol] = opts.orderBy.split(":");
|
||||
sortColName = sortCol;
|
||||
if (!columns.includes(sortCol)) {
|
||||
columns.push(sortCol);
|
||||
sortColAdded = true;
|
||||
}
|
||||
}
|
||||
query = query.select(columns);
|
||||
} else {
|
||||
query = query.select(["id", "text", "importance", "category", "createdAt"]);
|
||||
}
|
||||
if (opts.filter) {
|
||||
const filterCondition = String(opts.filter);
|
||||
if (filterCondition.length > 200) {
|
||||
throw new Error("Filter condition exceeds maximum length of 200 characters");
|
||||
}
|
||||
if (!/^[a-zA-Z0-9_\-\s='"><!.,()%*]+$/.test(filterCondition)) {
|
||||
throw new Error("Filter condition contains invalid characters");
|
||||
}
|
||||
query = query.where(filterCondition);
|
||||
}
|
||||
const limit = Number.parseInt(opts.limit, 10);
|
||||
if (Number.isNaN(limit) || limit <= 0) {
|
||||
throw new Error("Invalid limit: must be a positive integer");
|
||||
}
|
||||
|
||||
// Fetch all filtered rows first if we need to order them in memory
|
||||
if (!opts.orderBy) {
|
||||
query = query.limit(limit);
|
||||
}
|
||||
let rows = await query.toArray();
|
||||
if (opts.orderBy) {
|
||||
const [col, dir] = opts.orderBy.split(":");
|
||||
const direction = dir?.toLowerCase() === "desc" ? -1 : 1;
|
||||
rows.sort((a, b) => {
|
||||
if (a[col] < b[col]) {
|
||||
return -1 * direction;
|
||||
}
|
||||
if (a[col] > b[col]) {
|
||||
return 1 * direction;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
rows = rows.slice(0, limit);
|
||||
if (sortColAdded && sortColName) {
|
||||
for (const row of rows) {
|
||||
delete row[sortColName];
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(JSON.stringify(rows, null, 2));
|
||||
});
|
||||
|
||||
memory
|
||||
.command("stats")
|
||||
.description("Show memory statistics")
|
||||
|
||||
Reference in New Issue
Block a user