- Added Google provider thinking configuration parameters and force-reasoning-off controls.
- Implemented MCP SSE stream resumption using Last-Event-ID and `SSEResumeError`.
- Added support for TAR old-GNU sparse extension blocks, path length checks, and archive entry overrides.
- Restricted external thinking support to specific models and added semver fallback parsing.
Versionless Fable/Mythos aliases (bundled claude-fable-latest) never parse a numeric version, so the parser path missed them and they fell to the 1568px default. Restored the /claude.*(fable|mythos)/i rule ahead of the generic Claude rule, mapping to the shared high-res tier.
Added regressions for anthropic/claude-fable-latest and its ~ prefixed alias.
Replaced the local Opus version regex with the shared catalog Anthropic identity and semantic-version parser. This recognizes both kind-first and version-first model IDs, provider proxy prefixes, and multi-digit minor versions while preserving the 4.7 floor.
Added regressions for anthropic--claude-4.8-opus and claude-opus-4-10.
MODEL_VARIANTS gated the 1932px frame tier on /claude-?opus-?4[.-][7-9]/i,
so claude-opus-5 fell through to the generic /claude/i entry and rendered at
the 1568px default reserved for older lines that downscale. The 1932px tier
tracks the Anthropic 4,784 visual-token cap — a family-wide billing property
opus-5 shares with opus-4-8 — so the version bound was stale rather than a
per-version eval gap.
Widened the pattern to cover Opus 5 and later; 4.0-4.6 still keep the safe
1568px default. Documented why 1932 specifically (largest square not
downscaled under the 4,784-patch cap, kept below the 2000px per-image limit).
Added regression assertions for opus-5/opus-6 (high-res) and opus-4-6
(default).
Fixes#8256
- Added a new SQuAD-based context-compression benchmark script for evaluating recall conditions.
- Added model and shape command-line arguments along with pricing and shape configurations.
- Updated default model variants and added an unknown billing family to shape resolution.
- Updated shape resolution and model resolution tests to verify the new defaults.
- Collected distinct rendered frame widths for resume summaries.
- Covered mixed HQ/LQ archives with the existing foveation regression.
- Documented the fix in the snapcompact changelog.
Fixes#6712
- Re-compaction unfolds the prior archive's kept source verbatim, so archives written before includeThinking existed kept replaying reasoning to Claude (reasoning_extraction) even after the serializer fix; the prior text is now scrubbed when includeThinking is false, healing poisoned sessions at their next compaction.
Both compaction serializers reproduced prior assistant reasoning as text
bound for a Claude target, tripping Anthropic's reasoning_extraction
refusal and wedging Fable 5 sessions:
- context-full: serializeConversation rendered thinking verbatim inside
<thinking> tags via the anthropic dialect renderer. Now drops thinking
blocks when the summary target dialect is anthropic; other dialects
(e.g. Harmony) keep native reasoning.
- snapcompact: emitted ¶think sections baked into replayed archive
frames. Added an includeThinking serialize option (default true) and
wired the agent session to disable it for Anthropic-dialect models.
Fixes#6093
A branch whose last entry is a snapcompact CompactionEntry billed past the
compaction threshold (FRAME_TOKEN_ESTIMATE x frames) dead-ended on every
resume: prepareCompaction returns undefined (nothing after the entry to
summarize), and the #4786 elide/image rescue tiers only inspect
"message"/"custom_message" entries, so a type:"compaction" tail escaped both
and the "Compaction freed too little context" warning re-fired forever.
Add a dedicated first rescue tier that rebuilds the SAME archive locally (no
LLM, no network) by re-running snapcompact.compact() over the entry's
carried-forward source text at a maxFrames derived from the trigger
threshold's recovery band instead of the window-fit budget: planArchive
truncates the oldest chars to fit, so the rebuilt entry genuinely shrinks.
Persisting through appendCompaction lets the write-time
superseded-compaction elision drop the stale frame payload from the JSONL,
and the pass skips the misleading no-progress warning.
Fixes the loop reported in
https://github.com/can1357/oh-my-pi/issues/4786#issuecomment-5056055342
Claude-Session: https://claude.ai/code/session_014rh4JyWFkxgMhgFaEf8VBY
- Replaced markdown-style headings with concise `¶user:`, `¶think:`, `¶ai:`, and `¶call:` scope markers.
- Updated the serializer to merge consecutive messages or blocks of the same type under a shared prefix.
- Updated the documentation prompt to reflect the new compact formatting and scope rules.
- Added regression tests verifying scope merging and correct formatting of tool calls and intents.
- Made resolveShapeForText choose silver16-bw for CJK-heavy auto transcripts while preserving explicit variants and unsafe glyph protection.
- Added silver16-bw to the snapcompact shape settings submenu and renamed unsupported-glyph warnings.
- Covered auto shape selection, explicit variant precedence, unsafe glyph scans, and settings option parity.
Fixes#4486
- Added Silver.ttf TrueType font support to `pi-natives` with automated fallback logic for bitmap font rendering.
- Implemented wide code point detection and cell-width calculation to improve CJK character handling and layout.
- Introduced dynamic font-aware preflight probing via `resolveShapeForText` and `renderabilityProbeText` for better font selection.
- Enabled semantic emoji folding and improved text normalization to handle non-Latin characters and emoji filtering.
- Consolidated duplicate `stripSnapcompactPreserveData` functions into `snapcompact.stripPreservedArchive`.
- Added unit tests to verify archive removal and empty state collapse behavior.
- Added a 10-image budget for the umans provider to match its request cap.
- Updated the unit tests to verify the correct budget assignment for umans.
Fixes#3227
- Updated `render`, `renderMany`, and native snapcompact methods to return promises, ensuring scalable async execution.
- Refactored `transformProviderContext` and `buildSideRequestContext` to support asynchronous operations in agent loops.
- Integrated `Promise.all` for improved concurrency when processing frame rendering and rendering batch operations.
- Updated all internal call sites, SDK hooks, and test suites to accommodate the asynchronous API signatures.
- Unify `previousText` resolution to correctly concatenate `textHead` and `textTail` during re-compaction.
- Ensure summary fallback logic correctly handles non-text legacy archives.
- Add test coverage for cross-compaction text retention and legacy archive continuity.
- Enable snapcompact strategy in agent plan reference re-injection tests.
- Renamed the global `INTENT_FIELD` constant from `_i` to `i`.
- Updated documentation strings, type annotations, and test expectations across packages to reflect the new field name.
- Ensured consistent usage of the constant in tool schema construction and intent serialization.
- Removed legacy `pinnedFrames` logic and state, simplifying compaction to unconditionally re-render from the full source archive.
- Updated `historyBlocks` to reliably order archive regions (text head, imaged middle, text tail) based on the re-rendered state.
- Updated documentation and summary templates to reflect the transition to text-first compaction and the use of the new `FILES` section.
- Update `MAX_FRAMES_DEFAULT` to 80 to better utilize high-capacity model context windows.
- Remove `providerFrameBudget` from `snapcompact` to decouple archival limits from provider-specific image caps.
- Update `compact` logic to treat `maxFrames` as a hard upper bound rather than a provider-clamped limit.
- Standardized elision markers across all tool outputs and filters to use cohesive `[...N [type] elided...]`, `[...Nln elided...]`, and `[...xB elided...]` syntax.
- Updated documentation, prompts, and test expectations to reflect the unified elision format.
- Improved transcript viewer robustness by preventing content aliasing through path-inclusive signature hashing.
- Added logic to clear stale transcript content when associated session files are deleted, accompanied by verifying test cases.
- Expand `CHAR_FOLD` dictionary to include more punctuation, dashes, arrows, and bullets.
- Added `foldToAscii` function using NFKD decomposition to better handle compatibility characters like fullwidth text, ligatures, and vulgar fractions.
- Updated elision markers from `[... N chars elided ...]` to `[... Nch elided ...]` to reduce character count and improve visual clarity.
- Implemented `AdvisorTranscriptRecorder` to persist advisor sessions to append-only `__advisor.jsonl` files.
- Integrated transcript recording into agent sessions with managed flushing, atomic file switching, and synthetic turn attribution.
- Restricted advisor-kind agents by excluding them from rosters, history protocols, messaging, and interactive agent commands.
- Reserved the `__advisor` filename stem across the output manager and task registry to prevent task ID collisions.
- Prevented the serialization of empty or whitespace-only content blocks to avoid extraneous headers.
- Updated the prompt template to improve clarity for message roles and formatting.
- Prevent file operations containing URL schemes from being included in the generated file lists.
- Introduce `HEADING_MARKER` constant to provide a consistent suffix for conversation headers.
- Implemented structured markdown role headings and tool result merging to improve conversation readability.
- Added explicit `<out>` tags for tool result wrapping and enhanced rendering for thinking blocks.
- Refactored authentication snapshot validation to use manual structural checks instead of schema dependencies.
- Fixed instability in settings overlay scrolling and addressed assistant message splitting issues.
- Updated compaction, branch summarization, and session dump formatting to pass preferred model tool syntax into conversation serialization.
- Enhanced shared serializers to render assistant tool calls and tool results through grammar envelopes when syntax is available, with the prior compact format as fallback.
- Aligned prompt, preview, and test fixtures to the new transcript tags: `[Think]`, `[Tool Call]`, and `[Tool Result]`.
- Added 8on22-bw and 11on16-bw variants with spacing-tuned defaults for snapcompact.
- Changed provider defaults/mappings to use 11on16-bw for Anthropic and 8on22-bw for OpenAI/Google.
- Updated model frame rules so claude/fable/opus and gemini/gpt families map to new shapes and 2048 billing behavior.
- Fixed non-multiplexer resize dragging by using alternate screen during transient resize frames.
- Added optional `useless` flags to tool result types and payload builders.
- Added `pruneUseless` and `dropUeless` options to control uneventful result pruning.
- Changed compaction and shake passes to prune or ignore non-error useless tool results.
- Changed conversation serialization to omit useless toolCall/toolResult pairs from output.
- Added coverage for useless tagging, pruning, and serialization behavior.
- Used per-frame palette usage statistics to remap global indices into a compact local palette before PNG encoding.
- Encoded indexed outputs with dynamic 1-, 2-, and 4-bit depths based on used color count.
- Raised PNG compression from Balanced to High for indexed and RGB paths and updated parity and decode tests for variable-bit palette decoding.
- Implemented model-specific frame-size billing for Anthropic, OpenAI, and Google.
- Changed compaction shape resolution to bind model variants to ideal frame sizes.
- Updated tests and docs to reflect new frame-size and budget behavior.
- Adjusted snapcompact rendering to compute used rows from text, dim toggles, and doc line breaks, then derive output height from usedRows x lineRepeat x cellHeight.
- Updated indexed and RGB PNG encoders to accept explicit canvas width and height so native renders now emit non-square frames matching actual content.
- Expanded Rust and TypeScript tests and updated docs/changelogs to assert and describe variable-height frame behavior.
- Added support for `{api,id}` `ShapeTarget` in `resolveShape`, deriving variants from model IDs.
- Added provider budget APIs/constants and `providerFrameBudget` clamping with `MAX_FRAMES`.
- Added `Archive.textTail` and moved overflow pages into plain-text tail folding across frames.
- Updated summary prompt rendering to show continuation only when `textTail` exists and append it as text.
- Repointed `SHAPES.anthropic` and the `anthropic-messages`/unknown-API fallback in `resolveShape` at the `6x12-dim` variant: production mono eval on claude-fable scored f1 .840 vs .877 for the repeated grid (within noise at n=25) at 37% lower cost, with no refusals.
- Reworded the `snapcompact.shape` descriptions in `settings-schema.ts` to drop per-provider eval-winner claims from the variant help text.
- Updated `snapcompact.test.ts` (new `6x12-dim` default render/compact assertions, `8x8r-bw` exercised via `resolveShape`), `snapcompact-inline.test.ts` frame math for the new geometry, and the `docs/compaction.md` shape sentence.
- Amended the snapcompact `[Unreleased]` entry that said the Anthropic default stayed `8x8r-bw` and added the default-switch entry.
- Resolved OpenAI shape resolution to `openai` and default to `8on16-bw`.
- Fixed catalog generation to collapse effort tiers before provider grouping.
- Updated help text and schemas to describe `8on16-bw` as the OpenAI auto default.
- Added production `render_pages` and `mono_prod` scripts for end-to-end QA output.
- Added `6x12-dim`, `8x13-bw`, `8on16-bw`, `doc-8on16-bw`, `doc-8on16-sent`, and `doc-8on16-sent-dim` to `SHAPE_VARIANTS`, backed by new `Shape` fields `stretch`, `columns`, and `stopwordDim` and the X.org `6x12`/`8x13` fonts.
- Added `dimStopwords()` (high-frequency function words printed in dim ink via zero-width markers, skipping already-dim spans) and `wrap()`, the greedy word-wrap used to typeset doc-layout pages; `geometry`/`render`/`renderMany`/`frames`/`compact` paginate doc shapes into `2 * rows`-line pages and persist `columns`/`stopwordDim` on compaction frames for mixed-shape detection.
- Changed `normalize()` to keep line structure (whitespace runs containing a line break collapse to `NEWLINE_GLYPH`, U+2588 FULL BLOCK) and to drop unrenderable characters — ANSI escape sequences, control characters, zero-width format characters, combining marks, lone surrogates — instead of printing `?` blanks.
- Explained the line-break marker in the frame-reading prompt `snapcompact-summary.md` and extended `snapcompact.test.ts` for the new variants, wrapping, and normalization.
- Added the `research/parity_check.py` and `research/parity_render.ts` parity tooling for the native renderer.
- Recorded the snapcompact changelog entries.
- Added snapcompact.shape setting with auto and variant options in agent config.
- Implemented resolveShape support for forced variants, auto provider winners, and repricing.
- Threaded resolved shape into compaction and inline-image flows for pricing and rendering.
- Renamed all functions, types, and constants in @oh-my-pi/snapcompact to namespace-relative names (`snapcompactCompact` → `compact`, `renderSnapcompactFrames` → `renderMany`, `snapcompactFrameCount` → `frames`, `SnapcompactShape` → `Shape`, `SNAPCOMPACT_SHAPES` → `SHAPES`, …).
- Converted every consumer to `import * as snapcompact` member access: `agent/compaction.ts`, `coding-agent` `agent-session.ts`/`session-manager.ts`/`snapcompact-inline.ts`, and all affected tests.
- Renamed internal `geometry` locals to `geo` in `snapcompact.ts` to avoid TDZ collisions with the new `geometry` export.
- Updated `docs/compaction.md` prose and added a Breaking Changes entry to the snapcompact changelog documenting the full rename map.
- Added `renderSnapcompactFrames()` and `snapcompactFrameCount()` to @oh-my-pi/snapcompact for paging arbitrary text into PNG image blocks without dim-marker bookkeeping.
- Widened the agent loop's `transformProviderContext` hook to `(context, model) => Context` so per-request transforms can gate on the dispatch model's capabilities.
- Added `SnapcompactInlineTransformer` rendering the system prompt and large historical tool results as snapcompact frames on vision models: vision gate, per-provider image budgets, 3k-token floor, savings-margin gate, skip-last rule, and hash-keyed render caches swept to live tool calls.
- Added default-off `snapcompact.systemPrompt` and `snapcompact.toolResults` settings under a new Context → Experimental group, composed after secret obfuscation in `sdk.ts` so frames are built per-request and never persisted to session.jsonl.
- Added prompt stubs (`snapcompact-system-stub.md`, `snapcompact-system-frames-note.md`, `snapcompact-toolresult-note.md`) and unit tests covering frame paging, no-mutate guarantees, budget caps, gates, and render caching.
Oversized tool results and arguments are now truncated to keep archives
conversation-dense, and tool output is rendered in dim gray ink on image frames
to visually de-emphasize noise.
All truncation budgets and dimming behavior are configurable.
- Switched render outputs from byte arrays to base64 strings across native and TypeScript surfaces.
- Updated `RenderedFrame` and FFI declarations so `data` is a base64 string and `chars` are exposed.
- Added `SnapcompactSerializeOptions` with truncation, head/tail ratio and tool/arg/call limits.
- Tracked dim-marker state in rendering, reopening spans across chunk boundaries and stripping markers.
- The `snapcompact-summary.md` prompt was removed from `packages/agent` to further centralize `snapcompact`-related concerns within the dedicated `@oh-my-pi/snapcompact` package.
- Introduced `isSnapcompactShape` for runtime validation of `SnapcompactShape` overrides, enhancing data integrity when loading configuration from dynamic sources.
- Updated README and native module comments to reflect the standalone `snapcompact` package structure.
- Added a new @oh-my-pi/snapcompact package and redirected compaction call sites to it.
- Added provider-aware snapcompact shape resolution for model-specific mixed-frame behavior.
- Added optional image detail support by extending ImageContent and passing hints through OpenAI providers.
- Added native snapcompact render options, including 5x8/8x8 font loading and palette/geometry controls.