@akashabot/openclaw-mem 0.3.0 → 0.5.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.
Files changed (3) hide show
  1. package/dist/cli.js +119 -1
  2. package/package.json +2 -2
  3. package/src/cli.ts +138 -0
package/dist/cli.js CHANGED
@@ -5,7 +5,11 @@ 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, } = core;
8
+ insertFact, getFactsBySubject, getFactsByPredicate, searchFacts, getAllFacts, listSubjects, listPredicates, deleteFact, extractFactsSimple,
9
+ // Phase 3: Knowledge Graph
10
+ getEntityGraph, getRelatedEntities, findPaths, getGraphStats, exportGraphJson, searchEntities,
11
+ // Phase 3: Embedding Optimizations
12
+ getEmbeddingStats, quantizeF32ToF16, dequantizeF16ToF32, cosineSimilarity, benchmarkCosineSimilarity, runEmbeddingBenchmark, } = core;
9
13
  const program = new Command();
10
14
  program
11
15
  .name('openclaw-mem')
@@ -314,4 +318,118 @@ program
314
318
  const facts = extractFactsSimple(input);
315
319
  console.log(JSON.stringify({ ok: true, count: facts.length, facts }));
316
320
  });
321
+ // ============================================================================
322
+ // Phase 3: Knowledge Graph commands
323
+ // ============================================================================
324
+ program
325
+ .command('graph-stats')
326
+ .description('Get statistics about the knowledge graph')
327
+ .action(() => {
328
+ withDb((dbPath) => {
329
+ const db = openDb(dbPath);
330
+ initSchema(db);
331
+ const stats = getGraphStats(db);
332
+ console.log(JSON.stringify({ ok: true, stats }, null, 2));
333
+ });
334
+ });
335
+ program
336
+ .command('graph-entity <entity>')
337
+ .description('Get all facts connected to an entity (as subject or object)')
338
+ .action((entity) => {
339
+ withDb((dbPath) => {
340
+ const db = openDb(dbPath);
341
+ initSchema(db);
342
+ const edges = getEntityGraph(db, entity);
343
+ console.log(JSON.stringify({ ok: true, entity, count: edges.length, edges }));
344
+ });
345
+ });
346
+ program
347
+ .command('graph-related <entity>')
348
+ .description('Get all entities directly connected to an entity')
349
+ .action((entity) => {
350
+ withDb((dbPath) => {
351
+ const db = openDb(dbPath);
352
+ initSchema(db);
353
+ const related = getRelatedEntities(db, entity);
354
+ console.log(JSON.stringify({ ok: true, entity, count: related.length, related }));
355
+ });
356
+ });
357
+ program
358
+ .command('graph-path <fromEntity> <toEntity>')
359
+ .description('Find paths between two entities in the knowledge graph')
360
+ .option('--max-depth <n>', 'Maximum path depth (default 4)', '4')
361
+ .option('--max-paths <n>', 'Maximum number of paths to return (default 5)', '5')
362
+ .action((fromEntity, toEntity, cmdOpts) => {
363
+ withDb((dbPath) => {
364
+ const db = openDb(dbPath);
365
+ initSchema(db);
366
+ const maxDepth = Math.max(1, Math.min(10, Number(cmdOpts.maxDepth ?? 4)));
367
+ const maxPaths = Math.max(1, Math.min(20, Number(cmdOpts.maxPaths ?? 5)));
368
+ const paths = findPaths(db, fromEntity, toEntity, maxDepth, maxPaths);
369
+ console.log(JSON.stringify({ ok: true, from: fromEntity, to: toEntity, count: paths.length, paths }));
370
+ });
371
+ });
372
+ program
373
+ .command('graph-export [outputFile]')
374
+ .description('Export the knowledge graph as JSON (for visualization)')
375
+ .option('--limit <n>', 'Max edges to export (default 1000)', '1000')
376
+ .option('--min-confidence <n>', 'Minimum confidence threshold (default 0)', '0')
377
+ .option('--entity <entity>', 'Export only subgraph around this entity')
378
+ .action((outputFile, cmdOpts) => {
379
+ withDb((dbPath) => {
380
+ const db = openDb(dbPath);
381
+ initSchema(db);
382
+ const graph = exportGraphJson(db, {
383
+ limit: Number(cmdOpts.limit ?? 1000),
384
+ minConfidence: Number(cmdOpts.minConfidence ?? 0),
385
+ entity: cmdOpts.entity,
386
+ });
387
+ const output = JSON.stringify({ ok: true, graph }, null, 2);
388
+ if (outputFile) {
389
+ fs.writeFileSync(outputFile, output);
390
+ console.log(JSON.stringify({ ok: true, file: outputFile, nodes: graph.nodes.length, edges: graph.edges.length }));
391
+ }
392
+ else {
393
+ console.log(output);
394
+ }
395
+ });
396
+ });
397
+ program
398
+ .command('search-entities <pattern>')
399
+ .description('Search for entities matching a pattern')
400
+ .option('--limit <n>', 'Max results (default 50)', '50')
401
+ .action((pattern, cmdOpts) => {
402
+ withDb((dbPath) => {
403
+ const db = openDb(dbPath);
404
+ initSchema(db);
405
+ const limit = Math.max(1, Math.min(500, Number(cmdOpts.limit ?? 50)));
406
+ const entities = searchEntities(db, pattern, limit);
407
+ console.log(JSON.stringify({ ok: true, pattern, count: entities.length, entities }));
408
+ });
409
+ });
410
+ // ============================================================================
411
+ // Phase 3: Embedding Optimization commands
412
+ // ============================================================================
413
+ program
414
+ .command('embedding-stats')
415
+ .description('Get statistics about stored embeddings')
416
+ .action(() => {
417
+ withDb((dbPath) => {
418
+ const db = openDb(dbPath);
419
+ initSchema(db);
420
+ const stats = getEmbeddingStats(db);
421
+ const sizeMB = Math.round((stats.totalSizeBytes / (1024 * 1024)) * 100) / 100;
422
+ console.log(JSON.stringify({ ok: true, ...stats, sizeMB }, null, 2));
423
+ });
424
+ });
425
+ program
426
+ .command('benchmark')
427
+ .description('Run embedding operation benchmarks')
428
+ .option('--dims <n>', 'Vector dimensions (default 1024)', '1024')
429
+ .option('--iterations <n>', 'Iterations (default 5000)', '5000')
430
+ .action((cmdOpts) => {
431
+ console.log('Running embedding benchmarks...\n');
432
+ const results = runEmbeddingBenchmark();
433
+ console.log(JSON.stringify({ ok: true, benchmark: results }, null, 2));
434
+ });
317
435
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akashabot/openclaw-mem",
3
- "version": "0.3.0",
3
+ "version": "0.5.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.3.0"
20
+ "@akashabot/openclaw-memory-offline-core": "^0.5.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/uuid": "^10.0.0"
package/src/cli.ts CHANGED
@@ -27,6 +27,20 @@ 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,
37
+ // Phase 3: Embedding Optimizations
38
+ getEmbeddingStats,
39
+ quantizeF32ToF16,
40
+ dequantizeF16ToF32,
41
+ cosineSimilarity,
42
+ benchmarkCosineSimilarity,
43
+ runEmbeddingBenchmark,
30
44
  } = core;
