diff --git a/contributing/samples/adk_agent_builder_assistant/tools/write_files.py b/contributing/samples/adk_agent_builder_assistant/tools/write_files.py index 088f8c41..953a04b2 100644 --- a/contributing/samples/adk_agent_builder_assistant/tools/write_files.py +++ b/contributing/samples/adk_agent_builder_assistant/tools/write_files.py @@ -19,6 +19,8 @@ from pathlib import Path import shutil from typing import Any from typing import Dict +from typing import List +from typing import Optional from google.adk.tools.tool_context import ToolContext @@ -57,6 +59,12 @@ async def write_files( try: # Get session state for path resolution session_state = tool_context._invocation_context.session.state + project_root: Optional[Path] = None + if session_state is not None: + try: + project_root = resolve_file_path(".", session_state).resolve() + except Exception: + project_root = None result = { "success": True, @@ -76,6 +84,7 @@ async def write_files( "backup_created": False, "backup_path": None, "error": None, + "package_inits_created": [], } try: @@ -86,6 +95,11 @@ async def write_files( if create_directories: file_path_obj.parent.mkdir(parents=True, exist_ok=True) + if file_path_obj.suffix == ".py" and project_root is not None: + created_inits = _ensure_package_inits(file_path_obj, project_root) + if created_inits: + file_info["package_inits_created"] = created_inits + # Create backup if requested and file exists if create_backup and file_info["existed_before"]: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") @@ -130,3 +144,38 @@ async def write_files( "total_files": len(files) if files else 0, "errors": [f"Write operation failed: {str(e)}"], } + + +def _ensure_package_inits( + file_path: Path, + project_root: Path, +) -> List[str]: + """Ensure __init__.py files exist for importable subpackages (not project root).""" + created_inits: List[str] = [] + try: + target_parent = file_path.parent.resolve() + root_path = project_root.resolve() + relative_parent = target_parent.relative_to(root_path) + except Exception: + return created_inits + + def _touch_init(directory: Path) -> None: + init_file = directory / "__init__.py" + if not init_file.exists(): + init_file.touch() + created_inits.append(str(init_file)) + + root_path.mkdir(parents=True, exist_ok=True) + + if not relative_parent.parts: + return created_inits + + current_path = root_path + for part in relative_parent.parts: + if part in (".", ""): + continue + current_path = current_path / part + current_path.mkdir(parents=True, exist_ok=True) + _touch_init(current_path) + + return created_inits