Which agent spoke attribution
Per-agent attribution is what separates a transparent multi-agent system from a black box. When a user sees 'policy_agent is searching your policy...' then 'policy_agent answered', they understand the system. Ops teams can trace which subagent misbehaved. The same attribution feeds observability tools and lets you build dashboards that show request volume per route.
from fastapi import APIRouter
from fastapi.responses import StreamingResponse
from models import ChatRequest
from service import stream_chat
router = APIRouter(prefix='/insurance-copilot', tags=['insurance-copilot'])
@router.post('/chat/stream')
async def chat_stream(request: ChatRequest):
"""Server-Sent Events stream of the supervisor plus subagent trace."""
async def event_source():
async for chunk in stream_chat(
message=request.message,
thread_id=request.thread_id,
customer_id=request.customer_id,
):
yield chunk
return StreamingResponse(
event_source(),
media_type='text/event-stream',
headers={
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'X-Accel-Buffering': 'no',
},
)Three headers matter. Cache-Control: no-cache prevents proxies from buffering. Connection: keep-alive keeps the socket open. X-Accel-Buffering: no tells nginx not to buffer SSE, which would otherwise batch your events and kill the real-time feel.
SSE event timeline for a single message
Events the browser receives during one chat turn, from start to done.
Matching exercise: Match SSE event to what the UI should render
Loading practice…
Checkpoint: Streaming and attribution checkpoint
Loading practice…