pi-blackhole 0.5.6 → 0.5.8
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/CHANGELOG.md +42 -0
- package/README.md +25 -21
- package/dist/index.js +168 -167
- package/index.ts +2 -0
- package/package.json +12 -12
- package/src/commands/memory.ts +18 -8
- package/src/core/config-env.ts +1 -0
- package/src/core/unified-config.ts +4 -0
- package/src/hooks/compact-failed.ts +4 -1
- package/src/hooks/cosmetic-output.ts +11 -1
- package/src/om/agents/agent-context.ts +67 -0
- package/src/om/agents/dropper/agent.ts +10 -16
- package/src/om/agents/observer/agent.ts +6 -21
- package/src/om/agents/reflector/agent.ts +6 -16
- package/src/om/agents/turn-cap.ts +74 -0
- package/src/om/consolidation.ts +45 -36
- package/src/om/inline-compaction.ts +47 -1
- package/src/om/ledger/progress.ts +47 -0
- package/src/om/ledger/projection.ts +3 -0
- package/src/om/provider-stream.ts +18 -11
- package/src/om/status-bar.ts +355 -0
- package/src/pi-base/blackhole-settings.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,8 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## [0.5.8] - 2026-09-22
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **Observation-pool measurement is centralized.** The dropper trigger, `/blackhole-memory` pool lines, and footer P gauge each summed the active pool with their own inline copy; they now share `observationPoolTokens()` (`ledger/progress.ts`), which sums the live active pool plus — always explicitly — manual-mode pending observation batches. `/blackhole-memory` now includes those pending batches in its `Obs pool` / `Dropper:` percentages (so a manual-only user sees the same pool the trigger gates on) and labels the split (`· branch 0 + pending 1,400`); the footer P gauge deliberately stays branch-only. No trigger, threshold, or dropper-candidate behavior changes ([#120](https://github.com/k0valik/pi-blackhole/issues/120)).
|
|
10
|
+
|
|
11
|
+
- **Pi loads the prebuilt `dist/index.js`.** `pi.extensions` now points at the tsup bundle instead of `./index.ts`, removing jiti transpilation of the whole module graph on startup (measured import 500 to 570 ms down to 350 to 530 ms, factory time unchanged). Registry installs ship `dist/` in the tarball. Git installs need `npmCommand` set so devDependencies install and `prepare` builds `dist/`; when they don't, `scripts/prepare.mjs` now warns that the extension will not load instead of failing silently, documented next to the GitHub install command in `README.md`.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **`agentMaxTurns` is enforced on Pi 0.87.** The observer, reflector, and dropper capped their loops with `shouldStopAfterTurn`, which 0.87 removed in favour of `finishTurn` (whose `{ action: "end" }` ends the run), so the configured turn budget was silently ignored and a worker could keep running until it stopped naturally, errored, or was aborted. Both hooks are now emitted through `createTurnCap` with independent counters, so the loaded generation picks the one it knows and a host calling both still ends at `maxTurns`; a turn that already hard-exited (`error`/`aborted`) neither decides the run nor spends budget ([upstream OM `#83`](https://github.com/elpapi42/pi-observational-memory/pull/83)).
|
|
16
|
+
- **Extension registration survives class-based `ExtensionAPI` hosts.** `registerCompactFailedHook` widened and then invoked `pi.on` detached, so a host whose `on` reads instance state (e.g. oh-my-pi's `ConcreteExtensionAPI`) threw `TypeError: undefined is not an object (evaluating 'this.extension')` during registration and took the rest of the extension's hooks down with it; the handler is now bound to `pi` before the widening cast, a no-op on pi's closure-based API ([#124](https://github.com/k0valik/pi-blackhole/pull/124)).
|
|
17
|
+
- **Custom-provider streams keep their receiver when the bridge dispatches them.** Each `streamSimple` handler was stored in the global capture map detached from its provider config, and the api-only fallback for host-aliased provider ids extracted it the same way. A class-based config that reads instance state therefore threw `Cannot read properties of undefined`: the capture-map path crashed the worker stream, while the aliased path swallowed the error and silently degraded to the compat dispatcher. Captured handlers are now bound to their config, and the api-only match is invoked on it ([upstream OM `#80`](https://github.com/elpapi42/pi-observational-memory/pull/80)).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## [0.5.7] - 2026-09-21
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Footer status bar.** pi-blackhole now shows live state in the pi footer (config key `statusBar`, default on; env `PI_BLACKHOLE_STATUSBAR`): three token gauges — O (transcript since the last observer run), P (observation pool fill), X (context since the last compaction) — plus worker spinners, `✓ +N` completion events, and compaction notes with their trigger reason. Gauges color by fill: dim under 80%, theme warning color from 80%, theme error color at 100%. The bar reads in-process state (`runtime.config`, `model-budget.ts`, `ledger/progress.ts`, `runtime.consolidationPhase`), so its numbers match `/blackhole-memory` status; it adds no file polling and no threshold guessing, only a 1-second in-process poll of the runtime state. If you ran the standalone `blackhole-status.ts` footer extension before, remove it: two writers on the same `setStatus` key race.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **Pi 0.87 is supported.** The `@earendil-works/*` devDependencies move to `0.87.0` in lockstep and the dependabot `>=0.87.0` hold is removed ([#118](https://github.com/k0valik/pi-blackhole/issues/118)). `peerDependencies` (`>=0.85.1 <1.0.0`) is unchanged: the observational-memory system-prompt carrier is probed at runtime, so consolidation keeps its prompt on 0.85/0.86 (legacy `AgentContext.systemPrompt`) and 0.87+ (leading transcript system message) — see Fixed.
|
|
30
|
+
- **CI runs on pull requests targeting `dev` too.** `ci.yml` previously triggered only for `pull_request → main`, so PRs merged into the working branch were gated by bot reviews alone. The full gate (build → typecheck → lint → test → format:check) now covers both branches.
|
|
31
|
+
- **Installs work under pnpm's built-in minimum-release-age policy.** pnpm 11 enforces a 24-hour minimum release age by default, which rejected the brand-new `@earendil-works/*@0.87.0` set. The toolchain pin moves to `pnpm@11.27.1` and those versions are listed in `minimumReleaseAgeExclude` (the previous pin, `11.2.2`, ignored that list), so `pnpm install --frozen-lockfile`, CI, and git-based extension installs no longer wait out the window.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- **The compact-shape guard follows Pi 0.87's `_refreshFinalizedContext()` indirection.** 0.87 moved the `agent.state.messages` repoint out of `AgentSession.compact()` into a helper, so the guard that requires the write _inside_ `compact()` rejected the class and mid-run inline compaction failed closed on 0.87 ([#117](https://github.com/k0valik/pi-blackhole/issues/117)). The guard now accepts an assignment found one call level deep in one of the class's own prototype methods, and still rejects inherited helpers, deeper indirection, and a helper that only reads the property.
|
|
36
|
+
- **Observational-memory consolidation keeps its system prompt on Pi 0.87.** 0.87 removed `AgentContext.systemPrompt` and now carries the prompt as a leading transcript `system` message, so the observer, reflector, and dropper would have silently run without their prompts. They now build whichever carrier the loaded host reads — probed by the presence of Pi 0.87's `createInitialSystemMessage` helper, not a version allowlist — so 0.85/0.86 keep the legacy field and 0.87+ gets the transcript message ([#118](https://github.com/k0valik/pi-blackhole/issues/118)).
|
|
37
|
+
- **Discover Pi 0.86's bundled host behind its `createRequire` launcher.** Follow the same-package bootstrap file without executing it before locating the runtime chunk, so inline compaction captures the active `AgentSession` instead of patching the unused modular class and falling back to settled compaction. A bootstrap target that is missing, unreadable, or outside the Pi package now leaves the launcher's own source in place, so the direct-import scan still runs instead of being skipped.
|
|
38
|
+
- **Observer preamble cap now applies in auto/off compaction modes.** `observerPreambleMaxTokens` was previously only enforced in manual mode, so auto-mode observer prompts could grow without bound even though the main session prompt stayed capped by `observationsPoolMaxTokens`; the observer now applies the same relevance-ranked selection budget in all modes, defaulting to 30% of `observerChunkMaxTokens` when unset.
|
|
39
|
+
- **Observer preamble cap now covers reflections, and the context guard prices the full prompt.** Reflections were never trimmed (no drop entry type exists for them), leaving a permanently growing floor on the observer preamble; each preamble section is now capped at `observerPreambleMaxTokens` (reflections newest-first). The pre-flight `observer.context_window_exceeded` guard previously measured only `chunkTokens + 8000`, so oversized prompts sailed through and failed every attempt with a provider 400; it now accounts for the rendered preamble and the observer system prompt, skipping the model cleanly instead.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
5
43
|
## [0.5.6] - 2026-09-19
|
|
6
44
|
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- **Pre-compaction output stays visible after compaction** ([#103](https://github.com/k0valik/pi-blackhole/pull/103), thanks @sonSunnoi). After a successful Blackhole compaction, the newest assistant text removed from view is re-rendered as a display-only **Previous output — display only** block, so recent work stays readable without opening `/tree`. Bounded and opt-out: 16 KiB UTF-8 cap with a truncation marker, text only (no tool output, thinking, or images), idempotent per compaction, skipped when the newest dropped text is retained; disabled via `showPreCompactionMessage` (default `true`, env `PI_BLACKHOLE_SHOW_PRE_COMPACTION_MESSAGE`).
|
|
48
|
+
|
|
7
49
|
### Changed
|
|
8
50
|
|
|
9
51
|
- **Minimum supported Pi raised to 0.85.1; compat-floor CI retired.** The `compat-min-supported` job re-pinned the `@earendil-works/*` peers to the `peerDependencies` floor and typechecked against them, going red every time. The extension now builds against the pinned devDependencies (0.85.1) and the peer floor is set to match; `peerDependencies` remains the single source of truth for the declared minimum.
|
package/README.md
CHANGED
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
# From npm (recommended)
|
|
13
13
|
pi install npm:pi-blackhole
|
|
14
14
|
|
|
15
|
-
# Or directly from GitHub
|
|
15
|
+
# Or directly from GitHub.
|
|
16
|
+
# Requires npmCommand to be set in settings.json, otherwise pi runs
|
|
17
|
+
# `npm install --omit=dev`, devDependencies are skipped, and dist/ is not built.
|
|
18
|
+
# Example: "npmCommand": ["npm"] in ~/.pi/agent/settings.json
|
|
16
19
|
pi install git:github.com/k0valik/pi-blackhole
|
|
17
20
|
```
|
|
18
21
|
|
|
@@ -31,14 +34,15 @@ Then `/reload` or restart Pi. The config file at `~/.pi/agent/pi-blackhole/pi-bl
|
|
|
31
34
|
|
|
32
35
|
## ✨ What's new
|
|
33
36
|
|
|
34
|
-
> **Latest release: [0.5.
|
|
37
|
+
> **Latest release: [0.5.8](CHANGELOG.md)**
|
|
35
38
|
>
|
|
36
|
-
> - **
|
|
37
|
-
> -
|
|
38
|
-
> - **
|
|
39
|
-
> -
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
> - **Pi loads a prebuilt bundle** — `pi.extensions` points at the tsup `dist/index.js` instead of TypeScript source, cutting startup import time (500–570 ms → 350–530 ms). Registry installs ship `dist/`; git installs need `npmCommand` set, and a missing `dist/` now warns instead of failing silently.
|
|
40
|
+
> - **Every observation-pool readout agrees** — the dropper trigger, `/blackhole-memory` pool lines, and the footer P gauge each summed the pool inline; they now share one helper, and `/blackhole-memory` includes (and labels) manual-mode pending batches so the display matches what the trigger gates on. No threshold or candidate behavior changes. ([#120](https://github.com/k0valik/pi-blackhole/issues/120))
|
|
41
|
+
> - **`agentMaxTurns` is enforced on Pi 0.87** — the worker loops emitted only the removed `shouldStopAfterTurn`, so the turn budget was silently ignored; `createTurnCap` now emits both that hook and 0.87's `finishTurn`, with independent counters. ([upstream OM `#83`](https://github.com/elpapi42/pi-observational-memory/pull/83))
|
|
42
|
+
> - **Extension registration survives class-based hosts** — hooks were invoked detached from their API object, which threw on hosts like oh-my-pi; handlers are now bound before registration. ([#124](https://github.com/k0valik/pi-blackhole/pull/124))
|
|
43
|
+
> - **Custom-provider streams keep their receiver** — captured `streamSimple` handlers are bound to their config, so class-based providers no longer crash or silently fall back to the compat dispatcher. ([upstream OM `#80`](https://github.com/elpapi42/pi-observational-memory/pull/80))
|
|
44
|
+
>
|
|
45
|
+
> See [`CHANGELOG.md`](CHANGELOG.md) for the full history.
|
|
42
46
|
|
|
43
47
|
---
|
|
44
48
|
|
|
@@ -73,7 +77,8 @@ Both halves share a single hook and a single output. Together they keep the agen
|
|
|
73
77
|
|
|
74
78
|
All commands work regardless of `compaction` mode — only _when_ auto-compaction fires changes. See [Compaction modes](#compaction-modes) below.
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
<details>
|
|
81
|
+
<summary>The `recall` tool (agent-facing)</summary>
|
|
77
82
|
|
|
78
83
|
The agent gets one unified `recall` tool that handles every form of historical lookup. Searches read the raw session file directly, bypassing compaction.
|
|
79
84
|
|
|
@@ -95,6 +100,8 @@ Every recall response is capped at `recallResponseMaxChars` (default 48,000 ≈
|
|
|
95
100
|
|
|
96
101
|
The `/blackhole-recall` command exposes the same engine to the user. Results are shown as a collapsible message and auto-fed to the agent as context.
|
|
97
102
|
|
|
103
|
+
</details>
|
|
104
|
+
|
|
98
105
|
---
|
|
99
106
|
|
|
100
107
|
## Compaction modes
|
|
@@ -195,7 +202,8 @@ If any stage fails (model error, rate limit, timeout), remaining stages are skip
|
|
|
195
202
|
|
|
196
203
|
---
|
|
197
204
|
|
|
198
|
-
|
|
205
|
+
<details>
|
|
206
|
+
<summary>What the agent sees after compaction</summary>
|
|
199
207
|
|
|
200
208
|
After compaction, the agent sees something like this (sections appear only when relevant — a session with no git commits won't show `[Commits]`):
|
|
201
209
|
|
|
@@ -248,9 +256,12 @@ Use `recall` with an id to retrieve original context.
|
|
|
248
256
|
|
|
249
257
|
> **Note:** The OM injection format uses `## Reflections` and `## Observations` Markdown headers followed by a brief footer. Each observation and reflection has a 12-char hex identifier the agent (and you, via `/blackhole-recall`) can use to recover source evidence. When no observations or reflections exist, only the short recall-guidance footer is appended.
|
|
250
258
|
|
|
259
|
+
</details>
|
|
260
|
+
|
|
251
261
|
---
|
|
252
262
|
|
|
253
|
-
|
|
263
|
+
<details>
|
|
264
|
+
<summary>Feature comparison</summary>
|
|
254
265
|
|
|
255
266
|
| | pi-blackhole | pi-vcc | pi-obs-memory | Pi default |
|
|
256
267
|
| ------------------------------------------- | ------------ | ------ | ------------- | ---------- |
|
|
@@ -268,6 +279,8 @@ Use `recall` with an id to retrieve original context.
|
|
|
268
279
|
| Unified single-file config | ✓ | — | — | — |
|
|
269
280
|
| Per-session pending state | ✓ | — | — | — |
|
|
270
281
|
|
|
282
|
+
</details>
|
|
283
|
+
|
|
271
284
|
---
|
|
272
285
|
|
|
273
286
|
## Uninstall
|
|
@@ -285,6 +298,7 @@ rm -rf ~/.pi/agent/pi-blackhole
|
|
|
285
298
|
| ------------------------------------------------------------ | ----------------- | ----------------------------------------------------------------------------------------- |
|
|
286
299
|
| **[`README.md`](README.md)** | You, now | Install, commands, the pitch, the value, the demo. |
|
|
287
300
|
| **[`CHANGELOG.md`](CHANGELOG.md)** | You | Every release, what changed, who contributed. |
|
|
301
|
+
| **[`CONTRIBUTING.md`](CONTRIBUTING.md)** | You, if helping | Branch model, dev setup, PR description format, docs/changelog gates. |
|
|
288
302
|
| **[`docs/CONFIG.md`](docs/CONFIG.md)** | You, when tuning | Every config key with type, default, behavior, and env-var overrides. |
|
|
289
303
|
| **[`llms.txt`](llms.txt)** | Your agent | Step-by-step guided setup interview, anti-patterns, exact file paths, internal constants. |
|
|
290
304
|
| **[`docs/MIGRATION-GUIDE.md`](docs/MIGRATION-GUIDE.md)** | You, if upgrading | Old → new config key mapping, semantic changes, automatic migration behavior. |
|
|
@@ -296,16 +310,6 @@ rm -rf ~/.pi/agent/pi-blackhole
|
|
|
296
310
|
|
|
297
311
|
---
|
|
298
312
|
|
|
299
|
-
## Migration from an older version
|
|
300
|
-
|
|
301
|
-
If you're upgrading from a pre-0.4.0 config (the old `pi-vcc` / `pi-observational-memory` keys, or an early `pi-blackhole` config with `overrideDefaultCompaction` / `noAutoCompact` / `passive`): see **[`docs/MIGRATION-GUIDE.md`](docs/MIGRATION-GUIDE.md)** for the key mapping, semantic changes, and notes on automatic migration.
|
|
302
|
-
|
|
303
|
-
The short version: old keys are auto-migrated in memory at load time and the on-disk file is never mutated. Set the new keys explicitly via `/blackhole settings` (alias `/blackhole configure`) to silence the migration notification.
|
|
304
|
-
|
|
305
|
-
The legacy config surface is documented at **[`docs/OLD_CONFIG.md`](docs/OLD_CONFIG.md)** for reference only — no new keys are added there.
|
|
306
|
-
|
|
307
|
-
---
|
|
308
|
-
|
|
309
313
|
## Credits
|
|
310
314
|
|
|
311
315
|
`pi-blackhole` started as a merge of two upstream projects but has since diverged significantly. The codebase still carries DNA from both:
|