pi-smart-compact 7.5.2 → 7.9.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +513 -198
  3. package/dist/constants.d.ts +45 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/core.d.ts +27 -0
  6. package/dist/core.d.ts.map +1 -0
  7. package/dist/index.d.ts +8 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +3131 -0
  10. package/dist/phases/explore.d.ts +35 -0
  11. package/dist/phases/explore.d.ts.map +1 -0
  12. package/dist/phases/synthesize.d.ts +23 -0
  13. package/dist/phases/synthesize.d.ts.map +1 -0
  14. package/dist/phases/verify.d.ts +16 -0
  15. package/dist/phases/verify.d.ts.map +1 -0
  16. package/dist/types.d.ts +265 -0
  17. package/dist/types.d.ts.map +1 -0
  18. package/dist/ui/overlays.d.ts +29 -0
  19. package/dist/ui/overlays.d.ts.map +1 -0
  20. package/dist/utils/cache.d.ts +27 -0
  21. package/dist/utils/cache.d.ts.map +1 -0
  22. package/dist/utils/damage.d.ts +28 -0
  23. package/dist/utils/damage.d.ts.map +1 -0
  24. package/dist/utils/extraction.d.ts +27 -0
  25. package/dist/utils/extraction.d.ts.map +1 -0
  26. package/dist/utils/fingerprint.d.ts +32 -0
  27. package/dist/utils/fingerprint.d.ts.map +1 -0
  28. package/dist/utils/helpers.d.ts +22 -0
  29. package/dist/utils/helpers.d.ts.map +1 -0
  30. package/dist/utils/logger.d.ts +8 -0
  31. package/dist/utils/logger.d.ts.map +1 -0
  32. package/dist/utils/pruning.d.ts +19 -0
  33. package/dist/utils/pruning.d.ts.map +1 -0
  34. package/dist/utils/state.d.ts +62 -0
  35. package/dist/utils/state.d.ts.map +1 -0
  36. package/dist/utils/tokens.d.ts +8 -0
  37. package/dist/utils/tokens.d.ts.map +1 -0
  38. package/dist/utils/type-guards.d.ts +26 -0
  39. package/dist/utils/type-guards.d.ts.map +1 -0
  40. package/docs/assets/pi-smart-compact.png +0 -0
  41. package/package.json +13 -3
  42. package/src/constants.ts +0 -140
  43. package/src/core.ts +0 -360
  44. package/src/index.ts +0 -175
  45. package/src/phases/explore.ts +0 -371
  46. package/src/phases/synthesize.ts +0 -184
  47. package/src/phases/verify.ts +0 -191
  48. package/src/types.ts +0 -176
  49. package/src/ui/overlays.ts +0 -329
  50. package/src/utils/cache.ts +0 -145
  51. package/src/utils/damage.ts +0 -153
  52. package/src/utils/extraction.ts +0 -259
  53. package/src/utils/fingerprint.ts +0 -190
  54. package/src/utils/helpers.ts +0 -161
  55. package/src/utils/message-blocks.ts +0 -21
  56. package/src/utils/pruning.ts +0 -147
  57. package/src/utils/tokens.ts +0 -63
