# pi-vcc compacts a Pi coding session by extraction instead of by asking a model

> pi-vcc is an extension for the Pi coding agent that replaces the model's summary of a long conversation with an algorithmic one, pulling the goal, the files changed, the commits, the outstanding errors and the user preferences out of the transcript by extraction, keeping a short tail of the conversation intact, and leaving the full session searchable through a vcc_recall tool. It is MIT licensed, written in TypeScript, and makes no model calls at all.

**sting8k/pi-vcc** — Smart, Fast & Lossless session compaction for Pi. No LLM calls - produces structured, transcript-preserving summaries using pure extraction and formatting.

- Repository: https://github.com/sting8k/pi-vcc
- Stars: 528 · Forks: 52
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/sting8k-pi-vcc

## The idea: do not spend a model call on something a parser can do

pi-vcc is an algorithmic conversation compactor for Pi, and the repository description states the constraint plainly: no LLM calls, it builds the summary by extraction and formatting.

That single design choice determines everything else about the project. Pi's default compaction, like most agent frameworks, asks a model to summarise the conversation so far. That costs tokens, takes as long as a model call takes, and produces a different result every time, since the summary is generated rather than derived. It can also drop things that mattered, because a summary is a lossy operation performed by something that is trying to be fluent.

pi-vcc replaces that with a compiler-like approach, and the inspiration is stated: VCC, the View-oriented Conversation Compiler, which is a project by lllyasviel on the same idea of treating the conversation as something you compile rather than something you summarise.

The comparison table in the readme lays out the differences row by row, and it is the clearest statement of what the project is for.

The method is algorithmic extraction with no LLM, against an LLM-generated summary by default. Determinism is same input, same output, against non-deterministic output that can hallucinate. Size reduction is 97.6% median and 89% at p10 for pi-vcc, against a variable figure for the default. Compaction latency is 1 ms median, 11 ms p90 and 348 ms worst, against waiting for an LLM call. Cost is none, against burning tokens on the summarisation call.

Two rows matter more than the speed and cost ones. History after compaction is gone with the default, since the agent only sees the summary, while with pi-vcc it is searchable with vcc_recall. And repeated compactions are described as each rewrite risking losing more, against sections merging and staying capped.

The size and latency figures are measured over 1,884 real sessions, comparing summary characters against the summarised conversation, and the readme is careful to say that how much of a session's facts survive is measured separately, in the benchmarks directory.

## Installing it and triggering a compaction

Installation goes through Pi's own package installer, and there are three routes.

From npm:

```bash
pi install npm:@sting8k/pi-vcc
```

From GitHub:

```bash
pi install https://github.com/sting8k/pi-vcc
```

And without installing anything at all, which is the fastest way to try it:

```bash
pi -e https://github.com/sting8k/pi-vcc
```

The package is published under the @sting8k scope and its keywords declare it as a Pi package and a Pi extension, with the pi.extensions field pointing at index.ts as the extension entry point.

In use, pi-vcc runs automatically when your context window fills up, or on demand. The /pi-vcc command compacts now, keeping the last user turn. And /pi-vcc keep:N with an optional prompt keeps the last N user turns, where keep:0 compacts everything, and the optional prompt is sent to the agent afterwards.

With the default keep:1 a small tail is grown automatically, which the configuration section describes as the smartKeepTail behaviour. If you would rather leave /compact and the automatic compactions to Pi core, you set overrideDefaultCompaction to false.

There is a boundary condition worth knowing. On a short session /pi-vcc can answer Nothing to compact yet whatever keep:N says, because Pi stops before any extension runs while the whole session still fits in the recent part it always keeps, which is controlled by compaction.keepRecentTokens in Pi's own settings.

So the keep:N parameter is a request, not a command, and on a session that is still mostly inside Pi's recent window there is nothing for the compactor to do. That is the correct behaviour, since compacting a session that already fits would throw away context for no gain.

## What the compacted session actually looks like

The output is a fixed structure with a short transcript at the end, and the readme shows a complete example.

```
[Session Goal]
- Fix the authentication bug in login flow
- [Scope change]
- Also update the session token refresh logic

[Files And Changes]
- Modified: src/auth/session.ts
- Created: tests/auth-refresh.test.ts

[Commits]
- a1b2c3d: fix(auth): refresh token after password reset

[Tracked Commands]
- docker: docker compose restart api 2>&1

[Outstanding Context]
- lint check still failing on line 42

[User Preferences]
- Prefer Vietnamese responses
- Always run tests before committing
```

The rules for each section are listed in a table. Session Goal holds the initial goal and scope changes, and a scope change is marked inline so it is visible that the goal moved. Files And Changes holds files modified, created or read, capped, with paths trimmed to a common root. Commits holds the last 8 commits made in the session, as hash plus subject. Tracked Commands holds recent runs of only the commands listed in trackCommands, which is off by default. Outstanding Context holds unresolved errors and pending questions. User Preferences holds lines like always, never or prefer taken from user messages. And there is a brief transcript, the conversation in order, about 120 recent lines, with each tool call shortened to one line carrying a reference number.

A section only appears when it has something to say, and the example given is that a session with no git commits has no Commits section. That rule is what keeps the output tight: an empty section is noise, and the goal is a summary you can read in a few seconds.

The reference numbers are the other important detail. Each tool call in the transcript gets a number like (#11) or (#14), and those numbers are the same ones the recall tool uses, so the agent can go straight to a specific call. The summary ends with a line telling the agent to use vcc_recall to search for prior work, decisions and context from before this summary, and not to redo work already completed.

On the next compaction the sections are merged with the previous summary and re-capped, and the transcript rolls forward. Merging rather than replacing is what makes repeated compactions safe, and it is the difference between a summary that degrades and one that does not.

## vcc_recall: the part that makes compaction reversible

Pi's default compaction drops old messages for good. vcc_recall reads the raw session file instead, so anything compacted away stays reachable.

The default scope is the active conversation lineage, and scope:"all" also covers edited or retried branches. Only the current session is searchable, which is a deliberate limitation: the tool reads the session file, not a database of everything you have ever done.

Searching works best with plain keywords. Multi-word queries are OR-matched and ranked, rare terms weigh more, and a regex is accepted, falling back to keywords if it matches nothing.

```
vcc_recall({ query: "auth token" })                  // ranked OR search
vcc_recall({ query: "auth token", page: 2 })         // 5 results per page
vcc_recall({ query: "hook|inject" })                 // regex
vcc_recall({ query: "auth token", scope: "all" })    // all lineages
```

The reference numbers from the summary are the same numbers recall uses, so the agent can go directly to them:

```
vcc_recall({ range: [1250, 1290] })                  // entries in order, 20 per page
vcc_recall({ expand: [1253] })                       // full untruncated text
vcc_recall({ mode: "touched" })                      // files worked on, with #N
vcc_recall({ query: "#1253:auth.ts" })               // a file's content from #1253
```

Each call does one of these, and page and scope work with all of them. The one design decision here that deserves credit is the failure mode: a param the call cannot use is named in the output instead of dropped silently. In an agent context, a silently ignored parameter looks like a search that found nothing, and the agent concludes the information does not exist rather than that it asked the wrong question.

The same search is available as a slash command, with results shown in the chat and passed to the agent:

```
/pi-vcc-recall auth token scope:all
```

That last form is the one for a human at a keyboard, and it is what turns the recall mechanism from an internal tool into something you can use yourself when the agent asks you to repeat something it should have remembered.

## How the compaction is computed, and how it is configured

The algorithm is four steps and none of them involves a model.

First, pick the cut: everything before the kept tail is summarized and the tail stays as it is. Second, normalize Pi messages into uniform blocks and drop noise, specifically system messages and empty blocks. Third, extract the sections and the brief transcript, and format them. Fourth, if there is a previous summary, merge into it.

The closing line is the important one: no step calls a model, and token counts are estimated from the session's own numbers. So the size of the summary is measured in the same units the agent uses, and there is no model in the loop to slow the path down or to change the answer.

Configuration lives at pi-vcc-config.json in Pi's agent directory, which is ~/.pi/agent or $PI_CODING_AGENT_DIR if set, and the file is created with these defaults on first load:

```json
{
  "overrideDefaultCompaction": true,
  "smartKeepTail": true,
  "continueAfterThresholdCompact": true,
  "debug": false,
  "skipForProviders": [],
  "skipCustomTypes": [],
  "trackCommands": []
}
```

The six defaults each control something specific. overrideDefaultCompaction at true means pi-vcc handles /pi-vcc, /compact and automatic compactions, and with it false pi-vcc only handles /pi-vcc; existing config files keep their value rather than being reset. smartKeepTail at true means that if the keep:1 tail is under 5k tokens, it keeps as many turns as fit in 25k, which the readme notes is pi-vcc's own limit rather than Pi's. continueAfterThresholdCompact, debug, skipForProviders, skipCustomTypes and trackCommands round out the set, with trackCommands empty by default, which is why the Tracked Commands section is empty unless you ask for it.

The peer dependency range is worth noting for anyone on a different Pi version. The package requires @earendil-works/pi-coding-agent from 0.74.0 up to but not including 2.0.0, and typebox from 1.1.24 up to 2.0.0, and the only script in package.json is a typecheck that invokes tsc with explicit compiler flags rather than reading a tsconfig.

The repository root also carries a benchmarks/ directory, a CHANGELOG.md, an AGENTS.md, and a bun.lock, which is a hint that the toolchain is Bun rather than npm despite the package being published to npm.

## Where pi-vcc fits, and where it stops

The comparison worth making is with the default compaction it replaces, and with a larger context window.

Against the default compaction, the difference is in kind rather than degree. The default produces prose written by a model, which is readable and lossy and non-deterministic. pi-vcc produces a fixed set of sections derived from the transcript, which is terse and deterministic and searchable, and which keeps the original session intact so nothing is lost for good. The cost is that the output reads like a report rather than a narrative, and an agent asked to summarise what happened will not find a summary in the prose sense.

The 97.6% median size reduction is the number that makes the case, but the row that really matters is the one about history after compaction. A default compaction is a one-way door: once the old messages are dropped, the only thing that survives is whatever the model chose to write down. pi-vcc turns compaction into a reversible operation, which is a different relationship between the agent and its own history.

The limits are visible in the configuration and the scope. The tracked commands feature is off by default because collecting command output is opt-in. Only the current session is searchable, so this does not build you a long-term memory across sessions. The skipForProviders and skipCustomTypes options exist because some providers or message types cannot be extracted from reliably, and the readme does not detail which ones. And the extraction is pattern-based: the User Preferences section looks for lines like always, never or prefer, which will catch explicit preferences and miss preferences expressed in other ways.

There is also a measurement caveat the readme is upfront about. The size and latency numbers come from 1,884 real sessions, and how much of a session's facts survive is measured separately in the benchmarks directory. Those are two different claims, and the second is the one that matters if you are deciding whether the compaction is losing anything, since a small structured summary that drops the one fact you needed is worse than a longer one that keeps it.

On maintenance, the project is moving quickly. The releases are v0.10.2 from 2026-10-15, v0.10.1 from 2026-10-12 and v0.10.0 from 2026-10-07, so three releases in eight days, with the last push on 2026-10-15. A version 0.x package with a fast release cadence is one to watch rather than to depend on without pinning, though the licence is MIT and the peer dependency range is explicit about which Pi versions it supports.

## Conclusion

pi-vcc suits a Pi user whose sessions get long enough that the agent keeps forgetting earlier decisions, since the compaction is deterministic, costs nothing in tokens and leaves the original session searchable, so the information is not simply gone the way it is with the default summary. It is the wrong tool if you want a fluent natural-language summary of what happened, because the output is a fixed set of sections rather than prose, and it is the wrong tool if you are on a Pi version outside the supported peer range, since the package requires @earendil-works/pi-coding-agent from 0.74.0 up to 2.0.0. Before you rely on it, read the benchmarks README, because the size and latency figures are measured over real sessions and the fact-retention figure is measured separately, and check what the default keep:1 tail means for the shape of the summary you will get.

## FAQ

### What is pi-vcc?

It is an algorithmic conversation compactor for the Pi coding agent, published as the npm package @sting8k/pi-vcc and inspired by VCC, the View-oriented Conversation Compiler. It builds the summary by extraction and formatting and makes no LLM calls, so the same input always produces the same output.

### How do I install pi-vcc?

Run pi install npm:@sting8k/pi-vcc, or pi install https://github.com/sting8k/pi-vcc to install from GitHub. To try it without installing anything, run pi -e https://github.com/sting8k/pi-vcc.

### What sections does a pi-vcc summary contain?

Up to six: Session Goal for the initial goal and scope changes, Files And Changes for files modified, created or read, Commits for the last eight commits made in the session, Tracked Commands for recent runs of commands listed in trackCommands, Outstanding Context for unresolved errors and pending questions, and User Preferences for lines like always, never or prefer. There is also a brief transcript of about 120 recent lines. A section appears only when it has something to say.

### What does vcc_recall do?

It reads the raw session file rather than the compacted conversation, so anything dropped by compaction stays reachable. It searches the active lineage by default, with scope:"all" covering edited or retried branches, and accepts keyword queries, regex, ranges of entry numbers, expand for full untruncated text, and a touched mode listing files worked on.

### Where is the pi-vcc configuration file?

At pi-vcc-config.json in Pi's agent directory, which is ~/.pi/agent or $PI_CODING_AGENT_DIR if set. It is created with defaults on first load, including overrideDefaultCompaction and smartKeepTail both true, debug false, and empty skipForProviders, skipCustomTypes and trackCommands lists.

### How much does pi-vcc reduce a session, and how fast is it?

The readme reports 97.6% median size reduction and 89% at p10, with compaction latency of 1 ms median, 11 ms p90 and 348 ms worst, measured over 1,884 real sessions. How much of a session's facts survive is measured separately in the benchmarks README.

## Sources

- [Issues](https://github.com/sting8k/pi-vcc/issues)
- [License: MIT](https://github.com/sting8k/pi-vcc/blob/master/LICENSE)
- [README](https://github.com/sting8k/pi-vcc/blob/master/README.md)
- [Releases](https://github.com/sting8k/pi-vcc/releases)
- [sting8k/pi-vcc on GitHub](https://github.com/sting8k/pi-vcc)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sting8k-pi-vcc
