Skip to content

feat(compat): AgentCard backward compatibility helpers and tests#760

Open
bartek-w wants to merge 1 commit into1.0-devfrom
barekw-compat-agent-card
Open

feat(compat): AgentCard backward compatibility helpers and tests#760
bartek-w wants to merge 1 commit into1.0-devfrom
barekw-compat-agent-card

Conversation

@bartek-w
Copy link
Collaborator

@bartek-w bartek-w commented Mar 4, 2026

This commit implements the backwards compatibility helpers for exchanging legacy v0.3 Agent Cards across the v1.0 protocol bounds.

Also resolves linting and validation constraints.

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:

  • Follow the CONTRIBUTING Guide.
  • Make your Pull Request title in the https://www.conventionalcommits.org/ specification.
    • Important Prefixes for release-please:
      • fix: which represents bug fixes, and correlates to a SemVer 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.
  • Ensure the tests and linter pass (Run bash scripts/format.sh from the repository root to format)
  • Appropriate docs were updated (if necessary)

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces robust backward compatibility mechanisms for Agent Cards, enabling smooth communication between systems using different protocol versions (v0.3 and v1.0). By providing dedicated helpers for both parsing incoming legacy cards and serializing current cards for older clients, it ensures that the system can gracefully handle the transition and maintain interoperability without breaking existing integrations.

Highlights

  • AgentCard Backward Compatibility (Client-side): Introduced a new parse_agent_card helper function to handle backward compatibility when parsing legacy v0.3 Agent Cards into the v1.0 protocol format. This function intelligently maps older fields like supportsAuthenticatedExtendedCard, connection details (url, preferredTransport, additionalInterfaces), and security configurations to their modern equivalents, ensuring seamless client-side consumption of older card versions.
  • AgentCard Backward Compatibility (Server-side): Implemented an agent_card_to_dict helper function that converts a v1.0 AgentCard Protobuf message back into a dictionary format, injecting v0.3 compatible fields. This ensures that servers using the new protocol can still serve AgentCards that are understandable by older v0.3 clients, maintaining interoperability.
  • Integration Across Client and Server: The new compatibility helpers have been integrated into various client-side card resolution logic (e.g., card_resolver, jsonrpc, rest transports) and server-side response generation (e.g., jsonrpc_app, rest_adapter, jsonrpc_handler) to automatically apply the necessary transformations during AgentCard exchange.
  • Comprehensive Testing: Added extensive unit and integration tests to validate the backward compatibility logic. This includes tests for parsing various legacy AgentCard structures, ensuring no data loss during serialization/deserialization, and cross-version integration tests to confirm compatibility with older SDK versions.
