host: wire Variant C history-image opts through node + worker CLI

Threads compressHistory / historyKeepTail / historyMinPrefix through CliOpts,
env vars (COMPRESS_HISTORY, HISTORY_KEEP_TAIL, HISTORY_MIN_PREFIX), and CLI
flags (--history, --no-history, --history-keep-tail N, --history-min-prefix N).
Same wiring on Workers host. Startup log reports history=on/off.

TrackEvent extended with 4 new fields (collapsed_turns, collapsed_chars,
collapsed_images, history_reason) — emitted only when non-zero/defined.

Defaults: compressHistory=false (opt-in given round-3 MARGINAL rating).
229/229 tests green, 496 KB gzipped.
This commit is contained in:
teamchong
2026-05-18 22:50:36 -04:00
parent 97fdee8421
commit 4f5b10aaee
3 changed files with 55 additions and 1 deletions
+24
View File
@@ -44,6 +44,18 @@ export interface TrackEvent {
truncated_tool_results?: number;
/** Total chars elided by paging across all tool_results this request. */
omitted_chars?: number;
/** Variant C history-image: how many messages got collapsed into the
* prepended synthetic user message this request. Absent when not. */
collapsed_turns?: number;
/** Variant C: total chars of text serialized into the history image(s)
* before render. Absent when no collapse happened. */
collapsed_chars?: number;
/** Variant C: number of PNG image blocks emitted for the history. Folded
* into `image_count` too — surfaced separately so dashboards can
* attribute image-count growth to history vs system-slab vs reminders. */
collapsed_images?: number;
/** Variant C: why the history collapse didn't run (or did). Diagnostic. */
history_reason?: string;
/** Codepoints rendered into images that weren't in the glyph atlas. A
* spike here means users are typing glyphs we don't ship — consider
* switching ATLAS_PROFILE to `full-bmp`. */
@@ -161,6 +173,18 @@ export function toTrackEvent(ev: ProxyEvent): TrackEvent {
if (info.omittedChars !== undefined && info.omittedChars > 0) {
out.omitted_chars = info.omittedChars;
}
if (info.collapsedTurns !== undefined && info.collapsedTurns > 0) {
out.collapsed_turns = info.collapsedTurns;
}
if (info.collapsedChars !== undefined && info.collapsedChars > 0) {
out.collapsed_chars = info.collapsedChars;
}
if (info.collapsedImages !== undefined && info.collapsedImages > 0) {
out.collapsed_images = info.collapsedImages;
}
if (info.historyReason !== undefined) {
out.history_reason = info.historyReason;
}
if (info.droppedChars !== undefined && info.droppedChars > 0) {
out.dropped_chars = info.droppedChars;
}
+20 -1
View File
@@ -33,6 +33,11 @@ interface CliOpts {
compressSchemas: boolean;
compressReminders: boolean;
compressToolResults: boolean;
/** Variant C history-image compression (opt-in). Marginal savings per
* round-3 spec; only enable once cache topology is verified. */
compressHistory: boolean;
historyKeepTail: number;
historyMinPrefix: number;
minCompressChars: number;
minReminderChars: number;
minToolResultChars: number;
@@ -59,6 +64,13 @@ function parseCli(argv: string[]): CliOpts {
compressSchemas: envFlag('COMPRESS_SCHEMAS', true),
compressReminders: envFlag('COMPRESS_REMINDERS', true),
compressToolResults: envFlag('COMPRESS_TOOL_RESULTS', true),
// Variant C history-image: OFF by default. Round-3 spec marks the
// savings as MARGINAL (~1% per-call) against HIGH cache-topology risk.
// Flip via COMPRESS_HISTORY=1 or --history once telemetry shows the
// static-slab cache_control still hits.
compressHistory: envFlag('COMPRESS_HISTORY', false),
historyKeepTail: Number(process.env.HISTORY_KEEP_TAIL ?? 4),
historyMinPrefix: Number(process.env.HISTORY_MIN_PREFIX ?? 10),
minCompressChars: Number(process.env.MIN_COMPRESS_CHARS ?? 2000),
// Raised to 10,000 — the per-block break-even point at the current
// renderer config (Unifont 10px, cell 5×11, 100 cols). The real gate
@@ -85,6 +97,10 @@ function parseCli(argv: string[]): CliOpts {
case '--no-schemas': o.compressSchemas = false; break;
case '--no-reminders': o.compressReminders = false; break;
case '--no-tool-results':o.compressToolResults = false; break;
case '--history': o.compressHistory = true; break;
case '--no-history': o.compressHistory = false; break;
case '--history-keep-tail': o.historyKeepTail = Number(eat()); break;
case '--history-min-prefix': o.historyMinPrefix = Number(eat()); break;
case '--min-chars': o.minCompressChars = Number(eat()); break;
case '--min-reminder-chars': o.minReminderChars = Number(eat()); break;
case '--min-tool-result-chars': o.minToolResultChars = Number(eat()); break;
@@ -464,6 +480,9 @@ async function main(): Promise<void> {
compressSchemas: opts.compressSchemas,
compressReminders: opts.compressReminders,
compressToolResults: opts.compressToolResults,
compressHistory: opts.compressHistory,
historyKeepTail: opts.historyKeepTail,
historyMinPrefix: opts.historyMinPrefix,
minCompressChars: opts.minCompressChars,
minReminderChars: opts.minReminderChars,
minToolResultChars: opts.minToolResultChars,
@@ -584,7 +603,7 @@ async function main(): Promise<void> {
server.listen(opts.port, () => {
console.log(`[pixelpipe] listening on http://127.0.0.1:${opts.port}${opts.upstream}`);
console.log(
`[pixelpipe] config: compress=${opts.compress} tools=${opts.compressTools} schemas=${opts.compressSchemas} reminders=${opts.compressReminders} tool_results=${opts.compressToolResults} min=${opts.minCompressChars} placement=${opts.placement} cols=${opts.cols}`,
`[pixelpipe] config: compress=${opts.compress} tools=${opts.compressTools} schemas=${opts.compressSchemas} reminders=${opts.compressReminders} tool_results=${opts.compressToolResults} history=${opts.compressHistory} min=${opts.minCompressChars} placement=${opts.placement} cols=${opts.cols}`,
);
if (opts.track) console.log(`[pixelpipe] tracking events → ${opts.eventsFile}`);
else console.log('[pixelpipe] tracking disabled (--no-track or PIXELPIPE_TRACK=0)');
+11
View File
@@ -24,6 +24,11 @@ export interface Env {
COMPRESS_SCHEMAS?: string;
COMPRESS_REMINDERS?: string;
COMPRESS_TOOL_RESULTS?: string;
/** Variant C history-image compression. OFF by default round-3 spec
* rated savings as MARGINAL vs HIGH cache-topology risk. */
COMPRESS_HISTORY?: string;
HISTORY_KEEP_TAIL?: string;
HISTORY_MIN_PREFIX?: string;
MIN_COMPRESS_CHARS?: string;
MIN_REMINDER_CHARS?: string;
MIN_TOOL_RESULT_CHARS?: string;
@@ -46,6 +51,12 @@ export default {
compressSchemas: truthy(env.COMPRESS_SCHEMAS, true),
compressReminders: truthy(env.COMPRESS_REMINDERS, true),
compressToolResults: truthy(env.COMPRESS_TOOL_RESULTS, true),
// Variant C history-image: OFF by default. Round-3 spec marks the
// savings as MARGINAL (~1% per-call) against HIGH cache-topology risk.
// Flip via COMPRESS_HISTORY=1 once telemetry confirms safe rollout.
compressHistory: truthy(env.COMPRESS_HISTORY, false),
historyKeepTail: env.HISTORY_KEEP_TAIL ? Number(env.HISTORY_KEEP_TAIL) : 4,
historyMinPrefix: env.HISTORY_MIN_PREFIX ? Number(env.HISTORY_MIN_PREFIX) : 10,
minCompressChars: env.MIN_COMPRESS_CHARS ? Number(env.MIN_COMPRESS_CHARS) : 2000,
// Raised to 10,000 — per-block break-even point at current renderer
// config (Unifont 10px, cell 5×11, 100 cols). Real gate is