fix(stream): every running agent's live text shares one connection, which ends when its steps do (#48) #68
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/one-delta-stream-48"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #48.
osfd speaks HTTP/1.1, and a browser allows six connections per host across all its tabs. The console held one stream for the run plus one per running agent step. On production on 2026-09-26,
run_01M3GB3KN38YT9TZJ7KA7RQ5M0fanned out to fourpropose.specsteps andpropose.design, which used all six: the light said offline, steps showed as silent, step details failed with "signal is aborted without reason", and the page wouldn't reload.It lasted because a step's delta stream never ended when the step did.
/healthzshowedsse: {a: 1, b: 5}with only one step still running.What changes
GET /api/deltas?steps=a,b,c: every step's deltas on one connection, each frame naming its step. The console opens one for its run's running agent steps and replaces it when that set changes. A page now holds two long-lived connections however many agents run.endand closes, and the console doesn't reconnect. The old one-step route stays for pages loaded before the deploy, and ends the same way, which frees stuck connections as soon as the server is updated.Verification
./tools/test.sh: fast lane passed, with 1,778 backend, 414 UI unit and 66 browser tests. New tests cover:endwhen the steps settle, both at once and mid-stream;end;e2e/connection-budget.spec.tsuses a new six-agent fixture run. It checks that one delta stream names all six steps, and that an ordinary request and a step's details still answer. Chromium enforces the same six-connection limit, so the old console fails it.agent-transcriptgains "Live text uses one connection however many agents run".🤖 Generated with Claude Code
osfd speaks HTTP/1.1, and a browser allows six connections per host across all its tabs. The console held one stream for the run and one per running agent step, so on production a fan-out of four propose.spec steps and propose.design used all six. The light said offline, steps showed as silent, step details failed with "signal is aborted without reason", and the page would not reload. It lasted because a step's delta stream never ended with the step: /healthz showed five open streams for steps that had finished minutes earlier. GET /api/deltas?steps=a,b,c carries every step's deltas on one connection; each frame already names its step. The console opens one for its run's running agent steps and replaces it when that set changes, so a page holds two long-lived connections however many agents run. At connect and at every heartbeat the server looks the steps up, and once none is still writing it sends an `end` frame and closes. The console does not reconnect after `end`. The one-step /api/steps/{id}/deltas stays, for pages loaded before this, and ends the same way. A request osfd does not answer in time now says so, and suggests closing other Braid tabs, instead of the browser's abort text. The fixture serves /api/deltas and has a six-agent run. A browser test on it checks that one delta stream names all six steps and that an ordinary request and a step's details still answer. Chromium enforces the same six-connection limit, so the old console fails it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>