Skip to content

perf(workflow): reduce doStreamStep step-boundary payload - #16434

Merged
gr2m merged 1 commit into
mainfrom
peter/port-1929-reduce-stream-step-payload
Jul 6, 2026
Merged

gr2m merged 1 commit into
mainfrom
peter/port-1929-reduce-stream-step-payload

Conversation

@VaguelySerious

Copy link
Copy Markdown
Member

Summary

Port of vercel/workflow#1932 to @ai-sdk/workflow.

doStreamStep built the full StepResult inside the step and also returned a per-chunk snapshot array. Both were serialized into the durable event log on every step. But:

  • the iterator never read the chunk array (pure dead payload), and
  • StepResult carries redundant copies of data: content (= text + tool calls), the duplicate toolCalls/dynamicToolCalls lists, reasoningText (= joined reasoning), and the always-empty *ToolResults arrays.

Change

The step now returns only the minimal raw aggregates needed to rebuild the StepResult — text, reasoning, responseMetadata, warnings — alongside the existing finish and toolCalls. The iterator reconstructs the full StepResult via a new buildStepResult helper outside the step boundary.

  • The user-facing StepResult (yielded steps, onStepEnd, telemetry) is byte-for-byte the same shape; only the durable event-log payload shrinks.
  • runtimeContext / toolsContext / stepNumber no longer cross the boundary either — the iterator already holds them and applies them during reconstruction.

Tests

  • stream-text-iterator.test.ts mocks updated to the new { toolCalls, finish, raw, providerExecutedToolResults } shape; the contexts test now asserts the contexts are applied to the reconstructed step and yield value (rather than passed across the boundary).
  • The unmocked end-to-end workflow-agent tests exercise the real doStreamStep → buildStepResult path and pass unchanged, confirming the reconstruction is faithful.
  • pnpm --filter @ai-sdk/workflow build && test pass (node + edge).

Related

Opened as a draft — this is an AI-assisted port. The two copies of this package have diverged (vercel/ai's doStreamStep is streamModelCall-based and built the StepResult inline, with no separate chunksToStep), so this applies the same optimization rather than cherry-picking the diff; please review the adaptation before merge.

🤖 Generated with Claude Code

doStreamStep built the full StepResult inside the step and also returned a
per-chunk snapshot array, serializing both into the durable event log on
every step. The iterator never read the chunk array, and StepResult carries
redundant copies (content, duplicate tool-call lists, reasoningText, the
always-empty *ToolResults arrays).

The step now returns only the minimal raw aggregates needed to rebuild the
StepResult (text, reasoning, responseMetadata, warnings) alongside the
existing finish/toolCalls; the iterator reconstructs the full StepResult via
buildStepResult outside the boundary. The user-facing StepResult shape is
unchanged. runtimeContext/toolsContext/stepNumber no longer cross the
boundary — the iterator applies them during reconstruction.

Ported from vercel/workflow#1932.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@gr2m gr2m left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed: the payload reduction is a faithful field-for-field move of the StepResult construction out of the step boundary, the dropped chunks array was dead payload, and doStreamStep is internal-only. Replay compat across the shape change is acceptable while the package is experimental.

@gr2m
gr2m merged commit e660e45 into main Jul 6, 2026
50 checks passed
@gr2m
gr2m deleted the peter/port-1929-reduce-stream-step-payload branch July 6, 2026 21:19
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🚀 Published in:

Package Version
ai 7.0.17 github npm
@ai-sdk/amazon-bedrock 5.0.13 github npm
@ai-sdk/angular 3.0.17 github npm
@ai-sdk/anthropic 4.0.9 github npm
@ai-sdk/anthropic-aws 2.0.1 github npm
@ai-sdk/gateway 4.0.13 github npm
@ai-sdk/google 4.0.9 github npm
@ai-sdk/google-vertex 5.0.12 github npm
@ai-sdk/harness 1.0.20 github npm
@ai-sdk/harness-claude-code 1.0.20 github npm
@ai-sdk/harness-codex 1.0.21 github npm
@ai-sdk/harness-deepagents 1.0.19 github npm
@ai-sdk/harness-opencode 1.0.20 github npm
@ai-sdk/harness-pi 1.0.20 github npm
@ai-sdk/langchain 3.0.17 github npm
@ai-sdk/llamaindex 3.0.17 github npm
@ai-sdk/mcp 2.0.8 github npm
@ai-sdk/mistral 4.0.6 github npm
@ai-sdk/otel 1.0.17 github npm
@ai-sdk/policy-opa 1.0.17 github npm
@ai-sdk/react 4.0.18 github npm
@ai-sdk/rsc 3.0.17 github npm
@ai-sdk/sandbox-just-bash 1.0.20 github npm
@ai-sdk/sandbox-vercel 1.0.20 github npm
@ai-sdk/svelte 5.0.17 github npm
@ai-sdk/tui 1.0.17 github npm
@ai-sdk/vue 4.0.17 github npm
@ai-sdk/workflow 1.0.17 github npm
@ai-sdk/workflow-harness 1.0.20 github npm
@ai-sdk/xai 4.0.8 github npm

This branch was successfully deployed

1 active deployment
Preview — 0d4588a8 Deployed Jun 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants