pi-jev-compact

Verbatim context compaction for pi, powered by the TypeSafe Jev model

Packages

Package details

extension

Install pi-jev-compact from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-jev-compact
Package
pi-jev-compact
Version
0.1.0
Published
Sep 20, 2026
Downloads
167/mo · 167/wk
Author
019ec6e2
License
MIT
Types
extension
Size
55.7 KB
Dependencies
0 dependencies · 2 peers
Pi manifest JSON
{
  "extensions": [
    "./src/index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-jev-compact

tests typescript pi

Verbatim context compaction for pi, powered by the TypeSafe Jev model.

Replaces pi's LLM-written compaction summary with surgical pruning: every historical tool call is scored in one fast Jev request — stale calls are dropped, results that are no longer needed are truncated to a bounded head + note, and everything kept stays word-for-word. No lossy summarization, ever.

Port of fast-jev-compaction (Claude Code plugin) to a pi extension. See ADAPTATION.md for the design mapping.

Why

Most context compaction asks an LLM to summarize old turns. A summary is lossy: a file path, exact error, constraint, or command can disappear even when it matters later. This extension never rewrites anything. It only deletes tool calls and results Jev says are no longer needed, and it asks Jev while showing it the whole conversation. User and assistant text stays verbatim and in order.

How it works

pi auto-compact (threshold) ─┐
/compact ────────────────────┼─► session_before_compact ─► [fast-jev engine]
/jev-compact ────────────────┘         │
                                       ▼
                     1. Pair every tool call with its result
                     2. Pin the kept tail (pi's firstKeptEntryId)
                     3. Send the whole history (results omitted) as state,
                        fitted to 25k tokens in stages
                     4. Ask Jev per call: keep the call? keep the result verbatim?
                     5. Decide: keep · truncate result (head + note) · drop call+result
                     6. Return the pruned transcript VERBATIM as the compaction summary
                         │
                         └─ not enough reduction / Jev failed / no key?
                            → pi's built-in LLM summary (graceful fallback)

Dropped results keep their first FAST_JEV_TRUNCATE_HEAD_CHARS characters plus a note ([fast-jev-compaction truncated N chars of this tool result; re-run the tool if needed]), so the model knows it can re-run the tool. Repeated compactions chain: the previous pruned history is prepended as [Earlier compacted history].

Install

From a checkout (dev, hot-reloadable):

git clone https://github.com/019ec6e2/pi-jev-compact
ln -s "$PWD/pi-jev-compact" ~/.pi/agent/extensions/pi-jev-compact

As a pi package (npm or git):

pi install git:github.com/019ec6e2/pi-jev-compact@v1
# or
pi install npm:pi-jev-compact

Runtime dependency is typebox only; pi resolves it on install.

Setup

export TYPESAFE_API_KEY=...   # or FAST_JEV_API_KEY

Without a key the extension stays passive — pi's built-in compaction runs untouched.

Usage

Nothing to do: pi's own auto-compaction threshold routes through fast-jev, as do /compact and overflow recovery. Extras:

Command Effect
/jev-compact Trigger compaction now (pi's flow, fast-jev decides)
/jev-compact focus on the DB migration Optional instructions → used by the built-in summary if we fall back

After each compaction you get a notification with the outcome and a footer widget:

fast-jev: compaction done (fast-jev, extension-provided, manual) —
messages 4/10, calls 0 kept / 0 truncated / 3 dropped / 0 pinned —
state ~531 tokens (full), 1 request(s), 623ms

Falls back with an explicit reason, e.g. fast-jev: fallback to built-in summary (below 25% minimum: …).

Configuration

Precedence: defaults < environment < project file.

Variable Default Meaning
FAST_JEV_API_KEY / TYPESAFE_API_KEY — TypeSafe API key (extension is passive without it)
FAST_JEV_MODEL jev-latest Jev model
FAST_JEV_KEEP_THRESHOLD 0.5 Minimum keep probability for a call or result to stay
FAST_JEV_MIN_REDUCTION 0.25 Below this character reduction, fall back to the built-in summary
FAST_JEV_PRESERVE_RECENT 2 Newest messages inside the summarized span never touched (pi already keeps its own recent tail)
FAST_JEV_MAX_STATE_TOKENS 25000 Token ceiling for the state sent to Jev
FAST_JEV_MAX_REQUEST_TOKENS 30000 Ceiling for state plus one batch of questions
FAST_JEV_TRUNCATE_HEAD_CHARS 300 Characters of a truncated result retained
FAST_JEV_GOAL last user prompts Task hint included in the state

Project-local overrides in .pi/fast-jev.json (read only for trusted projects), same keys in camelCase (apiKey, model, keepThreshold, minReductionRatio, preserveRecentMessages, maxStateTokens, maxRequestTokens, truncateHeadChars, goal).

Architecture

src/
├── index.ts      entry: session_before_compact handler, /jev-compact, stats reporting
├── adapter.ts    pi AgentMessage ⇄ library Message (via pi's convertToLlm),
│                 verbatim summary serializer with previousSummary chaining
├── config.ts     env + project-file config resolution
└── jev/          host-agnostic engine (ported from fast-jev-compaction):
    types, request/client, state fitting, batching, decisions, rebuild

pi loads extensions via jiti — no build step. tsc is type-checking only.

Milestone tool Role
TypeScript 7 type checking only (tsc --noEmit), strictest flags
Biome 2 lint + format + import organizing
Vitest 4 unit tests (fake Jev asker — no network in tests)

Development

npm install
npm run typecheck        # tsc --noEmit
npm run lint             # biome check
npm test                 # vitest, offline
npm run demo             # live Jev round-trip; skips safely without TYPESAFE_API_KEY
npm run dev              # pi -e ./src/index.ts

The test suite covers the ported engine (options, token estimation, call collection, state-fitting stages, batching, decisions, HTTP client) plus pi-side adapter mapping, verbatim serialization, config layering, and an end-to-end pi-transcript round trip.

Notes and limitations

  • Pruned content is gone: Jev is a probability, not a guarantee. The assistant can always re-run a tool.
  • The summarized span becomes text — images and thinking blocks in that span are not reproduced (pi's kept tail is untouched, images there survive).
  • The full state is resent with each question batch (near the state ceiling that is one request per handful of calls).
  • Token sizes are estimates from character counts, not a tokenizer.
  • API keys are read from the environment at session start; never commit one. A project .pi/fast-jev.json is only honored for trusted projects.

Credits

Engine and algorithm by fast-jev-compaction (MIT). pi adaptation by this repository (MIT).