Skip to content

chore: remove the use of deprecated types from VertexTaskStore for the 1.0 branch#890

Closed
gaborfeher wants to merge 120 commits intoa2aproject:mainfrom
gaborfeher:gaborfeher-1.0-types
Closed

chore: remove the use of deprecated types from VertexTaskStore for the 1.0 branch#890
gaborfeher wants to merge 120 commits intoa2aproject:mainfrom
gaborfeher:gaborfeher-1.0-types

Conversation

@gaborfeher
Copy link
Copy Markdown
Collaborator

  • vertexai.Part & co. will be replaced soon by genai.Part & co.
  • It's better to use the more specifically named variants of Task and Status: A2aTask and A2aTaskStatus.

For #802

lkawka and others added 30 commits November 13, 2025 11:12
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Co-authored-by: Yaroslav <yarolegovich@gmail.com>
Co-authored-by: Agent2Agent (A2A) Bot <a2a-bot@google.com>
Co-authored-by: agil.yolchuyev <agilyolchuyev@outlook.com>
Co-authored-by: yolagil <agil@peotic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Holt Skinner <13262395+holtskinner@users.noreply.github.com>
Co-authored-by: Luca Muscariello <muscariello@ieee.org>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…the specification (a2aproject#511)

Commit:
a2aproject/A2A@0a9f629

This PR introduces support for the new `tasks/list` method, including:
- Automatically generated type definitions from the specification.
- Complete client-side and server-side implementations.

Fixes a2aproject#515 🦕

---------

Co-authored-by: lkawka <lkawka@google.com>
Co-authored-by: lkawka <luk.kawka@gmail.com>
Co-authored-by: Holt Skinner <13262395+holtskinner@users.noreply.github.com>
Co-authored-by: Iva Sokolaj <102302011+sokoliva@users.noreply.github.com>
Co-authored-by: Agent2Agent (A2A) Bot <a2a-bot@google.com>
Co-authored-by: Tadaki Asechi <127199356+TadakiAsechi@users.noreply.github.com>
Co-authored-by: tadaki <tadaki.asechi@gmail.com>
Co-authored-by: Holt Skinner <13262395+holtskinner@users.noreply.github.com>
Co-authored-by: TadakiAsechi <tadaki.asechi@icould.com>
Co-authored-by: TadakiAsechi <tadaki.asechi@iclould.com>
## Summary

This PR migrates the a2a-python SDK from Pydantic-based types to
protobuf-generated types, completing the upgrade to A2A v1.0. Fixes a2aproject#559

## Breaking Changes

- Replace Pydantic-based type system with protobuf types from `a2a_pb2`
- Update `Part` usage from `Part(root=TextPart(text=...))` to
`Part(text=...)`
- Update `Role` enum from `Role.user`/`Role.agent` to
`Role.ROLE_USER`/`Role.ROLE_AGENT`
- Update `TaskState` enum to use `TASK_STATE_*` prefix

## Changes

- Update all source files to use proto types directly from `a2a_pb2`
- Replace `model_dump()` with `MessageToDict()` for JSON serialization
- Replace `model_copy(deep=True)` with `CopyFrom()` for proto cloning
- Add new types module with proto imports and SDK-specific extras
- Add `proto_utils` module with identity conversion utilities
- Fix REST handler resource name formats for push notification configs
- Fix gRPC handler to use `SubscribeToTask` instead of
`TaskSubscription`
- Fix database task store to handle proto objects from ORM
- Update all test files for proto patterns and assertions
- Fix spelling check failures by updating allow list
- Fix inclusive language check failures:
    - Replace `master` with `main` in documentation
    - Rename `Dummy` classes to `Mock` in tests

## Testing

- **601 tests passing**
- 23 tests skipped (expected - require DB connections or cryptography
deps)

## Related

Builds on top of PR a2aproject#556

Release-As: 1.0.0

---------

Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Sam Betts <1769706+Tehsmash@users.noreply.github.com>
Co-authored-by: Lukasz Kawka <luk.kawka@gmail.com>
Co-authored-by: Agent2Agent (A2A) Bot <a2a-bot@google.com>
Co-authored-by: Didier Durand <2927957+didier-durand@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Iva Sokolaj <102302011+sokoliva@users.noreply.github.com>
Co-authored-by: Will Chen <36873565+chenweiyang0204@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# Description

Do not use `NULLS LAST` which is not available in MySQL, coalesce nulls
to empty strings which will appear last in descending ordering (there
are tests for this behavior already, however CI wasn't enabled for this
branch).

Currently `NULLS LAST` fails MySQL tests:

```
(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULLS LAST, tasks.id DESC \n LIMIT 51' at line 3")
```
([actions
run](https://github.com/a2aproject/a2a-python/actions/runs/21520017047/job/62008309612?pr=651))

Enable tests run against `1.0-dev` to prevent it in the future.

Re a2aproject#511 
Fixes a2aproject#652 

---
Mark as "refactor" for release please as it's a fix for a non-released
feature, hence shouldn't get into a changelog.

BEGIN_COMMIT_OVERRIDE
refactor: use MySQL compatible syntax in list tasks
END_COMMIT_OVERRIDE
# Conflicts:
#	CHANGELOG.md
#	tests/client/transports/test_rest_client.py
#	tests/utils/test_proto_utils.py
# Description

Merge `main` into `1.0-dev` through an intermediate branch to resolve
conflicts. Opening a PR from `main` to `1.0-dev` required pushing to
`main` to resolve conflicts.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Iva Sokolaj <102302011+sokoliva@users.noreply.github.com>
Co-authored-by: Agent2Agent (A2A) Bot <a2a-bot@google.com>
Co-authored-by: Tadaki Asechi <127199356+TadakiAsechi@users.noreply.github.com>
Co-authored-by: tadaki <tadaki.asechi@gmail.com>
Co-authored-by: Holt Skinner <13262395+holtskinner@users.noreply.github.com>
Co-authored-by: TadakiAsechi <tadaki.asechi@icould.com>
Co-authored-by: TadakiAsechi <tadaki.asechi@iclould.com>
Co-authored-by: ShishirRmc <113575088+ShishirRmc@users.noreply.github.com>
Co-authored-by: Lukasz Kawka <luk.kawka@gmail.com>
Co-authored-by: Didier Durand <2927957+didier-durand@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Will Chen <36873565+chenweiyang0204@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Vinay Ramesh <vinay.r.ramesh@gmail.com>
# Description

Run linter on `1.0-dev`.
This reverts commit 40613ed.

Should be merged without squashing
…#665)

## Description
Updates the SDK to support the A2A Protocol v1.0.0-rc specifications.

## Changes
- **Protocol Update**: Updated core types, definitions, `Client`, and
`Server` implementations to match Protocol v1.0.0-rc.
- **Bug Fixes**:
    - Fixed `RestTransport` URL construction.
- Resolved `pyright`, `ruff`, and `mypy` linting errors across the
codebase.
- Fixed import resolution issues for optional dependencies (`grpc`,
`sqlalchemy`, `opentelemetry`).
- **Tests**:
    - Fixed all failing unit and integration tests.
- Added support for running PostgreSQL and MySQL integration tests
(verified locally).
- **Cleanup**: Removed redundant `pyrightconfig.json`.

## Testing
- All unit and integration tests are passing.
- Database integration tests verified locally with Docker containers
(docker-compose file was used for verification but is not included in
the repo).

Re a2aproject#559

---------

Signed-off-by: Luca Muscariello <muscariello@ieee.org>
To resolve existing merge issues first.
Fixes
a2aproject#697 (comment),
bad merge in a2aproject#696.

Cover "list tasks" in client-server integration tests which would
prevent it.

Re a2aproject#559.
Bring back `.pre-commit-config.yaml` and disabled JSCPD linter.

Removal can be evaluated separately, for now bringing them back to make
diff against `main` more focused.

Re a2aproject#559.
Tests basic functionality with real client and server with real
handlers, only agent executor is provided in test as it'd be in a real
usage.

Re a2aproject#559
JSON-RPC diverged a bit, update it to match other transports. Domain
request handler returns `Task | Message` from `on_message_send` already.

Fixes
a2aproject#697 (comment).

Re a2aproject#559.
According to [the
spec](https://a2a-protocol.org/latest/specification/#314-list-tasks) all
response fields are mandatory. Update implementation and add tests to
cover.

Re a2aproject#515
Active updates are happening to [A2A
repo](https://github.com/a2aproject/A2A/commits/main/) currently. Switch
`buf.gen.yaml` back to `main` (a2aproject#699 switched it to the 1.0 RC tag to
progress with merge without regenerating files) and update code to work
with the latest changes.

Re a2aproject#559.
Following

> The operation MUST return a Task object as the first event in the
stream

introduced in 1.0:
https://a2a-protocol.org/latest/specification/#316-subscribe-to-task

It also correctly uses `UnsupportedOperationError` as per the "Errors"
section from the documentation linked above.

Fixes a2aproject#675

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
According to
https://a2a-protocol.org/latest/specification/#324-history-length-semantics.
It changes behavior so the fix was postponed till 1.0.

After changing to proto passing `.history_length` would not work anymore
due to the way how proto generated code works - optional values are
still translated to language defaults to avoid `None`s, while presence
should be checked via `HasField` - done in this PR.

Fixes a2aproject#573

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
## Description

As per the 1.0 spec update (see [4.3.3. Push Notification
Payload](https://a2a-protocol.org/latest/specification/#433-push-notification-payload))
use `StreamResponse` as push notifications payload.

Fixes a2aproject#678

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Use enum everywhere, data model uses `str` for protocol names, so custom
protocols won't be constrained with the enum.

Fixes a2aproject#705
ishymko and others added 28 commits March 13, 2026 11:35
…2aproject#827)

Turns out it creates more problems than solves and requires more
intervention into release-please to also update `uv.lock`.

release-please still uses SemVer values in its PRs, but they are
normalized during build (see
[here](https://packaging.python.org/en/latest/specifications/version-specifiers/#normalization)).
1. Aligned with
https://a2a-protocol.org/latest/specification/#54-error-code-mappings.
2. Added roundtrip tests to `test_client_server_integration.py`.
3. Renamed `AuthenticatedExtendedCardNotConfiguredError` ->
`ExtendedAgentCardNotConfiguredError`.
# Description

This PR refactors the client interceptors architecture, centralizing
their execution within the BaseClient rather than delegating them to the
underlying transport implementations.
These interceptors allow to modify request before being sent to the
server, and server responses before are sent back to the caller, with an
early return mechanism.
The Authentication interceptor is updated as well to store
authentication values in the ServiceParameters class of the
ClientCallContext.

Fix: a2aproject#757
# Description

This PR disables the automatic generation of A2A types for v1.0 and for
compatibility with v0.3 at build phase.
`gen_proto.sh` and `gen_proto_compat.sh` can be used as scripts to
generate those types
# Description
The old 0.3 version is not able to read the 1.0 entries from database
because of the inconsistencies between 1.0 and 0.3 data types. This
applies to both DatabaseTaskStore and
DatabasePushNotificationConfigStore. This PR fixes this issue by
allowing users to write 0.3 compatible entires during migration period.

## Changes
- adds new conversion methods to `compat/0_3/conversions.py`
- update `DatabaseTaskStore` and `DatabasePushNotificationConfigStore`
to accept new conversion methods
- utilize new conversion methods of `DatabaseTaskStore` and
`DatabasePushNotificationConfigStore`

## Tested
Created a database using `0.3` spec containing populated tables `task`
and `push_notification_configs`. Ran `uv run a2a-db` using `1.0` spec
against the database and added new entries using the new Zero-downtime
feature, `DatabaseTaskStore.core_to_model_conversion =
core_to_compat_task_model` and
`DatabasePushNotificationConfigStore.core_to_model_conversion =
core_to_compat_push_notification_config_model`. Succesfully read new
entries using `0.3` spec.


Fixes a2aproject#811 🦕
…aproject#838)

# Description
This PR refactors the REST transport error handling to adhere to the
`google.rpc.Status` JSON format. Both the server-side exception handlers
and the client-side REST transport have been updated to utilize the new
standard error envelope, ensuring consistency across A2A REST APIs.

## Summary of Changes

* **Server:** 
* Updated `rest_error_handler` and the global `StarletteHTTPException`
handler in `A2ARESTFastAPIApplication` to return errors wrapped in an
`{'error': {...}}` envelope.
* Payloads now correctly include the HTTP `code`, gRPC `status`,
`message`, and a `details` array containing
`type.googleapis.com/google.rpc.ErrorInfo` for the specific reason and
metadata.
* **Client:** 
* Modified `RestTransport._handle_http_error` to parse the new format.
It now gracefully extracts the `reason` from the `ErrorInfo` detail
object to map it back to the corresponding Python `A2AError` class.
* **Core/Utils:** 
* Introduced `A2A_REST_ERROR_MAPPING` in `errors.py` to centralize the
mapping of Python exceptions to their respective HTTP status codes, gRPC
statuses, and string reasons.
* Added a `data` attribute to the base `A2AError` to carry arbitrary
error metadata.
* **Tests:** 
* Updated REST client, server, and error handler tests to validate the
new nested `{'error': {...}}` JSON payload structures.


- [X] Follow the [`CONTRIBUTING`
Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md).
- [X] Make your Pull Request title in the
<https://www.conventionalcommits.org/> specification.
- Important Prefixes for
[release-please](https://github.com/googleapis/release-please):
- `fix:` which represents bug fixes, and correlates to a
[SemVer](https://semver.org/) patch.
- `feat:` represents a new feature, and correlates to a SemVer minor.
- `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking
change (indicated by the `!`) and will result in a SemVer major.
- [X] Ensure the tests and linter pass (Run `bash scripts/format.sh`
from the repository root to format)
- [X] Appropriate docs were updated (if necessary)

Fixes a2aproject#722  🦕

---------

Co-authored-by: Ivan Shymko <ishymko@google.com>
…ect#843)

POST should be always use for /tasks/{id}:subscribe.
Decisions for backward compatibility with invalid protocol
implementations:
1.0 server: Accept both POST and GET
1.0 client: Always use POST
0.3 server: Accept both POST and GET
0.3 client: Try POST first, on HTTP 405 error retry with GET. Cache the
retry state to ensure that there is at most one retry attempt per
transport instance.

Fixes a2aproject#840
…t#844)

# Description

This PR enhances the tck sut agent to support jsonrpc, rest and grpc
transport.

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…rd (a2aproject#847)

When generating backward compatible AgentCard format, keep only 0.3
compatible endpoints.
This affects /.well-known/agent-card.json and AgentCard generation in
0.3 compat layer.

Fixes a2aproject#742
# Description

This PR removes the generation and use of a2a.json.
Its content is not compatible with the JSON-RPC protocol, so there is no
need to load it with the FastAPI server generation.
There is a dedicated repo for samples
([a2a-samples](https://github.com/a2aproject/a2a-samples)), however
having something runnable in the repository is useful for manual testing
and ad-hoc experimentation. Add trivial hello-world/echo agent and a
simple client CLI to connect to it.

It exposes all transports and both 1.0 and 0.3 version.

1. Run server
```bash
$ uv run samples/hello_world_agent.py
```
2. (_separate terminal_) Run client (supports `--transport` as well)
```bash
$ uv run samples/cli.py
Connecting to http://127.0.0.1:41241 (preferred transport: Any)

✓ Agent Card Found:
  Name: Sample Agent
  Picked Transport: JsonRpcTransport

Connected! Send a message or type /quit to exit.
You: test
TaskStatusUpdate [TASK_STATE_WORKING]: Processing your question... 
TaskArtifactUpdate [response]: Hello World! You said: 'test'. Thanks for your message! 
TaskStatusUpdate [TASK_STATE_COMPLETED]: 
--- Task Completed ---
You: 
```
🤖 I have created a release *beep* *boop*
---


### ⚠ BREAKING CHANGES

* **spec**: upgrade SDK to A2A 1.0 spec and use proto-based types
([a2aproject#572](a2aproject#572),
[a2aproject#665](a2aproject#665),
[a2aproject#804](a2aproject#804),
[a2aproject#765](a2aproject#765))
* **client:** introduce ServiceParameters for extensions and include it
in ClientCallContext
([a2aproject#784](a2aproject#784))
* **client:** rename "callback" -> "push_notification_config"
([a2aproject#749](a2aproject#749))
* **client:** transport agnostic interceptors
([a2aproject#796](a2aproject#796))
([a910cbc](a2aproject@a910cbc))
* add `protocol_version` column to Task and PushNotificationConfig
models and create a migration
([a2aproject#789](a2aproject#789))
([2e2d431](a2aproject@2e2d431))
* **server:** implement `Resource Scoping` for tasks and push
notifications
([a2aproject#709](a2aproject#709))
([f0d4669](a2aproject@f0d4669))

### Features

* add GetExtendedAgentCardRequest as input parameter to
GetExtendedAgentCard method
([a2aproject#767](a2aproject#767))
([13a092f](a2aproject@13a092f))
* add validation for the JSON-RPC version
([a2aproject#808](a2aproject#808))
([6eb7e41](a2aproject@6eb7e41))
* **client:** expose close() and async context manager support on
abstract Client
([a2aproject#719](a2aproject#719))
([e25ba7b](a2aproject@e25ba7b))
* **compat:** AgentCard backward compatibility helpers and tests
([a2aproject#760](a2aproject#760))
([81f3494](a2aproject@81f3494))
* **compat:** GRPC client compatible with 0.3 server
([a2aproject#779](a2aproject#779))
([0ebca93](a2aproject@0ebca93))
* **compat:** GRPC server compatible with 0.3 client
([a2aproject#772](a2aproject#772))
([80d827a](a2aproject@80d827a))
* **compat:** legacy v0.3 protocol models, conversion logic and
utilities ([a2aproject#754](a2aproject#754))
([26835ad](a2aproject@26835ad))
* **compat:** REST and JSONRPC clients compatible with 0.3 servers
([a2aproject#798](a2aproject#798))
([08794f7](a2aproject@08794f7))
* **compat:** REST and JSONRPC servers compatible with 0.3 clients
([a2aproject#795](a2aproject#795))
([9856054](a2aproject@9856054))
* **compat:** set a2a-version header to 1.0.0
([a2aproject#764](a2aproject#764))
([4cb68aa](a2aproject@4cb68aa))
* **compat:** unify v0.3 REST url prefix and expand cross-version tests
([a2aproject#820](a2aproject#820))
([0925f0a](a2aproject@0925f0a))
* database forward compatibility: make `owner` field optional
([a2aproject#812](a2aproject#812))
([cc29d1f](a2aproject@cc29d1f))
* handle tenant in Client
([a2aproject#758](a2aproject#758))
([5b354e4](a2aproject@5b354e4))
* implement missing push notifications related methods
([a2aproject#711](a2aproject#711))
([041f0f5](a2aproject@041f0f5))
* implement rich gRPC error details per A2A v1.0 spec
([a2aproject#790](a2aproject#790))
([245eca3](a2aproject@245eca3))
* **rest:** add tenant support to rest
([a2aproject#773](a2aproject#773))
([4771b5a](a2aproject@4771b5a))
* send task as a first subscribe event
([a2aproject#716](a2aproject#716))
([e71ac62](a2aproject@e71ac62))
* **server, grpc:** Implement tenant context propagation for gRPC
requests. ([a2aproject#781](a2aproject#781))
([164f919](a2aproject@164f919))
* **server, json-rpc:** Implement tenant context propagation for
JSON-RPC requests.
([a2aproject#778](a2aproject#778))
([72a330d](a2aproject@72a330d))
* **server:** add v0.3 legacy compatibility for database models
([a2aproject#783](a2aproject#783))
([08c491e](a2aproject@08c491e))
* **spec:** add `tasks/list` method with filtering and pagination to the
specification
([a2aproject#511](a2aproject#511))
([d5818e5](a2aproject@d5818e5))
* use StreamResponse as push notifications payload
([a2aproject#724](a2aproject#724))
([a149a09](a2aproject@a149a09))
* **rest:** update REST error handling to use `google.rpc.Status`
([a2aproject#838](a2aproject#838))
([ea7d3ad](a2aproject@ea7d3ad))


### Bug Fixes

* add history length and page size validations
([a2aproject#726](a2aproject#726))
([e67934b](a2aproject@e67934b))
* allign error codes with the latest spec
([a2aproject#826](a2aproject#826))
([709b1ff](a2aproject@709b1ff))
* **client:** align send_message signature with BaseClient
([a2aproject#740](a2aproject#740))
([57cb529](a2aproject@57cb529))
* get_agent_card trailing slash when agent_card_path=""
([a2aproject#799](a2aproject#799))
([a2aproject#800](a2aproject#800))
([a55c97e](a2aproject@a55c97e))
* handle parsing error in REST
([a2aproject#806](a2aproject#806))
([bbd09f2](a2aproject@bbd09f2))
* Improve error handling for Timeout exceptions on REST and JSON-RPC
clients ([a2aproject#690](a2aproject#690))
([2acd838](a2aproject@2acd838))
* Improve streaming errors handling
([a2aproject#576](a2aproject#576))
([7ea7475](a2aproject@7ea7475))
* properly handle unset and zero history length
([a2aproject#717](a2aproject#717))
([72a1007](a2aproject@72a1007))
* return entire history when history_length=0
([a2aproject#537](a2aproject#537))
([acdc0de](a2aproject@acdc0de))
* return mandatory fields from list_tasks
([a2aproject#710](a2aproject#710))
([6132053](a2aproject@6132053))
* taskslist error on invalid page token and response serialization
([a2aproject#814](a2aproject#814))
([a102d31](a2aproject@a102d31))
* use correct REST path for Get Extended Agent Card operation
([a2aproject#769](a2aproject#769))
([ced3f99](a2aproject@ced3f99))
* Use POST method for REST endpoint /tasks/{id}:subscribe
([a2aproject#843](a2aproject#843))
([a0827d0](a2aproject@a0827d0))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: Ivan Shymko <ishymko@google.com>
Use validate_async_generator and add validators to compat grpc handler.
…ject#743)

# Description

Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make
sure it goes smoothly:

- [x] Follow the [`CONTRIBUTING`
Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md).
- [x] Make your Pull Request title in the
<https://www.conventionalcommits.org/> specification.
- Important Prefixes for
[release-please](https://github.com/googleapis/release-please):
- `fix:` which represents bug fixes, and correlates to a
[SemVer](https://semver.org/) patch.
- `feat:` represents a new feature, and correlates to a SemVer minor.
- `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking
change (indicated by the `!`) and will result in a SemVer major.
- [x] Ensure the tests and linter pass (Run `bash scripts/format.sh`
from the repository root to format)
- [x] Appropriate docs were updated (if necessary)

Fixes a2aproject#720 🦕

## Problem

`EventQueue` has a sophisticated `close()` with graceful/immediate
modes, child propagation, and cross-version handling — but doesn't
support `async with`. Server-side code must use explicit `try/finally`
or risk leaking resources on exceptions:

```python
queue = EventQueue()
try:
    await queue.enqueue_event(event)
    ...
finally:
    await queue.close()
```

## Fix

Add `__aenter__` and `__aexit__` as concrete methods on `EventQueue`:

* `__aenter__` returns `Self` (via `typing_extensions`).
* `__aexit__` delegates to `close()` with default `immediate=False`
(graceful). Code needing immediate shutdown can still call `await
queue.close(immediate=True)` explicitly.

This enables the idiomatic pattern:

```python
async with EventQueue() as queue:
    await queue.enqueue_event(event)
    ...
# close() called automatically, even on exceptions
```

Unlike the client-side hierarchy where `__aenter__`/`__aexit__` were
lifted to the abstract `Client` (a2aproject#719), `EventQueue` is a concrete class
with no abstract base above it — `QueueManager` manages queue lifecycles
by task ID but does not wrap or extend `EventQueue`. This is the correct
and only place for these methods.

Non-breaking, additive change. Manual `close()` and `try/finally`
continue to work as before.

Follows the pattern established in `ClientTransport` (a2aproject#682),
`BaseClient` (a2aproject#688), and `Client` (a2aproject#719).

## Tests

Two tests added to `tests/server/events/test_event_queue.py`, following
the same approach as `ClientTransport` and `BaseClient`.
# Description

Add documentation about database migrations for users.

Add `current` option to the `a2a-db` CLI command to see current version
of the database.

- [x] Follow the [`CONTRIBUTING`
Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md).
- [x] Make your Pull Request title in the
<https://www.conventionalcommits.org/> specification.
- Important Prefixes for
[release-please](https://github.com/googleapis/release-please):
- `fix:` which represents bug fixes, and correlates to a
[SemVer](https://semver.org/) patch.
- `feat:` represents a new feature, and correlates to a SemVer minor.
- `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking
change (indicated by the `!`) and will result in a SemVer major.
- [x] Ensure the tests and linter pass (Run `bash scripts/format.sh`
from the repository root to format)
- [x] Appropriate docs were updated (if necessary)

Fixes a2aproject#715 🦕
…roject#877)

Introduced a compatibility layer using the culsans library to backport
asyncio.Queue.shutdown functionality to Python versions older than 3.13.
Previous implementation was broken (deadlocks and inconsistent behaviour
with 3.13 implementation). Culsans library allowed for unified code
between versions.

This is one of the steps towards better concurrency model in a2a python
sdk.

Fixes a2aproject#869
Reproduced in `test_client_server_integration.py`.

### gRPC

`validate_async_generator` decorator was applied on top of the method
above A2A error handling. Compat handler was already refactored in a way
which made it possible to apply it on a nested function. It was done
there and v1 handler was refactored in the same way.

### SSE streaming

Iterator wrapped into `validate_async_generator` is assigned to
`EventSourceResponse` and is returned from the method, so when it throws
`rest_stream_error_handler` has no effect on it.


https://github.com/a2aproject/a2a-python/blob/4630efd0ca4bf6934a7d9215ef2a2986b6e6e73a/src/a2a/server/apps/rest/rest_adapter.py#L155-L163

Instead of throwing on the first iteration, throw on the method
invocation itself to avoid more sophisticated error handling (i.e.
reading one item to trigger error) by removing separate handling for
async generator.

Client-level handling is also updated to properly handle non-200 status
code for streaming and non-streaming response in case of JSON-RPC error.
…oject#889)

* vertexai.Part & co. will be replaced soon by genai.Part & co.
* It's better to use the more specifically named variants of `Task` and
`Status`: `A2aTask` and `A2aTaskStatus`.

For a2aproject#751
@gaborfeher gaborfeher closed this Mar 23, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the summary. You can try again by commenting /gemini summary.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.