pi-cap-context-images
Bound the number of images kept in a pi session's outgoing provider payload. Prevents the 'infinite compaction' loop caused by base64 screenshots (browser/winshot/image tools) accumulating in context — compaction can summarize text but can only keep or dr
Package details
Install pi-cap-context-images from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-cap-context-images- Package
pi-cap-context-images- Version
0.1.0- Published
- Jun 2, 2026
- Downloads
- not available
- Author
- blue-b
- License
- MIT
- Types
- extension
- Size
- 17.9 KB
- Dependencies
- 0 dependencies · 1 peer
Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-cap-context-images
Stop long pi coding agent sessions from getting stuck in an endless compaction loop when screenshots pile up. Keeps only the most-recent images on the wire to the model, so accumulated base64 captures can never blow past the context limit.
English | 한국어
Zero dependencies, ~100 lines. One before_provider_request hook, no native modules, no extra services.
Why
Tools like browser automation (pi-playwright) and screen capture (pi-winshot) hand the model base64 images. In a long session these stack up — and here's the trap:
Compaction can summarize text, but it cannot shrink an image. It can only keep an image whole or drop it whole.
Once a few dozen screenshots are sitting in the verbatim "recent" region that compaction preserves, every compaction pass keeps them all. tokensBefore never falls below the threshold, so the agent compacts again… and again… forever.
This is not hypothetical. A single real session accumulated 51 images ≈ 4.5 MB and fired 6 back-to-back compactions at ~900K–968K tokens that never converged — the session was effectively frozen.
pi-cap-context-images removes the root cause: it caps how many images ever reach the provider, so token usage stays bounded and compaction can actually do its job.
How it works
pi fires before_provider_request with the full outgoing payload and lets an extension return a modified copy — the same public hook the built-in sanitize-tool-call-ids extension uses. On every request this extension:
- walks the payload in document order and finds every image content block,
- keeps the most-recent
Nimages (default3), - replaces the older ones with a one-line text placeholder.
conversation (oldest → newest)
┌────────────────────────────────────────────────┐
│ 🖼 🖼 🖼 🖼 🖼 🖼 🖼 🖼 🖼 🖼 │
│ ↓ ↓ ↓ ↓ ↓ ↓ ↓ │
│ [placeholder × 7] 🖼 🖼 🖼 │ → sent to model
└────────────────────────────────────────────────┘
└── KEEP_IMAGES (3) ──┘
The model still sees your latest screenshots, so active visual work keeps working — only the stale ones are dropped from the wire payload.
Only the outgoing payload is touched. The persisted session
.jsonlis left intact, so your transcript and scrollback still show every screenshot you ever captured.
Image block shapes handled: pi-internal {type:"image", data, mimeType}, Anthropic {type:"image", source:{…}}, and OpenAI {type:"image_url", image_url:{…}}.
Install
pi install pi-cap-context-images
/reload
or from a clone:
git clone https://github.com/Blue-B/pi-cap-context-images
pi install ./pi-cap-context-images
/reload
or, if you keep local packages, add the folder to packages in your pi settings.json (path is relative to the settings file):
{
"packages": [
"../../projects/pi-cap-context-images"
]
}
Requirements
- pi coding agent ≥ 0.70.
- Nothing else — it's a single hook with no runtime deps.
Config
| Env var | Default | Meaning |
|---|---|---|
PI_CAP_CONTEXT_IMAGES |
3 |
How many of the most-recent images to keep on the wire. 0 strips every image. |
PI_CAP_CONTEXT_IMAGES=5 pi # keep the last 5 screenshots instead of 3
Project layout
pi-cap-context-images/
├── package.json
├── extensions/cap-context-images/index.ts # the before_provider_request hook
├── README.md
└── LICENSE
Revert
Remove the packages entry (or pi uninstall pi-cap-context-images) and /reload.
Sponsor
If this extension saved your session from an infinite-compaction freeze, supporting the project directly funds maintenance:
- Your support helps: keeping the image-block detection in sync as pi and provider payload formats evolve, testing across providers (Anthropic / OpenAI / bridge), and faster issue response.
- Transparency: funds go to maintenance time and testing infra. One-time donations stay one-time — no obligations.
- Monthly sponsors ($3/mo via GitHub Sponsors) get best-effort priority triage for "Sponsor Request" issues.
License
MIT