AshA2A

Hex Version HexDocs CI License: MIT

A Spark.Dsl.Extension that exposes Ash.Resource/Ash.Domain actions as A2A protocol agent skills, built on the :a2a Elixir SDK (a published Hex package, {:a2a, "~> 0.2"}, implementing A2A protocol v0.3 over JSON-RPC 2.0/HTTP with SSE streaming).

Naming: the library and module prefix is AshA2A, the Hex package is ash_a2a, and SA2A is the internal project codename used by the RFCs (docs/rfc/) and the conformance courts (docs/explanation/).

Every public Ash action on an extended resource or domain is projected into a verified capability index — no declaration required. An optional a2a do skill ... end block adds A2A-only metadata overrides, and the compiled index:

Requirements

Installation

def deps do
[
{:ash_a2a, "~> 26.9"}
]
end

:a2a arrives transitively; pin {:a2a, "~> 0.2"} explicitly only if your own code calls A2A.* modules directly.

mix ash_a2a.install (an Igniter task) wires the extension into an existing project; see Mix.Tasks.AshA2a.Install.

Usage

Declare the DSL on a resource (or domain):

defmodule MyApp.Echo do
use Ash.Resource,
domain: MyApp.Domain,
data_layer: Ash.DataLayer.Ets,
extensions: [AshA2A]
attributes do
uuid_primary_key(:id)
attribute(:message, :string, public?: true)
end
actions do
defaults([:read])
end
end
defmodule MyApp.Domain do
use Ash.Domain, extensions: [AshA2A]
resources do
resource(MyApp.Echo)
end
end

Public actions are exposed with no a2a block at all; a2a do skill(:echo, :read) end is an optional override (rename, describe, tag, exclude, or classify). AshA2A.Transformers.BuildCapabilityIndex compiles the residual overrides and AshA2A.Verify checks the projection fail-closed after compilation.

Dispatch a message directly (no process):

message = A2A.Message.new_user([A2A.Part.Data.new(%{})])
{:reply, [%A2A.Part.Data{data: %{results: []}}]} =
AshA2A.Dispatcher.dispatch(:echo, message, MyApp.Echo)

dispatch/5 takes further history and auth_identity arguments (both default to nil). auth_identity is the trust boundary: with the default nil, context.actor/context.tenant resolve to nil and dispatch fails closed for anything your Ash policies gate on identity — identity only ever arrives from transport-verified auth (A2A.Plug.Auth), never from message metadata. See Authenticate inbound A2A requests.

To boot supervised agent processes, serve them over HTTP (agent card + JSON-RPC + SSE), and drive them with A2A.Client, continue with the Getting Started tutorial; for the exact wire contract, see the A2A endpoint reference.

Local development setup

Running this repo's own mix test requires one native Rust CLI binary to be built first. CI (.github/workflows/ci.yml) builds it automatically (pinned Rust 1.97.1); a local clone does not, so this is a real, one-time manual step:

cd native/hddl_cli && cargo build --release --locked && cd -

Full detail: Testing ash_a2a (your app and this repo). Both target/ directories are gitignored build artifacts and are never committed.

Documentation

This project follows the Diataxis documentation framework: tutorials for learning, how-to guides for specific tasks, reference for lookup, and explanation for understanding. It is published on HexDocs and buildable locally with mix docs.

Internal evidence and reports (not user documentation)

These artifacts are deliberately published with the repository but are point-in-time engineering records, not guides:

Security

Identity is a trust boundary: actor/tenant only ever come from transport-verified A2A.Plug.Auth output, and consequential (:change/:external_do) skills additionally require a standing grant from AshA2A.Authority.Grant — authentication alone never confers authority (RFC-SA2A-001 S29). Neither shipped broker (InMemory, Ekv) is Sybil-resistant; bring your own identity system for production. See the authentication how-to and SECURITY.md.

Status

Versioning is calendar-based (26.9.x); ~> 26.9 pins within the 26.9 series. Semantic Versioning is intended after 1.0. See the CHANGELOG — note that main routinely runs ahead of the latest published Hex release.

License

MIT — see LICENSE.