31
45
 
32
46
  const program = new Command();
@@ -381,4 +395,128 @@ program
381
395
  console.log(JSON.stringify({ ok: true, count: facts.length, facts }));
382
396
  });
383
397
 
398
+ // ============================================================================
399
+ // Phase 3: Knowledge Graph commands
400
+ // ============================================================================
401
+
402
+ program
403
+ .command('graph-stats')
404
+ .description('Get statistics about the knowledge graph')
405
+ .action(() => {
406
+ withDb((dbPath) => {
407
+ const db = openDb(dbPath);
408
+ initSchema(db);
409
+ const stats = getGraphStats(db);
410
+ console.log(JSON.stringify({ ok: true, stats }, null, 2));
411
+ });
412
+ });
413
+
414
+ program
415
+ .command('graph-entity <entity>')
416
+ .description('Get all facts connected to an entity (as subject or object)')
417
+ .action((entity: string) => {
418
+ withDb((dbPath) => {
419
+ const db = openDb(dbPath);
420
+ initSchema(db);
421
+ const edges = getEntityGraph(db, entity);
422
+ console.log(JSON.stringify({ ok: true, entity, count: edges.length, edges }));
423
+ });
424
+ });
425
+
426
+ program
427
+ .command('graph-related <entity>')
428
+ .description('Get all entities directly connected to an entity')
429
+ .action((entity: string) => {
430
+ withDb((dbPath) => {
431
+ const db = openDb(dbPath);
432
+ initSchema(db);
433
+ const related = getRelatedEntities(db, entity);
434
+ console.log(JSON.stringify({ ok: true, entity, count: related.length, related }));
435
+ });
436
+ });
437
+
438
+ program
439
+ .command('graph-path <fromEntity> <toEntity>')
440
+ .description('Find paths between two entities in the knowledge graph')
441
+ .option('--max-depth <n>', 'Maximum path depth (default 4)', '4')
442
+ .option('--max-paths <n>', 'Maximum number of paths to return (default 5)', '5')
443
+ .action((fromEntity: string, toEntity: string, cmdOpts) => {
444
+ withDb((dbPath) => {
445
+ const db = openDb(dbPath);
446
+ initSchema(db);
447
+ const maxDepth = Math.max(1, Math.min(10, Number(cmdOpts.maxDepth ?? 4)));
448
+ const maxPaths = Math.max(1, Math.min(20, Number(cmdOpts.maxPaths ?? 5)));
449
+ const paths = findPaths(db, fromEntity, toEntity, maxDepth, maxPaths);
450
+ console.log(JSON.stringify({ ok: true, from: fromEntity, to: toEntity, count: paths.length, paths }));
451
+ });
452
+ });
453
+
454
+ program
455
+ .command('graph-export [outputFile]')
456
+ .description('Export the knowledge graph as JSON (for visualization)')
457
+ .option('--limit <n>', 'Max edges to export (default 1000)', '1000')
458
+ .option('--min-confidence <n>', 'Minimum confidence threshold (default 0)', '0')
459
+ .option('--entity <entity>', 'Export only subgraph around this entity')
460
+ .action((outputFile: string | undefined, cmdOpts) => {
461
+ withDb((dbPath) => {
462
+ const db = openDb(dbPath);
463
+ initSchema(db);
464
+ const graph = exportGraphJson(db, {
465
+ limit: Number(cmdOpts.limit ?? 1000),
466
+ minConfidence: Number(cmdOpts.minConfidence ?? 0),
467
+ entity: cmdOpts.entity,
468
+ });
469
+
470
+ const output = JSON.stringify({ ok: true, graph }, null, 2);
471
+ if (outputFile) {
472
+ fs.writeFileSync(outputFile, output);
473
+ console.log(JSON.stringify({ ok: true, file: outputFile, nodes: graph.nodes.length, edges: graph.edges.length }));
474
+ } else {
475
+ console.log(output);
476
+ }
477
+ });
478
+ });
479
+
480
+ program
481
+ .command('search-entities <pattern>')
482
+ .description('Search for entities matching a pattern')
483
+ .option('--limit <n>', 'Max results (default 50)', '50')
484
+ .action((pattern: string, cmdOpts) => {
485
+ withDb((dbPath) => {
486
+ const db = openDb(dbPath);
487
+ initSchema(db);
488
+ const limit = Math.max(1, Math.min(500, Number(cmdOpts.limit ?? 50)));
489
+ const entities = searchEntities(db, pattern, limit);
490
+ console.log(JSON.stringify({ ok: true, pattern, count: entities.length, entities }));
491
+ });
492
+ });
493
+
494
+ // ============================================================================
495
+ // Phase 3: Embedding Optimization commands
496
+ // ============================================================================
497
+
498
+ program
499
+ .command('embedding-stats')
500
+ .description('Get statistics about stored embeddings')
501
+ .action(() => {
502
+ withDb((dbPath) => {
503
+ const db = openDb(dbPath);
504
+ initSchema(db);
505
+ const stats = getEmbeddingStats(db);
506
+ const sizeMB = Math.round((stats.totalSizeBytes / (1024 * 1024)) * 100) / 100;
507
+ console.log(JSON.stringify({ ok: true, ...stats, sizeMB }, null, 2));
508
+ });
509
+ });
510
+
511
+ program
512
+ .command('benchmark')
513
+ .description('Run embedding operation benchmarks')
514
+ .option('--dims <n>', 'Vector dimensions (default 1024)', '1024')
515
+ .option('--iterations <n>', 'Iterations (default 5000)', '5000')
516
+ .action((cmdOpts) => {
517
+ console.log('Running embedding benchmarks...\n');
518
+ const results = runEmbeddingBenchmark();
519
+ console.log(JSON.stringify({ ok: true, benchmark: results }, null, 2));
520
+ });
521
+
384
522
  program.parse();