pi-hermes-memory 0.7.23 → 0.8.1
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 +18 -5
- package/package.json +5 -4
- package/scripts/ensure-dev.mjs +57 -0
- package/src/config.ts +6 -0
- package/src/constants.ts +53 -11
- package/src/extension-root-migration.ts +429 -5
- package/src/handlers/auto-consolidate.ts +118 -8
- package/src/handlers/background-review.ts +29 -23
- package/src/handlers/child-process-watchdog.mjs +90 -0
- package/src/handlers/correction-detector.ts +52 -36
- package/src/handlers/pi-child-process.ts +270 -37
- package/src/handlers/review-memory-ops.ts +18 -116
- package/src/handlers/session-flush.ts +71 -4
- package/src/handlers/sync-markdown-memories.ts +143 -51
- package/src/index.ts +32 -16
- package/src/store/atomic-lock-coordinator.ts +252 -0
- package/src/store/canonical-storage-path.ts +54 -0
- package/src/store/db.ts +244 -9
- package/src/store/markdown-mutation-lock.ts +38 -0
- package/src/store/memory-store.ts +455 -57
- package/src/store/sqlite-memory-store.ts +121 -4
- package/src/tools/memory-tool.ts +48 -9
- package/src/tools/session-search-tool.ts +70 -12
- package/src/types.ts +2 -0
package/README.md
CHANGED
|
@@ -92,6 +92,18 @@ Every write — memory and skills — passes through a scanner before being acce
|
|
|
92
92
|
|
|
93
93
|

