a2aproject / a2aproject/a2a-rs

a2acli: task subscribe resumption after disconnect

Abierto
#186 0 comentarios 0 reacciones 0 asignados Ver en GitHub
enhancement
Lenguaje dominante
Rust
Estrellas
75
Forks
19
Merge medio
11 h 27 min
PR fusionados (30 d)
21

Descripción

Part of #181 (Tier 2).

## Summary

`A2ACLI_TASK_SUBSCRIBE_002` (Tier 2):

> Stream resumption after disconnect; the first event re-delivers the full `Task`, so no separate `get` is required (§9.4, §9.2).

`task subscribe` exists (#171) but does not resume. `consume_stream` in `a2acli/src/lib.rs` loops until the stream yields `None` and then returns `Ok(())` — a connection dropped mid-task is indistinguishable from a task that finished, so the command exits `0` having silently stopped watching.

## Why

This is the requirement that makes `subscribe` usable for the long-running tasks it exists for. An SSE connection held open for minutes will be dropped by proxies, load balancers and laptop sleep; a watcher that exits cleanly on a dropped connection reports success for work it stopped following.

§9.4 also notes *why* resumption is cheap here: `task subscribe`'s first event, when the task exists, is the full `Task`, so reconnecting reconciles state through the protocol itself and **no additional `task get` is needed**. Getting this wrong in the obvious way — reconnect, then poll to catch up — would add a round-trip the protocol already covers.

## Scope

- [ ] Distinguish a stream that **ended** (the task reached a terminal or interrupted state) from one that was **cut** (transport-level end with the task unsettled). Only the latter reconnects.
- [ ] On a cut, re-subscribe with bounded backoff, honoring `--timeout` as the overall ceiling and `--poll-interval` as the backoff base, so the existing flags keep their meaning rather than gaining a second set.
- [ ] Reconcile from the first event's `Task` — do **not** issue a `task get` after reconnecting.
- [ ] Do not re-emit events already printed: under `-o json --stream` the output is JSONL consumed incrementally, so a duplicate `Task` line after a reconnect would corrupt a consumer's view. Suppress the reconciling first event unless it carries a state change.
- [ ] Report each reconnection attempt on stderr; stdout carries only protocol events (§11.1).
- [ ] Exhausting `--timeout` while still unsettled is `A2ACLI_ERR_TIMEOUT`, exit 5 — consistent with the polling path (#171).
- [ ] Where the server supports resumption from the last received event, use it; otherwise a plain re-subscribe is sufficient per §9.4's "where the server supports it".
- [ ] Tests: a fixture stream that closes mid-task drives a reconnect and reaches the terminal state; a fixture that closes *after* a terminal state exits 0 without reconnecting; a never-settling stream times out at exit 5.

## Requirements closed

| ID | Requirement |
| --- | --- |
| `A2ACLI_TASK_SUBSCRIBE_002` | Stream resumption after disconnect; the first event re-delivers the full `Task`, so no separate `get` is required (§9.4, §9.2) |

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.