@akashabot/openclaw-mem 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +92 -1
- package/package.json +2 -2
- package/src/cli.ts +103 -0
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,9 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
5
5
|
import * as core from '@akashabot/openclaw-memory-offline-core';
|
|
6
6
|
const { addItem, hybridSearch, hybridSearchFiltered, initSchema, openDb, runMigrations, searchItems, getMemoriesByEntity, getMemoriesBySession, getMemoriesByProcess, listEntities, listSessions,
|
|
7
7
|
// Phase 2: Facts
|
|
8
|
-
insertFact, getFactsBySubject, getFactsByPredicate, searchFacts, getAllFacts, listSubjects, listPredicates, deleteFact, extractFactsSimple,
|
|
8
|
+
insertFact, getFactsBySubject, getFactsByPredicate, searchFacts, getAllFacts, listSubjects, listPredicates, deleteFact, extractFactsSimple,
|
|
9
|
+
// Phase 3: Knowledge Graph
|
|
10
|
+
getEntityGraph, getRelatedEntities, findPaths, getGraphStats, exportGraphJson, searchEntities, } = core;
|
|
9
11
|
const program = new Command();
|
|
10
12
|
program
|
|
11
13
|
.name('openclaw-mem')
|
|
@@ -314,4 +316,93 @@ program
|
|
|
314
316
|
const facts = extractFactsSimple(input);
|
|
315
317
|
console.log(JSON.stringify({ ok: true, count: facts.length, facts }));
|
|
316
318
|
});
|
|
319
|
+
// ============================================================================
|
|
320
|
+
// Phase 3: Knowledge Graph commands
|
|
321
|
+
// ============================================================================
|
|
322
|
+
program
|
|
323
|
+
.command('graph-stats')
|
|
324
|
+
.description('Get statistics about the knowledge graph')
|
|
325
|
+
.action(() => {
|
|
326
|
+
withDb((dbPath) => {
|
|
327
|
+
const db = openDb(dbPath);
|
|
328
|
+
initSchema(db);
|
|
329
|
+
const stats = getGraphStats(db);
|
|
330
|
+
console.log(JSON.stringify({ ok: true, stats }, null, 2));
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
program
|
|
334
|
+
.command('graph-entity <entity>')
|
|
335
|
+
.description('Get all facts connected to an entity (as subject or object)')
|
|
336
|
+
.action((entity) => {
|
|
337
|
+
withDb((dbPath) => {
|
|
338
|
+
const db = openDb(dbPath);
|
|
339
|
+
initSchema(db);
|
|
340
|
+
const edges = getEntityGraph(db, entity);
|
|
341
|
+
console.log(JSON.stringify({ ok: true, entity, count: edges.length, edges }));
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
program
|
|
345
|
+
.command('graph-related <entity>')
|
|
346
|
+
.description('Get all entities directly connected to an entity')
|
|
347
|
+
.action((entity) => {
|
|
348
|
+
withDb((dbPath) => {
|
|
349
|
+
const db = openDb(dbPath);
|
|
350
|
+
initSchema(db);
|
|
351
|
+
const related = getRelatedEntities(db, entity);
|
|
352
|
+
console.log(JSON.stringify({ ok: true, entity, count: related.length, related }));
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
program
|
|
356
|
+
.command('graph-path <fromEntity> <toEntity>')
|
|
357
|
+
.description('Find paths between two entities in the knowledge graph')
|
|
358
|
+
.option('--max-depth <n>', 'Maximum path depth (default 4)', '4')
|
|
359
|
+
.option('--max-paths <n>', 'Maximum number of paths to return (default 5)', '5')
|
|
360
|
+
.action((fromEntity, toEntity, cmdOpts) => {
|
|
361
|
+
withDb((dbPath) => {
|
|
362
|
+
const db = openDb(dbPath);
|
|
363
|
+
initSchema(db);
|
|
364
|
+
const maxDepth = Math.max(1, Math.min(10, Number(cmdOpts.maxDepth ?? 4)));
|
|
365
|
+
const maxPaths = Math.max(1, Math.min(20, Number(cmdOpts.maxPaths ?? 5)));
|
|
366
|
+
const paths = findPaths(db, fromEntity, toEntity, maxDepth, maxPaths);
|
|
367
|
+
console.log(JSON.stringify({ ok: true, from: fromEntity, to: toEntity, count: paths.length, paths }));
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
program
|
|
371
|
+
.command('graph-export [outputFile]')
|
|
372
|
+
.description('Export the knowledge graph as JSON (for visualization)')
|
|
373
|
+
.option('--limit <n>', 'Max edges to export (default 1000)', '1000')
|
|
374
|
+
.option('--min-confidence <n>', 'Minimum confidence threshold (default 0)', '0')
|
|
375
|
+
.option('--entity <entity>', 'Export only subgraph around this entity')
|
|
376
|
+
.action((outputFile, cmdOpts) => {
|
|
377
|
+
withDb((dbPath) => {
|
|
378
|
+
const db = openDb(dbPath);
|
|
379
|
+
initSchema(db);
|
|
380
|
+
const graph = exportGraphJson(db, {
|
|
381
|
+
limit: Number(cmdOpts.limit ?? 1000),
|
|
382
|
+
minConfidence: Number(cmdOpts.minConfidence ?? 0),
|
|
383
|
+
entity: cmdOpts.entity,
|
|
384
|
+
});
|
|
385
|
+
const output = JSON.stringify({ ok: true, graph }, null, 2);
|
|
386
|
+
if (outputFile) {
|
|
387
|
+
fs.writeFileSync(outputFile, output);
|
|
388
|
+
console.log(JSON.stringify({ ok: true, file: outputFile, nodes: graph.nodes.length, edges: graph.edges.length }));
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
console.log(output);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
program
|
|
396
|
+
.command('search-entities <pattern>')
|
|
397
|
+
.description('Search for entities matching a pattern')
|
|
398
|
+
.option('--limit <n>', 'Max results (default 50)', '50')
|
|
399
|
+
.action((pattern, cmdOpts) => {
|
|
400
|
+
withDb((dbPath) => {
|
|
401
|
+
const db = openDb(dbPath);
|
|
402
|
+
initSchema(db);
|
|
403
|
+
const limit = Math.max(1, Math.min(500, Number(cmdOpts.limit ?? 50)));
|
|
404
|
+
const entities = searchEntities(db, pattern, limit);
|
|
405
|
+
console.log(JSON.stringify({ ok: true, pattern, count: entities.length, entities }));
|
|
406
|
+
});
|
|
407
|
+
});
|
|
317
408
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akashabot/openclaw-mem",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for OpenClaw Offline Memory (SQLite FTS + optional embeddings)",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"commander": "^12.1.0",
|
|
19
19
|
"uuid": "^10.0.0",
|
|
20
|
-
"@akashabot/openclaw-memory-offline-core": "^0.
|
|
20
|
+
"@akashabot/openclaw-memory-offline-core": "^0.4.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/uuid": "^10.0.0"
|
package/src/cli.ts
CHANGED
|
@@ -27,6 +27,13 @@ const {
|
|
|
27
27
|
listPredicates,
|
|
28
28
|
deleteFact,
|
|
29
29
|
extractFactsSimple,
|
|
30
|
+
// Phase 3: Knowledge Graph
|
|
31
|
+
getEntityGraph,
|
|
32
|
+
getRelatedEntities,
|
|
33
|
+
findPaths,
|
|
34
|
+
getGraphStats,
|
|
35
|
+
exportGraphJson,
|
|
36
|
+
searchEntities,
|
|
30
37
|
} = core;
|
|
31
38
|
|
|
32
39
|
const program = new Command();
|
|
@@ -381,4 +388,100 @@ program
|
|
|
381
388
|
console.log(JSON.stringify({ ok: true, count: facts.length, facts }));
|
|
382
389
|
});
|
|
383
390
|
|
|
391
|
+
// ============================================================================
|
|
392
|
+
// Phase 3: Knowledge Graph commands
|
|
393
|
+
// ============================================================================
|
|
394
|
+
|
|
395
|
+
program
|
|
396
|
+
.command('graph-stats')
|
|
397
|
+
.description('Get statistics about the knowledge graph')
|
|
398
|
+
.action(() => {
|
|
399
|
+
withDb((dbPath) => {
|
|
400
|
+
const db = openDb(dbPath);
|
|
401
|
+
initSchema(db);
|
|
402
|
+
const stats = getGraphStats(db);
|
|
403
|
+
console.log(JSON.stringify({ ok: true, stats }, null, 2));
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
program
|
|
408
|
+
.command('graph-entity <entity>')
|
|
409
|
+
.description('Get all facts connected to an entity (as subject or object)')
|
|
410
|
+
.action((entity: string) => {
|
|
411
|
+
withDb((dbPath) => {
|
|
412
|
+
const db = openDb(dbPath);
|
|
413
|
+
initSchema(db);
|
|
414
|
+
const edges = getEntityGraph(db, entity);
|
|
415
|
+
console.log(JSON.stringify({ ok: true, entity, count: edges.length, edges }));
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
program
|
|
420
|
+
.command('graph-related <entity>')
|
|
421
|
+
.description('Get all entities directly connected to an entity')
|
|
422
|
+
.action((entity: string) => {
|
|
423
|
+
withDb((dbPath) => {
|
|
424
|
+
const db = openDb(dbPath);
|
|
425
|
+
initSchema(db);
|
|
426
|
+
const related = getRelatedEntities(db, entity);
|
|
427
|
+
console.log(JSON.stringify({ ok: true, entity, count: related.length, related }));
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
program
|
|
432
|
+
.command('graph-path <fromEntity> <toEntity>')
|
|
433
|
+
.description('Find paths between two entities in the knowledge graph')
|
|
434
|
+
.option('--max-depth <n>', 'Maximum path depth (default 4)', '4')
|
|
435
|
+
.option('--max-paths <n>', 'Maximum number of paths to return (default 5)', '5')
|
|
436
|
+
.action((fromEntity: string, toEntity: string, cmdOpts) => {
|
|
437
|
+
withDb((dbPath) => {
|
|
438
|
+
const db = openDb(dbPath);
|
|
439
|
+
initSchema(db);
|
|
440
|
+
const maxDepth = Math.max(1, Math.min(10, Number(cmdOpts.maxDepth ?? 4)));
|
|
441
|
+
const maxPaths = Math.max(1, Math.min(20, Number(cmdOpts.maxPaths ?? 5)));
|
|
442
|
+
const paths = findPaths(db, fromEntity, toEntity, maxDepth, maxPaths);
|
|
443
|
+
console.log(JSON.stringify({ ok: true, from: fromEntity, to: toEntity, count: paths.length, paths }));
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
program
|
|
448
|
+
.command('graph-export [outputFile]')
|
|
449
|
+
.description('Export the knowledge graph as JSON (for visualization)')
|
|
450
|
+
.option('--limit <n>', 'Max edges to export (default 1000)', '1000')
|
|
451
|
+
.option('--min-confidence <n>', 'Minimum confidence threshold (default 0)', '0')
|
|
452
|
+
.option('--entity <entity>', 'Export only subgraph around this entity')
|
|
453
|
+
.action((outputFile: string | undefined, cmdOpts) => {
|
|
454
|
+
withDb((dbPath) => {
|
|
455
|
+
const db = openDb(dbPath);
|
|
456
|
+
initSchema(db);
|
|
457
|
+
const graph = exportGraphJson(db, {
|
|
458
|
+
limit: Number(cmdOpts.limit ?? 1000),
|
|
459
|
+
minConfidence: Number(cmdOpts.minConfidence ?? 0),
|
|
460
|
+
entity: cmdOpts.entity,
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
const output = JSON.stringify({ ok: true, graph }, null, 2);
|
|
464
|
+
if (outputFile) {
|
|
465
|
+
fs.writeFileSync(outputFile, output);
|
|
466
|
+
console.log(JSON.stringify({ ok: true, file: outputFile, nodes: graph.nodes.length, edges: graph.edges.length }));
|
|
467
|
+
} else {
|
|
468
|
+
console.log(output);
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
program
|
|
474
|
+
.command('search-entities <pattern>')
|
|
475
|
+
.description('Search for entities matching a pattern')
|
|
476
|
+
.option('--limit <n>', 'Max results (default 50)', '50')
|
|
477
|
+
.action((pattern: string, cmdOpts) => {
|
|
478
|
+
withDb((dbPath) => {
|
|
479
|
+
const db = openDb(dbPath);
|
|
480
|
+
initSchema(db);
|
|
481
|
+
const limit = Math.max(1, Math.min(500, Number(cmdOpts.limit ?? 50)));
|
|
482
|
+
const entities = searchEntities(db, pattern, limit);
|
|
483
|
+
console.log(JSON.stringify({ ok: true, pattern, count: entities.length, entities }));
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
|
|
384
487
|
program.parse();
|