@pi-unipi/unipi 3.0.0-alpha.3 → 3.0.0-alpha.4

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 (95) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +3 -3
  3. package/package.json +22 -22
  4. package/packages/ask-user/package.json +2 -2
  5. package/packages/autocomplete/package.json +1 -1
  6. package/packages/autocomplete/src/constants.ts +10 -4
  7. package/packages/background-tasks/package.json +2 -2
  8. package/packages/btw/package.json +2 -2
  9. package/packages/compactor/README.md +59 -286
  10. package/packages/compactor/package.json +5 -9
  11. package/packages/compactor/skills/compactor/SKILL.md +13 -20
  12. package/packages/compactor/src/card.ts +95 -0
  13. package/packages/compactor/src/commands/index.ts +85 -124
  14. package/packages/compactor/src/compaction/compact-args.ts +5 -3
  15. package/packages/compactor/src/compaction/filter-noise.ts +1 -1
  16. package/packages/compactor/src/compaction/hooks.ts +533 -312
  17. package/packages/compactor/src/compaction/jev-prune.ts +114 -0
  18. package/packages/compactor/src/compaction/source.ts +159 -0
  19. package/packages/compactor/src/compaction/summarize.ts +704 -52
  20. package/packages/compactor/src/config/manager.ts +127 -127
  21. package/packages/compactor/src/config/schema.ts +32 -48
  22. package/packages/compactor/src/index.ts +40 -431
  23. package/packages/compactor/src/info-screen.ts +44 -190
  24. package/packages/compactor/src/session/recall-blocks.ts +1 -1
  25. package/packages/compactor/src/stats.ts +76 -0
  26. package/packages/compactor/src/tools/context-budget.ts +17 -34
  27. package/packages/compactor/src/tools/ctx-doctor.ts +45 -36
  28. package/packages/compactor/src/tools/register.ts +29 -269
  29. package/packages/compactor/src/types.ts +48 -186
  30. package/packages/core/compaction-context.ts +41 -0
  31. package/packages/core/constants.ts +7 -7
  32. package/packages/core/index.ts +1 -0
  33. package/packages/core/package.json +1 -1
  34. package/packages/core/src/jev/settings.ts +177 -14
  35. package/packages/footer/README.md +4 -6
  36. package/packages/footer/package.json +3 -3
  37. package/packages/footer/src/help.ts +1 -1
  38. package/packages/footer/src/index.ts +33 -2
  39. package/packages/footer/src/presets.ts +3 -4
  40. package/packages/footer/src/rendering/icons.ts +0 -20
  41. package/packages/footer/src/segments/compactor.ts +52 -142
  42. package/packages/footer/src/segments/status-ext.ts +0 -1
  43. package/packages/fusion/package.json +3 -3
  44. package/packages/image/package.json +2 -2
  45. package/packages/info-screen/package.json +2 -2
  46. package/packages/input-shortcuts/package.json +2 -2
  47. package/packages/kanboard/package.json +7 -7
  48. package/packages/kanboard/src/runner.ts +31 -2
  49. package/packages/kanboard/src/settings.ts +3 -2
  50. package/packages/long-horizon/index.ts +6 -1
  51. package/packages/long-horizon/package.json +2 -2
  52. package/packages/long-horizon/src/compaction-brief.ts +35 -0
  53. package/packages/long-horizon/src/runtime.ts +6 -1
  54. package/packages/long-horizon/src/settings.ts +22 -37
  55. package/packages/mcp/package.json +2 -2
  56. package/packages/memory/index.ts +4 -0
  57. package/packages/memory/package.json +3 -3
  58. package/packages/notify/package.json +2 -2
  59. package/packages/skill-registry/package.json +1 -1
  60. package/packages/subagents/package.json +2 -2
  61. package/packages/unipi/bundled.js +3645 -5133
  62. package/packages/updater/package.json +2 -2
  63. package/packages/utility/package.json +2 -2
  64. package/packages/utility/src/settings.ts +3 -2
  65. package/packages/utility/src/skill-discovery.ts +2 -2
  66. package/packages/watchdog/index.ts +2 -2
  67. package/packages/watchdog/package.json +3 -3
  68. package/packages/watchdog/src/config.ts +3 -2
  69. package/packages/web-api/package.json +2 -2
  70. package/packages/workflow/package.json +2 -2
  71. package/packages/workflow/src/permission/index.ts +2 -2
  72. package/packages/workflow/src/permission/settings.ts +4 -1
  73. package/packages/compactor/skills/compactor-detail/SKILL.md +0 -116
  74. package/packages/compactor/skills/compactor-doctor/SKILL.md +0 -71
  75. package/packages/compactor/skills/compactor-stats/SKILL.md +0 -51
  76. package/packages/compactor/src/compaction/build-sections.ts +0 -76
  77. package/packages/compactor/src/compaction/extract/goals.ts +0 -36
  78. package/packages/compactor/src/compaction/extract/preferences.ts +0 -40
  79. package/packages/compactor/src/compaction/format.ts +0 -53
  80. package/packages/compactor/src/compaction/merge.ts +0 -143
  81. package/packages/compactor/src/config/presets.ts +0 -160
  82. package/packages/compactor/src/executor/executor.ts +0 -233
  83. package/packages/compactor/src/executor/runtime.ts +0 -115
  84. package/packages/compactor/src/security/evaluator.ts +0 -89
  85. package/packages/compactor/src/security/policy.ts +0 -96
  86. package/packages/compactor/src/security/scanner.ts +0 -65
  87. package/packages/compactor/src/session/auto-inject.ts +0 -60
  88. package/packages/compactor/src/session/db.ts +0 -325
  89. package/packages/compactor/src/session/extract.ts +0 -144
  90. package/packages/compactor/src/session/resume-inject.ts +0 -64
  91. package/packages/compactor/src/session/snapshot.ts +0 -327
  92. package/packages/compactor/src/tools/ctx-batch-execute.ts +0 -41
  93. package/packages/compactor/src/tools/ctx-execute-file.ts +0 -23
  94. package/packages/compactor/src/tools/ctx-execute.ts +0 -23
  95. package/packages/compactor/src/tools/ctx-stats.ts +0 -96
