@xamukavila/pxpipe 0.8.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/LICENSE +21 -0
- package/README.md +312 -0
- package/bin/cli.js +7 -0
- package/dist/core/applicability.d.ts +31 -0
- package/dist/core/applicability.js +96 -0
- package/dist/core/atlas-gray.d.ts +26 -0
- package/dist/core/atlas-gray.js +64 -0
- package/dist/core/atlas.d.ts +34 -0
- package/dist/core/atlas.js +71 -0
- package/dist/core/baseline.d.ts +80 -0
- package/dist/core/baseline.js +101 -0
- package/dist/core/caveman.d.ts +38 -0
- package/dist/core/caveman.js +183 -0
- package/dist/core/export.d.ts +128 -0
- package/dist/core/export.js +390 -0
- package/dist/core/factsheet.d.ts +78 -0
- package/dist/core/factsheet.js +216 -0
- package/dist/core/gpt-model-profiles.d.ts +60 -0
- package/dist/core/gpt-model-profiles.js +161 -0
- package/dist/core/history.d.ts +141 -0
- package/dist/core/history.js +553 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +8 -0
- package/dist/core/library.d.ts +74 -0
- package/dist/core/library.js +133 -0
- package/dist/core/measurement.d.ts +22 -0
- package/dist/core/measurement.js +213 -0
- package/dist/core/openai-history.d.ts +124 -0
- package/dist/core/openai-history.js +494 -0
- package/dist/core/openai-savings.d.ts +44 -0
- package/dist/core/openai-savings.js +75 -0
- package/dist/core/openai.d.ts +24 -0
- package/dist/core/openai.js +839 -0
- package/dist/core/png.d.ts +11 -0
- package/dist/core/png.js +132 -0
- package/dist/core/proxy.d.ts +81 -0
- package/dist/core/proxy.js +730 -0
- package/dist/core/render.d.ts +188 -0
- package/dist/core/render.js +785 -0
- package/dist/core/schema-strip.d.ts +29 -0
- package/dist/core/schema-strip.js +160 -0
- package/dist/core/tracker.d.ts +154 -0
- package/dist/core/tracker.js +216 -0
- package/dist/core/transform.d.ts +362 -0
- package/dist/core/transform.js +1828 -0
- package/dist/core/types.d.ts +77 -0
- package/dist/core/types.js +8 -0
- package/dist/dashboard/fragments.d.ts +36 -0
- package/dist/dashboard/fragments.js +938 -0
- package/dist/dashboard/types.d.ts +154 -0
- package/dist/dashboard/types.js +3 -0
- package/dist/dashboard/vendor.d.ts +3 -0
- package/dist/dashboard/vendor.js +6 -0
- package/dist/dashboard.d.ts +245 -0
- package/dist/dashboard.js +1140 -0
- package/dist/export-collect.d.ts +36 -0
- package/dist/export-collect.js +59 -0
- package/dist/node.d.ts +9 -0
- package/dist/node.js +9038 -0
- package/dist/sessions.d.ts +172 -0
- package/dist/sessions.js +510 -0
- package/dist/stats.d.ts +74 -0
- package/dist/stats.js +248 -0
- package/dist/worker.d.ts +53 -0
- package/dist/worker.js +102 -0
- package/package.json +96 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request-body transformer. Extracts the static system prompt + tool definitions,
|
|
3
|
+
* renders them as PNG image blocks, and rewrites the body to reference those images —
|
|
4
|
+
* saving 65-73% input tokens while preserving reasoning quality.
|
|
5
|
+
*/
|
|
6
|
+
import type { ImageBlock, MessagesRequest } from './types.js';
|
|
7
|
+
import type { GptHistoryOptions } from './openai-history.js';
|
|
8
|
+
/** Per-block descriptor passed to `TransformOptions.keepSharp`. */
|
|
9
|
+
export interface KeepSharpBlock {
|
|
10
|
+
/** Which live-region path is asking: `reminder`, `tool_result`, or `tool_result_part`. */
|
|
11
|
+
readonly kind: 'reminder' | 'tool_result' | 'tool_result_part';
|
|
12
|
+
/** The block's text exactly as the caller produced it (pre-render, pre-compaction). */
|
|
13
|
+
readonly text: string;
|
|
14
|
+
/** `tool_use_id` of the owning tool_result, when applicable. */
|
|
15
|
+
readonly toolUseId?: string;
|
|
16
|
+
}
|
|
17
|
+
/** A block pxpipe rendered to image(s), returned in `TransformInfo.recoverable`
|
|
18
|
+
* when the caller sets `emitRecoverable`. Lets a stateful harness restore
|
|
19
|
+
* byte-exact content if the model needs the imaged region verbatim. */
|
|
20
|
+
export interface RecoverableBlock {
|
|
21
|
+
/** `rec_` + 8 hex SHA-256 over kind + toolUseId + original text. */
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly kind: 'reminder' | 'tool_result' | 'tool_result_part';
|
|
24
|
+
readonly toolUseId?: string;
|
|
25
|
+
/** Original text before compaction/reflow/paging — the bytes to restore. */
|
|
26
|
+
readonly text: string;
|
|
27
|
+
readonly imageCount: number;
|
|
28
|
+
}
|
|
29
|
+
export interface TransformOptions {
|
|
30
|
+
/** Master switch — false makes this a no-op pass-through. */
|
|
31
|
+
compress?: boolean;
|
|
32
|
+
/** Move tool descriptions into the same image (and stub the originals). */
|
|
33
|
+
compressTools?: boolean;
|
|
34
|
+
/** Compress large `<system-reminder>` text blocks in the first user message. */
|
|
35
|
+
compressReminders?: boolean;
|
|
36
|
+
/** Compress large tool_result text content across all user messages. */
|
|
37
|
+
compressToolResults?: boolean;
|
|
38
|
+
/** Don't compress if total compressible chars below this. */
|
|
39
|
+
minCompressChars?: number;
|
|
40
|
+
/** Per-block threshold for compressReminders (chars). */
|
|
41
|
+
minReminderChars?: number;
|
|
42
|
+
/** Per-block threshold for compressToolResults (chars). */
|
|
43
|
+
minToolResultChars?: number;
|
|
44
|
+
/** Soft-wrap column count. */
|
|
45
|
+
cols?: number;
|
|
46
|
+
/** Hard upper bound on images per tool_result; source text truncated with a paging
|
|
47
|
+
* marker above this to stay under Anthropic's 100-image/request cap. Default 10. */
|
|
48
|
+
maxImagesPerToolResult?: number;
|
|
49
|
+
/** Pack N text columns side-by-side per image. Default 1. Auto-clamped to stay
|
|
50
|
+
* under 2000 px wide. OCR ordering risk at N≥2: model must read col 1 top-to-bottom
|
|
51
|
+
* before col 2. */
|
|
52
|
+
multiCol?: number;
|
|
53
|
+
/** Chars-per-token assumption for `isCompressionProfitable()`. Default 4. */
|
|
54
|
+
charsPerToken?: number;
|
|
55
|
+
/** Multi-turn amortization horizon for the history-collapse gate. N≥2 evaluates as
|
|
56
|
+
* if N future turns share the prefix (worst-case-warm-image vs best-case-warm-text).
|
|
57
|
+
* Default 1 (per-turn cold gate). See docs/HISTORY_CACHE_MODEL.md. */
|
|
58
|
+
historyAmortizationHorizon?: number;
|
|
59
|
+
/** Tokens the un-rewritten path would have cache-hit on. Adds a one-time burn
|
|
60
|
+
* penalty `priorWarmTokens × (CC − CR)` to the image side so the gate accounts
|
|
61
|
+
* for invalidating a warm text cache. Default 0 (cold-start). ≤0 clamped to 0. */
|
|
62
|
+
priorWarmTokens?: number;
|
|
63
|
+
/** Symmetric counterpart: tokens the image path would have cache-hit on. Adds the
|
|
64
|
+
* same burn formula to the TEXT side, preventing the gate from flipping out of
|
|
65
|
+
* image mode when the image prefix is already warm. Default 0. ≤0 clamped to 0. */
|
|
66
|
+
priorWarmImageTokens?: number;
|
|
67
|
+
/** GPT only: collapse the OLD closed-tool-call conversation prefix into history
|
|
68
|
+
* image(s), keeping the recent tail as text. Independent of the static slab.
|
|
69
|
+
* Default on. See src/core/openai-history.ts. */
|
|
70
|
+
collapseHistory?: boolean;
|
|
71
|
+
/** GPT only: history-collapse tuning overrides (keepTail / collapseChunk / …). */
|
|
72
|
+
gptHistory?: Partial<GptHistoryOptions>;
|
|
73
|
+
/** Re-pack image-bound text into a ↵-delimited stream to fill `cols` (~29%→75-80%
|
|
74
|
+
* glyph-fill). ON by default (98.95% char accuracy at L1 OCR eval, +1pp vs baseline).
|
|
75
|
+
* Hard newlines become visible ↵ glyphs — tell the model via system prompt. */
|
|
76
|
+
reflow?: boolean;
|
|
77
|
+
/** Caller fidelity hint: return `true` for a block that must stay as text (IDs,
|
|
78
|
+
* hashes, file paths — content where mis-OCR would be silent and wrong). Only
|
|
79
|
+
* consulted on per-block live-region paths (reminders, tool_results). A throwing
|
|
80
|
+
* or non-boolean return is treated as `false`. */
|
|
81
|
+
keepSharp?: (block: KeepSharpBlock) => boolean;
|
|
82
|
+
/** When true, populate `TransformInfo.recoverable` with original text + provenance
|
|
83
|
+
* for every block rendered to images. Off by default (entries inflate `info`;
|
|
84
|
+
* only a stateful harness can use them). */
|
|
85
|
+
emitRecoverable?: boolean;
|
|
86
|
+
/** EXPERIMENT (`PXPIPE_CAVEMAN=1`): deterministic rule-based prose compression
|
|
87
|
+
* (drop EN/PT articles + filler adverbs, rewrite politeness phrases) on
|
|
88
|
+
* image-bound text BEFORE compaction/reflow — fewer chars → fewer pixels →
|
|
89
|
+
* fewer image tokens. Applies to the static slab and reminder blocks when
|
|
90
|
+
* they classify as prose ('other'); tool_results are out of scope for v1
|
|
91
|
+
* (mostly logs/code — the classify gate would skip them anyway). Never
|
|
92
|
+
* touches code, table rows, quoted spans, or non-alphabetic tokens
|
|
93
|
+
* (src/core/caveman.ts). Off by default until the A/B shows gist/verbatim
|
|
94
|
+
* recall holds — see FINDINGS.md on redundancy as the channel's ECC. */
|
|
95
|
+
caveman?: boolean;
|
|
96
|
+
}
|
|
97
|
+
/** Empirical cpt for the system-slab path (Opus 4.7 tokenizer, N=391, observed 1.91).
|
|
98
|
+
* Slab-specific because reminders/tool_results have unknown shape; those stay at 4. */
|
|
99
|
+
export declare const SLAB_CHARS_PER_TOKEN = 2;
|
|
100
|
+
/** Empirical cpt for the history-collapse path (same Opus 4.7 telemetry as SLAB_CHARS_PER_TOKEN).
|
|
101
|
+
* History is even denser (tool_use JSON dominates), so 2.0 is doubly conservative. */
|
|
102
|
+
export declare const HISTORY_CHARS_PER_TOKEN = 2;
|
|
103
|
+
/** Chars-per-token for the `pxpipe export` *reporting* estimate (factsheet & savings %).
|
|
104
|
+
* Less conservative than the gate's CHARS_PER_TOKEN=4: reporting wants an accurate
|
|
105
|
+
* figure (~3.7 for source/prose text), not a safe-side under-estimate. Single source
|
|
106
|
+
* of truth — src/core/export.ts imports this rather than redefining it. */
|
|
107
|
+
export declare const REPORT_CHARS_PER_TOKEN = 3.7;
|
|
108
|
+
/** Anthropic image-billing formula: `tokens ≈ width × height / 750`.
|
|
109
|
+
* https://docs.anthropic.com/en/docs/build-with-claude/vision#image-tokens
|
|
110
|
+
* Accurate to ~5% on dense glyph PNGs (N=14 empirical calibration). The renderer
|
|
111
|
+
* sizes height to content, so per-block images cost far less than full-canvas.
|
|
112
|
+
* Exported so the export pipeline can reuse the same constant rather than hardcoding. */
|
|
113
|
+
export declare const ANTHROPIC_PIXELS_PER_TOKEN = 750;
|
|
114
|
+
/** Conservative 10% upward bias on Anthropic image token estimates — keeps the gate
|
|
115
|
+
* on the safe (pass-through) side when the true cost is near the break-even point.
|
|
116
|
+
* Exported so the export pipeline reuses the same value. */
|
|
117
|
+
export declare const IMAGE_COST_SAFETY_MARGIN = 1.1;
|
|
118
|
+
/** Visual rows per image: `floor((MAX_HEIGHT_PX − 2·PAD_Y) / CELL_H)`. Derived
|
|
119
|
+
* from render.ts constants so break-even math auto-tracks cell geometry changes. */
|
|
120
|
+
export declare const LINES_PER_IMAGE: number;
|
|
121
|
+
export declare function maxCharsPerImage(cols: number): number;
|
|
122
|
+
/** Lossless pre-render whitespace compactor (each `\n` costs ≥1 visual row):
|
|
123
|
+
* 1. Strip trailing whitespace per line (preserves leading indent).
|
|
124
|
+
* 2. Collapse 3+ consecutive newlines to 2. Typically saves 10-25% rows on
|
|
125
|
+
* markdown/tool-doc slabs, enough to flip borderline gates to profitable. */
|
|
126
|
+
export declare function compactSlabWhitespace(text: string): string;
|
|
127
|
+
/** Decompose the break-even gate into components for telemetry. Returns the
|
|
128
|
+
* imageTokens, textTokens, and symmetric burn terms the gate uses internally,
|
|
129
|
+
* or `null` for empty/non-finite input. */
|
|
130
|
+
export declare function evalCompressionProfitability(text: string, cols: number, imageCountCap?: number | undefined, numCols?: number, charsPerToken?: number, priorWarmTokens?: number, priorWarmImageTokens?: number, shrinkWidth?: boolean): {
|
|
131
|
+
imageTokens: number;
|
|
132
|
+
textTokens: number;
|
|
133
|
+
burnImageSide: number;
|
|
134
|
+
burnTextSide: number;
|
|
135
|
+
profitable: boolean;
|
|
136
|
+
} | null;
|
|
137
|
+
export declare function isCompressionProfitable(text: string, cols?: number, imageCountCap?: number, numCols?: number, charsPerToken?: number, priorWarmTokens?: number, priorWarmImageTokens?: number, shrinkWidth?: boolean, maxCharsPerImage?: number): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Horizon-aware variant of `isCompressionProfitable` for history-collapse.
|
|
140
|
+
*
|
|
141
|
+
* Evaluates expected lifetime cost over N turns: worst-case-warm for image
|
|
142
|
+
* (cache_create turn 1, cache_read turns 2..N) vs best-case-warm for text
|
|
143
|
+
* (cache_read all N). Gate condition: I×(CC + CR×(N-1)) < T×CR×N.
|
|
144
|
+
* Examples: N=5 → I < 0.30×T; N=10 → I < 0.47×T.
|
|
145
|
+
* Falls back to cold per-turn gate when `horizon <= 1`. See docs/HISTORY_CACHE_MODEL.md.
|
|
146
|
+
*/
|
|
147
|
+
export declare function isCompressionProfitableAmortized(text: string, cols: number, imageCountCap: number | undefined, numCols: number, charsPerToken: number, horizon: number, priorWarmTokens?: number, priorWarmImageTokens?: number, shrinkWidth?: boolean, maxCharsPerImage?: number): boolean;
|
|
148
|
+
/** Logical bucket for per-gate-call char attribution. Used by the rolling-cpt
|
|
149
|
+
* regression to derive per-bucket marginal cpt from production telemetry. */
|
|
150
|
+
export type BucketName = 'static_slab' | 'reminder' | 'tool_result_json' | 'tool_result_log' | 'tool_result_prose' | 'history';
|
|
151
|
+
/** Pre-compaction TEXT char totals per bucket. Absent when no bucket fired. */
|
|
152
|
+
export type BucketChars = Partial<Record<BucketName, number>>;
|
|
153
|
+
/** Parsed contents of Claude Code's <env> + git status blocks. All optional —
|
|
154
|
+
* fields are only populated if the corresponding line is present. */
|
|
155
|
+
export interface EnvFields {
|
|
156
|
+
/** Working directory at the time `claude` was launched. */
|
|
157
|
+
cwd?: string;
|
|
158
|
+
isGitRepo?: boolean;
|
|
159
|
+
/** Current git branch, parsed from <git_status> or a "Branch:" line. */
|
|
160
|
+
gitBranch?: string;
|
|
161
|
+
platform?: string;
|
|
162
|
+
osVersion?: string;
|
|
163
|
+
/** "Today's date" as Claude Code reported it (YYYY-MM-DD). */
|
|
164
|
+
today?: string;
|
|
165
|
+
}
|
|
166
|
+
export interface TransformInfo {
|
|
167
|
+
compressed: boolean;
|
|
168
|
+
reason?: string;
|
|
169
|
+
origChars: number;
|
|
170
|
+
/** Total source chars image-encoded this request (static slab + reminders + tool_results).
|
|
171
|
+
* Unlike `origChars` (static slab + tool docs only), reflects what `imageCount` replaced. */
|
|
172
|
+
compressedChars: number;
|
|
173
|
+
/** Chars removed by the opt-in caveman prose pass (`TransformOptions.caveman`).
|
|
174
|
+
* Reported as a separate delta; `origChars`/`compressedChars` stay anchored
|
|
175
|
+
* to the RAW source lengths so savings baselines remain comparable across
|
|
176
|
+
* caveman on/off runs. */
|
|
177
|
+
cavemanChars?: number;
|
|
178
|
+
imageCount: number;
|
|
179
|
+
imageBytes: number;
|
|
180
|
+
/** Σ width×height across all rendered images. Pairs with upstream token count for
|
|
181
|
+
* empirical px/token regression: `tokens ≈ α·outgoingTextChars + β·imagePixels`. */
|
|
182
|
+
imagePixels?: number;
|
|
183
|
+
/** GPT only. Vision tokens the rendered images actually cost as input
|
|
184
|
+
* (Σ openAIVisionTokens over real image dims). The "Sent as image" basis. */
|
|
185
|
+
imageTokens?: number;
|
|
186
|
+
/** GPT only. o200k_base text tokens of the content pxpipe imaged/stripped —
|
|
187
|
+
* the would-have-paid "as plain text" baseline. Compared against imageTokens
|
|
188
|
+
* for the per-request saving. See src/core/openai-savings.ts. */
|
|
189
|
+
baselineImagedTokens?: number;
|
|
190
|
+
/** Total TEXT chars in the outgoing body (system + messages, excluding image base64).
|
|
191
|
+
* Denominator for empirical chars-per-token regression on cold-miss events. */
|
|
192
|
+
outgoingTextChars?: number;
|
|
193
|
+
/** Length of the static (cacheable) slab rendered into the image. */
|
|
194
|
+
staticChars: number;
|
|
195
|
+
/** Length of the dynamic (per-turn) slab kept as plain text. */
|
|
196
|
+
dynamicChars: number;
|
|
197
|
+
/** Chars of volatile env/context text relocated from system to the tail of
|
|
198
|
+
* the last user message (absent when kept in system fallback). */
|
|
199
|
+
envRelocatedChars?: number;
|
|
200
|
+
dynamicBlockCount: number;
|
|
201
|
+
/** Tag-shaped blocks in the static slab not in DYNAMIC_BLOCK_TAGS.
|
|
202
|
+
* Canary: a new per-turn Claude Code tag would appear here before cache rate collapses. */
|
|
203
|
+
unknownStaticTags?: string[];
|
|
204
|
+
/** Static-slab tags whose content changed within a session — proven dynamic,
|
|
205
|
+
* busting the image cache each turn. The real alert signal. */
|
|
206
|
+
churningStaticTags?: string[];
|
|
207
|
+
env?: EnvFields;
|
|
208
|
+
/** sha8 of static slab + tool docs (what goes in the image). Repeats across turns → cache hits. */
|
|
209
|
+
systemSha8?: string;
|
|
210
|
+
/** sha8 of the CLAUDE.md section, for bucketing by project when cwd is absent. */
|
|
211
|
+
claudeMdSha8?: string;
|
|
212
|
+
/** sha8 of first user message text (first 4 KiB). Rough thread/session id. */
|
|
213
|
+
firstUserSha8?: string;
|
|
214
|
+
/** Raw bytes of the first rendered image. Dashboard preview only; NOT persisted to JSONL. */
|
|
215
|
+
firstImagePng?: Uint8Array;
|
|
216
|
+
firstImageWidth?: number;
|
|
217
|
+
firstImageHeight?: number;
|
|
218
|
+
/** All rendered PNGs this request. Dashboard only; NOT persisted to JSONL. */
|
|
219
|
+
imagePngs?: Uint8Array[];
|
|
220
|
+
imageDims?: Array<{
|
|
221
|
+
width: number;
|
|
222
|
+
height: number;
|
|
223
|
+
}>;
|
|
224
|
+
/** Source text rendered to images (slab + header), capped at 64 KiB. NOT persisted. */
|
|
225
|
+
imageSourceText?: string;
|
|
226
|
+
reminderImgs?: number;
|
|
227
|
+
toolResultImgs?: number;
|
|
228
|
+
/** Chars of tool docs moved to the system-text Tool Reference (not imaged). */
|
|
229
|
+
toolDocsChars?: number;
|
|
230
|
+
/** Codepoints missing from the atlas (rendered as blank cells). Telemetry for atlas tuning. */
|
|
231
|
+
droppedChars?: number;
|
|
232
|
+
/** Top dropped codepoints by frequency (`U+HHHH` → count), at most 20 entries. */
|
|
233
|
+
droppedCodepointsTop?: Record<string, number>;
|
|
234
|
+
/** Why blocks passed through without compression. Only present when count > 0. */
|
|
235
|
+
passthroughReasons?: {
|
|
236
|
+
below_threshold?: number;
|
|
237
|
+
not_profitable?: number;
|
|
238
|
+
kept_sharp?: number;
|
|
239
|
+
};
|
|
240
|
+
/** Slab gate diagnostics — imageTokens, textTokens, burn terms, and verdict.
|
|
241
|
+
* Lets hosts measure flap-prevention efficacy and tune amortization horizon. */
|
|
242
|
+
gateEval?: {
|
|
243
|
+
readonly site: 'slab';
|
|
244
|
+
readonly imageTokens: number;
|
|
245
|
+
readonly textTokens: number;
|
|
246
|
+
/** `priorWarmTokens × (CC − CR)` added to image side. */
|
|
247
|
+
readonly burnImageSide: number;
|
|
248
|
+
/** `priorWarmImageTokens × (CC − CR)` added to text side (anti-flapping anchor). */
|
|
249
|
+
readonly burnTextSide: number;
|
|
250
|
+
readonly profitable: boolean;
|
|
251
|
+
};
|
|
252
|
+
/** Pre-compaction TEXT char totals per gate-call bucket. Rolling-cpt regression denominator. */
|
|
253
|
+
bucketChars?: BucketChars;
|
|
254
|
+
/** Chars fed into the history-image renderer. Folded into `bucketChars.history` too. */
|
|
255
|
+
historyTextChars?: number;
|
|
256
|
+
/** Blocks pinned as text by the caller's `keepSharp` predicate this request. */
|
|
257
|
+
keptSharpBlocks?: number;
|
|
258
|
+
/** Imaged live-region blocks with original text + provenance, when `emitRecoverable`. */
|
|
259
|
+
recoverable?: RecoverableBlock[];
|
|
260
|
+
truncatedToolResults?: number;
|
|
261
|
+
omittedChars?: number;
|
|
262
|
+
/** History-collapse: messages collapsed into the synthetic prepended user message. */
|
|
263
|
+
collapsedTurns?: number;
|
|
264
|
+
collapsedChars?: number;
|
|
265
|
+
/** History-collapse images. Also folded into `info.imageCount`. */
|
|
266
|
+
collapsedImages?: number;
|
|
267
|
+
/** sha8 of concatenated history-image base64. Stable across the collapse window →
|
|
268
|
+
* proves Anthropic's prompt cache can `cache_read` (0.1×) instead of `cache_create`.
|
|
269
|
+
* A changing hash means cache-key drift is back. Only set when collapse produced images. */
|
|
270
|
+
historyImageSha?: string;
|
|
271
|
+
/** sha8 of the ACTUAL cacheable prefix sent this turn (tools + system +
|
|
272
|
+
* message blocks through the imaged history/slab boundary; the live tail is
|
|
273
|
+
* excluded). Read-only measurement. A change turn-over-turn within a session
|
|
274
|
+
* ⇒ pxpipe serialized different prefix bytes (we busted our own cache,
|
|
275
|
+
* pxpipe-side); STABLE while cache_create spikes / cache_read collapses ⇒ the
|
|
276
|
+
* prefix was evicted upstream. Decisive attribution signal (see #11). */
|
|
277
|
+
cachePrefixSha8?: string;
|
|
278
|
+
/** Approx size (chars) of that cached prefix — pairs with cachePrefixSha8 so a
|
|
279
|
+
* bust reads as growth (size up) vs pure invalidation (size unchanged). */
|
|
280
|
+
cachePrefixBytes?: number;
|
|
281
|
+
/** Why the history collapse didn't run (or did). Diagnostic only. */
|
|
282
|
+
historyReason?: 'no_history' | 'prefix_too_short' | 'no_closed_prefix' | 'below_min_chars' | 'below_min_tokens' | 'not_profitable' | 'too_many_images' | 'render_empty' | 'collapsed';
|
|
283
|
+
/** Token count of the pre-compression body from /v1/messages/count_tokens (free).
|
|
284
|
+
* Absent when probe failed — event excluded from savings rollup. */
|
|
285
|
+
baselineTokens?: number;
|
|
286
|
+
/** Token count of the pre-compression body truncated at the last cache_control marker.
|
|
287
|
+
* Absent when the original body has no cache_control markers (cacheable=0 exactly). */
|
|
288
|
+
baselineCacheableTokens?: number;
|
|
289
|
+
/** 'ok': both probes resolved. 'partial': full-body resolved but cacheable-prefix
|
|
290
|
+
* didn't (exclude from rollup — cacheable=0 fallback is dishonest). 'failed': no
|
|
291
|
+
* baseline. undefined: no probe attempted. */
|
|
292
|
+
baselineProbeStatus?: 'ok' | 'partial' | 'failed';
|
|
293
|
+
}
|
|
294
|
+
/** sha256[0..8] hex via Web Crypto (works in Node 18+ and Workers). 32-bit collision-safe. */
|
|
295
|
+
export declare function sha8(text: string): Promise<string>;
|
|
296
|
+
/** Best-effort extraction of the CLAUDE.md slab from a system text (heuristic).
|
|
297
|
+
* Returns empty string if nothing CLAUDE.md-shaped is detected. */
|
|
298
|
+
export declare function extractClaudeMdSlab(staticText: string): string;
|
|
299
|
+
/** First user message text, capped at 4 KiB (stable thread id; hashing large pastes is wasteful). */
|
|
300
|
+
export declare function firstUserText(req: MessagesRequest): string;
|
|
301
|
+
/** Parse structured fields from the dynamic slab for telemetry. Read-only. */
|
|
302
|
+
export declare function extractEnvFields(dynamicText: string): EnvFields;
|
|
303
|
+
/** Estimate how many images `text` will render to at the given column width.
|
|
304
|
+
* Counts soft-wrapped visual rows, which is what render.ts actually budgets
|
|
305
|
+
* against. Exported for tests + the paging gate.
|
|
306
|
+
*
|
|
307
|
+
* `numCols` (default 1) packs that many text columns side-by-side per
|
|
308
|
+
* image — must match the `multiCol` setting wired through to the renderer
|
|
309
|
+
* for the math to predict the actual image count. */
|
|
310
|
+
export declare function estimateImageCount(textOrLen: string | number, cols: number, numCols?: number, maxCharsPerImage?: number): number;
|
|
311
|
+
/** Classify content so we can pick a truncation strategy. Cheap heuristics on
|
|
312
|
+
* the first ~4 KiB. Returns:
|
|
313
|
+
* - `'structured'`: JSON/YAML/diff markers at the top. Truncate tail.
|
|
314
|
+
* - `'log'`: ≥30% of lines start with a log level or timestamp. Truncate middle.
|
|
315
|
+
* - `'other'`: prose, file dumps, etc. Truncate middle.
|
|
316
|
+
* Exported for tests. */
|
|
317
|
+
export declare function classifyContent(text: string): 'structured' | 'log' | 'other';
|
|
318
|
+
/** Truncate `text` so it renders to roughly `maxImages` images at the given
|
|
319
|
+
* `cols`. Picks head/tail split based on `classifyContent`. Budget measured
|
|
320
|
+
* in visual rows (what render.ts actually slices on). Returns the truncated
|
|
321
|
+
* text (with paging marker embedded) and the count of chars omitted. If
|
|
322
|
+
* `text` already fits, returns unchanged with `omittedChars: 0`. Exported
|
|
323
|
+
* for tests. */
|
|
324
|
+
export declare function truncateForBudget(text: string, maxImages: number, cols: number, numCols?: number, maxCharsPerImage?: number): {
|
|
325
|
+
text: string;
|
|
326
|
+
omittedChars: number;
|
|
327
|
+
truncated: boolean;
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* Render text → Anthropic image blocks for the proxy. The column-selection rule below
|
|
331
|
+
* (shrink, then single-col unless the content fills the width) is mirrored exactly by
|
|
332
|
+
* the public SDK primitive `renderTextToImages` (library.ts), so the proxy and the
|
|
333
|
+
* `pxpipe export` CLI emit byte-identical PNGs for the same text. Exported so
|
|
334
|
+
* export-proxy-align.test.ts can pin that invariant against the real proxy code.
|
|
335
|
+
*/
|
|
336
|
+
export declare function textToImageBlocks(text: string, cols: number, numCols?: number,
|
|
337
|
+
/** Shrink canvas to the longest wrapped line. `false` for the slab path
|
|
338
|
+
* (fills full `cols` for multi-col packing). Default `true`. */
|
|
339
|
+
shrinkWidth?: boolean): Promise<{
|
|
340
|
+
blocks: ImageBlock[];
|
|
341
|
+
/** Raw PNG bytes parallel to `blocks` (avoids re-decoding base64 for dashboard). */
|
|
342
|
+
pngs: Uint8Array[];
|
|
343
|
+
/** Pixel dimensions parallel to `pngs`. */
|
|
344
|
+
dims: Array<{
|
|
345
|
+
width: number;
|
|
346
|
+
height: number;
|
|
347
|
+
}>;
|
|
348
|
+
droppedChars: number;
|
|
349
|
+
droppedCodepoints: Map<number, number>;
|
|
350
|
+
/** Σ width×height — caller accumulates into `info.imagePixels` for px/token regression. */
|
|
351
|
+
pixels: number;
|
|
352
|
+
}>;
|
|
353
|
+
/**
|
|
354
|
+
* Rewrite a Messages API request body. Returns the new body (still JSON
|
|
355
|
+
* bytes) plus diagnostic info. On any error, returns the original bytes
|
|
356
|
+
* unchanged.
|
|
357
|
+
*/
|
|
358
|
+
export declare function transformRequest(body: Uint8Array, opts?: TransformOptions): Promise<{
|
|
359
|
+
body: Uint8Array;
|
|
360
|
+
info: TransformInfo;
|
|
361
|
+
}>;
|
|
362
|
+
//# sourceMappingURL=transform.d.ts.map
|