Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 83 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"a2a-pb",
"a2a-grpc",
"a2a-slimrpc",
"a2a-websocket",
"a2acli",
"examples",
]
Expand Down Expand Up @@ -37,6 +38,7 @@ a2a-server = { package = "a2a-server-lf", path = "a2a-server", version = "0.2.7"
a2a-pb = { package = "a2a-pb", path = "a2a-pb", version = "0.1.7" }
a2a-grpc = { package = "a2a-grpc", path = "a2a-grpc", version = "0.2.1" }
a2a-slimrpc = { package = "a2a-slimrpc", path = "a2a-slimrpc", version = "0.1.10" }
a2a-websocket = { package = "a2a-websocket", path = "a2a-websocket", version = "0.1.0" }

# Serialization
serde = { version = "1", features = ["derive"] }
Expand Down Expand Up @@ -74,12 +76,19 @@ pbjson-build = "0.9"
protoc-bin-vendored = "3"
slim_bindings = { package = "agntcy-slim-bindings", version = "1.3.0" }

# WebSocket
fastwebsockets = { version = "0.10", features = ["upgrade", "with_axum"] }
http-body-util = "0.1"
hyper-util = { version = "0.1", features = ["tokio"] }
bytes = "1"

# Utilities
rcgen = { version = "0.14", default-features = false, features = ["crypto", "pem", "aws_lc_rs"] }
rustls-pemfile = "2"
chrono = { version = "0.4", features = ["serde"] }
base64 = "0.22"
thiserror = "2"
parking_lot = "0.12"
uuid = { version = "1", features = ["v7"] }
semver = "1"
tracing = "0.1"
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The workspace supports:
- REST / HTTP+JSON
- gRPC via `tonic`
- SLIMRPC via `slim_bindings`
- WebSocket custom protocol binding via `fastwebsockets`
- Server-Sent Events for streaming responses
- Protobuf-based interop with other SDKs and runtimes

Expand All @@ -29,6 +30,7 @@ The workspace supports:
| `a2a-pb` | Protobuf schema, generated types, ProtoJSON-capable generated types, and native <-> protobuf conversion helpers |
| `a2a-grpc` | gRPC client and server bindings built on `tonic` |
| `a2a-slimrpc` | SLIMRPC client and server bindings built on `slim_bindings` |
| `a2a-websocket` | WebSocket custom protocol binding (client and server) built on `fastwebsockets` and `axum` |
| `a2acli` | Standalone A2A client CLI, published as `a2a-cli`, for inspecting agent cards, sending messages, managing tasks, and handling push configs |
| `examples/helloworld` | Minimal runnable example agent |

Expand All @@ -40,6 +42,7 @@ The workspace supports:
| HTTP+JSON / REST | `a2a-client` | `a2a-server` |
| gRPC | `a2a-grpc` | `a2a-grpc` |
| SLIMRPC | `a2a-slimrpc` | `a2a-slimrpc` |
| WebSocket | `a2a-websocket` | `a2a-websocket` |

The gRPC support uses the schema in `a2a-pb/proto/a2a.proto`. The REST and
JSON-RPC bindings are intended to stay wire-compatible with other A2A SDKs,
Expand Down Expand Up @@ -138,6 +141,7 @@ a2a-server = { package = "a2a-server-lf", git = "https://github.com/a2aproject/a
a2a-pb = { package = "a2a-pb", git = "https://github.com/a2aproject/a2a-rs.git" }
a2a-grpc = { package = "a2a-grpc", git = "https://github.com/a2aproject/a2a-rs.git" }
a2a-slimrpc = { package = "a2a-slimrpc", git = "https://github.com/a2aproject/a2a-rs.git" }
a2a-websocket = { package = "a2a-websocket", git = "https://github.com/a2aproject/a2a-rs.git" }
```

Typical usage is:
Expand All @@ -147,6 +151,7 @@ Typical usage is:
- `a2a-server` for agent implementations on `axum`
- `a2a-grpc` when you need gRPC transport support
- `a2a-slimrpc` when you need SLIMRPC transport support
- `a2a-websocket` when you need the WebSocket custom protocol binding
- `a2a-pb` when you need direct access to protobuf messages or conversion helpers

## Repository Layout
Expand All @@ -157,6 +162,7 @@ Typical usage is:
- `a2a-pb/`: protobuf schema and conversion layer
- `a2a-grpc/`: tonic-based bindings
- `a2a-slimrpc/`: SLIMRPC bindings
- `a2a-websocket/`: WebSocket custom protocol bindings
- `a2acli/`: standalone A2A client CLI and published binary package
- `examples/helloworld/`: runnable sample agent

Expand Down
2 changes: 1 addition & 1 deletion a2a-pb/proto/a2a.proto
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ message AgentInterface {
string url = 1 [(google.api.field_behavior) = REQUIRED];
// The protocol binding supported at this URL. This is an open form string, to be
// easily extended for other protocol bindings. The core ones officially
// supported are `JSONRPC`, `GRPC` and `HTTP+JSON`.
// supported are `JSONRPC`, `GRPC`, `HTTP+JSON`, `SLIMRPC`, and `WEBSOCKET`.
string protocol_binding = 2 [(google.api.field_behavior) = REQUIRED];
// Tenant ID to be used in the request when calling the agent.
string tenant = 3;
Expand Down
2 changes: 1 addition & 1 deletion a2a-pb/src/gen/lf.a2a.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ pub struct AgentInterface {
pub url: ::prost::alloc::string::String,
/// The protocol binding supported at this URL. This is an open form string, to be
/// easily extended for other protocol bindings. The core ones officially
/// supported are `JSONRPC`, `GRPC` and `HTTP+JSON`.
/// supported are `JSONRPC`, `GRPC`, `HTTP+JSON`, `SLIMRPC`, and `WEBSOCKET`.
#[prost(string, tag = "2")]
pub protocol_binding: ::prost::alloc::string::String,
/// Tenant ID to be used in the request when calling the agent.
Expand Down
28 changes: 28 additions & 0 deletions a2a-websocket/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.1.0] - 2026-05-06

### Added

- Add WebSocket custom protocol binding for A2A v1, including:
- `WebSocketTransport` and `WebSocketTransportFactory` implementing the
`a2a_client::transport::Transport` and `TransportFactory` traits.
- `websocket_router` adapting an `a2a_server::RequestHandler` to an
`axum::Router` that serves the binding over a persistent WebSocket
connection with full bidirectional streaming and multiplexing.
- JSON envelope types (`WsRequestEnvelope`, `WsResponseEnvelope`,
`WsErrorObject`) implementing the wire format defined in the
A2A WebSocket binding specification.
- Mapping helpers between `A2AError` and the canonical WebSocket
error type strings, plus close-code selection for fatal failures.
- Service parameter handling that combines connection-scoped headers
with per-request `serviceParams` (per-request takes precedence).
- Re-export `TRANSPORT_PROTOCOL_WEBSOCKET` from the `a2a` core crate so
application code can register the factory using the shared constant.
Loading
Loading