@prometheus-ai/snapcompact
v0.5.18
Published
Bitmap-frame context compression for vision-capable LLMs
Downloads
1,654
Maintainers
Readme
@prometheus-ai/snapcompact
Bitmap-frame context compression for vision-capable LLMs.
Instead of asking an LLM to summarize discarded conversation history, snapcompact serializes it and renders the text into dense PNG frames of pixel-font glyphs that vision models read back directly. The whole pass is local and deterministic — no LLM call, no API key, no latency beyond rendering. Rasterization and PNG encoding happen in native code (@prometheus-ai/natives).
Built for prometheus's compaction pipeline, but the rendering API works on arbitrary text.
How it works
- Discarded history is serialized to compact text (
serializeConversation), with per-tool-result and per-argument character caps. - Text is normalized for the bundled bitmap fonts (
normalize): ANSI sequences stripped, whitespace collapsed, newline runs folded into a single full-block glyph so line structure survives. - Pages of text are rasterized into PNG frames (
render/renderMany). Frame width is fixed per shape; height hugs the rows actually printed, so a partially filled frame never bills blank pixel rows. - Frames persist in the compaction entry's
preserveDataand are re-attached to the summary message on every context rebuild.
Frame shapes are provider-aware, chosen by SQuAD recall evals (see research/) against real provider billing:
| Reader | Default shape | Notes |
| --- | --- | --- |
| Anthropic | 6x12-dim | X.org 6x12 glyphs, stopwords dimmed gray; high-res Claude lines get 1932px frames |
| Google | doc-8on16-sent-dim @2048 | Two newspaper columns, sentence-hue ink; Gemini bills a fixed per-image budget, so larger frames are free chars |
| OpenAI | 8on16-bw | 8x13 glyphs on a patch-aligned 16px pitch, sent at detail: "original" |
| Unknown | Anthropic shape | Per-provider image-count budgets guard against gateways that silently drop frames |
resolveShape({ api, id }) matches the model id, not just the wire API — a Claude routed through Vertex or OpenRouter keeps its Claude shape, priced for the gateway actually carrying the request.
Install
bun add @prometheus-ai/snapcompactShips TypeScript source directly (no build step); requires Bun ≥ 1.3.14.
Usage
Render arbitrary text into LLM image blocks:
import { renderMany, frames, resolveShape } from "@prometheus-ai/snapcompact";
const images = renderMany(longText, { model }); // ImageContent[], first page first
const count = frames(longText, { model }); // frame count without rendering
const shape = resolveShape(model); // eval-optimal Shape for the readerRun a full compaction pass over prepared messages:
import { compact } from "@prometheus-ai/snapcompact";
const result = await compact(preparation, { model, maxFrames: 8 });
// result.summary — text summary with <files> operations block
// result.preserveData — frame archive, re-attachable via getPreservedArchive() + images()API surface
- Compaction:
compact,CompactionPreparation,CompactionResult,getPreservedArchive,images - Rendering:
render,renderMany,frames,geometry - Shapes:
SHAPES,SHAPE_VARIANTS,resolveShape,idealShapeVariant,isShape,isShapeVariantName - Text:
serializeConversation,normalize,dimStopwords,wrap - Budgets:
providerImageBudget,providerFrameBudget,MAX_FRAMES,FRAME_TOKEN_ESTIMATE - File ops:
createFileOps,computeFileLists,upsertFileOperations