package/README.md CHANGED
@@ -1,110 +1,457 @@
1
- # Smart Compact
1
+ # pi-smart-compact
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/pi-smart-compact.svg)](https://www.npmjs.com/package/pi-smart-compact)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
5
5
  [![GitHub](https://img.shields.io/badge/GitHub-alpertarhan%2Fpi--smart--compact-blue)](https://github.com/alpertarhan/pi-smart-compact)
6
6
 
7
- > EESV-powered intelligent context compaction for the [Pi Coding Agent](https://github.com/earendil-works/pi-coding-agent).
7
+ <p align="center">
8
+ <img src="./docs/assets/pi-smart-compact.png" alt="pi-smart-compact" width="760" />
9
+ </p>
8
10
 
9
- **Smart Compact** compresses long conversation contexts by understanding *what happened* — not by blindly truncating. It deterministically extracts files, errors, decisions, and constraints from your session, then uses LLM-guided exploration and parallel batch synthesis to produce a structured summary that preserves the meaning and state of your work.
11
+ > Verification-oriented smart compaction for the [Pi Coding Agent](https://github.com/earendil-works/pi-coding-agent).
10
12
 
11
- The result: a shorter context that the agent can actually work with, without losing critical information.
13
+ `pi-smart-compact` replaces blind conversation trimming with a structured compaction pipeline that tries to preserve the agent's working state: goal, files, errors, decisions, constraints, open loops, and cross-compaction deltas.
14
+
15
+ It is built around an **EESV** pipeline:
16
+
17
+ **Extract → Explore → Synthesize → Verify**
18
+
19
+ ---
20
+
21
+ ## Table of Contents
22
+
23
+ - [What this project is](#what-this-project-is)
24
+ - [Current repository snapshot](#current-repository-snapshot)
25
+ - [Visual identity](#visual-identity)
26
+ - [Why it exists](#why-it-exists)
27
+ - [Architecture flow](#architecture-flow)
28
+ - [Execution model](#execution-model)
29
+ - [Repository layout](#repository-layout)
30
+ - [Runtime artifacts](#runtime-artifacts)
31
+ - [Installation](#installation)
32
+ - [Usage](#usage)
33
+ - [Configuration](#configuration)
34
+ - [Output contract](#output-contract)
35
+ - [Quality controls](#quality-controls)
36
+ - [Current caveats](#current-caveats)
37
+ - [Development](#development)
38
+ - [License](#license)
12
39
 
13
40
  ---
14
41
 
15
- ## Why Smart Compact?
42
+ ## What this project is
43
+
44
+ This package is a **Pi extension** that registers three integration surfaces:
16
45
 
17
- Pi's built-in compaction truncates old messages. Smart Compact **understands** them first:
46
+ | Surface | Where | Purpose |
47
+ | --- | --- | --- |
48
+ | Slash command | `/smart-compact` | Manual compaction, interactive or direct |
49
+ | Session hook | `session_before_compact` | Auto-trigger smart compaction before Pi's default compaction |
50
+ | Tool | `smart_compact` | Agent-callable compaction that stages a pending summary |
18
51
 
19
- - **Zero-LLM extraction** files modified/read, errors with retry lifecycle, user decisions, constraints, topic segmentation all deterministically extracted before any LLM call
20
- - **Hallucination detection** — verifies the summary doesn't invent file paths or misstate error status
21
- - **Decision propagation** — carries decisions across batch boundaries so the LLM never forgets what was decided
22
- - **Redundancy pruning** — collapses duplicate reads, consecutive failures, and low-info messages before compaction, reducing input by 15–30%
23
- - **Cross-session memory** — learns your project's language, framework, and file structure across sessions
24
- - **Damage detection** — monitors post-compaction behavior for regression signals
52
+ The extension keeps a short-lived pending compaction in memory, then hands that summary back to Pi when compaction is applied.
25
53
 
26
54
  ---
27
55
 
28
- ## The EESV Pipeline
56
+ ## Current repository snapshot
29
57
 
30
- ```
31
- Extract → Explore → Synthesize → Verify
32
- (0 LLM) (0–8 LLM) (N+1 LLM) (0–1 LLM)
33
- ```
58
+ **Observed from the current codebase (`README`, `src/`, `test/`, `package.json`)**
34
59
 
35
- | Phase | What it does | LLM cost |
36
- |-------|-------------|----------|
37
- | **Extract** | Deterministically mine files, errors, decisions, constraints, topics | **0 calls** |
38
- | **Explore** | LLM investigates conversation with tools to verify boundaries and enrich context. **Skipped for simple sessions.** | 0–8 calls |
39
- | **Synthesize** | Parallel batch summarization with decision propagation, then single-pass assembly | N+1 calls |
40
- | **Verify** | Coverage checks, hallucination detection, deterministic patching (zero LLM), LLM patch only as last resort | 0–1 calls |
60
+ - **Package version:** `7.8.0`
61
+ - **Runtime entrypoint:** `dist/index.js`
62
+ - **Source entrypoint:** `src/index.ts`
63
+ - **Source modules:** 16 TypeScript files under `src/`
64
+ - **Tests:** 9 test files, **93 passing tests**
65
+ - **Approx repo footprint:** ~5,053 lines across `src/` + `test/`
66
+ - **Documentation asset:** `docs/assets/pi-smart-compact.png`
67
+ - **Published package files:** `dist/`, `docs/`, `README.md`, `LICENSE`, `CHANGELOG.md`
41
68
 
42
- ### Pre-Processing (before EESV)
69
+ ### Current command health
43
70
 
44
- ```
45
- Pruning: Remove duplicate reads, collapse error chains, strip acknowledgments, truncate long outputs
46
- Reduces compaction input by 15–30%
47
- Fingerprint: Load project context (language, framework, known files) from previous sessions
48
- ```
71
+ | Command | Status | Notes |
72
+ | --- | --- | --- |
73
+ | `bun test` | Pass | 93/93 tests passing |
74
+ | `bun run build` | Pass | Bundles `src/index.ts` to `dist/index.js` |
75
+ | `bun run typecheck` | ⚠️ Fails | Current repo has TypeScript compatibility issues against the installed Pi typings / `.ts` import style |
76
+
77
+ So the project is currently **buildable and tested**, but **not fully typecheck-clean**.
78
+
79
+ ---
80
+
81
+ ## Visual identity
82
+
83
+ The repository image used by this `README.md` now lives at:
84
+
85
+ - `docs/assets/pi-smart-compact.png`
86
+
87
+ The asset is now a cleaned transparent `PNG` instead of a checkerboard/transparent-preview render, so it displays correctly inside GitHub `README.md`.
88
+
89
+ This keeps documentation assets separate from `src/` implementation code and `test/` fixtures while still shipping the image with the package via `package.json` `files`.
90
+
91
+ ---
92
+
93
+ ## Why it exists
49
94
 
50
- ### Post-Processing (after EESV)
95
+ Default compaction usually loses exactly the things a coding agent needs most:
51
96
 
97
+ - which files were actually modified
98
+ - which errors are still unresolved
99
+ - what the user explicitly asked for
100
+ - what decisions already won
101
+ - what still needs to happen next
102
+
103
+ `pi-smart-compact` tries to preserve that operational state instead of producing a generic prose summary.
104
+
105
+ ---
106
+
107
+ ## Architecture flow
108
+
109
+ ```mermaid
110
+ flowchart TD
111
+ A["Entry points<br/>/smart-compact<br/>session_before_compact<br/>smart_compact tool"] --> B["Load config and resolve models<br/>loadConfig()<br/>summaryModel / segmentationModel"]
112
+ B --> C{"Context >= 5000 tokens?"}
113
+ C -- No --> C1["Exit early"]
114
+ C -- Yes --> D["Read current branch<br/>keep recent tail by profile<br/>smartKeepBoundary()"]
115
+ D --> E["Pre-processing<br/>pruneRedundant()<br/>serializeConversation()<br/>backupConversation()<br/>getPreviousCompactionContext()"]
116
+ E --> F["Phase 1: Extract<br/>extractStructured()<br/>files, errors, decisions, constraints,<br/>heuristic topics, timeline, goal"]
117
+ F --> G["Cross-session helpers<br/>load or save cached extraction<br/>deriveProjectId()<br/>loadProjectFingerprint()"]
118
+ G --> H{"Compacted text below singlePassMaxTokens?"}
119
+ H -- Yes --> I["Single-pass path<br/>singlePassCompact()"]
120
+ H -- No --> J{"shouldExplore()?"}
121
+ J -- Yes --> K["Phase 2: Explore<br/>exploreConversation()<br/>tool probe -> tool loop<br/>or direct JSON fallback"]
122
+ J -- No --> L["Skip exploration<br/>use heuristic boundaries only"]
123
+ K --> M["Merge LLM boundaries<br/>with heuristic boundaries"]
124
+ L --> N["chunkLlmMessages()"]
125
+ M --> N
126
+ N --> O["createBatches()<br/>provider-aware concurrency"]
127
+ O --> P["Phase 3: Synthesize<br/>summarizeBatch() per batch<br/>assembleLLM() or assembleFallback()"]
128
+ I --> Q["Phase 4: Verify<br/>verifySummary()"]
129
+ P --> Q
130
+ Q --> R{"Quality score below 85?"}
131
+ R -- No --> S["Accept summary"]
132
+ R -- Yes --> T["patchDeterministic()"]
133
+ T --> U{"Still below 75?"}
134
+ U -- No --> S
135
+ U -- Yes --> V["patchSummary() via LLM"]
136
+ V --> S
137
+ S --> W["Post-processing<br/>extractOpenLoops()<br/>buildCompactionState()<br/>computeDelta()<br/>inject sections"]
138
+ W --> X["Persist artifacts<br/>project fingerprint<br/>compaction state<br/>metrics log<br/>damage report"]
139
+ X --> Y["Store pending compaction<br/>in memory<br/>TTL: 5 minutes"]
140
+ Y --> Z["ctx.compact() now<br/>or next tree compact consumes it"]
52
141
  ```
53
- Damage Detection: Monitor agent behavior for regression signals (re-reads, user complaints, re-questions)
54
- ↳ Builds a quality feedback dataset over time
142
+
143
+ ---
144
+
145
+ ## Execution model
146
+
147
+ ### 1. Entry and model resolution
148
+
149
+ `src/index.ts` is the extension boundary.
150
+
151
+ It does four jobs:
152
+
153
+ 1. registers `/smart-compact`
154
+ 2. registers `session_before_compact`
155
+ 3. registers `smart_compact`
156
+ 4. keeps a shared in-memory `pendingRef` and `isRunning` lock
157
+
158
+ Model resolution order is effectively:
159
+
160
+ - explicit command model argument, if provided
161
+ - configured `summaryModel`, if resolvable
162
+ - current session model
163
+ - first available model in the registry
164
+
165
+ `segmentationModel` falls back to the summary model unless explicitly configured.
166
+
167
+ ### 2. Context gate and keep window
168
+
169
+ `src/core.ts` is the pipeline orchestrator.
170
+
171
+ Before compaction starts it:
172
+
173
+ - checks `MIN_TOKEN_THRESHOLD = 5000`
174
+ - reads the current session branch
175
+ - keeps the most recent tail according to the selected profile
176
+ - nudges the keep boundary with `smartKeepBoundary()` if adjacent messages appear to reference the same file
177
+
178
+ ### 3. Pre-processing
179
+
180
+ Before any summarization, the pipeline performs:
181
+
182
+ - **redundancy pruning** via `src/utils/pruning.ts`
183
+ - **conversation backup** via `backupConversation()`
184
+ - **previous compaction context injection** via `getPreviousCompactionContext()`
185
+ - **incremental extraction cache lookup** via `src/utils/cache.ts`
186
+ - **project fingerprint lookup** via `src/utils/fingerprint.ts`
187
+
188
+ ### 4. Phase 1 — Extract
189
+
190
+ `src/utils/extraction.ts` is the deterministic core.
191
+
192
+ It extracts, with zero LLM calls:
193
+
194
+ - modified files
195
+ - read files
196
+ - deleted files
197
+ - tool and bash-like errors
198
+ - retry / resolution signals
199
+ - explicit decisions from `ask_user`
200
+ - implicit user choices
201
+ - English and Turkish constraints
202
+ - heuristic topic segments
203
+ - timeline events
204
+ - main goal
205
+ - recent user messages
206
+ - recent error snippets
207
+
208
+ It also builds **open loops** from:
209
+
210
+ - unresolved errors
211
+ - follow-up language
212
+ - blocked/waiting language
213
+ - retried-but-unresolved failures
214
+
215
+ ### 5. Phase 2 — Explore
216
+
217
+ `src/phases/explore.ts` adds targeted LLM exploration only when complexity justifies it.
218
+
219
+ Exploration is skipped for simple sessions when the extraction stays below these heuristics:
220
+
221
+ - `<= 3` topics
222
+ - `<= 1` unresolved error
223
+ - `<= 2` decisions
224
+ - `<= 2` directory groups touched
225
+
226
+ If exploration runs, it can use these tools:
227
+
228
+ - `get_message_range`
229
+ - `search_conversation`
230
+ - `get_recent_user_messages`
231
+ - `get_context_around`
232
+ - `get_file_changes`
233
+ - `get_error_chain`
234
+
235
+ If the provider cannot or does not use tools, exploration falls back to a direct JSON analysis prompt.
236
+
237
+ ### 6. Phase 3 — Synthesize
238
+
239
+ `src/phases/synthesize.ts` supports two paths:
240
+
241
+ #### Single-pass
242
+ Used when the pruned conversation fits under the profile's `singlePassMaxTokens`.
243
+
244
+ #### Hierarchical
245
+ Used for larger sessions:
246
+
247
+ - merge heuristic and exploratory boundaries
248
+ - chunk messages with `chunkLlmMessages()`
249
+ - batch chunks with `createBatches()`
250
+ - summarize each batch with `summarizeBatch()`
251
+ - assemble a final summary with `assembleLLM()`
252
+ - fall back to `assembleFallback()` if assembly fails
253
+
254
+ Important synthesis behaviors already present in code:
255
+
256
+ - **decision propagation** into later batch prompts
257
+ - **session-type-specific prompting**
258
+ - **topic-level budget hints** during assembly pre-processing
259
+ - **provider-aware batch concurrency** from `src/utils/tokens.ts`
260
+
261
+ ### 7. Phase 4 — Verify
262
+
263
+ `src/phases/verify.ts` scores the summary against deterministic extraction data.
264
+
265
+ It checks for:
266
+
267
+ - missing modified files
268
+ - missing unresolved errors
269
+ - missing high-confidence constraints
270
+ - missing goal coverage
271
+ - missing required sections
272
+ - suspicious fabricated file references
273
+ - done/unresolved inconsistency
274
+ - missing explicit decisions
275
+ - missing open-loop coverage when unresolved errors exist
276
+
277
+ Repair strategy is intentionally ordered:
278
+
279
+ 1. no patch if score is acceptable
280
+ 2. deterministic patch first
281
+ 3. LLM patch only if deterministic patch is insufficient
282
+
283
+ ### 8. Post-processing and persistence
284
+
285
+ After verification, the pipeline:
286
+
287
+ - extracts open loops
288
+ - injects `## Open Loops`
289
+ - builds a machine-readable `CompactionState`
290
+ - loads previous compaction state
291
+ - computes delta across compactions
292
+ - injects `## Changes Since Last Compaction`
293
+ - saves project fingerprint
294
+ - saves compaction state
295
+ - appends metrics log
296
+ - attempts post-compaction damage detection
297
+
298
+ ### 9. Applying compaction
299
+
300
+ The extension stores the result in an in-memory pending object containing:
301
+
302
+ - summary
303
+ - first kept entry id
304
+ - tokens before compaction
305
+ - details payload
306
+ - structured compaction state
307
+
308
+ That pending summary is valid for **5 minutes** and is consumed by:
309
+
310
+ - immediate `ctx.compact()` in the slash-command flow, or
311
+ - the next `session_before_compact` hook call in tool-driven flows
312
+
313
+ ---
314
+
315
+ ## Repository layout
316
+
317
+ ### Top-level
318
+
319
+ ```text
320
+ .
321
+ ├── CHANGELOG.md
322
+ ├── DEVPLAN.md
323
+ ├── LICENSE
324
+ ├── README.md
325
+ ├── dist/
326
+ │ └── index.js
327
+ ├── docs/
328
+ │ └── assets/
329
+ │ └── pi-smart-compact.png
330
+ ├── package.json
331
+ ├── src/
332
+ ├── test/
333
+ └── tsconfig.json
55
334
  ```
56
335
 
336
+ ### Source modules
337
+
338
+ | File | Role |
339
+ | --- | --- |
340
+ | `src/index.ts` | Extension registration: command, hook, tool |
341
+ | `src/core.ts` | End-to-end pipeline orchestration |
342
+ | `src/constants.ts` | Version, prompts, profiles, thresholds, config keys |
343
+ | `src/types.ts` | Shared types and guards |
344
+ | `src/phases/explore.ts` | Exploration phase, tool loop, JSON fallback |
345
+ | `src/phases/synthesize.ts` | Chunking, batching, single-pass and hierarchical synthesis |
346
+ | `src/phases/verify.ts` | Verification, deterministic patch, LLM patch |
347
+ | `src/ui/overlays.ts` | 2-step picker UI, progress notices, result screen |
348
+ | `src/utils/cache.ts` | Metrics, cache-aware LLM options, extraction cache |
349
+ | `src/utils/damage.ts` | Post-compaction regression signal detection |
350
+ | `src/utils/extraction.ts` | Deterministic extraction and open-loop detection |
351
+ | `src/utils/fingerprint.ts` | Cross-session project fingerprinting |
352
+ | `src/utils/helpers.ts` | Config loading, backups, batching, prompt helpers |
353
+ | `src/utils/pruning.ts` | Redundancy pruning before compaction |
354
+ | `src/utils/state.ts` | Compaction state persistence and delta logic |
355
+ | `src/utils/tokens.ts` | Provider capabilities and token estimation |
356
+
357
+ ### Tests
358
+
359
+ | Test file | Coverage |
360
+ | --- | --- |
361
+ | `test/extraction.test.ts` | deterministic extraction |
362
+ | `test/exploration.test.ts` | exploration parsing and gating |
363
+ | `test/eval.test.ts` | gold scenarios, delta evaluation, fabrication safety |
364
+ | `test/fingerprint.test.ts` | project fingerprint helpers |
365
+ | `test/pruning.test.ts` | redundancy pruning |
366
+ | `test/semantic-compact.test.ts` | legacy-name regression coverage |
367
+ | `test/state.test.ts` | open loops, state, delta, persistence |
368
+ | `test/tokens.test.ts` | token estimation and provider caps |
369
+ | `test/verify.test.ts` | verification and patching |
370
+
371
+ ---
372
+
373
+ ## Runtime artifacts
374
+
375
+ The current code writes to these paths at runtime:
376
+
377
+ | Artifact | Path |
378
+ | --- | --- |
379
+ | Settings file | `~/.pi/agent/settings.json` |
380
+ | Conversation backups | `~/.pi/agent/compact-backups/` |
381
+ | Extraction cache | `~/.pi/agent/.cache/compact-extraction-<session>.json` |
382
+ | Metrics log | `~/.pi/agent/.cache/compact-metrics.jsonl` |
383
+ | Project fingerprints | `~/.pi/agent/.cache/smart-compact/projects/<projectId>.json` |
384
+ | Compaction states | `~/.pi/agent/.cache/smart-compact/states/<projectId>.json` |
385
+ | Damage reports | `~/.pi/agent/.cache/smart-compact/damage-reports.jsonl` |
386
+
387
+ ### TTLs currently implemented
388
+
389
+ | Item | TTL |
390
+ | --- | --- |
391
+ | pending in-memory compaction | 5 minutes |
392
+ | exploration tool-support cache | 30 minutes |
393
+ | extraction cache | 1 hour |
394
+ | compaction state | 7 days |
395
+ | project fingerprint | 30 days |
396
+
57
397
  ---
58
398
 
59
399
  ## Installation
60
400
 
401
+ ### npm / Pi package
402
+
61
403
  ```bash
62
- # Option 1: Install via bun (recommended)
63
- bun add pi-smart-compact
404
+ pi install npm:pi-smart-compact
405
+ ```
64
406
 
65
- # Option 2: Install via npm
66
- npm install pi-smart-compact
407
+ ### GitHub
67
408
 
68
- # Option 3: Clone directly
69
- cd ~/.pi/agent/extensions
70
- git clone https://github.com/alpertarhan/pi-smart-compact.git
71
- cd pi-smart-compact && bun install
409
+ ```bash
410
+ pi install git:github.com/alpertarhan/pi-smart-compact
72
411
  ```
73
412
 
74
- Then add to your Pi `settings.json`:
413
+ ### Local development
75
414
 
76
- ```json
77
- {
78
- "extensions": ["pi-smart-compact"]
79
- }
415
+ ```bash
416
+ cd ~/.pi/agent/extensions
417
+ git clone https://github.com/alpertarhan/pi-smart-compact.git
418
+ cd pi-smart-compact
419
+ bun install
420
+ bun run build
80
421
  ```
81
422
 
82
423
  ---
83
424
 
84
425
  ## Usage
85
426
 
86
- ### Command
427
+ ### Interactive
87
428
 
88
429
  ```bash
89
- # Interactive TUI — pick model + profile
90
430
  /smart-compact
431
+ ```
91
432
 
92
- # Direct specific model + profile
93
- /smart-compact anthropic/claude-sonnet-4 balanced
433
+ With no arguments, the extension opens a **2-step TUI**:
94
434
 
95
- # Dry run — preview what would be compacted
96
- /smart-compact dry-run
435
+ 1. model selection
436
+ 2. profile selection
97
437
 
98
- # Verbose detailed pipeline logging
99
- /smart-compact debug
438
+ ### Direct command examples
100
439
 
101
- # Steering note — guide the summary focus
102
- /smart-compact "focus on auth changes"
440
+ ```bash
441
+ /smart-compact anthropic/claude-sonnet-4 balanced
442
+ /smart-compact dry-run
443
+ /smart-compact debug
444
+ /smart-compact "focus on auth changes and unresolved follow-up work"
103
445
  ```
104
446
 
105
- ### Tool (agent-callable)
447
+ Argument parsing in the current code supports:
448
+
449
+ - model ids containing `/`
450
+ - profiles: `light`, `balanced`, `aggressive`
451
+ - flags: `verbose`, `debug`, `dry-run`
452
+ - remaining free text as a user steering note
106
453
 
107
- The extension registers a tool the agent can call automatically:
454
+ ### Tool usage
108
455
 
109
456
  ```json
110
457
  {
@@ -117,25 +464,17 @@ The extension registers a tool the agent can call automatically:
117
464
  }
118
465
  ```
119
466
 
120
- ### Auto-Trigger
467
+ Tool behavior is slightly different from the slash command:
121
468
 
122
- When `autoTrigger` is enabled (default), Smart Compact runs automatically before Pi's built-in compaction kicks in. The `session_before_compact` hook intercepts the event and produces the smart summary instead of blind truncation.
123
-
124
- ---
125
-
126
- ## Profiles
127
-
128
- | Profile | Summary Budget | Keep Recent | Best For |
129
- |---------|---------------|-------------|----------|
130
- | **light** | 10K tokens | 30K tokens | Debugging sessions, complex multi-file refactors where detail matters |
131
- | **balanced** | 6K tokens | 20K tokens | General development (default) |
132
- | **aggressive** | 3K tokens | 10K tokens | Quick exploration, prototyping, or very large contexts |
469
+ - it generates a pending smart summary
470
+ - it does **not** immediately compact when `skipCompact` is used internally
471
+ - it expects the next tree compaction to consume the pending result within 5 minutes
133
472
 
134
473
  ---
135
474
 
136
475
  ## Configuration
137
476
 
138
- Add to `~/.pi/agent/settings.json`:
477
+ Add this to `~/.pi/agent/settings.json`:
139
478
 
140
479
  ```json
141
480
  {
@@ -146,181 +485,157 @@ Add to `~/.pi/agent/settings.json`:
146
485
  "autoTrigger": true,
147
486
  "backupEnabled": true,
148
487
  "profiles": {
149
- "balanced": { "summaryBudgetTokens": 6000, "keepRecentTokens": 20000 }
488
+ "balanced": {
489
+ "summaryBudgetTokens": 6000,
490
+ "keepRecentTokens": 20000
491
+ }
150
492
  }
151
493
  }
152
494
  }
153
495
  ```
154
496
 
155
- | Option | Type | Default | Description |
156
- |--------|------|---------|-------------|
157
- | `profile` | `"light"` \| `"balanced"` \| `"aggressive"` | `"balanced"` | Default compression profile |
158
- | `summaryModel` | `string` \| `null` | `null` | Override model for summarization (e.g. `"anthropic/claude-sonnet-4"`) |
159
- | `segmentationModel` | `string` \| `null` | `null` | Override model for exploration (e.g. `"anthropic/claude-haiku-3"`) |
160
- | `autoTrigger` | `boolean` | `true` | Automatically run on Pi's `session_before_compact` hook |
161
- | `backupEnabled` | `boolean` | `true` | Save conversation backup before compaction |
162
- | `profiles` | `object` | — | Override per-profile token budgets |
163
-
164
- ---
165
-
166
- ## Architecture Deep Dive
167
-
168
- ### Deterministic Extraction (Phase 1)
497
+ ### Supported keys
169
498
 
170
- Zero LLM calls. Extracts purely from message structure:
499
+ | Key | Type | Default |
500
+ | --- | --- | --- |
501
+ | `profile` | `light \| balanced \| aggressive` | `balanced` |
502
+ | `summaryModel` | `string \| null` | `null` |
503
+ | `segmentationModel` | `string \| null` | `null` |
504
+ | `autoTrigger` | `boolean` | `true` |
505
+ | `backupEnabled` | `boolean` | `true` |
506
+ | `backupDir` | `string` | `~/.pi/agent/compact-backups` |
507
+ | `profiles` | partial per-profile overrides | built-ins |
171
508
 
172
- - **File operations** — tracks read/write/edit/delete with no-op detection (`"applied: 0"`, `"no changes"`)
173
- - **Error lifecycle** — not just "isError" but retry detection (same tool re-called within 6 messages) and resolution tracking
174
- - **Decisions** — explicit (`ask_user` tool calls) and implicit (user choice patterns like "use X instead of Y")
175
- - **Constraints** — regex-based mining with English + Turkish patterns, categorized as requirement/prohibition/preference
176
- - **Topic segmentation** — heuristic boundaries based on file transitions, error density, user "shift" patterns, and token limits
509
+ ### Profiles currently shipped
177
510
 
178
- ### Adaptive Exploration Gate
511
+ | Profile | Summary budget | Keep recent | Min chunk | Max chunk | Single-pass max | Batch max |
512
+ | --- | ---: | ---: | ---: | ---: | ---: | ---: |
513
+ | `light` | 10000 | 30000 | 800 | 12000 | 40000 | 30000 |
514
+ | `balanced` | 6000 | 20000 | 500 | 8000 | 30000 | 24000 |
515
+ | `aggressive` | 3000 | 10000 | 300 | 6000 | 20000 | 18000 |
179
516
 
180
- Exploration is **skipped** for simple sessions that meet all criteria:
181
- - ≤ 3 topics
182
- - ≤ 1 unresolved error
183
- - ≤ 2 decisions
184
- - ≤ 2 directory groups
517
+ ### Backward compatibility
185
518
 
186
- This saves 3–8 LLM calls on straightforward sessions.
519
+ The code still accepts the old config key:
187
520
 
188
- ### Decision Propagation
521
+ - `semanticCompact`
189
522
 
190
- Each batch receives "Active Decisions from previous segments" — decisions made before the batch's message range. This prevents the common failure mode where Batch 2 doesn't know that Batch 1 decided to use React.
523
+ but the current key is:
191
524
 
192
- ### Immutable Context Framing
525
+ - `smartCompact`
193
526
 
194
- The assembly prompt presents deterministic data as **IMMUTABLE CONTEXT** with explicit rules:
195
-
196
- > *"These are deterministically verified from the original conversation. They take priority over ANY summary content below."*
197
-
198
- This reduces fabrication by making the LLM treat verified data as ground truth.
199
-
200
- ### Verification & Patching
201
-
202
- 1. **Verification** — checks file coverage, error coverage, constraint coverage, hallucinated file paths, error-done inconsistencies, decision coverage
203
- 2. **Deterministic patch** (score < 85) — injects missing items directly into the relevant markdown sections, zero LLM cost
204
- 3. **LLM patch** (score < 75 after deterministic) — last resort, only if deterministic patch was insufficient
205
- 4. **Skip** (score ≥ 85) — no patching needed
527
+ ---
206
528
 
207
- ### Redundancy Pruning
529
+ ## Output contract
208
530
 
209
- Before compaction, deterministic pruning removes:
210
- - **Duplicate file reads** — keeps only the last read per file
211
- - **Collapsed error chains** — 3+ consecutive same-tool failures → keep first + last only
212
- - **Agent acknowledgments** — "I'll fix that", "Let me check", "Sure" (zero-information messages)
213
- - **Long tool outputs** — truncates to 800 chars (head 400 + tail 400)
531
+ The generated Markdown is expected to follow this structure:
214
532
 
215
- ### Project Fingerprint
533
+ ```markdown
534
+ ## Goal
535
+ ## Constraints & Preferences
536
+ ## Progress
537
+ ### Done
538
+ ### In Progress
539
+ ### Blocked
540
+ ## Key Decisions
541
+ ## Files Modified
542
+ ## Files Read
543
+ ## Open Loops
544
+ ## Changes Since Last Compaction
545
+ ## Next Steps
546
+ ## Critical Context
547
+ ## Topics Covered
548
+ ```
216
549
 
217
- Cross-session learning stored at `~/.pi/agent/.cache/smart-compact/projects/`:
550
+ The extension also builds a structured `CompactionState` object containing:
218
551
 
219
- | Field | How it's detected |
220
- |-------|-------------------|
221
- | Language | Most common file extension (.ts → typescript, .rs → rust, etc.) |
222
- | Framework | Config file patterns (next.config → nextjs, vite.config → vite, etc.) |
223
- | Key directories | Most frequently modified directory paths |
224
- | Known files | Last 50 unique files across sessions |
225
- | Session count | Incremented each compaction |
552
+ - goal
553
+ - decisions
554
+ - constraints
555
+ - modified/read/deleted files
556
+ - unresolved/resolved errors
557
+ - open loops
558
+ - topics
559
+ - next actions
560
+ - critical context
561
+ - session type
562
+ - compaction version
226
563
 
227
- 30-day TTL. Loaded before Phase 1 and injected into the synthesis prompt as project context.
564
+ This state is persisted on disk and reused for delta tracking on later compactions.
228
565
 
229
- ### Damage Detection
566
+ ---
230
567
 
231
- After compaction, monitors the next 15 messages for regression signals:
568
+ ## Quality controls
232
569
 
233
- | Signal | Severity | Detection |
234
- |--------|----------|-----------|
235
- | Agent re-reads compacted file | Medium | Tool call `read` with path from compacted section |
236
- | User complaint | High | Regex: "I already told you", "you forgot", "nerede kaldı" |
237
- | Re-question | Low | User mentions compacted decision topic |
570
+ The current codebase includes these safeguards:
238
571
 
239
- Logged to `~/.pi/agent/.cache/smart-compact/damage-reports.jsonl` for future analysis.
572
+ - deterministic extraction before any summarization
573
+ - adaptive exploration skip for simple sessions
574
+ - project fingerprint reuse across sessions
575
+ - incremental extraction cache
576
+ - provider-aware token estimation and concurrency
577
+ - deterministic verification scoring
578
+ - deterministic patch before LLM patch
579
+ - hallucinated file-reference detection
580
+ - open-loop injection
581
+ - cross-compaction delta injection
582
+ - post-compaction damage detection
583
+ - backup creation before compaction
584
+ - metrics logging for LLM cost/latency/cache usage
240
585
 
241
- ### Token Estimation
586
+ ---
242
587
 
243
- - **Provider-specific ratios** (OpenAI: 4.0, Anthropic: 3.5, MiniMax: 3.8)
244
- - **JSON penalty** (0.85x) — JSON.stringify'd content has denser tokenization
245
- - **Language penalty** (0.9x) — Turkish/CE characters tokenize differently
246
- - **Per-provider EMA calibration** — learns from actual API responses, scoped per provider
588
+ ## Current caveats
247
589
 
248
- ### Provider Concurrency
590
+ To keep this README aligned with the repository's **actual** current state:
249
591
 
250
- | Provider | Concurrency Limit | Cache Strategy |
251
- |----------|-------------------|----------------|
252
- | OpenAI | 5 | prompt caching |
253
- | Anthropic (zai) | 3 | anthropic caching |
254
- | MiniMax | 2 | anthropic caching |
255
- | Xiaomi | 2 | openai caching |
256
- | Default | 2 | none |
592
+ 1. **`bun run typecheck` is currently failing.** The repo builds with Bun and passes tests, but strict TypeScript compatibility is not clean right now.
593
+ 2. **One legacy test filename remains:** `test/semantic-compact.test.ts`.
594
+ 3. **The package is published from `dist/`, not directly from `src/`.** Source and tests are not included in the package tarball.
595
+ 4. **The extension depends on Pi runtime APIs and peer packages** (`@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-tui`, `typebox`).
257
596
 
258
597
  ---
259
598
 
260
- ## Summary Format
261
-
262
- Smart Compact produces structured markdown:
263
-
264
- ```markdown
265
- ## Goal
266
- [What the user is trying to accomplish]
599
+ ## Development
267
600
 
268
- ## Constraints & Preferences
269
- - [requirement] Must use TypeScript strict mode
270
- - [preference] Prefer functional components
601
+ ### Install
271
602
 
272
- ## Progress
273
- ### Done
274
- - [x] Auth module implemented (src/auth.ts)
275
- ### In Progress
276
- - [ ] Database migration
277
- ### Blocked
278
- - Waiting for API credentials
603
+ ```bash
604
+ bun install
605
+ ```
279
606
 
280
- ## Key Decisions
281
- - **Use JWT for auth**: User confirmed over session cookies
607
+ ### Test
282
608
 
283
- ## Files Modified
284
- - src/auth.ts
285
- - src/db/migrations/001.sql
609
+ ```bash
610
+ bun test
611
+ bun test test/eval.test.ts
612
+ ```
286
613
 
287
- ## Files Read
288
- - src/config.ts
289
- - package.json
614
+ ### Build
290
615
 
291
- ## Next Steps
292
- 1. Complete database migration
293
- 2. Add integration tests
616
+ ```bash
617
+ bun run build
618
+ ```
294
619
 
295
- ## Critical Context
296
- - Unresolved error: test failed in auth.ts line 42
297
- - API base URL: https://api.example.com/v2
620
+ Current build command:
298
621
 
299
- ## Topics Covered
300
- - **Auth implementation** [high]
301
- - **DB schema design** [normal]
302
- - **Config review** [low]
622
+ ```bash
623
+ rm -rf dist && mkdir dist && bun build ./src/index.ts --outdir ./dist --target bun --external '@earendil-works/*' --external 'typebox'
303
624
  ```
304
625
 
305
- ---
306
-
307
- ## Development
626
+ ### Typecheck
308
627
 
309
628
  ```bash
310
- bun install
311
- bun test # 56 tests across 7 files
312
- bun run typecheck # TypeScript check
629
+ bun run typecheck
313
630
  ```
314
631
 
315
- ---
632
+ At the moment, this command is expected to report errors.
316
633
 
317
- ## Contributing
634
+ ### Typical local path inside Pi
318
635
 
319
- 1. Fork the repo
320
- 2. Create your branch (`git checkout -b feat/amazing-feature`)
321
- 3. Commit (`git commit -am 'Add amazing feature'`)
322
- 4. Push (`git push origin feat/amazing-feature`)
323
- 5. Open a Pull Request
636
+ ```text
637
+ ~/.pi/agent/extensions/pi-smart-compact
638
+ ```
324
639
 
325
640
  ---
326
641