fix(agent): report a failed stream as failed + release 0.3.0 - #109
Merged
Merged
Conversation
A {:stream, …} reply finalizes the task from the cleanup hook that fires
when enumeration stops, and that hook cannot tell why it stopped — so it
reported success for every ending. A stream that raised was stored as
completed, and its partial output kept as the result. The connection
process meanwhile rescued and told the client the task had failed, so
the two never agreed and nothing reconciled them.
Enumeration now carries how it ended, by splitting the hook that runs
only on normal completion from the one that always runs. A stream that
raised, or that was abandoned when the client disconnected, marks the
task failed. The parts it managed to emit are still kept — they are the
agent's output, and discarding them would lose information — but the
state no longer claims a result that was never produced.
Recently widened rather than introduced: push notification delivery and
resubscribe both read that state, so a failed stream had started
actively telling webhook receivers and subscribers it had succeeded.
Also merges two duplicate Changed sections in the unreleased changelog.
Closes #107.
Stamps the changelog for release. The version in mix.exs was bumped after 0.2.0 but never published, so everything since March ships here: the v1.0 wire format, push notification delivery, task resubscribe, and the compliance work that drove the TCK baseline to empty. Pre-1.0, so the breaking wire changes land in a minor bump.
TCK Compliance ResultsResult: passed - failures match the tracked baseline. TCK run complete — 0 known failure(s), matching test/tck/expected-failures.txt. |
|
Reviewed — no high-confidence issues found. LGTM. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #107 — a stream that raises was stored as
completed— and stamps the changelog for 0.3.0, the first release since 0.2.0 in March.Type of change
The bug
Verified before and after, driving
CrashingStreamAgentthrough a realA2A.Plug:wrap_stream/3finalized the task fromStream.transform/4's after-fun — a cleanup hook that runs however enumeration stops, so it reported success for every ending. The connection process rescued separately and told the clientfailed. Nothing reconciled them.The fix
Stream.transform/5splits the hook that runs only on normal completion (last_fun) from the one that always runs (after_fun), so enumeration can carry how it ended:completedfailedfailedPartial parts are kept — they're the agent's real output, and discarding them loses information — but the state no longer claims a result that was never produced.
Regression test included; it fails without the fix (
15/16 passed).Why now rather than later
The bug predates this work and shipped in 0.2.0. But #92 and #99 widened its blast radius: push notification receivers and resubscribers now read that state, so a failed stream had started actively telling them it succeeded. Releasing that amplification without the fix seemed wrong.
Release: 0.3.0
Second commit stamps
## [0.3.0] - 2026-09-23.mix.exswas already at 0.3.0 — bumped after 0.2.0 but never published — so it needs no change.Also merges two duplicate
### Changedsections that had accumulated in[Unreleased].Pre-1.0, so the breaking wire changes (
StreamResponse, ErrorInfo, streaming gate) land in a minor bump.Note for
a2ui-elixir: it depends on{:a2a, "~> 0.2", optional: true}, which resolves to>= 0.2.0, < 1.0.0— somix deps.update a2apicks 0.3.0 up with no constraint change. The SSE wire format changed, so anything consuming stream events there will need checking.Closes #107.