Merge PR #8257: fix(snapcompact): extend high-res frame tier to opus 5+ (@roboomp)
This commit is contained in:
@@ -228,6 +228,7 @@
|
||||
"version": "17.2.14",
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-ai": "catalog:",
|
||||
"@oh-my-pi/pi-catalog": "catalog:",
|
||||
"@oh-my-pi/pi-natives": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"@oh-my-pi/pi-wire": "catalog:",
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `claude-opus-5` (and later Opus lines) falling back to the 1568px frame instead of the 1932px high-res tier, so snapcompact archives for the current flagship Opus now retain ~33% more history at the same per-frame bill ([#8256](https://github.com/can1357/oh-my-pi/issues/8256)).
|
||||
|
||||
## [17.1.5] - 2026-07-27
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@oh-my-pi/pi-ai": "catalog:",
|
||||
"@oh-my-pi/pi-catalog": "catalog:",
|
||||
"@oh-my-pi/pi-natives": "catalog:",
|
||||
"@oh-my-pi/pi-utils": "catalog:",
|
||||
"@oh-my-pi/pi-wire": "catalog:"
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
*/
|
||||
|
||||
import type { Api, ImageContent, Message, TextContent } from "@oh-my-pi/pi-ai";
|
||||
import { isFableOrMythos, parseAnthropicModel, semverGte } from "@oh-my-pi/pi-catalog/identity";
|
||||
import { renderSnapcompactPng, snapcompactSupportedChars } from "@oh-my-pi/pi-natives";
|
||||
import { formatGroupedPaths, prompt } from "@oh-my-pi/pi-utils";
|
||||
import { INTENT_FIELD } from "@oh-my-pi/pi-wire";
|
||||
@@ -336,17 +337,17 @@ export interface IdealShape {
|
||||
frameSize?: number;
|
||||
}
|
||||
|
||||
/** Eval-winning format per model line, matched against the model id. The
|
||||
* wire API only identifies the gateway — a Claude served through Vertex or
|
||||
* OpenRouter still reads best with its own shape. Patterns cover the model
|
||||
* lines the mono evals measured; everything else falls back to the API
|
||||
* family's winner at the standard 1568px frame. First match wins. */
|
||||
/** Eval-winning format per model line. The wire API only identifies the
|
||||
* gateway — a Claude served through Vertex or OpenRouter still reads best
|
||||
* with its own shape. Classified Anthropic models use the shared catalog
|
||||
* identity parser; remaining model lines use first-match regex rules and fall
|
||||
* back to the API family's winner at the standard 1568px frame. */
|
||||
const HIGH_RES_ANTHROPIC_VARIANT = { variant: "11on16-bw", frameSize: 1932 } as const satisfies IdealShape;
|
||||
const MODEL_VARIANTS: readonly (readonly [RegExp, IdealShape])[] = [
|
||||
// Opus 4.7+ and Fable/Mythos read high-res natively (2576px edge under a
|
||||
// 4,784 visual-token cap → 1932px square sweet spot): same recall and
|
||||
// cost as 1568, a third fewer frames.
|
||||
[/claude.*(fable|mythos)/i, { variant: "11on16-bw", frameSize: 1932 }],
|
||||
[/claude-?opus-?4[.-][7-9]/i, { variant: "11on16-bw", frameSize: 1932 }],
|
||||
// Versionless Fable/Mythos aliases (e.g. `claude-fable-latest`) never parse
|
||||
// a numeric version, so keep them on the high-res tier by name — every
|
||||
// Fable/Mythos line reads it natively.
|
||||
[/claude.*(fable|mythos)/i, HIGH_RES_ANTHROPIC_VARIANT],
|
||||
// Older Claude lines downscale past 1568px — keep the safe size.
|
||||
[/claude/i, { variant: "11on16-bw" }],
|
||||
// Gemini 3.x bills a fixed 1,120-token budget per image regardless of
|
||||
@@ -363,6 +364,18 @@ const MODEL_VARIANTS: readonly (readonly [RegExp, IdealShape])[] = [
|
||||
|
||||
/** Eval-ideal format for a model id, or undefined when unmeasured. */
|
||||
export function idealShapeVariant(modelId: string): IdealShape | undefined {
|
||||
const anthropic = parseAnthropicModel(modelId);
|
||||
if (
|
||||
anthropic &&
|
||||
(isFableOrMythos(anthropic.kind) || (anthropic.kind === "opus" && semverGte(anthropic.version, "4.7")))
|
||||
) {
|
||||
// Opus 4.7+ and Fable/Mythos read high-res natively: same recall and
|
||||
// cost as 1568, a third fewer frames. 1932 is the largest *square* not
|
||||
// downscaled under Anthropic's 4,784 visual-token cap ((1932/28)² =
|
||||
// 69² = 4,761 ≤ 4,784 28px patches), and staying below 2000px clears
|
||||
// the stricter ≤2000px limit for requests with more than 20 images.
|
||||
return HIGH_RES_ANTHROPIC_VARIANT;
|
||||
}
|
||||
return MODEL_VARIANTS.find(([pattern]) => pattern.test(modelId))?.[1];
|
||||
}
|
||||
|
||||
|
||||
@@ -299,6 +299,26 @@ describe("shape resolution", () => {
|
||||
// High-res frames are reserved for the lines that read them natively;
|
||||
// older Claude lines keep the safe 1568px family default.
|
||||
expect(snapcompact.resolveShape({ api: "anthropic-messages", id: "claude-opus-4-8" }).frameSize).toBe(1932);
|
||||
expect(snapcompact.resolveShape({ api: "anthropic-messages", id: "anthropic--claude-4.8-opus" }).frameSize).toBe(
|
||||
1932,
|
||||
);
|
||||
expect(snapcompact.resolveShape({ api: "anthropic-messages", id: "claude-opus-4-10" }).frameSize).toBe(1932);
|
||||
// Versionless Fable/Mythos aliases (bundled `claude-fable-latest`) never
|
||||
// parse a numeric version but still read the high-res tier by name (#8257).
|
||||
expect(
|
||||
snapcompact.resolveShape({ api: "openai-completions", id: "anthropic/claude-fable-latest" }).frameSize,
|
||||
).toBe(1932);
|
||||
expect(
|
||||
snapcompact.resolveShape({ api: "openai-completions", id: "~anthropic/claude-fable-latest" }).frameSize,
|
||||
).toBe(1932);
|
||||
// Opus 5+ shares the Anthropic visual-token cap, so it stays on the
|
||||
// high-res tier rather than falling back to the 1568px default (#8256).
|
||||
expect(snapcompact.resolveShape({ api: "anthropic-messages", id: "claude-opus-5" }).frameSize).toBe(1932);
|
||||
expect(snapcompact.resolveShape({ api: "anthropic-messages", id: "claude-opus-6" }).frameSize).toBe(1932);
|
||||
// Opus lines below 4.7 downscale, so they keep the safe family default.
|
||||
expect(snapcompact.resolveShape({ api: "anthropic-messages", id: "claude-opus-4-6" })).toBe(
|
||||
snapcompact.SHAPES.anthropic,
|
||||
);
|
||||
expect(snapcompact.resolveShape({ api: "anthropic-messages", id: "claude-3-5-sonnet" })).toBe(
|
||||
snapcompact.SHAPES.anthropic,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user