diff --git a/src/google/adk/cli/cli_deploy.py b/src/google/adk/cli/cli_deploy.py index 2772cf1d3b..3db2ec3f44 100644 --- a/src/google/adk/cli/cli_deploy.py +++ b/src/google/adk/cli/cli_deploy.py @@ -642,6 +642,8 @@ def _validate_agent_import( # Add parent directory to path so imports work correctly if parent_dir not in sys.path: sys.path.insert(0, parent_dir) + + importlib.invalidate_caches() try: module = importlib.import_module(f'{module_name}.agent') except ImportError as e: diff --git a/tests/unittests/cli/utils/test_cli_deploy.py b/tests/unittests/cli/utils/test_cli_deploy.py index eea406f018..064a7d9050 100644 --- a/tests/unittests/cli/utils/test_cli_deploy.py +++ b/tests/unittests/cli/utils/test_cli_deploy.py @@ -18,6 +18,7 @@ import importlib import json +import os from pathlib import Path import shutil import subprocess @@ -781,6 +782,38 @@ def test_success_with_relative_imports(self, tmp_path: Path) -> None: str(tmp_path), "root_agent", is_config_agent=False ) + def test_invalidates_import_cache_for_new_agent( + self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch + ) -> None: + """Should discover an agent created after the import cache is primed.""" + parent_dir = tmp_path / "agents" + parent_dir.mkdir() + + # Prime Python's import cache before the agent package exists. + monkeypatch.syspath_prepend(str(parent_dir)) + + with pytest.raises(ModuleNotFoundError): + importlib.import_module("new_agent.agent") + + parent_stat = parent_dir.stat() + + # Create the agent package after the parent directory was already scanned. + agent_dir = parent_dir / "new_agent" + agent_dir.mkdir() + (agent_dir / "__init__.py").touch() + (agent_dir / "agent.py").write_text("root_agent = 'my_agent'\n") + + # Keep the directory timestamp unchanged so the cached directory contents + # remain stale unless importlib caches are explicitly invalidated. + os.utime( + parent_dir, + ns=(parent_stat.st_atime_ns, parent_stat.st_mtime_ns), + ) + + cli_deploy._validate_agent_import( + str(agent_dir), "root_agent", is_config_agent=False + ) + def test_raises_on_import_error(self, tmp_path: Path) -> None: """Should raise with helpful message on ImportError.""" agent_file = tmp_path / "agent.py"