feat: add SSE endpoint for streaming ticket notes generation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-28 23:04:14 +00:00
parent 72fc56529d
commit d456b1156e

View File

@@ -924,6 +924,52 @@ async def get_documentation(
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
@router.get("/{session_id}/documentation/stream")
@limiter.limit("20/minute")
async def stream_documentation(
request: Request,
session_id: UUID,
current_user: Annotated[User, Depends(get_current_active_user)],
db: Annotated[AsyncSession, Depends(get_db)],
):
"""Stream AI-generated ticket notes as Server-Sent Events."""
from starlette.responses import StreamingResponse
# Verify session ownership
result = await db.execute(
select(AISession).where(AISession.id == session_id)
)
session = result.scalar_one_or_none()
if not session:
raise HTTPException(status_code=404, detail="Session not found")
if session.user_id != current_user.id:
raise HTTPException(status_code=403, detail="Not authorized")
async def event_generator():
try:
async for chunk in flowpilot_engine.stream_ticket_notes(
session_id=session_id,
user_id=current_user.id,
db=db,
):
# SSE format: data: <text>\n\n
yield f"data: {chunk}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logger.exception("SSE stream error for session %s: %s", session_id, e)
yield f"data: [ERROR] {str(e)}\n\n"
return StreamingResponse(
event_generator(),
media_type="text/event-stream",
headers={
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"X-Accel-Buffering": "no", # Disable nginx buffering
},
)
# ── Status Update ──
@router.post("/{session_id}/status-update", response_model=StatusUpdateResponse)