Skip to content

fix(a2a): Support to_a2a(Workflow) and reject non-agent root nodes#5710

Open
sokoliva wants to merge 1 commit into
google:mainfrom
sokoliva:fix/5487-to-a2a-workflow
Open

fix(a2a): Support to_a2a(Workflow) and reject non-agent root nodes#5710
sokoliva wants to merge 1 commit into
google:mainfrom
sokoliva:fix/5487-to-a2a-workflow

Conversation

@sokoliva
Copy link
Copy Markdown
Member

Link to Issue

Problem:
to_a2a(workflow) fails because AgentCardBuilder requires field sub_agents which Workflow does not have.

Solution:

  • Make to_a2a() and AgentCardBuilder accept Workflow (the v2 graph orchestrator) as a root, not just BaseAgent. Previously crashed withRuntimeError: 'Workflow' object has no attribute 'sub_agents'.
  • Tighten the public type contract to BaseAgent | Workflow and reject other BaseNode subtypes (e.g. FunctionNode, JoinNode) at call time with TypeError. They previously produced a degenerate "custom agent" card silently.

Testing Plan

tests/unittests/a2a/utils/test_agent_card_builder.py — 9 new tests:

  • test_get_agent_type_workflow — returns 'graph_workflow' for the new v2 Workflow.
  • test_get_agent_skill_name_workflow — returns 'workflow' for Workflow.
  • test_init_rejects_function_node — AgentCardBuilder(agent=FunctionNode(...)) raises TypeError (regression coverage for the runtime guard).
  • test_init_rejects_arbitrary_object — AgentCardBuilder(agent="...") raises TypeError.
  • test_build_succeeds_for_llm_agent — regression coverage that the original BaseAgent path still works after the type narrowing.
  • test_build_succeeds_for_workflow_with_llm_agent_node — exact OP repro shape, end-to-end through build().
  • test_build_succeeds_for_workflow_with_output_schema_node — covers the output_schema shape mentioned in the issue.
  • test_build_succeeds_for_empty_workflow — degenerate but valid case (no edges).
  • test_get_workflow_description_workflow_with_nodes — verifies graph nodes appear in the description string.
  • test_get_workflow_description_empty_workflow — returns None when no nodes.
    tests/unittests/a2a/utils/test_agent_to_a2a.py — 2 new tests, 1 rewritten:
  • test_to_a2a_succeeds_for_workflow (new) — end-to-end through the actual Starlette lifespan (the exact code path that crashed in the OP's repro).
  • test_to_a2a_rejects_function_node (new) — to_a2a(FunctionNode(...)) raises TypeError at call time.
  • test_to_a2a_rejects_non_agent_non_workflow (rewrote existing test_to_a2a_with_invalid_agent_type) — now asserts TypeError raised eagerly at to_a2a() call time instead of AttributeError raised lazily during request handling. This is a deliberate behavior change, not a regression: the old test encoded buggy lazy-failure UX where misuse only surfaced when a client hit the endpoint.

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Please include a summary of passed pytest results.
ran uv run pytest tests/unittests

6275 passed, 14 skipped, 25 xfailed, 10 xpassed, 2532 warnings

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

@sokoliva sokoliva changed the base branch from main to release/v2.0.0-beta.1 May 15, 2026 08:40
@sokoliva sokoliva changed the title Fix/5487 to a2a workflow fix(a2a): Support to_a2a(Workflow) and reject non-agent root nodes May 15, 2026
@rohityan rohityan self-assigned this May 18, 2026
@rohityan rohityan added the a2a [Component] This issue is related a2a support inside ADK. label May 18, 2026
@rohityan rohityan closed this May 18, 2026
@rohityan rohityan reopened this May 20, 2026
@haranrk haranrk self-assigned this May 21, 2026
@haranrk haranrk added the ready to pull [Status] This PR is ready to be imported back to Google label May 29, 2026
@sokoliva sokoliva changed the base branch from release/v2.0.0-beta.1 to main June 1, 2026 07:33
@sokoliva sokoliva changed the base branch from main to release/v2.0.0-beta.1 June 1, 2026 08:20
@sokoliva sokoliva force-pushed the fix/5487-to-a2a-workflow branch from b3eac05 to f3f5019 Compare June 1, 2026 08:26
@sokoliva sokoliva changed the base branch from release/v2.0.0-beta.1 to main June 1, 2026 08:26
@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a2a [Component] This issue is related a2a support inside ADK. core [Component] This issue is related to the core interface and implementation ready to pull [Status] This PR is ready to be imported back to Google

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants