omp packages

pi-precompact0.4.0

Precompute Pi compaction summaries without interrupting the agent.

patlux Published 4 hours ago MIT ~959 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-precompact

An experimental Pi extension that prepares compaction summaries while the agent continues its work. Pi still decides when to compact. The extension supplies a valid prepared summary at that boundary, or leaves the request to Pi.

Inspired by OpenCode background compaction. This is an independent implementation, not an OpenCode port.

pi-precompact in Pi: the context bar fades in, a summary is prepared while the agent keeps working, and Pi adopts it at its threshold

Status

  • Supports Pi 1.2.0 up to 1.5.x. CI tests every release in that range, and the newest Pi every day.
  • Uses Pi's native context projection, preparation, and summary generator.
  • Does not abort the agent or inject a continue message.
  • Does not install itself, change settings, or run a background process.
  • Has deterministic unit tests and SDK integration tests with Pi's local Faux provider.
  • Has no live-provider endurance or latency benchmark yet.

Install

pi install npm:pi-precompact

New sessions load the extension. Run /reload in a session that is already open. To try it for one invocation without changing settings:

pi -e npm:pi-precompact

Do not combine it with another extension that replaces compaction.

Commands:

/precompact status
/precompact off
/precompact on
/precompact reset

These commands affect only the current session. reset cancels the prepared job and clears the failure counter.

/precompact and /precompact status open a status card in the TUI, in place of the editor. The card appears only on this explicit request. It shows the state and last event, a context bar with the plugin's start and Pi's threshold, the expected result of a held summary, the request usage, and the failure count. It updates every second. Press r to reset, o to switch off or on, and Escape or Enter to close. RPC, JSON, and print modes keep the one-line answer.

When Pi adopts a background summary, the TUI and RPC clients receive one notice, for example:

✓ Background summary applied · no wait · 249k → ~38k tokens · prepared in 48s

waited 12s replaces no wait when Pi had to wait for a running request. The token value after → is Pi's estimate. Native fallback compactions produce no notice.

The compaction block, the notice for the adopted summary, and the status card in a Pi session

The plugin sets one footer status from session start, precompact: <state>:

State Meaning
idle Enabled; no summary is in progress.
running Preparing a summary while the agent continues.
ready Holding a summary until Pi requests threshold compaction.
paused Two background requests failed; native compaction remains available.
off Disabled for this session, or native auto-compaction is disabled.
unavailable Unsupported Pi installation, virtual model, or no model selected.

In Pi's built-in TUI footer, the plugin moves this status from the status row into the statistics line. Pi's own context segment stays exactly as Pi renders it. From 100 columns, a context bar comes before it:

━━━━━━━━━━━━━━━━━━━│━━━─│─ 91.6%/272k (auto) → ~14%
  • The accent mark is where background preparation starts. The error mark is where Pi compacts.
  • The fill uses the state colour: running accent, ready success, paused warning, the others muted or dim.
  • → ~14% follows while a summary is ready: the estimated context after Pi adopts it.
  • ✓ pre follows directly after an adopted summary, until the next change.
  • pre running, pre ready (without an estimate), pre paused, pre off, and pre unavailable name the other states.
The statistics line with the context bar in five states: idle, running, ready with the expected context, adopted, and off

From top to bottom: idle, running, ready with the expected context, an adopted summary, and off. After a compaction Pi shows ? until it has measured the next response.

Below 100 columns the line shows 91.6%/272k (auto) pre: ready instead. When even that does not fit, or the footer has an unknown layout, Pi's status row keeps precompact: <state>.

Before the first response with token usage, Pi shows only its context value and no usage numbers. The plugin then shows nothing either: no bar, no pre text, and no status row entry. With the first measured response, the bar fades in once:

  • Pi's numbers appear at once; the bar reserves its columns in the same frame.
  • Each glyph fades from the terminal background to its colour in 120 ms, 5 ms after its left neighbour.
  • The fill grows from 80 to 240 ms. A frame follows every 40 ms; the easing is cubic-bezier(0.23, 1, 0.32, 1).
  • A new width or state during the animation shows the final bar at once. A new context value, such as a tool result right after the first response, updates Pi's number and lets the fill grow towards it.
  • Sessions with earlier responses, for example after /resume or /reload, show the bar without animation.
The context bar fading in after the first measured response, at half speedNine frames of the fade-in: the wave fades the bar in from the left, then the marks appear and the fill grows

The plugin asks the terminal for its background colour once, as Pi's theme does. Without an answer or without truecolor, each glyph appears directly in its colour as the wave reaches it. Set PI_PRECOMPACT_MOTION=off before starting Pi to show the bar without animation.

Use /precompact status for the last event and failure count. Pi's (auto) context indicator refers to native automatic compaction, not this plugin.

Pi has no public API to place text inside its footer. A zero-row widget below the editor finds the one mounted built-in FooterComponent and wraps the render method of that instance; the prototype stays untouched. The plugin reads the instance's status provider read-only and never modifies shared statuses. Other footer decorators can wrap the same instance before or after it; each keeps the other's lines. Custom footers are left alone. Shutdown and reload restore Pi's method and clear this plugin's status only. JSON, print, and RPC modes receive no terminal status or footer decoration.

To remove it, run pi remove npm:pi-precompact.

Scheduling

  1. After a completed turn, resolve Pi's effective compaction settings for the current model.
  2. Start one summary when context reaches 85% of the native compaction ceiling.
  3. Require at least 64,000 measured input and cache tokens from the latest valid assistant response.
  4. Keep the result in memory while the agent continues.
  5. At native threshold compaction, validate the snapshot and await its result if necessary.
  6. Return the prepared summary to Pi, or let Pi perform normal compaction.

The ceiling is contextWindow - reserveTokens. With Pi's default reserve of 16,384 tokens and a 272,000-token model, the ceiling is 255,616 tokens: background work starts at 217,274 tokens (80%), and Pi compacts above 255,616 tokens (94%). The extension reads Pi's effective compaction settings, so a changed reserve or a model override moves both marks. The extension does not start speculative work after the ceiling is already reached.

A job has a two-minute deadline from its start. Foreground waiting uses the remaining time, not a new two-minute timeout. Two background failures pause speculative work until compaction or an explicit reset. Manual compaction, custom instructions, and overflow recovery always use Pi's foreground path.

Context safety

The summary uses the canonical prepareCompaction() and compact() functions from the running Pi installation. There is no copied cut-point or projection algorithm.

The extension hashes the original branch and checks it again before applying a result. It rejects changed models, settings, branch prefixes, context edits, and intervening compactions. It also checks after a foreground wait, because session changes can race the request. Session replacement, tree navigation, reload, model selection, and cancellation discard pending work.

Pi keeps the retained history as native messages. The extension does not convert recent tool output or attachments into truncated text. New messages after the snapshot remain in that retained history. No catch-up summary call is necessary. Pi can still make two native summary calls for a split turn.

Before acceptance, an in-memory SessionManager previews the real compaction entry, including replayed system state. The estimated result must reduce context and fit below the native ceiling with a 15% estimate margin. New history after the snapshot must also fit within min(max(2 × keepRecentTokens, 30,000), ceiling / 4). These checks use Pi's token estimates, not an exact provider tokenizer. Native overflow recovery remains the final safeguard.

Pi 1.2 to 1.5 skip inherited file metadata from all extension-generated compactions. A narrow adapter preserves this extension's marked file lists in both background preparation and foreground fallback. It leaves other extensions' details alone.

Compatibility and limits

prepareCompaction() is not a public root export in Pi. The adapter loads the installed distribution module after it checks that the runtime is Pi 1.2.0 up to 1.5.x and matches its package. Other versions, mismatched installations, and binary installations without distribution modules leave the extension inactive. Pi's normal compaction remains available. To try an untested Pi release at your own risk, start Pi with PI_PRECOMPACT_ALLOW_UNTESTED_PI=1. The extension then shows a warning.

Virtual routing models use native compaction only. This avoids speculative work against unresolved model limits. Physical models use ctx.modelRegistry.streamSimple(), with the configured provider and request-time authentication. The extension does not read credential files or resolve secrets itself. Background requests do not use custom SDK agent.streamFunction overrides or request-transform hooks.

Background summaries consume provider quota, even when discarded. Requests can overlap with ordinary agent requests. Accepted summaries carry their native usage into the compaction entry. The extension records known discarded-result usage as a non-context precompact.discarded custom entry. Pi does not include those custom entries in its built-in cost totals.

Partial failures and cancelled or late requests can incur costs without returning usage. A provider that ignores abort can continue remote work after the local wait ends.

This extension follows Pi's summary prompt and cache policy. It does not implement OpenCode's prompt-cache optimization. It reads persisted context, not temporary context or context_with_system hook transformations. Persistent omissions and replacements must use Pi's context_edit entries.

Development

See CONTRIBUTING.md for setup, Changesets, the commit hook, and the separate release procedure. See CHANGELOG.md for release notes.

Prerequisites: Node.js 22.19+, Python 3.11+, Git, npm, Make, and tar.

From the repository root, install the locked development dependencies:

npm ci --ignore-scripts

Install the changeset hook once per clone:

make hooks-install

Run the same checks as CI:

npm run check

This checks formatting, lint, types, runtime tests, the actual npm tarball, and the Changesets flow. CI runs these checks on Linux and macOS with Node.js 22 and 24, and the tests against every supported Pi release. A daily workflow runs the tests against the newest Pi.

Tests use temporary directories, in-memory credentials, in-memory sessions, and a local scripted provider. They do not load personal extensions, read real credential files, or call a remote model. The integration tests inject deterministic token usage through Pi's finalized-message hook. They exercise real extension loading, provider streaming, tool-driven turns, threshold compaction, fallback, and shutdown.

Source:

  • src/index.ts: lifecycle hooks and commands.
  • src/controller.ts: job scheduling and cancellation.
  • src/native.ts: version-guarded native adapter.
  • src/validation.ts: branch validation and context preview.
  • src/files.ts: file-metadata inheritance for Pi 1.2 to 1.5.
  • src/card.ts: the status card for /precompact status.
  • src/footer.ts: the context bar in Pi's built-in footer.
  • src/format.ts: token, duration, and share formatting.