feat: add A2A protocol support via serve_a2a#349
Conversation
Adds ~130 lines of Bedrock-specific glue around the official a2a-sdk, replacing the need for a custom protocol implementation. The industry (ADK, Strands, CrewAI) has converged on the a2a-sdk, and this delegates all protocol handling to it. New exports from bedrock_agentcore.runtime: - serve_a2a(executor, agent_card=None, ...) — one-liner to start an A2A server - build_a2a_app(executor, agent_card=None, ...) — returns a Starlette app - BedrockCallContextBuilder — extracts Bedrock headers into contextvars Key features: - Optional a2a-sdk dependency: pip install "bedrock-agentcore[a2a]" - Auto-builds AgentCard from StrandsA2AExecutor when not provided - Auto-populates agent_card.url from AGENTCORE_RUNTIME_URL env var - Docker/container host detection (0.0.0.0 vs 127.0.0.1) - /ping health check endpoint with optional custom handler - Propagates session, request, token, and custom headers via contextvars Works with any framework that provides an a2a-sdk AgentExecutor: - Strands: serve_a2a(StrandsA2AExecutor(agent)) - ADK: serve_a2a(A2aAgentExecutor(runner=runner), card) - LangGraph: serve_a2a(CustomExecutor(graph), card)
80adc3e to
3bcc879
Compare
|
Your proposal listed three components: serve_a2a, BedrockCallContextBuilder, and build_runtime_url(agent_arn, region). The third one isn’t here. Intentionally dropped, or coming in a follow-up? Customers deploying to AgentCore need to construct the runtime URL from their ARN — without this utility they’ll do it themselves (and can get the URL-encoding of the ARN wrong). |
…routes Create the Starlette app with the /ping route included in the constructor, then use add_routes_to_app() to wire A2A endpoints. This avoids depending on route mutation after build().
|
Addressed review comment from @sundargthb in 8588bb9: refactored to build the |
notgitika
left a comment
There was a problem hiding this comment.
Following up on @sundargthb's earlier comment. what's the plan for build_runtime_url(agent_arn, region)?
If it's coming in a follow-up, might be worth tracking it in an issue so it doesn't get lost.
Adds build_runtime_url(agent_arn, region=None) that constructs the Bedrock AgentCore runtime invocation URL from an agent ARN, properly URL-encoding the ARN. Extracts region from the ARN if not provided.
|
Added from bedrock_agentcore.runtime import build_runtime_url
url = build_runtime_url('arn:aws:bedrock-agentcore:us-east-1:123456789012:runtime/my-agent-abc123')
# https://bedrock-agentcore.us-east-1.amazonaws.com/runtimes/arn%3Aaws%3A.../invocations@sundargthb and @notgitika this addresses your comment about the missing third component from the proposal. |
Adds [tool.ruff.lint.isort] known-third-party = ["a2a"] so ruff classifies a2a imports consistently regardless of whether a2a-sdk is installed in the lint environment.
Summary
serve_a2a,build_a2a_app,build_runtime_url, andBedrockCallContextBuildertobedrock_agentcore.runtimea2a-sdkpip install "bedrock-agentcore[a2a]"— lazy-loaded so non-A2A users are unaffectedAgentCardfromStrandsA2AExecutorwhen not providedagent_card.urlfromAGENTCORE_RUNTIME_URLenv var on deploybuild_runtime_url(agent_arn)utility for constructing invocation URLs from ARNs0.0.0.0vs127.0.0.1/pinghealth check endpoint with Bedrock-compatible response formatBedrockAgentCoreContextcontextvarsdocs/examples/a2a_protocol_examples.md+ README sectionWhy
PR #217 reimplemented A2A from scratch (~1700 lines). The industry (ADK, Strands, CrewAI) has converged on the official
a2a-sdk. This replaces that approach with minimal glue that delegates protocol handling to the SDK.Strands
Google ADK
LangGraph
Test plan
tests/bedrock_agentcore/runtime/test_a2a.pytests/integration/runtime/test_a2a_integration.pyAGENTCORE_RUNTIME_URLruff check/ruff formatclean