sse-streaming-safely
Skill0 starsChanged 25 days agoMITView on GitHub
Stream LLM/agent tokens over SSE without the two bugs that bite every deploy — nginx buffering (tokens dump) and Hono onError not firing once the stream starts (silent truncation). Use when asked to "stream LLM tokens", "add an SSE endpoint", "build a streaming route", or "tokens arrive all at once / the stream just stops". Encodes turbo's S-08 scenario + O-12 opinion + P-10/P-11/P-12 pitfalls.
In this repository33 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- llms.txtllms.txt
- agent-runtimeSkill
- frontend-designSkill
- architectSkill
- deep-thinkSkill
- design-systemsSkill
- ecosystem-referenceSkill
- fractal-delegationSkill
- harness-reviewSkill
- heartbeatSkill
- integrate-resourcesSkill
- llm-council-critiqueSkill
- loop-createSkill
- mcp-setupSkill
- memory-compressionSkill
- memorySkill
- model-routingSkill
- oss-project-scaffoldSkill
- playwright-cliSkill
- repo-scoutSkill
- self-improveSkill
- skill-creatorSkill
- skill-routingSkill
- sprintSkill
- test-visualSkill
- troubleshootSkill
- ux-auditSkill
- audit-serverless-stateSkill
- design-api-contractSkill
- scaffold-hono-serviceSkill
- zod-boundary-and-patchSkill
The file
Files
sse-streaming-safely
Encodes scenario S-08 (the SSE stream that dumped and swallowed its error), opinion O-12 (default to SSE for agent/LLM output; always the 3rd-arg error handler +
X-Accel-Buffering: no), and pitfalls P-10 (tokens batch behind nginx), P-11 (HonoonErrordoes NOT fire once a stream starts), P-12 (response body is one-shot). The two failures bite every SSE deploy.
Trigger
Invoke when the user (or a coding agent) asks to:
- "stream LLM tokens" / "add an SSE / streaming endpoint" / "build a streaming route"
- "tokens arrive all at once" (the nginx-buffering symptom) / "the stream just stops with no error" (the onError symptom)
- anything where an agent/LLM emits tokens incrementally to a client.
(Reach for WebSocket instead ONLY when the client must talk back during the stream — interrupts/stop-generation, tool-use approvals, multi-agent routing, live collaboration.)
Steps
- Default to SSE for one-way token streaming. OpenAI/Anthropic/Gemini all use SSE; HTTP/2 multiplexes;
EventSourceauto-reconnects viaLast-Event-ID. Use HonostreamSSE. - Audit the route file with the detector first:
It flags the SSE traps: missing 3rd-arg error handler, missingturbo stream-doctor <route-file>X-Accel-Buffering: no, nowhile (!stream.aborted)loop, and re-read body. Expect it to report P-10 and P-11 on a naive route. - Fix P-10 (nginx buffering — the #1 SSE prod issue): set the headers so the proxy stops buffering:
On Cloudflare Workers, setX-Accel-Buffering: no Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-aliveContent-Encoding: IdentityifstreamTextmalfunctions. - Fix P-11 (onError doesn't fire mid-stream): once headers/status are sent you cannot turn 200 into 500, so
app.onErrorwill NOT catch a throw inside the stream callback. Pass the optional 3rd-arg error handler tostreamSSE; on error, write anevent: errorSSE frame, then close. A route-leveltry/catcharound the whole handler does NOT help — the stream already started. - Stop burning tokens on disconnect: loop
while (!stream.aborted)+ registerstream.onAbort()so generation stops when the client leaves. Emit a monotonicidforLast-Event-IDresume; send: pingevery ~15s when idle. - Never re-read the body (P-12): a Fetch
Responsebody is one-shot —res.clone()before reading, or read once and pass the parsed value downstream. Body-inspecting middleware that reads the body before the handler also reads it triggers "disturbed or locked." - Verify the behavior (the binary gate): tokens arrive incrementally through the proxy (not batched); an injected in-stream error produces an
event: errorframe + clean close (not silent truncation); a client disconnect stops token generation.
Output
turbo stream-doctorfindings (P-10/P-11 cleared)- the streaming route with: the four buffering headers, the 3rd-arg error handler writing
event: error, thewhile (!stream.aborted)loop +onAbort, monotonicids - the three behavior checks: incremental delivery through the proxy · injected error →
event: errorframe + clean close · disconnect stops generation - a note if WebSocket was considered (and why SSE was kept, or why WS is justified for bidirectional)
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