|
|
94
94
|
|
|
95
|
+
## Development
|
|
96
|
+
|
|
97
|
+
`npm run check` and `npm test` only work from a **full git checkout** after `npm install`. The published npm package intentionally omits `tests/`, TypeScript, and `tsconfig.json` (production install for Pi). Validate from source or rely on CI before publish.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
git clone https://github.com/chandra447/pi-hermes-memory.git
|
|
101
|
+
cd pi-hermes-memory
|
|
102
|
+
npm install
|
|
103
|
+
npm run check
|
|
104
|
+
npm test
|
|
105
|
+
```
|
|
106
|
+
|
|
95
107
|
## Installation
|
|
96
108
|
|
|
97
109
|
```bash
|
|
@@ -339,18 +351,18 @@ Background review triggers based on **activity level**, not just turn count:
|
|
|
339
351
|
|
|
340
352
|
Both counters reset after each review.
|
|
341
353
|
|
|
342
|
-
###
|
|
354
|
+
### Direct-Transport LLM Calls (Review, Flush, Correction, Consolidation)
|
|
343
355
|
|
|
344
|
-
By default, background review
|
|
356
|
+
By default, background review, session flush, correction save, and the manual `/memory-consolidate` command use an in-process `completeSimple()` side-channel: a small JSON-only prompt, no child `pi` process, and memory writes applied directly by the extension. This keeps the main session's system prompt, tools, and LLM prefix cache intact, and avoids the subprocess path's argv/`--no-extensions` concerns entirely on the common path.
|
|
345
357
|
|
|
346
|
-
If direct
|
|
358
|
+
If direct mode fails (no model, no auth, provider error, unparseable response, or — for consolidation only — a result that didn't actually free any space), it automatically falls back to the legacy `pi -p --no-session` subprocess path. The automatic over-capacity consolidator triggered from `MemoryStore` itself always uses the subprocess path, since it runs without extension-runtime access.
|
|
347
359
|
|
|
348
360
|
Set `reviewTransport` in config only when you need to override this:
|
|
349
361
|
|
|
350
362
|
| Value | Behavior |
|
|
351
363
|
|---|---|
|
|
352
364
|
| `direct` (default) | Try in-process `completeSimple()` first; fall back to subprocess on failure |
|
|
353
|
-
| `subprocess` | Always use `pi -p` subprocess (pre-PR #92 behavior) |
|
|
365
|
+
| `subprocess` | Always use `pi -p` subprocess for every LLM-driven memory operation (pre-PR #92 behavior) |
|
|
354
366
|
|
|
355
367
|
### Skill Auto-Extraction
|
|
356
368
|
|
|
@@ -471,11 +483,12 @@ Create `~/.pi/agent/hermes-memory-config.json`:
|
|
|
471
483
|
| `sessionSearch` | `{ "variant": "legacy" }` | Session search implementation: `legacy` keeps the existing SQLite/FTS snippet search; `anchors` uses the opt-in Markdown request surface and returns compact JSONL line-range anchors from `~/.pi/agent/sessions/` |
|
|
472
484
|
| `llmModelOverride` | unset | Optional model override for background review (direct and subprocess), correction save, session flush, and consolidation |
|
|
473
485
|
| `llmThinkingOverride` | unset | Optional thinking override for those LLM calls; valid values are `off`, `minimal`, `low`, `medium`, `high`, and `xhigh`. If `llmModelOverride` is set and this is omitted, review/child calls default to `off` |
|
|
486
|
+
| `childExtensionPaths` | unset | Trusted provider/auth adapter entry paths explicitly allowed in isolated child Pi processes; sibling packages matching the `*-oauth-adapter`/`*-auth-adapter` naming convention (including scoped packages, via their `package.json` `pi.extensions` manifest) are detected automatically — this setting is only needed for adapters that don't match that convention. In-process direct transport (the default for review/flush/correction/consolidation) doesn't need this at all, since it reads whatever provider auth is already registered |
|
|
474
487
|
| `nudgeInterval` | `10` | Turns between auto-reviews |
|
|
475
488
|
| `nudgeToolCalls` | `15` | Tool calls between auto-reviews (OR with turns) |
|
|
476
489
|
| `reviewRecentMessages` | `0` | Recent messages included in background review (`0` = all) |
|
|
477
490
|
| `reviewEnabled` | `true` | Enable/disable background learning loop |
|
|
478
|
-
| `reviewTransport` | `direct` |
|
|
491
|
+
| `reviewTransport` | `direct` | LLM transport for background review, session flush, correction save, and manual consolidation: `direct` uses in-process `completeSimple()` with subprocess fallback; `subprocess` forces legacy `pi -p` only |
|
|
479
492
|
| `memoryOverflowStrategy` | `auto-consolidate` | Behavior when MEMORY.md, USER.md, failures.md, or project-scoped memory reaches its character limit: `auto-consolidate` runs the existing consolidation flow; `reject` returns an error; `fifo-evict` rotates older entries in file order until the new entry fits |
|
|
480
493
|
| `autoConsolidate` | `true` | Legacy alias for `memoryOverflowStrategy` when `memoryOverflowStrategy` is not set (`true` = `auto-consolidate`, `false` = `reject`) |
|
|
481
494
|
| `consolidationTimeoutMs` | `60000` | Maximum time in milliseconds for auto-consolidation to complete |
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-hermes-memory",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "🧠 Persistent memory + 🔍 session search + 🛡️ secret scanning for Pi. Token-aware policy-only memory by default, SQLite FTS5 search, auto-consolidation, procedural skills.
|
|
3
|
+
"version": "0.8.1",
|
|
4
|
+
"description": "🧠 Persistent memory + 🔍 session search + 🛡️ secret scanning for Pi. Token-aware policy-only memory by default, SQLite FTS5 search, auto-consolidation, procedural skills. 693 tests. Ported from Hermes agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"src",
|
|
9
|
+
"scripts",
|
|
9
10
|
"README.md",
|
|
10
11
|
"LICENSE",
|
|
11
12
|
"docs"
|
|
@@ -16,8 +17,8 @@
|
|
|
16
17
|
]
|
|
17
18
|
},
|
|
18
19
|
"scripts": {
|
|
19
|
-
"check": "tsc --noEmit",
|
|
20
|
-
"test": "tests/run-all.sh"
|
|
20
|
+
"check": "node scripts/ensure-dev.mjs check && tsc --noEmit",
|
|
21
|
+
"test": "node scripts/ensure-dev.mjs test && tests/run-all.sh"
|
|
21
22
|
},
|
|
22
23
|
"keywords": [
|
|
23
24
|
"pi-package",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Guard for check/test npm scripts.
|
|
4
|
+
*
|
|
5
|
+
* The published tarball intentionally omits tests/ and TypeScript (devDependency).
|
|
6
|
+
* When those scripts are run from an installed package (e.g. after `pi install`),
|
|
7
|
+
* fail with a clear message instead of `tsc: not found` / `tests/run-all.sh: not found`.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/chandra447/pi-hermes-memory/issues/108
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
12
|
+
import { createRequire } from "node:module";
|
|
13
|
+
import { dirname, join } from "node:path";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
|
|
16
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
17
|
+
const mode = process.argv[2];
|
|
18
|
+
const REPO = "https://github.com/chandra447/pi-hermes-memory";
|
|
19
|
+
|
|
20
|
+
function fail(message) {
|
|
21
|
+
console.error(`\n[pi-hermes-memory] ${message}`);
|
|
22
|
+
console.error("");
|
|
23
|
+
console.error("These scripts only work from a full source checkout:");
|
|
24
|
+
console.error(` git clone ${REPO}.git`);
|
|
25
|
+
console.error(" cd pi-hermes-memory && npm install");
|
|
26
|
+
console.error(" npm run check # or: npm test");
|
|
27
|
+
console.error("");
|
|
28
|
+
console.error(
|
|
29
|
+
"The published package is for runtime use via Pi; CI validates check/test before publish.",
|
|
30
|
+
);
|
|
31
|
+
console.error("");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (mode === "check") {
|
|
36
|
+
const require = createRequire(join(root, "package.json"));
|
|
37
|
+
try {
|
|
38
|
+
require.resolve("typescript/package.json");
|
|
39
|
+
} catch {
|
|
40
|
+
fail(
|
|
41
|
+
"`npm run check` requires TypeScript (a devDependency). The published npm package does not include it.",
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (!existsSync(join(root, "tsconfig.json"))) {
|
|
45
|
+
fail(
|
|
46
|
+
"`npm run check` requires tsconfig.json. The published npm package does not include it.",
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
} else if (mode === "test") {
|
|
50
|
+
if (!existsSync(join(root, "tests", "run-all.sh"))) {
|
|
51
|
+
fail(
|
|
52
|
+
"`npm test` requires the tests/ directory. The published npm package intentionally omits it.",
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
fail(`Unknown mode "${mode ?? ""}". Expected "check" or "test".`);
|
|
57
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -141,6 +141,12 @@ export function loadConfig(configPath = DEFAULT_CONFIG_PATH): MemoryConfig {
|
|
|
141
141
|
if (trimmed.length > 0) config.llmModelOverride = trimmed;
|
|
142
142
|
}
|
|
143
143
|
if (isThinkingLevel(parsed.llmThinkingOverride)) config.llmThinkingOverride = parsed.llmThinkingOverride;
|
|
144
|
+
if (isStringArray(parsed.childExtensionPaths)) {
|
|
145
|
+
const childExtensionPaths = [...new Set<string>(
|
|
146
|
+
(parsed.childExtensionPaths as string[]).map((item) => item.trim()).filter(Boolean),
|
|
147
|
+
)];
|
|
148
|
+
if (childExtensionPaths.length > 0) config.childExtensionPaths = childExtensionPaths;
|
|
149
|
+
}
|
|
144
150
|
if (hasMemoryOverflowStrategy) {
|
|
145
151
|
config.autoConsolidate = config.memoryOverflowStrategy === "auto-consolidate";
|
|
146
152
|
} else if (hasLegacyAutoConsolidate) {
|
package/src/constants.ts
CHANGED
|
@@ -145,16 +145,11 @@ For failures, include: what was tried, why it failed, what error occurred, and w
|
|
|
145
145
|
|
|
146
146
|
Only act if there's something genuinely worth saving. If nothing stands out, just say 'Nothing to save.' and stop.`;
|
|
147
147
|
|
|
148
|
-
// ───
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
- **Failures & Corrections**: What failed, user corrections, insights, conventions, tool quirks.
|
|
154
|
-
|
|
155
|
-
Do NOT create or modify skills. Only save genuinely durable facts — not task progress, session outcomes, or temporary state.
|
|
156
|
-
|
|
157
|
-
Respond with JSON only (no markdown fences):
|
|
148
|
+
// ─── Shared JSON operations schema for direct (in-process) completions ───
|
|
149
|
+
// (review/flush/consolidation/correction all ask the model to respond with
|
|
150
|
+
// this same {"operations":[...]} shape instead of calling the memory tool,
|
|
151
|
+
// since direct mode is a single completeSimple() call with no tool loop).
|
|
152
|
+
const DIRECT_MEMORY_OPERATIONS_SCHEMA = `Respond with JSON only (no markdown fences):
|
|
158
153
|
{
|
|
159
154
|
"operations": [
|
|
160
155
|
{
|
|
@@ -171,10 +166,57 @@ Operation fields:
|
|
|
171
166
|
- content: required for add/replace
|
|
172
167
|
- old_text: required for replace/remove (substring match)
|
|
173
168
|
- category: for failure target — failure | correction | insight | convention | tool-quirk | preference
|
|
174
|
-
- failure_reason: optional context for failure entries
|
|
169
|
+
- failure_reason: optional context for failure entries`;
|
|
170
|
+
|
|
171
|
+
export const DIRECT_REVIEW_SYSTEM_PROMPT = `You review coding conversations and extract durable memories worth saving across sessions.
|
|
172
|
+
|
|
173
|
+
Review these aspects:
|
|
174
|
+
- **Memory**: User persona, preferences, expectations about how the agent should behave, work style.
|
|
175
|
+
- **Failures & Corrections**: What failed, user corrections, insights, conventions, tool quirks.
|
|
176
|
+
|
|
177
|
+
Do NOT create or modify skills. Only save genuinely durable facts — not task progress, session outcomes, or temporary state.
|
|
178
|
+
|
|
179
|
+
${DIRECT_MEMORY_OPERATIONS_SCHEMA}
|
|
175
180
|
|
|
176
181
|
If nothing is worth saving, return {"operations":[]}.`;
|
|
177
182
|
|
|
183
|
+
// ─── Direct (in-process) flush prompt — used by session-flush.ts when the
|
|
184
|
+
// session is about to lose context (compaction/shutdown). ───
|
|
185
|
+
export const DIRECT_FLUSH_SYSTEM_PROMPT = `The session is being compressed and about to lose context. Save anything worth remembering from the conversation — prioritize user preferences, corrections, and recurring patterns over task-specific details.
|
|
186
|
+
|
|
187
|
+
${DIRECT_MEMORY_OPERATIONS_SCHEMA}
|
|
188
|
+
|
|
189
|
+
If nothing is worth saving, return {"operations":[]}.`;
|
|
190
|
+
|
|
191
|
+
// ─── Direct (in-process) consolidation prompt — used by auto-consolidate.ts.
|
|
192
|
+
// Unlike review/flush/correction, a single triggerConsolidation() call is
|
|
193
|
+
// always scoped to exactly one target/store, passed via the user prompt. ───
|
|
194
|
+
export const DIRECT_CONSOLIDATION_SYSTEM_PROMPT = `The memory store you're given is at capacity. Consolidate its current entries:
|
|
195
|
+
- Merge related entries into a single, concise entry
|
|
196
|
+
- Remove outdated or superseded entries (entries older than 30 days without recent references are candidates for removal)
|
|
197
|
+
- Keep the most important and frequently-referenced facts
|
|
198
|
+
- Preserve user preferences and corrections (highest priority)
|
|
199
|
+
|
|
200
|
+
Each entry shows when it was created and last referenced in HTML comments (<!-- created=..., last=... -->). Use this to identify stale entries.
|
|
201
|
+
|
|
202
|
+
Express a merge as "remove" operations for the entries being dropped plus one "add" operation for the new merged entry. Be aggressive about merging — less is more. Every operation MUST use the exact target given to you in the user message; do not touch any other target.
|
|
203
|
+
|
|
204
|
+
${DIRECT_MEMORY_OPERATIONS_SCHEMA}`;
|
|
205
|
+
|
|
206
|
+
// ─── Direct (in-process) correction-save prompt — used by correction-detector.ts. ───
|
|
207
|
+
export const DIRECT_CORRECTION_SYSTEM_PROMPT = `The user just corrected the agent. Review what went wrong and decide what durable memory to save.
|
|
208
|
+
|
|
209
|
+
Priority:
|
|
210
|
+
1. User preference ("don't do X", "always use Y instead")
|
|
211
|
+
2. Wrong assumption the agent made
|
|
212
|
+
3. Environment fact the agent got wrong
|
|
213
|
+
|
|
214
|
+
If this contradicts an existing entry, use a "replace" operation to update it instead of "add".
|
|
215
|
+
|
|
216
|
+
${DIRECT_MEMORY_OPERATIONS_SCHEMA}
|
|
217
|
+
|
|
218
|
+
If nothing is worth saving beyond the automatic failure-memory capture, return {"operations":[]}.`;
|
|
219
|
+
|
|
178
220
|
// ─── Flush prompt (ported from flush_memories() in run_agent.py ~L7379) ───
|
|
179
221
|
export const FLUSH_PROMPT = `[System: The session is being compressed. Save anything worth remembering — prioritize user preferences, corrections, and recurring patterns over task-specific details.]`;
|
|
180
222
|
|