Changelog
  • src/a2a/client/card_resolver.py
    • Removed direct import of ParseDict from google.protobuf.json_format.
    • Imported parse_agent_card from a2a.client.helpers.
    • Replaced direct ParseDict calls with the new parse_agent_card helper for AgentCard deserialization.
  • src/a2a/client/helpers.py
    • Added parse_agent_card function to handle backward compatibility for AgentCard parsing.
    • Implemented _handle_extended_card_compatibility to map legacy supportsAuthenticatedExtendedCard to capabilities.
    • Implemented _handle_connection_fields_compatibility to map legacy connection fields (url, preferredTransport, additionalInterfaces) to supportedInterfaces.
    • Implemented _map_legacy_security to convert old security requirement lists to the new Protobuf format.
    • Implemented _handle_security_compatibility to map legacy security requirements and schemes to their v1.0 Protobuf equivalents.
    • Imported ParseDict from google.protobuf.json_format and AgentCard from a2a.types.a2a_pb2.
  • src/a2a/client/transports/jsonrpc.py
    • Imported parse_agent_card from a2a.client.helpers.
    • Replaced direct json_format.ParseDict calls with the new parse_agent_card helper.
  • src/a2a/client/transports/rest.py
    • Imported parse_agent_card from a2a.client.helpers.
    • Replaced direct ParseDict calls with the new parse_agent_card helper.
  • src/a2a/server/apps/jsonrpc/jsonrpc_app.py
    • Removed direct import of MessageToDict from google.protobuf.json_format.
    • Imported agent_card_to_dict from a2a.server.request_handlers.response_helpers.
    • Replaced MessageToDict calls with the new agent_card_to_dict helper for AgentCard serialization.
  • src/a2a/server/apps/rest/rest_adapter.py
    • Removed direct import of MessageToDict from google.protobuf.json_format.
    • Imported agent_card_to_dict from a2a.server.request_handlers.response_helpers.
    • Replaced MessageToDict calls with the new agent_card_to_dict helper for AgentCard serialization.
  • src/a2a/server/request_handlers/jsonrpc_handler.py
    • Imported agent_card_to_dict from a2a.server.request_handlers.response_helpers.
    • Replaced MessageToDict calls with the new agent_card_to_dict helper.
    • Updated ParseDict call in a test to include ignore_unknown_fields=True for robustness.
  • src/a2a/server/request_handlers/response_helpers.py
    • Imported to_compat_agent_card from a2a.compat.v0_3.conversions and AgentCard from a2a.types.a2a_pb2.
    • Added agent_card_to_dict function to convert AgentCard to a dictionary, injecting backward compatible fields for v0.3 clients.
    • Implemented a merge helper function within agent_card_to_dict for dictionary merging.
  • tests/client/test_card_resolver.py
    • Updated test data in test_get_agent_card_validation_error to reflect a more specific validation failure scenario.
  • tests/client/test_client_helpers.py
    • Added new test file to cover the functionality of parse_agent_card and create_text_message_object.
    • Included comprehensive tests for parsing legacy AgentCard formats, including various compatibility mappings for capabilities, connection fields, and security schemes.
    • Added a helper _assert_agent_card_diff to verify that re-serialization of parsed cards retains all original data.
  • tests/integration/cross_version/test_cross_version_card_validation.py
    • Added new integration test file to validate cross-version AgentCard deserialization.
    • Serialized complex and minimal AgentCards using the current SDK and fed them to a subprocess running an older 0.3.24 SDK for validation.
  • tests/integration/cross_version/validate_agent_cards_030.py
    • Added new script to validate AgentCards against the 0.3.0 schema, intended to be run by the cross-version integration test.
    • Defined validate_complex_card and validate_minimal_card functions to assert expected structures for legacy cards.
  • tests/server/apps/jsonrpc/test_serialization.py
    • Updated the location field value for APIKeySecurityScheme from IN_HEADER to header for consistency.
  • tests/server/request_handlers/test_jsonrpc_handler.py
    • Modified test_get_authenticated_extended_card_not_configured to use a concrete AgentCard instance instead of a mock.
    • Added ignore_unknown_fields=True to a ParseDict call within a test to handle potential unknown fields during parsing.
  • tests/server/request_handlers/test_response_helpers.py
    • Added new test cases for agent_card_to_dict to specifically verify the correct handling and presence/absence of the supportsAuthenticatedExtendedCard field based on the extended_agent_card capability.
Activity
  • The author has followed the CONTRIBUTING Guide.
  • The Pull Request title adheres to the Conventional Commits specification, indicating a new feature related to compatibility.
  • The author has ensured that tests and linter pass.
  • The author has confirmed that appropriate documentation was updated (if necessary).
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces backward compatibility helpers for v0.3 Agent Cards, allowing them to be used with the v1.0 protocol. The changes include both client-side parsing of legacy cards and server-side serialization to include legacy fields for older clients. The implementation is robust and accompanied by an excellent set of unit and integration tests, including cross-version validation against an older SDK version.

My review focuses on improving type safety in the new compatibility helpers. I've suggested a more specific type hint. Overall, this is a high-quality contribution that significantly improves interoperability.

Note: Security Review did not run due to the size of the PR.

@bartek-w bartek-w force-pushed the barekw-compat-agent-card branch 2 times, most recently from a95abdd to 41bf29c Compare March 4, 2026 12:22
@bartek-w bartek-w marked this pull request as ready for review March 4, 2026 12:23
@bartek-w bartek-w requested a review from a team as a code owner March 4, 2026 12:23
@bartek-w bartek-w requested a review from ishymko March 4, 2026 12:24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To the best of my knowledge snake_case shouldn't be required here, both 1.0 and 0.3 use camelCase for field names.

Comment on lines +89 to +92
'schemes': {
scheme_name: {'list': scopes}
for scheme_name, scopes in sec_dict.items()
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the source of schemes key here?

Note that in 0.3 the actual data model used is JSON Schema based, not proto based (and have some differences).

Comment on lines 512 to 518
case GetExtendedAgentCardRequest():
handler_result = (
await self.handler.get_authenticated_extended_card(
request_obj,
context,
)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that compat mode was applied in REST, I believe it should be applied here as well. It happens after version negotiation though, so it doesn't have to be a "union", can be handled in follow-up PR(s) for other conversions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if it meant to be committed maybe some short readme on how to use it? We can skip if in the end (after compat work) it's going to be removed completely and fully replaced with automated tests.

This commit implements the backwards compatibility helpers for exchanging
legacy v0.3 Agent Cards across the v1.0 protocol bounds.
@bartek-w bartek-w force-pushed the barekw-compat-agent-card branch from 41bf29c to f573741 Compare March 4, 2026 14:31
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.

2 participants