"""SSE 스트리밍 공통 유틸리티. persona_agent의 SSE 이벤트를 수신하여 토큰을 수집한다. kei_client, content_editor, design_director에서 공통 사용. """ from __future__ import annotations import json import logging import httpx logger = logging.getLogger(__name__) async def stream_sse_tokens(response: httpx.Response) -> str: """SSE 스트리밍 응답에서 토큰을 실시간 수집한다. persona_agent의 SSE 이벤트: - token: 텍스트 토큰 수집 - done: 완료, 중단 - error: 에러, 즉시 중단 - planning/planning_done/research_progress/warning: 스킵 """ tokens: list[str] = [] event_type = "" async for line in response.aiter_lines(): line = line.strip() if not line: event_type = "" continue if line.startswith("event:"): event_type = line[6:].strip() elif line.startswith("data:"): data = line[5:].strip() if event_type == "token" and data: try: token = json.loads(data) if isinstance(token, str): tokens.append(token) except json.JSONDecodeError: tokens.append(data) elif event_type == "done": break elif event_type == "error": logger.warning(f"Kei API SSE 에러: {data}") break return "".join(tokens)