stream.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. """
  2. engine.stream — SSE and WebSocket stream adapters.
  3. """
  4. from __future__ import annotations
  5. import json
  6. from typing import AsyncIterator
  7. from fastapi import WebSocket
  8. from fastapi.responses import StreamingResponse
  9. async def sse_response(event_iter: AsyncIterator[dict]) -> StreamingResponse:
  10. """Convert async event iterator to SSE StreamingResponse."""
  11. async def generate():
  12. async for event in event_iter:
  13. evt_type = event.get("event", "message")
  14. data = json.dumps(event.get("data", {}), ensure_ascii=False)
  15. yield f"event: {evt_type}\ndata: {data}\n\n"
  16. return StreamingResponse(generate(), media_type="text/event-stream",
  17. headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"})
  18. async def ws_handler(websocket: WebSocket, execute_fn):
  19. """WebSocket bidirectional handler for multi-turn agent interaction."""
  20. await websocket.accept()
  21. try:
  22. while True:
  23. data = await websocket.receive_json()
  24. if data.get("type") == "close":
  25. break
  26. input_text = data.get("input", "")
  27. result = await execute_fn(input_text)
  28. await websocket.send_json({"type": "response", "content": result.output,
  29. "usage": {"duration_ms": result.duration_ms, "steps": result.steps}})
  30. except Exception:
  31. pass
  32. finally:
  33. await websocket.close()