Skip to content

feat(aws-strands): add tool_stream_event_handler hook to ToolBehavior#1634

Draft
malaporte wants to merge 1 commit into
ag-ui-protocol:mainfrom
malaporte:tool-stream-event-handler
Draft

feat(aws-strands): add tool_stream_event_handler hook to ToolBehavior#1634
malaporte wants to merge 1 commit into
ag-ui-protocol:mainfrom
malaporte:tool-stream-event-handler

Conversation

@malaporte
Copy link
Copy Markdown

Summary

Add a new optional ToolStreamEventHandler callback to ToolBehavior that is invoked for every intermediate event yielded by an async-generator tool (tool_stream_event).

Motivation

When an orchestrator agent calls a specialist sub-agent via an async-generator @tool, Strands wraps each yielded value in a tool_stream_event. The existing handler only checks for {"state": ...} payloads and ignores everything else — making it impossible to surface the specialist's streaming activity (text, tool calls, results) to the frontend without reimplementing the entire event loop in a subclass.

This hook makes that use case a first-class citizen.

Changes

config.py

  • Added ToolStreamEventHandler = Callable[[str, Any], AsyncIterator[Any]] type alias
  • Added tool_stream_event_handler: Optional[ToolStreamEventHandler] = None field to ToolBehavior

agent.py

  • Replaced the 5-line tool_stream_event branch with a dispatch: if a ToolBehavior with tool_stream_event_handler is registered for the tool, call it and forward its yielded events; otherwise fall through to the existing {"state": ...} snapshot behaviour

__init__.py

  • Exported ToolStreamEventHandler

Behaviour

  • Backward compatible: tools without a tool_stream_event_handler continue to work exactly as before
  • When a handler is registered, the default state-snapshot behaviour is suppressed for that tool; the handler is responsible for any state updates it wants to emit
  • The handler receives (tool_use_id: str, stream_data: Any) and may yield zero or more AG-UI Event objects which are forwarded directly into the top-level stream

Add a new optional ToolStreamEventHandler callback to ToolBehavior that
is invoked for every intermediate event yielded by an async-generator
tool (tool_stream_event). The handler receives (tool_use_id, stream_data)
and may yield zero or more AG-UI events forwarded into the top-level stream.

When a handler is registered the default state-snapshot behaviour is
suppressed for that tool; the handler is responsible for any state
updates it wants to emit. All other tools retain the existing behaviour.

This makes it possible to surface sub-agent streaming activity (e.g.
specialist-run ActivityMessages) without reimplementing the full event
loop in a subclass.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 5, 2026

@malaporte is attempting to deploy a commit to the CopilotKit Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant