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:release/v2.0.0-beta.1from
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:release/v2.0.0-beta.1from
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant