ARES

ADR-0005: Streaming uses Server-Sent Events

Superseded by ADR-0007. This record was inaccurate when written: on the date below, chat-stream.ts already used WebSocket. It describes the decision ARES inherited from upstream Hermes WebUI, not what ARES implemented. Retained unedited as history; do not cite it as current architecture.

Status: Superseded (was: Accepted (inherited)) Date: 2026-07-22 (recorded retroactively)

Context

ARES inherited SSE streaming from Hermes WebUI, whose own ADR-004 chose SSE over WebSockets. ARES never recorded the reasoning, so the choice has periodically looked arbitrary.

Chat streaming is one-directional: the server pushes tokens, tool activity, and completion events. The client’s only upstream actions — send, cancel, approve — are ordinary HTTP requests.

Decision

Keep SSE. POST /api/chat/start returns a stream_id; the browser opens EventSource('/api/chat/stream?stream_id=…') and consumes typed events until done or error.

Consequences

Good:

Costs:

Note

fastapi_app/routers/realtime.py also exposes a WebSocket route for session streams. SSE remains the path used by the Chat surface; the WebSocket route is not the default and should not be treated as a second parallel implementation without a product decision.

Revisit if

Streaming becomes genuinely bidirectional and latency-sensitive — for example live voice, where round-trip audio would justify a persistent duplex channel.