Skip to content

[BUG] Managed Agents: client.beta.sessions.events.stream() silently drops all events #1357

Description

@lelandfy

Environment:

  • anthropic 0.93.0
  • Python 3.11

Description:
client.beta.sessions.events.stream() returns a Stream[BetaManagedAgentsStreamSessionEvents] , but its iterator yields nothing because
Stream.__stream__ (in anthropic/_streaming.py) is hardcoded to match
only Messages API event names:

  if sse.event == "completion": ...                                                                                                                                                                                                                                                     
  if sse.event in ("message_start", "message_delta", "message_stop",
                   "content_block_start", "content_block_delta",                                                                                                                                                                                                                        
                   "content_block_stop", "message"): ...
  if sse.event == "ping": continue                                                                                                                                                                                                                                                      
  if sse.event == "error": raise ...           
  # No else — unknown event types silently dropped        

None of the managed agents event types: session.status_, agent.message,
agent.tool_use, agent.tool_result, agent.thinking, span.model_request_
,
session.error, etc. in this if chain. They are all dropped.

Minimal repro (no server required):

from unittest.mock import MagicMock                                                                                                                                                                                                                                                   
from anthropic._streaming import Stream, SSEDecoder, ServerSentEvent                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                      
# Build a fake SSE response with managed agents events                                                                                                                                                                                                                                
sse_bytes = b"""data: {"id":"evt_1","type":"session.status_running"}                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                      
data: {"id":"evt_2","type":"agent.message","content":[{"type":"text","text":"hi"}]}                                                                                                                                                                                                   
                                                                                                                                                                                                                                                                                      
data: {"id":"evt_3","type":"session.status_idle","stop_reason":{"type":"end_turn"}}                                                                                                                                                                                                   
                                             
"""                                                                                                                                                                                                                                                                                   
                                             
class FakeResponse:
    def iter_bytes(self):
        yield sse_bytes                                                                                                                                                                                                                                                               
    def close(self): pass
                                                                                                                                                                                                                                                                                      
# Mimic how events.stream() constructs the Stream                                                                                                                                                                                                                                     
stream = Stream.__new__(Stream)
stream.response = FakeResponse()                                                                                                                                                                                                                                                      
stream._cast_to = object                                                                                                                                                                                                                                                              
stream._client = MagicMock()
stream._client._process_response_data = lambda data, cast_to, response: data                                                                                                                                                                                                          
stream._decoder = SSEDecoder()                                                                                                                                                                                                                                                        
stream._iterator = stream.__stream__()                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                      
received = list(stream)                                                                                                                                                                                                                                                               
print(f"Stream yielded {len(received)} events out of 3 sent")                                                                                                                                                                                                                         
# Prints: Stream yielded 0 events out of 3 sent     

Expected: Stream yields 3 events matching the discriminated union.
Actual: Stream yields 0 events.

Impact: Every consumer of client.beta.sessions.events.stream()
is affected — managed agents streaming is entirely broken in 0.93.0.
events.list() still works for polling; only the streaming method is broken.

Suggested fix: Either add the managed agents event names to the
existing if chain, or fall through unknown sse.event values to
process_data(data=sse.json(), cast_to=cast_to, response=response)
so the discriminated union parsing kicks in.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions