1919import shutil
2020from typing import Any
2121from typing import Dict
22+ from typing import List
23+ from typing import Optional
2224
2325from google .adk .tools .tool_context import ToolContext
2426
@@ -57,6 +59,12 @@ async def write_files(
5759 try :
5860 # Get session state for path resolution
5961 session_state = tool_context ._invocation_context .session .state
62+ project_root : Optional [Path ] = None
63+ if session_state is not None :
64+ try :
65+ project_root = resolve_file_path ("." , session_state ).resolve ()
66+ except Exception :
67+ project_root = None
6068
6169 result = {
6270 "success" : True ,
@@ -76,6 +84,7 @@ async def write_files(
7684 "backup_created" : False ,
7785 "backup_path" : None ,
7886 "error" : None ,
87+ "package_inits_created" : [],
7988 }
8089
8190 try :
@@ -86,6 +95,11 @@ async def write_files(
8695 if create_directories :
8796 file_path_obj .parent .mkdir (parents = True , exist_ok = True )
8897
98+ if file_path_obj .suffix == ".py" and project_root is not None :
99+ created_inits = _ensure_package_inits (file_path_obj , project_root )
100+ if created_inits :
101+ file_info ["package_inits_created" ] = created_inits
102+
89103 # Create backup if requested and file exists
90104 if create_backup and file_info ["existed_before" ]:
91105 timestamp = datetime .now ().strftime ("%Y%m%d_%H%M%S" )
@@ -130,3 +144,38 @@ async def write_files(
130144 "total_files" : len (files ) if files else 0 ,
131145 "errors" : [f"Write operation failed: { str (e )} " ],
132146 }
147+
148+
149+ def _ensure_package_inits (
150+ file_path : Path ,
151+ project_root : Path ,
152+ ) -> List [str ]:
153+ """Ensure __init__.py files exist for importable subpackages (not project root)."""
154+ created_inits : List [str ] = []
155+ try :
156+ target_parent = file_path .parent .resolve ()
157+ root_path = project_root .resolve ()
158+ relative_parent = target_parent .relative_to (root_path )
159+ except Exception :
160+ return created_inits
161+
162+ def _touch_init (directory : Path ) -> None :
163+ init_file = directory / "__init__.py"
164+ if not init_file .exists ():
165+ init_file .touch ()
166+ created_inits .append (str (init_file ))
167+
168+ root_path .mkdir (parents = True , exist_ok = True )
169+
170+ if not relative_parent .parts :
171+ return created_inits
172+
173+ current_path = root_path
174+ for part in relative_parent .parts :
175+ if part in ("." , "" ):
176+ continue
177+ current_path = current_path / part
178+ current_path .mkdir (parents = True , exist_ok = True )
179+ _touch_init (current_path )
180+
181+ return created_inits
0 commit comments