Skip to content

evals: AgentConfig.from_agent raises AttributeError for workflow / non-LlmAgent root agents (no 'tools' field) #6865

@eliasecchig

Description

@eliasecchig

Environment

  • google-cloud-aiplatform: 1.156.0
  • google-adk: 2.2.0
  • Python: 3.12

Summary

vertexai.types.evals.AgentConfig.from_agent() raises AttributeError when the root agent is a workflow / non-LlmAgent agent — i.e. any BaseAgent subclass such as SequentialAgent, ParallelAgent, LoopAgent, or a custom BaseAgent. Those agents do not define a tools field; only LlmAgent does.

_get_tool_declarations_from_agent reads agent.tools directly (no default), whereas the sibling fields in from_agent (description, instruction, sub_agents) all use getattr(agent, ..., default). As a result, introspection fails before any inference runs, which makes client-side eval impossible for any multi-agent system whose root is an orchestrator.

This affects every public entry point that introspects a live agent:

  • client.evals.run_inference(agent=...)AgentConfig.from_agent(agent)
  • types.evals.AgentInfo.load_from_agent(agent=...)AgentData.get_agents_map(agent)AgentConfig.from_agent(agent)

Reproduction

from google.adk.agents import LlmAgent, SequentialAgent
from vertexai import types

leaf = LlmAgent(name="step", model="gemini-2.5-flash", instruction="do a step")
wf = SequentialAgent(name="pipeline", sub_agents=[leaf])

types.evals.AgentConfig.from_agent(wf)

Actual behavior

Traceback (most recent call last):
  File ".../vertexai/_genai/types/evals.py", line 128, in from_agent
    tools=AgentConfig._get_tool_declarations_from_agent(agent),
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../vertexai/_genai/types/evals.py", line 86, in _get_tool_declarations_from_agent
    for tool in agent.tools:
                ^^^^^^^^^^^
  File ".../pydantic/main.py", line 1042, in __getattr__
    raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
AttributeError: 'SequentialAgent' object has no attribute 'tools'

The same failure occurs via client.evals.run_inference(agent=wf) and types.evals.AgentInfo.load_from_agent(agent=wf), since both reach AgentConfig.from_agent.

Expected behavior

from_agent should treat a missing tools field as "no tools", consistent with how it already handles instruction and sub_agents. A workflow root with LlmAgent leaves should produce an AgentConfig with empty tools for the root and recurse into sub_agents normally.

Suggested fix

In _get_tool_declarations_from_agent (vertexai/_genai/types/evals.py, and the mirrored agentplatform/_genai/types/evals.py copy), iterate over a guarded value:

for tool in getattr(agent, "tools", None) or []:
    ...

This mirrors the existing getattr(...) usage for the other fields in from_agent.

Related

Distinct from #6861 / #6862, which addressed a TypeError for toolset elements within tools (e.g. McpToolset). Here the tools attribute is absent entirely. Both point at the same fragile extraction path.

Workaround

Inject an empty list before introspection:

if not hasattr(root_agent, "tools"):
    object.__setattr__(root_agent, "tools", [])

Metadata

Metadata

Assignees

No one assigned

    Labels

    api: vertex-aiIssues related to the googleapis/python-aiplatform API.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions