hippo-memory 0.24.1 → 0.26.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.
@@ -0,0 +1,52 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Hippo Brain Observatory</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
+ <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
10
+ <style>
11
+ :root {
12
+ --bg: #0a0c10;
13
+ --surface: #14161e;
14
+ --border: rgba(255, 255, 255, 0.06);
15
+ --text: #e1e4ed;
16
+ --muted: #6b7084;
17
+ --accent: #7c5cff;
18
+ --green: #34d399;
19
+ --yellow: #f0a030;
20
+ --red: #f87171;
21
+ --purple: #a78bfa;
22
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
23
+ --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
24
+ --glass-bg: rgba(10, 12, 16, 0.82);
25
+ --glass-blur: blur(16px);
26
+ --glass-border: 1px solid rgba(255, 255, 255, 0.06);
27
+ }
28
+
29
+ * {
30
+ margin: 0;
31
+ padding: 0;
32
+ box-sizing: border-box;
33
+ }
34
+
35
+ body {
36
+ background: var(--bg);
37
+ color: var(--text);
38
+ font-family: var(--font-body);
39
+ overflow: hidden;
40
+ }
41
+
42
+ #root {
43
+ width: 100vw;
44
+ height: 100vh;
45
+ }
46
+ </style>
47
+ <script type="module" crossorigin src="/assets/index-CxxqB9Wc.js"></script>
48
+ </head>
49
+ <body>
50
+ <div id="root"></div>
51
+ </body>
52
+ </html>
@@ -33,7 +33,7 @@ Add to `openclaw.json`:
33
33
  budget: 1500, // token budget for context injection
34
34
  autoContext: true, // auto-inject memory at session start
35
35
  autoLearn: true, // auto-capture errors (filtered, deduplicated, rate-limited)
36
- autoSleep: false, // auto-consolidate after heavy sessions
36
+ autoSleep: false, // queue detached hippo sleep after heavy sessions
37
37
  framing: "observe" // observe | suggest | assert
38
38
  // root: "C:/path/to/workspace/.hippo" // optional override
39
39
  }
@@ -45,6 +45,16 @@ Add to `openclaw.json`:
45
45
 
46
46
  Restart the gateway after enabling.
47
47
 
48
+ `autoSleep` is off by default so consolidation does not compete with the live
49
+ session. If you turn it on, the plugin schedules `hippo sleep` in a detached
50
+ background process on `session_end` once the session has created at least 10 new
51
+ memories, then returns immediately to OpenClaw.
52
+
53
+ Strict daily consolidation does not depend on `autoSleep`. `hippo init` /
54
+ `hippo setup` install one machine-level daily runner that sweeps every
55
+ registered Hippo workspace and runs `hippo learn --git --days 1` followed by
56
+ `hippo sleep`.
57
+
48
58
  ## What It Does
49
59
 
50
60
  ### Auto-context injection
@@ -56,6 +66,13 @@ workspace's local `.hippo/` store and automatically merges any global `~/.hippo/
56
66
  store during `recall` / `context`. You only need `config.root` if you want to
57
67
  override workspace auto-detection.
58
68
 
69
+ ### Session-end auto-sleep
70
+
71
+ When `autoSleep` is enabled, Hippo does not block OpenClaw shutdown waiting for
72
+ consolidation. The plugin records the session end event, spawns a detached
73
+ `hippo sleep` worker, and returns. If detached spawn fails, it falls back to the
74
+ old inline `sleep` path so consolidation still happens.
75
+
59
76
  ### Agent tools
60
77
 
61
78
  The plugin registers these tools for the agent to call:
@@ -7,7 +7,7 @@
7
7
  * Config lives under plugins.entries.hippo-memory.config
8
8
  */
9
9
 
10
- import { execFileSync } from 'child_process';
10
+ import { execFileSync, spawn } from 'child_process';
11
11
  import { existsSync, readdirSync, rmSync } from 'fs';
12
12
  import { join } from 'path';
13
13
  import { basename as posixBasename, dirname as posixDirname } from 'path/posix';
@@ -191,21 +191,36 @@ function hippoRememberSucceeded(result: string): boolean {
191
191
  return result.includes('Remembered [');
192
192
  }
193
193
 
