Skip to content

fix: prevent stream_async() from yielding non-serializable invocation_state fields#2066

Open
Zelys-DFKH wants to merge 1 commit intostrands-agents:mainfrom
Zelys-DFKH:fix/stream-async-invocation-state-pollution
Open

fix: prevent stream_async() from yielding non-serializable invocation_state fields#2066
Zelys-DFKH wants to merge 1 commit intostrands-agents:mainfrom
Zelys-DFKH:fix/stream-async-invocation-state-pollution

Conversation

@Zelys-DFKH
Copy link
Copy Markdown

Description

stream_async() yields each event dict directly after calling event.prepare(invocation_state=...). The prepare() method merges the full invocation_state mapping into the event dict, which includes non-serializable objects such as the Agent instance, OTel span objects, message history, and the model object. Callers that attempt to serialize these events (for example, AgentCore's SSE stream) raise TypeError: Object of type Agent is not JSON serializable.

The fix snapshots event.as_dict() before prepare() runs, so callers of stream_async() only ever receive the serializable event fields. The callback_handler still receives the full merged dict (preserving existing behavior).

Related Issues

Resolves #1928

Documentation PR

N/A

Type of Change

Bug fix

Testing

  • I ran hatch run prepare

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

ModelStreamEvent.prepare() merged the full invocation_state dict into the
event dict before it was yielded to callers. Because invocation_state can
contain non-JSON-serializable objects (Agent instance, OTel spans), those
objects appeared in every streamed event, causing repr() serialization on
the wire and hitting payload limits in runtimes like AgentCore.

The fix snapshots the event data before prepare() is called and yields that
snapshot instead of the merged dict. The callback_handler still receives the
fully-merged dict for backward compatibility.

Fixes strands-agents#1928
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stream_async() yields events with non-serializable fields, breaking AgentCore SSE streaming

1 participant