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
agent_card_to_dict() merges compat fields into the same dict instead of returning a separate compat view.
to_compat_agent_card() selects legacy-compatible interfaces only and derives top-level compat fields from that filtered subset.
- 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:
- Keep the default
agent_card_to_dict() output "pure v1" and expose compat fields only through an explicit compat serializer.
- Make compat field injection opt-in for server authors.
- Only emit legacy compat card fields on an explicit
v0.3 discovery path, instead of merging them into the default card output.
- 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.
Summary
When a server wants to remain operationally
1.0-first but also reuse the SDK'sv0.3compatibility support, the current compatibility projection can make machine-readable discovery look0.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 corev1AgentCard. It also merges fields fromto_compat_agent_card()back into the same dict:a2a.server.request_handlers.response_helpers.agent_card_to_dicta2a.compat.v0_3.conversions.to_compat_agent_cardto_compat_agent_card()filterssupported_interfacesdown to legacy-compatible interfaces and then uses the first such interface as the primary source for compat fields such as:protocolVersionpreferredTransporturladditionalInterfacesAs a result, if a server declares both
1.0and0.3interfaces in the core card, the serialized output can contain:supportedInterfaceswith both1.0and0.3protocolVersionset to0.3This is especially visible because many server implementations will use the same helper for:
GetExtendedAgentCardWhy This Is A Problem
For downstream server authors, this makes the meaning of discovery less clear:
1.0-first by policy and default negotiation0.3-first at the top levelIn practice, this discourages downstreams from using the SDK's
0.3compatibility support at all, because the discovery semantics become harder to reason about and harder to document honestly.Evidence In The Current Implementation
agent_card_to_dict()merges compat fields into the same dict instead of returning a separate compat view.to_compat_agent_card()selects legacy-compatible interfaces only and derives top-level compat fields from that filtered subset.AgentCardproto itself does not have a top-levelprotocolVersionfield; 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.0and0.3ingress compatibility?Or should the SDK provide a cleaner separation between:
v1card serialization, andv0.3compatibility projection?Possible Directions
A few possible directions that seem worth discussing:
agent_card_to_dict()output "pure v1" and expose compat fields only through an explicit compat serializer.v0.3discovery path, instead of merging them into the default card output.Why This Matters
This is not only a documentation issue. It changes whether downstreams can cleanly adopt the SDK's
0.3compatibility layer while preserving:At the moment, the merged compatibility projection makes that tradeoff much harder than it appears from the compat APIs alone.