The API wrapper
AutoGen gives you an event stream. FastAPI gives you HTTP. The bridge between them is an async generator that translates AutoGen events into Server-Sent Events the frontend can render.
from fastapi import APIRouter
from fastapi.responses import StreamingResponse
from service import generate_chat_stream
import uuid
router = APIRouter(prefix="/travel-support", tags=["travel-support"])
@router.post("/chat/stream")
async def chat_stream(request: ChatRequest):
session_id = request.session_id or str(uuid.uuid4())
return StreamingResponse(
generate_chat_stream(session_id, request.message),
media_type="text/event-stream",
)StreamingResponse pipes an async generator straight to the client as SSE. session_id keeps conversation state per user across turns.
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.messages import (
ToolCallRequestEvent,
ToolCallExecutionEvent,
ModelClientStreamingChunkEvent,
)
from autogen_core import CancellationToken
import json
async def generate_chat_stream(session_id, message):
agent = create_agent_with_tools(session_id)
team = RoundRobinGroupChat(participants=[agent], max_turns=5)
async for event in team.run_stream(
task=message,
cancellation_token=CancellationToken(),
):
if isinstance(event, ToolCallRequestEvent):
for tool_call in event.content:
yield f"data: {json.dumps({'type': 'tools', 'tool_name': tool_call.name, 'arguments': tool_call.arguments})}\n\n"
elif isinstance(event, ToolCallExecutionEvent):
for result in event.content:
yield f"data: {json.dumps({'type': 'tool_result', 'tool_name': result.name, 'result': result.content})}\n\n"
elif isinstance(event, ModelClientStreamingChunkEvent):
yield f"data: {json.dumps({'content': event.content})}\n\n"
yield f"data: {json.dumps({'done': True})}\n\n"Wrapping the agent in a RoundRobinGroupChat gives you the tool-execution loop for free. Each event type becomes a different SSE payload the frontend can render as markers, results, or streamed text.
GroupChat is what runs the tool-execution loop. With a bare AssistantAgent you would have to hand-roll the logic that catches ToolCallRequestEvent, runs the function, feeds the result back, and asks the model to continue. RoundRobinGroupChat does all of that, even with one participant. When you add more specialists later, the code does not change.
Quiz: Quiz
Loading practice…