3f62880da4
Three dashboard-scoped stream routes were passing request.signal into realtimeStream.streamResponse. That signal is broken under Remix+Express (see apps/webapp/CLAUDE.md, nodejs/node#55428 — the chain is severed when Remix internally clones the Request), so when a user closes their dashboard tab the signal never fires. The underlying RedisRealtimeStreams.streamResponse loops while(!signal.aborted) over XREAD BLOCK and only exits on its 15s inactivity timeout; the S2 path keeps the upstream fetch open for up to its 60s wait window. Thread getRequestAbortSignal() through: - resources/orgs/.../runs/$runParam/realtime/v1/streams/$runId/$streamId - resources/orgs/.../runs/$runParam/realtime/v1/streams/$runId/input/$streamId - resources/orgs/.../playground/realtime/v1/streams/$runId/$streamId Each picks up the Express res.on('close')-backed signal that fires reliably when the downstream client disconnects.