fix(keycardai-a2a)!: 0.3 compat for cross-SDK interop, example audience binding, dead code removal#207
Open
Larry-Osakwe wants to merge 3 commits into
Open
fix(keycardai-a2a)!: 0.3 compat for cross-SDK interop, example audience binding, dead code removal#207Larry-Osakwe wants to merge 3 commits into
Larry-Osakwe wants to merge 3 commits into
Conversation
…cross-SDK interop a2a-sdk 1.x's JSONRPC dispatcher ships enable_v0_3_compat=False, so a server composed per our README/example rejected 0.3 message/send requests from the Go/TS Keycard SDKs with -32601 MethodNotFound. The package deliberately does not wrap create_jsonrpc_routes (it is glue, not a server abstraction), so the flag is now passed at every composition point we ship: the README quickstart, the keycard_protected_server example, and the test fixtures that mirror them. The a2a_jsonrpc_usage example's manual envelope was itself a 0.3 shape (message/send, plain role, no messageId, no A2A-Version header) aimed at the 1.0 server the sibling example builds; it now shows the current 1.0 envelope, with a comment pointing 0.3 callers at the compat flag. Adds a dispatch test proving a 0.3 message/send request round-trips through the built app when compat is on. Interim measure per ECO-161: the flag goes away once all Keycard SDKs speak A2A 1.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…truction The example and README quickstart constructed AuthProvider without an audience, which disables the verifier's audience check: any token minted in the zone for any service would be accepted. Delegation tokens are minted with audience = the target service's public URL, so the correct binding is the service's own identity_url. The test_agent_card_server fixture that mirrors the example gets the same binding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ardai-agents extraction
Two leftovers from the pre-split keycardai-agents package:
- DelegationClient.invoke_service returned a hardcoded
delegation_chain: [] field that nothing populates; the return shape
is now just {result}. No consumer reads it (the only test assertion
checked it was always empty).
- ServiceDiscovery.list_delegatable_services was a warn-and-return-[]
stub whose docstring and log message pointed at get_a2a_tools(),
which does not exist in this package. Removed along with its
placeholder test and the orphaned mock_delegatable_services fixture.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
📦 Release PreviewThis analysis shows the expected release impact: 📈 Expected Version Changes📋 Package Details[
{
"package_name": "keycardai-a2a",
"package_dir": "packages/a2a",
"has_changes": true,
"current_version": "0.3.0",
"next_version": "0.4.0",
"increment": "MINOR"
}
]📝 Changelog PreviewThis comment was automatically generated by the release preview workflow. |
Larry-Osakwe
marked this pull request as ready for review
July 21, 2026 23:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The three PR-sized items from the ECO-115 re-eval of
keycardai-a2a(full scorecard on the ticket). All changes confined topackages/a2a.Cross-SDK interop: enable A2A 0.3 compat at every composition point
a2a-sdk 1.x's dispatcher ships
enable_v0_3_compat=Falseand accepts only protocol-1.0 method names, so Go/TS Keycard clients (which send 0.3message/send) got-32601 MethodNotFoundfrom Python-built agents. There is no package wrapper to default (deliberate: this package is glue, customers call a2a-sdk'screate_jsonrpc_routesdirectly), so the flag is now set with a cross-SDK comment at every composition point we ship: README quickstart, the protected-server example, and the mirroring test fixtures. New test proves a 0.3message/sendround-trips to the executor with token propagation.Also fixes the
a2a_jsonrpc_usageexample's manual envelope, which was a malformed 0.3 shape (missingmessageId); it now sends the current 1.0 shape with a pointer at the compat flag for 0.3 callers. Note: this example is a standalone script needing a live server, so CI does not execute it; the 1.0 envelope was verified field-by-field against the pinned a2a-sdk proto (ParseDictaccepts it, and the part shape is the protooneofform where the field name is the discriminator, nokind).Interim measure per ECO-161: the flag drops once all three SDKs speak protocol 1.0.
Audience binding in the examples
audience=config.identity_urladded to the exampleAuthProviderconstruction, README quickstart, and test fixture, each with the one-line note that unset disables the check. (Same treatment as go-sdk #37 and python-sdk #206; the structural fix is ECO-159.)Dead keycardai-agents remnants removed (the breaking part)
invoke_serviceno longer returns the always-emptydelegation_chain: []field.list_delegatable_servicesplaceholder is deleted. Correction from review: it was a callable public method that logged a warning and returned[](the nonexistentget_a2a_tools()was referenced only in its docstring, not called), so a caller relying on the empty list now getsAttributeError, andresult["delegation_chain"]readers now getKeyError.Both are public-surface removals, hence the
!on this PR's title so the squash lands as a breaking change (0.3.0 → 0.4.0). Blast radius is near zero (the method did nothing useful and the field was always empty), but the semantics should be honest.BREAKING CHANGE:
ServiceDiscovery.list_delegatable_services()is removed andinvoke_service()responses no longer include the always-emptydelegation_chainfield.Validation
45 tests pass, ruff clean, commit messages validate.
Noted but out of scope (stale keycardai-agents-era docs):
examples/a2a_jsonrpc_usage/README.mdandkeycard_protected_server/README.mdboth describe surfaces that no longer exist; happy to sweep in a follow-up.🤖 Generated with Claude Code