can1357--oh-my-pi
16 KiB
16 KiB
Changelog
[Unreleased]
Changed
- Changed archived transcript rendering to compact
¶user:,¶think:,¶ai:, and¶call:scopes; repeated adjacent scopes now continue as plain lines, tool-call intents trail calls as//comments, and the compaction prompt documents the format.
[16.3.7] - 2026-07-05
Fixed
- Fixed
resolveShapeForText(..., "auto")to correctly select thesilver16-bwshape for CJK-heavy transcript text while preserving explicit shape overrides.
[16.2.8] - 2026-06-30
Fixed
- Fixed large snapcompact archives being reconstructed into unbounded per-request image payloads by adding a frame base64 byte budget and omitting over-budget archive frames from prompt blocks. (#3792)
[16.2.7] - 2026-06-30
Added
- Added the
silver16-bwshape backed by an embedded Silver TrueType font to support CJK and other non-Latin text. - Added
resolveShapeForTextto support font-aware shape resolution.
Changed
- Improved non-ASCII text normalization by folding semantic emojis to ASCII labels (e.g.,
[OK],[WARN]), dropping decorative emojis, and folding box-drawing symbols to ASCII skeletons. - Enhanced missing glyph rendering to use the embedded Silver TrueType fallback per-character, including support for East Asian wide characters across two grid cells.
- Updated text wrapping, pagination, and provider shape geometries to support wide character footprints and updated X.org 8x13 font metrics.
[16.1.23] - 2026-06-26
Added
- Added
archiveSourceText(archive)to extract a persisted frame archive's source text as plain text for LLM summarization. (#3561 by @serverinspector) - Added
stripPreservedArchive(preserveData)to drop the persisted frame-archive slot (PRESERVE_KEY) and collapse toundefinedwhen no other state remains — shared by the agent and coding-agent compaction paths instead of duplicating the strip rule.
[16.1.13] - 2026-06-22
Fixed
- Fixed the Umans provider image budget to match its 10-image request cap.
[16.1.8] - 2026-06-20
Breaking Changes
- Changed core rendering functions
renderandrenderManyto be asynchronous
[16.1.0] - 2026-06-19
Added
- Added
historyBlocks(archive)to reconstruct ordered history blocks from archive data
Changed
- Refactored compaction to be text-sourced, re-rendering from unified
Archive.textsource - Implemented foveated archive layout (HQ edges, dense LQ middle) for optimized context usage
- Raised
MAX_FRAMES_DEFAULTto 80 and consolidatedPROVIDER_IMAGE_BUDGETS - Updated OpenRouter to use standard 90-image budget
- Updated prompt instructions to clearly distinguish between plain-text and image history regions
Options.maxFramesis now an upper limit clamped toMAX_FRAMES_DEFAULT, not a per-call default- Rewrote the resume summary prompt into a structured reading guide (turn headings, grid/two-column layout, ink notes) and render file operations inline as a
FILESsection instead of a spliced<files>tag
Fixed
- Fixed context budget undercounting by raising
FRAME_TOKEN_ESTIMATEto 5024 - Improved file list formatting in compaction summaries
[16.0.11] - 2026-06-19
Changed
- Refined elision markers for file operations and truncated text for better display consistency
- Updated summary text for consistent descriptions of archived tool output
- Folded a much wider range of Unicode to ASCII in
normalize()before native rendering: added a per-character Unicode NFKD decomposition fallback (fullwidth forms, super/subscripts, ligatures, circled and math-styled alphanumerics, Roman numerals, vulgar fractions) and expanded theCHAR_FOLDpunctuation table (more quotes/primes, hyphens, the fraction slash, dot leaders, bullets, and arrows) so undrawable glyphs land on close ASCII equivalents instead of?
[16.0.8] - 2026-06-18
Added
- Added
<out>block wrapping for tool results to improve document structure - Rendered thinking process as italicized blocks above assistant text
- Displayed tool call intents as
//comments in tool call headers - Changed conversation role markers to standard Markdown headings
Changed
- Merged tool results into their corresponding tool call blocks
- Preserved prose formatting around tool calls to maintain conversation flow
- Hidden
_iargument from tool call output when an intent is provided - Optimized assistant turn output to group thinking and text blocks efficiently
Fixed
- Fixed improper splitting of assistant messages around useless tool calls
[16.0.1] - 2026-06-15
Added
- Added
openai-codexto first-party provider image budgets so ChatGPT Plus/Pro Codex sessions use the same 200-image request cap as OpenAI API sessions instead of the unknown-provider floor.
[15.13.1] - 2026-06-15
Added
- Added two spacing-tuned frame variants to
SHAPE_VARIANTS:8on22-bw(8x13 glyphs on a 22px pitch — extra line spacing) and11on16-bw(8x13 glyphs on an 11px advance — extra letter spacing). Both pin the indexedstretch: falsepath, so the native renderer draws natural-size glyphs on the padded cell box (the Rust path already advances bycellWidthand the new variants validate horizontal padding)
Changed
- Changed the per-provider default shapes to the spacing-tuned cells. The previous shapes were tuned on the SQuAD prose eval, where dense cells won; a new tool-result legibility benchmark (
research/toolbench.py— realsearch/read/findoutput with structure-sensitive QA) showed the prose-era density erases the line numbers and indentation that code/search output depends on. Anthropic moves from6x12-dimto11on16-bw(opus-4.8 f1 .806 vs .755 for plain8on16-bwand .351 for6x12-dim, which fell below the OCR ~16px/char floor and abstained); OpenAI and Google move to8on22-bw(gemini-3.5-flash f1 .934 vs .807 for8on16-bwand .287 fordoc-8on16-sent-dim; same leading win on gpt-5.5/gpt-5.4-mini). Kimi and GLM keep their measured8on16-bw. The bigger cells pack fewer chars per frame, so inline frame-swapping now breaks even at a larger tool-result size
[15.12.1] - 2026-06-12
Changed
serializeConversationnow skips tool call/result pairs whose result is flagged contextually useless (useless: true, non-error), so archived frames stop carrying zero-match searches and timed-out waits
[15.11.7] - 2026-06-12
Added
- Added
SHAPE_VARIANTS, the catalog of research-eval frame variants the native renderer reproduces faithfully (8x8r/8x8u/6x6u/5x8×sent/bw), withShapeVariantName,SHAPE_VARIANT_NAMES, and theisShapeVariantNameguard resolveShape(api, variant?)now accepts an explicit variant name (or"auto"); forced variants keep their geometry but are re-priced for the target provider's image billing (token estimate and OpenAIoriginaldetail hint)- Added the six research-eval winning frame variants to
SHAPE_VARIANTS:6x12-dim(Claude fable),8x13-bw(Opus),8on16-bw(GPT grid runner-up),doc-8on16-bw(GPT),doc-8on16-sent(GLM), anddoc-8on16-sent-dim(Gemini/Kimi), backed by newShapefieldsstretch(disable Lanczos stretch: natural glyphs on a larger cell pitch),columns(two word-wrapped newspaper columns),stopwordDim, and the X.org6x12/8x13fonts - Added
dimStopwords(), which prints high-frequency function words in dim ink via zero-width markers (skipping spans that are already dim), andwrap(), the greedy word-wrap used to typeset doc-layout pages;geometry/render/renderMany/frames/compactunderstand doc shapes (wrap once, paginate into2 * rows-line pages), and compaction frames persistcolumns/stopwordDimfor mixed-shape detection resolveShapenow takes aShapeTarget({ api, id }— a pi-aiModelworks as-is) and detects the ideal shape from the model id, not just the wire API: a Claude routed through Vertex or an OpenAI-compatible gateway keeps its Claude shape, with billing still priced by the API family actually carrying the request.idealShapeVariant(modelId)exposes the model-line table; unmeasured models fall back to the API family's winnerresolveShapenow also resolves an ideal frame size per model line, and billing estimates come from verified per-family formulas instead of flat 1568px constants: Anthropic bills 28px patches capped at 4,784 visual tokens (+5% margin), Gemini 3.x bills a fixed 1,120-tokenmedia_resolutionbudget per image at any pixel size, and OpenAI bills 32px patches × 1.2 under the 10,000-patchdetail: "original"budget. High-res Claude lines (Opus 4.7+, Fable, Mythos — native 2576px-edge ingestion) get 1932px frames (same recall and cost, a third fewer frames); Gemini gets 2048px frames (+70% chars per frame at the same bill); GPT and Kimi stay at 1568px (area-proportional billing and a model-side 1792px processor cap, respectively).idealShapeVariantnow returns anIdealShape({ variant, frameSize? })- Added per-provider image-count budgets:
PROVIDER_IMAGE_BUDGETS,DEFAULT_PROVIDER_IMAGE_BUDGET,providerImageBudget(), andproviderFrameBudget()(the image budget clamped toMAX_FRAMES). OpenRouter is capped at its measured hard limit of 8 images per request (excess images are silently dropped with no error); unknown providers get a safe floor of 5 - Added
Archive.textTail: archive content past the frame budget is no longer dropped —compact()stops rendering at the budget and keeps the newest unframed slice as verbatim text on the summary (capped at two frame capacities with middle elision, counted intotruncatedCharswhen elided). The tail persists inpreserveDataand is folded back into frames by the next compaction
Changed
- Frames are no longer padded to a square: the native renderer clips each PNG's height to the text rows actually printed, so a partially filled frame (typically the newest) bills only the pixel rows it uses
- Changed the OpenAI default shape from
6x6u-sentto8on16-bw. A production-regime mono eval (gpt-5.5, the full 800k-char SQuAD flow in one request, n=50) scored the old dense default f1 .602 vs .851 for8on16-bwrendered by the production pipeline, at near-equal total cost (the dense cells burned the frame savings on reasoning tokens); chunked exp14 had already scored8on16-bw.906.SHAPES.openaiDenseis renamed toSHAPES.openai - Changed the Google default shape from
8x8r-senttodoc-8on16-sent-dim. Production-rendered mono eval on gemini-3.5-flash (400k chars, one request, n=25): f1 .900 vs .853 for the repeated grid at lower cost, agreeing with the chunked round-2 winner - Changed the Anthropic default shape from
8x8r-bwto6x12-dim. Production mono eval on claude-fable (400k chars, one request, n=25): f1 .840 vs .877 for the repeated grid — within noise — at 37% lower cost (12 frames instead of 21 per 400k chars), with clean completions in every probe; opus reads the same trade (.800 vs .833 at 42% lower cost) normalize()now keeps line structure: whitespace runs containing a line break collapse toNEWLINE_GLYPH(U+2588 FULL BLOCK, drawn by the native renderer as a pitch-black cell one character wide) instead of a plain space; leading/trailing breaks are trimmed, and the frame-reading prompt explains the markernormalize()now skips characters the fonts cannot render instead of printing?blanks: whole ANSI escape sequences are stripped, and bare control characters, zero-width format characters (ZWSP, BOM, directional marks), combining marks, and lone surrogates are dropped without occupying a cell;?remains the fallback for unsupported graphic characters only
[15.11.4] - 2026-06-12
Breaking Changes
- Renamed every export to drop the
snapcompact/Snapcompact/SNAPCOMPACT_qualifier — the package is meant to be consumed viaimport * as snapcompact from "@oh-my-pi/snapcompact". Functions:snapcompactCompact→compact,renderSnapcompactFrame→render,snapcompactGeometry→geometry,normalizeForSnapcompact→normalize,serializeSnapcompactConversation→serializeConversation,snapcompactImages→images,getPreservedSnapcompactArchive→getPreservedArchive,isSnapcompactShape→isShape,resolveSnapcompactShape→resolveShape,createSnapcompactFileOps→createFileOps,computeSnapcompactFileLists→computeFileLists,upsertSnapcompactFileOperations→upsertFileOperations. Types:SnapcompactShape→Shape,SnapcompactFrame→Frame,SnapcompactArchive→Archive,SnapcompactGeometry→Geometry,SnapcompactOptions→Options,SnapcompactSerializeOptions→SerializeOptions,SnapcompactFileOperations→FileOperations,SnapcompactCompactionDetails/Preparation/Result→CompactionDetails/CompactionPreparation/CompactionResult,SnapcompactConvertToLlm→ConvertToLlm. Constants:SNAPCOMPACT_X→X(SHAPES,FRAME_SIZE,MAX_FRAMES,FRAME_TOKEN_ESTIMATE,PRESERVE_KEY,TOOL_RESULT_MAX_CHARS,TOOL_ARG_MAX_CHARS,TOOL_CALL_MAX_CHARS,TRUNCATE_HEAD_RATIO,DIM_ON,DIM_OFF).
Added
- Added
renderMany()for paging arbitrary text into snapcompact PNG frames as LLM image blocks, andframes()for predicting the frame count without rendering
[15.11.0] - 2026-06-10
Breaking Changes
- Changed
renderSnapcompactFrameoutput frompng: Uint8Arraytodata: stringbase64, requiring consumers to read frame payloads fromframe.data
Added
- Added new serialization options
toolResultMaxChars,toolArgMaxChars,toolCallMaxChars,truncateHeadRatio, anddimToolResultstosnapcompactCompact/serializeSnapcompactConversationso callers can tune how tool results and arguments are archived - Added exported default constants
SNAPCOMPACT_TOOL_RESULT_MAX_CHARS,SNAPCOMPACT_TOOL_ARG_MAX_CHARS,SNAPCOMPACT_TOOL_CALL_MAX_CHARS, andSNAPCOMPACT_TRUNCATE_HEAD_RATIOfor reuse when configuring truncation limits - Added provider-specific snapcompact frame-shape presets and shape helpers (
SNAPCOMPACT_SHAPES,resolveSnapcompactShape,isSnapcompactShape) so callers can consistently select validated image-frame geometry for archive renders - Added
file-operations.mdandsnapcompact-summary.mdprompts to preserve file-read/write context and frame metadata in the compaction prompt flow - Added a full
packages/snapcompact/researchexperiment and visualization suite for running snapcompact SQuAD studies, provider probes, and activation-style analyses - Added package-level TypeScript exports and publication config so consumers can import
@oh-my-pi/snapcompactwith typed access to snapcompact APIs - Published
@oh-my-pi/snapcompactas the reusable snapcompact compaction package, including bitmap-frame rendering helpers, archive helpers, and the localsnapcompactCompact()strategy.
Changed
- Changed truncation in archived tool output to keep both the beginning and end of long text using a configurable head/tail ratio instead of a single hard cut
- Changed tool-result text rendering so archived tool results are shown in dim gray ink by default and the summary prompt notes that dim text is archived tool output
- Changed
RenderedFramevisible-character accounting socharsno longer includes invisible dim-control markers - Changed the file-operations summary block to a single
<files>tag: one grouped, prefix-folded directory tree with per-file(Read)/(Write)/(RW)markers, replacing the separate<read-files>/<modified-files>lists;upsertSnapcompactFileOperationstakes the cumulative read set to distinguish(RW)from blind writes
Fixed
- Fixed frame rendering at archive chunk boundaries to reopen dim spans when a chunk ends inside a dimmed tool-result segment
- Fixed message serialization to strip user- and assistant-provided dim markers so only renderer-generated dim spans can be applied