Repository navigation
fix(workflow-runtime-core): bound step output and reduce oversized status reports - #1457
alfredolopez80 wants to merge 5 commits into
Conversation
…s report size The status reporter now cuts step output to 65,536 characters, the largest preview WRC can store, and keeps every step status body under 256 KiB by degrading in a fixed order (error text, tool-call previews, then output). Artifacts declared in a cut output are sent as outputArtifacts, and outputLength/outputTruncated describe the original output; WRC clamps both and merges the artifacts. Serialization and artifact extraction now have one copy in workflow-runtime-core. The inherited test that asserted the full output is sent now asserts the bounded output, as an approved behaviour change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…limit' into fix/workflow-status-output-bound * origin/fix/workflow-status-report-body-limit: test(workflow-recipes): assert the drain cap on what the server read
|
Took a deep pass through this one, scoped to this PR's own changes ( Verdict: 🔴 Not ready to approve
This is my read from the review, not a formal GH approval. Must resolve before approval1. [R1-H1] Degradation drops the standard artifact tool result, so the artifact vanishes from
|
…tput-bound Brings in #1135 (final head 9b7258f) and #1453. Resolved conflicts: - workflow-recipes version: dev 0.1.505 + 1 = 0.1.506 (package.json and both lock lines). - restEndpoints.functional.test.ts: kept both new describe blocks (A3's output-bound tests and #1135's byte-heavy tool-call tests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts when reducing a report Address the round-1 review of #1457 (zach88 R1-H1/H2/M4/L2-L6, blind review A3-*) on top of #1135's byte-bounded tool-call previews: - Serialize the step output with JSON semantics; only an object that contains itself becomes "[Circular]" (ancestor stack). - When a report is reduced, keep the accepted artifact of every tool call (also when mcp-host adds `content`) and remove previews from the last calls first, only as much as needed. - Extract artifacts of a cut output from the serialized text and cap them at MAX_REPORTED_OUTPUT_ARTIFACTS. - Tests: an input that still exceeds 256 KiB after byte bounding, with a witness that the reduction ran (output-status), and #1135's reporter test asserted against the cut-output contract (status-reporter). Orphans checked: isArtifactOnlyResult, dropToolCallPreviews; removed: both (replaced by the artifact-preserving reduction, no remaining caller). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… of an uncut one WRC side of the #1457 round-1 fixes (zach88 R1-H1, A3-M1 and the preview findings): - postStepStatus reads `outputArtifacts` only for an output the coordinator cut (`outputTruncated: true`), caps them at the shared MAX_REPORTED_OUTPUT_ARTIFACTS, and handles them like the artifacts it extracts from an uncut output. - The stored `outputPreviewMaxChars` is the limit that produced the preview: WRC's, or the shorter length the coordinator cut to (OD-3). - docs/crds/workflowrecipe.md: the preview-length sentence, and that tool-call previews are removed only while the body is still over 256 KiB after error/failureReason are cut. Orphans checked: MAX_CUSTOM_ARTIFACTS_PER_STEP; removed (replaced by the core constant, no remaining reference). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-up to #1135, which is merged.
git diff origin/devshows only this PR's files.Summary
Follow-up to the
toolsCalledbounding in #1135, which leftoutputunbounded.outputto 65,536 characters, the largest preview WRC can beconfigured to store (
MAX_WORKFLOW_STEP_OUTPUT_PREVIEW_MAX_CHARS, now defined from the sharedSTATUS_OUTPUT_MAX_CHARS), so the stored preview is the same prefix as before for every allowedconfiguration, unless the report needs the size reduction described below.
output. When the reporter cuts theoutput, it extracts them first and sends them as
outputArtifacts; WRC handles them like theartifacts it extracts from an uncut output: normalized, at most 21 (
artifactplus 20 fromartifacts[]), de-duplicated by name againststatus.artifacts. WRC reads them only when thereport says the output was cut. Artifact extraction has one copy in
@clerum/workflow-runtime-core; the reporter has its own serializer for the live output, andWRC keeps the one for the value it receives.
one that references the same object twice, is stored as before this PR. A BigInt or a
toJSONthat throws makes
reportStepStatusthrow, as before. Three kinds of output are storeddifferently from before this PR: an output that contains itself is stored with
"[Circular]"atthat point (before, the report threw);
NaNandInfinityare stored as"null", and afunction or a symbol as its
String()text (before, no output was stored for these).outputLengthandoutputTruncatedso the stored preview metadata stilldescribes the original output. WRC honours
outputLengthonly whenoutputTruncatedistrueand the length is a safe integer at least as long as what it received, so a client can report a
longer original output but never a shorter one, and cannot mark an output WRC cut as complete.
reporter reduces it in a fixed order and stops as soon as it fits: cut
error/failureReasonto 8,192 characters; remove tool-call
argsandresultpreviews from the last callbackwards, keeping the artifact metadata WRC registers (also when mcp-host adds
contenttoan artifact result); then halve
output, not below 1,024 characters. Other fields are notreduced, so a report can still be over 256 KiB; it is sent anyway and logged with structural
fields only (
label,bodyBytes). After a halving WRC stores a preview shorter than itsconfigured limit and records that length in
outputPreviewMaxChars; a resumed run theninterpolates the shorter preview.
Compatibility and deploy order
A coordinator without this change keeps working against the new WRC and stores the same step and
artifacts as before. A coordinator with this change is accepted by a WRC without it, but for an
output over 65,536 characters that WRC registers none of the artifacts declared in the output and
records
outputLength65,536. WRC and the default coordinator image are built from the samesources and pinned to the same release in the WRC Deployment, so this needs a custom coordinator
image newer than WRC, or a WRC rollback while newer coordinators run. Roll out WRC before, or
together with, the coordinator image. No CRD schema change: the stored step fields already exist.
Behaviour change in inherited tests
Bounding the output is the point of this PR, so two tests from #1135 that asserted a full
150,000-character output now assert this PR's contract:
and output in step reports". It asserts the first 65,536 characters,
outputLength: 150000andoutputTruncated: true, and measures the remaining body against the bounded output. ItstoolsCalledassertions are unchanged.full 150,000-character output and a
toolsCalledlist over 200 KiB. With this PR the output iscut to 65,536 characters and the report is reduced to 256 KiB, so the test now asserts the cut
output, that at least 40 of the 100 calls keep their previews, that every value sent is at most
2,079 bytes, and that the body is between 200 and 256 KiB. fix(workflow): bound agent-step status reports and answer oversized WRC bodies with a readable 413 #1135's per-value byte bound is
still what this test catches.
boundStepStatusBodyis applied once per report;reportStepStatusis its only caller. Appliedtwice it gives the same result when the output was not cut and no call past the first 50 had its
result replaced by a preview or removed.
Testing
All on head
5f2d9f324:packages/workflow-runtime-core:npm run buildclean;npm test286/286 passed(16 files)
workflow-recipes:npm run buildandnpx tsc --noEmitclean;npm test3416 passed,29 skipped (153 files passed, 4 skipped)
toJSON, no-JSONvalues); artifact results kept through the reduction, including mcp-host's
{success, artifact, content}shape; reduction from the last call backwards, only as muchas needed; a body that still exceeds 256 KiB after fix(workflow): bound agent-step status reports and answer oversized WRC bodies with a readable 413 #1135's byte bounding, with a witness
that the reduction ran; WRC storing the artifacts of a cut output like those of an uncut
one; the recorded preview length
mutations made the intended tests fail
scripts/minikube/t0.shpassed on this headpackages/workflow-runtime-coreis int1PackagesChecklist
🤖 Generated with Claude Code