Repository navigation
A2A on a2a-sdk 1.x: build the routes through ADK's compat layer - #224
Merged
Merged
Conversation
adk_main.py was written for a2a-sdk 0.3. On the pinned 1.2.1,
a2a.server.apps is gone, so --a2a printed "A2A dependencies not
available" and mounted no /a2a routes, which broke A2A and agents
exposed over MCP (the bridge calls /a2a/{agent}).
The routes and cards are now built in shared/utils/a2a_routes.py through
google.adk.a2a._compat, which supports 0.3 and 1.x; on 1.x the 0.3 method
names stay accepted. The default card names the agent's own endpoint,
and agent.json files in the 0.3 form are still read. The MCP bridge reads
the reply from the task's artifacts instead of returning the whole task.
A test mounts the routes and calls both method names, so a breaking
dependency bump fails CI.
Fixes #223
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.
Fixes #223.
What was wrong
requirements.lockpinsa2a-sdk==1.2.1, butadk_main.pyused the 0.3 API (a2a.server.apps.A2AStarletteApplication, a pydanticAgentCard). On 1.x the import fails.--a2a, which the dashboard always passes, printed "A2A dependencies not available" and mounted no/a2a/*routes. A2A calls failed, and so did agents exposed over MCP: the bridge calls/a2a/{agent}.It went unnoticed locally because a venv that wasn't reinstalled from the lock still had a2a-sdk 0.3.22.
The fix
shared/utils/a2a_routes.pybuilds each agent's card and routes throughgoogle.adk.a2a._compat(parse_agent_card,attach_a2a_routes_to_app), the same way ADK's own--a2adoes. It works on 0.3.x and 1.x.adk_main.pykeeps its agent discovery (files, database, runners) and calls it. A missing dependency still gets the "A2A dependencies not available" message.message/send) keep working.urlis nowhttp://localhost:8000/a2a/{agent}, the agent's endpoint, instead of the server root. A client resolving the card would have posted to the wrong URL. The base address is still fixed; MATE has no public-URL setting.text/plain, what the executor reads and writes.metadatablock is dropped; 1.x cards have no such field.agents/<name>/agent.jsonis still merged over the default, and 0.3-form files are converted byparse_agent_card.agent_mcp_protocol_handler.py) now takes the reply text from the task's artifacts, or a failed task's status message. It used to return the whole task as a Python dict string, since ADK's executor answers with a task rather than a message.Checks
Venv installed from
requirements.lock(a2a-sdk 1.2.1, google-adk 2.11.0). The server started throughauth_server.py, which starts ADK with--a2a. Through the auth server:GET /a2a/creative_agent/.well-known/agent-card.json→ 200. The card is in 1.x form, withsupportedInterfaces[0].url = http://localhost:8000/a2a/creative_agent.message/send(0.3) topisac_root→ taskcompleted, reply "Zdravo".SendMessage(1.x,A2A-Version: 1.0) topisac_root→TASK_STATE_COMPLETED, with a reply.tools/callonchess_mate_root(/agents/chess_mate_root/mcp) →[{"type": "text", "text": "chess"}]. Before the bridge change, the same call returned the whole task as a dict string.shared/test/test_a2a_routes.py, 11 tests. It mounts the routes on a FastAPI app with an echo executor and checks:/a2a/{agent};agent.jsonmerge;message/sendandSendMessageboth answered;A dependency bump that breaks this now fails CI.
Full suite: 1467 OK.
gen_docs.py --check: OK.Docs
gen_docs.py driftflagsdocs/dev/a2a.mdanddocs/dev/architecture.md.architecture.mdonly says the agent server starts with--a2a, which still holds.a2a.mdis being rewritten in docs(dev): verify a2a guide against code and remove migrated status (#206) #217, so I left it out of this PR to avoid a conflict. What it needs to say after this:SendMessage,SendStreamingMessage,GetTask,CancelTask,GetExtendedAgentCard) and the 0.3 ones (message/send,message/stream,tasks/get, ...) are accepted.supportedInterfaces, noturl).agent.jsonmay be in either form.http://localhost:8000/a2a/{agent}.