Skip to content

feat(a2a): upgrade a2a-sdk from >=0.3.4,<0.4 to >=1.0,<2 (A2A 1.0 spec)#5917

Open
waadarsh wants to merge 2 commits into
google:mainfrom
waadarsh:feat/upgrade-a2a-sdk-1x
Open

feat(a2a): upgrade a2a-sdk from >=0.3.4,<0.4 to >=1.0,<2 (A2A 1.0 spec)#5917
waadarsh wants to merge 2 commits into
google:mainfrom
waadarsh:feat/upgrade-a2a-sdk-1x

Conversation

@waadarsh
Copy link
Copy Markdown

@waadarsh waadarsh commented May 31, 2026

Summary

  • Upgrades `a2a-sdk` dependency from `>=0.3.4,<0.4` to `>=1.0,<2` (A2A 1.0 spec)
  • Migrates all A2A integration code from Pydantic-based types to Protocol Buffer (proto) types
  • Updates 16 source files and 15 test files across converters, executor, utils, and agent modules

Fixes #5056

Key changes

  • `Part` type: `TextPart`/`DataPart`/`FilePart` → flat proto `Part` with `WhichOneof("content")`
  • Enum prefixes: `TaskState.working` → `TASK_STATE_WORKING`, `Role.agent` → `ROLE_AGENT`
  • `TaskStatus.timestamp`: string `.isoformat()` → proto `Timestamp.FromDatetime()`
  • `AgentCard.url` → `supported_interfaces` list with `AgentInterface` (A2A 1.0 schema)
  • `A2AStarletteApplication` → `create_agent_card_routes()` / `create_jsonrpc_routes()` / `create_rest_routes()`
  • `DefaultRequestHandler` now requires `agent_card=` argument
  • `ClientCallContext`: `a2a.client.middleware` → `a2a.client.client`
  • `send_message()` now takes `SendMessageRequest` proto and yields `StreamResponse`
  • proto Struct metadata: use `"in"` + subscript instead of `.get()`
  • v1 SDK requires `Task` enqueued before `TaskStatusUpdateEvent`
  • `part_metadata` propagation preserved from GenAI ↔ A2A part conversions
  • Auth-required support: `MOCK_FUNCTION_CALL_FOR_REQUIRED_USER_AUTH` with `auth_required` args key

Test plan

```
uv run pytest tests/unittests/a2a/ -q
```

```
314 passed, 0 skipped, 0 failed
```

  • All previously skipped tests now pass using `add_a2a_routes_to_fastapi` (v1 equivalent of removed `A2AFastAPIApplication`)
  • Includes 13 new tests added to `main` after branching (auth-required, part_metadata round-trips, type validation)
  • Pylint score: 9.30/10 on all changed source files (baseline was 9.39/10 before migration)

@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label May 31, 2026
@rohityan rohityan self-assigned this Jun 5, 2026
@waadarsh waadarsh marked this pull request as draft June 5, 2026 07:44
waadarsh added 2 commits June 5, 2026 13:17
Migrates all A2A integration code and tests from the Pydantic-based
a2a-sdk 0.3.x API to the Protocol Buffer (proto) based a2a-sdk 1.x
API, implementing the A2A 1.0 specification.

Breaking changes addressed:

- Part types: TextPart/DataPart/FilePart replaced by flat proto Part
  with WhichOneof("content") oneof pattern (text, url, raw, data)
- Enum prefixes: TaskState.working -> TASK_STATE_WORKING,
  Role.agent -> ROLE_AGENT (all enums now SCREAMING_SNAKE_CASE)
- Timestamps: TaskStatus.timestamp is now proto Timestamp
  (use .FromDatetime() instead of .isoformat() string)
- TaskStatusUpdateEvent.final field removed; finality via task state
- AgentCard.url moved to supported_interfaces list (AgentInterface)
  with protocolBinding + protocolVersion fields (A2A 1.0 schema)
- A2AStarletteApplication removed; replaced by create_agent_card_routes(),
  create_jsonrpc_routes(), create_rest_routes() builders
- DefaultRequestHandler now requires agent_card= constructor argument
- ClientCallContext moved: a2a.client.middleware -> a2a.client.client
- ClientConfig.supported_transports -> supported_protocol_bindings
- TransportProtocol enum values now uppercase (JSONRPC, HTTP_JSON)
- Client send_message() takes SendMessageRequest proto and yields
  StreamResponse (use .WhichOneof("payload") to dispatch)
- proto Struct metadata: use "in" + subscript instead of .get()
- AgentCard construction: use json_format.ParseDict() not **dict
- v1 SDK requires Task enqueued before TaskStatusUpdateEvent

Files changed: pyproject.toml, 16 source files, 15 test files

All 299 a2a unit + integration tests pass (2 skipped for removed
A2AFastAPIApplication which has no 1.x equivalent).

Fixes google#5056
Replace A2AFastAPIApplication (removed in a2a-sdk v1) with
FastAPI + add_a2a_routes_to_fastapi in the two input_required
follow-up tests. Also fix proto Task construction (remove 'kind'
field, use Role.ROLE_USER enum).

All 301 a2a tests now pass with 0 skipped.
@waadarsh waadarsh force-pushed the feat/upgrade-a2a-sdk-1x branch from f2273a3 to 5987e3f Compare June 5, 2026 07:48
@waadarsh waadarsh marked this pull request as ready for review June 5, 2026 07:48
@adk-bot
Copy link
Copy Markdown
Collaborator

adk-bot commented Jun 5, 2026

🔍 ADK Pull Request Analysis: PR #5917

Title: feat(a2a): upgrade a2a-sdk from >=0.3.4,<0.4 to >=1.0,<2 (A2A 1.0 spec)
Author: @waadarsh
Status: OPEN
Impact: 2,617 additions, 4,088 deletions across 32 files


Executive Summary

  1. Core Objective: Upgrade the a2a-sdk dependency from standard 0.3.x to 1.0 (A2A 1.0 spec) and migrate all ADK A2A integration code from Pydantic-based schemas to official Protobuf types.
  2. Justification & Value: [Valuable Feature / Justified Fix] - Essential upgrade that aligns the ADK adapter with the stable A2A 1.0 specification, enabling cleaner Protobuf payload exchanges, streaming-friendly interfaces (StreamResponse), and significantly faster type processing compared to old Pydantic dynamic validation loops.
  3. Alignment with Principles: [Pass] - The PR preserves full backwards compatibility for the public to_a2a API, strictly uses from __future__ import annotations, structures imports and visibility limits perfectly, logs via lazy eval (%), and presents highly clean, streamlined tests.
  4. Recommendation: Approve
Detailed Findings & Analysis

1. Objectives & Impact ("What does it do?")

  • Context & Background: Resolves linked Issue #5056. Users were blocked from migrating to a2a-sdk version 1.0 due to major breaking changes and types redesign in A2A's core protocol schemas.
  • Implementation Mechanism:
    • Migrates old nested dynamic Pydantic structures (TextPart, FilePart, DataPart) into the flat A2A Protobuf Part representation utilizing a clean WhichOneof("content") validation system.
    • Redesigns agent_card_builder.py to build proto-based AgentCard objects where url, preferred_transport, and protocol_version are handled elegantly under a supported_interfaces array (AgentInterface).
    • Swaps out deprecated endpoint/starlette application classes (A2AStarletteApplication) inside agent_to_a2a.py in favor of Starlette's decoupled route generators (create_agent_card_routes, create_jsonrpc_routes, create_rest_routes).
    • Adapts remote_a2a_agent.py to communicate using standard SendMessageRequest headers and generator-friendly StreamResponse payloads.
    • Replaces all legacy Pydantic .model_dump(by_alias=True) occurrences with standard google.protobuf.json_format.MessageToDict() and MessageToJson() serialization utilities.
  • Affected Surface: None of the changes introduce a breaking change to public ADK interface methods or caller-facing attributes. Backward compatibility is successfully kept intact.

2. Justification & Value ("Is it a valid and useful change?")

  • Workspace Verification:
    • Investigated agent_to_a2a.py and part_converter.py in the active workspace.
    • Found that the baseline main codebase directly utilized Pydantic .model_dump structures and subclass constructs. This design would instantly fail compile/runtime checks with the new a2a-sdk version.
  • Value Assessment: Highly valuable. Moving to precompiled C-backed Protobuf types enhances runtime efficiency, enforces rigid contract validation across languages, and satisfies the underlying A2A stable schema specifications.
  • Alternative Approaches: Code structure perfectly represents the layout defined in the official A2A v1.0 migration manual. Moving away from the dense Starlette custom Application class to modular, independent route functions is an elegant, future-proof approach.
  • Scope & Depth: Systematic Fix & Root Cause Resolution - Fully updates all parts, events, executors, clients, registry parameters, log formatting tools, and unit tests (removing ~3000 lines of obsolete mock logic).

3. Principle & Style Alignment Checklist ("Does it follow rules?")

  • Public API & Visibility Boundaries:
    • Status: Pass
    • Analysis: Public interfaces like to_a2a are maintained and stable. No internal helper classes are leaked. Code imports remain fully encapsulated.
  • Code Quality, Typing & Conventions:
    • Status: Pass
    • Analysis: Every modified target file includes from __future__ import annotations following the standard license blocks. Type inputs/returns are strongly guarded, modern union syntax X | None is prioritized, and logging utilizes formatting templates (such as %s lazy formatting) rather than eager f-strings (e.g. inside log_utils.py).
  • Robustness & Edge Cases:
    • Status: Pass
    • Analysis: Part encoding gracefully employs fallback JSON-formatted tagged inline data serialization (inside part_converter.py) to round-trip complex unrecognized types without hard crashing client applications.
  • Test Integrity & Quality:
    • Status: Pass
    • Analysis: 15 test files have been streamlined. Protobuf structures let developers assert on typed properties cleanly, drastically reducing complex mocking lines. Unit tests leverage clear Arrange-Act-Assert logical structures.

Analysis Summary & Conclusion

The proposed PR is highly complete, fully compliant with ADK styling/architectural requirements, and ready for immediate merging. All Google CLA signatures have been verified and validated successfully. Under testing conditions, the modified code generates sound execution behaviors.

  • Recommended Action: Approve without additional nits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade a2a-sdk dependency to support A2A 1.0 spec

3 participants