Skip to content

Commit fbe6a7b

Browse files
yeesiancopybara-github
authored andcommitted
fix: Add absolutize_imports option when deploying to agent engine
PiperOrigin-RevId: 786749263
1 parent bfc203a commit fbe6a7b

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ classifiers = [ # List of https://pypi.org/classifiers/
2626
dependencies = [
2727
# go/keep-sorted start
2828
"PyYAML>=6.0.2", # For APIHubToolset.
29+
"absolufy-imports>=0.3.1", # For Agent Engine deployment.
2930
"anyio>=4.9.0;python_version>='3.10'", # For MCP Session Manager
3031
"authlib>=1.5.1", # For RestAPI Tool
3132
"click>=8.1.8", # For CLI tools

src/google/adk/cli/cli_deploy.py

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"""
6060

6161
_AGENT_ENGINE_APP_TEMPLATE = """
62-
from agent import root_agent
62+
from {app_name}.agent import root_agent
6363
from vertexai.preview.reasoning_engines import AdkApp
6464
6565
adk_app = AdkApp(
@@ -254,6 +254,7 @@ def to_agent_engine(
254254
adk_app: str,
255255
staging_bucket: str,
256256
trace_to_cloud: bool,
257+
absolutize_imports: bool = True,
257258
project: Optional[str] = None,
258259
region: Optional[str] = None,
259260
display_name: Optional[str] = None,
@@ -293,6 +294,8 @@ def to_agent_engine(
293294
region (str): Google Cloud region.
294295
staging_bucket (str): The GCS bucket for staging the deployment artifacts.
295296
trace_to_cloud (bool): Whether to enable Cloud Trace.
297+
absolutize_imports (bool): Whether to absolutize imports. If True, all relative
298+
imports will be converted to absolute import statements. Default is True.
296299
requirements_file (str): The filepath to the `requirements.txt` file to use.
297300
If not specified, the `requirements.txt` file in the `agent_folder` will
298301
be used.
@@ -301,14 +304,16 @@ def to_agent_engine(
301304
values of `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` will be
302305
overridden by `project` and `region` if they are specified.
303306
"""
304-
# remove temp_folder if it exists
305-
if os.path.exists(temp_folder):
307+
app_name = os.path.basename(agent_folder)
308+
agent_src_path = os.path.join(temp_folder, app_name)
309+
# remove agent_src_path if it exists
310+
if os.path.exists(agent_src_path):
306311
click.echo('Removing existing files')
307-
shutil.rmtree(temp_folder)
312+
shutil.rmtree(agent_src_path)
308313

309314
try:
310315
click.echo('Copying agent source code...')
311-
shutil.copytree(agent_folder, temp_folder)
316+
shutil.copytree(agent_folder, agent_src_path)
312317
click.echo('Copying agent source code complete.')
313318

314319
click.echo('Initializing Vertex AI...')
@@ -317,13 +322,13 @@ def to_agent_engine(
317322
import vertexai
318323
from vertexai import agent_engines
319324

320-
sys.path.append(temp_folder)
325+
sys.path.append(temp_folder) # To register the adk_app operations
321326
project = _resolve_project(project)
322327

323328
click.echo('Resolving files and dependencies...')
324329
if not requirements_file:
325330
# Attempt to read requirements from requirements.txt in the dir (if any).
326-
requirements_txt_path = os.path.join(temp_folder, 'requirements.txt')
331+
requirements_txt_path = os.path.join(agent_src_path, 'requirements.txt')
327332
if not os.path.exists(requirements_txt_path):
328333
click.echo(f'Creating {requirements_txt_path}...')
329334
with open(requirements_txt_path, 'w', encoding='utf-8') as f:
@@ -333,7 +338,7 @@ def to_agent_engine(
333338
env_vars = None
334339
if not env_file:
335340
# Attempt to read the env variables from .env in the dir (if any).
336-
env_file = os.path.join(temp_folder, '.env')
341+
env_file = os.path.join(agent_src_path, '.env')
337342
if os.path.exists(env_file):
338343
from dotenv import dotenv_values
339344

@@ -371,21 +376,35 @@ def to_agent_engine(
371376
)
372377
click.echo('Vertex AI initialized.')
373378

374-
adk_app_file = f'{adk_app}.py'
375-
with open(
376-
os.path.join(temp_folder, adk_app_file), 'w', encoding='utf-8'
377-
) as f:
379+
adk_app_file = os.path.join(temp_folder, f'{adk_app}.py')
380+
with open(adk_app_file, 'w', encoding='utf-8') as f:
378381
f.write(
379382
_AGENT_ENGINE_APP_TEMPLATE.format(
380-
trace_to_cloud_option=trace_to_cloud
383+
app_name=app_name,
384+
trace_to_cloud_option=trace_to_cloud,
381385
)
382386
)
383-
click.echo(f'Created {os.path.join(temp_folder, adk_app_file)}')
387+
click.echo(f'Created {adk_app_file}')
384388
click.echo('Files and dependencies resolved')
389+
if absolutize_imports:
390+
for root, _, files in os.walk(agent_src_path):
391+
for file in files:
392+
if file.endswith('.py'):
393+
absolutize_imports_path = os.path.join(root, file)
394+
try:
395+
click.echo(
396+
f'Running `absolufy-imports {absolutize_imports_path}`'
397+
)
398+
subprocess.run(
399+
['absolufy-imports', absolutize_imports_path],
400+
cwd=temp_folder,
401+
)
402+
except Exception as e:
403+
click.echo(f'The following exception was raised: {e}')
385404

386405
click.echo('Deploying to agent engine...')
387406
agent_engine = agent_engines.ModuleAgent(
388-
module_name=adk_app,
407+
module_name='agent_engine_app',
389408
agent_name='adk_app',
390409
register_operations={
391410
'': [

src/google/adk/cli/cli_tools_click.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,16 @@ def cli_deploy_cloud_run(
10551055
" any.)"
10561056
),
10571057
)
1058+
@click.option(
1059+
"--absolutize_imports",
1060+
type=bool,
1061+
default=True,
1062+
help=(
1063+
"Optional. Whether to absolutize imports. If True, all relative imports"
1064+
" will be converted to absolute import statements (default: True)."
1065+
" NOTE: This flag is temporary and will be removed in the future."
1066+
),
1067+
)
10581068
@click.argument(
10591069
"agent",
10601070
type=click.Path(
@@ -1073,11 +1083,10 @@ def cli_deploy_agent_engine(
10731083
temp_folder: str,
10741084
env_file: str,
10751085
requirements_file: str,
1086+
absolutize_imports: bool,
10761087
):
10771088
"""Deploys an agent to Agent Engine.
10781089
1079-
AGENT: The path to the agent source code folder.
1080-
10811090
Example:
10821091
10831092
adk deploy agent_engine --project=[project] --region=[region]
@@ -1097,6 +1106,7 @@ def cli_deploy_agent_engine(
10971106
temp_folder=temp_folder,
10981107
env_file=env_file,
10991108
requirements_file=requirements_file,
1109+
absolutize_imports=absolutize_imports,
11001110
)
11011111
except Exception as e:
11021112
click.secho(f"Deploy failed: {e}", fg="red", err=True)

0 commit comments

Comments
 (0)