feat: A2A server support in serve()#179
Merged
Merged
Conversation
Add A2A transport support so the same ADCPHandler can be served over both MCP and A2A protocols with a single flag: serve(MyHandler(), name="my-agent", transport="a2a") Implementation: - ADCPAgentExecutor bridges ADCPHandler to a2a-sdk's AgentExecutor interface, parsing DataPart skill invocations and dispatching to handler methods - create_a2a_server() builds a Starlette app with A2A endpoints (agent card at /.well-known/agent.json, JSON-RPC at /) - TestControllerStore wired into A2A via the same _handle_test_controller dispatch logic MCP uses, so storyboards work over both transports - Transport validation rejects unknown transport strings - Exception details not leaked to callers (security review) 15 tests covering executor dispatch, error handling, test controller integration, agent card generation, and server creation. Closes #175 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Skip create_a2a_server tests on Python <3.11 (a2a-sdk starlette compat issue: Cannot subclass typing.Any) - Don't leak exception details to A2A callers (security review) - Add transport validation with helpful error message - Restore specific security warning about exposed endpoints - Add handler exception test - Move Task import to top-level (cleanup) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ADCP requires that if a request contains a context field, the response must echo it back unchanged. Previously handlers had to manually call inject_context() — easy to forget, causing storyboard failures. Now create_tool_caller() automatically injects context after the handler returns, for both MCP and A2A transports. Handlers no longer need to call inject_context() manually (though it's still safe to do so — it won't overwrite if context is already set). Validated: capability_discovery storyboard passes 2/2 over A2A, media_buy_seller passes 7/9 (remaining 2 are test handler issues). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tested skill-doc DX by having agents build seller/signals/creative agents. Seller doc forced iteration on undocumented schema fields; other docs were shipping-quality. - Seller product example now includes required reporting_capabilities and delivery_measurement fields so agents pass 9/9 first try - Added Common Mistakes entries: reporting_capabilities sub-fields, valid enum values (hourly|daily|monthly), delivery_measurement.provider - Removed inject_context calls from code examples — context passthrough is now automatic in create_tool_caller, so teaching it is wrong - Updated serve() reference to document transport="a2a" and port= kwargs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
Summary
serve(handler, transport="a2a")to serve an ADCPHandler as an A2A agentADCPAgentExecutorbridges ADCPHandler methods to the a2a-sdkAgentExecutorinterface — parses DataPart skill invocations, dispatches to handler methods, returns results as A2A Task eventscreate_a2a_server()builds a Starlette app with agent card + JSON-RPC endpointsTestControllerStoreworks over A2A (same_handle_test_controllerdispatch as MCP), so storyboards will work over both transportsTest plan
Closes #175
🤖 Generated with Claude Code