docs: add wire-safe serialization section for TypeScript streaming events#693
Conversation
…ents
Document the toJSON() serialization behavior for all TypeScript streaming
events. This includes:
- New 'Wire-Safe Serialization' section in the streaming overview
- Table showing what each event serializes to
- Explanation of excluded fields (agent, tool, cancel, retry)
- Error handling format ({ error: { message?: string } })
- In-process vs wire access patterns
- Updated Express.js example with serialization comments
Related: strands-agents/sdk-typescript#708
- Remove verbose 'How It Works', 'Excluded Fields', 'Error Handling', and 'In-Process Access' subsections - Keep single concise paragraph explaining serialization behavior - Retain events table showing what each event serializes to - Mention excluded fields (agent, tool, cancel, retry) inline Co-authored-by: mkmeral <mkmeral@users.noreply.github.com>
Documentation Preview ReadyYour documentation preview has been successfully deployed! Preview URL: https://d3ehv1nix5p99z.cloudfront.net/pr-cms-693/docs/user-guide/quickstart/overview/ Updated at: 2026-04-01T14:10:52.004Z |
…fields Address review feedback: - Rename 'Wire-Safe Serialization (TypeScript)' to 'Event Serialization' - Wrap in <Tabs> with Python/TypeScript tabs - Lead with what each event keeps during serialization - Move excluded fields mention to secondary position after table - Use 'serialization' language instead of 'wire-safe'
|
add this under streaming events tabs (that already exist) or something, I don't want a tab for python. also that python info is not correct anyway |
…nt types Address review feedback from @mkmeral: - Remove Tabs wrapper and Python tab (info was not correct) - Downgrade to ### subsection under Event Types (same level as Lifecycle Events, Model Stream Events, etc.) - TypeScript serialization content stays as-is, directly under heading
|
Done in
Net change: -11 lines, +1 line. |
…aming-serialization
|
Merged Root cause: The in Fix: Merged upstream CI should be green now. @mkmeral |
Updates Event Serialization section for sdk-typescript PR #741: - Put Event Serialization under Python/TypeScript tabs - Add multi-agent event serialization table (10 events from PR #741) - Add A2A event serialization table (2 events from PR #741) - Add Python tab explaining event filtering approach - Update excluded fields list to include orchestrator and state - Note Error object serialization format
Replace the three comprehensive tables (agent events, multi-agent events, A2A events) in the TypeScript serialization tab with prose that explains the behavior, the key differences during serialization, and mentions a few examples of filtered/included fields without an exhaustive listing. Python tab remains unchanged.
Show what an event looks like in-process (with agent reference) versus what JSON.stringify produces (compact wire-safe output). Covers text deltas, lifecycle events, and result events.
|
/strands review |
agent-of-mkmeral
left a comment
There was a problem hiding this comment.
Review — /strands review
Overall: Looks good to me ✅ — clean addition, well-structured, all previous feedback addressed.
Summary
| Aspect | Status |
|---|---|
| CI | ✅ Green |
| All 3 review threads | ✅ Resolved |
| Placement | ✅ ### Event Serialization under Event Types, before Quick Examples |
| Consistency | ✅ Uses <Tabs> pattern matching rest of page |
| Files changed | 2 files, +81/-2 lines |
What's Good
-
TypeScript tab — Clear explanation of
toJSON()mechanics. The code example with inline comments showing in-process vs serialized output is really instructive. Leads with what each event keeps (per earlier feedback). -
Python tab — The
filter_event()helper is practical and actionable. Since Python events are plain dicts with no built-in serialization filter, showing a concrete pattern users can adapt is the right call. -
async-iterators.ts — The 3-line comment on the
JSON.stringify(event)call adds context without being noisy.
Minor Nits (non-blocking)
-
"wire-safe" in async-iterators.ts comment — The code comment says
"Events automatically serialize to compact, wire-safe JSON via toJSON()". Earlier feedback asked to prefer "serialization" language over "wire" language. Consider:// Events automatically serialize to compact JSON via toJSON().(Drop "wire-safe" to stay consistent with the main docs section title "Event Serialization".)
-
Python tab existence — Previous feedback said "I don't want a tab for python". The content is completely rewritten now (the incorrect info is gone, replaced with a useful
filter_eventpattern), so this is likely fine — but flagging in case @mkmeral still prefers no Python tab here.
Neither nit is blocking. PR is ready for maintainer approval.
| The same behavior applies to multi-agent and A2A events. Multi-agent events include identifying context like `nodeId` and `nodeType` alongside their data, while the `orchestrator` and `state` references are filtered out. This means you can serialize any event from `agent.stream()` or a multi-agent orchestrator's stream without additional processing: | ||
|
|
||
| ```typescript | ||
| for await (const event of agent.stream('Hello')) { |
There was a problem hiding this comment.
Nit: Consider defining in ts file for type checking/linting.
There was a problem hiding this comment.
Done in the previous commit (26b0635) — moved the snippet into overview.ts with --8<-- [start/end:event_serialization] markers for type checking. This latest commit (d506871) also rewrites the snippet contents to be real executable code.
Address @pgrayy's review nit: extract the inline TypeScript code block from index.mdx into overview.ts with --8<-- markers, matching the existing pattern used by all other code snippets on this page. Also drops 'wire-safe' from the async-iterators.ts comment per earlier review feedback to use 'serialization' language consistently.
|
Addressed @pgrayy's nit in
CI should pick it up. PR is ready to merge once it goes green. 🚀 |
| for await (const event of agent.stream('Hello')) { | ||
| // Every event is a class instance. In-process, it carries the full agent reference: | ||
| // | ||
| // event.type → "modelStreamUpdateEvent" |
There was a problem hiding this comment.
Good call — pushed d506871 to fix this.
Replaced the commented-out block with a real switch/case that mirrors the Python tab's filter_event pattern:
- Forwards text deltas for real-time display
- Forwards tool names for progress indicators
- Forwards the final
agentResultEvent - Skips everything else (lifecycle, metadata, etc.)
All executable code, no comments pretending to be output.
|
|
||
| Every event class implements a `toJSON()` method that controls what `JSON.stringify()` produces. This keeps serialized payloads compact for SSE, WebSockets, or HTTP responses — without changing the in-process API. | ||
|
|
||
| Each serialized event always includes its `type` discriminator alongside the data fields relevant to that event. For example, a `ModelStreamUpdateEvent` serializes to `{ type, event }` with just the streaming delta, and an `AgentResultEvent` includes `{ type, result }` with the final output. Lifecycle events like `BeforeInvocationEvent` and `AfterInvocationEvent` serialize to just `{ type }`, since they signal state transitions without carrying additional data. |
There was a problem hiding this comment.
This can be much more concise; we spend 4 paragraphs explaining that toJSON() excludes object references and properties that are settable; I think we can state that and indicate that it matches the general shape and data of the class but exclude settable properties and object references specific to in-memory (like agent/graph etc.)
There was a problem hiding this comment.
Condensed in the same commit (d506871).
4 paragraphs → 1 paragraph. Now reads:
Every event class implements a
toJSON()method thatJSON.stringify()calls automatically. Each serialized event retains itstypediscriminator and the relevant data fields — matching the general shape of the class — while excluding in-memory runtime references (agent,orchestrator,state,tool) and mutable hook properties (cancel,retry).Errorobjects are converted to{ message: string }. This applies to single-agent, multi-agent, and A2A events alike.
- Condensed 4 paragraphs about toJSON() into 1 concise paragraph (index.mdx) - Replaced commented-out code with a real event-filtering example that mirrors the Python tab's filter_event pattern (overview.ts) - The TS snippet now shows a switch/case that forwards text deltas, tool names, and the final result — all real executable code
|
Addressed @zastrowm's review in
CI should pick it up. Ready for re-review. 🚀 |
|
Assessment: Approve Good documentation addition for TypeScript event serialization. Previous review feedback from @pgrayy and @zastrowm has been addressed. Review Summary
The open review threads can be resolved since all feedback has been implemented. 🚀 |
|
|
||
| Every event class implements a `toJSON()` method that `JSON.stringify()` calls automatically. Each serialized event retains its `type` discriminator and the relevant data fields — matching the general shape of the class — while excluding in-memory runtime references (`agent`, `orchestrator`, `state`, `tool`) and mutable hook properties (`cancel`, `retry`). `Error` objects are converted to `{ message: string }`. This applies to single-agent, multi-agent, and A2A events alike. | ||
|
|
||
| Like the Python example, you can filter which events to forward: |
There was a problem hiding this comment.
Don't reference Python here! People aren't looking at both
There was a problem hiding this comment.
Fixed in 8fc5a3a — changed:
Like the Python example, you can filter which events to forward:
→
You can filter which events to forward to the client:
Good catch — users viewing the TS tab haven't seen the Python tab.
Address @zastrowm review — users viewing the TypeScript tab haven't seen the Python tab, so 'Like the Python example' is a broken reference. Changed to standalone phrasing.
|
Addressed @zastrowm's latest feedback in
All previous threads were already addressed. Ready for re-review. 🚀 |

Description
Documents the
toJSON()serialization behavior for all TypeScript streaming events. When events are sent over the wire (SSE, WebSockets, HTTP responses), thetoJSON()method ensures compact output (~100-200 bytes) instead of serializing the entireAgentinstance (~54KB+ per event).Changes
Streaming Overview (
index.mdx): Added new "Wire-Safe Serialization (TypeScript)" section with:toJSON()works withJSON.stringify()agent,tool,cancel,retry){ error: { message?: string } })Express.js example (
async-iterators.ts): Added comments explaining the automatic wire-safe serialization behaviorRelated Issues
toJSON()to all streaming eventsType of Change
Checklist
npm run dev