diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2c8954f..bef8018c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: components: clippy - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 # protoc is bundled via the `protoc-bin-vendored` crate (see the - # `grpc` build scripts in crates/a2a-client and crates/a2a-server), + # `grpc` build scripts in crates/a2a-protocol-client and crates/a2a-protocol-server), # so no system protoc install is needed. Contributors building # `--features grpc` on a clean machine get the same behaviour. - name: Clippy (default features) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b48c004a..cc40e899 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -40,7 +40,7 @@ jobs: - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 # protoc is bundled via the `protoc-bin-vendored` crate (see the - # grpc build scripts in crates/a2a-client and crates/a2a-server). + # grpc build scripts in crates/a2a-protocol-client and crates/a2a-protocol-server). - name: Install cargo-llvm-cov run: cargo install cargo-llvm-cov --locked diff --git a/.github/workflows/mutants.yml b/.github/workflows/mutants.yml index 36a4bcd7..06897851 100644 --- a/.github/workflows/mutants.yml +++ b/.github/workflows/mutants.yml @@ -12,7 +12,7 @@ # minutes when run sequentially. # - A lightweight aggregation job merges per-crate reports and produces the # combined score. -# - Incremental mode (PRs) tests only changed files in a single job. +# - Incremental mode (PRs) mutates only PR-diff changes (--in-diff) in one job. # # CI output is optimised for readability: # - cargo-mutants raw output is captured to a file (not streamed to the log) @@ -25,8 +25,9 @@ name: Mutation Testing on: # PRs run the **incremental** job (`mutants-incremental` below): only the - # Rust source files changed in the PR are mutated, which fits inside the - # per-job timeout without needing a full sweep. The full sweep across + # source lines changed in the PR diff are mutated (cargo-mutants `--in-diff`), + # which fits inside the per-job timeout without needing a full sweep. The + # full sweep across # every crate (`mutants-crate`) is gated on the matrix itself (`if: # github.event_name != 'pull_request'`) so incremental runs on PRs and # the full sweep runs on schedule / workflow_dispatch. @@ -404,43 +405,40 @@ jobs: - name: Install cargo-mutants run: cargo install cargo-mutants - - name: Determine changed files - id: changed + - name: Build PR source diff (rename-aware) + id: diff run: | - FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- 'crates/*/src/**/*.rs') - FILE_COUNT=$(echo "$FILES" | grep -c . 2>/dev/null || echo 0) - - if [ -z "$FILES" ] || [ "$FILE_COUNT" -eq 0 ]; then + BASE="origin/${{ github.base_ref }}" + # `-M` so a pure file/directory rename carries no content hunks. + # Without it, a large rename (e.g. crates/a2a-* -> crates/a2a-protocol-*) + # looks like thousands of brand-new lines and balloons the run to the + # entire mutant set, blowing the timeout. We scope to library source. + git diff -M "${BASE}...HEAD" -- 'crates/*/src/**/*.rs' > pr-src.diff + ADDED=$(grep -cE '^\+[^+]' pr-src.diff || true) + + if [ "${ADDED:-0}" -eq 0 ]; then echo "skip=true" >> "$GITHUB_OUTPUT" - echo "No Rust source files changed in crates/ — mutation testing will be skipped." + echo "No added/changed lines in crates/*/src — nothing to mutate (renames carry no content)." else echo "skip=false" >> "$GITHUB_OUTPUT" - # Convert to comma-separated for later parsing - echo "files=$(echo "$FILES" | tr '\n' ',')" >> "$GITHUB_OUTPUT" - echo "" - echo "Changed files to mutate (${FILE_COUNT}):" - echo "$FILES" | sed 's/^/ /' + echo "Changed source lines to mutate: ${ADDED}" + echo "::group::PR source diff" + cat pr-src.diff + echo "::endgroup::" fi - - name: Run mutation tests on changed files + - name: Run incremental mutation testing id: mutants - if: steps.changed.outputs.skip == 'false' + if: steps.diff.outputs.skip == 'false' run: | echo "::group::cargo-mutants execution log" - IFS=',' read -ra FILE_ARRAY <<< "${{ steps.changed.outputs.files }}" - GLOB_ARGS="" - for f in "${FILE_ARRAY[@]}"; do - if [ -n "$f" ]; then - GLOB_ARGS="$GLOB_ARGS --file $f" - fi - done - set +e - # --timeout matches `cap_timeout` in mutants.toml so trivial - # accessors / Debug impls aren't reported as TIMEOUT on slower - # GitHub runners; see the lint in mutants.toml for context. - cargo mutants $GLOB_ARGS \ + # `--in-diff` restricts mutants to functions whose lines were added or + # changed in this PR's diff, so renames contribute nothing and only + # genuinely edited code is mutated. --timeout matches `cap_timeout` + # in mutants.toml (see the lint there for context). + cargo mutants --in-diff pr-src.diff \ --output mutants.out \ --timeout 300 \ --jobs 4 \ @@ -452,14 +450,14 @@ jobs: echo "exit_code=${MUTANTS_EXIT}" >> "$GITHUB_OUTPUT" - name: No source changes to mutate - if: steps.changed.outputs.skip == 'true' + if: steps.diff.outputs.skip == 'true' run: | echo "# Mutation Testing — Skipped" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" echo "No Rust source files changed in \`crates/*/src/\` — nothing to mutate." >> "$GITHUB_STEP_SUMMARY" - name: Generate mutation report - if: always() && steps.changed.outputs.skip == 'false' + if: always() && steps.diff.outputs.skip == 'false' run: | count() { if [ -f "$1" ]; then grep -c . "$1" 2>/dev/null || echo 0; else echo 0; fi; } @@ -569,7 +567,7 @@ jobs: fi - name: Upload mutation report - if: always() && steps.changed.outputs.skip == 'false' + if: always() && steps.diff.outputs.skip == 'false' uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: mutation-report-incremental diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aa78ccfe..f1b398e0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -85,7 +85,7 @@ jobs: FAILED=0 echo "::group::Version consistency" - for toml in crates/a2a-types/Cargo.toml crates/a2a-client/Cargo.toml crates/a2a-server/Cargo.toml crates/a2a-sdk/Cargo.toml; do + for toml in crates/a2a-protocol-types/Cargo.toml crates/a2a-protocol-client/Cargo.toml crates/a2a-protocol-server/Cargo.toml crates/a2a-protocol-sdk/Cargo.toml; do CARGO_VER=$(grep '^version' "$toml" | head -1 | sed 's/.*"\(.*\)".*/\1/') if [[ "$CARGO_VER" != "$TAG_VER" ]]; then echo "::error file=$toml::$toml version ($CARGO_VER) != tag ($TAG_VER)." diff --git a/CITATION.cff b/CITATION.cff index 7b6d0674..f470e38a 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,7 +2,7 @@ # Copyright 2026 Tom F. (https://github.com/tomtom215) cff-version: 1.2.0 -title: "a2a-rust: A2A Protocol SDK for Rust" +title: "a2a-rust: Agent2Agent (A2A) Protocol SDK for Rust" message: "If you use this software, please cite it using the metadata from this file." type: software authors: @@ -10,12 +10,13 @@ authors: email: "tomf@tomtomtech.net" alias: "tomtom215" repository-code: "https://github.com/tomtom215/a2a-rust" -url: "https://github.com/tomtom215/a2a-rust" +url: "https://a2a-rust.com" license: Apache-2.0 version: "0.5.1" date-released: "2026-04-15" keywords: - a2a + - agent2agent - agent-to-agent - rust - sdk @@ -23,6 +24,6 @@ keywords: - json-rpc - grpc abstract: >- - A complete Rust implementation of the Agent-to-Agent (A2A) protocol v1.0, + A complete Rust implementation of the Agent2Agent (A2A) protocol v1.0, providing types, server framework, and client library for building interoperable AI agent systems. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 16f242b5..72edf3b5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -84,9 +84,9 @@ Before adding a dependency: |---|---|---| | Unit tests | `#[cfg(test)]` modules in source files | `cargo test --workspace` | | Integration tests | `crates/*/tests/` | included in workspace test | -| TCK conformance | `crates/a2a-types/tests/tck_wire_format.rs` | `cargo test -p a2a-protocol-types --test tck_wire_format` | -| Property-based tests | `crates/a2a-types/tests/proptest_types.rs` | `cargo test -p a2a-protocol-types --test proptest_types` | -| Corpus-based JSON tests | `crates/a2a-types/tests/corpus_json.rs` | `cargo test -p a2a-protocol-types --test corpus_json` | +| TCK conformance | `crates/a2a-protocol-types/tests/tck_wire_format.rs` | `cargo test -p a2a-protocol-types --test tck_wire_format` | +| Property-based tests | `crates/a2a-protocol-types/tests/proptest_types.rs` | `cargo test -p a2a-protocol-types --test proptest_types` | +| Corpus-based JSON tests | `crates/a2a-protocol-types/tests/corpus_json.rs` | `cargo test -p a2a-protocol-types --test corpus_json` | | Mutation tests | `mutants.toml` (workspace root) | `cargo mutants --workspace` | | End-to-end examples | `examples/echo-agent`, `examples/agent-team`, `examples/multi-lang-team`, `examples/rig-agent`, `examples/genai-agent` | `cargo run -p echo-agent` | | Benchmarks | `crates/*/benches/` | `cargo bench` | @@ -136,7 +136,7 @@ cargo mutants --workspace cargo mutants -p a2a-protocol-types # Run on a specific file -cargo mutants --file crates/a2a-types/src/task.rs +cargo mutants --file crates/a2a-protocol-types/src/task.rs # List mutants without running (dry-run) cargo mutants --list --workspace @@ -165,7 +165,7 @@ Examples: ### Property-Based Tests (`proptest`) -Located in `crates/a2a-types/tests/proptest_types.rs`. These verify invariants +Located in `crates/a2a-protocol-types/tests/proptest_types.rs`. These verify invariants that must hold for all possible inputs: - **TaskState** — round-trip, terminal classification, wire format prefix @@ -174,7 +174,7 @@ that must hold for all possible inputs: ### Corpus-Based JSON Tests -Located in `crates/a2a-types/tests/corpus_json.rs`. Each test deserializes a +Located in `crates/a2a-protocol-types/tests/corpus_json.rs`. Each test deserializes a representative JSON sample matching the A2A v1.0 wire format and verifies `deserialize → serialize → deserialize` round-trip fidelity. Covers: diff --git a/Cargo.toml b/Cargo.toml index 102d5641..fd12e1a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,10 +4,10 @@ [workspace] resolver = "2" members = [ - "crates/a2a-types", - "crates/a2a-client", - "crates/a2a-server", - "crates/a2a-sdk", + "crates/a2a-protocol-types", + "crates/a2a-protocol-client", + "crates/a2a-protocol-server", + "crates/a2a-protocol-sdk", "examples/echo-agent", "examples/agent-team", "examples/multi-lang-team", @@ -23,9 +23,9 @@ rust-version = "1.93" license = "Apache-2.0" authors = ["Tom F."] repository = "https://github.com/tomtom215/a2a-rust" -homepage = "https://github.com/tomtom215/a2a-rust" +homepage = "https://a2a-rust.com" documentation = "https://docs.rs/a2a-protocol-sdk" -keywords = ["a2a", "agent", "protocol", "sdk", "ai"] +keywords = ["a2a", "agent2agent", "agent", "protocol", "ai"] categories = ["network-programming", "web-programming", "api-bindings"] [workspace.dependencies] diff --git a/README.md b/README.md index b3d648bc..f99c0be7 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,30 @@ -# a2a-rust +

+ + + + a2a-rust — Agent2Agent (A2A) Protocol SDK for Rust + + +

+ +# a2a-rust — Agent2Agent (A2A) Protocol SDK for Rust [![CI](https://github.com/tomtom215/a2a-rust/actions/workflows/ci.yml/badge.svg)](https://github.com/tomtom215/a2a-rust/actions/workflows/ci.yml) [![TCK](https://github.com/tomtom215/a2a-rust/actions/workflows/tck.yml/badge.svg)](https://github.com/tomtom215/a2a-rust/actions/workflows/tck.yml) [![codecov](https://codecov.io/gh/tomtom215/a2a-rust/graph/badge.svg)](https://codecov.io/gh/tomtom215/a2a-rust) [![Crates.io](https://img.shields.io/crates/v/a2a-protocol-sdk.svg)](https://crates.io/crates/a2a-protocol-sdk) [![docs.rs](https://img.shields.io/docsrs/a2a-protocol-sdk)](https://docs.rs/a2a-protocol-sdk) +[![Guide](https://img.shields.io/badge/guide-a2a--rust.com-blue)](https://a2a-rust.com) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![MSRV](https://img.shields.io/badge/rust-1.93%2B-orange.svg)](https://www.rust-lang.org) [![A2A Conformance](https://img.shields.io/badge/A2A%20v1.0-TCK%20conformant-brightgreen)](tck/) -Pure Rust implementation of the [A2A (Agent-to-Agent) protocol](https://google.github.io/A2A/) v1.0.0. +Pure Rust implementation of the [**Agent2Agent (A2A) protocol**](https://a2a-protocol.org/), built to the final **v1.0.0** wire specification — the open, vendor-neutral standard for AI-agent interoperability. -Build, connect, and orchestrate AI agents using a type-safe, async-first SDK with both JSON-RPC 2.0 and REST transport bindings. +Build, connect, and orchestrate AI agents with a type-safe, async-first SDK spanning four transports — JSON-RPC 2.0, REST, WebSocket, and gRPC — for both client and server. ## Motivation @@ -90,10 +100,10 @@ This project aims to be the first **v1.0.0-compliant** Rust SDK for A2A. We inte | Crate | Purpose | When to Use | |---|---|---| -| [`a2a-protocol-types`](crates/a2a-types) | All A2A wire types — `serde` only, no I/O | You need types without the HTTP stack | -| [`a2a-protocol-client`](crates/a2a-client) | HTTP client for A2A requests | Building an orchestrator, gateway, or test harness | -| [`a2a-protocol-server`](crates/a2a-server) | Server framework for A2A agents | Building an agent that handles A2A requests | -| [`a2a-protocol-sdk`](crates/a2a-sdk) | Umbrella re-export + prelude | Quick-start / full-stack usage | +| [`a2a-protocol-types`](crates/a2a-protocol-types) | All A2A wire types — `serde` only, no I/O | You need types without the HTTP stack | +| [`a2a-protocol-client`](crates/a2a-protocol-client) | HTTP client for A2A requests | Building an orchestrator, gateway, or test harness | +| [`a2a-protocol-server`](crates/a2a-protocol-server) | Server framework for A2A agents | Building an agent that handles A2A requests | +| [`a2a-protocol-sdk`](crates/a2a-protocol-sdk) | Umbrella re-export + prelude | Quick-start / full-stack usage | `a2a-protocol-client` and `a2a-protocol-server` are **siblings** — neither depends on the other. Use only what you need. diff --git a/RELEASING.md b/RELEASING.md index 890813dc..86f9b874 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -30,10 +30,10 @@ Publishing must happen in this order (each crate depends on the ones above it): git checkout -b release/vX.Y.Z main # Update version in all 4 crate Cargo.toml files (must all match) -# crates/a2a-types/Cargo.toml -# crates/a2a-client/Cargo.toml -# crates/a2a-server/Cargo.toml -# crates/a2a-sdk/Cargo.toml +# crates/a2a-protocol-types/Cargo.toml +# crates/a2a-protocol-client/Cargo.toml +# crates/a2a-protocol-server/Cargo.toml +# crates/a2a-protocol-sdk/Cargo.toml # Update CHANGELOG.md: move [Unreleased] content to [X.Y.Z] with date # Add new empty [Unreleased] section diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 9fc5fff0..f12e087c 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -13,9 +13,9 @@ authors.workspace = true [dependencies] # SDK crates under test -a2a-protocol-types = { path = "../crates/a2a-types" } -a2a-protocol-client = { path = "../crates/a2a-client" } -a2a-protocol-server = { path = "../crates/a2a-server" } +a2a-protocol-types = { path = "../crates/a2a-protocol-types" } +a2a-protocol-client = { path = "../crates/a2a-protocol-client" } +a2a-protocol-server = { path = "../crates/a2a-protocol-server" } # Benchmark harness criterion = { workspace = true, features = ["html_reports", "async_tokio"] } diff --git a/book/book.toml b/book/book.toml index 095ac245..819375cf 100644 --- a/book/book.toml +++ b/book/book.toml @@ -1,6 +1,6 @@ [book] title = "a2a-rust" -description = "Official Rust SDK for the A2A (Agent-to-Agent) protocol — build interoperable AI agents with type-safe, async Rust" +description = "Rust SDK for the Agent2Agent (A2A) protocol — build interoperable AI agents with type-safe, async Rust" authors = ["Tom F."] language = "en" src = "src" diff --git a/book/src/concepts/protocol-overview.md b/book/src/concepts/protocol-overview.md index de6a20e8..46612b1e 100644 --- a/book/src/concepts/protocol-overview.md +++ b/book/src/concepts/protocol-overview.md @@ -1,6 +1,6 @@ # Protocol Overview -The A2A (Agent-to-Agent) protocol defines how AI agents discover each other, exchange messages, manage task lifecycles, and stream results. This page covers the conceptual model — the "what" before the "how." +The Agent2Agent (A2A) protocol defines how AI agents discover each other, exchange messages, manage task lifecycles, and stream results. This page covers the conceptual model — the "what" before the "how." ## The Big Picture diff --git a/book/src/deployment/dogfooding-bugs.md b/book/src/deployment/dogfooding-bugs.md index 840685a2..d2a33787 100644 --- a/book/src/deployment/dogfooding-bugs.md +++ b/book/src/deployment/dogfooding-bugs.md @@ -567,7 +567,7 @@ Auth interceptor headers were applied to JSON-RPC and REST HTTP requests but not **Fix (initial):** Added `validate_webhook_url_with_dns()` that resolves DNS before IP validation and checks every resolved IP against the private/loopback ranges. -**Fix (hardening, 2026-04-15):** The initial fix validated a set of IPs but still allowed the HTTP client to re-resolve the hostname on connect, leaving a narrow TOCTOU window. `validate_webhook_url_with_dns()` now returns the specific `SocketAddr` it validated, and `HttpPushSender::send()` rewrites the outgoing URI so the request connects directly to the literal pinned IP (`http://:/…`) with the original hostname preserved via an explicit `Host:` header. This closes the window: the HTTP client sees an IP literal and never re-enters DNS resolution, so a rebinding attacker cannot flip the record between validation and connect. See `crates/a2a-server/src/push/sender.rs:rewrite_uri_with_pinned_addr` and the `rewrite_uri_*` / `host_header_*` tests. +**Fix (hardening, 2026-04-15):** The initial fix validated a set of IPs but still allowed the HTTP client to re-resolve the hostname on connect, leaving a narrow TOCTOU window. `validate_webhook_url_with_dns()` now returns the specific `SocketAddr` it validated, and `HttpPushSender::send()` rewrites the outgoing URI so the request connects directly to the literal pinned IP (`http://:/…`) with the original hostname preserved via an explicit `Host:` header. This closes the window: the HTTP client sees an IP literal and never re-enters DNS resolution, so a rebinding attacker cannot flip the record between validation and connect. See `crates/a2a-protocol-server/src/push/sender.rs:rewrite_uri_with_pinned_addr` and the `rewrite_uri_*` / `host_header_*` tests. ### Bug H7: Retry Transport Deep-Clones serde_json::Value Per Attempt diff --git a/book/src/deployment/dogfooding-tests.md b/book/src/deployment/dogfooding-tests.md index f3daa93d..60f6f968 100644 --- a/book/src/deployment/dogfooding-tests.md +++ b/book/src/deployment/dogfooding-tests.md @@ -207,9 +207,9 @@ In addition to the 81 agent-team E2E tests (94 with optional features), the SDK | Suite | Location | Tests | What it covers | |---|---|---|---| -| **TLS/mTLS** | `crates/a2a-client/tests/tls_integration_tests.rs` | 7 | Client cert validation, SNI hostname verification, unknown CA rejection, mutual TLS | -| **WebSocket server** | `crates/a2a-server/tests/websocket_tests.rs` | 7 | Send/stream, error handling, ping/pong, connection reuse, close frames | -| **Memory & load stress** | `crates/a2a-server/tests/stress_tests.rs` | 5 | 200 concurrent requests, sustained load (500 requests/10 waves), eviction under load, multi-tenant isolation (10×50), rapid connect/disconnect | +| **TLS/mTLS** | `crates/a2a-protocol-client/tests/tls_integration_tests.rs` | 7 | Client cert validation, SNI hostname verification, unknown CA rejection, mutual TLS | +| **WebSocket server** | `crates/a2a-protocol-server/tests/websocket_tests.rs` | 7 | Send/stream, error handling, ping/pong, connection reuse, close frames | +| **Memory & load stress** | `crates/a2a-protocol-server/tests/stress_tests.rs` | 5 | 200 concurrent requests, sustained load (500 requests/10 waves), eviction under load, multi-tenant isolation (10×50), rapid connect/disconnect | ## Features NOT Covered by E2E Tests diff --git a/book/src/deployment/dogfooding.md b/book/src/deployment/dogfooding.md index 9caec1d3..854e17c6 100644 --- a/book/src/deployment/dogfooding.md +++ b/book/src/deployment/dogfooding.md @@ -199,12 +199,12 @@ All architecture, ergonomics, observability, performance, and durability issues | Feature | Location | |---|---| -| **OpenTelemetry integration** | `crates/a2a-server/src/otel/` — `OtelMetrics`, `OtelMetricsBuilder`, `init_otlp_pipeline` (`otel` feature) | -| **Connection pooling metrics** | `crates/a2a-server/src/metrics.rs` — `ConnectionPoolStats`, `on_connection_pool_stats` | -| **Hot-reload agent cards** | `crates/a2a-server/src/agent_card/hot_reload.rs` — file polling + SIGHUP reload | -| **Store migration tooling** | `crates/a2a-server/src/store/migration.rs` — `MigrationRunner`, V1–V3 migrations | -| **Per-tenant configuration** | `crates/a2a-server/src/tenant_config.rs` — `PerTenantConfig`, `TenantLimits` | -| **TenantResolver trait** | `crates/a2a-server/src/tenant_resolver.rs` — header, bearer token, path segment strategies | +| **OpenTelemetry integration** | `crates/a2a-protocol-server/src/otel/` — `OtelMetrics`, `OtelMetricsBuilder`, `init_otlp_pipeline` (`otel` feature) | +| **Connection pooling metrics** | `crates/a2a-protocol-server/src/metrics.rs` — `ConnectionPoolStats`, `on_connection_pool_stats` | +| **Hot-reload agent cards** | `crates/a2a-protocol-server/src/agent_card/hot_reload.rs` — file polling + SIGHUP reload | +| **Store migration tooling** | `crates/a2a-protocol-server/src/store/migration.rs` — `MigrationRunner`, V1–V3 migrations | +| **Per-tenant configuration** | `crates/a2a-protocol-server/src/tenant_config.rs` — `PerTenantConfig`, `TenantLimits` | +| **TenantResolver trait** | `crates/a2a-protocol-server/src/tenant_resolver.rs` — header, bearer token, path segment strategies | | **Agent card signing E2E** | `examples/agent-team/src/tests/coverage_gaps/feature_gated.rs` — test 79 (`signing` feature) | ## Sub-pages diff --git a/book/src/deployment/testing.md b/book/src/deployment/testing.md index 0d667522..47c78cd0 100644 --- a/book/src/deployment/testing.md +++ b/book/src/deployment/testing.md @@ -308,7 +308,7 @@ cargo mutants --workspace cargo mutants -p a2a-protocol-types # Test a specific file -cargo mutants --file crates/a2a-types/src/task.rs +cargo mutants --file crates/a2a-protocol-types/src/task.rs # Dry-run: list all mutants without running tests cargo mutants --list --workspace @@ -321,16 +321,16 @@ Mutation testing is configured via `mutants.toml` at the workspace root: ```toml # Which files to mutate examine_globs = [ - "crates/a2a-types/src/**/*.rs", - "crates/a2a-client/src/**/*.rs", - "crates/a2a-server/src/**/*.rs", - "crates/a2a-sdk/src/**/*.rs", + "crates/a2a-protocol-types/src/**/*.rs", + "crates/a2a-protocol-client/src/**/*.rs", + "crates/a2a-protocol-server/src/**/*.rs", + "crates/a2a-protocol-sdk/src/**/*.rs", ] # Skip unproductive mutations (re-exports, generated code) # Note: Display/Debug impls are NOT excluded — we have tests for them. exclude_globs = [ - "crates/a2a-sdk/src/lib.rs", # pure re-exports + "crates/a2a-protocol-sdk/src/lib.rs", # pure re-exports "**/mod.rs", # thin mod files (re-exports only) "crates/*/src/proto/**", # generated protobuf code ] @@ -368,7 +368,7 @@ When a mutant survives, `cargo mutants` prints the exact source location and mutation. For example: ``` -MISSED: crates/a2a-types/src/task.rs:42: replace TaskState::is_terminal -> bool with false +MISSED: crates/a2a-protocol-types/src/task.rs:42: replace TaskState::is_terminal -> bool with false ``` This tells you that replacing the body of `is_terminal()` with `false` did not diff --git a/book/src/getting-started/project-structure.md b/book/src/getting-started/project-structure.md index 0016a8fd..30ff0a2d 100644 --- a/book/src/getting-started/project-structure.md +++ b/book/src/getting-started/project-structure.md @@ -8,7 +8,7 @@ a2a-rust is organized as a Cargo workspace with four crates, each with a clear r a2a-rust/ ├── Cargo.toml # Workspace root ├── crates/ -│ ├── a2a-types/ # Wire types (serde, no I/O) — publishes as a2a-protocol-types +│ ├── a2a-protocol-types/ # Wire types (serde, no I/O) │ │ └── src/ │ │ ├── lib.rs │ │ ├── task.rs # Task, TaskState, TaskStatus, TaskId @@ -25,7 +25,7 @@ a2a-rust/ │ │ ├── signing.rs # Agent card signing (JWS/ES256) │ │ └── extensions.rs # Extension types │ │ -│ ├── a2a-client/ # HTTP client — publishes as a2a-protocol-client +│ ├── a2a-protocol-client/ # HTTP client │ │ └── src/ │ │ ├── lib.rs # A2aClient, ClientBuilder │ │ ├── builder/ # ClientBuilder (fluent config) @@ -62,7 +62,7 @@ a2a-rust/ │ │ ├── discovery.rs # Agent card discovery │ │ └── tls.rs # TLS configuration helpers │ │ -│ ├── a2a-server/ # Server framework — publishes as a2a-protocol-server +│ ├── a2a-protocol-server/ # Server framework │ │ └── src/ │ │ ├── lib.rs # Public re-exports │ │ ├── handler/ # RequestHandler (core orchestration) @@ -160,7 +160,7 @@ a2a-rust/ │ │ ├── tenant_config.rs # PerTenantConfig, TenantLimits │ │ └── tenant_resolver.rs # TenantResolver trait + impls │ │ -│ └── a2a-sdk/ # Umbrella crate — publishes as a2a-protocol-sdk +│ └── a2a-protocol-sdk/ # Umbrella crate │ └── src/ │ └── lib.rs # Re-exports + prelude │ diff --git a/book/src/introduction.md b/book/src/introduction.md index 70479be3..1b46b38c 100644 --- a/book/src/introduction.md +++ b/book/src/introduction.md @@ -1,12 +1,19 @@ +

+ + + a2a-rust — Agent2Agent (A2A) Protocol SDK for Rust + +