package/CHANGELOG.md CHANGED
@@ -6,6 +6,39 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.0.0-alpha.4] — 2026-09-28
10
+
11
+ ### Breaking Changes
12
+
13
+ - **BREAKING: compactor reworked.** Session continuity (the SQLite event log and the snapshot restored after compaction) is removed: it logged every session under one shared ID, so restored snapshots mixed projects and reached ~60k tokens. Also removed: the sandbox tools (`sandbox`, `sandbox_file`, `sandbox_batch`), the `compact` tool (it never compacted), the `compactor_stats`/`compactor_doctor` tools, presets, and the strategy modes that had no effect. **Migration path:** `/unipi:compact` and `/unipi:lossless-compact` still work but are deprecated. Use `/unipi:compact-vcc`, `/unipi:compact-jev` or `/unipi:compact-by-llm`. Old configs are translated: `overrideDefaultCompaction: false` becomes Method = model summary, and `autoCompaction.enabled` becomes When = at a percentage. `~/.unipi/db/compactor` is no longer used and can be deleted.
14
+
15
+ ### Added
16
+
17
+ - `compactor`: the lossless summary is rebuilt from the full session history on every compaction, so it can no longer grow from one compaction to the next (a real session went 15k → 236k → 248k characters). It puts the current state first: Active Work, Your Requests, Latest State, Decisions & Constraints, Files, Commits, Open Errors, Recent Transcript. Each section has a hard budget.
18
+ - Text that extensions inject with the user role (loop prompts, nudges, notifications) is recognised and left out of Your Requests; extension-sent messages are also marked when they are sent.
19
+ - `ask_user` answers are kept as "question → answer" decisions.
20
+ - Typed credentials are redacted.
21
+ - `compactor`: **lossless + jev** method (`/unipi:compact-jev`). jev, the Decision model, drops items that are no longer in force, such as finished one-off requests, reversed decisions and fixed errors, at per-kind confidence thresholds. If jev is unavailable, the plain lossless summary is used.
22
+ - `compactor`: the settings screen shows 5 main settings (Method, Pi's /compact, When, Percentage, Notifications); everything else is under **Advanced compaction**.
23
+ - `core`: `registerCompactionContext()`. long-horizon (goal, ralph) and kanboard register their live state, and every compaction summary leads with it.
24
+ - `scripts/compactor-eval.mts` replays the compactor at real compaction points of recorded sessions and shows what happened next, for review. `scripts/compactor-continue.mts` writes resumable A/B session files (old vs new compaction) for a blind "continue from here" test with `pi --fork … -nt -p`.
25
+ - **Decision Model settings** (`/unipi:settings → Decision Model`): the jev provider, model, base URL, key and timeout now live in one shared `decision-model` namespace instead of long-horizon's judge. Every module that uses it (long-horizon routing, permission auto mode, skill exposure, watchdog, kanboard strategy, compactor pruning) has a **Decision model** block that inherits the shared model by default or switches to a custom one; empty custom fields fall back to the shared value. Existing `long-horizon.judge.*` transport settings are migrated once.
26
+ - `compactor`: user corrections ("restore the background… I did not request this change") are kept as decisions.
27
+ - `compactor`: **Lessons** section: lessons the agent wrote down itself (memory notes, `# Confirmed: …` comments in its commands, diagnosis sentences), kept verbatim. **Project Knowledge** section: notes it wrote or read, repeated build/test/deploy commands, hosts. Decisions keep early standing rules ("always…", "never…") instead of only the most recent ones.
28
+ - `compactor`: jev asks short, local questions it can answer precisely: "durable lesson or one-off note?" and "does this later item replace that earlier one?" on items about the same subject. A reversal in the recent messages removes the stale lesson it replaces.
29
+ - `compactor`: **compaction card** in the transcript under Pi's `[compaction]` block: one line (`Compacted 7.9k → 2.2k tokens · lossless + jev · 1 stale dropped · at 3%`), ctrl+o for method, trigger, kept tail, sections and jev drops. Never sent to the model; replaces the compaction toasts.
30
+ - `footer`: the stats strip under the input shows `5 compactions · 47k→15k · just now` once the session has compacted. The five compactor segments are now one icon-free `compactions` segment.
31
+ - `compactor`: the info-screen Compactor tab shows the method and trigger settings, compactions by method, tokens before → after, and the last compaction.
32
+
33
+ ### Fixed
34
+
35
+ - `compactor`: the percentage trigger compacts at the `turn_end` boundary instead of calling `ctx.compact()`, which aborted the run and left goal, ralph and kanboard loops waiting. The "auto-continue" message is removed; Pi 0.87 continues after automatic compaction on its own, so it only added empty extra turns.
36
+ - `compactor`: stats come from the session's own compaction entries instead of a fixed "12% kept" guess (also in the footer segments).
37
+ - `compactor`: the kept tail is sized to the model's context window (recut above 40%, `keep:N` included) and the summary is capped at 8% of it, so compaction can no longer overflow small-context models.
38
+ - `compactor`: secrets are redacted before summary items are clipped (a clipped quote could leak a password).
39
+ - `compactor`: `/unipi:compact-doctor` no longer calls the jev method "model summary"; `/unipi:compact-stats` counts jev separately; a manual compaction with nothing to compact no longer repeats Pi's error.
40
+ - `kanboard` tests wrote a fake judge key (`"k"`) into the real `~/.unipi/config/long-horizon/config.json`, which silently disabled the jev judge. They now use project scope.
41
+
9
42
  ## [3.0.0-alpha.3] — 2026-09-27
10
43
 
11
44
  ### Breaking Changes
package/README.md CHANGED
@@ -21,7 +21,7 @@ pi install npm:@pi-unipi/unipi
21
21
 
22
22
  **[Memory](./packages/memory/README.md)** — Markdown files + [MemPalace](https://github.com/mempalace/mempalace) semantic search share a memory palace across pi, Devin, and zcode. Facts, preferences, and decisions persist across sessions; v2 data converts via `/unipi:memory migrate`.
23
23
 
24
- **[Compactor](./packages/compactor/README.md)** — Zero-LLM context engine. 6-stage pipeline hits 95%+ token reduction at zero API cost. Session continuity, percentage auto-compaction, session recall, and sandbox execution.
24
+ **[Compactor](./packages/compactor/README.md)** — Compaction that keeps work going. Lossless zero-LLM summaries (or Pi's model summary), rebuilt from the full session history, led by the live goal/ralph/kanboard state; the full history stays searchable with session recall.
25
25
 
26
26
  **[Prefix-cache architecture](./docs/prefix-cache-architecture.md)** — Append-only request discipline, explicit cache epochs, deterministic tools, privacy-safe diagnostics, provider limitations, and bounded cold-epoch output.
27
27
 
@@ -92,7 +92,7 @@ Coexists triggers enhance behavior when packages are installed together. Workflo
92
92
  | Kanboard | `/unipi:` | kanboard (board: capture, work runner, web UI) |
93
93
  | Long-Horizon | `/unipi:goal`, `/unipi:ralph`, `/unipi:swarm`, `/unipi:graph` | <prompt>, start, stop, status, resume, clear |
94
94
  | Memory | `/unipi:memory-` | process, search, consolidate, forget |
95
- | Compactor | `/unipi:` | lossless-compact, session-recall, compact-stats, compact-preset, compact-help |
95
+ | Compactor | `/unipi:` | compact-vcc, compact-by-llm, session-recall, compact-stats, compact-doctor, compact-help |
96
96
  | Notify | `/unipi:notify-` | settings, test, set-tg, set-ntfy |
97
97
  | MCP | `/unipi:mcp-` | add, settings, sync, status |
98
98
  | Web | `/unipi:web-` | settings, cache-clear |
@@ -121,7 +121,7 @@ Coexists triggers enhance behavior when packages are installed together. Workflo
121
121
  | `sidekick` / `read_subagent` | fusion | Delegate to the persistent sidekick and collect its report |
122
122
  | `bg_run` / `bg_status` / `bg_logs` / `bg_kill` / `bg_delegate` / `bg_result` | background-tasks | Long-running commands and background delegate agents |
123
123
  | `ask_user` | ask-user | User input |
124
- | `compact` / `session_recall` / `sandbox` | compactor | Context management |
124
+ | `session_recall` / `context_budget` | compactor | Context management |
125
125
  | `ctx_env` | utility | Environment info |
126
126
  | `set_session_name` | utility | Session name for badge |
127
127
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/unipi",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0-alpha.4",
4
4
  "description": "All-in-one extension suite for Pi coding agent",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -84,27 +84,27 @@
84
84
  "typebox": "^1.1.38"
85
85
  },
86
86
  "dependencies": {
87
- "@pi-unipi/ask-user": "3.0.0-alpha.3",
88
- "@pi-unipi/background-tasks": "3.0.0-alpha.3",
89
- "@pi-unipi/btw": "3.0.0-alpha.3",
90
- "@pi-unipi/command-enchantment": "3.0.0-alpha.3",
91
- "@pi-unipi/compactor": "3.0.0-alpha.3",
92
- "@pi-unipi/core": "3.0.0-alpha.3",
93
- "@pi-unipi/footer": "3.0.0-alpha.3",
94
- "@pi-unipi/image": "3.0.0-alpha.3",
95
- "@pi-unipi/fusion": "3.0.0-alpha.3",
96
- "@pi-unipi/info-screen": "3.0.0-alpha.3",
97
- "@pi-unipi/input-shortcuts": "3.0.0-alpha.3",
98
- "@pi-unipi/kanboard": "3.0.0-alpha.3",
99
- "@pi-unipi/mcp": "3.0.0-alpha.3",
100
- "@pi-unipi/memory": "3.0.0-alpha.3",
101
- "@pi-unipi/notify": "3.0.0-alpha.3",
102
- "@pi-unipi/skill-registry": "3.0.0-alpha.3",
103
- "@pi-unipi/subagents": "3.0.0-alpha.3",
104
- "@pi-unipi/updater": "3.0.0-alpha.3",
105
- "@pi-unipi/utility": "3.0.0-alpha.3",
106
- "@pi-unipi/web-api": "3.0.0-alpha.3",
107
- "@pi-unipi/workflow": "3.0.0-alpha.3"
87
+ "@pi-unipi/ask-user": "3.0.0-alpha.4",
88
+ "@pi-unipi/background-tasks": "3.0.0-alpha.4",
89
+ "@pi-unipi/btw": "3.0.0-alpha.4",
90
+ "@pi-unipi/command-enchantment": "3.0.0-alpha.4",
91
+ "@pi-unipi/compactor": "3.0.0-alpha.4",
92
+ "@pi-unipi/core": "3.0.0-alpha.4",
93
+ "@pi-unipi/footer": "3.0.0-alpha.4",
94
+ "@pi-unipi/image": "3.0.0-alpha.4",
95
+ "@pi-unipi/fusion": "3.0.0-alpha.4",
96
+ "@pi-unipi/info-screen": "3.0.0-alpha.4",
97
+ "@pi-unipi/input-shortcuts": "3.0.0-alpha.4",
98
+ "@pi-unipi/kanboard": "3.0.0-alpha.4",
99
+ "@pi-unipi/mcp": "3.0.0-alpha.4",
100
+ "@pi-unipi/memory": "3.0.0-alpha.4",
101
+ "@pi-unipi/notify": "3.0.0-alpha.4",
102
+ "@pi-unipi/skill-registry": "3.0.0-alpha.4",
103
+ "@pi-unipi/subagents": "3.0.0-alpha.4",
104
+ "@pi-unipi/updater": "3.0.0-alpha.4",
105
+ "@pi-unipi/utility": "3.0.0-alpha.4",
106
+ "@pi-unipi/web-api": "3.0.0-alpha.4",
107
+ "@pi-unipi/workflow": "3.0.0-alpha.4"
108
108
  },
109
109
  "devDependencies": {
110
110
  "@earendil-works/pi-agent-core": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/ask-user",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0-alpha.4",
4
4
  "description": "Structured user input tool for Pi coding agent — single-select, multi-select, freeform",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@pi-unipi/core": "3.0.0-alpha.3"
43
+ "@pi-unipi/core": "3.0.0-alpha.4"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/command-enchantment",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0-alpha.4",
4
4
  "description": "Enhanced TUI autocomplete for /unipi:* commands — colored, sorted, and grouped by package",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -97,6 +97,9 @@ export const COMMAND_REGISTRY: Record<string, string> = {
97
97
  // web-api (2 commands)
98
98
 
99
99
  // compact (9 commands)
100
+ "unipi:compact-vcc": "compact",
101
+ "unipi:compact-jev": "compact",
102
+ "unipi:compact-by-llm": "compact",
100
103
  "unipi:lossless-compact": "compact",
101
104
  "unipi:compact": "compact",
102
105
  "unipi:session-recall": "compact",
@@ -169,12 +172,15 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
169
172
  "unipi:info": "Show system information",
170
173
 
171
174
 
172
- "unipi:lossless-compact": "Immediate zero-LLM compaction",
173
- "unipi:compact": "(DEPRECATED) Use /unipi:lossless-compact instead",
175
+ "unipi:compact-vcc": "Lossless compaction now — no model call (keep:N)",
176
+ "unipi:compact-jev": "Lossless compaction, pruned by jev of what is no longer in force",
177
+ "unipi:compact-by-llm": "Compact now with a model-written summary",
178
+ "unipi:lossless-compact": "(DEPRECATED) Use /unipi:compact-vcc instead",
179
+ "unipi:compact": "(DEPRECATED) Use /unipi:compact-vcc instead",
174
180
  "unipi:session-recall": "Search session history, including compacted-away messages",
175
181
  "unipi:compact-recall": "(DEPRECATED) Use /unipi:session-recall instead",
176
- "unipi:compact-stats": "Show compaction statistics",
177
- "unipi:compact-doctor": "Diagnose compaction issues",
182
+ "unipi:compact-stats": "Show this session's compaction savings",
183
+ "unipi:compact-doctor": "Check compaction settings",
178
184
  "unipi:compact-help": "Show compactor command help",
179
185
  "unipi:notify-event": "Toggle a notify event without the TUI: <event> <on|off>",
180
186
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/background-tasks",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0-alpha.4",
4
4
  "description": "Background tasks for UniPi — durable shell jobs and delegated background agents with a footer dock",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@earendil-works/pi-ai": "^0.87.1",
13
- "@pi-unipi/core": "3.0.0-alpha.3",
13
+ "@pi-unipi/core": "3.0.0-alpha.4",
14
14
  "turndown": "^7.2.4"
15
15
  },
16
16
  "devDependencies": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/btw",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0-alpha.4",
4
4
  "description": "A pi extension for parallel side conversations with /unipi:btw — part of the Unipi suite",
5
5
  "type": "module",
6
6
  "main": "extensions/btw.ts",
@@ -37,7 +37,7 @@
37
37
  "@earendil-works/pi-tui": "^0.87.1"
38
38
  },
39
39
  "dependencies": {
40
- "@pi-unipi/core": "3.0.0-alpha.3"
40
+ "@pi-unipi/core": "3.0.0-alpha.4"
41
41
  },
42
42
  "pi": {
43
43
  "extensions": [
@@ -1,318 +1,91 @@
1
1
  # @pi-unipi/compactor
2
2
 
3
- Deterministic context management for Pi/UniPi. The compactor keeps long coding sessions usable by replacing large conversation history with a structured, zero-LLM summary, while preserving session recall, continuity snapshots, stats, sandbox helpers, and safer tool display.
3
+ Compaction for Pi that keeps work going. When the context fills up, the compactor replaces older messages with a summary. The full history stays in the session file, so nothing is lost and anything can be recalled.
4
4
 
5
- ## What it does
5
+ ## Methods
6
6
 
7
- - **Zero-LLM compaction:** Pi asks for compaction; UniPi builds the summary locally instead of spending model tokens on a summarization call.
8
- - **Session continuity:** important goals, changed files, commits, blockers, preferences, and a recent transcript survive compaction.
9
- - **Optional percentage trigger:** UniPi can compact at a configured context percentage before Pi's fixed reserve-token safety net fires.
10
- - **Recall:** agents can search the append-only session branch, including messages that no longer fit in live LLM context.
11
- - **Runtime helpers:** sandbox execution, context budget checks, diagnostics, and stats.
12
- - **Display guards:** tool output/diff rendering is clamped and summarized to avoid noisy or terminal-breaking output.
13
-
14
- The compaction pipeline is deterministic and runs locally. It does not call an LLM during compaction.
15
-
16
- ---
17
-
18
- ## Quick start
19
-
20
- ```text
21
- /unipi:settings (Compactor)
22
- ```
23
-
24
- 1. Choose a preset in **Presets**.
25
- 2. Optionally enable **Auto → Percentage Trigger**.
26
- 3. Press **Enter** to save.
27
- 4. Use `/unipi:lossless-compact` when you want to compact immediately.
28
-
29
- Config files:
30
-
31
- | Scope | Path | Notes |
32
- |---|---|---|
33
- | Global | `~/.unipi/config/compactor/config.json` | Used by default |
34
- | Per project | `<project>/.unipi/config/compactor.json` | Enabled from settings with **Project Override** |
35
-
36
- Per-project config is merged over global config when the current project directory is known.
37
-
38
- ---
39
-
40
- ## User-facing slash commands
41
-
42
- | Command | What it does | Notes |
7
+ | Method | What it does | Cost |
43
8
  |---|---|---|
44
- | `/unipi:lossless-compact` | Immediately calls Pi compaction with UniPi's zero-LLM sentinel. | Main manual compaction command. |
45
- | `/unipi:compact` | Deprecated alias for `/unipi:lossless-compact`. | Kept for backward compatibility. |
46
- | `/unipi:session-recall <query>` | Searches current session history with BM25/regex recall. | Uses the append-only session branch when available, so pre-compaction messages can still be found. |
47
- | `/unipi:compact-recall <query>` | Deprecated alias for `/unipi:session-recall`. | Kept for backward compatibility. |
48
- | `/unipi:compact-stats` | Shows session events, compaction count, token savings, sandbox runs, and search counts. | Stats are DB-backed with runtime fallbacks. |
49
- | `/unipi:compact-doctor` | Runs diagnostics for config, SQLite/session DB, and runtimes. | Useful when stats/recall/sandbox look broken. |
50
- | `/unipi:settings (Compactor)` | Opens the TUI settings overlay. | Tabs: Presets, Strategies, Auto, Pipeline. |
51
- | `/unipi:settings (Compactor › Presets) <name>` | Applies a preset globally. | Names: `precise`, `balanced`, `thorough`, `lean`. Old names map to new ones: `opencode→precise`, `verbose→thorough`, `minimal→lean`. |
52
- | `/unipi:compact-help` | Shows compact help inside Pi. | Quick command reference. |
9
+ | **Lossless** (default) | Builds a structured summary without a model call, in milliseconds. | Free |
10
+ | **Lossless + jev** | The lossless summary, then jev (the Decision model, TypeSafe jev) drops items no longer in force: completed one-off requests, reversed decisions, fixed errors, an outdated report. Their room goes to other items. | ~0.5–2 s, fractions of a cent |
11
+ | **Model summary** | Pi's own model-written summary, with the active-work block added on top. | One model call |
53
12
 
54
- Content/project indexing is not part of this package. Use `read`/`bash` (rg) for project search.
13
+ jev only drops what it is confident about: decisions (including your answers to agent questions) need ≥92% certainty, one-off requests ≥80%, errors ≥75%. Your first and latest requests are never dropped. With no jev key or on timeout it falls back to the plain lossless summary. It uses the shared Decision Model (`/unipi:settings → Decision Model`); `Compactor → jev pruning — Decision model` can switch it to a custom one for the compactor only.
55
14
 
56
- ---
15
+ ### The lossless summary
57
16
 
58
- ## User-facing settings
17
+ It is rebuilt from the **full** session history on every compaction, never merged onto the previous summary, so it cannot drift or grow over time. Sections, in the order a resuming model needs them:
59
18
 
60
- Open settings with `/unipi:settings (Compactor)`.
19
+ 1. **Active Work**: the goal, ralph loop or kanboard task in flight, supplied by those modules from their own state.
20
+ 2. **Your Requests**: the user's own messages and answers to agent questions (`ask_user`: "question → answer"). Text that extensions send with the user role (loop prompts, nudges, notifications) is excluded.
21
+ 3. **Latest State**: the most recent step and the last full progress report.
22
+ 4. **Decisions & Constraints**: the user's instructions ("keep the orange theme"), corrections ("I did not ask for this"), and answers to agent questions. Half the room goes to the most recent ones, the rest to standing rules from anywhere in the session ("always…", "never…", "by default…"). Bug reports, pasted text and code blocks are left out.
23
+ 5. **Files**: modified, created and read files, as relative paths.
24
+ 6. **Project Knowledge**: what the agent learned that no message states: project notes it wrote or read (SKILL.md, AGENTS.md, DESIGN.md, docs), build/test/deploy commands it ran more than once, and the hosts it worked against. Switched with the Files section.
25
+ 7. **Commits**: hash and subject.
26
+ 8. **Open Errors**: recent failures that were not followed by a success.
27
+ 9. **Recent Transcript**: a ranked slice of recent work.
61
28
 
62
- Keyboard:
29
+ Each section has its own share of a hard budget (auto: 1.5k–4k tokens, scaling with session size). Credentials (typed passwords, API keys, bearer tokens) are redacted before anything is clipped; `session_recall` still has them. A closing line points the model to `session_recall`.
63
30
 
64
- | Key | Action |
65
- |---|---|
66
- | `Tab` | Switch tabs |
67
- | `↑/↓` | Move selection |
68
- | `Space` | Cycle/toggle selected value |
69
- | `/` | Search inside the Strategies tab |
70
- | `Enter` | Save and close |
71
- | `Esc` | Cancel |
31
+ ## In the TUI
72
32
 
73
- ### Presets tab
33
+ - **Compaction card:** one line under Pi's own `[compaction]` block, e.g. `▌ Compacted 7.9k → 2.2k tokens · lossless + jev · 1 stale dropped · at 3%`. ctrl+o expands it: method, trigger, what was kept verbatim, summary sections, what jev dropped. It is a custom entry: shown, never sent to the model.
34
+ - **Footer strip** (under the input): `5 compactions · 47k→15k · just now`, hidden until the first compaction. With the glance frame off, the `compactions` segment shows the same (`cmp 5× 47k→15k · 1m`).
35
+ - **Info screen** (`/unipi:info` → Compactor): method and trigger settings, compactions by method, tokens before → after, the last compaction.
74
36
 
75
- Presets are profiles that set strategies, the implemented Auto Injection pipeline behavior, and sandbox mode.
37
+ ## When it compacts
76
38
 
77
- | Preset | Intended use | Important effects |
78
- |---|---|---|
79
- | `precise` | Code-heavy work, minimal waste | Full compaction sections, sandbox enabled, Auto Injection off. |
80
- | `balanced` | Daily/default profile | Compact transcript, sandbox enabled, Auto Injection on. |
81
- | `thorough` | Debug/audit sessions | Full transcript, sandbox enabled, Auto Injection on. |
82
- | `lean` | Quick fixes or short sessions | Brief/minimal compaction sections, no sandbox, no session continuity, Auto Injection off. |
83
-
84
- The **Project Override** row controls where settings are saved:
39
+ - **Pi's context limit** (default): Pi decides when, using its own compaction settings (`compaction.reserveTokens`, per-model overrides). The compactor decides what the summary contains. Pi continues the run after compacting.
40
+ - **At a percentage**: compacts once context use reaches the set percentage. This happens at a turn boundary, so running goal, ralph and kanboard loops are not interrupted.
85
41
 
86
- - `disabled` → save global config.
87
- - `enabled` → save `<project>/.unipi/config/compactor.json` for only this project.
42
+ ## Settings
88
43
 
89
- ### Strategies tab
44
+ `/unipi:settings → Compactor`
90
45
 
91
- These settings control what is extracted into compaction summaries or how related compactor features behave.
92
-
93
- | Setting | Values | Meaning |
46
+ | Setting | Default | |
94
47
  |---|---|---|
95
- | `Verbose Debug` | `on`, `off` | Enables internal debug state. Console debug output is intentionally muted to avoid TUI rendering issues. |
96
- | `Session Goals` | `full`, `brief`, `off` | Extracts the user's active goals/request history into `[Session Goal]`. |
97
- | `Files & Changes` | `all`, `modified-only`, `off` | Tracks read, created, edited, and written files in `[Files And Changes]`. |
98
- | `Commits` | `full`, `brief`, `off` | Captures git commit hashes/messages detected in the conversation. |
99
- | `Outstanding Context` | `full`, `critical-only`, `off` | Keeps blockers, TODOs, pending decisions, and follow-ups. |
100
- | `User Preferences` | `all`, `recent-only`, `off` | Preserves user preferences learned during the session. |
101
- | `Brief Transcript` | `full`, `compact`, `minimal`, `off` | Keeps a rolling recent transcript after the structured sections. |
102
- | `Session Continuity` | `full`, `off` | Controls XML-style resume snapshots. Off prevents snapshot creation and injection; Pi’s normal compaction summary still remains. |
103
- | `Sandbox Execution` | `all`, `off` | Controls sandbox tool registration. Changes require a session reload. Allowed languages and output limit are enforced from config. |
104
-
105
- Config-only legacy field: `fts5Index` remains in the schema for compatibility. It is hidden from Compactor settings and presets. Legacy `sessionContinuity.mode: "essential-only"`, `eventCategories`, and `sandboxExecution.mode: "safe-only"` values remain loadable; essential-only behaves as full and safe-only behaves as enabled/all until explicit filtering/security policies are designed. Legacy `toolDisplay` and `showTruncationHints` fields also remain loadable but are deprecated and ignored; their profile names were never mapped to runtime renderer modes. Narrow-terminal diff clamping remains active as independent safety behavior.
48
+ | Method | lossless | lossless · lossless + jev · model summary |
49
+ | Pi's /compact | same as Method | What Pi's built-in `/compact` does |
50
+ | When | Pi's context limit | Or: at a percentage |
51
+ | Percentage | 80 | Used when When = at a percentage |
52
+ | Notifications | on | The compaction card after automatic compactions (commands always show it); failures still notify |
106
53
 
107
- ### Auto tab
54
+ **Advanced compaction** (collapsed): smart keep tail, summary budget, per-section toggles, percentage cooldown and repeat growth, extra instructions for model summaries, debug output.
108
55
 
109
- These settings control UniPi-managed percentage auto-compaction. They are separate from Pi core's own `compaction.reserveTokens` behavior.
56
+ Configs from before the rework are translated automatically: `overrideDefaultCompaction: false` becomes Method = model summary, and `autoCompaction.enabled` becomes When = at a percentage.
110
57
 
111
- **Prefix-cache policy:** every compaction replaces provider-visible history and starts a new cache epoch. UniPi therefore keeps this second percentage trigger **off by default** and does not compact repeatedly merely to shorten a cache-hit request. Pi core remains the default safety trigger: with its documented defaults it compacts when estimated context exceeds `contextWindow - 16,384` reserved response tokens, while keeping about 20,000 recent tokens. If you deliberately enable the UniPi percentage trigger, 80% is an earlier explicit boundary and the cooldown/growth guards prevent loops. UniPi's compiler is deterministic and zero-LLM; it does not issue a second summarizer request.
58
+ ## Commands
112
59
 
113
- | Setting | Default | Meaning |
114
- |---|---:|---|
115
- | `Percentage Trigger` | `off` | When on, UniPi checks context usage at `agent_end` (after the agent run settles) and can call compaction when the threshold is reached. Disabled by default for backward compatibility. |
116
- | `Threshold` | `80%` | Trigger point using Pi's live `ctx.getContextUsage().percent`. |
117
- | `Cooldown` | `60s` | Minimum time between UniPi-triggered compaction attempts. Prevents loops. |
118
- | `Repeat Growth` | `4k` | If usage is still above threshold after compaction, require this many new tokens before triggering again. |
119
- | `Notifications` | `on` | Shows user-visible notifications for UniPi-triggered compaction attempts/results. |
120
-
121
- Example config:
122
-
123
- ```json
124
- {
125
- "autoCompaction": {
126
- "enabled": true,
127
- "thresholdPercent": 80,
128
- "cooldownMs": 60000,
129
- "repeatMinGrowthTokens": 4000,
130
- "notify": true
131
- }
132
- }
133
- ```
134
-
135
- ### Pipeline tab
136
-
137
- The Pipeline tab exposes only behavior implemented by the current runtime.
138
-
139
- | Setting | Preset behavior | Current effect |
140
- |---|---|---|
141
- | `Auto Injection` | On in `balanced`, `thorough`; off in `precise`, `lean` | Adds behavioral/session state to the one-shot resume context after compaction. |
142
-
143
- Deprecated config-only compatibility fields are still accepted so existing files load without migration failures, but they are ignored and no longer controlled or advertised by presets: `ttlCache`, `mmapPragma`, `proximityReranking`, `timelineSort`, and `progressiveThrottling`.
144
-
145
- Other config-only pipeline field:
146
-
147
- | Field | Meaning |
148
- |---|---|
149
- | `customNoisePatterns` | Extra regex/string patterns used by session recall filtering to remove noisy user blocks. |
150
-
151
- ---
152
-
153
- ## What the agent gets
154
-
155
- ### Agent tools
156
-
157
- The extension registers tools during `session_start` after the session DB is initialized.
158
-
159
- | Tool | Purpose |
60
+ | Command | |
160
61
  |---|---|
161
- | `compact` | Agent-facing compaction request; supports `dryRun: true` preview. Slash command `/unipi:lossless-compact` is the user-facing immediate compaction path. |
162
- | `session_recall` | Search current session history with BM25 or regex. Defaults to 10 hits, hard-caps pages at 50, and caps expanded hit text at 16 KiB. |
163
- | `vcc_recall` | Deprecated alias for `session_recall`. |
164
- | `sandbox` | Run code in a sandboxed environment. Languages: JavaScript, TypeScript, Python, shell, Ruby, Go, Rust, PHP, Perl, R, Elixir. |
165
- | `sandbox_file` | Execute a file with its content injected as `FILE_CONTENT`. |
166
- | `sandbox_batch` | Run multiple sandbox execution items in one atomic response. |
167
- | `ctx_execute` | Deprecated alias for `sandbox`. |
168
- | `ctx_execute_file` | Deprecated alias for `sandbox_file`. |
169
- | `ctx_batch_execute` | Deprecated alias for `sandbox_batch`. |
170
- | `compactor_stats` | Agent-readable stats dashboard. |
171
- | `ctx_stats` | Deprecated alias for `compactor_stats`. |
172
- | `compactor_doctor` | Agent-readable diagnostics. |
173
- | `ctx_doctor` | Deprecated alias for `compactor_doctor`. |
174
- | `context_budget` | Uses live Pi context usage when available and returns compaction guidance. |
62
+ | `/unipi:compact-vcc [keep:N]` | Lossless compaction now; `keep:N` keeps the last N user turns |
63
+ | `/unipi:compact-jev [keep:N]` | Lossless compaction pruned by jev |
64
+ | `/unipi:compact-by-llm [focus]` | Model-summary compaction now; optional text focuses the summary |
65
+ | `/unipi:session-recall <query>` | Search the full session history (`scope:all`, `page:N`) |
66
+ | `/unipi:compact-stats` | This session's compactions and savings |
67
+ | `/unipi:compact-doctor` | Check settings, Pi's compaction switch, leftovers |
68
+ | `/unipi:compact-help` | Command summary |
175
69
 
176
- ### Agent skills
70
+ Deprecated: `/unipi:compact` and `/unipi:lossless-compact` (use `/unipi:compact-vcc`), `/unipi:compact-recall` (use `/unipi:session-recall`).
177
71
 
178
- | Skill | Purpose |
179
- |---|---|
180
- | `compactor` | Small always-loadable routing skill: when to compact, recall, check budget, or use sandbox. |
181
- | `compactor-detail` | On-demand full tool reference and workflow guidance. |
182
- | `compactor-stats` | Help interpreting compactor stats. |
183
- | `compactor-doctor` | Help diagnosing config/DB/runtime issues. |
72
+ ## Tools
184
73
 
185
- ---
74
+ - `session_recall`: keyword/regex search over the session branch, including compacted-away messages. `expand` returns full entries by index (the `#N` refs in summaries); `mode: "touched"` lists files.
75
+ - `context_budget`: how full the context is.
186
76
 
187
- ## How the system works
77
+ ## For other modules
188
78
 
189
- ### Chronological hook flow
79
+ Register an active-work provider so summaries lead with your state:
190
80
 
191
- Typical session order:
192
-
193
- 1. **Extension load**
194
- - Registers compaction hooks immediately with lazy dependencies.
195
- - Creates in-memory runtime counters/state.
196
-
197
- 2. **`session_start`**
198
- - Scaffolds config if needed.
199
- - Initializes `SessionDB` and sandbox executor.
200
- - Computes the current session ID, including worktree suffix.
201
- - Registers agent tools and slash commands.
202
- - Registers the info-screen Compactor group.
203
- - Emits UniPi `MODULE_READY`.
204
-
205
- 3. **`before_agent_start`**
206
- - Reloads config for the active project.
207
- - Applies runtime `autoDetect` behavior, such as disabling commit extraction outside git repos.
208
- - Rebuilds cached recall blocks from Pi's append-only session branch.
209
- - If a resume snapshot exists from a prior compaction, injects it into session context and marks it consumed.
210
-
211
- 4. **`input`**
212
- - Performs advisory security checks for shell/network/file patterns.
213
- - Can block some known-dangerous network shell commands.
214
-
215
- 5. **Tool execution → `tool_result`**
216
- - Extracts file/change/search/sandbox events into the session DB.
217
- - Updates runtime byte/tool counters.
218
- - Applies display overrides and width-safe diff clamping before output reaches the TUI.
219
-
220
- 6. **`agent_end`**
221
- - If percentage auto-compaction is enabled, reads `ctx.getContextUsage()`.
222
- - Runs cooldown/repeat-growth safeguards.
223
- - Calls `ctx.compact({ customInstructions: COMPACTOR_INSTRUCTION })` when eligible.
224
- - Fires only after the agent run settles: `ctx.compact()` aborts any active operation first, so triggering mid-run (e.g. at `turn_end`) would kill the next provider request.
225
-
226
- 7. **Pi decides to compact**
227
- - This can be from `/unipi:lossless-compact`, UniPi percentage auto-compaction, or Pi core's reserve-token fallback.
228
-
229
- 8. **`session_before_compact`**
230
- - Pi provides `preparation`, `branchEntries`, and optional custom instructions.
231
- - If compactor should handle it, UniPi:
232
- 1. chooses the safe cut point (`buildOwnCut`),
233
- 2. converts messages to LLM-like input,
234
- 3. runs the zero-LLM compile pipeline,
235
- 4. persists stats/snapshots,
236
- 5. returns `{ compaction: { summary, details, tokensBefore, firstKeptEntryId } }` to Pi.
237
-
238
- 9. **`session_compact`**
239
- - Pi commits the compaction entry.
240
- - UniPi increments compaction counters and persists token/character savings.
241
-
242
- 10. **Next `before_agent_start` after compaction**
243
- - UniPi injects the resume snapshot so the agent gets continuity without needing the full old transcript in context.
244
-
245
- 11. **`session_shutdown`**
246
- - Cleans old sessions.
247
- - Cleans sandbox/background processes.
248
- - Closes DB handles.
249
-
250
- ### Zero-LLM compile pipeline
251
-
252
- When UniPi handles `session_before_compact`, it transforms old messages through these deterministic stages:
253
-
254
- 1. **Normalize** — flatten user/assistant/tool/thinking messages into normalized blocks.
255
- 2. **Filter** — remove noise and apply `customNoisePatterns`.
256
- 3. **Build sections** — extract goals, files, commits, outstanding context, preferences, and transcript entries.
257
- 4. **Brief** — cap and condense transcript lines.
258
- 5. **Format** — emit a structured markdown summary.
259
- 6. **Merge** — merge with the previous summary when Pi provides one.
260
-
261
- The resulting summary is optimized for continuity, not for perfect archival fidelity. Use `session_recall` when the agent needs details from the raw session branch. Recall is deliberately paginated: request another offset page or narrow the query instead of injecting an unbounded result set. Even with `expand: true`, each hit is capped at 16 KiB to prevent a single historical message or tool result from dominating future cold-cache requests.
262
-
263
- ---
264
-
265
- ## Benchmarks
266
-
267
- Synthetic compile-only benchmark, run on this repository with Node 24 using `compile()` directly. Token counts use the common `chars / 4` estimate. Real compaction also keeps a recent live tail, so final live-context size can be larger than the summary-only number below.
268
-
269
- | Synthetic session | Input chars | Approx input tokens | Summary chars | Approx summary tokens | Reduction | Compile time |
270
- |---:|---:|---:|---:|---:|---:|---:|
271
- | 100 turns / 400 messages | 356,913 | 89,228 | 36,451 | 9,113 | 89.8% | 12.5 ms |
272
- | 250 turns / 1,000 messages | 894,063 | 223,516 | 36,585 | 9,146 | 95.9% | 16.6 ms |
273
- | 500 turns / 2,000 messages | 1,789,313 | 447,328 | 36,605 | 9,151 | 98.0% | 35.8 ms |
274
-
275
- Practical interpretation:
276
-
277
- - Larger sessions compress better because the structured summary has fixed caps.
278
- - Runtime is local and usually small relative to model/tool latency.
279
- - Actual savings reported to users should come from `/unipi:compact-stats`, because Pi supplies real `tokensBefore` during compaction when available.
280
-
281
- ---
282
-
283
- ## Troubleshooting
284
-
285
- ### "Whatever preset I choose, Pipeline is always off"
286
-
287
- That means preset application is not updating `config.pipeline`. The intended behavior is:
288
-
289
- - `precise`: Auto Injection off.
290
- - `balanced`: Auto Injection on.
291
- - `thorough`: Auto Injection on.
292
- - `lean`: Auto Injection off.
293
-
294
- The five deprecated compatibility fields remain off in every preset.
295
-
296
- Make sure you are running a version with the preset pipeline fix, select the preset, and press **Enter** to save.
297
-
298
- ### "Compaction did not happen"
299
-
300
- - For immediate user-triggered compaction, use `/unipi:lossless-compact`.
301
- - For automatic percentage compaction, enable **Auto → Percentage Trigger**.
302
- - Pi core still has its own reserve-token fallback; UniPi's percentage trigger is optional and disabled by default.
303
-
304
- ### "Stats show zero"
305
-
306
- - Stats only increase after compaction or after tracked sandbox/search events.
307
- - Run `/unipi:compact-doctor` to check DB/config health.
308
- - Long sessions may show all-time DB fallbacks if current in-memory counters are zero.
309
-
310
- ### "Recall cannot find something"
81
+ ```ts
82
+ import { registerCompactionContext } from "@pi-unipi/core";
83
+ registerCompactionContext("my-module", () => (running ? "Task X is in progress — …" : null));
84
+ ```
311
85
 
312
- - Use specific terms with `/unipi:session-recall <query>`.
313
- - The recall path prefers Pi's append-only branch and falls back to cached normalized blocks.
314
- - Extra noise filtering can be added with `pipeline.customNoisePatterns`.
86
+ Compactions applied at a turn boundary (percentage trigger) do not fire Pi's `session_compact`; listen to `UNIPI_EVENTS.COMPACTOR_COMPACTED` to react to every compaction.
315
87
 
316
- ## License
88
+ ## Removed in 3.0
317
89
 
318
- MIT
90
+ - **Session continuity**: the SQLite event log and the hidden snapshot restored after compaction. It logged every session under one shared ID, so snapshots mixed projects and grew to ~60k tokens. The summary now derives files, errors and commits from the session itself. `/unipi:compact-doctor` reports the old `~/.unipi/db/compactor` directory, which can be deleted.
91
+ - **Sandbox tools** (`sandbox`, `sandbox_file`, `sandbox_batch`), the `compact` tool (it never compacted), `compactor_stats` / `compactor_doctor` tools (use the commands), presets, and the inert strategy modes.