a2aproject / a2aproject/a2a-rs
a2acli: task subscribe resumption after disconnect
- 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
Evaluación
Este issue todavía no se ha evaluado.