fix(server): SSE keep-alive on /v1/agent/stream to survive proxy idle timeouts (T-125) #116

Merged
ahitosly merged 1 commit from feat/T-125-agent-stream-keepalive into main 2026-09-07 21:59:13 +02:00
Owner

Tâche

T-xxx — (titre dans docs/STATUS.md)

Changements

Contrat modifié ?

  • Non
  • Oui : packages/contract / supabase/migrations — docs/API.md / docs/DATA.md mis à jour, label contract, approbation humaine requise

Tests

  • scripts/check.sh vert
  • Test manuel (OS, scénario) :

Impacts cross-domaine

Fichiers hors périmètre de l'agent (et pourquoi) :

Suivi

  • docs/STATUS.md mis à jour (ligne de la tâche)
  • docs/CHANGELOG.md : entrée ajoutée sous Unreleased
  • docs/DECISIONS.md / docs/ECARTS.md mis à jour si décision ou écart
## Tâche T-xxx — (titre dans docs/STATUS.md) ## Changements - ## Contrat modifié ? - [ ] Non - [ ] Oui : `packages/contract` / `supabase/migrations` — `docs/API.md` / `docs/DATA.md` mis à jour, label `contract`, approbation humaine requise ## Tests - [ ] `scripts/check.sh` vert - [ ] Test manuel (OS, scénario) : ## Impacts cross-domaine Fichiers hors périmètre de l'agent (et pourquoi) : ## Suivi - [ ] `docs/STATUS.md` mis à jour (ligne de la tâche) - [ ] `docs/CHANGELOG.md` : entrée ajoutée sous Unreleased - [ ] `docs/DECISIONS.md` / `docs/ECARTS.md` mis à jour si décision ou écart
fix(server): SSE keep-alive on /v1/agent/stream to survive proxy idle timeouts (T-125)
All checks were successful
ci / desktop-rust (pull_request) Successful in 3m14s
ci / server (pull_request) Successful in 14s
ci / desktop-ts (pull_request) Successful in 28s
7d47b36c11
Real bug confirmed against the deployed server: the SSE connection was cut
after ~50s systematically while waiting for Hermes to produce its first
token (typically mid tool-call), even though Hermes finished responding on
its own dashboard. Distinct from the buffering fix in T-104 (X-Accel-Buffering):
an intermediary reverse proxy idle timeout cuts a connection with zero bytes
in flight, which disabling buffering does not address.

pipeline/agent.py::_stream_with_keepalive wraps agent.run_stream() with a
persistent asyncio task observed via asyncio.wait(timeout=...) and emits an
SSE comment line (": keep-alive\n\n") every agent_stream_keepalive_s seconds
(15s default) of inactivity. Using asyncio.wait_for directly on __anext__()
was tried first and is documented as a real pitfall: it cancels the
underlying task on timeout, closing the async generator for good.

Transport-level only, no new SSE event type / no contract change; confirmed
by an explicit Rust test that the desktop SSE parser already ignores
comment-only frames silently.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011MSWGSF3VJrGALNM8JsE2u
ahitosly scheduled this pull request to auto merge when all checks succeed 2026-09-07 21:59:01 +02:00
ahitosly deleted branch feat/T-125-agent-stream-keepalive 2026-09-07 21:59:13 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
cloud-rennais/aria!116
No description provided.