mirror of
https://github.com/teamchong/pxpipe.git
synced 2026-07-22 02:02:51 +02:00
Reapply "fix(render): fit Anthropic page to 1568×728 (~1.15 MP) for WYSIWYG glyphs"
This reverts commit 6eaa8bfcd0.
This commit is contained in:
+1
-1
@@ -33,7 +33,7 @@ import {
|
||||
export const DEFAULT_EXPORT_MODEL = 'claude-sonnet-4-5';
|
||||
// Chars-per-token for the reporting estimate now lives in transform.ts as
|
||||
// REPORT_CHARS_PER_TOKEN (single source of truth for all token-estimate constants).
|
||||
/** Default column width — dense content mode (384 cols = 1928 px). */
|
||||
/** Default column width — dense content mode (312 cols = 1568 px). */
|
||||
export const DEFAULT_EXPORT_COLS: number = DENSE_CONTENT_COLS;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -16,7 +16,15 @@
|
||||
* PXPIPE_GPT_PROFILES='{"gpt-5.6":{"stripCols":176}}' # widen only
|
||||
*/
|
||||
|
||||
import { MAX_HEIGHT_PX } from './render.js';
|
||||
/**
|
||||
* GPT strip height, DECOUPLED from render.ts's MAX_HEIGHT_PX (which is Anthropic's
|
||||
* 1568-edge / ~1.15 MP clamp). OpenAI's pre-tokenize resize is different: fit within
|
||||
* 2048×2048, then shortest side → 768. A 768-px-wide portrait strip up to 2048 px tall
|
||||
* survives un-resampled, so GPT keeps the taller page. Every built-in cost number below
|
||||
* (1190 / 1445 / 2372 / 1464 / 630 …) was calibrated at this height — do not re-link to
|
||||
* the Anthropic constant.
|
||||
*/
|
||||
export const GPT_MAX_HEIGHT_PX = 1932;
|
||||
|
||||
/** Image-token cost model (mirrors OpenAI's mandatory pre-tokenize resize). */
|
||||
export type GptVisionCost =
|
||||
@@ -38,7 +46,7 @@ export interface GptModelProfile {
|
||||
export const DEFAULT_GPT_STRIP_COLS = 152;
|
||||
|
||||
const C = DEFAULT_GPT_STRIP_COLS;
|
||||
const H = MAX_HEIGHT_PX;
|
||||
const H = GPT_MAX_HEIGHT_PX;
|
||||
|
||||
/**
|
||||
* Conservative fallback for unrecognized models: tile 85/170 over-states cost,
|
||||
|
||||
+1
-1
@@ -165,7 +165,7 @@ export interface RenderTextToImagesOptions {
|
||||
readonly maxCharsPerImage?: number;
|
||||
/** Render style. Default DENSE_RENDER_STYLE (bare 5×8 cell, anti-aliased). */
|
||||
readonly style?: RenderStyle;
|
||||
/** Max page height in px. Default MAX_HEIGHT_PX (1932). */
|
||||
/** Max page height in px. Default MAX_HEIGHT_PX (728 — Anthropic 1568-edge / ~1.15 MP safe). */
|
||||
readonly maxHeightPx?: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
* HistoryTurn list and the planner/renderer are shared.
|
||||
*/
|
||||
|
||||
import { renderTextToPngs, reflow, neutralizeSentinel, MAX_HEIGHT_PX, type RenderedImage } from './render.js';
|
||||
import { renderTextToPngs, reflow, neutralizeSentinel, type RenderedImage } from './render.js';
|
||||
import { GPT_MAX_HEIGHT_PX } from './gpt-model-profiles.js';
|
||||
import { countTokens as o200kCountTokens } from 'gpt-tokenizer/encoding/o200k_base';
|
||||
|
||||
/** Portrait-strip width for GPT history images. Mirrors GPT_STRIP_COLS in
|
||||
@@ -101,7 +102,9 @@ export const GPT_HISTORY_DEFAULTS: GptHistoryOptions = {
|
||||
collapseChunk: 10,
|
||||
freezeChunk: 10,
|
||||
sectionTokens: 2000,
|
||||
maxHeightPx: MAX_HEIGHT_PX,
|
||||
// GPT path: OpenAI's resize bounds (2048-bbox / 768 short side) permit the tall
|
||||
// strip — do NOT re-link to render.ts MAX_HEIGHT_PX (Anthropic's 1568/1.15 MP clamp).
|
||||
maxHeightPx: GPT_MAX_HEIGHT_PX,
|
||||
maxImages: GPT_HISTORY_MAX_IMAGES,
|
||||
reflow: true,
|
||||
};
|
||||
|
||||
+20
-15
@@ -23,21 +23,26 @@ import {
|
||||
} from './atlas-gray.js';
|
||||
import { encodeGrayPng, encodeRgbPng } from './png.js';
|
||||
|
||||
/** Page-height ceiling. 1932 px → 384-col page = 69×69 = 4761 tokens, under both Fable/Opus 4.8
|
||||
* limits (≤4784 tokens AND ≤2000 px/side for >20-image requests). Exported for transform.ts math. */
|
||||
export const MAX_HEIGHT_PX = 1932;
|
||||
/** Char budget for the static slab (system + tools + CLAUDE.md). ~50k leaves headroom for
|
||||
* soft-wrap and dropped chars; pages stay well under the 1932 px ceiling at cols=313. */
|
||||
export const READABLE_CHARS_PER_IMAGE = 50000;
|
||||
/** Char budget for dense content (tool output, collapsed history). 384 cols × 240 rows = 92160 chars
|
||||
* fills the full ~1932×1932 ceiling. NOTE: verbatim recall of imaged text is unreliable at any size. */
|
||||
export const DENSE_CONTENT_CHARS_PER_IMAGE = 92160;
|
||||
export const DENSE_CONTENT_COLS = 384;
|
||||
/** Page-height ceiling. Measured (2026-07-01, count_tokens sweep, claude-sonnet-4-5 — see
|
||||
* /tmp/pxexp/LEVER1-findings.md): the API downscales any image to fit BOTH long-edge ≤1568
|
||||
* AND ~1.15 MP (≈1,143,750 px), then bills ≈ px/750 (≈1525 tok cap, applied per-image).
|
||||
* The old 1932×1932 page was billed at cap but resampled 0.555× → 5×8 glyphs reached the
|
||||
* encoder at ~2.8×4.4 px. New page shape 1568×728 = 1,141,504 px fits both bounds →
|
||||
* WYSIWYG for the vision encoder (also satisfies ≤2000 px/side for >20-image requests). */
|
||||
export const MAX_HEIGHT_PX = 728;
|
||||
/** Char budget for the static slab (system + tools + CLAUDE.md). Matches physical page
|
||||
* capacity at 312 cols × 90 rows so image-count estimates track real pagination. */
|
||||
export const READABLE_CHARS_PER_IMAGE = 28080;
|
||||
/** Char budget for dense content (tool output, collapsed history). 312 cols × 90 rows = 28080
|
||||
* chars fills the 1568×728 page. NOTE: verbatim recall of imaged text is unreliable at any size. */
|
||||
export const DENSE_CONTENT_CHARS_PER_IMAGE = 28080;
|
||||
export const DENSE_CONTENT_COLS = 312;
|
||||
/** Bare 5×8 cell (no padding). A/B showed 5×8 beats 7×10 on dense JSON (4/5 vs 3/5 reads, 42% fewer tokens).
|
||||
* Revert to {cellWBonus:2, cellHBonus:2} if misread rates rise. */
|
||||
export const DENSE_RENDER_STYLE: RenderStyle = { cellWBonus: 0, cellHBonus: 0, aa: true };
|
||||
/** Default columns for the static slab. 313 × 5 px + 8 px pad = 1573 px — under the 1932 px ceiling. */
|
||||
const DEFAULT_COLS = 313;
|
||||
/** Default columns for the static slab. 312 × 5 px + 8 px pad = 1568 px — exactly the API's
|
||||
* long-edge bound (313 cols = 1573 px would trigger a 0.997× resample, blurring every glyph). */
|
||||
const DEFAULT_COLS = 312;
|
||||
/** Horizontal padding (left + right each), px. Exported for transform.ts token-cost math. */
|
||||
export const PAD_X = 4;
|
||||
/** Vertical padding (top + bottom each), px. Exported for transform.ts token-cost math. */
|
||||
@@ -732,9 +737,9 @@ export async function renderTextToPngs(
|
||||
// OCR column ordering is the risk — gated behind an opt-in flag pending empirical eval.
|
||||
|
||||
const GUTTER_CELLS = 4;
|
||||
// Width is capped at 1932 px, not 2000 px: a 1932-tall page = 69 patches, so width must
|
||||
// also be ≤69 patches (4761 tokens ≤ 4784). A 2000-px width → 72×69 = 4968 > 4784 → REJECTED.
|
||||
const MAX_WIDTH_PX = 1932;
|
||||
// Width hard-capped at the API's long-edge bound: anything wider is resampled server-side
|
||||
// (measured 2026-07-01: fit-within 1568-edge AND ~1.15 MP, then ≈px/750 billing).
|
||||
const MAX_WIDTH_PX = 1568;
|
||||
|
||||
const GUTTER_DIVIDER_INK = 64; // pre-invert → 191 post-invert: light gray column separator
|
||||
const GUTTER_DIVIDER_INSET_PX = 2; // keep divider clear of padding rows
|
||||
|
||||
Reference in New Issue
Block a user