@oh-my-pi/snapcompact 17.2.14 → 17.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +6 -5
- package/src/prompts/snapcompact-summary.md +15 -15
- package/src/snapcompact.ts +25 -10
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [17.2.15] - 2026-08-12
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed Anthropic model ID parsing to be case-insensitive and extended the high-resolution 1932px frame tier to Claude Opus 5 and later, preventing sessions from falling back to lower-resolution 1568px frames and preserving full history per compaction.
|
|
10
|
+
|
|
5
11
|
## [17.1.5] - 2026-07-27
|
|
6
12
|
|
|
7
13
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/snapcompact",
|
|
4
|
-
"version": "17.
|
|
4
|
+
"version": "17.3.0",
|
|
5
5
|
"description": "Bitmap-frame context compression for vision-capable LLMs",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -31,10 +31,11 @@
|
|
|
31
31
|
"fmt": "biome format --write ."
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@oh-my-pi/pi-ai": "17.
|
|
35
|
-
"@oh-my-pi/pi-
|
|
36
|
-
"@oh-my-pi/pi-
|
|
37
|
-
"@oh-my-pi/pi-
|
|
34
|
+
"@oh-my-pi/pi-ai": "17.3.0",
|
|
35
|
+
"@oh-my-pi/pi-catalog": "17.3.0",
|
|
36
|
+
"@oh-my-pi/pi-natives": "17.3.0",
|
|
37
|
+
"@oh-my-pi/pi-utils": "17.3.0",
|
|
38
|
+
"@oh-my-pi/pi-wire": "17.3.0"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@types/bun": "^1.3.14"
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
Resume prior conversation. Earlier turns archived under HISTORY below, oldest→newest. Read HISTORY fully; continue the live conversation following it.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- `¶user:`, `¶think:`, `¶ai:`,
|
|
5
|
-
-
|
|
6
|
-
-
|
|
3
|
+
Archived transcript scopes:
|
|
4
|
+
- `¶user:`, `¶think:`, `¶ai:`, `¶call:`: user, assistant reasoning, assistant reply, tool call.
|
|
5
|
+
- Unprefixed following lines: current scope. Consecutive same-kind blocks omit repeated prefix.
|
|
6
|
+
- Tool call: `¶call:name(args)//intent`; trailing `//intent` optional. `<out>…</out>`: tool output.
|
|
7
7
|
|
|
8
8
|
Reading HISTORY:
|
|
9
|
-
- Plain
|
|
10
|
-
{{#if frameCount}}- Some middle sections
|
|
11
|
-
{{#if docColumns}} -
|
|
12
|
-
{{else}} -
|
|
13
|
-
{{/if}}{{#if sentenceInk}} - Ink
|
|
14
|
-
{{/if}}{{#if stopwordDimmed}} - Function words
|
|
15
|
-
{{/if}}{{#if lineRepeated}} - Each line
|
|
16
|
-
{{/if}}{{/if}}{{#if includedPreviousSummary}}- HISTORY opens with a condensed digest of still-older context
|
|
17
|
-
{{/if}}{{#if truncatedChars}}- About {{truncatedChars}} characters of older middle history
|
|
18
|
-
{{/if}}-
|
|
9
|
+
- Plain text: verbatim transcript; rely on it exactly.
|
|
10
|
+
{{#if frameCount}}- Some middle sections: images, not text. Each image: one page of that transcript, in reading order between marked delimiters. Solid black cell: newline; runs of spaces collapse to one.
|
|
11
|
+
{{#if docColumns}} - Frame: two side-by-side columns, each {{cols}} characters wide, up to {{rows}} rows tall; read left top→bottom, then right.
|
|
12
|
+
{{else}} - Frame: one grid {{cols}} characters wide, up to {{rows}} rows tall; read left→right, top→bottom. No word wrap; words may break across rows.
|
|
13
|
+
{{/if}}{{#if sentenceInk}} - Ink: six colors, one per sentence.
|
|
14
|
+
{{/if}}{{#if stopwordDimmed}} - Function words: dim gray; content words: full ink.
|
|
15
|
+
{{/if}}{{#if lineRepeated}} - Each line printed twice (white, then pale-yellow band); copies identical.
|
|
16
|
+
{{/if}}{{/if}}{{#if includedPreviousSummary}}- HISTORY opens with a condensed digest of still-older context predating archived turns.
|
|
17
|
+
{{/if}}{{#if truncatedChars}}- About {{truncatedChars}} characters of older middle history dropped to fit archive budget.
|
|
18
|
+
{{/if}}- If an exact earlier detail matters and a section is unclear, re-derive from workspace (re-read files, re-run commands), rather than guess.
|
|
19
19
|
|
|
20
20
|
{{#if files}}FILES
|
|
21
21
|
===================
|
package/src/snapcompact.ts
CHANGED
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
*/
|
|
47
47
|
|
|
48
48
|
import type { Api, ImageContent, Message, TextContent } from "@oh-my-pi/pi-ai";
|
|
49
|
+
import { isFableOrMythos, parseAnthropicModel, semverGte } from "@oh-my-pi/pi-catalog/identity";
|
|
49
50
|
import { renderSnapcompactPng, snapcompactSupportedChars } from "@oh-my-pi/pi-natives";
|
|
50
51
|
import { formatGroupedPaths, prompt } from "@oh-my-pi/pi-utils";
|
|
51
52
|
import { INTENT_FIELD } from "@oh-my-pi/pi-wire";
|
|
@@ -336,17 +337,17 @@ export interface IdealShape {
|
|
|
336
337
|
frameSize?: number;
|
|
337
338
|
}
|
|
338
339
|
|
|
339
|
-
/** Eval-winning format per model line
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* family's winner at the standard 1568px frame.
|
|
340
|
+
/** Eval-winning format per model line. The wire API only identifies the
|
|
341
|
+
* gateway — a Claude served through Vertex or OpenRouter still reads best
|
|
342
|
+
* with its own shape. Classified Anthropic models use the shared catalog
|
|
343
|
+
* identity parser; remaining model lines use first-match regex rules and fall
|
|
344
|
+
* back to the API family's winner at the standard 1568px frame. */
|
|
345
|
+
const HIGH_RES_ANTHROPIC_VARIANT = { variant: "11on16-bw", frameSize: 1932 } as const satisfies IdealShape;
|
|
344
346
|
const MODEL_VARIANTS: readonly (readonly [RegExp, IdealShape])[] = [
|
|
345
|
-
//
|
|
346
|
-
//
|
|
347
|
-
//
|
|
348
|
-
[/claude.*(fable|mythos)/i,
|
|
349
|
-
[/claude-?opus-?4[.-][7-9]/i, { variant: "11on16-bw", frameSize: 1932 }],
|
|
347
|
+
// Versionless Fable/Mythos aliases (e.g. `claude-fable-latest`) never parse
|
|
348
|
+
// a numeric version, so keep them on the high-res tier by name — every
|
|
349
|
+
// Fable/Mythos line reads it natively.
|
|
350
|
+
[/claude.*(fable|mythos)/i, HIGH_RES_ANTHROPIC_VARIANT],
|
|
350
351
|
// Older Claude lines downscale past 1568px — keep the safe size.
|
|
351
352
|
[/claude/i, { variant: "11on16-bw" }],
|
|
352
353
|
// Gemini 3.x bills a fixed 1,120-token budget per image regardless of
|
|
@@ -363,6 +364,20 @@ const MODEL_VARIANTS: readonly (readonly [RegExp, IdealShape])[] = [
|
|
|
363
364
|
|
|
364
365
|
/** Eval-ideal format for a model id, or undefined when unmeasured. */
|
|
365
366
|
export function idealShapeVariant(modelId: string): IdealShape | undefined {
|
|
367
|
+
// The catalog parser is case-sensitive; the regex rules below are not.
|
|
368
|
+
// Normalize so mixed-case gateway ids keep matching the Anthropic tier.
|
|
369
|
+
const anthropic = parseAnthropicModel(modelId.toLowerCase());
|
|
370
|
+
if (
|
|
371
|
+
anthropic &&
|
|
372
|
+
(isFableOrMythos(anthropic.kind) || (anthropic.kind === "opus" && semverGte(anthropic.version, "4.7")))
|
|
373
|
+
) {
|
|
374
|
+
// Opus 4.7+ and Fable/Mythos read high-res natively: same recall and
|
|
375
|
+
// cost as 1568, a third fewer frames. 1932 is the largest *square* not
|
|
376
|
+
// downscaled under Anthropic's 4,784 visual-token cap ((1932/28)² =
|
|
377
|
+
// 69² = 4,761 ≤ 4,784 28px patches), and staying below 2000px clears
|
|
378
|
+
// the stricter ≤2000px limit for requests with more than 20 images.
|
|
379
|
+
return HIGH_RES_ANTHROPIC_VARIANT;
|
|
380
|
+
}
|
|
366
381
|
return MODEL_VARIANTS.find(([pattern]) => pattern.test(modelId))?.[1];
|
|
367
382
|
}
|
|
368
383
|
|