Skip to content

[Design]: Clarify discovery semantics for v0.3 compatibility projections on AgentCard output #1051

@liujuanjuan1984

Description

@liujuanjuan1984

Summary

When a server wants to remain operationally 1.0-first but also reuse the SDK's v0.3 compatibility support, the current compatibility projection can make machine-readable discovery look 0.3-first or at least semantically ambiguous.

I am opening this issue as a design / semantics question because it affects whether downstream servers can safely opt into narrow ingress compatibility without also changing the meaning of their discovery surfaces.

Current Behavior

The SDK helper agent_card_to_dict() does not only serialize the core v1 AgentCard. It also merges fields from to_compat_agent_card() back into the same dict:

  • a2a.server.request_handlers.response_helpers.agent_card_to_dict
  • a2a.compat.v0_3.conversions.to_compat_agent_card

to_compat_agent_card() filters supported_interfaces down to legacy-compatible interfaces and then uses the first such interface as the primary source for compat fields such as:

  • protocolVersion
  • preferredTransport
  • url
  • additionalInterfaces

As a result, if a server declares both 1.0 and 0.3 interfaces in the core card, the serialized output can contain:

  • supportedInterfaces with both 1.0 and 0.3
  • but top-level compat fields such as protocolVersion set to 0.3

This is especially visible because many server implementations will use the same helper for:

  • public Agent Card
  • authenticated extended Agent Card
  • JSON-RPC GetExtendedAgentCard

Why This Is A Problem

For downstream server authors, this makes the meaning of discovery less clear:

  • the runtime may still want to be 1.0-first by policy and default negotiation
  • but the merged compatibility projection can make the card appear 0.3-first at the top level
  • different discovery surfaces may then drift in what they imply about the runtime's "real" default or primary protocol line

In practice, this discourages downstreams from using the SDK's 0.3 compatibility support at all, because the discovery semantics become harder to reason about and harder to document honestly.

Evidence In The Current Implementation

  1. agent_card_to_dict() merges compat fields into the same dict instead of returning a separate compat view.
  2. to_compat_agent_card() selects legacy-compatible interfaces only and derives top-level compat fields from that filtered subset.
  3. The core AgentCard proto itself does not have a top-level protocolVersion field; that field is introduced by the compatibility projection.

Open Question

Is this behavior intentional as the long-term discovery model for servers that support both 1.0 and 0.3 ingress compatibility?

Or should the SDK provide a cleaner separation between:

  • the core v1 card serialization, and
  • the legacy v0.3 compatibility projection?

Possible Directions

A few possible directions that seem worth discussing:

  1. Keep the default agent_card_to_dict() output "pure v1" and expose compat fields only through an explicit compat serializer.
  2. Make compat field injection opt-in for server authors.
  3. Only emit legacy compat card fields on an explicit v0.3 discovery path, instead of merging them into the default card output.
  4. If the current merged behavior is intentional, document the discovery semantics more explicitly so downstreams know that top-level compat fields do not imply the server's runtime default line.

Why This Matters

This is not only a documentation issue. It changes whether downstreams can cleanly adopt the SDK's 0.3 compatibility layer while preserving:

  • runtime purity
  • honest machine-readable discovery
  • maintainable and testable server behavior

At the moment, the merged compatibility projection makes that tradeoff much harder than it appears from the compat APIs alone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions