hippo-memory 0.11.2 → 0.13.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/README.md +9 -0
- package/dist/autolearn.d.ts.map +1 -1
- package/dist/autolearn.js +3 -1
- package/dist/autolearn.js.map +1 -1
- package/dist/cli.js +11 -6
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/embeddings.js +45 -22
- package/dist/embeddings.js.map +1 -1
- package/dist/importers.d.ts.map +1 -1
- package/dist/importers.js +5 -1
- package/dist/importers.js.map +1 -1
- package/dist/mcp/server.js +18 -14
- package/dist/mcp/server.js.map +1 -1
- package/dist/memory.d.ts +1 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +9 -5
- package/dist/memory.js.map +1 -1
- package/dist/physics-state.d.ts +1 -1
- package/dist/physics-state.d.ts.map +1 -1
- package/dist/physics-state.js +5 -2
- package/dist/physics-state.js.map +1 -1
- package/dist/physics.d.ts.map +1 -1
- package/dist/physics.js +16 -4
- package/dist/physics.js.map +1 -1
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +18 -15
- package/dist/search.js.map +1 -1
- package/dist/shared.d.ts +4 -2
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +16 -8
- package/dist/shared.js.map +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +24 -6
- package/dist/store.js.map +1 -1
- package/extensions/openclaw-plugin/index.ts +39 -33
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Config lives under plugins.entries.hippo-memory.config
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { execFileSync } from 'child_process';
|
|
11
11
|
import { existsSync } from 'fs';
|
|
12
12
|
import { join } from 'path';
|
|
13
13
|
import { basename as posixBasename, dirname as posixDirname } from 'path/posix';
|
|
@@ -77,10 +77,13 @@ function getConfig(api: any): HippoConfig {
|
|
|
77
77
|
function findHippoRoot(workspace?: string, configRoot?: string): string | null {
|
|
78
78
|
if (configRoot && existsSync(configRoot)) return configRoot;
|
|
79
79
|
|
|
80
|
+
const home = process.env.USERPROFILE || process.env.HOME || '';
|
|
80
81
|
const candidates = [
|
|
81
82
|
workspace ? join(workspace, '.hippo') : null,
|
|
83
|
+
process.env.HIPPO_HOME,
|
|
82
84
|
process.env.HIPPO_ROOT,
|
|
83
|
-
|
|
85
|
+
process.env.XDG_DATA_HOME ? join(process.env.XDG_DATA_HOME, 'hippo') : null,
|
|
86
|
+
home ? join(home, '.hippo') : null,
|
|
84
87
|
].filter(Boolean) as string[];
|
|
85
88
|
|
|
86
89
|
for (const candidate of candidates) {
|
|
@@ -164,15 +167,15 @@ function hippoRememberSucceeded(result: string): boolean {
|
|
|
164
167
|
return result.includes('Remembered [');
|
|
165
168
|
}
|
|
166
169
|
|
|
167
|
-
function runHippo(args: string, cwd?: string): string {
|
|
170
|
+
function runHippo(args: readonly string[], cwd?: string): string {
|
|
168
171
|
try {
|
|
169
|
-
const result =
|
|
172
|
+
const result = execFileSync('hippo', args, {
|
|
170
173
|
cwd: cwd || process.cwd(),
|
|
171
|
-
|
|
172
|
-
|
|
174
|
+
encoding: 'utf8',
|
|
175
|
+
timeout: 30_000,
|
|
173
176
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
174
177
|
});
|
|
175
|
-
return result.trim();
|
|
178
|
+
return typeof result === 'string' ? result.trim() : '';
|
|
176
179
|
} catch (err: any) {
|
|
177
180
|
return err.stdout?.trim() || err.message || 'hippo command failed';
|
|
178
181
|
}
|
|
@@ -206,7 +209,7 @@ export default function register(api: any) {
|
|
|
206
209
|
const framing = cfg.framing ?? 'observe';
|
|
207
210
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
208
211
|
const result = runHippo(
|
|
209
|
-
|
|
212
|
+
['recall', params.query, '--budget', String(budget), '--framing', framing],
|
|
210
213
|
hippoCwd,
|
|
211
214
|
);
|
|
212
215
|
return { content: [{ type: 'text', text: result || 'No relevant memories found.' }] };
|
|
@@ -246,10 +249,13 @@ export default function register(api: any) {
|
|
|
246
249
|
) {
|
|
247
250
|
const cfg = getConfig(api);
|
|
248
251
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
249
|
-
|
|
250
|
-
if (params.error) args
|
|
251
|
-
if (params.pin) args
|
|
252
|
-
if (params.tag)
|
|
252
|
+
const args: string[] = ['remember', params.text];
|
|
253
|
+
if (params.error) args.push('--error');
|
|
254
|
+
if (params.pin) args.push('--pin');
|
|
255
|
+
if (params.tag) {
|
|
256
|
+
const safe = sanitizeTag(params.tag);
|
|
257
|
+
if (safe) args.push('--tag', safe);
|
|
258
|
+
}
|
|
253
259
|
const result = runHippo(args, hippoCwd);
|
|
254
260
|
if (hippoRememberSucceeded(result)) {
|
|
255
261
|
recordSessionMemory(ctx);
|
|
@@ -277,7 +283,7 @@ export default function register(api: any) {
|
|
|
277
283
|
const cfg = getConfig(api);
|
|
278
284
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
279
285
|
const flag = params.good ? '--good' : '--bad';
|
|
280
|
-
const result = runHippo(
|
|
286
|
+
const result = runHippo(['outcome', flag], hippoCwd);
|
|
281
287
|
return { content: [{ type: 'text', text: result || 'Outcome recorded.' }] };
|
|
282
288
|
},
|
|
283
289
|
}));
|
|
@@ -295,7 +301,7 @@ export default function register(api: any) {
|
|
|
295
301
|
async execute() {
|
|
296
302
|
const cfg = getConfig(api);
|
|
297
303
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
298
|
-
const result = runHippo('status', hippoCwd);
|
|
304
|
+
const result = runHippo(['status'], hippoCwd);
|
|
299
305
|
return { content: [{ type: 'text', text: result || 'No hippo store found.' }] };
|
|
300
306
|
},
|
|
301
307
|
}),
|
|
@@ -323,7 +329,7 @@ export default function register(api: any) {
|
|
|
323
329
|
const framing = cfg.framing ?? 'observe';
|
|
324
330
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
325
331
|
const result = runHippo(
|
|
326
|
-
|
|
332
|
+
['context', '--auto', '--budget', String(budget), '--framing', framing],
|
|
327
333
|
hippoCwd,
|
|
328
334
|
);
|
|
329
335
|
return { content: [{ type: 'text', text: result || 'No context available.' }] };
|
|
@@ -350,7 +356,7 @@ export default function register(api: any) {
|
|
|
350
356
|
async execute(_id: string, params: { json?: boolean }) {
|
|
351
357
|
const cfg = getConfig(api);
|
|
352
358
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
353
|
-
const args = params.json ? 'conflicts --json' : 'conflicts';
|
|
359
|
+
const args: string[] = params.json ? ['conflicts', '--json'] : ['conflicts'];
|
|
354
360
|
const result = runHippo(args, hippoCwd);
|
|
355
361
|
return { content: [{ type: 'text', text: result || 'No conflicts found.' }] };
|
|
356
362
|
},
|
|
@@ -388,8 +394,8 @@ export default function register(api: any) {
|
|
|
388
394
|
) {
|
|
389
395
|
const cfg = getConfig(api);
|
|
390
396
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
391
|
-
|
|
392
|
-
if (params.forget) args
|
|
397
|
+
const args: string[] = ['resolve', String(params.conflict_id), '--keep', params.keep];
|
|
398
|
+
if (params.forget) args.push('--forget');
|
|
393
399
|
const result = runHippo(args, hippoCwd);
|
|
394
400
|
return { content: [{ type: 'text', text: result || 'Conflict resolved.' }] };
|
|
395
401
|
},
|
|
@@ -423,12 +429,12 @@ export default function register(api: any) {
|
|
|
423
429
|
) {
|
|
424
430
|
const cfg = getConfig(api);
|
|
425
431
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
426
|
-
|
|
432
|
+
const args: string[] = ['share'];
|
|
427
433
|
if (params.id === 'auto') {
|
|
428
|
-
args
|
|
434
|
+
args.push('--auto');
|
|
429
435
|
} else {
|
|
430
|
-
args
|
|
431
|
-
if (params.force) args
|
|
436
|
+
args.push(params.id);
|
|
437
|
+
if (params.force) args.push('--force');
|
|
432
438
|
}
|
|
433
439
|
const result = runHippo(args, hippoCwd);
|
|
434
440
|
return { content: [{ type: 'text', text: result || 'Share complete.' }] };
|
|
@@ -450,7 +456,7 @@ export default function register(api: any) {
|
|
|
450
456
|
async execute() {
|
|
451
457
|
const cfg = getConfig(api);
|
|
452
458
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
453
|
-
const result = runHippo('peers', hippoCwd);
|
|
459
|
+
const result = runHippo(['peers'], hippoCwd);
|
|
454
460
|
return { content: [{ type: 'text', text: result || 'No peers found.' }] };
|
|
455
461
|
},
|
|
456
462
|
}),
|
|
@@ -489,9 +495,8 @@ export default function register(api: any) {
|
|
|
489
495
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
490
496
|
const scope = params.scope ?? 'repo';
|
|
491
497
|
const importance = params.importance ?? 0.5;
|
|
492
|
-
const escapedContent = params.content.replace(/"/g, '\\"');
|
|
493
498
|
const result = runHippo(
|
|
494
|
-
|
|
499
|
+
['wm', 'push', '--scope', scope, '--content', params.content, '--importance', String(importance)],
|
|
495
500
|
hippoCwd,
|
|
496
501
|
);
|
|
497
502
|
return { content: [{ type: 'text', text: result || 'Working memory entry pushed.' }] };
|
|
@@ -521,7 +526,7 @@ export default function register(api: any) {
|
|
|
521
526
|
// Record session_start event
|
|
522
527
|
try {
|
|
523
528
|
runHippo(
|
|
524
|
-
|
|
529
|
+
['session', 'log', '--id', sessionKey, '--type', 'session_start', '--content', 'Session started', '--source', 'openclaw'],
|
|
525
530
|
hippoCwd,
|
|
526
531
|
);
|
|
527
532
|
} catch (err) {
|
|
@@ -530,7 +535,7 @@ export default function register(api: any) {
|
|
|
530
535
|
|
|
531
536
|
try {
|
|
532
537
|
const context = runHippo(
|
|
533
|
-
|
|
538
|
+
['context', '--auto', '--budget', String(budget), '--framing', framing],
|
|
534
539
|
hippoCwd,
|
|
535
540
|
);
|
|
536
541
|
if (context && context.length > 10 && !context.includes('No hippo store')) {
|
|
@@ -580,10 +585,11 @@ export default function register(api: any) {
|
|
|
580
585
|
|
|
581
586
|
const hippoCwd = resolveHippoCwdFromContext(api, ctx, cfg.root);
|
|
582
587
|
const toolTag = sanitizeTag(event.toolName);
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
'
|
|
586
|
-
|
|
588
|
+
const args: string[] = [
|
|
589
|
+
'remember', formatToolErrorMemory(event.toolName, event.error),
|
|
590
|
+
'--error', '--observed', '--tag', 'openclaw',
|
|
591
|
+
];
|
|
592
|
+
if (toolTag) args.push('--tag', toolTag);
|
|
587
593
|
|
|
588
594
|
const result = runHippo(args, hippoCwd);
|
|
589
595
|
if (hippoRememberSucceeded(result)) {
|
|
@@ -612,7 +618,7 @@ export default function register(api: any) {
|
|
|
612
618
|
// Record session_end event
|
|
613
619
|
try {
|
|
614
620
|
runHippo(
|
|
615
|
-
|
|
621
|
+
['session', 'log', '--id', sessionKey, '--type', 'session_end', '--content', 'Session ended', '--source', 'openclaw'],
|
|
616
622
|
hippoCwd,
|
|
617
623
|
);
|
|
618
624
|
} catch (err) {
|
|
@@ -621,7 +627,7 @@ export default function register(api: any) {
|
|
|
621
627
|
|
|
622
628
|
const newMemories = consumeSessionMemoryCount(ctx);
|
|
623
629
|
if (!cfg.autoSleep || newMemories < AUTO_SLEEP_SESSION_THRESHOLD) return;
|
|
624
|
-
const result = runHippo('sleep', hippoCwd);
|
|
630
|
+
const result = runHippo(['sleep'], hippoCwd);
|
|
625
631
|
logger.info?.(
|
|
626
632
|
`[hippo] autoSleep ran for session ${ctx.sessionId ?? ctx.sessionKey ?? 'unknown'} ` +
|
|
627
633
|
`after ${newMemories} new memories`,
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "hippo-memory",
|
|
3
3
|
"name": "Hippo Memory",
|
|
4
4
|
"description": "Biologically-inspired memory for AI agents. Decay by default, retrieval strengthening, sleep consolidation.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.13.0",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|