v3.3.0 — image-guard pipeline (#87)
image-guard pipeline (#87)
Replaces v3.2.1's static CACHE_FIX_IMAGE_MAX_DIM with a conditional pipeline that mirrors Anthropic's actual image rules: the per-image dimension ceiling depends on image count (2000 px when count > 20, else 8000 px), the API enforces a 32 MB request body cap independently, and current-generation models accept up to 100 images per request. The new pipeline addresses all three axes; MAX_DIM only addressed the dimension axis with a single static value that overcorrected for ≤20-image requests.
Pipeline
Five passes, all gated by a single top-level env var (CACHE_FIX_IMAGE_GUARD=1):
| Pass | Trigger | Action |
|---|---|---|
| Pass 0 (legacy back-compat) | CACHE_FIX_IMAGE_KEEP_LAST=N set |
Strip tool_result images from user messages older than N most recent |
| Pass 3 (opt-in) | CACHE_FIX_IMAGE_PRESERVE_DETAIL=1 AND long edge > model native cap |
Lanczos resize via sharp to native cap (2576 px Opus 4.7, 1568 px otherwise), preserve aspect ratio and media type |
| Pass 1 | long edge > active rejection cap | Strip with forensic placeholder. Cap = MAX_DIM if set, else 2000 (count > 20) or 8000 (count ≤ 20) |
| Pass 2 | request body bytes > CACHE_FIX_IMAGE_REQUEST_SIZE_MAX (default 30 MB) |
Drop oldest images until under budget |
| Count cap | image count > CACHE_FIX_IMAGE_COUNT_MAX (default 100) |
Drop oldest images down to cap |
Execution order: Pass 0 → Pass 3 → Pass 1 → Pass 2 → count cap. Each pass is independent — Pass 1 never resizes; Pass 3 never strips. README's precedence matrix documents every supported env-var combination.
Optional sharp peer dependency
Pass 3 requires sharp for Lanczos resize. Declared in peerDependenciesMeta only — users who don't want it pay nothing:
npm install sharpIf sharp is missing, Pass 3 logs library_missing and skips; Passes 0/1/2 + count cap still run.
New env vars
CACHE_FIX_IMAGE_GUARD=1— top-level pipeline gateCACHE_FIX_IMAGE_PRESERVE_DETAIL=1— enable Pass 3 Lanczos resize viasharpCACHE_FIX_IMAGE_REQUEST_SIZE_MAX=<bytes>— Pass 2 byte budget (default 31457280 = 30 MB)CACHE_FIX_IMAGE_COUNT_MAX=<n>— hard image-count cap (default 100; legacy Claude 1/2.x/Instant users can set 600)
Telemetry
New ctx.meta.imageGuardStats carries the full counter set (counts + bytes + estimated tokens + library_missing flag). One stderr line per processed request when the pipeline did anything observable:
[image-guard] resized=3 evicted=1 req_bytes=35M->28M (headroom=2M) images=8->7
Back-compat
All v3.2.1 legacy paths (CACHE_FIX_IMAGE_KEEP_LAST only, CACHE_FIX_IMAGE_MAX_DIM only, both together) continue to work exactly as before — no migration required for existing users.
Tests
553 → 597 (44 new in proxy-image-guard.test.mjs, covering activation, every Pass, count cap, all 10 precedence-matrix rows, telemetry shape, sharp-unavailable + sharp-throws fallbacks, Pass 1 stderr emission, post-count-cap byte recompute). Pass 3 sharp tests use injected mocks — no real sharp install required to run the suite.
Install
npm install -g claude-code-cache-fix@3.3.0For Pass 3 (Lanczos resize), additionally:
npm install -g sharpSee README.md for the full precedence matrix and tunables, and docs/extension-impact-guide.md for the impact analysis.