Skip to content

feat(starter): send SSE heartbeat comments on streaming endpoints - #80

Merged
Zhoujie628 merged 1 commit into
project-openan:mainfrom
Zhoujie628:main
Sep 17, 2026
Merged

Zhoujie628 merged 1 commit into
project-openan:mainfrom
Zhoujie628:main

Conversation

@Zhoujie628

Copy link
Copy Markdown
Contributor

Long-running agent executions leave the SSE stream silent between the WORKING status and the terminal event, allowing intermediaries (gateways, load balancers) to idle-timeout the connection before the result arrives.

Add a heartbeat scheduler to the A2AController that sends a standard SSE comment (: heartbeat) at a configurable interval on all streaming endpoints (message:stream, tasks/{id}:subscribe). The interval defaults to 15 seconds; set a2at.server.heartbeat-interval-seconds=0 to disable.

The heartbeat integrates with the existing emitter lifecycle: it is cancelled when the stream completes, errors, times out, or the client disconnects, and uses a single daemon thread shared by all streams.

4 new tests: default interval, zero-disables, negative-rejects, and stream-survives-through-multiple-heartbeat-intervals.

Long-running agent executions leave the SSE stream silent between the
WORKING status and the terminal event, allowing intermediaries (gateways,
load balancers) to idle-timeout the connection before the result arrives.
Field logs show ~81 seconds of silence before a gateway killed the stream,
forcing the client into a polling fallback.

Add a heartbeat scheduler to the A2AController that sends a standard SSE
comment (": heartbeat") at a configurable interval on all streaming
endpoints (message:stream, tasks/{id}:subscribe). The interval defaults
to 15 seconds, matching the cadence proven by field agents that keep
their streams alive through long diagnoses. Set
a2at.server.heartbeat-interval-seconds=0 to disable.

The heartbeat integrates with the existing emitter lifecycle: it is
cancelled when the stream completes, errors, times out, or the client
disconnects, and uses a single daemon thread shared by all streams.

Signed-off-by: Zhoujie628 <zhoujie628@users.noreply.github.com>
@Zhoujie628
Zhoujie628 requested a review from a team as a code owner September 17, 2026 01:28
@Zhoujie628
Zhoujie628 merged commit 61148e2 into project-openan:main Sep 17, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant