Validates that the agent module can be imported successfully. This pre-deployment validation catches common issues like missing dependencies or import errors in custom BaseLlm implementations before the agent is deployed to Agent Engine. This provides clearer error messages and prevents dep
(
agent_src_path: str,
adk_app_object: str,
is_config_agent: bool,
)
| 452 | |
| 453 | |
| 454 | def _validate_agent_import( |
| 455 | agent_src_path: str, |
| 456 | adk_app_object: str, |
| 457 | is_config_agent: bool, |
| 458 | ) -> None: |
| 459 | """Validates that the agent module can be imported successfully. |
| 460 | |
| 461 | This pre-deployment validation catches common issues like missing |
| 462 | dependencies or import errors in custom BaseLlm implementations before |
| 463 | the agent is deployed to Agent Engine. This provides clearer error |
| 464 | messages and prevents deployments that would fail at runtime. |
| 465 | |
| 466 | Args: |
| 467 | agent_src_path: Path to the staged agent source code. |
| 468 | adk_app_object: The Python object name to import ('root_agent' or 'app'). |
| 469 | is_config_agent: Whether this is a config-based agent. |
| 470 | |
| 471 | Raises: |
| 472 | click.ClickException: If the agent module cannot be imported. |
| 473 | """ |
| 474 | if is_config_agent: |
| 475 | # Config agents are loaded from YAML, skip Python import validation |
| 476 | return |
| 477 | |
| 478 | agent_module_path = os.path.join(agent_src_path, 'agent.py') |
| 479 | if not os.path.exists(agent_module_path): |
| 480 | raise click.ClickException( |
| 481 | f'Agent module not found at {agent_module_path}. ' |
| 482 | 'Please ensure your agent folder contains an agent.py file.' |
| 483 | ) |
| 484 | |
| 485 | # Add the parent directory to sys.path temporarily for import resolution |
| 486 | parent_dir = os.path.dirname(agent_src_path) |
| 487 | module_name = os.path.basename(agent_src_path) |
| 488 | |
| 489 | original_sys_path = sys.path.copy() |
| 490 | original_sys_modules_keys = set(sys.modules.keys()) |
| 491 | try: |
| 492 | # Add parent directory to path so imports work correctly |
| 493 | if parent_dir not in sys.path: |
| 494 | sys.path.insert(0, parent_dir) |
| 495 | try: |
| 496 | module = importlib.import_module(f'{module_name}.agent') |
| 497 | except ImportError as e: |
| 498 | error_msg = str(e) |
| 499 | tb = traceback.format_exc() |
| 500 | |
| 501 | # Check for common issues |
| 502 | if 'BaseLlm' in tb or 'base_llm' in tb.lower(): |
| 503 | raise click.ClickException( |
| 504 | 'Failed to import agent module due to a BaseLlm-related error:\n' |
| 505 | f'{error_msg}\n\n' |
| 506 | 'This error often occurs when deploying agents with custom LLM ' |
| 507 | 'implementations. Please ensure:\n' |
| 508 | '1. All custom LLM classes are defined in files within your agent ' |
| 509 | 'folder\n' |
| 510 | '2. All required dependencies are listed in requirements.txt\n' |
| 511 | '3. Import paths use relative imports (e.g., "from .my_llm import ' |