()
| 1556 | |
| 1557 | # Convert the events to properly formatted SSE |
| 1558 | async def event_generator(): |
| 1559 | async with Aclosing( |
| 1560 | runner.run_async( |
| 1561 | user_id=req.user_id, |
| 1562 | session_id=req.session_id, |
| 1563 | new_message=req.new_message, |
| 1564 | state_delta=req.state_delta, |
| 1565 | run_config=RunConfig( |
| 1566 | streaming_mode=stream_mode, |
| 1567 | custom_metadata=req.custom_metadata, |
| 1568 | ), |
| 1569 | invocation_id=req.invocation_id, |
| 1570 | ) |
| 1571 | ) as agen: |
| 1572 | try: |
| 1573 | async for event in agen: |
| 1574 | # ADK Web renders artifacts from `actions.artifactDelta` |
| 1575 | # during part processing *and* during action processing |
| 1576 | # 1) the original event with `artifactDelta` cleared (content) |
| 1577 | # 2) a content-less "action-only" event carrying `artifactDelta` |
| 1578 | events_to_stream = [event] |
| 1579 | if ( |
| 1580 | not req.function_call_event_id |
| 1581 | and event.actions.artifact_delta |
| 1582 | and event.content |
| 1583 | and event.content.parts |
| 1584 | ): |
| 1585 | content_event = event.model_copy(deep=True) |
| 1586 | content_event.actions.artifact_delta = {} |
| 1587 | artifact_event = event.model_copy(deep=True) |
| 1588 | artifact_event.content = None |
| 1589 | events_to_stream = [content_event, artifact_event] |
| 1590 | |
| 1591 | for event_to_stream in events_to_stream: |
| 1592 | sse_event = event_to_stream.model_dump_json( |
| 1593 | exclude_none=True, |
| 1594 | by_alias=True, |
| 1595 | ) |
| 1596 | logger.debug( |
| 1597 | "Generated event in agent run streaming: %s", sse_event |
| 1598 | ) |
| 1599 | yield f"data: {sse_event}\n\n" |
| 1600 | except Exception as e: |
| 1601 | logger.exception("Error in event_generator: %s", e) |
| 1602 | yield f"data: {json.dumps({'error': str(e)})}\n\n" |
| 1603 | |
| 1604 | # Returns a streaming response with the proper media type for SSE |
| 1605 | return StreamingResponse( |
nothing calls this directly
no test coverage detected