First release since 0.2.0 in March. This is the A2A v1.0 protocol release: the JSON-RPC transport is now v1.0-complete for messaging, task lifecycle, streaming, and push notifications, and the TCK compliance baseline is empty — every test the pinned v1.0 suite runs against this library passes.
Compliance: 76.8% overall, 75/114 MUST passing. The remainder are capability- or transport-gated, not failures.
Breaking changes
Streaming events use the StreamResponse wrapper. Each SSE result now carries exactly one of task, message, statusUpdate or artifactUpdate instead of a flat object tagged with kind. The kind field is gone from status and artifact events, and final is gone from status events — v1.0 removed it, and a stream now ends when the task reaches a terminal or interrupted state.
%A2A.Event.StatusUpdate{} keeps its :final field, reconstructed on decode from the state, so matching on final: true still works. Decoding still accepts the old kind shape, so a v1.0 client can consume an older peer's stream.
A2A errors (-32001…-32009) serialize data as a google.rpc.ErrorInfo array rather than a bare map.
message/stream is gated on the declared streaming capability. A server that does not advertise capabilities.streaming now returns -32004 instead of streaming anyway:
{A2A.Plug, agent: MyAgent, base_url: url,
agent_card_opts: [capabilities: %{streaming: true}]}Added
- Push notification delivery — every task state change POSTs a
StreamResponsestatus update to each registered webhook, with the config's credentials as anAuthorizationheader. Pluggable viaA2A.PushNotificationSender; the bundled HTTP sender retries with backoff and can optionally reject plain-HTTP or private-IP URLs. - Push notification config CRUD — the four
tasks/pushNotificationConfig/*methods, plus inline registration throughconfiguration.taskPushNotificationConfigonmessage/send. tasks/resubscribe— reattach to a running task's stream: task snapshot first, then a status update per state change, ending at the terminal state.A2A.Client.resubscribe/3is the client half.- Bare
Messagereplies —{:message, parts}answersmessage/sendwith aMessageinstead of aTask, the other half of theSendMessageResponseoneof. - Agent card caching headers —
ETag,Last-ModifiedandCache-Controlper §8.6. A2A-VersionandA2A-Extensionsnegotiation, v1.0 PascalCase method names, flatPartencoding, and task-level authorization hooks.
Fixed
- A stream that raises, or whose client disconnects mid-stream, is no longer stored as
completed. It is markedfailed, and its partial output is kept rather than presented as the result. - The opening task snapshot is no longer dropped by our own client on every stream.
- Spec error codes on the send path,
historyLengthhonoured consistently, and optional-callback detection no longer depends on module load order.
Upgrading
Anything consuming SSE events needs updating for the StreamResponse wrapper — that is the one change most likely to bite.
If you depend on {:a2a, "~> 0.2"}, that constraint resolves to >= 0.2.0, < 1.0.0, so mix deps.update a2a picks this up including the breaking wire changes. Pin to ~> 0.2.0 if you are not ready.
Full detail in CHANGELOG.md.