Skip to content

fix: wrap optimization handler responses in SSE streaming events#383

Open
Klausc06 wants to merge 2 commits intoAlishahryar1:mainfrom
Klausc06:fix/sse-optimization-streaming
Open

fix: wrap optimization handler responses in SSE streaming events#383
Klausc06 wants to merge 2 commits intoAlishahryar1:mainfrom
Klausc06:fix/sse-optimization-streaming

Conversation

@Klausc06
Copy link
Copy Markdown

@Klausc06 Klausc06 commented May 7, 2026

Summary

Optimization handlers (fast-prefix detection, quota check, title generation skip, suggestion skip, filepath mock) previously returned a plain JSON MessagesResponse directly. But Claude Code always sends stream=True, so the client expects Anthropic SSE event stream format. This mismatch caused Stream completed without receiving message_start errors and forced non-streaming fallbacks on every optimized request.

This PR adds _messages_response_to_sse_stream() which converts a MessagesResponse into a proper SSE event stream (message_startcontent_block_startcontent_block_deltacontent_block_stopmessage_deltamessage_stop), and wraps optimization results through it.

中文说明

优化处理器(前缀匹配、配额检查、标题生成跳过、建议跳过等)之前直接返回了普通的 JSON MessagesResponse。但 Claude Code 客户端始终发送 stream=True,期望收到 Anthropic SSE 事件流格式。这个不匹配导致了 Stream completed without receiving message_start 错误,并且每次优化命中的请求都会触发非流式降级。

本次 PR 新增了 _messages_response_to_sse_stream() 函数,将 MessagesResponse 转换为标准的 SSE 事件流,并包裹所有优化处理器的返回结果。

Test plan

  • uv run pytest tests/api/test_routes_optimizations.py passes
  • Optimization requests return text/event-stream; charset=utf-8 content type
  • SSE stream parses correctly with message_start / content_block_* / message_delta / message_stop events
  • No Stream completed without receiving message_start errors in Claude Code client logs

Files changed

File Δ
api/services.py +81/-1
tests/api/test_routes_optimizations.py +25/-2

🤖 Generated with Claude Code

Klausc06 and others added 2 commits May 7, 2026 16:37
Optimization handlers (prefix detection, quota check, title skip,
suggestion skip, filepath mock) previously returned plain JSON
MessagesResponse, but Claude Code always sends stream=True. This
caused "Stream completed without receiving message_start" errors
and forced non-streaming fallbacks on every optimized request.

Convert optimization results to proper Anthropic SSE event streams
(message_start → content blocks → message_delta → message_stop)
using json.dumps() for safe serialization.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…itation

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant