Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/google/adk/cli/cli_tools_click.py
Original file line number Diff line number Diff line change
Expand Up @@ -1632,8 +1632,9 @@ def cli_web(
):
"""Starts a FastAPI server with Web UI for agents.

AGENTS_DIR: The directory of agents, where each subdirectory is a single
agent, containing at least `__init__.py` and `agent.py` files.
AGENTS_DIR: The directory of agents, where each entry is a single agent —
either a subdirectory (containing `agent.py`, `__init__.py`, or
`root_agent.yaml`) or a flat `<agent_name>.py` module file.

Example:

Expand Down Expand Up @@ -1745,8 +1746,9 @@ def cli_api_server(
):
"""Starts a FastAPI server for agents.

AGENTS_DIR: The directory of agents, where each subdirectory is a single
agent, containing at least `__init__.py` and `agent.py` files.
AGENTS_DIR: The directory of agents, where each entry is a single agent —
either a subdirectory (containing `agent.py`, `__init__.py`, or
`root_agent.yaml`) or a flat `<agent_name>.py` module file.

Example:

Expand Down
2 changes: 2 additions & 0 deletions src/google/adk/cli/utils/agent_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ def _determine_agent_language(
return "python"
elif (base_path / "__init__.py").exists():
return "python"
elif (base_path.parent / f"{agent_name}.py").exists():
return "python"

raise ValueError(f"Could not determine agent type for '{agent_name}'.")

Expand Down
53 changes: 53 additions & 0 deletions tests/unittests/cli/utils/test_agent_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -1006,3 +1006,56 @@ def test_validate_agent_name_rejects_nonexistent_agent(self):
# 'subprocess' is a valid identifier but shouldn't be importable as an agent
with pytest.raises(ValueError, match="Agent not found"):
loader.load_agent("subprocess")


class TestDetermineAgentLanguage:
"""Tests for AgentLoader._determine_agent_language covering all 4 load patterns."""

def test_flat_module_returns_python(self):
"""Flat-module agent (agents_dir/agent_name.py) is detected as python."""
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
(temp_path / "my_agent.py").write_text("root_agent = None\n")
loader = AgentLoader(temp_dir)
assert loader._determine_agent_language("my_agent") == "python"

def test_agent_py_subdirectory_returns_python(self):
"""Subdirectory with agent.py is detected as python."""
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
agent_dir = temp_path / "my_agent"
agent_dir.mkdir()
(agent_dir / "agent.py").write_text("root_agent = None\n")
loader = AgentLoader(temp_dir)
assert loader._determine_agent_language("my_agent") == "python"

def test_init_py_subdirectory_returns_python(self):
"""Subdirectory with __init__.py is detected as python."""
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
agent_dir = temp_path / "my_agent"
agent_dir.mkdir()
(agent_dir / "__init__.py").write_text("root_agent = None\n")
loader = AgentLoader(temp_dir)
assert loader._determine_agent_language("my_agent") == "python"

def test_root_agent_yaml_returns_yaml(self):
"""Subdirectory with root_agent.yaml is detected as yaml."""
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
agent_dir = temp_path / "my_agent"
agent_dir.mkdir()
(agent_dir / "root_agent.yaml").write_text("root_agent: {}\n")
loader = AgentLoader(temp_dir)
assert loader._determine_agent_language("my_agent") == "yaml"

def test_unrecognized_structure_raises_value_error(self):
"""A directory with no recognized structure raises ValueError."""
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
agent_dir = temp_path / "my_agent"
agent_dir.mkdir()
(agent_dir / "main.py").write_text("root_agent = None\n")
loader = AgentLoader(temp_dir)
with pytest.raises(ValueError, match="Could not determine agent type"):
loader._determine_agent_language("my_agent")