pi-hermes-memory 0.1.0 → 0.2.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/docs/ROADMAP.md CHANGED
@@ -14,122 +14,204 @@
14
14
  - 119 automated tests, 0 type errors
15
15
  - Atomic writes (temp + rename)
16
16
 
17
- ## Architecture Evolution
17
+ ---
18
18
 
19
- ```mermaid
20
- graph TB
21
- subgraph "v0.1.0 — Current"
22
- T1["memory tool<br/>(add / replace / remove)"]
23
- SC["Content Scanner<br/>(injection · exfiltration · unicode)"]
24
- MD["Markdown Backend<br/>MEMORY.md · USER.md"]
25
- FS["Frozen Snapshot<br/>(system prompt injection)"]
26
- BL["Background Review<br/>(pi.exec child process)"]
27
- SF["Session Flush<br/>(compact · shutdown)"]
28
- IC["/memory-insights<br/>(command)"]
29
- CF["Config File<br/>(hermes-memory-config.json)"]
30
- end
19
+ ## Hermes Agent Competitive Analysis
31
20
 
32
- T1 --> SC --> MD
33
- BL --> MD
34
- SF --> MD
35
- MD --> FS
36
-
37
- style T1 fill:#e94560,stroke:#fff,color:#fff
38
- style SC fill:#ff6600,stroke:#fff,color:#fff
39
- style MD fill:#0f3460,stroke:#fff,color:#fff
40
- style FS fill:#16213e,stroke:#fff,color:#fff
41
- style BL fill:#16213e,stroke:#fff,color:#fff
42
- style SF fill:#16213e,stroke:#fff,color:#fff
43
- style IC fill:#16213e,stroke:#fff,color:#fff
44
- style CF fill:#16213e,stroke:#fff,color:#fff
45
- ```
21
+ > Research conducted 2026-04-26. Sources: [hermes-agent.ai](https://hermes-agent.ai/blog/hermes-agent-memory-system), [GitHub README](https://github.com/NousResearch/Hermes-Agent), [official docs](https://hermes-agent.nousresearch.com/docs/user-guide/features/memory), [skills docs](https://hermes-agent.nousresearch.com/docs/user-guide/features/skills).
22
+
23
+ ### Hermes 3-Layer Memory Architecture
24
+
25
+ Hermes has three memory subsystems operating at different timescales:
26
+
27
+ | Layer | What | Capacity | Token Cost |
28
+ |---|---|---|---|
29
+ | **L1: Persistent Memory** (MEMORY.md + USER.md) | Curated facts, frozen snapshot injection | ~1,300 tokens total | Fixed per session |
30
+ | **L2: Episodic Memory** (Skills System) | Procedural memory — SKILL.md files created from experience, progressive disclosure | Unlimited | ~3K tokens for index, full content on demand |
31
+ | **L3: Session Search** (SQLite FTS5) | Full-text search over ALL conversations | Unlimited | On-demand only |
32
+
33
+ Plus **L4: External Providers** — Honcho, Mem0, Hindsight, etc. for deeper user modeling.
34
+
35
+ ### Gap Analysis: Hermes vs. Our v0.1
36
+
37
+ | Capability | Hermes | Our v0.1 | Priority |
38
+ |---|---|---|---|
39
+ | L1: Persistent Memory (MEMORY.md + USER.md) | ✅ | ✅ **Covered** | — |
40
+ | Frozen snapshot + prefix cache preservation | ✅ | ✅ **Covered** | — |
41
+ | Content scanning (injection, exfil, unicode) | ✅ | ✅ **Covered** | — |
42
+ | Background learning loop (periodic nudge) | ✅ | ✅ **Covered** | — |
43
+ | Session flush (compact + shutdown) | ✅ | ✅ **Covered** | — |
44
+ | **L2: Skills / Procedural Memory** | ✅ Auto-created after complex tasks, progressive disclosure, SKILL.md format | ❌ **MISSING** — our COMBINED_REVIEW_PROMPT already asks about skills but there's no skill tool | 🔴 **Critical** |
45
+ | **L3: Session Search** | ✅ SQLite FTS5 over all conversations, on-demand retrieval + summarization | ❌ **MISSING** — no cross-session recall at all | 🔴 **Critical** |
46
+ | **Auto-consolidation when memory full** | ✅ Agent merges/removes entries automatically | ❌ Returns error "Replace or remove existing entries" | 🟡 **High** |
47
+ | **Correction-triggered memory save** | ✅ Detects user corrections for immediate save | ❌ Only saves on nudge interval (every 10 turns) | 🟡 **High** |
48
+ | **Tool-call-aware nudge** | ✅ Self-evaluation every 15 tool calls | ❌ Only turn-count based | 🟡 **Medium** |
49
+ | **Progressive disclosure** | ✅ 3-level loading (index → full → references) | ❌ Not applicable (no skills yet) | 🟡 **Depends on Skills** |
50
+ | **Memory aging / staleness tracking** | ✅ Consolidation removes superseded entries | ❌ Entries live forever until manually removed | 🟠 **Medium** |
51
+ | **Context fencing** (memory-context XML tags) | ✅ Prevents prompt injection through stored memories | ❌ Raw injection | 🟠 **Medium** |
52
+ | **External providers** (Honcho, Mem0, etc.) | ✅ 8+ external provider plugins | ⏳ Planned for v0.4 | 🟢 **Deferred** |
53
+ | **Skills Hub / Community skills** | ✅ agentskills.io, search, install, audit | ❌ Not applicable (Pi has its own skill system) | ⚪ **N/A** |
54
+ | **Cross-platform messaging** | ✅ Telegram, Discord, Slack, WhatsApp, Signal | ❌ Not applicable (Pi extension, not standalone agent) | ⚪ **N/A** |
55
+
56
+ ### Key Painpoints Hermes Solves That We Must Address
57
+
58
+ 1. **"Goldfish memory"** — Every session starts from zero, user re-explains preferences, stack, conventions. Our L1 solves this. ✅
59
+
60
+ 2. **No procedural knowledge** — The agent forgets *how* it solved problems. After 60+ sessions, Hermes shows "anticipatory behavior" because it has skill documents from past experience. Our review prompt asks about skills but has nowhere to save them. 🔴
61
+
62
+ 3. **No cross-session recall** — "Did we discuss X last week?" is unanswerable. Hermes searches all past conversations via FTS5. We have zero session search. 🔴
63
+
64
+ 4. **Memory full = dead end** — When our memory hits capacity, we return an error and force the user/agent to manually fix it. Hermes auto-consolidates. 🟡
65
+
66
+ 5. **Missed corrections** — User says "no, don't do that" and the agent only saves it 8 turns later at the next nudge. Hermes detects corrections immediately. 🟡
67
+
68
+ ---
69
+
70
+ ## Revised Roadmap
71
+
72
+ The roadmap is restructured based on the Hermes gap analysis. The biggest missing pieces are **Skills/Procedural Memory** and **Smart Curation** (auto-consolidation, correction detection). Session Search and External Providers stay in later phases.
46
73
 
47
74
  ```mermaid
48
- graph TB
49
- subgraph "v0.2.0 — Structured Storage & Search"
50
- T2["memory tool<br/>(add / replace / remove / search)"]
51
- SC2["Content Scanner<br/>(v0.1.0 scanner unchanged)"]
52
- SA["Search Abstraction<br/>(MemoryBackend interface)"]
53
- SQL["SQLite Backend<br/>(FTS5 · key-value · confidence)"]
54
- PI2["Context-Aware Injection<br/>(relevance-filtered)"]
55
- PS["Project-Scoped Memory<br/>(keyed by cwd)"]
75
+ graph LR
76
+ subgraph "v0.1 "
77
+ A[L1: Persistent Memory]
78
+ B[Content Scanner]
79
+ C[Background Review]
80
+ D[Session Flush]
56
81
  end
57
82
 
58
- T2 --> SC2 --> SA
59
- SA --> SQL
60
- SQL --> PI2
61
- SQL --> PS
62
-
63
- style T2 fill:#e94560,stroke:#fff,color:#fff
64
- style SC2 fill:#ff6600,stroke:#fff,color:#fff
65
- style SA fill:#1282a2,stroke:#fff,color:#fff
66
- style SQL fill:#0f3460,stroke:#fff,color:#fff
67
- style PI2 fill:#16213e,stroke:#fff,color:#fff
68
- style PS fill:#16213e,stroke:#fff,color:#fff
69
- ```
83
+ subgraph "v0.2 Next"
84
+ E[Skill Tool]
85
+ F[Auto-Consolidation]
86
+ G[Correction Detection]
87
+ H[Tool-Call-Aware Nudge]
88
+ end
70
89
 
71
- ```mermaid
72
- graph TB
73
- subgraph "v0.3.0 — Pluggable Backend & External Memory"
74
- T3["memory tool<br/>(add / replace / remove / search)"]
75
- SC3["Content Scanner<br/>(unchanged — guards all backends)"]
76
- SA3["Search Abstraction<br/>(MemoryBackend interface)"]
77
- LOC["Local SQLite<br/>(default · offline)"]
78
- M0["Mem0 Backend<br/>(vector search · cloud)"]
79
- HON["Honcho Backend<br/>(dialectic reasoning · Hermes-native)"]
80
- SEL["Selective Injection<br/>(search-relevant · project-scoped)"]
90
+ subgraph "v0.3"
91
+ I[Session Search]
92
+ J[Context Fencing]
93
+ K[Memory Aging]
81
94
  end
82
95
 
83
- T3 --> SC3 --> SA3
84
- SA3 --> LOC
85
- SA3 --> M0
86
- SA3 --> HON
87
- LOC --> SEL
88
- M0 --> SEL
89
- HON --> SEL
90
-
91
- style T3 fill:#e94560,stroke:#fff,color:#fff
92
- style SC3 fill:#ff6600,stroke:#fff,color:#fff
93
- style SA3 fill:#1282a2,stroke:#fff,color:#fff
94
- style LOC fill:#0f3460,stroke:#fff,color:#fff
95
- style M0 fill:#6b21a8,stroke:#fff,color:#fff
96
- style HON fill:#6b21a8,stroke:#fff,color:#fff
97
- style SEL fill:#16213e,stroke:#fff,color:#fff
98
- ```
96
+ subgraph "v0.4"
97
+ L[MemoryBackend Interface]
98
+ M[SQLite Backend]
99
+ N[Project-Scoped Memory]
100
+ end
99
101
 
100
- ```mermaid
101
- graph TB
102
- subgraph "v1.0.0 — Production Memory Substrate"
103
- T4["memory tool<br/>(add / replace / remove / search / consolidate)"]
104
- SC4["Content Scanner<br/>(extensible rule system)"]
105
- SA4["Pluggable Backend<br/>(local · Mem0 · Honcho · custom)"]
106
- CON["Smart Consolidation<br/>(structured extraction · dedup)"]
107
- MUL["Multi-Agent Memory<br/>(shared context · scoping)"]
108
- OBS["Observability<br/>(memory stats · usage · audit log)"]
102
+ subgraph "v0.5"
103
+ O[ExternalSync Interface]
104
+ P[Mem0 / Honcho]
109
105
  end
110
106
 
111
- T4 --> SC4 --> SA4
112
- SA4 --> CON
113
- SA4 --> MUL
114
- CON --> OBS
115
-
116
- style T4 fill:#e94560,stroke:#fff,color:#fff
117
- style SC4 fill:#ff6600,stroke:#fff,color:#fff
118
- style SA4 fill:#1282a2,stroke:#fff,color:#fff
119
- style CON fill:#16213e,stroke:#fff,color:#fff
120
- style MUL fill:#16213e,stroke:#fff,color:#fff
121
- style OBS fill:#16213e,stroke:#fff,color:#fff
107
+ A --> E
108
+ C --> F
109
+ C --> G
110
+ C --> H
111
+ E --> I
112
+ F --> K
113
+ A --> J
114
+ K --> L
115
+ I --> N
116
+ L --> O
117
+ O --> P
122
118
  ```
123
119
 
124
120
  ---
125
121
 
126
- ## v0.2.0 — Structured Storage & Search
122
+ ## v0.2.0 — Skills + Smart Curation
123
+
124
+ **Goal**: Close the two biggest gaps from the Hermes analysis — procedural memory (skills) and intelligent memory management (auto-consolidation, correction detection, tool-call-aware nudges).
125
+
126
+ **Why this before SQLite/Session Search**: Our `COMBINED_REVIEW_PROMPT` already asks the agent to save skills — but there's no skill tool. The review prompt is literally asking the agent to do something it can't do. Fixing this is the single highest-leverage change. Auto-consolidation and correction detection are small, high-impact additions to the existing curation system.
127
+
128
+ ### Epic 1: Skill Tool + Procedural Memory
129
+
130
+ Hermes creates skills after complex tasks (5+ tool calls). Skills are SKILL.md files in `~/.hermes/skills/` with progressive disclosure. We adapt this for Pi's existing skill infrastructure at `~/.pi/agent/skills/`.
131
+
132
+ **Key insight**: Pi already has a skill system. Our skill tool should write SKILL.md files that are compatible with Pi's skill discovery. This means our skills are immediately usable as Pi slash commands — no separate ecosystem needed.
133
+
134
+ - [ ] `skill` tool — register via `pi.registerTool()` with actions: `create`, `patch`, `edit`, `delete`
135
+ - [ ] Skill storage in `~/.pi/agent/memory/skills/` (not `~/.pi/agent/skills/` — avoid conflicting with user's own skills)
136
+ - [ ] SKILL.md format — compatible with Pi's SKILL.md spec (frontmatter + markdown body)
137
+ - [ ] Progressive disclosure — skill index (name + description only) injected into system prompt, full content loaded on demand via `skill_view` action
138
+ - [ ] Auto-trigger after complex tasks — track tool calls per turn, trigger skill extraction at 5+ tool calls
139
+ - [ ] Background skill review — extend `COMBINED_REVIEW_PROMPT` to actually call the `skill` tool (currently it asks about skills but can't save them)
140
+ - [ ] Security — skill writes go through the same content scanner as memory writes
141
+ - [ ] `/memory-skills` command — list all agent-created skills with usage stats
142
+
143
+ **Reference**: Hermes `skill_manage` tool and `~/.hermes/skills/` directory structure. See [Hermes Skills docs](https://hermes-agent.nousresearch.com/docs/user-guide/features/skills).
144
+
145
+ ### Epic 2: Auto-Consolidation
146
+
147
+ When Hermes memory hits capacity, it automatically merges related entries and removes superseded ones. Our extension currently returns an error. This fixes the "memory full" dead end.
148
+
149
+ - [ ] When `add()` would exceed char limit, trigger auto-consolidation instead of returning error
150
+ - [ ] Consolidation via `pi.exec()` — spawn a one-shot process with a consolidation prompt
151
+ - [ ] Consolidation prompt — "Memory is at capacity. Merge related entries, remove outdated ones, keep the most important facts. Use the memory tool to make changes."
152
+ - [ ] After consolidation, retry the original `add()`
153
+ - [ ] Config: `autoConsolidate: boolean` (default: true)
154
+ - [ ] `/memory-consolidate` command — manual consolidation trigger
155
+
156
+ **Reference**: Hermes memory compression behavior described in [hermes-agent.ai memory blog](https://hermes-agent.ai/blog/hermes-agent-memory-system).
157
+
158
+ ### Epic 3: Correction Detection + Immediate Save
159
+
160
+ Hermes detects user corrections and saves them immediately. Our extension only saves on the nudge interval (every 10 turns). User corrections are the most valuable memories — every missed correction is a repeated mistake.
161
+
162
+ - [ ] Correction detector — scan user messages for patterns: "no,", "wrong,", "actually,", "don't do that", "stop", "not like that", "I said..."
163
+ - [ ] On detection, trigger an immediate memory save prompt via `pi.exec()`
164
+ - [ ] Config: `correctionDetection: boolean` (default: true)
165
+ - [ ] Rate limit — max 1 correction save per 3 turns (avoid over-triggering on multi-turn corrections)
127
166
 
128
- **Goal**: Replace flat markdown with SQLite. Add search. Keep the same tool interface.
167
+ **Reference**: Hermes correction patterns inferred from the `MEMORY_TOOL_DESCRIPTION` priority list: "User preferences and corrections > environment facts > procedural knowledge."
129
168
 
130
- ### `MemoryBackend` Interface
169
+ ### Epic 4: Tool-Call-Aware Nudge
131
170
 
132
- The core abstraction that makes everything after this possible:
171
+ Hermes runs a self-evaluation checkpoint every 15 tool calls. Our nudge is purely turn-count based. Complex tasks with many tool calls generate more valuable memories than simple conversations.
172
+
173
+ - [ ] Track tool call count per turn (via `tool_end` event or similar)
174
+ - [ ] Trigger background review when EITHER `nudgeInterval` turns OR `nudgeToolCalls` (default: 15) tool calls are reached
175
+ - [ ] Weight the review prompt based on complexity — more tool calls = deeper review
176
+ - [ ] Config: `nudgeToolCalls: number` (default: 15)
177
+
178
+ **Reference**: Hermes self-evaluation checkpoint described in [hermes-agent.ai skills blog](https://hermes-agent.ai/blog/hermes-agent-memory-system): "Every 15 tool calls, Hermes runs a self-evaluation checkpoint."
179
+
180
+ ---
181
+
182
+ ## v0.3.0 — Session Search + Context Hardening
183
+
184
+ **Goal**: Add cross-session recall (Hermes L3) and security hardening via context fencing.
185
+
186
+ ### Epic 5: Session Search
187
+
188
+ Hermes stores all conversations in SQLite with FTS5 full-text search. When it needs past context, it searches + summarizes. This transforms the extension from "2 files of notes" to "infinite searchable memory."
189
+
190
+ - [ ] Investigate Pi's `SessionManager` API for reading past session history
191
+ - [ ] Session indexer — index past and current session conversations for full-text search
192
+ - [ ] Storage: either a separate SQLite file (`~/.pi/agent/memory/sessions.db`) or leverage Pi's built-in session storage
193
+ - [ ] `session_search` tool — agent can query past conversations on demand
194
+ - [ ] Summarization via `pi.exec()` — summarize relevant session fragments to keep token cost manageable
195
+ - [ ] Config: `sessionSearchEnabled: boolean` (default: true)
196
+ - [ ] Config: `sessionRetentionDays: number` (default: 90)
197
+
198
+ **Reference**: Hermes `~/.hermes/state.db` with FTS5 indexing. See [Hermes Session Search docs](https://hermes-agent.nousresearch.com/docs/user-guide/features/memory#session-search).
199
+
200
+ ### Epic 6: Context Fencing + Memory Aging
201
+
202
+ - [ ] `<memory-context>` XML tags wrapping the system prompt injection — prevents the model from treating recalled memory as user discourse
203
+ - [ ] Memory aging — track last-referenced timestamp per entry, surface stale entries during consolidation
204
+ - [ ] Entry metadata — add optional `last_referenced` and `created_at` fields (stored in comments, transparent to § delimiter)
205
+
206
+ **Reference**: Hermes `MemoryManager.build_memory_context_block()` fencing with `<memory-context>` tags and "NOT new user input" system note.
207
+
208
+ ---
209
+
210
+ ## v0.4.0 — Structured Storage + Project Scoping
211
+
212
+ **Goal**: Replace flat markdown with SQLite backend. Add search. Add project-scoped memory. Keep the same tool interface.
213
+
214
+ ### Core Abstraction
133
215
 
134
216
  ```typescript
135
217
  interface MemoryBackend {
@@ -150,6 +232,18 @@ interface MemoryBackend {
150
232
 
151
233
  Current `MemoryStore` becomes `MarkdownBackend` — the default, zero-dependency implementation. New `SQLiteBackend` adds structure without breaking anything.
152
234
 
235
+ ### Onboarding: `/memory-interview`
236
+
237
+ New users install the extension and memory starts empty — the LLM has to learn preferences over many sessions through trial and error. The interview command solves this:
238
+
239
+ ```
240
+ /memory-interview
241
+ ```
242
+
243
+ The LLM asks 5-7 structured questions. Each answer is saved to `USER.md` via the existing content scanner. Users get immediate value on the very first session.
244
+
245
+ Inspired by [Honcho's `/honcho:interview`](https://docs.honcho.dev/v3/guides/integrations/claude-code#the-interview) pattern.
246
+
153
247
  ### Deliverables
154
248
 
155
249
  - [ ] `MemoryBackend` interface in `src/types.ts`
@@ -159,7 +253,10 @@ Current `MemoryStore` becomes `MarkdownBackend` — the default, zero-dependency
159
253
  - [ ] Project-scoped memory — entries tagged with `cwd`, injected when matching
160
254
  - [ ] Context-aware injection — `formatForSystemPrompt(cwd, prompt)` filters by relevance
161
255
  - [ ] Config: `"backend": "markdown" | "sqlite"` (defaults to `markdown` for zero-dep install)
162
- - [ ] Migration tool: `markdown → sqlite` one-time import
256
+ - [ ] Migration tool: markdown → sqlite one-time import
257
+ - [ ] `/memory-interview` command — guided first-run interview that saves preferences to USER.md
258
+ - [ ] Interview prompt in `src/constants.ts` — structured questions with save instructions
259
+ - [ ] Content scanner validates interview answers (same as all writes)
163
260
 
164
261
  ### What Does NOT Change
165
262
 
@@ -170,38 +267,45 @@ Current `MemoryStore` becomes `MarkdownBackend` — the default, zero-dependency
170
267
 
171
268
  ---
172
269
 
173
- ## v0.3.0 — Pluggable External Memory
270
+ ## v0.5.0 — External Sync
174
271
 
175
- **Goal**: Let users swap the backend to Mem0 or Honcho without changing anything else. The content scanner guards all data before it leaves the machine.
272
+ **Goal**: Run a local backend (SQLite) as the source of truth, with optional external sync (Mem0 or Honcho) that mirrors writes and supplements search. Based on the [Hermes MemoryManager pattern](https://github.com/NousResearch/hermes-agent/blob/main/agent/memory_manager.py).
176
273
 
177
- ### Why This Matters
178
-
179
- External memory services provide better semantic search, cross-session continuity, and multi-agent awareness. But they introduce trust boundaries — your agent's memories leave your machine. The content scanner becomes the security gate between Pi and any external service.
180
-
181
- ### Deliverables
182
-
183
- - [ ] `Mem0Backend` — wraps Mem0's Node.js SDK (`add`, `search`, `update`, `delete`)
184
- - [ ] `HonchoBackend` — wraps Honcho's API (`honcho_context`, `honcho_search_conclusions`, `honcho_reasoning`)
185
- - [ ] Backend auto-detection — check for `MEM0_API_KEY` or `HONCHO_API_KEY` env vars, offer to configure
186
- - [ ] Config: `"backend": "sqlite" | "mem0" | "honcho"` with `"mem0": { "apiKey": "...", "orgId": "..." }` options
187
- - [ ] Selective injection by default when using external backends (leverage their search APIs)
188
- - [ ] Offline fallback — if external backend is unreachable, fall back to local SQLite cache
189
- - [ ] Data export — `memory export` command to dump all entries as JSON
190
-
191
- ### Security Model
274
+ ### Architecture: Orchestrator + Sync Mirror
192
275
 
193
276
  ```
194
- LLM tool call
277
+ memory tool call (add/replace/remove/search)
195
278
 
196
- Content Scanner (local, always runs first)
279
+ Content Scanner (always runs first, local)
197
280
  ↓ blocked? → return error to LLM
198
281
  ↓ passed
199
- MemoryBackend.add()
282
+ MemoryOrchestrator.write()
283
+
284
+ ├── BuiltinBackend.add() ← always runs (source of truth)
285
+
286
+ └── ExternalSync.onWrite() ← if configured (Mem0 or Honcho)
287
+ ├── Mirror the write to external API
288
+ └── If external fails → log warning, don't block
289
+
290
+ MemoryOrchestrator.search()
200
291
 
201
- Mem0 / Honcho / SQLite / Markdown
292
+ ├── BuiltinBackend.search() ← always runs
293
+ └── ExternalSync.search() ← supplementary results (if configured)
294
+
295
+ Merge + deduplicate → return to LLM
202
296
  ```
203
297
 
204
- The scanner runs **before** any backend. No adversarial content reaches external services.
298
+ ### Deliverables
299
+
300
+ - [ ] `MemoryOrchestrator` — wraps `MemoryBackend` + optional `ExternalSync`
301
+ - [ ] `ExternalSync` interface in `src/types.ts`
302
+ - [ ] `Mem0Sync` — implements `ExternalSync` using Mem0 Node.js SDK
303
+ - [ ] `HonchoSync` — implements `ExternalSync` using Honcho API
304
+ - [ ] `onWrite()` mirroring — builtin writes propagate to external sync
305
+ - [ ] One-external-only enforcement — same as Hermes, prevents conflicts
306
+ - [ ] Offline fallback — if external sync `isAvailable()` returns false, skip silently
307
+ - [ ] Config: `"externalSync": "mem0" | "honcho" | "none"` with credentials
308
+ - [ ] Data export — `memory export` command to dump all entries as JSON
205
309
 
206
310
  ---
207
311
 
@@ -216,7 +320,7 @@ The scanner runs **before** any backend. No adversarial content reaches external
216
320
  - [ ] Multi-agent memory — shared context between agents, scoping rules (per-user, per-project, global)
217
321
  - [ ] Extensible scanner rules — users can add custom patterns to the content scanner
218
322
  - [ ] `/memory-insights` upgrade — show backend type, entry count, storage stats, last sync time
219
- - [ ] Audit log — track all memory operations with timestamps (already in SQLite schema for `SQLiteBackend`)
323
+ - [ ] Audit log — track all memory operations with timestamps
220
324
  - [ ] Import/export — migrate between backends without data loss
221
325
  - [ ] Benchmarks — context injection latency, search relevance, token budget utilization
222
326
 
@@ -232,6 +336,7 @@ These hold across all versions:
232
336
  4. **Crash safety** — Atomic writes for markdown, WAL mode for SQLite, graceful degradation for external backends.
233
337
  5. **Zero-config start** — Install and it works with sensible defaults. Configuration is for power users.
234
338
  6. **Backwards compatible** — Every new version is a drop-in upgrade. No breaking changes to the tool interface or config format without a major version bump.
339
+ 7. **Hermes-compatible data format** — `§` delimiter, MEMORY.md/USER.md structure, so users migrating from Hermes keep their data.
235
340
 
236
341
  ---
237
342
 
@@ -243,30 +348,35 @@ gantt
243
348
  dateFormat YYYY-MM-DD
244
349
  axisFormat %b %Y
245
350
 
246
- section v0.1.0
247
- Core memory + scanner + tool + review + flush :done, v01, 2025-04-20, 5d
351
+ section v0.1.0
352
+ Core memory + scanner + tool + review + flush :done, v01, 2026-04-20, 5d
248
353
 
249
- section v0.2.0
250
- MemoryBackend interface :v02a, after v01, 7d
251
- SQLite backend + FTS5 search :v02b, after v02a, 7d
252
- memory search tool + project scoping :v02c, after v02b, 5d
253
- Context-aware injection :v02d, after v02c, 5d
354
+ section v0.2.0 — Next
355
+ Skill tool + procedural memory :v02a, after v01, 5d
356
+ Auto-consolidation :v02b, after v02a, 3d
357
+ Correction detection + immediate save :v02c, after v02b, 3d
358
+ Tool-call-aware nudge :v02d, after v02c, 2d
254
359
 
255
360
  section v0.3.0
256
- Mem0 backend :v03a, after v02d, 7d
257
- Honcho backend :v03b, after v03a, 7d
258
- Offline fallback + data export :v03c, after v03b, 5d
361
+ Session search + indexer :v03a, after v02d, 7d
362
+ Context fencing + memory aging :v03b, after v03a, 3d
363
+
364
+ section v0.4.0
365
+ MemoryBackend interface + SQLite :v04a, after v03b, 7d
366
+ Project-scoped memory + interview :v04b, after v04a, 5d
367
+
368
+ section v0.5.0
369
+ ExternalSync + Mem0 / Honcho :v05a, after v04b, 10d
259
370
 
260
371
  section v1.0.0
261
- Smart consolidation + confidence :v1a, after v03c, 10d
372
+ Smart consolidation + confidence :v1a, after v05a, 10d
262
373
  Multi-agent memory + audit log :v1b, after v1a, 10d
263
- Extensible scanner + benchmarks :v1c, after v1b, 7d
264
374
  ```
265
375
 
266
376
  ---
267
377
 
268
378
  ## How to Contribute
269
379
 
270
- See [TASKS.md](0.1/TASKS.md) for current work. Pick an unchecked item, mark it `[~]`, implement, mark it `[x]` with the commit hash.
380
+ See [TASKS.md](0.1/TASKS.md) for current v0.1 work. Pick an unchecked item, mark it `[~]`, implement, mark it `[x]` with the commit hash.
271
381
 
272
- For roadmap items, open an issue with the version tag (e.g. `v0.2.0`) and describe what you want to work on.
382
+ For v0.2+ items, see [v0.2/TASKS.md](0.2/TASKS.md) once created. Open an issue with the version tag and describe what you want to work on.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-hermes-memory",
3
- "version": "0.1.0",
4
- "description": "Persistent memory and self-directed learning loop for Pi ported from the Hermes agent harness. Security-first content scanning, real-time saves, and frozen snapshot injection.",
3
+ "version": "0.2.0",
4
+ "description": "Your Pi agent remembers everything across sessionsyour preferences, your stack, your corrections, and even how it solved problems. Zero-config install, works immediately. Persistent memory + procedural skills + auto-correction detection + security-first content scanning.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "files": [
@@ -23,11 +23,14 @@
23
23
  "pi-package",
24
24
  "pi-extension",
25
25
  "memory",
26
+ "skills",
26
27
  "learning-loop",
27
28
  "agent",
28
29
  "hermes",
29
30
  "persistent-memory",
30
- "content-scanner"
31
+ "content-scanner",
32
+ "correction-detection",
33
+ "auto-consolidation"
31
34
  ],
32
35
  "license": "MIT",
33
36
  "repository": {
package/src/config.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  DEFAULT_USER_CHAR_LIMIT,
8
8
  DEFAULT_NUDGE_INTERVAL,
9
9
  DEFAULT_FLUSH_MIN_TURNS,
10
+ DEFAULT_NUDGE_TOOL_CALLS,
10
11
  } from "./constants.js";
11
12
 
12
13
  const DEFAULT_CONFIG: MemoryConfig = {
@@ -17,6 +18,9 @@ const DEFAULT_CONFIG: MemoryConfig = {
17
18
  flushOnCompact: true,
18
19
  flushOnShutdown: true,
19
20
  flushMinTurns: DEFAULT_FLUSH_MIN_TURNS,
21
+ autoConsolidate: true,
22
+ correctionDetection: true,
23
+ nudgeToolCalls: DEFAULT_NUDGE_TOOL_CALLS,
20
24
  };
21
25
 
22
26
  export const DEFAULT_CONFIG_PATH = path.join(
@@ -40,6 +44,9 @@ export function loadConfig(): MemoryConfig {
40
44
  if (typeof parsed.flushOnCompact === "boolean") config.flushOnCompact = parsed.flushOnCompact;
41
45
  if (typeof parsed.flushOnShutdown === "boolean") config.flushOnShutdown = parsed.flushOnShutdown;
42
46
  if (typeof parsed.flushMinTurns === "number") config.flushMinTurns = parsed.flushMinTurns;
47
+ if (typeof parsed.autoConsolidate === "boolean") config.autoConsolidate = parsed.autoConsolidate;
48
+ if (typeof parsed.correctionDetection === "boolean") config.correctionDetection = parsed.correctionDetection;
49
+ if (typeof parsed.nudgeToolCalls === "number") config.nudgeToolCalls = parsed.nudgeToolCalls;
43
50
  return config;
44
51
  }
45
52
  } catch {
package/src/constants.ts CHANGED
@@ -14,6 +14,8 @@ export const DEFAULT_USER_CHAR_LIMIT = 1375;
14
14
  // ─── Learning loop defaults ───
15
15
  export const DEFAULT_NUDGE_INTERVAL = 10;
16
16
  export const DEFAULT_FLUSH_MIN_TURNS = 6;
17
+ export const DEFAULT_NUDGE_TOOL_CALLS = 15;
18
+ export const DEFAULT_SKILL_TRIGGER_TOOL_CALLS = 8;
17
19
 
18
20
  // ─── File names ───
19
21
  export const MEMORY_FILE = "MEMORY.md";
@@ -44,9 +46,79 @@ export const COMBINED_REVIEW_PROMPT = `Review the conversation above and conside
44
46
 
45
47
  **Memory**: Has the user revealed things about themselves — their persona, desires, preferences, or personal details? Has the user expressed expectations about how you should behave, their work style, or ways they want you to operate? If so, save using the memory tool.
46
48
 
47
- **Skills**: Was a non-trivial approach used to complete a task that required trial and error, or changing course due to experiential findings along the way, or did the user expect or desire a different method or outcome?
49
+ **Skills**: Was a complex, non-trivial approach used to complete a task — one that required trial and error, multiple tool calls, or changing course? If so, save a reusable procedure using the skill tool with action 'create'. Include: when to use it, step-by-step procedure, pitfalls to avoid, and how to verify success. If a related skill already exists, use action 'patch' to update it instead of creating a duplicate.
48
50
 
49
51
  Only act if there's something genuinely worth saving. If nothing stands out, just say 'Nothing to save.' and stop.`;
50
52
 
51
53
  // ─── Flush prompt (ported from flush_memories() in run_agent.py ~L7379) ───
52
54
  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.]`;
55
+
56
+ // ─── Auto-consolidation prompt ───
57
+ export const CONSOLIDATION_PROMPT = `The memory is at capacity. Review the current entries and consolidate them:
58
+ - Merge related entries into a single, concise entry
59
+ - Remove outdated or superseded entries
60
+ - Keep the most important and frequently-referenced facts
61
+ - Preserve user preferences and corrections (highest priority)
62
+
63
+ Use the memory tool to make changes. Be aggressive about merging — less is more.`;
64
+
65
+ // ─── Correction detection patterns (two-pass filter) ───
66
+
67
+ /** Strong patterns — always trigger (high confidence these are corrections) */
68
+ export const CORRECTION_STRONG_PATTERNS: RegExp[] = [
69
+ /don'?t do that/i,
70
+ /not like that/i,
71
+ /^I said\b/i,
72
+ /^I told you\b/i,
73
+ /we already discussed/i,
74
+ /^please don'?t/i,
75
+ /^that'?s not what I/i,
76
+ ];
77
+
78
+ /** Weak patterns — only trigger if followed by a directive (verb or "the/that/this") */
79
+ export const CORRECTION_WEAK_PATTERNS: RegExp[] = [
80
+ /^no[,\.\s!]/i,
81
+ /^wrong[,\.\s!]/i,
82
+ /^actually[,\.\s]/i,
83
+ /^stop[,\.\s!]/i,
84
+ ];
85
+
86
+ /** Negative patterns — suppress trigger even if a positive pattern matches */
87
+ export const CORRECTION_NEGATIVE_PATTERNS: RegExp[] = [
88
+ /^no worries/i,
89
+ /^no problem/i,
90
+ /^no thanks/i,
91
+ /^no need/i,
92
+ /^actually.{0,10}(looks? great|perfect|good|correct|right)/i,
93
+ /^stop.{0,5}(there|here|for now)/i,
94
+ ];
95
+
96
+ // ─── Correction save prompt ───
97
+ export const CORRECTION_SAVE_PROMPT = `The user just corrected you. Review what went wrong and save the correction to persistent memory.
98
+
99
+ Priority:
100
+ 1. User preference ("don't do X", "always use Y instead")
101
+ 2. Wrong assumption you made
102
+ 3. Environment fact you got wrong
103
+
104
+ Use the memory tool to save. If this contradicts an existing entry, use 'replace' to update it.`;
105
+
106
+ // ─── Skill tool description ───
107
+ export const SKILL_TOOL_DESCRIPTION = `Save reusable procedures and patterns as skills that survive across sessions. Skills are procedural memory — they capture HOW to do something, not just what happened.
108
+
109
+ WHEN TO CREATE A SKILL:
110
+ - After completing a complex task that required trial and error or multiple tool calls
111
+ - When you discover a non-obvious approach that could be reused
112
+ - When the user teaches you a specific workflow or procedure
113
+
114
+ WHEN TO UPDATE A SKILL (use 'patch'):
115
+ - You discover a better approach for an existing skill
116
+ - A pitfall or edge case not covered by the skill
117
+ - A step in the procedure changed
118
+
119
+ SKILL FORMAT:
120
+ - name: short, descriptive (e.g., "debug-typescript-errors")
121
+ - description: one-line summary of when to use it
122
+ - body: structured with sections — ## When to Use, ## Procedure, ## Pitfalls, ## Verification
123
+
124
+ ACTIONS: create (new skill), view (read full content), patch (update a section), edit (replace description + body), delete (remove skill).`;