mirror of
https://github.com/teamchong/pxpipe.git
synced 2026-07-22 02:02:51 +02:00
08b1b43b1e
Two fixes to the image-cost prediction that gates compression: 1. **Content-aware image cost.** The old gate used a fixed `TOKENS_PER_IMAGE_SINGLE_COL = 2500` constant per image, modelling every tool_result block as a full 1568px canvas. The renderer actually produces images sized to the wrapped line count, so a 5,000-char tool_result becomes a ~80px-tall image costing ~54 tokens, not 2,500. Result: the break-even for small blocks was over-estimated by ~50x and the gate rejected anything below ~10k chars even though image-form was cheaper. Replace `estImages × effectiveTokensPerImage(numCols)` with a single content-aware `imageTokensCost(text, cols, numCols, imageCountCap)` that mirrors the renderer's height math: `tokens = (rows + 1) × overhead + fullImageRows × perRow`, derived from the cold-miss anchor and applied row-proportionally for partial final images. Calibrated against N=33 production cold-miss measurements (median multiplier 1.05, mean 1.32 — high-image case is ~1.05x of the documented `width × height / 750` rate). 2. **Width-shrinking on per-block paths.** For per-block call sites (tool_result, reminder) the renderer now narrows the canvas width to the longest wrapped line via `shrinkColsToContent`. Multi-col layouts already pack tightly; this captures the single-col savings that were previously paying for whitespace. The gate threads `shrinkWidth` through to `evalCompressionProfitability` / `isCompressionProfitable` / `isCompressionProfitableAmortized` so the prediction matches what the renderer will actually produce. System-slab and history-collapse paths pass `shrinkWidth=false` — they fill the configured canvas deliberately. Knobs removed: `MinToolResultChars` and `MinReminderChars` now default to 0 (let the math decide). The TransformOptions fields are kept for env-override observability but no longer set a floor in production. `isCompressionProfitable` / `evalCompressionProfitability` / `isCompressionProfitableAmortized` are now string-only at the public API; the numeric-length fallback is gone (it under-counted images and silently leaked net-losing compressions through). Tests: gate-flap and history.test updated for the new physics, but 24 tests in render.test.ts still assert the OLD over-estimation as truth (e.g. "5,000 chars is not profitable", "7000 chars stays as text"). They need to be deleted or have their expected verdicts inverted — left for the next session to finish the rewrite cleanly. Typecheck passes. Measured impact: the production tail's $1.43 flap is gone and per-block tool_result/reminder content is now genuinely compressed when it would save tokens, not just when it crosses the (wrong) 10k-char threshold.