diff --git a/src/google/adk/cli/cli_tools_click.py b/src/google/adk/cli/cli_tools_click.py index f884bce61a..29484a3bca 100644 --- a/src/google/adk/cli/cli_tools_click.py +++ b/src/google/adk/cli/cli_tools_click.py @@ -1806,8 +1806,8 @@ 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 `agent.py` or `root_agent.yaml` files) or a path pointing - directly to a single agent folder. + agent containing `agent.py`, `__init__.py`, or `root_agent.yaml`) or a path + pointing directly to a single agent folder. Example: @@ -1947,8 +1947,8 @@ def cli_api_server( """Starts a FastAPI server for agents. AGENTS_DIR: The directory of agents (where each subdirectory is a single - agent containing `agent.py` or `root_agent.yaml` files) or a path pointing - directly to a single agent folder. + agent containing `agent.py`, `__init__.py`, or `root_agent.yaml`) or a path + pointing directly to a single agent folder. Example: diff --git a/src/google/adk/cli/utils/agent_loader.py b/src/google/adk/cli/utils/agent_loader.py index dd5e0ed81a..1a865fd104 100644 --- a/src/google/adk/cli/utils/agent_loader.py +++ b/src/google/adk/cli/utils/agent_loader.py @@ -471,6 +471,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}'.") diff --git a/tests/unittests/cli/utils/test_agent_loader.py b/tests/unittests/cli/utils/test_agent_loader.py index 6e682ba7d8..52935a9a8d 100644 --- a/tests/unittests/cli/utils/test_agent_loader.py +++ b/tests/unittests/cli/utils/test_agent_loader.py @@ -1039,3 +1039,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")