From 0eaa0ba5986e4c500bfccfbbafa2c27728d131ef Mon Sep 17 00:00:00 2001 From: Vito Sansevero Date: Thu, 22 Oct 2026 08:48:01 -0700 Subject: [PATCH] perf(inspect): measure the local response size natively and yield between steps fitInspectionPayload counted the UTF-8 size of an 8-12 MB wire with a per-character loop and ran every omission step on the main thread in one turn (PR #277 final review M7). The size is now counted by TextEncoder encodeInto through one bounded scratch buffer, and each re-measure follows a yieldControl turn, with an abort signal checked between steps. The fit is async; the fitted payload is the same as before. --- tests/js/workspace-local-inspection.test.js | 8 ++--- tests/js/workspace-local-projection.test.js | 31 ++++++++++++----- web/js/workspace/local-inspection.mjs | 6 ++-- web/js/workspace/local-projection.mjs | 38 +++++++++++++++------ 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/tests/js/workspace-local-inspection.test.js b/tests/js/workspace-local-inspection.test.js index 0fa8966d..f20400d0 100644 --- a/tests/js/workspace-local-inspection.test.js +++ b/tests/js/workspace-local-inspection.test.js @@ -189,7 +189,7 @@ test("local cap measures escaped UTF-8 atomically", async () => { const wire = m.buildLocalPayload({ read: raw.result, file: { name: file.name, size: file.size, lastModified: file.lastModified }, classification: handle.classification }); const text = JSON.stringify(wire); assert.ok(text.length < LIMIT && bytes(wire) > LIMIT, `${text.length} code units, ${bytes(wire)} bytes`); - const fitted = m.fitLocalPayload(wire); + const fitted = await m.fitLocalPayload(wire); assert.ok(bytes(fitted) <= LIMIT); assert.equal(fitted.metadata.workflow_graph.status, "limited", "the workflow graph goes first"); assert.equal(fitted.metadata.prompt_graph.status, "parsed"); @@ -198,9 +198,9 @@ test("local cap measures escaped UTF-8 atomically", async () => { assert.equal(inspectionDownloads(record).metadata.available, true); assert.equal(inspectionDownloads(record).workflow.available, false); // Whole-raw omission is atomic and marks the response-size limit; the inspector offers no metadata download. - const squeezed = m.fitLocalPayload(wire, bytes(fitted) - 1); + const squeezed = await m.fitLocalPayload(wire, bytes(fitted) - 1); assert.deepEqual([squeezed.metadata.workflow_graph.status, squeezed.metadata.prompt_graph.status], ["limited", "limited"]); - const tiny = m.fitLocalPayload(wire, 2000); + const tiny = await m.fitLocalPayload(wire, 2000); assert.equal(tiny.metadata.status, "limited"); assert.equal(tiny.metadata.omitted_reason, "response-size-limit"); assert.deepEqual(tiny.metadata.raw, {}); @@ -209,7 +209,7 @@ test("local cap measures escaped UTF-8 atomically", async () => { const omitted = m.localFileAdapter.toRecord(tiny, handle, extractGenerationFacts); assert.equal(inspectionDownloads(omitted).metadata.available, false); assert.equal(omitted.generation.seed.reason, "projection-limited"); - assert.throws(() => m.fitLocalPayload(wire, 100), /exceeds/); + await assert.rejects(m.fitLocalPayload(wire, 100), /exceeds/); assert.equal(wire.metadata.status, "available", "the input wire is not mutated"); assert.equal((await m.localFileAdapter.read(handle)).metadata.workflow_graph.status, "limited", "adapter.read returns the fitted wire"); }); diff --git a/tests/js/workspace-local-projection.test.js b/tests/js/workspace-local-projection.test.js index 4954ff43..faa3e5cc 100644 --- a/tests/js/workspace-local-projection.test.js +++ b/tests/js/workspace-local-projection.test.js @@ -176,7 +176,7 @@ test("projectMetadata mirrors _metadata for records, formats and carriers", () = assert.deepEqual(objectPrompt.prompt_graph, { status: "parsed", value: { 1: { class_type: "A", inputs: {} } } }); }); -test("fitInspectionPayload omits the workflow graph, then the prompt graph, then all raw atomically", () => { +test("fitInspectionPayload omits the workflow graph, then the prompt graph, then all raw atomically", async () => { const payload = { success: true, inspection_version: 1, metadata: { status: "available", omitted_reason: null, raw: { prompt: "é".repeat(100), workflow: "{}" }, record_formats: { prompt: "original-text", workflow: "original-text" }, @@ -188,28 +188,43 @@ test("fitInspectionPayload omits the workflow graph, then the prompt graph, then // UTF-8 bytes, not UTF-16 code units: 'é' is 2 bytes, an escaped lone surrogate 6. assert.equal(m.inspectionBytes(payload), Buffer.byteLength(text, "utf8")); assert.ok(m.inspectionBytes(payload) > text.length); - const whole = m.fitInspectionPayload(payload, bytes(payload)); + // Measured in bounded chunks: pairs and 2-byte characters across every chunk edge count once. + for (const shift of [0, 1, 2, 3]) { + const wide = { s: "x".repeat(shift) + "é😀".repeat(200000) + "\ud800", t: "a😀".repeat(70000) }; + assert.equal(m.inspectionBytes(wide), Buffer.byteLength(JSON.stringify(wide), "utf8"), `shift ${shift}`); + } + const whole = await m.fitInspectionPayload(payload, bytes(payload)); assert.equal(whole, payload, "a payload within the limit is returned as is"); - const first = m.fitInspectionPayload(payload, bytes(payload) - 1); + const first = await m.fitInspectionPayload(payload, bytes(payload) - 1); assert.equal(first.metadata.workflow_graph.status, "limited"); assert.equal(first.metadata.prompt_graph.status, "parsed"); assert.deepEqual(first.metadata.raw, payload.metadata.raw); assert.ok(bytes(first) <= bytes(payload) - 1); - const second = m.fitInspectionPayload(payload, bytes(first) - 1); + const second = await m.fitInspectionPayload(payload, bytes(first) - 1); assert.deepEqual([second.metadata.workflow_graph.status, second.metadata.prompt_graph.status], ["limited", "limited"]); assert.equal(second.metadata.status, "available"); assert.deepEqual(second.metadata.raw, payload.metadata.raw); - const third = m.fitInspectionPayload(payload, bytes(second) - 1); + const third = await m.fitInspectionPayload(payload, bytes(second) - 1); assert.deepEqual(third.metadata, { ...second.metadata, raw: {}, parameters: null, status: "limited", omitted_reason: "response-size-limit" }); assert.ok(bytes(third) <= bytes(second) - 1); - assert.throws(() => m.fitInspectionPayload(payload, bytes(third) - 1), /exceeds/); + await assert.rejects(m.fitInspectionPayload(payload, bytes(third) - 1), /exceeds/); // The caller's payload is never mutated and absent graphs are left alone. assert.equal(JSON.stringify(payload), text); const absent = { ...payload, metadata: { ...payload.metadata, workflow_graph: { status: "absent", value: null } } }; - const fitted = m.fitInspectionPayload(absent, bytes(absent) - 1); + const fitted = await m.fitInspectionPayload(absent, bytes(absent) - 1); assert.equal(fitted.metadata.workflow_graph.status, "absent"); assert.equal(fitted.metadata.prompt_graph.status, "limited"); - assert.equal(m.fitInspectionPayload(payload).metadata.status, "available", "the default limit is 8 MiB"); + assert.equal((await m.fitInspectionPayload(payload)).metadata.status, "available", "the default limit is 8 MiB"); + // Every omission step after the first measure hands the event loop a turn, and an + // abort between steps rejects with AbortError; the answer itself is unchanged. + let turns = 0; + const counted = await m.fitInspectionPayload(payload, bytes(second) - 1, { yieldControl: async () => { turns += 1; } }); + assert.equal(JSON.stringify(counted), JSON.stringify(third)); + assert.equal(turns, 3); + assert.equal(await m.fitInspectionPayload(payload, bytes(payload), { yieldControl: async () => { turns += 1; } }), payload); + assert.equal(turns, 3, "a payload within the limit is measured once, without a turn"); + const controller = new AbortController(); + await assert.rejects(m.fitInspectionPayload(payload, bytes(second) - 1, { signal: controller.signal, yieldControl: async () => controller.abort() }), { name: "AbortError" }); }); test("the committed projection corpus has every outcome and parses with the oracle entry shape", () => { diff --git a/web/js/workspace/local-inspection.mjs b/web/js/workspace/local-inspection.mjs index 402f413c..8b5c0344 100644 --- a/web/js/workspace/local-inspection.mjs +++ b/web/js/workspace/local-inspection.mjs @@ -109,8 +109,8 @@ export function buildLocalPayload({ read, file, classification }) { } /** The server's 8 MiB response budget, applied to the local wire with the same omission order. */ -export function fitLocalPayload(wire, limit = MAX_RESPONSE_BYTES) { - return fitInspectionPayload(wire, limit); +export function fitLocalPayload(wire, limit = MAX_RESPONSE_BYTES, options = {}) { + return fitInspectionPayload(wire, limit, options); } // Handles this module created, by a private token: the controller and the viewer @@ -161,7 +161,7 @@ export const localFileAdapter = Object.freeze({ async read(handle, { signal } = {}) { const secret = owned(handle); const { result } = await readLocalFile(secret.file, { classification: secret.classification, signal }); - return fitLocalPayload(buildLocalPayload({ read: result, file: { name: secret.filename, size: secret.file.size, lastModified: secret.file.lastModified }, classification: secret.classification })); + return fitLocalPayload(buildLocalPayload({ read: result, file: { name: secret.filename, size: secret.file.size, lastModified: secret.file.lastModified }, classification: secret.classification }), MAX_RESPONSE_BYTES, { signal }); }, toRecord(result, handle, extractFacts) { const secret = owned(handle); diff --git a/web/js/workspace/local-projection.mjs b/web/js/workspace/local-projection.mjs index 02bb7bb3..a8c7ffe2 100644 --- a/web/js/workspace/local-projection.mjs +++ b/web/js/workspace/local-projection.mjs @@ -348,38 +348,56 @@ export function projectMetadata(inspection) { return result; } -/** UTF-8 length of `JSON.stringify(value)`: the server's `_bytes` count (lone surrogates are already escaped). */ +const UTF8 = new TextEncoder(); +const MEASURE_CHUNK_BYTES = 256 * 1024; + +/** + * UTF-8 length of `JSON.stringify(value)`: the server's `_bytes` count. The text + * holds no lone surrogate (JSON.stringify escapes them), so the encoder's count is + * exact; it encodes into one bounded scratch buffer and never splits a pair. + */ export function inspectionBytes(value) { const text = JSON.stringify(value); + const scratch = new Uint8Array(Math.min(MEASURE_CHUNK_BYTES, text.length * 3 + 4)); let count = 0; - for (let index = 0; index < text.length; index++) { - const code = text.charCodeAt(index); - if (code < 0x80) count += 1; - else if (code < 0x800) count += 2; - else if (code >= 0xd800 && code <= 0xdbff) { count += 4; index++; } else count += 3; + for (let offset = 0; offset < text.length; ) { + const { read, written } = UTF8.encodeInto(offset ? text.slice(offset) : text, scratch); + offset += read; + count += written; } return count; } const withMetadata = (payload, changes) => ({ ...payload, metadata: { ...payload.metadata, ...changes } }); +function defaultYield() { + return new Promise((resolve) => setTimeout(resolve, 0)); +} + /** * The omission steps of `_encode_inspection`: the workflow graph first, then the * prompt graph, then all raw records atomically, each measured as encoded bytes. - * Returns a new payload; throws when even the bare payload is over `limit`. + * Each re-measure of a multi-megabyte payload follows a `yieldControl` turn, and + * `signal` aborts between steps. Resolves to a new payload; rejects when even the + * bare payload is over `limit`. */ -export function fitInspectionPayload(payload, limit = MAX_RESPONSE_BYTES) { +export async function fitInspectionPayload(payload, limit = MAX_RESPONSE_BYTES, { yieldControl = defaultYield, signal } = {}) { + const measure = async (candidate) => { + await yieldControl(); + if (signal && signal.aborted) throw new DOMException('The inspection was aborted', 'AbortError'); + return inspectionBytes(candidate); + }; let fitted = payload, body = inspectionBytes(payload); for (const field of ['workflow_graph', 'prompt_graph']) { if (body <= limit) break; if (fitted.metadata[field].status !== 'absent') { fitted = withMetadata(fitted, { [field]: { status: 'limited', value: null } }); - body = inspectionBytes(fitted); + body = await measure(fitted); } } if (body > limit) { fitted = withMetadata(fitted, { raw: {}, parameters: null, status: 'limited', omitted_reason: 'response-size-limit' }); - body = inspectionBytes(fitted); + body = await measure(fitted); } if (body > limit) throw new RangeError('Inspection response exceeds limits'); return fitted;