194
- function runHippo(args: readonly string[], cwd?: string): string {
195
- try {
196
- const result = execFileSync('hippo', args, {
197
- cwd: cwd || process.cwd(),
198
- encoding: 'utf8',
194
+ function runHippo(args: readonly string[], cwd?: string): string {
195
+ try {
196
+ const result = execFileSync('hippo', args, {
197
+ cwd: cwd || process.cwd(),
198
+ encoding: 'utf8',
199
199
  timeout: 30_000,
200
200
  stdio: ['pipe', 'pipe', 'pipe'],
201
201
  });
202
202
  return typeof result === 'string' ? result.trim() : '';
203
203
  } catch (err: any) {
204
204
  return err.stdout?.trim() || err.message || 'hippo command failed';
205
- }
206
- }
207
-
208
- let _registered = false;
205
+ }
206
+ }
207
+
208
+ function spawnHippoDetached(args: readonly string[], cwd?: string): boolean {
209
+ try {
210
+ const child = spawn('hippo', [...args], {
211
+ cwd: cwd || process.cwd(),
212
+ detached: true,
213
+ stdio: 'ignore',
214
+ windowsHide: true,
215
+ });
216
+ child.unref();
217
+ return true;
218
+ } catch {
219
+ return false;
220
+ }
221
+ }
222
+
223
+ let _registered = false;
209
224
 
210
225
  export default function register(api: any) {
211
226
  if (_registered) return;
@@ -655,18 +670,27 @@ export default function register(api: any) {
655
670
  );
656
671
  } catch (err) {
657
672
  logger.debug?.('[hippo] session_end event skipped:', err);
658
- }
659
-
660
- const newMemories = consumeSessionMemoryCount(ctx);
661
- if (!cfg.autoSleep || newMemories < AUTO_SLEEP_SESSION_THRESHOLD) return;
662
- const result = runHippo(['sleep'], hippoCwd);
663
- logger.info?.(
664
- `[hippo] autoSleep ran for session ${ctx.sessionId ?? ctx.sessionKey ?? 'unknown'} ` +
665
- `after ${newMemories} new memories`,
666
- );
667
- logger.debug?.(`[hippo] autoSleep result: ${result}`);
668
- },
669
- );
673
+ }
674
+
675
+ const newMemories = consumeSessionMemoryCount(ctx);
676
+ if (!cfg.autoSleep || newMemories < AUTO_SLEEP_SESSION_THRESHOLD) return;
677
+ const sessionLabel = ctx.sessionId ?? ctx.sessionKey ?? 'unknown';
678
+ if (spawnHippoDetached(['sleep'], hippoCwd)) {
679
+ logger.info?.(
680
+ `[hippo] autoSleep scheduled for session ${sessionLabel} ` +
681
+ `after ${newMemories} new memories`,
682
+ );
683
+ return;
684
+ }
685
+
686
+ const result = runHippo(['sleep'], hippoCwd);
687
+ logger.warn?.(
688
+ `[hippo] autoSleep fell back to inline execution for session ${sessionLabel} ` +
689
+ `after ${newMemories} new memories`,
690
+ );
691
+ logger.debug?.(`[hippo] autoSleep result: ${result}`);
692
+ },
693
+ );
670
694
 
671
695
  logger.info?.('[hippo] Memory plugin registered (tools: hippo_recall, hippo_remember, hippo_outcome, hippo_status, hippo_context, hippo_conflicts, hippo_resolve, hippo_share, hippo_peers, hippo_wm_push)');
672
696
  }
@@ -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.24.1",
5
+ "version": "0.26.0",
6
6
 
7
7
  "configSchema": {
8
8
  "type": "object",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "autoSleep": {
24
24
  "type": "boolean",
25
- "description": "Run consolidation after sessions with 10+ new memories (default: false)"
25
+ "description": "Queue detached consolidation after sessions with 10+ new memories (default: false)"
26
26
  },
27
27
  "framing": {
28
28
  "type": "string",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hippo-memory",
3
- "version": "0.24.1",
3
+ "version": "0.26.0",
4
4
  "description": "Hippo Memory plugin for OpenClaw - biologically-inspired agent memory",
5
5
  "main": "index.ts",
6
6
  "openclaw": {
@@ -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.24.1",
5
+ "version": "0.26.0",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "autoSleep": {
23
23
  "type": "boolean",
24
- "description": "Run consolidation after sessions with 10+ new memories (default: false)"
24
+ "description": "Queue detached consolidation after sessions with 10+ new memories (default: false)"
25
25
  },
26
26
  "framing": {
27
27
  "type": "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hippo-memory",
3
- "version": "0.24.1",
3
+ "version": "0.26.0",
4
4
  "description": "Biologically-inspired memory system for AI agents. Decay by default, strength through use.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,6 +17,7 @@
17
17
  },
18
18
  "files": [
19
19
  "dist",
20
+ "dist-ui",
20
21
  "bin",
21
22
  "scripts/postinstall.cjs",
22
23
  "openclaw.plugin.json",
@@ -30,7 +31,9 @@
30
31
  "postinstall": "node scripts/postinstall.cjs",
31
32
  "smoke:pack": "node scripts/smoke-pack.mjs",
32
33
  "smoke:openclaw-install": "node scripts/smoke-openclaw-install.mjs",
33
- "prepublishOnly": "npm run build"
34
+ "build:ui": "cd ui && npm install && npm run build",
35
+ "build:all": "npm run build && npm run build:ui",
36
+ "prepublishOnly": "npm run build:all"
34
37
  },
35
38
  "keywords": [
36
39
  "memory",