diff --git a/src/google/adk/cli/adk_web_server.py b/src/google/adk/cli/adk_web_server.py index c3b81b287b..ee3ccf6143 100644 --- a/src/google/adk/cli/adk_web_server.py +++ b/src/google/adk/cli/adk_web_server.py @@ -1623,9 +1623,23 @@ async def event_generator(): "Generated event in agent run streaming: %s", sse_event ) yield f"data: {sse_event}\n\n" + + # Send termination signal after all events have been streamed + yield "data: [DONE]\n\n" except Exception as e: logger.exception("Error in event_generator: %s", e) - yield f"data: {json.dumps({'error': str(e)})}\n\n" + # Yield a proper Event object for the error + error_event = Event( + author="system", + content=types.Content( + role="model", parts=[types.Part(text=f"Error: {e}")] + ), + ) + yield ( + "data:" + f" {error_event.model_dump_json(by_alias=True, exclude_none=True)}\n\n" + ) + yield "data: [DONE]\n\n" # Returns a streaming response with the proper media type for SSE return StreamingResponse( diff --git a/tests/unittests/cli/test_fast_api.py b/tests/unittests/cli/test_fast_api.py index 1ab1d41f47..d1cbf53304 100755 --- a/tests/unittests/cli/test_fast_api.py +++ b/tests/unittests/cli/test_fast_api.py @@ -1094,7 +1094,7 @@ async def run_async_with_artifact_delta( sse_events = [ json.loads(line.removeprefix("data: ")) for line in response.text.splitlines() - if line.startswith("data: ") + if line.startswith("data: ") and line != "data: [DONE]" ] assert len(sse_events) == 2