feat(compact): route /compact through the ACP compression pipeline - #143
Open
ranxianglei wants to merge 2 commits into
Open
feat(compact): route /compact through the ACP compression pipeline#143ranxianglei wants to merge 2 commits into
ranxianglei wants to merge 2 commits into
Conversation
added 2 commits
August 14, 2026 00:07
Intercept Pi's session_before_compact: instead of cancelling native compaction, pick a compressible span (selectRangeSpan), summarize it with a model, and applyCompression, then hand the summary back to Pi as the compaction result. On any failure (no compressible ranges, no usable model, unparseable response, kernel rejection, exception) return undefined so Pi falls back to its own compaction rather than losing context. The summary prompt is built from the kernel's load-bearing compression rules (compressPhilosophy + howToCompressRules) via the Prompts interface, so /compact honors acp.json prompt overrides and stays consistent with the compress tool — NOT a hand-rolled prompt that would drift from the rules. Model resolution: explicit compressModel (provider:modelId in acp.json) wins, else the current session model (zero-config). Adds @earendil-works/pi-ai as a devDependency for the complete() type (kept external at runtime via tsup). Extracted from #119 (lsmir2).
readCompressModel uses os.homedir(), which reads USERPROFILE on Windows (not HOME). The three home-scoped tests only set HOME, so they read the real home dir on Windows CI and failed. Extract a withHome helper that sets both env vars.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Intercept Pi's
session_before_compactand route it through the ACP compression pipeline instead of cancelling native compaction: pick a compressible span, summarize it with a model,applyCompression, then hand the summary back to Pi as the compaction result.How
processTurn→ get compressible rangesselectRangeSpan→ pick a span ≥minCompressRange(seeds on largest range, expands by smallest gap)summarizeRange→ call a model (compressModelor session model) with the sliceapplyCompression→ create an ACP block{ compaction: { summary, firstKeptEntryId, tokensBefore } }so Pi stores itFallback: on any failure (no compressible ranges, no usable model, unparseable response, kernel rejection, exception) return
undefined→ Pi falls back to its own compaction. Context is never lost.Summary prompt uses the kernel
Prompts(key design choice)The summary-generation system prompt is built from the kernel's load-bearing compression rules (
compressPhilosophy+howToCompressRules) via thePromptsinterface — not a hand-rolled constant. This means:/compacthonorsacp.jsonprompt overrides (the samePromptsthe compress tool + tier-1 compression use)/compactand thecompresstool)howToCompressRulesare the right rule set (/compactcompresses an old contiguous range, not a tier-2/3 distillation)Config
compressModelin~/.pi/acp.jsonasprovider:modelId(e.g."openai:gpt-4o"). When unset, falls back to the current session model — so/compactworks with zero config.Dependency
Adds
@earendil-works/pi-aias a devDependency for thecomplete()type (keptexternalat runtime via tsup — resolves inside Pi where pi-ai is installed).ctx.modelRegistryis a synchronous facade that deliberately does not exposecomplete()/stream(), so the standalone import is the supported path.Files
src/auto-compress.ts(new) — range helpers +summarizeRange+buildSummaryPromptsrc/index.ts—wireCompactionDisableinterceptiontests/auto-compress.test.ts(new) — 19 teststests/integration.test.ts— updated compaction-contract testValidation
typecheck ✓ / 294 tests pass (19 new) ✓ / build ✓
Not included (split into separate PRs)
usageTriggerPercentauto-nudge (dropped — redundant with kernel growth/overLimit triggers)acp_summary_surfaced as inlineusermessage (dropped — redundant with the block; compress tool is the compression)capToolOutputrefactor (separate concern)Extracted from #119 (thanks @21307369).