pi-observational-memory 2.4.3 → 3.0.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 +312 -103
- package/package.json +9 -9
- package/src/agents/dropper/agent.ts +152 -0
- package/src/agents/dropper/pool.ts +67 -0
- package/src/agents/dropper/prompts.ts +43 -0
- package/src/{observer.ts → agents/observer/agent.ts} +11 -13
- package/src/agents/observer/prompts.ts +119 -0
- package/src/agents/reflector/agent.ts +134 -0
- package/src/agents/reflector/prompts.ts +77 -0
- package/src/clipboard.ts +63 -0
- package/src/commands/status.ts +79 -78
- package/src/commands/view.ts +58 -66
- package/src/config.ts +78 -55
- package/src/debug-log.ts +1 -5
- package/src/hooks/compaction-hook.ts +24 -369
- package/src/hooks/compaction-trigger.ts +12 -21
- package/src/hooks/consolidation-trigger.ts +331 -0
- package/src/index.ts +3 -3
- package/src/model-budget.ts +1 -1
- package/src/runtime.ts +46 -19
- package/src/serialize.ts +1 -1
- package/src/session-ledger/fold.ts +100 -0
- package/src/session-ledger/index.ts +6 -0
- package/src/session-ledger/progress.ts +129 -0
- package/src/session-ledger/projection.ts +220 -0
- package/src/session-ledger/recall.ts +237 -0
- package/src/session-ledger/render-summary.ts +31 -0
- package/src/session-ledger/types.ts +200 -0
- package/src/tokens.ts +1 -1
- package/src/tools/recall-observation.ts +84 -214
- package/src/branch.ts +0 -577
- package/src/compaction.ts +0 -1030
- package/src/hooks/observer-trigger.ts +0 -129
- package/src/progress.ts +0 -155
- package/src/prompts.ts +0 -302
- package/src/relevance.ts +0 -15
- package/src/types.ts +0 -155
package/README.md
CHANGED
|
@@ -1,57 +1,175 @@
|
|
|
1
|
+
> [!IMPORTANT]
|
|
2
|
+
> **V3 update notice:** this extension now uses the new V3 memory model. If you used V2, update your `observational-memory` settings before running this version. V3 does **not** read the old V2 settings or memory format, and you should start a new clean Pi session after upgrading. See [Migrating from V2](#migrating-from-v2).
|
|
3
|
+
|
|
4
|
+
> [!NOTE]
|
|
5
|
+
> The `master` branch is the active development branch and may include unreleased or unstable changes. For stable versions, install the published npm package with `pi install npm:pi-observational-memory`.
|
|
6
|
+
|
|
1
7
|
# pi-observational-memory
|
|
2
8
|
|
|
3
|
-
> **Make
|
|
9
|
+
> **Make Pi sessions feel endless.**
|
|
10
|
+
|
|
11
|
+
`pi-observational-memory` is a Pi extension that keeps long agent sessions coherent across compactions, handoffs, and days of work.
|
|
12
|
+
|
|
13
|
+
It helps Pi remember what matters while you work, so your agent does not lose the thread when the session gets long.
|
|
14
|
+
|
|
15
|
+
Built for engineers who use Pi for real coding work: multi-day refactors, deep debugging sessions, architecture exploration, migrations, product implementation, and long-running branches where context matters.
|
|
4
16
|
|
|
5
17
|
---
|
|
6
18
|
|
|
7
|
-
## The
|
|
19
|
+
## The problem
|
|
8
20
|
|
|
9
|
-
|
|
21
|
+
Long AI coding sessions eventually hit a wall.
|
|
10
22
|
|
|
11
|
-
|
|
23
|
+
Not because the agent stops being useful. Not because the work is too complex. But because the session starts getting compressed.
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
A compaction summarizes the session. Later, another compaction summarizes that summary. Then another. After enough cycles, your agent is no longer carrying the real working context. It is carrying a compressed version of a compressed version of a compressed version.
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
That is when the small but important details start disappearing:
|
|
16
28
|
|
|
17
|
-
|
|
29
|
+
* why a design decision was made
|
|
30
|
+
* what approaches were already rejected
|
|
31
|
+
* which constraint mattered most
|
|
32
|
+
* what the current branch is trying to achieve
|
|
33
|
+
* what the user already clarified
|
|
34
|
+
* what the agent already investigated
|
|
35
|
+
* what should not be reopened
|
|
18
36
|
|
|
19
|
-
|
|
37
|
+
The session is still alive, but it no longer feels connected to the work that came before.
|
|
20
38
|
|
|
21
|
-
|
|
39
|
+
For engineers, that is painful. Long coding sessions are built out of accumulated decisions. When those decisions lose their rationale, the agent starts drifting.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## The second problem: slow compaction
|
|
44
|
+
|
|
45
|
+
Compaction can also break flow.
|
|
46
|
+
|
|
47
|
+
You are deep in a coding session, the agent needs to compact, and suddenly you wait while a model rewrites the past. In large sessions, that pause can take minutes.
|
|
48
|
+
|
|
49
|
+
That interruption is costly because it happens exactly when the session is already complex and you most need continuity.
|
|
50
|
+
|
|
51
|
+
`pi-observational-memory` changes the experience: memory work happens as the session progresses, so when compaction time arrives, Pi can move forward quickly.
|
|
52
|
+
|
|
53
|
+
The goal is simple:
|
|
54
|
+
|
|
55
|
+
> When compaction happens, you should barely notice.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## What this extension gives you
|
|
60
|
+
|
|
61
|
+
`pi-observational-memory` continuously captures useful session memory while you work.
|
|
62
|
+
|
|
63
|
+
It focuses on two simple concepts:
|
|
64
|
+
|
|
65
|
+
### Observations
|
|
66
|
+
|
|
67
|
+
Observations are concrete things that happened or were established during the session.
|
|
68
|
+
|
|
69
|
+
Examples:
|
|
70
|
+
|
|
71
|
+
* the user decided to switch from REST to GraphQL
|
|
72
|
+
* the migration was completed and validated
|
|
73
|
+
* a bug was traced to a specific module
|
|
74
|
+
* a branch is focused on replacing one implementation with another
|
|
75
|
+
* a deadline, constraint, or preference was stated
|
|
76
|
+
|
|
77
|
+
Observations keep the session grounded in actual work.
|
|
78
|
+
|
|
79
|
+
### Reflections
|
|
80
|
+
|
|
81
|
+
Reflections are durable facts distilled from observations.
|
|
82
|
+
|
|
83
|
+
Examples:
|
|
84
|
+
|
|
85
|
+
* the user is building a Next.js 15 dashboard with Supabase auth
|
|
86
|
+
* the current implementation must ship by a specific date
|
|
87
|
+
* the project prefers minimal abstractions over framework-heavy patterns
|
|
88
|
+
* the branch is about improving long-session agent memory
|
|
89
|
+
|
|
90
|
+
Reflections help the agent stay oriented over time.
|
|
91
|
+
|
|
92
|
+
Together, observations and reflections let Pi carry the important parts of the session forward without depending on fragile summary chains.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## What it feels like
|
|
97
|
+
|
|
98
|
+
With `pi-observational-memory`, long sessions feel less like racing against the context window and more like working with an agent that can stay with you.
|
|
99
|
+
|
|
100
|
+
You can keep a session alive across many compactions. You can come back after a long break. You can hand work across sessions with less context loss. The agent has a better chance of remembering what was decided, what matters, and why the work is shaped the way it is.
|
|
101
|
+
|
|
102
|
+
This extension was built from real long-session usage, including Pi sessions that lasted for weeks without feeling close to the end of the usable working context.
|
|
103
|
+
|
|
104
|
+
The promise is not magic infinite memory.
|
|
105
|
+
|
|
106
|
+
The promise is practical continuity:
|
|
107
|
+
|
|
108
|
+
> Your agent keeps understanding the work, even after days of iteration.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Why it works
|
|
113
|
+
|
|
114
|
+
Traditional compaction asks a model to rewrite the past at the moment the context window needs relief.
|
|
115
|
+
|
|
116
|
+
`pi-observational-memory` does the important memory work earlier, while the session is still happening.
|
|
117
|
+
|
|
118
|
+
As you work, the extension captures observations and distills reflections in the background. When Pi needs to compact, the memory is already prepared. Compaction becomes a fast rendering step instead of a slow summarization event.
|
|
119
|
+
|
|
120
|
+
That gives you two big benefits:
|
|
121
|
+
|
|
122
|
+
1. **Less coherence loss** — important context is preserved as observations and reflections instead of repeatedly compressed through summary chains.
|
|
123
|
+
2. **Faster compaction** — the expensive memory work happens before compaction, not while you are waiting.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Example
|
|
128
|
+
|
|
129
|
+
At compaction time, Pi may receive memory like this:
|
|
130
|
+
|
|
131
|
+
```md
|
|
132
|
+
These are condensed memories from earlier in this session.
|
|
133
|
+
|
|
134
|
+
- Reflections: stable, long-lived facts about the user, project, decisions, and constraints. New reflection lines may include ids in brackets.
|
|
135
|
+
- Observations: timestamped events from the conversation history, in chronological order. Observation lines include ids in brackets.
|
|
136
|
+
|
|
137
|
+
Treat these as past records. When entries conflict, the most recent observation reflects the latest known state. Work that prior observations describe as completed should not be redone unless the user explicitly asks to revisit it.
|
|
138
|
+
|
|
139
|
+
When exact source context is needed for precision or traceability, use the recall tool with the relevant observation or reflection id. This is especially useful when a reflection materially affects a decision or is too compressed to continue confidently. Do not use recall as broad search or inject raw source unless it is needed.
|
|
22
140
|
|
|
23
|
-
```
|
|
24
141
|
## Reflections
|
|
25
142
|
[a1b2c3d4e5f6] User works at Acme Corp building Acme Dashboard on Next.js 15 with Supabase auth.
|
|
26
143
|
[b2c3d4e5f6a1] Hard constraint: ship by January 22nd 2026.
|
|
27
|
-
[c3d4e5f6a1b2] Public API uses GraphQL (switched from REST to reduce mobile over-fetching).
|
|
28
144
|
|
|
29
145
|
## Observations
|
|
30
146
|
[d4e5f6a1b2c3] 2026-01-15 14:30 [high] User decided to switch from REST to GraphQL for the public API; motivation was reducing over-fetching on mobile clients.
|
|
31
|
-
[e5f6a1b2c3d4] 2026-01-15 14:
|
|
32
|
-
[f6a1b2c3d4e5] 2026-01-15 14:50 [medium] GraphQL migration completed; user confirmed queries working.
|
|
33
|
-
[a6b1c2d3e4f5] 2026-01-15 15:10 [critical] User wants rate limiting on all public endpoints; prefers token bucket algorithm at 100 req/min per API key.
|
|
147
|
+
[e5f6a1b2c3d4] 2026-01-15 14:50 [medium] GraphQL migration completed; user confirmed queries working.
|
|
34
148
|
```
|
|
35
149
|
|
|
36
|
-
|
|
150
|
+
The IDs are useful because the agent-facing `recall` tool can recover source evidence for a specific observation or reflection.
|
|
37
151
|
|
|
38
|
-
|
|
39
|
-
|
|
152
|
+
That means memory is not just a vague statement. The agent can look back at the evidence behind it.
|
|
153
|
+
|
|
154
|
+
---
|
|
40
155
|
|
|
41
|
-
|
|
156
|
+
## Who this is for
|
|
42
157
|
|
|
43
|
-
|
|
158
|
+
Use `pi-observational-memory` if you use Pi for:
|
|
44
159
|
|
|
45
|
-
|
|
160
|
+
* long coding sessions
|
|
161
|
+
* multi-day feature work
|
|
162
|
+
* architecture exploration
|
|
163
|
+
* large refactors
|
|
164
|
+
* production debugging
|
|
165
|
+
* repository migrations
|
|
166
|
+
* agent-assisted planning
|
|
167
|
+
* sessions that need to survive many compactions
|
|
168
|
+
* workflows where handoff quality matters
|
|
46
169
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
- **Relevance-aware pruning.** Four relevance tiers drive what gets dropped first when the observation pool grows. Trivia goes; user assertions, decisions, and verbatim errors stay.
|
|
51
|
-
- **Reflections that crystallize.** Identity, constraints, and durable preferences settle into a separate layer that doesn't get re-paraphrased on each compaction.
|
|
52
|
-
- **Predictable token cost.** Properly configured for your use case, this can save real money. The reflector + pruner only run above a configurable gate, so below-gate compactions skip those LLM calls; they only call a model if sync catch-up observation is needed. The observer can be pointed at a cheap fast model independently of your main coding model.
|
|
53
|
-
- **Cache-friendly by design.** Memory updates are batched at compaction boundaries instead of injected into every turn, so prompt prefix caching keeps working between compactions.
|
|
54
|
-
- **Fewer mid-work surprises.** The extension proactively triggers compaction when the agent is idle, and this will not affect your current work as after compaction you still keep the tail of your session intact.
|
|
170
|
+
This extension is especially useful when the session contains decisions that should survive over time.
|
|
171
|
+
|
|
172
|
+
---
|
|
55
173
|
|
|
56
174
|
## Install
|
|
57
175
|
|
|
@@ -59,129 +177,220 @@ Hour six should feel like hour one. The agent knows who you are, what you've bui
|
|
|
59
177
|
pi install npm:pi-observational-memory
|
|
60
178
|
```
|
|
61
179
|
|
|
62
|
-
Or from GitHub:
|
|
180
|
+
Or install from GitHub/local development:
|
|
63
181
|
|
|
64
182
|
```bash
|
|
65
183
|
pi install git:github.com/elpapi42/pi-observational-memory
|
|
184
|
+
# or, from a local checkout:
|
|
185
|
+
pi install /absolute/path/to/pi-observational-memory
|
|
66
186
|
```
|
|
67
187
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
## How it works (60-second version)
|
|
188
|
+
Pi loads the extension from `src/index.ts` through the package `pi.extensions` entry.
|
|
71
189
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```mermaid
|
|
75
|
-
flowchart TD
|
|
76
|
-
Conv([Conversation accumulates])
|
|
77
|
-
Obs[Observer<br/>async, fire-and-forget<br/>compresses each chunk into timestamped,<br/>relevance-tagged observations<br/>stored as silent tree entries]
|
|
78
|
-
Comp[Compaction<br/>extension-owned; merges accumulated<br/>observations with prior compaction state]
|
|
79
|
-
RP[Reflector + Pruner<br/>Reflector runs two focused passes<br/>to crystallize durable patterns<br/>Pruner drops observations by id<br/>across up to 2 passes]
|
|
80
|
-
Sum[Summary mechanically assembled<br/>## Reflections<br/> [id] durable insight<br/>## Observations<br/> [id] YYYY-MM-DD HH:MM relevance ...<br/>Becomes the compactionSummary<br/>the agent sees on the next turn]
|
|
81
|
-
|
|
82
|
-
Conv -->|every ~1k raw tokens since last bound| Obs
|
|
83
|
-
Obs -->|live tail reaches ~50k raw tokens| Comp
|
|
84
|
-
Comp -->|observation pool ≥ 30k tokens| RP
|
|
85
|
-
RP --> Sum
|
|
86
|
-
Comp -.->|pool below gate — skip reflector/pruner| Sum
|
|
87
|
-
```
|
|
190
|
+
---
|
|
88
191
|
|
|
89
|
-
|
|
90
|
-
- **Compaction** is owned by the extension. The summary is *mechanically concatenated* from current reflections + current observations — never an LLM rewrite. This is what eliminates the summary-of-a-summary problem.
|
|
91
|
-
- **Reflector + Pruner** run as an inseparable pair, and only when there's enough material to crystallize. Below the gate, those roles are skipped; compaction only calls a model if sync catch-up observation is needed for uncovered raw history.
|
|
192
|
+
## Quick configuration
|
|
92
193
|
|
|
93
|
-
|
|
194
|
+
Settings live under the `observational-memory` namespace in either:
|
|
94
195
|
|
|
95
|
-
|
|
196
|
+
* `~/.pi/agent/settings.json`
|
|
197
|
+
* project-local `.pi/settings.json`
|
|
96
198
|
|
|
97
|
-
|
|
98
|
-
- **[docs/how-it-works.md](docs/how-it-works.md)** — the full lifecycle, data shapes, and async-race handling.
|
|
99
|
-
- **[docs/configuration.md](docs/configuration.md)** — every setting, what it trades off, and tuning recipes.
|
|
199
|
+
Project settings override global settings.
|
|
100
200
|
|
|
101
|
-
|
|
201
|
+
`PI_OBSERVATIONAL_MEMORY_PASSIVE` can override only `passive`.
|
|
102
202
|
|
|
103
|
-
|
|
203
|
+
A typical config:
|
|
104
204
|
|
|
105
205
|
```json
|
|
106
206
|
{
|
|
107
207
|
"observational-memory": {
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"
|
|
208
|
+
"observeAfterTokens": 10000,
|
|
209
|
+
"reflectAfterTokens": 20000,
|
|
210
|
+
"compactAfterTokens": 81000,
|
|
211
|
+
"observationsPoolMaxTokens": 20000,
|
|
212
|
+
"observationsPoolTargetTokens": 10000,
|
|
213
|
+
"agentMaxTurns": 16,
|
|
214
|
+
"model": {
|
|
215
|
+
"provider": "openrouter",
|
|
216
|
+
"id": "google/gemma-4-31b-it",
|
|
217
|
+
"thinking": "low"
|
|
218
|
+
},
|
|
219
|
+
"passive": false,
|
|
220
|
+
"debugLog": false
|
|
115
221
|
}
|
|
116
222
|
}
|
|
117
223
|
```
|
|
118
224
|
|
|
119
|
-
|
|
225
|
+
Most users can start with the defaults and tune only if they have a specific reason.
|
|
120
226
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
227
|
+
### Defaults
|
|
228
|
+
|
|
229
|
+
| Setting | Default | Meaning |
|
|
230
|
+
| --------------------------- | ------------- | ------------------------------------------------------------------------------------------------- |
|
|
231
|
+
| `observeAfterTokens` | `10000` | Raw/source token threshold for observation runs. |
|
|
232
|
+
| `reflectAfterTokens` | `20000` | Raw/source token threshold for reflection and memory maintenance. |
|
|
233
|
+
| `compactAfterTokens` | `81000` | Raw/source token threshold for proactive auto-compaction. |
|
|
234
|
+
| `observationsPoolMaxTokens` | `20000` | Observation-token budget used for compaction full-fold pressure. |
|
|
235
|
+
| `observationsPoolTargetTokens` | half of max | Active-ledger observation target used by post-reflection dropper maintenance. |
|
|
236
|
+
| `agentMaxTurns` | `16` | Shared turn cap for background memory-agent loops. |
|
|
237
|
+
| `model` | session model | Optional memory-worker model override: `{ provider, id, thinking }`. |
|
|
238
|
+
| `passive` | `false` | Disables proactive background observation, reflection, maintenance, and auto-compaction triggers. |
|
|
239
|
+
| `debugLog` | `false` | Writes extension debug events to Pi's agent directory. |
|
|
240
|
+
|
|
241
|
+
Valid `model.thinking` values are:
|
|
242
|
+
|
|
243
|
+
* `off`
|
|
244
|
+
* `minimal`
|
|
245
|
+
* `low`
|
|
246
|
+
* `medium`
|
|
247
|
+
* `high`
|
|
248
|
+
* `xhigh`
|
|
249
|
+
|
|
250
|
+
If no `model` is configured, memory workers use the session model.
|
|
251
|
+
|
|
252
|
+
For details and tuning guidance, see [`docs/configuration.md`](docs/configuration.md).
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Commands and agent tool
|
|
257
|
+
|
|
258
|
+
| Surface | What it does |
|
|
259
|
+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
260
|
+
| `/om-status` | Shows memory counts, plain `+N` / `-N` visible/full drift suffixes, progress clocks, visible and active-ledger memory pressure, passive/in-flight state, and last worker errors. |
|
|
261
|
+
| `/om-view` | Shows current visible memory and attempts to copy the rendered memory text to the clipboard. |
|
|
262
|
+
| `/om-view full` | Shows the full current memory state for the branch and attempts to copy the rendered memory text to the clipboard. |
|
|
263
|
+
| `recall` agent tool | Recovers source evidence for a 12-character observation/reflection id on the current branch. It is not semantic search or a transcript browser. |
|
|
264
|
+
|
|
265
|
+
`/om-view` copies only the rendered memory content. The success/failure line shown in Pi is not included in the clipboard text. If clipboard support is unavailable, the command still prints the memory view and shows a warning. Before the first V3 compaction, visible memory can be empty because nothing has been folded into `om.folded` details; use `/om-view full` to inspect recorded branch memory.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## How it works in 60 seconds
|
|
270
|
+
|
|
271
|
+
```mermaid
|
|
272
|
+
flowchart TD
|
|
273
|
+
Turn[turn_end]
|
|
274
|
+
Observe[Capture observations]
|
|
275
|
+
Reflect[Distill reflections]
|
|
276
|
+
AgentEnd[agent_end]
|
|
277
|
+
Trigger[auto-compaction trigger]
|
|
278
|
+
Compact[session_before_compact]
|
|
279
|
+
Summary[visible memory for Pi]
|
|
280
|
+
|
|
281
|
+
Turn -->|observation due| Observe
|
|
282
|
+
Turn -->|reflection due| Reflect
|
|
283
|
+
AgentEnd -->|compactAfterTokens and idle| Trigger --> Compact --> Summary
|
|
127
284
|
```
|
|
128
285
|
|
|
129
|
-
|
|
286
|
+
The high-level lifecycle:
|
|
287
|
+
|
|
288
|
+
1. Pi session continues normally.
|
|
289
|
+
2. The extension captures observations from the session as work happens.
|
|
290
|
+
3. Durable reflections are distilled in the background.
|
|
291
|
+
4. When compaction time arrives, Pi receives prepared memory quickly.
|
|
292
|
+
5. The agent continues with a compact but useful view of the work so far.
|
|
293
|
+
|
|
294
|
+
The important part: compaction does not need to rethink the whole session from scratch.
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Current V3 behavior
|
|
299
|
+
|
|
300
|
+
Current behavior:
|
|
301
|
+
|
|
302
|
+
* **Observation-centered memory.** The extension records useful session observations while you work.
|
|
303
|
+
* **Durable reflections.** The extension distills stable facts that help the agent stay oriented over time.
|
|
304
|
+
* **Fast compaction.** `session_before_compact` does not call a model or wait for background workers. It renders the current prepared memory state.
|
|
305
|
+
* **Background memory work.** Observation and reflection work run from `turn_end` when their token clocks are due; dropper work runs only after successful reflection and prunes the folded active observation ledger toward `observationsPoolTargetTokens`.
|
|
306
|
+
* **Source-backed recall.** Observations and reflections can be traced back through the `recall` tool.
|
|
307
|
+
* **Visible/full views.** `/om-view` shows visible memory and `/om-view full` shows the full current memory state. Use `/om-status` for visible-vs-full drift and for the separate visible observation pool vs active ledger pool.
|
|
308
|
+
* **No V2 compatibility layer.** Old V2 settings and memory entries are ignored rather than migrated.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Migrating from V2
|
|
313
|
+
|
|
314
|
+
V3 is **not backwards compatible** with V2 memory or settings.
|
|
315
|
+
|
|
316
|
+
What this means in practice:
|
|
317
|
+
|
|
318
|
+
1. **Update your settings.** V2 keys are silently ignored by V3. Keeping the old names will make V3 fall back to defaults.
|
|
319
|
+
2. **Start a new clean Pi session after upgrading.** Existing sessions may still contain old visible compaction-summary text until a new V3 compaction replaces what the agent sees, so a clean session is the safest migration path.
|
|
320
|
+
3. **Do not expect rollback continuity.** If you create V3 memory entries and then roll back to V2, V2 will not understand the V3 memory format. Treat that as memory reset/visibility loss.
|
|
321
|
+
|
|
322
|
+
### Settings migration table
|
|
323
|
+
|
|
324
|
+
| V2 setting | V3 setting | What to do |
|
|
325
|
+
| ---------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
326
|
+
| `observationThresholdTokens` | `observeAfterTokens` | Rename. Same rough role: observation cadence based on raw/source tokens. |
|
|
327
|
+
| `compactionThresholdTokens` | `compactAfterTokens` | Rename. Same rough role: proactive compaction cadence. |
|
|
328
|
+
| `reflectionThresholdTokens` | `reflectAfterTokens`, `observationsPoolMaxTokens`, and/or `observationsPoolTargetTokens` | Split. Use `reflectAfterTokens` for reflection scheduling, `observationsPoolMaxTokens` for compaction full-fold pressure, and `observationsPoolTargetTokens` for dropper active-ledger maintenance. |
|
|
329
|
+
| `compactionModel` | `model` | Move `{ provider, id }` to `model`. |
|
|
330
|
+
| `thinkingLevel` | `model.thinking` | Move under `model`. |
|
|
331
|
+
| `observerMaxTurnsPerRun` | `agentMaxTurns` | Replace with the shared memory-agent turn cap. |
|
|
332
|
+
| `reflectorMaxTurnsPerPass` | `agentMaxTurns` | Replace with the shared memory-agent turn cap. |
|
|
333
|
+
| `prunerMaxTurnsPerPass` | `agentMaxTurns` | Replace with the shared memory-agent turn cap. |
|
|
334
|
+
| `compactionMaxToolCalls` | none | Remove. There is no V3 alias. |
|
|
335
|
+
| `passive` | `passive` | Keep if desired. |
|
|
336
|
+
| `debugLog` | `debugLog` | Keep if desired. |
|
|
337
|
+
|
|
338
|
+
Example V2 config:
|
|
130
339
|
|
|
131
340
|
```json
|
|
132
341
|
{
|
|
133
342
|
"observational-memory": {
|
|
343
|
+
"observationThresholdTokens": 1000,
|
|
344
|
+
"compactionThresholdTokens": 50000,
|
|
345
|
+
"reflectionThresholdTokens": 30000,
|
|
346
|
+
"compactionModel": { "provider": "openrouter", "id": "google/gemma-4-31b-it" },
|
|
347
|
+
"thinkingLevel": "low",
|
|
134
348
|
"observerMaxTurnsPerRun": 8,
|
|
135
349
|
"reflectorMaxTurnsPerPass": 12,
|
|
136
|
-
"prunerMaxTurnsPerPass": 12
|
|
350
|
+
"prunerMaxTurnsPerPass": 12,
|
|
351
|
+
"passive": false
|
|
137
352
|
}
|
|
138
353
|
}
|
|
139
354
|
```
|
|
140
355
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
For memory model calls, you can also tune thinking effort with one unified setting. Valid values are `off`, `minimal`, `low`, `medium`, `high`, and `xhigh`; the default is `low`.
|
|
356
|
+
V3 equivalent:
|
|
144
357
|
|
|
145
358
|
```json
|
|
146
359
|
{
|
|
147
360
|
"observational-memory": {
|
|
148
|
-
"
|
|
361
|
+
"observeAfterTokens": 10000,
|
|
362
|
+
"reflectAfterTokens": 20000,
|
|
363
|
+
"compactAfterTokens": 81000,
|
|
364
|
+
"observationsPoolMaxTokens": 20000,
|
|
365
|
+
"observationsPoolTargetTokens": 10000,
|
|
366
|
+
"agentMaxTurns": 12,
|
|
367
|
+
"model": {
|
|
368
|
+
"provider": "openrouter",
|
|
369
|
+
"id": "google/gemma-4-31b-it",
|
|
370
|
+
"thinking": "low"
|
|
371
|
+
},
|
|
372
|
+
"passive": false
|
|
149
373
|
}
|
|
150
374
|
}
|
|
151
375
|
```
|
|
152
376
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
| Setting | Default | What it controls |
|
|
156
|
-
|---|---|---|
|
|
157
|
-
| `observationThresholdTokens` | `1,000` | How often the observer fires in the background |
|
|
158
|
-
| `compactionThresholdTokens` | `50,000` | How often the extension proactively triggers compaction |
|
|
159
|
-
| `reflectionThresholdTokens` | `30,000` | The observation pool size at which reflector + pruner engage |
|
|
160
|
-
| `passive` | `false` | Disables proactive observation and extension-triggered compaction while keeping manual/Pi compaction and commands active |
|
|
161
|
-
| `compactionModel` | session model | Which model runs the observer / reflector / pruner — point at a cheaper one to save cost |
|
|
162
|
-
| `observerMaxTurnsPerRun` | `16` | Assistant-turn cap for each observer run |
|
|
163
|
-
| `reflectorMaxTurnsPerPass` | `16` | Assistant-turn cap for each reflector pass |
|
|
164
|
-
| `prunerMaxTurnsPerPass` | `16` | Assistant-turn cap for each pruner pass |
|
|
165
|
-
| `thinkingLevel` | `low` | Thinking effort for observer, reflector, and pruner calls; `off` omits Pi's reasoning option |
|
|
166
|
-
| `compaction.keepRecentTokens` | `20,000` | How much recent conversation Pi keeps verbatim post-compaction (Pi setting; structural to the extension) |
|
|
377
|
+
---
|
|
167
378
|
|
|
168
|
-
|
|
379
|
+
## More docs
|
|
169
380
|
|
|
170
|
-
|
|
381
|
+
* [`docs/concepts.md`](docs/concepts.md) — vocabulary and V3 mental model.
|
|
382
|
+
* [`docs/how-it-works.md`](docs/how-it-works.md) — lifecycle, memory shapes, projections, and recall flow.
|
|
383
|
+
* [`docs/configuration.md`](docs/configuration.md) — all V3 settings and migration notes.
|
|
171
384
|
|
|
172
|
-
|
|
385
|
+
---
|
|
173
386
|
|
|
174
|
-
##
|
|
387
|
+
## Credits
|
|
175
388
|
|
|
176
|
-
|
|
177
|
-
|---|---|
|
|
178
|
-
| `/om-status` | Memory totals, percent-to-threshold for each gate, passive-mode status, and in-flight flags for observer and compaction |
|
|
179
|
-
| `/om-view` | Full dump of memory state: every reflection, every committed observation, every pending observation. Reflection and observation ids shown here can be used with `recall` |
|
|
180
|
-
| `recall` agent tool | Recovers exact source evidence for a specific reflection or observation id on the current branch. It is for agent self-recovery and provenance, not a user command, semantic search, or transcript browser |
|
|
389
|
+
Inspired by [Mastra's Observational Memory](https://mastra.ai/blog/observational-memory) research.
|
|
181
390
|
|
|
182
|
-
|
|
391
|
+
This is an independent implementation built for Pi's extension system.
|
|
183
392
|
|
|
184
|
-
|
|
393
|
+
---
|
|
185
394
|
|
|
186
395
|
## License
|
|
187
396
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-observational-memory",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Observational memory extension for pi — cache-friendly tiered compaction with observations and reflections.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,16 +34,16 @@
|
|
|
34
34
|
"test": "vitest run"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
40
|
-
"@
|
|
37
|
+
"@earendil-works/pi-agent-core": "*",
|
|
38
|
+
"@earendil-works/pi-ai": "*",
|
|
39
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
40
|
+
"@earendil-works/pi-tui": "*"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
43
|
+
"@earendil-works/pi-agent-core": "^0.74.0",
|
|
44
|
+
"@earendil-works/pi-ai": "^0.74.0",
|
|
45
|
+
"@earendil-works/pi-coding-agent": "^0.74.0",
|
|
46
|
+
"@earendil-works/pi-tui": "^0.74.0",
|
|
47
47
|
"@types/node": "^22.0.0",
|
|
48
48
|
"typebox": "^1.1.38",
|
|
49
49
|
"typescript": "^5.6.0",
|