pi-jev-compact
Verbatim context compaction for pi, powered by the TypeSafe Jev model
Package details
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
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.jsonis only honored for trusted projects.
Credits
Engine and algorithm by fast-jev-compaction
(MIT). pi adaptation by this repository (MIT).