Skip to content

v0.3.0

Latest

Choose a tag to compare

@maxekman maxekman released this 23 Sep 08:50
· 1 commit to main since this release

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 StreamResponse status update to each registered webhook, with the config's credentials as an Authorization header. Pluggable via A2A.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 through configuration.taskPushNotificationConfig on message/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/3 is the client half.
  • Bare Message replies — {:message, parts} answers message/send with a Message instead of a Task, the other half of the SendMessageResponse oneof.
  • Agent card caching headers — ETag, Last-Modified and Cache-Control per §8.6.
  • A2A-Version and A2A-Extensions negotiation, v1.0 PascalCase method names, flat Part encoding, and task-level authorization hooks.

Fixed

  • A stream that raises, or whose client disconnects mid-stream, is no longer stored as completed. It is marked failed, 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, historyLength honoured 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.