+ # Introduction -**a2a-rust** is a pure Rust implementation of the [A2A (Agent-to-Agent) protocol v1.0.0](https://google.github.io/A2A/) — an open standard for connecting AI agents over the network. +**a2a-rust** is a pure Rust implementation of the [Agent2Agent (A2A) protocol v1.0.0](https://a2a-protocol.org/) — an open standard for connecting AI agents over the network. If you're building AI agents that need to talk to each other, discover capabilities, delegate tasks, and stream results — this library gives you the full protocol stack with zero `unsafe` code, compile-time type safety, and production-grade hardening. ## What is the A2A Protocol? -The Agent-to-Agent protocol defines how AI agents discover, communicate with, and delegate work to each other. Think of it as HTTP for AI agents: a shared language that lets any agent talk to any other, regardless of implementation. +The Agent2Agent protocol defines how AI agents discover, communicate with, and delegate work to each other. Think of it as HTTP for AI agents: a shared language that lets any agent talk to any other, regardless of implementation. The protocol defines: diff --git a/book/src/reference/adrs.md b/book/src/reference/adrs.md index a16db865..e5e94088 100644 --- a/book/src/reference/adrs.md +++ b/book/src/reference/adrs.md @@ -94,7 +94,7 @@ The `Transport` trait (client) and `Dispatcher` trait (server) make transports p **Context:** The SDK lacked formal wire format conformance tests and required raw hyper for HTTP serving. Other SDKs integrate with their ecosystem's dominant web framework. **Decision:** Two additions: -1. **TCK conformance tests** — 44 golden-fixture tests in `crates/a2a-types/tests/tck_wire_format.rs` validating ProtoJSON serialization, SecurityRequirement/StringList format, Part discriminators, cross-SDK interop fixtures, and full round-trip. +1. **TCK conformance tests** — 44 golden-fixture tests in `crates/a2a-protocol-types/tests/tck_wire_format.rs` validating ProtoJSON serialization, SecurityRequirement/StringList format, Part discriminators, cross-SDK interop fixtures, and full round-trip. 2. **Axum integration** — Feature-gated `A2aRouter` (`axum` feature) wrapping `RequestHandler` as an idiomatic `axum::Router`. Zero business logic duplication. **Rationale:** TCK tests catch interop regressions before release. Axum integration reduces server setup from ~25 lines to 3 while remaining optional (the raw hyper `serve()` API is unchanged). diff --git a/book/static/apple-touch-icon.png b/book/static/apple-touch-icon.png new file mode 100644 index 00000000..dd3506c2 Binary files /dev/null and b/book/static/apple-touch-icon.png differ diff --git a/book/static/brand/README.md b/book/static/brand/README.md new file mode 100644 index 00000000..841327ae --- /dev/null +++ b/book/static/brand/README.md @@ -0,0 +1,51 @@ + + +# a2a-rust brand kit + +Visual identity for **a2a-rust**. These assets are versioned here and published at +`https://a2a-rust.com/brand/`. + +## Palette + +| Role | Hex | +|------|-----| +| Amber (dark bg) | `#F0A93B` | +| Amber (light bg) | `#D97706` | +| Ink (tile / dark card) | `#19150F` | +| Cream | `#F4EEE0` | + +## Type + +- **Display / wordmark:** Space Grotesk (Bold) +- **Code / mono / URLs:** JetBrains Mono + +The amber **2** in `a2a-rust` (agent-**2**-agent) is the brand's hero device. + +## Social / link-preview cards — 1200×630 + +| File | Use | +|------|-----| +| `og-card-editorial-dark.png` | **Primary.** Wired as the site's `og-image.png`; README hero in dark mode. | +| `og-card-editorial-light.png` | Light variant; README hero in light mode. | +| `og-card-code.png` | Code-snippet card for social posts / docs. | + +## Icon & favicon + +| File | Use | +|------|-----| +| `avatar.png` (1024) | Profile / logo mark — upload as the GitHub org/repo avatar. | +| `favicon.svg` | Vector favicon (text outlined to paths — no font dependency). | +| `favicon.ico` | 16/32/48 multi-size. | +| `favicon-16.png`, `favicon-32.png` | Raster favicons. | +| `apple-touch-icon.png` (180, opaque) | iOS home-screen icon. | +| `icon-192.png`, `icon-512.png` | PWA / Android. | + +## Sources + +`sources/` holds the files the assets render from: + +- `editorial.html` — light/dark card (append `#light` or `#dark`); render with headless Chrome. +- `code-card.html` — code card; render with headless Chrome. +- `avatar.svg` — avatar with live text; `avatar-outlined.svg` is the same with text converted to paths (the favicon master). + +Reproducing requires the **Space Grotesk** and **JetBrains Mono** fonts installed. diff --git a/book/static/brand/apple-touch-icon.png b/book/static/brand/apple-touch-icon.png new file mode 100644 index 00000000..dd3506c2 Binary files /dev/null and b/book/static/brand/apple-touch-icon.png differ diff --git a/book/static/brand/avatar.png b/book/static/brand/avatar.png new file mode 100644 index 00000000..75978637 Binary files /dev/null and b/book/static/brand/avatar.png differ diff --git a/book/static/brand/favicon-16.png b/book/static/brand/favicon-16.png new file mode 100644 index 00000000..5632ec35 Binary files /dev/null and b/book/static/brand/favicon-16.png differ diff --git a/book/static/brand/favicon-32.png b/book/static/brand/favicon-32.png new file mode 100644 index 00000000..f75be76e Binary files /dev/null and b/book/static/brand/favicon-32.png differ diff --git a/book/static/brand/favicon.ico b/book/static/brand/favicon.ico new file mode 100644 index 00000000..8a82c5fb Binary files /dev/null and b/book/static/brand/favicon.ico differ diff --git a/book/static/brand/favicon.svg b/book/static/brand/favicon.svg new file mode 100644 index 00000000..ca6f079a --- /dev/null +++ b/book/static/brand/favicon.svg @@ -0,0 +1,35 @@ + + + + + + + + + + diff --git a/book/static/brand/icon-192.png b/book/static/brand/icon-192.png new file mode 100644 index 00000000..2e038bd4 Binary files /dev/null and b/book/static/brand/icon-192.png differ diff --git a/book/static/brand/icon-512.png b/book/static/brand/icon-512.png new file mode 100644 index 00000000..1c9c3ff5 Binary files /dev/null and b/book/static/brand/icon-512.png differ diff --git a/book/static/brand/og-card-code.png b/book/static/brand/og-card-code.png new file mode 100644 index 00000000..5375d721 Binary files /dev/null and b/book/static/brand/og-card-code.png differ diff --git a/book/static/brand/og-card-editorial-dark.png b/book/static/brand/og-card-editorial-dark.png new file mode 100644 index 00000000..7c50ceff Binary files /dev/null and b/book/static/brand/og-card-editorial-dark.png differ diff --git a/book/static/brand/og-card-editorial-light.png b/book/static/brand/og-card-editorial-light.png new file mode 100644 index 00000000..0a1be9dd Binary files /dev/null and b/book/static/brand/og-card-editorial-light.png differ diff --git a/book/static/brand/sources/avatar-outlined.svg b/book/static/brand/sources/avatar-outlined.svg new file mode 100644 index 00000000..ca6f079a --- /dev/null +++ b/book/static/brand/sources/avatar-outlined.svg @@ -0,0 +1,35 @@ + + + + + + + + + + diff --git a/book/static/brand/sources/avatar.svg b/book/static/brand/sources/avatar.svg new file mode 100644 index 00000000..4d61e5cd --- /dev/null +++ b/book/static/brand/sources/avatar.svg @@ -0,0 +1,4 @@ + + + a2a + diff --git a/book/static/brand/sources/code-card.html b/book/static/brand/sources/code-card.html new file mode 100644 index 00000000..43dabb65 --- /dev/null +++ b/book/static/brand/sources/code-card.html @@ -0,0 +1,44 @@ + +
+
a2a-rust
+
Agent2Agent (A2A) Protocol SDK for Rust
+
+
+
+ + + + agent.rs +
+
use a2a_protocol_sdk::prelude::*;
+
+agent_executor!(MyAgent, |ctx, q| async {
+    let emit = EventEmitter::new(ctx, q);
+    emit.status(TaskState::Working).await?;
+    emit.artifact("hello", parts).await?;
+    emit.status(TaskState::Completed).await?;
+    Ok(())
+});
+
+
+
a2a-rust.com · v1.0.0
+
+ diff --git a/book/static/brand/sources/editorial.html b/book/static/brand/sources/editorial.html new file mode 100644 index 00000000..e0f3ec82 --- /dev/null +++ b/book/static/brand/sources/editorial.html @@ -0,0 +1,22 @@ + +
+
AGENT2AGENT (A2A) PROTOCOL
+
a2a-rust
+
Type-safe, async SDK — built to the final v1.0.0 spec
+
a2a-rust.comJSON-RPC · REST · WebSocket · gRPC
+ + diff --git a/book/static/fonts/JetBrainsMono-Bold.woff2 b/book/static/fonts/JetBrainsMono-Bold.woff2 new file mode 100644 index 00000000..349ef3a9 Binary files /dev/null and b/book/static/fonts/JetBrainsMono-Bold.woff2 differ diff --git a/book/static/fonts/JetBrainsMono.woff2 b/book/static/fonts/JetBrainsMono.woff2 new file mode 100644 index 00000000..dc74b334 Binary files /dev/null and b/book/static/fonts/JetBrainsMono.woff2 differ diff --git a/book/static/fonts/SpaceGrotesk.woff2 b/book/static/fonts/SpaceGrotesk.woff2 new file mode 100644 index 00000000..cd478904 Binary files /dev/null and b/book/static/fonts/SpaceGrotesk.woff2 differ diff --git a/book/static/og-image.png b/book/static/og-image.png new file mode 100644 index 00000000..7c50ceff Binary files /dev/null and b/book/static/og-image.png differ diff --git a/book/static/robots.txt b/book/static/robots.txt index c52b5b71..ab60d980 100644 --- a/book/static/robots.txt +++ b/book/static/robots.txt @@ -1,4 +1,4 @@ -# a2a-rust — Official Rust SDK for the A2A (Agent-to-Agent) protocol +# a2a-rust — Rust SDK for the Agent2Agent (A2A) protocol # # Indexing policy: fully open to well-behaved web crawlers, with a small # crawl-delay for low-effort bots to avoid hammering the GitHub Pages diff --git a/book/theme/custom.css b/book/theme/custom.css index e7037bfb..610d7883 100644 --- a/book/theme/custom.css +++ b/book/theme/custom.css @@ -1,15 +1,52 @@ -/* a2a-rust documentation theme */ +/* a2a-rust documentation theme — brand identity (Space Grotesk + JetBrains Mono, amber) */ -/* ── Brand colors ─────────────────────────────────────────────────────────── */ +/* ── Brand web fonts (vendored locally; the site avoids third-party CDNs) ──── */ +@font-face { + font-family: 'Space Grotesk'; + src: url('fonts/SpaceGrotesk.woff2') format('woff2'); + font-weight: 300 700; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'JetBrains Mono'; + src: url('fonts/JetBrainsMono.woff2') format('woff2'); + font-weight: 400; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'JetBrains Mono'; + src: url('fonts/JetBrainsMono-Bold.woff2') format('woff2'); + font-weight: 700; + font-style: normal; + font-display: swap; +} + +/* ── Brand palette ────────────────────────────────────────────────────────── */ :root { - --a2a-primary: #2563eb; - --a2a-primary-dark: #1d4ed8; - --a2a-accent: #059669; - --a2a-bg-code: #f8fafc; - --a2a-border: #e2e8f0; + --a2a-amber: #D97706; /* decorative accent: rules, borders */ + --a2a-link: #B45309; /* AA-contrast link on light backgrounds */ + --a2a-link-hover: #8a3f08; + --a2a-border: #e7e2d9; + --a2a-soft: #faf7f1; +} + +/* Dark themes: brighter amber, translucent neutrals. */ +.coal, .navy, .ayu { + --a2a-amber: #F0A93B; + --a2a-link: #F0A93B; + --a2a-link-hover: #fbbf5a; + --a2a-border: rgba(255, 255, 255, 0.12); + --a2a-soft: rgba(255, 255, 255, 0.045); } +/* Re-point mdBook's own accent variables at the brand amber + (content links + active sidebar entry), per theme. */ +.light, .rust { --links: #B45309; --sidebar-active: #B45309; } +.coal, .navy, .ayu { --links: #F0A93B; --sidebar-active: #F0A93B; } + /* ── Typography ───────────────────────────────────────────────────────────── */ .content main { @@ -18,8 +55,19 @@ line-height: 1.8; } +.content main h1, +.content main h2, +.content main h3, +.content main h4, +.menu-title { + font-family: 'Space Grotesk', system-ui, -apple-system, "Segoe UI", sans-serif; + letter-spacing: -0.02em; +} + +.menu-title { font-weight: 700; } + .content main h1 { - border-bottom: 2px solid var(--a2a-primary); + border-bottom: 3px solid var(--a2a-amber); padding-bottom: 0.3em; margin-bottom: 1em; } @@ -30,21 +78,21 @@ padding-bottom: 0.2em; } -/* ── Code blocks ──────────────────────────────────────────────────────────── */ +/* ── Code (JetBrains Mono) ────────────────────────────────────────────────── */ + +code, kbd, pre, pre code { + font-family: 'JetBrains Mono', ui-monospace, "Source Code Pro", monospace; +} .content main pre { border: 1px solid var(--a2a-border); - border-radius: 6px; + border-radius: 8px; padding: 1em; } -.content main code { - font-size: 0.92em; -} - -.content main pre > code { - font-size: 0.92em; -} +.content main code { font-size: 0.9em; } +.content main pre > code { font-size: 0.9em; } +.content main pre code:not([class*="language-"]) { color: var(--fg); } /* ── Tables ───────────────────────────────────────────────────────────────── */ @@ -55,7 +103,7 @@ } .content main table th { - background-color: var(--a2a-bg-code); + background-color: var(--a2a-soft); border: 1px solid var(--a2a-border); padding: 0.5em 0.75em; text-align: left; @@ -68,87 +116,27 @@ } .content main table tr:nth-child(even) { - background-color: var(--a2a-bg-code); + background-color: var(--a2a-soft); } /* ── Links ────────────────────────────────────────────────────────────────── */ -.content main a { - color: var(--a2a-primary); - text-decoration: none; -} - -.content main a:hover { - color: var(--a2a-primary-dark); - text-decoration: underline; -} +.content main a { color: var(--a2a-link); text-decoration: none; } +.content main a:hover { color: var(--a2a-link-hover); text-decoration: underline; } /* ── Sidebar ──────────────────────────────────────────────────────────────── */ -.sidebar .sidebar-scrollbox { - padding-top: 1em; - font-size: 1.0625rem; -} - -.sidebar .chapter li.chapter-item { - margin-top: 0.35em; - line-height: 1.6; -} +.sidebar .sidebar-scrollbox { padding-top: 1em; font-size: 1.0625rem; } +.sidebar .chapter li.chapter-item { margin-top: 0.35em; line-height: 1.6; } -/* ── Blockquotes (tips/notes) ─────────────────────────────────────────────── */ +/* ── Blockquotes (tips / notes) ───────────────────────────────────────────── */ .content main blockquote { - border-left: 4px solid var(--a2a-primary); - background-color: var(--a2a-bg-code); + border-left: 4px solid var(--a2a-amber); + background-color: var(--a2a-soft); padding: 0.75em 1em; margin: 1em 0; - border-radius: 0 6px 6px 0; -} - -.content main blockquote p { - margin: 0; -} - -/* ── ASCII diagrams ──────────────────────────────────────────────────────── */ - -.content main pre code:not([class*="language-"]) { - color: var(--fg); -} - -/* ── Dark theme adjustments ───────────────────────────────────────────────── */ - -.ayu .content main table th, -.navy .content main table th, -.coal .content main table th { - background-color: rgba(255, 255, 255, 0.05); + border-radius: 0 8px 8px 0; } -.ayu .content main table td, -.navy .content main table td, -.coal .content main table td { - border-color: rgba(255, 255, 255, 0.1); -} - -.ayu .content main table th, -.navy .content main table th, -.coal .content main table th { - border-color: rgba(255, 255, 255, 0.1); -} - -.ayu .content main table tr:nth-child(even), -.navy .content main table tr:nth-child(even), -.coal .content main table tr:nth-child(even) { - background-color: rgba(255, 255, 255, 0.03); -} - -.ayu .content main blockquote, -.navy .content main blockquote, -.coal .content main blockquote { - background-color: rgba(255, 255, 255, 0.05); -} - -.ayu .content main pre, -.navy .content main pre, -.coal .content main pre { - border-color: rgba(255, 255, 255, 0.1); -} +.content main blockquote p { margin: 0; } diff --git a/book/theme/favicon.png b/book/theme/favicon.png new file mode 100644 index 00000000..f75be76e Binary files /dev/null and b/book/theme/favicon.png differ diff --git a/book/theme/favicon.svg b/book/theme/favicon.svg new file mode 100644 index 00000000..ca6f079a --- /dev/null +++ b/book/theme/favicon.svg @@ -0,0 +1,35 @@ + + + + + + + + + + diff --git a/book/theme/head.hbs b/book/theme/head.hbs index 2eb677cc..d31a16a4 100644 --- a/book/theme/head.hbs +++ b/book/theme/head.hbs @@ -23,31 +23,34 @@ cards in SERPs. --> - - + + + + + - - + + - + - - + + - + @@ -84,7 +87,7 @@ "@type": "SoftwareSourceCode", "name": "a2a-rust", "alternateName": "a2a-protocol-sdk", - "description": "Pure Rust implementation of the A2A (Agent-to-Agent) protocol v1.0, providing types, server framework, and client library for building interoperable AI agent systems.", + "description": "Pure Rust implementation of the Agent2Agent (A2A) protocol v1.0, providing types, server framework, and client library for building interoperable AI agent systems.", "url": "https://a2a-rust.com/", "codeRepository": "https://github.com/tomtom215/a2a-rust", "programmingLanguage": { @@ -101,6 +104,7 @@ "url": "https://github.com/tomtom215" }, "keywords": [ + "agent2agent", "agent-to-agent", "a2a-protocol", "rust", diff --git a/codecov.yml b/codecov.yml index 80e4704d..61d59d8c 100644 --- a/codecov.yml +++ b/codecov.yml @@ -16,11 +16,11 @@ ignore: # TCK is test infrastructure, not library code. - "tck/**" # Postgres stores require a running database; tested via integration tests. - - "crates/a2a-server/src/store/postgres_store.rs" - - "crates/a2a-server/src/store/tenant_postgres_store.rs" - - "crates/a2a-server/src/store/pg_migration.rs" - - "crates/a2a-server/src/push/postgres_config_store.rs" - - "crates/a2a-server/src/push/tenant_postgres_config_store.rs" + - "crates/a2a-protocol-server/src/store/postgres_store.rs" + - "crates/a2a-protocol-server/src/store/tenant_postgres_store.rs" + - "crates/a2a-protocol-server/src/store/pg_migration.rs" + - "crates/a2a-protocol-server/src/push/postgres_config_store.rs" + - "crates/a2a-protocol-server/src/push/tenant_postgres_config_store.rs" # Examples are not library code. - "examples/**" # ITK (interop test kit) agents are not library code. diff --git a/crates/README.md b/crates/README.md index 047164b6..46d31d1c 100644 --- a/crates/README.md +++ b/crates/README.md @@ -22,10 +22,10 @@ a2a-protocol-sdk ← umbrella re-export + prelude | Crate | Published Name | Purpose | When to Use | |-------|---------------|---------|-------------| -| [a2a-types](a2a-types/) | `a2a-protocol-types` | Pure A2A v1.0 data types -- serde only, no I/O. Includes `serde_helpers` module with `SerBuffer` (thread-local buffer reuse) and `deser_from_str`/`deser_from_slice` (borrowed deserialization) for optimized serialization paths. | You need typed protocol definitions without HTTP dependencies | -| [a2a-client](a2a-client/) | `a2a-protocol-client` | Async HTTP client (hyper 1.x) with pluggable transports | Building orchestrators, gateways, or test harnesses | -| [a2a-server](a2a-server/) | `a2a-protocol-server` | Server framework with dispatchers, stores, and streaming | Building A2A-compliant agents | -| [a2a-sdk](a2a-sdk/) | `a2a-protocol-sdk` | Umbrella re-export + `prelude` module | Full applications that need client + server + types | +| [a2a-protocol-types](a2a-protocol-types/) | `a2a-protocol-types` | Pure A2A v1.0 data types -- serde only, no I/O. Includes `serde_helpers` module with `SerBuffer` (thread-local buffer reuse) and `deser_from_str`/`deser_from_slice` (borrowed deserialization) for optimized serialization paths. | You need typed protocol definitions without HTTP dependencies | +| [a2a-protocol-client](a2a-protocol-client/) | `a2a-protocol-client` | Async HTTP client (hyper 1.x) with pluggable transports | Building orchestrators, gateways, or test harnesses | +| [a2a-protocol-server](a2a-protocol-server/) | `a2a-protocol-server` | Server framework with dispatchers, stores, and streaming | Building A2A-compliant agents | +| [a2a-protocol-sdk](a2a-protocol-sdk/) | `a2a-protocol-sdk` | Umbrella re-export + `prelude` module | Full applications that need client + server + types | ## Quick Start diff --git a/crates/a2a-client/Cargo.toml b/crates/a2a-protocol-client/Cargo.toml similarity index 88% rename from crates/a2a-client/Cargo.toml rename to crates/a2a-protocol-client/Cargo.toml index 0110c3f2..94682947 100644 --- a/crates/a2a-client/Cargo.toml +++ b/crates/a2a-protocol-client/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "a2a-protocol-client" version = "0.5.1" -description = "A2A protocol v1.0 — HTTP client (hyper-backed)" +description = "Agent2Agent (A2A) protocol v1.0 — HTTP client (hyper-backed)" readme = "README.md" edition.workspace = true @@ -14,7 +14,7 @@ authors.workspace = true repository.workspace = true homepage.workspace = true documentation = "https://docs.rs/a2a-protocol-client" -keywords = ["a2a", "agent", "client", "http"] +keywords = ["a2a", "agent2agent", "agent", "protocol", "client"] categories = ["network-programming", "web-programming"] [features] @@ -30,7 +30,7 @@ websocket = ["dep:tokio-tungstenite", "dep:futures-util"] grpc = ["dep:tonic", "dep:tonic-prost", "dep:prost", "dep:tokio-stream", "dep:tonic-prost-build", "dep:protoc-bin-vendored"] [dependencies] -a2a-protocol-types = { version = "0.5.1", path = "../a2a-types" } +a2a-protocol-types = { version = "0.5.1", path = "../a2a-protocol-types" } serde_json = { workspace = true } hyper = { workspace = true } http-body-util = { workspace = true } @@ -68,8 +68,8 @@ rustls-pki-types = { version = ">=1.7, <2" } hyper = { workspace = true } http-body-util = { workspace = true } hyper-util = { workspace = true, features = ["server", "server-auto"] } -a2a-protocol-types = { version = "0.5.1", path = "../a2a-types" } -a2a-protocol-server = { version = "0.5.1", path = "../a2a-server", features = ["websocket"] } +a2a-protocol-types = { version = "0.5.1", path = "../a2a-protocol-types" } +a2a-protocol-server = { version = "0.5.1", path = "../a2a-protocol-server", features = ["websocket"] } futures-util = { version = ">=0.3.30, <0.4", default-features = false, features = ["sink"] } [[bench]] diff --git a/crates/a2a-client/README.md b/crates/a2a-protocol-client/README.md similarity index 100% rename from crates/a2a-client/README.md rename to crates/a2a-protocol-client/README.md diff --git a/crates/a2a-client/benches/sse_parse.rs b/crates/a2a-protocol-client/benches/sse_parse.rs similarity index 100% rename from crates/a2a-client/benches/sse_parse.rs rename to crates/a2a-protocol-client/benches/sse_parse.rs diff --git a/crates/a2a-client/build.rs b/crates/a2a-protocol-client/build.rs similarity index 95% rename from crates/a2a-client/build.rs rename to crates/a2a-protocol-client/build.rs index 31b26715..6de4330e 100644 --- a/crates/a2a-client/build.rs +++ b/crates/a2a-protocol-client/build.rs @@ -15,7 +15,7 @@ fn main() { // Point `prost-build` (the transitive dep of `tonic-prost-build`) at // the protoc binary vendored by `protoc-bin-vendored`, unless the user // has set `PROTOC` themselves. See the matching comment in - // crates/a2a-server/build.rs for the rationale. + // crates/a2a-protocol-server/build.rs for the rationale. if std::env::var_os("PROTOC").is_none() { if let Ok(path) = protoc_bin_vendored::protoc_bin_path() { std::env::set_var("PROTOC", path); diff --git a/crates/a2a-client/proto/a2a.proto b/crates/a2a-protocol-client/proto/a2a.proto similarity index 100% rename from crates/a2a-client/proto/a2a.proto rename to crates/a2a-protocol-client/proto/a2a.proto diff --git a/crates/a2a-client/src/auth.rs b/crates/a2a-protocol-client/src/auth.rs similarity index 100% rename from crates/a2a-client/src/auth.rs rename to crates/a2a-protocol-client/src/auth.rs diff --git a/crates/a2a-client/src/builder/mod.rs b/crates/a2a-protocol-client/src/builder/mod.rs similarity index 100% rename from crates/a2a-client/src/builder/mod.rs rename to crates/a2a-protocol-client/src/builder/mod.rs diff --git a/crates/a2a-client/src/builder/transport_factory.rs b/crates/a2a-protocol-client/src/builder/transport_factory.rs similarity index 100% rename from crates/a2a-client/src/builder/transport_factory.rs rename to crates/a2a-protocol-client/src/builder/transport_factory.rs diff --git a/crates/a2a-client/src/client.rs b/crates/a2a-protocol-client/src/client.rs similarity index 100% rename from crates/a2a-client/src/client.rs rename to crates/a2a-protocol-client/src/client.rs diff --git a/crates/a2a-client/src/config.rs b/crates/a2a-protocol-client/src/config.rs similarity index 100% rename from crates/a2a-client/src/config.rs rename to crates/a2a-protocol-client/src/config.rs diff --git a/crates/a2a-client/src/discovery.rs b/crates/a2a-protocol-client/src/discovery.rs similarity index 100% rename from crates/a2a-client/src/discovery.rs rename to crates/a2a-protocol-client/src/discovery.rs diff --git a/crates/a2a-client/src/error.rs b/crates/a2a-protocol-client/src/error.rs similarity index 100% rename from crates/a2a-client/src/error.rs rename to crates/a2a-protocol-client/src/error.rs diff --git a/crates/a2a-client/src/interceptor.rs b/crates/a2a-protocol-client/src/interceptor.rs similarity index 100% rename from crates/a2a-client/src/interceptor.rs rename to crates/a2a-protocol-client/src/interceptor.rs diff --git a/crates/a2a-client/src/lib.rs b/crates/a2a-protocol-client/src/lib.rs similarity index 98% rename from crates/a2a-client/src/lib.rs rename to crates/a2a-protocol-client/src/lib.rs index 15654f0f..140675ba 100644 --- a/crates/a2a-client/src/lib.rs +++ b/crates/a2a-protocol-client/src/lib.rs @@ -102,7 +102,7 @@ #![forbid(unsafe_code)] #![warn(clippy::all, clippy::pedantic, clippy::nursery)] #![allow(clippy::module_name_repetitions)] -// See `crates/a2a-server/src/lib.rs` for the full rationale behind this +// See `crates/a2a-protocol-server/src/lib.rs` for the full rationale behind this // allow — in short, the lint lands in clippy 1.95 but its suggested // `Duration::from_hours` fix requires Rust 1.95, while our MSRV is 1.93. #![allow(unknown_lints, clippy::duration_suboptimal_units)] diff --git a/crates/a2a-client/src/methods/extended_card.rs b/crates/a2a-protocol-client/src/methods/extended_card.rs similarity index 100% rename from crates/a2a-client/src/methods/extended_card.rs rename to crates/a2a-protocol-client/src/methods/extended_card.rs diff --git a/crates/a2a-client/src/methods/mod.rs b/crates/a2a-protocol-client/src/methods/mod.rs similarity index 100% rename from crates/a2a-client/src/methods/mod.rs rename to crates/a2a-protocol-client/src/methods/mod.rs diff --git a/crates/a2a-client/src/methods/push_config.rs b/crates/a2a-protocol-client/src/methods/push_config.rs similarity index 100% rename from crates/a2a-client/src/methods/push_config.rs rename to crates/a2a-protocol-client/src/methods/push_config.rs diff --git a/crates/a2a-client/src/methods/send_message.rs b/crates/a2a-protocol-client/src/methods/send_message.rs similarity index 100% rename from crates/a2a-client/src/methods/send_message.rs rename to crates/a2a-protocol-client/src/methods/send_message.rs diff --git a/crates/a2a-client/src/methods/tasks.rs b/crates/a2a-protocol-client/src/methods/tasks.rs similarity index 100% rename from crates/a2a-client/src/methods/tasks.rs rename to crates/a2a-protocol-client/src/methods/tasks.rs diff --git a/crates/a2a-client/src/retry.rs b/crates/a2a-protocol-client/src/retry.rs similarity index 100% rename from crates/a2a-client/src/retry.rs rename to crates/a2a-protocol-client/src/retry.rs diff --git a/crates/a2a-client/src/streaming/event_stream.rs b/crates/a2a-protocol-client/src/streaming/event_stream.rs similarity index 100% rename from crates/a2a-client/src/streaming/event_stream.rs rename to crates/a2a-protocol-client/src/streaming/event_stream.rs diff --git a/crates/a2a-client/src/streaming/mod.rs b/crates/a2a-protocol-client/src/streaming/mod.rs similarity index 100% rename from crates/a2a-client/src/streaming/mod.rs rename to crates/a2a-protocol-client/src/streaming/mod.rs diff --git a/crates/a2a-client/src/streaming/sse_parser/mod.rs b/crates/a2a-protocol-client/src/streaming/sse_parser/mod.rs similarity index 100% rename from crates/a2a-client/src/streaming/sse_parser/mod.rs rename to crates/a2a-protocol-client/src/streaming/sse_parser/mod.rs diff --git a/crates/a2a-client/src/streaming/sse_parser/parser.rs b/crates/a2a-protocol-client/src/streaming/sse_parser/parser.rs similarity index 100% rename from crates/a2a-client/src/streaming/sse_parser/parser.rs rename to crates/a2a-protocol-client/src/streaming/sse_parser/parser.rs diff --git a/crates/a2a-client/src/streaming/sse_parser/types.rs b/crates/a2a-protocol-client/src/streaming/sse_parser/types.rs similarity index 100% rename from crates/a2a-client/src/streaming/sse_parser/types.rs rename to crates/a2a-protocol-client/src/streaming/sse_parser/types.rs diff --git a/crates/a2a-client/src/tls.rs b/crates/a2a-protocol-client/src/tls.rs similarity index 100% rename from crates/a2a-client/src/tls.rs rename to crates/a2a-protocol-client/src/tls.rs diff --git a/crates/a2a-client/src/trace.rs b/crates/a2a-protocol-client/src/trace.rs similarity index 100% rename from crates/a2a-client/src/trace.rs rename to crates/a2a-protocol-client/src/trace.rs diff --git a/crates/a2a-client/src/transport/grpc.rs b/crates/a2a-protocol-client/src/transport/grpc.rs similarity index 100% rename from crates/a2a-client/src/transport/grpc.rs rename to crates/a2a-protocol-client/src/transport/grpc.rs diff --git a/crates/a2a-client/src/transport/jsonrpc.rs b/crates/a2a-protocol-client/src/transport/jsonrpc.rs similarity index 100% rename from crates/a2a-client/src/transport/jsonrpc.rs rename to crates/a2a-protocol-client/src/transport/jsonrpc.rs diff --git a/crates/a2a-client/src/transport/mod.rs b/crates/a2a-protocol-client/src/transport/mod.rs similarity index 100% rename from crates/a2a-client/src/transport/mod.rs rename to crates/a2a-protocol-client/src/transport/mod.rs diff --git a/crates/a2a-client/src/transport/rest/mod.rs b/crates/a2a-protocol-client/src/transport/rest/mod.rs similarity index 100% rename from crates/a2a-client/src/transport/rest/mod.rs rename to crates/a2a-protocol-client/src/transport/rest/mod.rs diff --git a/crates/a2a-client/src/transport/rest/query.rs b/crates/a2a-protocol-client/src/transport/rest/query.rs similarity index 100% rename from crates/a2a-client/src/transport/rest/query.rs rename to crates/a2a-protocol-client/src/transport/rest/query.rs diff --git a/crates/a2a-client/src/transport/rest/request.rs b/crates/a2a-protocol-client/src/transport/rest/request.rs similarity index 100% rename from crates/a2a-client/src/transport/rest/request.rs rename to crates/a2a-protocol-client/src/transport/rest/request.rs diff --git a/crates/a2a-client/src/transport/rest/routing.rs b/crates/a2a-protocol-client/src/transport/rest/routing.rs similarity index 100% rename from crates/a2a-client/src/transport/rest/routing.rs rename to crates/a2a-protocol-client/src/transport/rest/routing.rs diff --git a/crates/a2a-client/src/transport/rest/streaming.rs b/crates/a2a-protocol-client/src/transport/rest/streaming.rs similarity index 100% rename from crates/a2a-client/src/transport/rest/streaming.rs rename to crates/a2a-protocol-client/src/transport/rest/streaming.rs diff --git a/crates/a2a-client/src/transport/websocket.rs b/crates/a2a-protocol-client/src/transport/websocket.rs similarity index 100% rename from crates/a2a-client/src/transport/websocket.rs rename to crates/a2a-protocol-client/src/transport/websocket.rs diff --git a/crates/a2a-client/tests/client_method_tests.rs b/crates/a2a-protocol-client/tests/client_method_tests.rs similarity index 100% rename from crates/a2a-client/tests/client_method_tests.rs rename to crates/a2a-protocol-client/tests/client_method_tests.rs diff --git a/crates/a2a-client/tests/client_tests.rs b/crates/a2a-protocol-client/tests/client_tests.rs similarity index 100% rename from crates/a2a-client/tests/client_tests.rs rename to crates/a2a-protocol-client/tests/client_tests.rs diff --git a/crates/a2a-client/tests/coverage_gap_tests.rs b/crates/a2a-protocol-client/tests/coverage_gap_tests.rs similarity index 100% rename from crates/a2a-client/tests/coverage_gap_tests.rs rename to crates/a2a-protocol-client/tests/coverage_gap_tests.rs diff --git a/crates/a2a-client/tests/discovery_tests.rs b/crates/a2a-protocol-client/tests/discovery_tests.rs similarity index 100% rename from crates/a2a-client/tests/discovery_tests.rs rename to crates/a2a-protocol-client/tests/discovery_tests.rs diff --git a/crates/a2a-client/tests/extended_card_tests.rs b/crates/a2a-protocol-client/tests/extended_card_tests.rs similarity index 100% rename from crates/a2a-client/tests/extended_card_tests.rs rename to crates/a2a-protocol-client/tests/extended_card_tests.rs diff --git a/crates/a2a-client/tests/rest_streaming_tests.rs b/crates/a2a-protocol-client/tests/rest_streaming_tests.rs similarity index 100% rename from crates/a2a-client/tests/rest_streaming_tests.rs rename to crates/a2a-protocol-client/tests/rest_streaming_tests.rs diff --git a/crates/a2a-client/tests/sse_edge_case_tests.rs b/crates/a2a-protocol-client/tests/sse_edge_case_tests.rs similarity index 100% rename from crates/a2a-client/tests/sse_edge_case_tests.rs rename to crates/a2a-protocol-client/tests/sse_edge_case_tests.rs diff --git a/crates/a2a-client/tests/tls_integration_tests.rs b/crates/a2a-protocol-client/tests/tls_integration_tests.rs similarity index 99% rename from crates/a2a-client/tests/tls_integration_tests.rs rename to crates/a2a-protocol-client/tests/tls_integration_tests.rs index ac543bd1..76fc2205 100644 --- a/crates/a2a-client/tests/tls_integration_tests.rs +++ b/crates/a2a-protocol-client/tests/tls_integration_tests.rs @@ -82,7 +82,7 @@ fn generate_test_certs(san: &str) -> TestCerts { /// [`rustls::ServerConfig::builder`] / [`rustls::ClientConfig::builder`], /// so we construct every config with an explicit provider via the /// `_with_provider` entry points. This mirrors what -/// `crates/a2a-client/src/tls.rs` does in production code. +/// `crates/a2a-protocol-client/src/tls.rs` does in production code. fn test_ring_provider() -> std::sync::Arc { std::sync::Arc::new(rustls::crypto::ring::default_provider()) } diff --git a/crates/a2a-client/tests/ws_transport_tests.rs b/crates/a2a-protocol-client/tests/ws_transport_tests.rs similarity index 100% rename from crates/a2a-client/tests/ws_transport_tests.rs rename to crates/a2a-protocol-client/tests/ws_transport_tests.rs diff --git a/crates/a2a-sdk/Cargo.toml b/crates/a2a-protocol-sdk/Cargo.toml similarity index 80% rename from crates/a2a-sdk/Cargo.toml rename to crates/a2a-protocol-sdk/Cargo.toml index e36488e4..dc71dc04 100644 --- a/crates/a2a-sdk/Cargo.toml +++ b/crates/a2a-protocol-sdk/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "a2a-protocol-sdk" version = "0.5.1" -description = "A2A protocol v1.0 — convenience umbrella re-export crate" +description = "Agent2Agent (A2A) protocol v1.0 — convenience umbrella re-export crate" readme = "README.md" edition.workspace = true @@ -14,7 +14,7 @@ authors.workspace = true repository.workspace = true homepage.workspace = true documentation = "https://docs.rs/a2a-protocol-sdk" -keywords = ["a2a", "agent", "sdk"] +keywords = ["a2a", "agent2agent", "agent", "protocol", "ai"] categories = ["network-programming", "web-programming", "api-bindings"] [features] @@ -42,6 +42,6 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -a2a-protocol-types = { version = "0.5.1", path = "../a2a-types" } -a2a-protocol-client = { version = "0.5.1", path = "../a2a-client" } -a2a-protocol-server = { version = "0.5.1", path = "../a2a-server" } +a2a-protocol-types = { version = "0.5.1", path = "../a2a-protocol-types" } +a2a-protocol-client = { version = "0.5.1", path = "../a2a-protocol-client" } +a2a-protocol-server = { version = "0.5.1", path = "../a2a-protocol-server" } diff --git a/crates/a2a-sdk/README.md b/crates/a2a-protocol-sdk/README.md similarity index 100% rename from crates/a2a-sdk/README.md rename to crates/a2a-protocol-sdk/README.md diff --git a/crates/a2a-sdk/src/lib.rs b/crates/a2a-protocol-sdk/src/lib.rs similarity index 100% rename from crates/a2a-sdk/src/lib.rs rename to crates/a2a-protocol-sdk/src/lib.rs diff --git a/crates/a2a-sdk/tests/reexport_tests.rs b/crates/a2a-protocol-sdk/tests/reexport_tests.rs similarity index 100% rename from crates/a2a-sdk/tests/reexport_tests.rs rename to crates/a2a-protocol-sdk/tests/reexport_tests.rs diff --git a/crates/a2a-server/Cargo.toml b/crates/a2a-protocol-server/Cargo.toml similarity index 92% rename from crates/a2a-server/Cargo.toml rename to crates/a2a-protocol-server/Cargo.toml index 6d9f720b..1b3b5405 100644 --- a/crates/a2a-server/Cargo.toml +++ b/crates/a2a-protocol-server/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "a2a-protocol-server" version = "0.5.1" -description = "A2A protocol v1.0 — server framework (hyper-backed)" +description = "Agent2Agent (A2A) protocol v1.0 — server framework (hyper-backed)" readme = "README.md" edition.workspace = true @@ -14,7 +14,7 @@ authors.workspace = true repository.workspace = true homepage.workspace = true documentation = "https://docs.rs/a2a-protocol-server" -keywords = ["a2a", "agent", "server", "http"] +keywords = ["a2a", "agent2agent", "agent", "protocol", "server"] categories = ["network-programming", "web-programming"] [features] @@ -36,7 +36,7 @@ otel = ["dep:opentelemetry", "dep:opentelemetry_sdk", "dep:opentelemetry-otlp"] axum = ["dep:axum"] [dependencies] -a2a-protocol-types = { version = "0.5.1", path = "../a2a-types" } +a2a-protocol-types = { version = "0.5.1", path = "../a2a-protocol-types" } serde = { workspace = true } serde_json = { workspace = true } hyper = { workspace = true } @@ -78,7 +78,7 @@ hyper-util = { workspace = true, features = ["server", "server-auto"] } http-body-util = { workspace = true } bytes = "1" serde_json = { workspace = true } -a2a-protocol-types = { version = "0.5.1", path = "../a2a-types" } +a2a-protocol-types = { version = "0.5.1", path = "../a2a-protocol-types" } criterion = { workspace = true } sqlx = { workspace = true } axum = { version = "0.8", features = ["json", "query", "tokio"] } diff --git a/crates/a2a-server/README.md b/crates/a2a-protocol-server/README.md similarity index 100% rename from crates/a2a-server/README.md rename to crates/a2a-protocol-server/README.md diff --git a/crates/a2a-server/benches/handler_bench.rs b/crates/a2a-protocol-server/benches/handler_bench.rs similarity index 100% rename from crates/a2a-server/benches/handler_bench.rs rename to crates/a2a-protocol-server/benches/handler_bench.rs diff --git a/crates/a2a-server/build.rs b/crates/a2a-protocol-server/build.rs similarity index 100% rename from crates/a2a-server/build.rs rename to crates/a2a-protocol-server/build.rs diff --git a/crates/a2a-server/proto/a2a.proto b/crates/a2a-protocol-server/proto/a2a.proto similarity index 100% rename from crates/a2a-server/proto/a2a.proto rename to crates/a2a-protocol-server/proto/a2a.proto diff --git a/crates/a2a-server/src/agent_card/caching.rs b/crates/a2a-protocol-server/src/agent_card/caching.rs similarity index 100% rename from crates/a2a-server/src/agent_card/caching.rs rename to crates/a2a-protocol-server/src/agent_card/caching.rs diff --git a/crates/a2a-server/src/agent_card/dynamic_handler.rs b/crates/a2a-protocol-server/src/agent_card/dynamic_handler.rs similarity index 100% rename from crates/a2a-server/src/agent_card/dynamic_handler.rs rename to crates/a2a-protocol-server/src/agent_card/dynamic_handler.rs diff --git a/crates/a2a-server/src/agent_card/hot_reload.rs b/crates/a2a-protocol-server/src/agent_card/hot_reload.rs similarity index 100% rename from crates/a2a-server/src/agent_card/hot_reload.rs rename to crates/a2a-protocol-server/src/agent_card/hot_reload.rs diff --git a/crates/a2a-server/src/agent_card/mod.rs b/crates/a2a-protocol-server/src/agent_card/mod.rs similarity index 100% rename from crates/a2a-server/src/agent_card/mod.rs rename to crates/a2a-protocol-server/src/agent_card/mod.rs diff --git a/crates/a2a-server/src/agent_card/static_handler.rs b/crates/a2a-protocol-server/src/agent_card/static_handler.rs similarity index 100% rename from crates/a2a-server/src/agent_card/static_handler.rs rename to crates/a2a-protocol-server/src/agent_card/static_handler.rs diff --git a/crates/a2a-server/src/builder.rs b/crates/a2a-protocol-server/src/builder.rs similarity index 100% rename from crates/a2a-server/src/builder.rs rename to crates/a2a-protocol-server/src/builder.rs diff --git a/crates/a2a-server/src/call_context.rs b/crates/a2a-protocol-server/src/call_context.rs similarity index 100% rename from crates/a2a-server/src/call_context.rs rename to crates/a2a-protocol-server/src/call_context.rs diff --git a/crates/a2a-server/src/dispatch/axum_adapter.rs b/crates/a2a-protocol-server/src/dispatch/axum_adapter.rs similarity index 100% rename from crates/a2a-server/src/dispatch/axum_adapter.rs rename to crates/a2a-protocol-server/src/dispatch/axum_adapter.rs diff --git a/crates/a2a-server/src/dispatch/cors.rs b/crates/a2a-protocol-server/src/dispatch/cors.rs similarity index 100% rename from crates/a2a-server/src/dispatch/cors.rs rename to crates/a2a-protocol-server/src/dispatch/cors.rs diff --git a/crates/a2a-server/src/dispatch/grpc/config.rs b/crates/a2a-protocol-server/src/dispatch/grpc/config.rs similarity index 100% rename from crates/a2a-server/src/dispatch/grpc/config.rs rename to crates/a2a-protocol-server/src/dispatch/grpc/config.rs diff --git a/crates/a2a-server/src/dispatch/grpc/dispatcher.rs b/crates/a2a-protocol-server/src/dispatch/grpc/dispatcher.rs similarity index 100% rename from crates/a2a-server/src/dispatch/grpc/dispatcher.rs rename to crates/a2a-protocol-server/src/dispatch/grpc/dispatcher.rs diff --git a/crates/a2a-server/src/dispatch/grpc/helpers.rs b/crates/a2a-protocol-server/src/dispatch/grpc/helpers.rs similarity index 100% rename from crates/a2a-server/src/dispatch/grpc/helpers.rs rename to crates/a2a-protocol-server/src/dispatch/grpc/helpers.rs diff --git a/crates/a2a-server/src/dispatch/grpc/mod.rs b/crates/a2a-protocol-server/src/dispatch/grpc/mod.rs similarity index 100% rename from crates/a2a-server/src/dispatch/grpc/mod.rs rename to crates/a2a-protocol-server/src/dispatch/grpc/mod.rs diff --git a/crates/a2a-server/src/dispatch/grpc/service.rs b/crates/a2a-protocol-server/src/dispatch/grpc/service.rs similarity index 100% rename from crates/a2a-server/src/dispatch/grpc/service.rs rename to crates/a2a-protocol-server/src/dispatch/grpc/service.rs diff --git a/crates/a2a-server/src/dispatch/jsonrpc/mod.rs b/crates/a2a-protocol-server/src/dispatch/jsonrpc/mod.rs similarity index 100% rename from crates/a2a-server/src/dispatch/jsonrpc/mod.rs rename to crates/a2a-protocol-server/src/dispatch/jsonrpc/mod.rs diff --git a/crates/a2a-server/src/dispatch/jsonrpc/response.rs b/crates/a2a-protocol-server/src/dispatch/jsonrpc/response.rs similarity index 100% rename from crates/a2a-server/src/dispatch/jsonrpc/response.rs rename to crates/a2a-protocol-server/src/dispatch/jsonrpc/response.rs diff --git a/crates/a2a-server/src/dispatch/mod.rs b/crates/a2a-protocol-server/src/dispatch/mod.rs similarity index 100% rename from crates/a2a-server/src/dispatch/mod.rs rename to crates/a2a-protocol-server/src/dispatch/mod.rs diff --git a/crates/a2a-server/src/dispatch/rest/mod.rs b/crates/a2a-protocol-server/src/dispatch/rest/mod.rs similarity index 100% rename from crates/a2a-server/src/dispatch/rest/mod.rs rename to crates/a2a-protocol-server/src/dispatch/rest/mod.rs diff --git a/crates/a2a-server/src/dispatch/rest/query.rs b/crates/a2a-protocol-server/src/dispatch/rest/query.rs similarity index 100% rename from crates/a2a-server/src/dispatch/rest/query.rs rename to crates/a2a-protocol-server/src/dispatch/rest/query.rs diff --git a/crates/a2a-server/src/dispatch/rest/response.rs b/crates/a2a-protocol-server/src/dispatch/rest/response.rs similarity index 100% rename from crates/a2a-server/src/dispatch/rest/response.rs rename to crates/a2a-protocol-server/src/dispatch/rest/response.rs diff --git a/crates/a2a-server/src/dispatch/websocket.rs b/crates/a2a-protocol-server/src/dispatch/websocket.rs similarity index 100% rename from crates/a2a-server/src/dispatch/websocket.rs rename to crates/a2a-protocol-server/src/dispatch/websocket.rs diff --git a/crates/a2a-server/src/error.rs b/crates/a2a-protocol-server/src/error.rs similarity index 100% rename from crates/a2a-server/src/error.rs rename to crates/a2a-protocol-server/src/error.rs diff --git a/crates/a2a-server/src/executor.rs b/crates/a2a-protocol-server/src/executor.rs similarity index 100% rename from crates/a2a-server/src/executor.rs rename to crates/a2a-protocol-server/src/executor.rs diff --git a/crates/a2a-server/src/executor_helpers.rs b/crates/a2a-protocol-server/src/executor_helpers.rs similarity index 100% rename from crates/a2a-server/src/executor_helpers.rs rename to crates/a2a-protocol-server/src/executor_helpers.rs diff --git a/crates/a2a-server/src/handler/event_processing/background/mod.rs b/crates/a2a-protocol-server/src/handler/event_processing/background/mod.rs similarity index 100% rename from crates/a2a-server/src/handler/event_processing/background/mod.rs rename to crates/a2a-protocol-server/src/handler/event_processing/background/mod.rs diff --git a/crates/a2a-server/src/handler/event_processing/background/push_delivery.rs b/crates/a2a-protocol-server/src/handler/event_processing/background/push_delivery.rs similarity index 100% rename from crates/a2a-server/src/handler/event_processing/background/push_delivery.rs rename to crates/a2a-protocol-server/src/handler/event_processing/background/push_delivery.rs diff --git a/crates/a2a-server/src/handler/event_processing/background/state_machine.rs b/crates/a2a-protocol-server/src/handler/event_processing/background/state_machine.rs similarity index 100% rename from crates/a2a-server/src/handler/event_processing/background/state_machine.rs rename to crates/a2a-protocol-server/src/handler/event_processing/background/state_machine.rs diff --git a/crates/a2a-server/src/handler/event_processing/mod.rs b/crates/a2a-protocol-server/src/handler/event_processing/mod.rs similarity index 100% rename from crates/a2a-server/src/handler/event_processing/mod.rs rename to crates/a2a-protocol-server/src/handler/event_processing/mod.rs diff --git a/crates/a2a-server/src/handler/event_processing/sync_collector.rs b/crates/a2a-protocol-server/src/handler/event_processing/sync_collector.rs similarity index 100% rename from crates/a2a-server/src/handler/event_processing/sync_collector.rs rename to crates/a2a-protocol-server/src/handler/event_processing/sync_collector.rs diff --git a/crates/a2a-server/src/handler/helpers.rs b/crates/a2a-protocol-server/src/handler/helpers.rs similarity index 100% rename from crates/a2a-server/src/handler/helpers.rs rename to crates/a2a-protocol-server/src/handler/helpers.rs diff --git a/crates/a2a-server/src/handler/lifecycle/cancel_task.rs b/crates/a2a-protocol-server/src/handler/lifecycle/cancel_task.rs similarity index 100% rename from crates/a2a-server/src/handler/lifecycle/cancel_task.rs rename to crates/a2a-protocol-server/src/handler/lifecycle/cancel_task.rs diff --git a/crates/a2a-server/src/handler/lifecycle/extended_card.rs b/crates/a2a-protocol-server/src/handler/lifecycle/extended_card.rs similarity index 100% rename from crates/a2a-server/src/handler/lifecycle/extended_card.rs rename to crates/a2a-protocol-server/src/handler/lifecycle/extended_card.rs diff --git a/crates/a2a-server/src/handler/lifecycle/get_task.rs b/crates/a2a-protocol-server/src/handler/lifecycle/get_task.rs similarity index 100% rename from crates/a2a-server/src/handler/lifecycle/get_task.rs rename to crates/a2a-protocol-server/src/handler/lifecycle/get_task.rs diff --git a/crates/a2a-server/src/handler/lifecycle/list_tasks.rs b/crates/a2a-protocol-server/src/handler/lifecycle/list_tasks.rs similarity index 100% rename from crates/a2a-server/src/handler/lifecycle/list_tasks.rs rename to crates/a2a-protocol-server/src/handler/lifecycle/list_tasks.rs diff --git a/crates/a2a-server/src/handler/lifecycle/mod.rs b/crates/a2a-protocol-server/src/handler/lifecycle/mod.rs similarity index 100% rename from crates/a2a-server/src/handler/lifecycle/mod.rs rename to crates/a2a-protocol-server/src/handler/lifecycle/mod.rs diff --git a/crates/a2a-server/src/handler/lifecycle/subscribe.rs b/crates/a2a-protocol-server/src/handler/lifecycle/subscribe.rs similarity index 100% rename from crates/a2a-server/src/handler/lifecycle/subscribe.rs rename to crates/a2a-protocol-server/src/handler/lifecycle/subscribe.rs diff --git a/crates/a2a-server/src/handler/limits.rs b/crates/a2a-protocol-server/src/handler/limits.rs similarity index 100% rename from crates/a2a-server/src/handler/limits.rs rename to crates/a2a-protocol-server/src/handler/limits.rs diff --git a/crates/a2a-server/src/handler/messaging.rs b/crates/a2a-protocol-server/src/handler/messaging.rs similarity index 100% rename from crates/a2a-server/src/handler/messaging.rs rename to crates/a2a-protocol-server/src/handler/messaging.rs diff --git a/crates/a2a-server/src/handler/mod.rs b/crates/a2a-protocol-server/src/handler/mod.rs similarity index 100% rename from crates/a2a-server/src/handler/mod.rs rename to crates/a2a-protocol-server/src/handler/mod.rs diff --git a/crates/a2a-server/src/handler/push_config.rs b/crates/a2a-protocol-server/src/handler/push_config.rs similarity index 100% rename from crates/a2a-server/src/handler/push_config.rs rename to crates/a2a-protocol-server/src/handler/push_config.rs diff --git a/crates/a2a-server/src/handler/shutdown.rs b/crates/a2a-protocol-server/src/handler/shutdown.rs similarity index 100% rename from crates/a2a-server/src/handler/shutdown.rs rename to crates/a2a-protocol-server/src/handler/shutdown.rs diff --git a/crates/a2a-server/src/interceptor.rs b/crates/a2a-protocol-server/src/interceptor.rs similarity index 100% rename from crates/a2a-server/src/interceptor.rs rename to crates/a2a-protocol-server/src/interceptor.rs diff --git a/crates/a2a-server/src/lib.rs b/crates/a2a-protocol-server/src/lib.rs similarity index 100% rename from crates/a2a-server/src/lib.rs rename to crates/a2a-protocol-server/src/lib.rs diff --git a/crates/a2a-server/src/metrics.rs b/crates/a2a-protocol-server/src/metrics.rs similarity index 100% rename from crates/a2a-server/src/metrics.rs rename to crates/a2a-protocol-server/src/metrics.rs diff --git a/crates/a2a-server/src/otel/builder.rs b/crates/a2a-protocol-server/src/otel/builder.rs similarity index 100% rename from crates/a2a-server/src/otel/builder.rs rename to crates/a2a-protocol-server/src/otel/builder.rs diff --git a/crates/a2a-server/src/otel/mod.rs b/crates/a2a-protocol-server/src/otel/mod.rs similarity index 100% rename from crates/a2a-server/src/otel/mod.rs rename to crates/a2a-protocol-server/src/otel/mod.rs diff --git a/crates/a2a-server/src/otel/pipeline.rs b/crates/a2a-protocol-server/src/otel/pipeline.rs similarity index 100% rename from crates/a2a-server/src/otel/pipeline.rs rename to crates/a2a-protocol-server/src/otel/pipeline.rs diff --git a/crates/a2a-server/src/push/config_store.rs b/crates/a2a-protocol-server/src/push/config_store.rs similarity index 100% rename from crates/a2a-server/src/push/config_store.rs rename to crates/a2a-protocol-server/src/push/config_store.rs diff --git a/crates/a2a-server/src/push/mod.rs b/crates/a2a-protocol-server/src/push/mod.rs similarity index 100% rename from crates/a2a-server/src/push/mod.rs rename to crates/a2a-protocol-server/src/push/mod.rs diff --git a/crates/a2a-server/src/push/postgres_config_store.rs b/crates/a2a-protocol-server/src/push/postgres_config_store.rs similarity index 100% rename from crates/a2a-server/src/push/postgres_config_store.rs rename to crates/a2a-protocol-server/src/push/postgres_config_store.rs diff --git a/crates/a2a-server/src/push/sender.rs b/crates/a2a-protocol-server/src/push/sender.rs similarity index 100% rename from crates/a2a-server/src/push/sender.rs rename to crates/a2a-protocol-server/src/push/sender.rs diff --git a/crates/a2a-server/src/push/sqlite_config_store.rs b/crates/a2a-protocol-server/src/push/sqlite_config_store.rs similarity index 100% rename from crates/a2a-server/src/push/sqlite_config_store.rs rename to crates/a2a-protocol-server/src/push/sqlite_config_store.rs diff --git a/crates/a2a-server/src/push/tenant_config_store.rs b/crates/a2a-protocol-server/src/push/tenant_config_store.rs similarity index 100% rename from crates/a2a-server/src/push/tenant_config_store.rs rename to crates/a2a-protocol-server/src/push/tenant_config_store.rs diff --git a/crates/a2a-server/src/push/tenant_postgres_config_store.rs b/crates/a2a-protocol-server/src/push/tenant_postgres_config_store.rs similarity index 100% rename from crates/a2a-server/src/push/tenant_postgres_config_store.rs rename to crates/a2a-protocol-server/src/push/tenant_postgres_config_store.rs diff --git a/crates/a2a-server/src/push/tenant_sqlite_config_store.rs b/crates/a2a-protocol-server/src/push/tenant_sqlite_config_store.rs similarity index 100% rename from crates/a2a-server/src/push/tenant_sqlite_config_store.rs rename to crates/a2a-protocol-server/src/push/tenant_sqlite_config_store.rs diff --git a/crates/a2a-server/src/rate_limit.rs b/crates/a2a-protocol-server/src/rate_limit.rs similarity index 100% rename from crates/a2a-server/src/rate_limit.rs rename to crates/a2a-protocol-server/src/rate_limit.rs diff --git a/crates/a2a-server/src/request_context.rs b/crates/a2a-protocol-server/src/request_context.rs similarity index 100% rename from crates/a2a-server/src/request_context.rs rename to crates/a2a-protocol-server/src/request_context.rs diff --git a/crates/a2a-server/src/serve.rs b/crates/a2a-protocol-server/src/serve.rs similarity index 100% rename from crates/a2a-server/src/serve.rs rename to crates/a2a-protocol-server/src/serve.rs diff --git a/crates/a2a-server/src/store/migration.rs b/crates/a2a-protocol-server/src/store/migration.rs similarity index 100% rename from crates/a2a-server/src/store/migration.rs rename to crates/a2a-protocol-server/src/store/migration.rs diff --git a/crates/a2a-server/src/store/mod.rs b/crates/a2a-protocol-server/src/store/mod.rs similarity index 100% rename from crates/a2a-server/src/store/mod.rs rename to crates/a2a-protocol-server/src/store/mod.rs diff --git a/crates/a2a-server/src/store/pg_migration.rs b/crates/a2a-protocol-server/src/store/pg_migration.rs similarity index 100% rename from crates/a2a-server/src/store/pg_migration.rs rename to crates/a2a-protocol-server/src/store/pg_migration.rs diff --git a/crates/a2a-server/src/store/postgres_store.rs b/crates/a2a-protocol-server/src/store/postgres_store.rs similarity index 100% rename from crates/a2a-server/src/store/postgres_store.rs rename to crates/a2a-protocol-server/src/store/postgres_store.rs diff --git a/crates/a2a-server/src/store/sqlite_store.rs b/crates/a2a-protocol-server/src/store/sqlite_store.rs similarity index 100% rename from crates/a2a-server/src/store/sqlite_store.rs rename to crates/a2a-protocol-server/src/store/sqlite_store.rs diff --git a/crates/a2a-server/src/store/task_store/in_memory/eviction.rs b/crates/a2a-protocol-server/src/store/task_store/in_memory/eviction.rs similarity index 100% rename from crates/a2a-server/src/store/task_store/in_memory/eviction.rs rename to crates/a2a-protocol-server/src/store/task_store/in_memory/eviction.rs diff --git a/crates/a2a-server/src/store/task_store/in_memory/mod.rs b/crates/a2a-protocol-server/src/store/task_store/in_memory/mod.rs similarity index 100% rename from crates/a2a-server/src/store/task_store/in_memory/mod.rs rename to crates/a2a-protocol-server/src/store/task_store/in_memory/mod.rs diff --git a/crates/a2a-server/src/store/task_store/mod.rs b/crates/a2a-protocol-server/src/store/task_store/mod.rs similarity index 100% rename from crates/a2a-server/src/store/task_store/mod.rs rename to crates/a2a-protocol-server/src/store/task_store/mod.rs diff --git a/crates/a2a-server/src/store/tenant/context.rs b/crates/a2a-protocol-server/src/store/tenant/context.rs similarity index 100% rename from crates/a2a-server/src/store/tenant/context.rs rename to crates/a2a-protocol-server/src/store/tenant/context.rs diff --git a/crates/a2a-server/src/store/tenant/mod.rs b/crates/a2a-protocol-server/src/store/tenant/mod.rs similarity index 100% rename from crates/a2a-server/src/store/tenant/mod.rs rename to crates/a2a-protocol-server/src/store/tenant/mod.rs diff --git a/crates/a2a-server/src/store/tenant/store.rs b/crates/a2a-protocol-server/src/store/tenant/store.rs similarity index 100% rename from crates/a2a-server/src/store/tenant/store.rs rename to crates/a2a-protocol-server/src/store/tenant/store.rs diff --git a/crates/a2a-server/src/store/tenant_postgres_store.rs b/crates/a2a-protocol-server/src/store/tenant_postgres_store.rs similarity index 100% rename from crates/a2a-server/src/store/tenant_postgres_store.rs rename to crates/a2a-protocol-server/src/store/tenant_postgres_store.rs diff --git a/crates/a2a-server/src/store/tenant_sqlite_store.rs b/crates/a2a-protocol-server/src/store/tenant_sqlite_store.rs similarity index 100% rename from crates/a2a-server/src/store/tenant_sqlite_store.rs rename to crates/a2a-protocol-server/src/store/tenant_sqlite_store.rs diff --git a/crates/a2a-server/src/streaming/event_queue/in_memory.rs b/crates/a2a-protocol-server/src/streaming/event_queue/in_memory.rs similarity index 100% rename from crates/a2a-server/src/streaming/event_queue/in_memory.rs rename to crates/a2a-protocol-server/src/streaming/event_queue/in_memory.rs diff --git a/crates/a2a-server/src/streaming/event_queue/manager.rs b/crates/a2a-protocol-server/src/streaming/event_queue/manager.rs similarity index 100% rename from crates/a2a-server/src/streaming/event_queue/manager.rs rename to crates/a2a-protocol-server/src/streaming/event_queue/manager.rs diff --git a/crates/a2a-server/src/streaming/event_queue/mod.rs b/crates/a2a-protocol-server/src/streaming/event_queue/mod.rs similarity index 100% rename from crates/a2a-server/src/streaming/event_queue/mod.rs rename to crates/a2a-protocol-server/src/streaming/event_queue/mod.rs diff --git a/crates/a2a-server/src/streaming/mod.rs b/crates/a2a-protocol-server/src/streaming/mod.rs similarity index 100% rename from crates/a2a-server/src/streaming/mod.rs rename to crates/a2a-protocol-server/src/streaming/mod.rs diff --git a/crates/a2a-server/src/streaming/sse.rs b/crates/a2a-protocol-server/src/streaming/sse.rs similarity index 100% rename from crates/a2a-server/src/streaming/sse.rs rename to crates/a2a-protocol-server/src/streaming/sse.rs diff --git a/crates/a2a-server/src/tenant_config.rs b/crates/a2a-protocol-server/src/tenant_config.rs similarity index 100% rename from crates/a2a-server/src/tenant_config.rs rename to crates/a2a-protocol-server/src/tenant_config.rs diff --git a/crates/a2a-server/src/tenant_resolver.rs b/crates/a2a-protocol-server/src/tenant_resolver.rs similarity index 100% rename from crates/a2a-server/src/tenant_resolver.rs rename to crates/a2a-protocol-server/src/tenant_resolver.rs diff --git a/crates/a2a-server/src/trace.rs b/crates/a2a-protocol-server/src/trace.rs similarity index 100% rename from crates/a2a-server/src/trace.rs rename to crates/a2a-protocol-server/src/trace.rs diff --git a/crates/a2a-server/tests/audit_tests/edge_cases.rs b/crates/a2a-protocol-server/tests/audit_tests/edge_cases.rs similarity index 100% rename from crates/a2a-server/tests/audit_tests/edge_cases.rs rename to crates/a2a-protocol-server/tests/audit_tests/edge_cases.rs diff --git a/crates/a2a-server/tests/audit_tests/lifecycle.rs b/crates/a2a-protocol-server/tests/audit_tests/lifecycle.rs similarity index 100% rename from crates/a2a-server/tests/audit_tests/lifecycle.rs rename to crates/a2a-protocol-server/tests/audit_tests/lifecycle.rs diff --git a/crates/a2a-server/tests/audit_tests/main.rs b/crates/a2a-protocol-server/tests/audit_tests/main.rs similarity index 100% rename from crates/a2a-server/tests/audit_tests/main.rs rename to crates/a2a-protocol-server/tests/audit_tests/main.rs diff --git a/crates/a2a-server/tests/audit_tests/public_api.rs b/crates/a2a-protocol-server/tests/audit_tests/public_api.rs similarity index 100% rename from crates/a2a-server/tests/audit_tests/public_api.rs rename to crates/a2a-protocol-server/tests/audit_tests/public_api.rs diff --git a/crates/a2a-server/tests/audit_tests/security_boundaries.rs b/crates/a2a-protocol-server/tests/audit_tests/security_boundaries.rs similarity index 100% rename from crates/a2a-server/tests/audit_tests/security_boundaries.rs rename to crates/a2a-protocol-server/tests/audit_tests/security_boundaries.rs diff --git a/crates/a2a-server/tests/axum_adapter_tests.rs b/crates/a2a-protocol-server/tests/axum_adapter_tests.rs similarity index 100% rename from crates/a2a-server/tests/axum_adapter_tests.rs rename to crates/a2a-protocol-server/tests/axum_adapter_tests.rs diff --git a/crates/a2a-server/tests/dispatch_edge_tests.rs b/crates/a2a-protocol-server/tests/dispatch_edge_tests.rs similarity index 100% rename from crates/a2a-server/tests/dispatch_edge_tests.rs rename to crates/a2a-protocol-server/tests/dispatch_edge_tests.rs diff --git a/crates/a2a-server/tests/dispatch_rest_coverage.rs b/crates/a2a-protocol-server/tests/dispatch_rest_coverage.rs similarity index 100% rename from crates/a2a-server/tests/dispatch_rest_coverage.rs rename to crates/a2a-protocol-server/tests/dispatch_rest_coverage.rs diff --git a/crates/a2a-server/tests/dispatch_tests/hardening.rs b/crates/a2a-protocol-server/tests/dispatch_tests/hardening.rs similarity index 100% rename from crates/a2a-server/tests/dispatch_tests/hardening.rs rename to crates/a2a-protocol-server/tests/dispatch_tests/hardening.rs diff --git a/crates/a2a-server/tests/dispatch_tests/jsonrpc.rs b/crates/a2a-protocol-server/tests/dispatch_tests/jsonrpc.rs similarity index 100% rename from crates/a2a-server/tests/dispatch_tests/jsonrpc.rs rename to crates/a2a-protocol-server/tests/dispatch_tests/jsonrpc.rs diff --git a/crates/a2a-server/tests/dispatch_tests/main.rs b/crates/a2a-protocol-server/tests/dispatch_tests/main.rs similarity index 100% rename from crates/a2a-server/tests/dispatch_tests/main.rs rename to crates/a2a-protocol-server/tests/dispatch_tests/main.rs diff --git a/crates/a2a-server/tests/dispatch_tests/rest.rs b/crates/a2a-protocol-server/tests/dispatch_tests/rest.rs similarity index 100% rename from crates/a2a-server/tests/dispatch_tests/rest.rs rename to crates/a2a-protocol-server/tests/dispatch_tests/rest.rs diff --git a/crates/a2a-server/tests/dynamic_handler_tests.rs b/crates/a2a-protocol-server/tests/dynamic_handler_tests.rs similarity index 100% rename from crates/a2a-server/tests/dynamic_handler_tests.rs rename to crates/a2a-protocol-server/tests/dynamic_handler_tests.rs diff --git a/crates/a2a-server/tests/edge_case_tests/concurrency.rs b/crates/a2a-protocol-server/tests/edge_case_tests/concurrency.rs similarity index 100% rename from crates/a2a-server/tests/edge_case_tests/concurrency.rs rename to crates/a2a-protocol-server/tests/edge_case_tests/concurrency.rs diff --git a/crates/a2a-server/tests/edge_case_tests/error_mapping.rs b/crates/a2a-protocol-server/tests/edge_case_tests/error_mapping.rs similarity index 100% rename from crates/a2a-server/tests/edge_case_tests/error_mapping.rs rename to crates/a2a-protocol-server/tests/edge_case_tests/error_mapping.rs diff --git a/crates/a2a-server/tests/edge_case_tests/event_queue.rs b/crates/a2a-protocol-server/tests/edge_case_tests/event_queue.rs similarity index 100% rename from crates/a2a-server/tests/edge_case_tests/event_queue.rs rename to crates/a2a-protocol-server/tests/edge_case_tests/event_queue.rs diff --git a/crates/a2a-server/tests/edge_case_tests/handler_basics.rs b/crates/a2a-protocol-server/tests/edge_case_tests/handler_basics.rs similarity index 100% rename from crates/a2a-server/tests/edge_case_tests/handler_basics.rs rename to crates/a2a-protocol-server/tests/edge_case_tests/handler_basics.rs diff --git a/crates/a2a-server/tests/edge_case_tests/main.rs b/crates/a2a-protocol-server/tests/edge_case_tests/main.rs similarity index 100% rename from crates/a2a-server/tests/edge_case_tests/main.rs rename to crates/a2a-protocol-server/tests/edge_case_tests/main.rs diff --git a/crates/a2a-server/tests/edge_case_tests/store_and_eviction.rs b/crates/a2a-protocol-server/tests/edge_case_tests/store_and_eviction.rs similarity index 100% rename from crates/a2a-server/tests/edge_case_tests/store_and_eviction.rs rename to crates/a2a-protocol-server/tests/edge_case_tests/store_and_eviction.rs diff --git a/crates/a2a-server/tests/edge_case_tests/type_system.rs b/crates/a2a-protocol-server/tests/edge_case_tests/type_system.rs similarity index 100% rename from crates/a2a-server/tests/edge_case_tests/type_system.rs rename to crates/a2a-protocol-server/tests/edge_case_tests/type_system.rs diff --git a/crates/a2a-server/tests/event_processing_tests/background_processor.rs b/crates/a2a-protocol-server/tests/event_processing_tests/background_processor.rs similarity index 100% rename from crates/a2a-server/tests/event_processing_tests/background_processor.rs rename to crates/a2a-protocol-server/tests/event_processing_tests/background_processor.rs diff --git a/crates/a2a-server/tests/event_processing_tests/error_handling.rs b/crates/a2a-protocol-server/tests/event_processing_tests/error_handling.rs similarity index 100% rename from crates/a2a-server/tests/event_processing_tests/error_handling.rs rename to crates/a2a-protocol-server/tests/event_processing_tests/error_handling.rs diff --git a/crates/a2a-server/tests/event_processing_tests/main.rs b/crates/a2a-protocol-server/tests/event_processing_tests/main.rs similarity index 100% rename from crates/a2a-server/tests/event_processing_tests/main.rs rename to crates/a2a-protocol-server/tests/event_processing_tests/main.rs diff --git a/crates/a2a-server/tests/event_processing_tests/state_transitions.rs b/crates/a2a-protocol-server/tests/event_processing_tests/state_transitions.rs similarity index 100% rename from crates/a2a-server/tests/event_processing_tests/state_transitions.rs rename to crates/a2a-protocol-server/tests/event_processing_tests/state_transitions.rs diff --git a/crates/a2a-server/tests/event_processing_tests/streaming_mode.rs b/crates/a2a-protocol-server/tests/event_processing_tests/streaming_mode.rs similarity index 100% rename from crates/a2a-server/tests/event_processing_tests/streaming_mode.rs rename to crates/a2a-protocol-server/tests/event_processing_tests/streaming_mode.rs diff --git a/crates/a2a-server/tests/event_processing_tests/sync_mode.rs b/crates/a2a-protocol-server/tests/event_processing_tests/sync_mode.rs similarity index 100% rename from crates/a2a-server/tests/event_processing_tests/sync_mode.rs rename to crates/a2a-protocol-server/tests/event_processing_tests/sync_mode.rs diff --git a/crates/a2a-server/tests/event_queue_tests.rs b/crates/a2a-protocol-server/tests/event_queue_tests.rs similarity index 100% rename from crates/a2a-server/tests/event_queue_tests.rs rename to crates/a2a-protocol-server/tests/event_queue_tests.rs diff --git a/crates/a2a-server/tests/grpc_dispatch_tests.rs b/crates/a2a-protocol-server/tests/grpc_dispatch_tests.rs similarity index 100% rename from crates/a2a-server/tests/grpc_dispatch_tests.rs rename to crates/a2a-protocol-server/tests/grpc_dispatch_tests.rs diff --git a/crates/a2a-server/tests/handler_tests/advanced.rs b/crates/a2a-protocol-server/tests/handler_tests/advanced.rs similarity index 100% rename from crates/a2a-server/tests/handler_tests/advanced.rs rename to crates/a2a-protocol-server/tests/handler_tests/advanced.rs diff --git a/crates/a2a-server/tests/handler_tests/agent_card.rs b/crates/a2a-protocol-server/tests/handler_tests/agent_card.rs similarity index 100% rename from crates/a2a-server/tests/handler_tests/agent_card.rs rename to crates/a2a-protocol-server/tests/handler_tests/agent_card.rs diff --git a/crates/a2a-server/tests/handler_tests/main.rs b/crates/a2a-protocol-server/tests/handler_tests/main.rs similarity index 100% rename from crates/a2a-server/tests/handler_tests/main.rs rename to crates/a2a-protocol-server/tests/handler_tests/main.rs diff --git a/crates/a2a-server/tests/handler_tests/push_config.rs b/crates/a2a-protocol-server/tests/handler_tests/push_config.rs similarity index 100% rename from crates/a2a-server/tests/handler_tests/push_config.rs rename to crates/a2a-protocol-server/tests/handler_tests/push_config.rs diff --git a/crates/a2a-server/tests/handler_tests/send_message.rs b/crates/a2a-protocol-server/tests/handler_tests/send_message.rs similarity index 100% rename from crates/a2a-server/tests/handler_tests/send_message.rs rename to crates/a2a-protocol-server/tests/handler_tests/send_message.rs diff --git a/crates/a2a-server/tests/handler_tests/streaming.rs b/crates/a2a-protocol-server/tests/handler_tests/streaming.rs similarity index 100% rename from crates/a2a-server/tests/handler_tests/streaming.rs rename to crates/a2a-protocol-server/tests/handler_tests/streaming.rs diff --git a/crates/a2a-server/tests/handler_tests/task_operations.rs b/crates/a2a-protocol-server/tests/handler_tests/task_operations.rs similarity index 100% rename from crates/a2a-server/tests/handler_tests/task_operations.rs rename to crates/a2a-protocol-server/tests/handler_tests/task_operations.rs diff --git a/crates/a2a-server/tests/hardening_tests/builder.rs b/crates/a2a-protocol-server/tests/hardening_tests/builder.rs similarity index 100% rename from crates/a2a-server/tests/hardening_tests/builder.rs rename to crates/a2a-protocol-server/tests/hardening_tests/builder.rs diff --git a/crates/a2a-server/tests/hardening_tests/concurrency.rs b/crates/a2a-protocol-server/tests/hardening_tests/concurrency.rs similarity index 100% rename from crates/a2a-server/tests/hardening_tests/concurrency.rs rename to crates/a2a-protocol-server/tests/hardening_tests/concurrency.rs diff --git a/crates/a2a-server/tests/hardening_tests/event_queue.rs b/crates/a2a-protocol-server/tests/hardening_tests/event_queue.rs similarity index 100% rename from crates/a2a-server/tests/hardening_tests/event_queue.rs rename to crates/a2a-protocol-server/tests/hardening_tests/event_queue.rs diff --git a/crates/a2a-server/tests/hardening_tests/interceptor_chain.rs b/crates/a2a-protocol-server/tests/hardening_tests/interceptor_chain.rs similarity index 100% rename from crates/a2a-server/tests/hardening_tests/interceptor_chain.rs rename to crates/a2a-protocol-server/tests/hardening_tests/interceptor_chain.rs diff --git a/crates/a2a-server/tests/hardening_tests/main.rs b/crates/a2a-protocol-server/tests/hardening_tests/main.rs similarity index 100% rename from crates/a2a-server/tests/hardening_tests/main.rs rename to crates/a2a-protocol-server/tests/hardening_tests/main.rs diff --git a/crates/a2a-server/tests/hardening_tests/push_config_store.rs b/crates/a2a-protocol-server/tests/hardening_tests/push_config_store.rs similarity index 100% rename from crates/a2a-server/tests/hardening_tests/push_config_store.rs rename to crates/a2a-protocol-server/tests/hardening_tests/push_config_store.rs diff --git a/crates/a2a-server/tests/hardening_tests/task_store.rs b/crates/a2a-protocol-server/tests/hardening_tests/task_store.rs similarity index 100% rename from crates/a2a-server/tests/hardening_tests/task_store.rs rename to crates/a2a-protocol-server/tests/hardening_tests/task_store.rs diff --git a/crates/a2a-server/tests/interceptor_tests.rs b/crates/a2a-protocol-server/tests/interceptor_tests.rs similarity index 100% rename from crates/a2a-server/tests/interceptor_tests.rs rename to crates/a2a-protocol-server/tests/interceptor_tests.rs diff --git a/crates/a2a-server/tests/jsonrpc_dispatch_coverage_tests.rs b/crates/a2a-protocol-server/tests/jsonrpc_dispatch_coverage_tests.rs similarity index 100% rename from crates/a2a-server/tests/jsonrpc_dispatch_coverage_tests.rs rename to crates/a2a-protocol-server/tests/jsonrpc_dispatch_coverage_tests.rs diff --git a/crates/a2a-server/tests/jsonrpc_edge_tests.rs b/crates/a2a-protocol-server/tests/jsonrpc_edge_tests.rs similarity index 100% rename from crates/a2a-server/tests/jsonrpc_edge_tests.rs rename to crates/a2a-protocol-server/tests/jsonrpc_edge_tests.rs diff --git a/crates/a2a-server/tests/push_config_tests.rs b/crates/a2a-protocol-server/tests/push_config_tests.rs similarity index 100% rename from crates/a2a-server/tests/push_config_tests.rs rename to crates/a2a-protocol-server/tests/push_config_tests.rs diff --git a/crates/a2a-server/tests/push_sender_tests.rs b/crates/a2a-protocol-server/tests/push_sender_tests.rs similarity index 100% rename from crates/a2a-server/tests/push_sender_tests.rs rename to crates/a2a-protocol-server/tests/push_sender_tests.rs diff --git a/crates/a2a-server/tests/rest_edge_tests.rs b/crates/a2a-protocol-server/tests/rest_edge_tests.rs similarity index 100% rename from crates/a2a-server/tests/rest_edge_tests.rs rename to crates/a2a-protocol-server/tests/rest_edge_tests.rs diff --git a/crates/a2a-server/tests/send_sync_tests.rs b/crates/a2a-protocol-server/tests/send_sync_tests.rs similarity index 100% rename from crates/a2a-server/tests/send_sync_tests.rs rename to crates/a2a-protocol-server/tests/send_sync_tests.rs diff --git a/crates/a2a-server/tests/serve_tests.rs b/crates/a2a-protocol-server/tests/serve_tests.rs similarity index 100% rename from crates/a2a-server/tests/serve_tests.rs rename to crates/a2a-protocol-server/tests/serve_tests.rs diff --git a/crates/a2a-server/tests/sqlite_store_tests.rs b/crates/a2a-protocol-server/tests/sqlite_store_tests.rs similarity index 100% rename from crates/a2a-server/tests/sqlite_store_tests.rs rename to crates/a2a-protocol-server/tests/sqlite_store_tests.rs diff --git a/crates/a2a-server/tests/sse_format_tests.rs b/crates/a2a-protocol-server/tests/sse_format_tests.rs similarity index 100% rename from crates/a2a-server/tests/sse_format_tests.rs rename to crates/a2a-protocol-server/tests/sse_format_tests.rs diff --git a/crates/a2a-server/tests/state_validation_tests.rs b/crates/a2a-protocol-server/tests/state_validation_tests.rs similarity index 100% rename from crates/a2a-server/tests/state_validation_tests.rs rename to crates/a2a-protocol-server/tests/state_validation_tests.rs diff --git a/crates/a2a-server/tests/store_tests.rs b/crates/a2a-protocol-server/tests/store_tests.rs similarity index 100% rename from crates/a2a-server/tests/store_tests.rs rename to crates/a2a-protocol-server/tests/store_tests.rs diff --git a/crates/a2a-server/tests/streaming_tests.rs b/crates/a2a-protocol-server/tests/streaming_tests.rs similarity index 100% rename from crates/a2a-server/tests/streaming_tests.rs rename to crates/a2a-protocol-server/tests/streaming_tests.rs diff --git a/crates/a2a-server/tests/stress_tests.rs b/crates/a2a-protocol-server/tests/stress_tests.rs similarity index 100% rename from crates/a2a-server/tests/stress_tests.rs rename to crates/a2a-protocol-server/tests/stress_tests.rs diff --git a/crates/a2a-server/tests/tenant_sqlite_push_config_tests.rs b/crates/a2a-protocol-server/tests/tenant_sqlite_push_config_tests.rs similarity index 100% rename from crates/a2a-server/tests/tenant_sqlite_push_config_tests.rs rename to crates/a2a-protocol-server/tests/tenant_sqlite_push_config_tests.rs diff --git a/crates/a2a-server/tests/tenant_sqlite_store_tests.rs b/crates/a2a-protocol-server/tests/tenant_sqlite_store_tests.rs similarity index 100% rename from crates/a2a-server/tests/tenant_sqlite_store_tests.rs rename to crates/a2a-protocol-server/tests/tenant_sqlite_store_tests.rs diff --git a/crates/a2a-server/tests/tenant_store_tests.rs b/crates/a2a-protocol-server/tests/tenant_store_tests.rs similarity index 100% rename from crates/a2a-server/tests/tenant_store_tests.rs rename to crates/a2a-protocol-server/tests/tenant_store_tests.rs diff --git a/crates/a2a-server/tests/validation_edge_tests.rs b/crates/a2a-protocol-server/tests/validation_edge_tests.rs similarity index 100% rename from crates/a2a-server/tests/validation_edge_tests.rs rename to crates/a2a-protocol-server/tests/validation_edge_tests.rs diff --git a/crates/a2a-server/tests/websocket_tests.rs b/crates/a2a-protocol-server/tests/websocket_tests.rs similarity index 100% rename from crates/a2a-server/tests/websocket_tests.rs rename to crates/a2a-protocol-server/tests/websocket_tests.rs diff --git a/crates/a2a-types/Cargo.toml b/crates/a2a-protocol-types/Cargo.toml similarity index 86% rename from crates/a2a-types/Cargo.toml rename to crates/a2a-protocol-types/Cargo.toml index 6f2b419e..0593e243 100644 --- a/crates/a2a-types/Cargo.toml +++ b/crates/a2a-protocol-types/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "a2a-protocol-types" version = "0.5.1" -description = "A2A protocol v1.0 — pure data types, serde only, no I/O" +description = "Agent2Agent (A2A) protocol v1.0 — pure data types, serde only, no I/O" readme = "README.md" edition.workspace = true @@ -14,7 +14,7 @@ authors.workspace = true repository.workspace = true homepage.workspace = true documentation = "https://docs.rs/a2a-protocol-types" -keywords = ["a2a", "agent", "protocol", "types"] +keywords = ["a2a", "agent2agent", "agent", "protocol", "types"] categories = ["api-bindings"] [features] diff --git a/crates/a2a-types/README.md b/crates/a2a-protocol-types/README.md similarity index 100% rename from crates/a2a-types/README.md rename to crates/a2a-protocol-types/README.md diff --git a/crates/a2a-types/benches/json_serde.rs b/crates/a2a-protocol-types/benches/json_serde.rs similarity index 100% rename from crates/a2a-types/benches/json_serde.rs rename to crates/a2a-protocol-types/benches/json_serde.rs diff --git a/crates/a2a-types/src/agent_card.rs b/crates/a2a-protocol-types/src/agent_card.rs similarity index 100% rename from crates/a2a-types/src/agent_card.rs rename to crates/a2a-protocol-types/src/agent_card.rs diff --git a/crates/a2a-types/src/artifact.rs b/crates/a2a-protocol-types/src/artifact.rs similarity index 100% rename from crates/a2a-types/src/artifact.rs rename to crates/a2a-protocol-types/src/artifact.rs diff --git a/crates/a2a-types/src/error.rs b/crates/a2a-protocol-types/src/error.rs similarity index 100% rename from crates/a2a-types/src/error.rs rename to crates/a2a-protocol-types/src/error.rs diff --git a/crates/a2a-types/src/events.rs b/crates/a2a-protocol-types/src/events.rs similarity index 100% rename from crates/a2a-types/src/events.rs rename to crates/a2a-protocol-types/src/events.rs diff --git a/crates/a2a-types/src/extensions.rs b/crates/a2a-protocol-types/src/extensions.rs similarity index 100% rename from crates/a2a-types/src/extensions.rs rename to crates/a2a-protocol-types/src/extensions.rs diff --git a/crates/a2a-types/src/jsonrpc.rs b/crates/a2a-protocol-types/src/jsonrpc.rs similarity index 100% rename from crates/a2a-types/src/jsonrpc.rs rename to crates/a2a-protocol-types/src/jsonrpc.rs diff --git a/crates/a2a-types/src/lib.rs b/crates/a2a-protocol-types/src/lib.rs similarity index 100% rename from crates/a2a-types/src/lib.rs rename to crates/a2a-protocol-types/src/lib.rs diff --git a/crates/a2a-types/src/message.rs b/crates/a2a-protocol-types/src/message.rs similarity index 100% rename from crates/a2a-types/src/message.rs rename to crates/a2a-protocol-types/src/message.rs diff --git a/crates/a2a-types/src/params.rs b/crates/a2a-protocol-types/src/params.rs similarity index 100% rename from crates/a2a-types/src/params.rs rename to crates/a2a-protocol-types/src/params.rs diff --git a/crates/a2a-types/src/push.rs b/crates/a2a-protocol-types/src/push.rs similarity index 100% rename from crates/a2a-types/src/push.rs rename to crates/a2a-protocol-types/src/push.rs diff --git a/crates/a2a-types/src/responses.rs b/crates/a2a-protocol-types/src/responses.rs similarity index 100% rename from crates/a2a-types/src/responses.rs rename to crates/a2a-protocol-types/src/responses.rs diff --git a/crates/a2a-types/src/security.rs b/crates/a2a-protocol-types/src/security.rs similarity index 100% rename from crates/a2a-types/src/security.rs rename to crates/a2a-protocol-types/src/security.rs diff --git a/crates/a2a-types/src/serde_helpers.rs b/crates/a2a-protocol-types/src/serde_helpers.rs similarity index 100% rename from crates/a2a-types/src/serde_helpers.rs rename to crates/a2a-protocol-types/src/serde_helpers.rs diff --git a/crates/a2a-types/src/signing.rs b/crates/a2a-protocol-types/src/signing.rs similarity index 100% rename from crates/a2a-types/src/signing.rs rename to crates/a2a-protocol-types/src/signing.rs diff --git a/crates/a2a-types/src/task.rs b/crates/a2a-protocol-types/src/task.rs similarity index 100% rename from crates/a2a-types/src/task.rs rename to crates/a2a-protocol-types/src/task.rs diff --git a/crates/a2a-types/tests/corpus_json.rs b/crates/a2a-protocol-types/tests/corpus_json.rs similarity index 100% rename from crates/a2a-types/tests/corpus_json.rs rename to crates/a2a-protocol-types/tests/corpus_json.rs diff --git a/crates/a2a-types/tests/coverage_gap_tests.rs b/crates/a2a-protocol-types/tests/coverage_gap_tests.rs similarity index 100% rename from crates/a2a-types/tests/coverage_gap_tests.rs rename to crates/a2a-protocol-types/tests/coverage_gap_tests.rs diff --git a/crates/a2a-types/tests/proptest_types.proptest-regressions b/crates/a2a-protocol-types/tests/proptest_types.proptest-regressions similarity index 100% rename from crates/a2a-types/tests/proptest_types.proptest-regressions rename to crates/a2a-protocol-types/tests/proptest_types.proptest-regressions diff --git a/crates/a2a-types/tests/proptest_types.rs b/crates/a2a-protocol-types/tests/proptest_types.rs similarity index 100% rename from crates/a2a-types/tests/proptest_types.rs rename to crates/a2a-protocol-types/tests/proptest_types.rs diff --git a/crates/a2a-types/tests/serde_edge_cases.rs b/crates/a2a-protocol-types/tests/serde_edge_cases.rs similarity index 100% rename from crates/a2a-types/tests/serde_edge_cases.rs rename to crates/a2a-protocol-types/tests/serde_edge_cases.rs diff --git a/crates/a2a-types/tests/signing_tests.rs b/crates/a2a-protocol-types/tests/signing_tests.rs similarity index 100% rename from crates/a2a-types/tests/signing_tests.rs rename to crates/a2a-protocol-types/tests/signing_tests.rs diff --git a/crates/a2a-types/tests/state_transition_tests.rs b/crates/a2a-protocol-types/tests/state_transition_tests.rs similarity index 100% rename from crates/a2a-types/tests/state_transition_tests.rs rename to crates/a2a-protocol-types/tests/state_transition_tests.rs diff --git a/crates/a2a-types/tests/tck_wire_format.rs b/crates/a2a-protocol-types/tests/tck_wire_format.rs similarity index 99% rename from crates/a2a-types/tests/tck_wire_format.rs rename to crates/a2a-protocol-types/tests/tck_wire_format.rs index 9587dbd3..ae06f969 100644 --- a/crates/a2a-types/tests/tck_wire_format.rs +++ b/crates/a2a-protocol-types/tests/tck_wire_format.rs @@ -7,7 +7,7 @@ //! //! These tests validate that this SDK's serialization and deserialization of A2A //! v1.0 types matches the canonical wire format defined by the official A2A -//! specification (). +//! specification (). //! //! Each test uses a **golden JSON fixture** — the exact JSON that compliant //! implementations MUST produce or accept. Tests verify: diff --git a/docs/adr/0007-axum-integration-and-tck.md b/docs/adr/0007-axum-integration-and-tck.md index 90e1a3b3..96f71e46 100644 --- a/docs/adr/0007-axum-integration-and-tck.md +++ b/docs/adr/0007-axum-integration-and-tck.md @@ -27,7 +27,7 @@ Two gaps were identified during the SDK audit: ### TCK Wire Format Conformance Tests -Add a dedicated test file (`crates/a2a-types/tests/tck_wire_format.rs`) with +Add a dedicated test file (`crates/a2a-protocol-types/tests/tck_wire_format.rs`) with golden JSON fixtures representing the canonical A2A v1.0 wire format. Tests validate: @@ -41,7 +41,7 @@ validate: ### Axum Framework Integration -Add a feature-gated `axum` module (`crates/a2a-server/src/dispatch/axum_adapter.rs`) +Add a feature-gated `axum` module (`crates/a2a-protocol-server/src/dispatch/axum_adapter.rs`) that provides `A2aRouter` — a thin adapter that builds an `axum::Router` wrapping the existing `RequestHandler`. Design principles: diff --git a/docs/adr/0008-agent-executor-trait-shape.md b/docs/adr/0008-agent-executor-trait-shape.md index 85bb92fc..a47ece2f 100644 --- a/docs/adr/0008-agent-executor-trait-shape.md +++ b/docs/adr/0008-agent-executor-trait-shape.md @@ -182,7 +182,7 @@ agent_executor!(EchoAgent, |ctx, queue| async move { ``` The macro expands to the full trait impl including the default `cancel` -and `on_shutdown` methods. In `crates/a2a-server/src/handler/lifecycle/` +and `on_shutdown` methods. In `crates/a2a-protocol-server/src/handler/lifecycle/` every test fixture uses the macro form — `DummyExecutor`, `CancelableExecutor`, etc. For production executors with more than trivial logic, `boxed_future` is the idiomatic choice: it preserves the imperative diff --git a/docs/implementation/plan.md b/docs/implementation/plan.md index 819fd6de..f99fe0ec 100644 --- a/docs/implementation/plan.md +++ b/docs/implementation/plan.md @@ -17,20 +17,20 @@ All proposed beyond-spec features have been implemented: | Feature | Location | Details | |---|---|---| -| **OpenTelemetry integration** | `crates/a2a-server/src/otel/` | `OtelMetrics` with OTLP export via `opentelemetry-otlp`; feature-gated under `otel` | -| **Connection pooling metrics** | `crates/a2a-server/src/metrics.rs` | `ConnectionPoolStats` struct; `on_connection_pool_stats` on `Metrics` trait | -| **Hot-reload agent cards** | `crates/a2a-server/src/agent_card/hot_reload.rs` | `HotReloadAgentCardHandler` with file polling and SIGHUP reload | -| **Store migration tooling** | `crates/a2a-server/src/store/migration.rs` | `MigrationRunner` with `BUILTIN_MIGRATIONS` (V1–V3), `schema_versions` table | -| **Per-tenant configuration** | `crates/a2a-server/src/tenant_config.rs` | `PerTenantConfig`, `TenantLimits` with per-tenant overrides | -| **TenantResolver trait** | `crates/a2a-server/src/tenant_resolver.rs` | `HeaderTenantResolver`, `BearerTokenTenantResolver`, `PathSegmentTenantResolver` | +| **OpenTelemetry integration** | `crates/a2a-protocol-server/src/otel/` | `OtelMetrics` with OTLP export via `opentelemetry-otlp`; feature-gated under `otel` | +| **Connection pooling metrics** | `crates/a2a-protocol-server/src/metrics.rs` | `ConnectionPoolStats` struct; `on_connection_pool_stats` on `Metrics` trait | +| **Hot-reload agent cards** | `crates/a2a-protocol-server/src/agent_card/hot_reload.rs` | `HotReloadAgentCardHandler` with file polling and SIGHUP reload | +| **Store migration tooling** | `crates/a2a-protocol-server/src/store/migration.rs` | `MigrationRunner` with `BUILTIN_MIGRATIONS` (V1–V3), `schema_versions` table | +| **Per-tenant configuration** | `crates/a2a-protocol-server/src/tenant_config.rs` | `PerTenantConfig`, `TenantLimits` with per-tenant overrides | +| **TenantResolver trait** | `crates/a2a-protocol-server/src/tenant_resolver.rs` | `HeaderTenantResolver`, `BearerTokenTenantResolver`, `PathSegmentTenantResolver` | | **Agent card signing E2E** | `examples/agent-team/src/tests/coverage_gaps.rs` | `test_agent_card_signing` with ES256 key generation (`#[cfg(feature = "signing")]`) | -| **Request ID propagation** | `crates/a2a-server/src/call_context.rs` | `CallContext::request_id` auto-extracted from `X-Request-ID` header | -| **Metrics hooks** | `crates/a2a-server/src/metrics.rs` | `Metrics` trait: `on_request`, `on_response`, `on_error`, `on_latency`, `on_queue_depth_change` | -| **Rate limiting** | `crates/a2a-server/src/rate_limit.rs` | `RateLimitInterceptor` with fixed-window per-caller counters | -| **gRPC transport** | `crates/a2a-server/src/dispatch/grpc/` | `GrpcDispatcher` + `GrpcTransport` via `tonic` (`grpc` feature) | -| **WebSocket transport** | `crates/a2a-server/src/dispatch/websocket.rs` | `WebSocketDispatcher` + `WebSocketTransport` via `tokio-tungstenite` (`websocket` feature) | -| **Multi-tenancy** | `crates/a2a-server/src/store/tenant/` | In-memory via `task_local!`, SQLite via `tenant_id` column partitioning | -| **Persistent task store** | `crates/a2a-server/src/store/sqlite_store.rs` | `SqliteTaskStore` + `SqlitePushConfigStore` behind `sqlite` feature flag | +| **Request ID propagation** | `crates/a2a-protocol-server/src/call_context.rs` | `CallContext::request_id` auto-extracted from `X-Request-ID` header | +| **Metrics hooks** | `crates/a2a-protocol-server/src/metrics.rs` | `Metrics` trait: `on_request`, `on_response`, `on_error`, `on_latency`, `on_queue_depth_change` | +| **Rate limiting** | `crates/a2a-protocol-server/src/rate_limit.rs` | `RateLimitInterceptor` with fixed-window per-caller counters | +| **gRPC transport** | `crates/a2a-protocol-server/src/dispatch/grpc/` | `GrpcDispatcher` + `GrpcTransport` via `tonic` (`grpc` feature) | +| **WebSocket transport** | `crates/a2a-protocol-server/src/dispatch/websocket.rs` | `WebSocketDispatcher` + `WebSocketTransport` via `tokio-tungstenite` (`websocket` feature) | +| **Multi-tenancy** | `crates/a2a-protocol-server/src/store/tenant/` | In-memory via `task_local!`, SQLite via `tenant_id` column partitioning | +| **Persistent task store** | `crates/a2a-protocol-server/src/store/sqlite_store.rs` | `SqliteTaskStore` + `SqlitePushConfigStore` behind `sqlite` feature flag | See the book's [Configuration Reference](../../book/src/reference/configuration.md) for usage details. @@ -288,7 +288,7 @@ impl A2aClient { Every file listed with its responsibility and actual line count. No source file exceeds 500 lines. -### `crates/a2a-types/` (4,098 lines) +### `crates/a2a-protocol-types/` (4,098 lines) ``` Cargo.toml [~37 lines] serde + serde_json; optional base64 + ring (signing feature) @@ -314,7 +314,7 @@ benches/ json_serde.rs [122 lines] 5 criterion benchmarks: AgentCard/Task serialize+deserialize, Message serialize ``` -### `crates/a2a-client/` (3,909 lines) +### `crates/a2a-protocol-client/` (3,909 lines) > **Note:** Several monolithic files listed below have since been refactored into > submodule directories (e.g., `rest.rs` → `rest/{mod, routing, query, request, streaming}.rs`, @@ -353,7 +353,7 @@ benches/ sse_parse.rs [71 lines] 3 criterion benchmarks: single/batch/fragmented SSE parsing ``` -### `crates/a2a-server/` (5,399 lines) +### `crates/a2a-protocol-server/` (5,399 lines) > **Note:** Several monolithic files listed below have since been refactored into > submodule directories (e.g., `dispatch/rest.rs` → `dispatch/rest/{mod, response, query}.rs`, @@ -398,7 +398,7 @@ src/ task_store.rs [156 lines] TaskStore trait, InMemoryTaskStore (with list filtering) ``` -### `crates/a2a-sdk/` (83 lines) +### `crates/a2a-protocol-sdk/` (83 lines) ``` Cargo.toml [~24 lines] re-exports all workspace crates @@ -419,7 +419,7 @@ echo-agent/ ### Integration Tests (2,022 lines) ``` -crates/a2a-server/tests/ +crates/a2a-protocol-server/tests/ handler_tests.rs [907 lines] 24 tests: EchoExecutor, FailingExecutor, CancelableExecutor, RejectInterceptor, send/get/list/cancel/resubscribe/push config CRUD, return_immediately, context/task mismatch, interceptor rejection @@ -706,7 +706,7 @@ Files: `agent_card/caching.rs`, `agent_card/static_handler.rs`, `agent_card/dyna | Signature verification | ✅ `verify_agent_card()` with public key DER | | Feature-gated | ✅ Behind `signing` feature flag (`ring` + `base64` deps) | -Files: `crates/a2a-types/src/signing.rs` +Files: `crates/a2a-protocol-types/src/signing.rs` #### 8C. Quality & Release Tasks @@ -741,7 +741,7 @@ Files: `crates/a2a-types/src/signing.rs` | Echo-agent `tracing-subscriber` setup | ✅ Optional via `tracing` feature, `RUST_LOG` env filter | | SDK umbrella feature | ✅ `a2a-protocol-sdk/tracing` enables both client + server tracing | -Files: `crates/a2a-client/src/trace.rs`, `crates/a2a-server/src/trace.rs` +Files: `crates/a2a-protocol-client/src/trace.rs`, `crates/a2a-protocol-server/src/trace.rs` #### 9B. TLS Support (`tls-rustls` feature) ✅ @@ -757,7 +757,7 @@ Files: `crates/a2a-client/src/trace.rs`, `crates/a2a-server/src/trace.rs` | SDK umbrella feature | ✅ `a2a-protocol-sdk/tls-rustls` enables client TLS | | Unit tests | ✅ 4 tests: config creation, client creation, custom roots | -Files: `crates/a2a-client/src/tls.rs` +Files: `crates/a2a-protocol-client/src/tls.rs` #### 9C. CI Pipeline Hardening ✅ @@ -803,7 +803,7 @@ Files: `.github/workflows/ci.yml` ### Test Organization - Unit tests: `#[cfg(test)]` modules inside each source file -- Integration tests: `crates/a2a-server/tests/` directory +- Integration tests: `crates/a2a-protocol-server/tests/` directory - End-to-end validation: `examples/echo-agent` (runs all transport paths) ### Test Naming Convention diff --git a/docs/implementation/spec-compliance-gaps.md b/docs/implementation/spec-compliance-gaps.md index cc9401cb..027a365e 100644 --- a/docs/implementation/spec-compliance-gaps.md +++ b/docs/implementation/spec-compliance-gaps.md @@ -40,7 +40,7 @@ These produce or expect incorrect JSON and MUST be fixed before any public relea ### C1. `TaskState::Pending` should be `Submitted` -**File:** `crates/a2a-types/src/task.rs` +**File:** `crates/a2a-protocol-types/src/task.rs` Our variant `Pending` serializes as `"TASK_STATE_PENDING"`. The proto and JSON schema both define value 1 as `TASK_STATE_SUBMITTED`. @@ -60,7 +60,7 @@ Submitted, ### C2. `SecurityRequirements` type structure is wrong -**File:** `crates/a2a-types/src/security.rs` +**File:** `crates/a2a-protocol-types/src/security.rs` Our type alias: ```rust @@ -104,7 +104,7 @@ pub struct SecurityRequirement { ### C3. `AgentCard.security` field name → `securityRequirements` -**File:** `crates/a2a-types/src/agent_card.rs:188` +**File:** `crates/a2a-protocol-types/src/agent_card.rs:188` ```rust // CURRENT (serializes as "security"): @@ -118,7 +118,7 @@ pub security_requirements: Option>, ### C4. `AgentSkill.security` field name → `securityRequirements` -**File:** `crates/a2a-types/src/agent_card.rs:129` +**File:** `crates/a2a-protocol-types/src/agent_card.rs:129` Same issue as C3 but on `AgentSkill`. @@ -138,7 +138,7 @@ These represent incomplete API surface. Other SDKs can send values we can't pars ### H1. `MessageRole` missing `ROLE_UNSPECIFIED` -**File:** `crates/a2a-types/src/message.rs` +**File:** `crates/a2a-protocol-types/src/message.rs` Proto defines three values; we only have two: @@ -158,7 +158,7 @@ Unspecified, ### H3. `PasswordOAuthFlow` missing -**File:** `crates/a2a-types/src/security.rs` +**File:** `crates/a2a-protocol-types/src/security.rs` Proto and JSON schema both define `PasswordOAuthFlow` (deprecated but present). Our `OAuthFlows` struct is missing the `password` field. @@ -182,7 +182,7 @@ pub struct PasswordOAuthFlow { ### H4. No `ListPushConfigsParams` struct -**File:** `crates/a2a-types/src/params.rs` +**File:** `crates/a2a-protocol-types/src/params.rs` Proto defines `ListTaskPushNotificationConfigsRequest` with `task_id`, `page_size`, `page_token`, and `tenant`. Our client uses inline `serde_json::json!()` instead. @@ -203,7 +203,7 @@ pub struct ListPushConfigsParams { ### H5. `list_push_configs` return type lacks pagination -**File:** `crates/a2a-client/src/methods/push_config.rs` +**File:** `crates/a2a-protocol-client/src/methods/push_config.rs` Proto `ListTaskPushNotificationConfigsResponse` includes `next_page_token`. Our client returns `Vec`, discarding pagination. @@ -215,7 +215,7 @@ Proto `ListTaskPushNotificationConfigsResponse` includes `next_page_token`. Our ### L1. `AgentCapabilities.state_transition_history` not in spec -**File:** `crates/a2a-types/src/agent_card.rs:63` +**File:** `crates/a2a-protocol-types/src/agent_card.rs:63` We added this in Phase 7 but it does not appear in the proto or JSON schema. With `skip_serializing_if = "Option::is_none"` it's harmless — it won't appear on the wire when `None`, and will be silently ignored by other SDKs if set. **Remove to avoid confusion.** diff --git a/docs/implementation/type-mapping.md b/docs/implementation/type-mapping.md index d8bb7c37..ec591355 100644 --- a/docs/implementation/type-mapping.md +++ b/docs/implementation/type-mapping.md @@ -2,8 +2,8 @@ > **Updated** — This document has been updated to reflect A2A v1.0.0 types. > For the authoritative wire format, see: -> - The actual serde attributes in `crates/a2a-types/src/*.rs` -> - The TCK conformance tests in `crates/a2a-types/tests/tck_wire_format.rs` +> - The actual serde attributes in `crates/a2a-protocol-types/src/*.rs` +> - The TCK conformance tests in `crates/a2a-protocol-types/tests/tck_wire_format.rs` > - The spec compliance verification in `docs/implementation/spec-compliance-gaps.md` Complete field-by-field mapping from A2A v1.0.0 JSON schema to Rust types. diff --git a/examples/agent-team/Cargo.toml b/examples/agent-team/Cargo.toml index 9e23c9e5..b12b8217 100644 --- a/examples/agent-team/Cargo.toml +++ b/examples/agent-team/Cargo.toml @@ -43,9 +43,9 @@ axum = ["a2a-protocol-server/axum", "dep:axum"] sqlite = ["a2a-protocol-server/sqlite"] [dependencies] -a2a-protocol-types = { path = "../../crates/a2a-types" } -a2a-protocol-client = { path = "../../crates/a2a-client" } -a2a-protocol-server = { path = "../../crates/a2a-server" } +a2a-protocol-types = { path = "../../crates/a2a-protocol-types" } +a2a-protocol-client = { path = "../../crates/a2a-protocol-client" } +a2a-protocol-server = { path = "../../crates/a2a-protocol-server" } tracing = { workspace = true, optional = true } tracing-subscriber = { version = ">=0.3.18, <0.4", features = ["env-filter"], optional = true } diff --git a/examples/echo-agent/Cargo.toml b/examples/echo-agent/Cargo.toml index 6c887314..aeaf9694 100644 --- a/examples/echo-agent/Cargo.toml +++ b/examples/echo-agent/Cargo.toml @@ -16,9 +16,9 @@ license.workspace = true tracing = ["a2a-protocol-client/tracing", "a2a-protocol-server/tracing", "dep:tracing", "dep:tracing-subscriber"] [dependencies] -a2a-protocol-types = { path = "../../crates/a2a-types" } -a2a-protocol-client = { path = "../../crates/a2a-client" } -a2a-protocol-server = { path = "../../crates/a2a-server" } +a2a-protocol-types = { path = "../../crates/a2a-protocol-types" } +a2a-protocol-client = { path = "../../crates/a2a-protocol-client" } +a2a-protocol-server = { path = "../../crates/a2a-protocol-server" } tracing = { workspace = true, optional = true } tracing-subscriber = { version = ">=0.3.18, <0.4", features = ["env-filter"], optional = true } diff --git a/examples/genai-agent/Cargo.toml b/examples/genai-agent/Cargo.toml index 595a3cac..48b65bbd 100644 --- a/examples/genai-agent/Cargo.toml +++ b/examples/genai-agent/Cargo.toml @@ -12,8 +12,8 @@ rust-version.workspace = true license.workspace = true [dependencies] -a2a-protocol-types = { path = "../../crates/a2a-types" } -a2a-protocol-server = { path = "../../crates/a2a-server" } +a2a-protocol-types = { path = "../../crates/a2a-protocol-types" } +a2a-protocol-server = { path = "../../crates/a2a-protocol-server" } serde_json = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros", "net", "time", "signal"] } diff --git a/examples/multi-lang-team/Cargo.toml b/examples/multi-lang-team/Cargo.toml index 9c3a10f5..80749496 100644 --- a/examples/multi-lang-team/Cargo.toml +++ b/examples/multi-lang-team/Cargo.toml @@ -12,9 +12,9 @@ rust-version.workspace = true license.workspace = true [dependencies] -a2a-protocol-types = { path = "../../crates/a2a-types" } -a2a-protocol-client = { path = "../../crates/a2a-client" } -a2a-protocol-server = { path = "../../crates/a2a-server" } +a2a-protocol-types = { path = "../../crates/a2a-protocol-types" } +a2a-protocol-client = { path = "../../crates/a2a-protocol-client" } +a2a-protocol-server = { path = "../../crates/a2a-protocol-server" } serde_json = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros", "net", "time", "signal"] } diff --git a/examples/rig-agent/Cargo.toml b/examples/rig-agent/Cargo.toml index 7b27e1f5..c3cccf3e 100644 --- a/examples/rig-agent/Cargo.toml +++ b/examples/rig-agent/Cargo.toml @@ -12,9 +12,9 @@ rust-version.workspace = true license.workspace = true [dependencies] -a2a-protocol-types = { path = "../../crates/a2a-types" } -a2a-protocol-client = { path = "../../crates/a2a-client" } -a2a-protocol-server = { path = "../../crates/a2a-server" } +a2a-protocol-types = { path = "../../crates/a2a-protocol-types" } +a2a-protocol-client = { path = "../../crates/a2a-protocol-client" } +a2a-protocol-server = { path = "../../crates/a2a-protocol-server" } serde_json = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros", "net", "time", "signal"] } diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index f799b2fb..4d480d43 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -12,7 +12,7 @@ cargo-fuzz = true [dependencies] libfuzzer-sys = "0.4" -a2a-protocol-types = { path = "../crates/a2a-types" } +a2a-protocol-types = { path = "../crates/a2a-protocol-types" } serde_json = "1" # Prevent this from interfering with the workspace diff --git a/mutants.toml b/mutants.toml index 0b3012a6..39be4582 100644 --- a/mutants.toml +++ b/mutants.toml @@ -35,17 +35,17 @@ jobs = 4 # indirectly by the dogfood test suite but are not the subject of mutation # testing (their code is demonstration, not library surface area). examine_globs = [ - "crates/a2a-types/src/**/*.rs", - "crates/a2a-client/src/**/*.rs", - "crates/a2a-server/src/**/*.rs", - "crates/a2a-sdk/src/**/*.rs", + "crates/a2a-protocol-types/src/**/*.rs", + "crates/a2a-protocol-client/src/**/*.rs", + "crates/a2a-protocol-server/src/**/*.rs", + "crates/a2a-protocol-sdk/src/**/*.rs", ] # ── Exclusions ─────────────────────────────────────────────────────────────── # Thin re-export modules: mutating `pub use` re-exports produces false # positives because they are tested indirectly through the public API. exclude_globs = [ - "crates/a2a-sdk/src/lib.rs", # pure re-exports + "crates/a2a-protocol-sdk/src/lib.rs", # pure re-exports "**/mod.rs", # thin mod files (re-exports only) "crates/*/src/proto/**", # generated protobuf code ] diff --git a/tck/Cargo.toml b/tck/Cargo.toml index b9870c8c..8fffcde8 100644 --- a/tck/Cargo.toml +++ b/tck/Cargo.toml @@ -16,8 +16,8 @@ name = "a2a-tck" path = "src/main.rs" [dependencies] -a2a-protocol-types = { path = "../crates/a2a-types" } -a2a-protocol-client = { path = "../crates/a2a-client" } +a2a-protocol-types = { path = "../crates/a2a-protocol-types" } +a2a-protocol-client = { path = "../crates/a2a-protocol-client" } serde_json = { workspace = true } serde = { workspace = true }