google-adk 0.1.1__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. google/adk/agents/base_agent.py +4 -4
  2. google/adk/agents/callback_context.py +0 -1
  3. google/adk/agents/invocation_context.py +1 -1
  4. google/adk/agents/remote_agent.py +1 -1
  5. google/adk/agents/run_config.py +1 -1
  6. google/adk/auth/auth_credential.py +2 -1
  7. google/adk/auth/auth_handler.py +7 -3
  8. google/adk/auth/auth_preprocessor.py +2 -2
  9. google/adk/auth/auth_tool.py +1 -1
  10. google/adk/cli/browser/index.html +2 -2
  11. google/adk/cli/browser/{main-SLIAU2JL.js → main-HWIBUY2R.js} +69 -69
  12. google/adk/cli/cli_create.py +279 -0
  13. google/adk/cli/cli_deploy.py +10 -1
  14. google/adk/cli/cli_eval.py +3 -3
  15. google/adk/cli/cli_tools_click.py +95 -19
  16. google/adk/cli/fast_api.py +57 -16
  17. google/adk/cli/utils/envs.py +0 -3
  18. google/adk/cli/utils/evals.py +2 -2
  19. google/adk/evaluation/agent_evaluator.py +2 -2
  20. google/adk/evaluation/evaluation_generator.py +4 -4
  21. google/adk/evaluation/response_evaluator.py +17 -5
  22. google/adk/evaluation/trajectory_evaluator.py +4 -5
  23. google/adk/events/event.py +3 -3
  24. google/adk/flows/llm_flows/_nl_planning.py +10 -4
  25. google/adk/flows/llm_flows/agent_transfer.py +1 -1
  26. google/adk/flows/llm_flows/base_llm_flow.py +1 -1
  27. google/adk/flows/llm_flows/contents.py +2 -2
  28. google/adk/flows/llm_flows/functions.py +1 -3
  29. google/adk/flows/llm_flows/instructions.py +2 -2
  30. google/adk/models/gemini_llm_connection.py +2 -2
  31. google/adk/models/lite_llm.py +51 -34
  32. google/adk/models/llm_response.py +10 -1
  33. google/adk/planners/built_in_planner.py +1 -0
  34. google/adk/planners/plan_re_act_planner.py +2 -2
  35. google/adk/runners.py +1 -1
  36. google/adk/sessions/database_session_service.py +91 -26
  37. google/adk/sessions/state.py +2 -2
  38. google/adk/telemetry.py +2 -2
  39. google/adk/tools/agent_tool.py +2 -3
  40. google/adk/tools/application_integration_tool/clients/integration_client.py +3 -2
  41. google/adk/tools/base_tool.py +1 -1
  42. google/adk/tools/function_parameter_parse_util.py +2 -2
  43. google/adk/tools/google_api_tool/__init__.py +74 -1
  44. google/adk/tools/google_api_tool/google_api_tool_set.py +12 -9
  45. google/adk/tools/google_api_tool/google_api_tool_sets.py +91 -34
  46. google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +3 -1
  47. google/adk/tools/load_artifacts_tool.py +1 -1
  48. google/adk/tools/load_memory_tool.py +25 -2
  49. google/adk/tools/mcp_tool/mcp_session_manager.py +176 -0
  50. google/adk/tools/mcp_tool/mcp_tool.py +15 -2
  51. google/adk/tools/mcp_tool/mcp_toolset.py +31 -37
  52. google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +4 -4
  53. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +1 -1
  54. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +5 -12
  55. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +47 -9
  56. google/adk/tools/toolbox_tool.py +1 -1
  57. google/adk/version.py +1 -1
  58. google_adk-0.3.0.dist-info/METADATA +235 -0
  59. {google_adk-0.1.1.dist-info → google_adk-0.3.0.dist-info}/RECORD +62 -60
  60. google_adk-0.1.1.dist-info/METADATA +0 -181
  61. {google_adk-0.1.1.dist-info → google_adk-0.3.0.dist-info}/WHEEL +0 -0
  62. {google_adk-0.1.1.dist-info → google_adk-0.3.0.dist-info}/entry_points.txt +0 -0
  63. {google_adk-0.1.1.dist-info → google_adk-0.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,279 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import os
16
+ import subprocess
17
+ from typing import Optional
18
+ from typing import Tuple
19
+
20
+ import click
21
+
22
+ _INIT_PY_TEMPLATE = """\
23
+ from . import agent
24
+ """
25
+
26
+ _AGENT_PY_TEMPLATE = """\
27
+ from google.adk.agents import Agent
28
+
29
+ root_agent = Agent(
30
+ model='{model_name}',
31
+ name='root_agent',
32
+ description='A helpful assistant for user questions.',
33
+ instruction='Answer user questions to the best of your knowledge',
34
+ )
35
+ """
36
+
37
+
38
+ _GOOGLE_API_MSG = """
39
+ Don't have API Key? Create one in AI Studio: https://aistudio.google.com/apikey
40
+ """
41
+
42
+ _GOOGLE_CLOUD_SETUP_MSG = """
43
+ You need an existing Google Cloud account and project, check out this link for details:
44
+ https://google.github.io/adk-docs/get-started/quickstart/#gemini---google-cloud-vertex-ai
45
+ """
46
+
47
+ _OTHER_MODEL_MSG = """
48
+ Please see below guide to configure other models:
49
+ https://google.github.io/adk-docs/agents/models
50
+ """
51
+
52
+ _SUCCESS_MSG = """
53
+ Agent created in {agent_folder}:
54
+ - .env
55
+ - __init__.py
56
+ - agent.py
57
+ """
58
+
59
+
60
+ def _get_gcp_project_from_gcloud() -> str:
61
+ """Uses gcloud to get default project."""
62
+ try:
63
+ result = subprocess.run(
64
+ ["gcloud", "config", "get-value", "project"],
65
+ capture_output=True,
66
+ text=True,
67
+ check=True,
68
+ )
69
+ return result.stdout.strip()
70
+ except (subprocess.CalledProcessError, FileNotFoundError):
71
+ return ""
72
+
73
+
74
+ def _get_gcp_region_from_gcloud() -> str:
75
+ """Uses gcloud to get default region."""
76
+ try:
77
+ result = subprocess.run(
78
+ ["gcloud", "config", "get-value", "compute/region"],
79
+ capture_output=True,
80
+ text=True,
81
+ check=True,
82
+ )
83
+ return result.stdout.strip()
84
+ except (subprocess.CalledProcessError, FileNotFoundError):
85
+ return ""
86
+
87
+
88
+ def _prompt_str(
89
+ prompt_prefix: str,
90
+ *,
91
+ prior_msg: Optional[str] = None,
92
+ default_value: Optional[str] = None,
93
+ ) -> str:
94
+ if prior_msg:
95
+ click.secho(prior_msg, fg="green")
96
+ while True:
97
+ value: str = click.prompt(
98
+ prompt_prefix, default=default_value or None, type=str
99
+ )
100
+ if value and value.strip():
101
+ return value.strip()
102
+
103
+
104
+ def _prompt_for_google_cloud(
105
+ google_cloud_project: Optional[str],
106
+ ) -> str:
107
+ """Prompts user for Google Cloud project ID."""
108
+ google_cloud_project = (
109
+ google_cloud_project
110
+ or os.environ.get("GOOGLE_CLOUD_PROJECT", None)
111
+ or _get_gcp_project_from_gcloud()
112
+ )
113
+
114
+ google_cloud_project = _prompt_str(
115
+ "Enter Google Cloud project ID", default_value=google_cloud_project
116
+ )
117
+
118
+ return google_cloud_project
119
+
120
+
121
+ def _prompt_for_google_cloud_region(
122
+ google_cloud_region: Optional[str],
123
+ ) -> str:
124
+ """Prompts user for Google Cloud region."""
125
+ google_cloud_region = (
126
+ google_cloud_region
127
+ or os.environ.get("GOOGLE_CLOUD_LOCATION", None)
128
+ or _get_gcp_region_from_gcloud()
129
+ )
130
+
131
+ google_cloud_region = _prompt_str(
132
+ "Enter Google Cloud region",
133
+ default_value=google_cloud_region or "us-central1",
134
+ )
135
+ return google_cloud_region
136
+
137
+
138
+ def _prompt_for_google_api_key(
139
+ google_api_key: Optional[str],
140
+ ) -> str:
141
+ """Prompts user for Google API key."""
142
+ google_api_key = google_api_key or os.environ.get("GOOGLE_API_KEY", None)
143
+
144
+ google_api_key = _prompt_str(
145
+ "Enter Google API key",
146
+ prior_msg=_GOOGLE_API_MSG,
147
+ default_value=google_api_key,
148
+ )
149
+ return google_api_key
150
+
151
+
152
+ def _generate_files(
153
+ agent_folder: str,
154
+ *,
155
+ google_api_key: Optional[str] = None,
156
+ google_cloud_project: Optional[str] = None,
157
+ google_cloud_region: Optional[str] = None,
158
+ model: Optional[str] = None,
159
+ ):
160
+ """Generates a folder name for the agent."""
161
+ os.makedirs(agent_folder, exist_ok=True)
162
+
163
+ dotenv_file_path = os.path.join(agent_folder, ".env")
164
+ init_file_path = os.path.join(agent_folder, "__init__.py")
165
+ agent_file_path = os.path.join(agent_folder, "agent.py")
166
+
167
+ with open(dotenv_file_path, "w", encoding="utf-8") as f:
168
+ lines = []
169
+ if google_api_key:
170
+ lines.append("GOOGLE_GENAI_USE_VERTEXAI=0")
171
+ elif google_cloud_project and google_cloud_region:
172
+ lines.append("GOOGLE_GENAI_USE_VERTEXAI=1")
173
+ if google_api_key:
174
+ lines.append(f"GOOGLE_API_KEY={google_api_key}")
175
+ if google_cloud_project:
176
+ lines.append(f"GOOGLE_CLOUD_PROJECT={google_cloud_project}")
177
+ if google_cloud_region:
178
+ lines.append(f"GOOGLE_CLOUD_LOCATION={google_cloud_region}")
179
+ f.write("\n".join(lines))
180
+
181
+ with open(init_file_path, "w", encoding="utf-8") as f:
182
+ f.write(_INIT_PY_TEMPLATE)
183
+
184
+ with open(agent_file_path, "w", encoding="utf-8") as f:
185
+ f.write(_AGENT_PY_TEMPLATE.format(model_name=model))
186
+
187
+ click.secho(
188
+ _SUCCESS_MSG.format(agent_folder=agent_folder),
189
+ fg="green",
190
+ )
191
+
192
+
193
+ def _prompt_for_model() -> str:
194
+ model_choice = click.prompt(
195
+ """\
196
+ Choose a model for the root agent:
197
+ 1. gemini-2.0-flash-001
198
+ 2. Other models (fill later)
199
+ Choose model""",
200
+ type=click.Choice(["1", "2"]),
201
+ )
202
+ if model_choice == "1":
203
+ return "gemini-2.0-flash-001"
204
+ else:
205
+ click.secho(_OTHER_MODEL_MSG, fg="green")
206
+ return "<FILL_IN_MODEL>"
207
+
208
+
209
+ def _prompt_to_choose_backend(
210
+ google_api_key: Optional[str],
211
+ google_cloud_project: Optional[str],
212
+ google_cloud_region: Optional[str],
213
+ ) -> Tuple[Optional[str], Optional[str], Optional[str]]:
214
+ """Prompts user to choose backend.
215
+
216
+ Returns:
217
+ A tuple of (google_api_key, google_cloud_project, google_cloud_region).
218
+ """
219
+ backend_choice = click.prompt(
220
+ "1. Google AI\n2. Vertex AI\nChoose a backend",
221
+ type=click.Choice(["1", "2"]),
222
+ )
223
+ if backend_choice == "1":
224
+ google_api_key = _prompt_for_google_api_key(google_api_key)
225
+ elif backend_choice == "2":
226
+ click.secho(_GOOGLE_CLOUD_SETUP_MSG, fg="green")
227
+ google_cloud_project = _prompt_for_google_cloud(google_cloud_project)
228
+ google_cloud_region = _prompt_for_google_cloud_region(google_cloud_region)
229
+ return google_api_key, google_cloud_project, google_cloud_region
230
+
231
+
232
+ def run_cmd(
233
+ agent_name: str,
234
+ *,
235
+ model: Optional[str],
236
+ google_api_key: Optional[str],
237
+ google_cloud_project: Optional[str],
238
+ google_cloud_region: Optional[str],
239
+ ):
240
+ """Runs `adk create` command to create agent template.
241
+
242
+ Args:
243
+ agent_name: str, The name of the agent.
244
+ google_api_key: Optional[str], The Google API key for using Google AI as
245
+ backend.
246
+ google_cloud_project: Optional[str], The Google Cloud project for using
247
+ VertexAI as backend.
248
+ google_cloud_region: Optional[str], The Google Cloud region for using
249
+ VertexAI as backend.
250
+ """
251
+ agent_folder = os.path.join(os.getcwd(), agent_name)
252
+ # check folder doesn't exist or it's empty. Otherwise, throw
253
+ if os.path.exists(agent_folder) and os.listdir(agent_folder):
254
+ # Prompt user whether to override existing files using click
255
+ if not click.confirm(
256
+ f"Non-empty folder already exist: '{agent_folder}'\n"
257
+ "Override existing content?",
258
+ default=False,
259
+ ):
260
+ raise click.Abort()
261
+
262
+ if not model:
263
+ model = _prompt_for_model()
264
+
265
+ if not google_api_key and not (google_cloud_project and google_cloud_region):
266
+ if model.startswith("gemini"):
267
+ google_api_key, google_cloud_project, google_cloud_region = (
268
+ _prompt_to_choose_backend(
269
+ google_api_key, google_cloud_project, google_cloud_region
270
+ )
271
+ )
272
+
273
+ _generate_files(
274
+ agent_folder,
275
+ google_api_key=google_api_key,
276
+ google_cloud_project=google_cloud_project,
277
+ google_cloud_region=google_cloud_region,
278
+ model=model,
279
+ )
@@ -54,7 +54,7 @@ COPY "agents/{app_name}/" "/app/agents/{app_name}/"
54
54
 
55
55
  EXPOSE {port}
56
56
 
57
- CMD adk {command} --port={port} {trace_to_cloud_option} "/app/agents"
57
+ CMD adk {command} --port={port} {session_db_option} {trace_to_cloud_option} "/app/agents"
58
58
  """
59
59
 
60
60
 
@@ -84,6 +84,8 @@ def to_cloud_run(
84
84
  port: int,
85
85
  trace_to_cloud: bool,
86
86
  with_ui: bool,
87
+ verbosity: str,
88
+ session_db_url: str,
87
89
  ):
88
90
  """Deploys an agent to Google Cloud Run.
89
91
 
@@ -110,6 +112,8 @@ def to_cloud_run(
110
112
  port: The port of the ADK api server.
111
113
  trace_to_cloud: Whether to enable Cloud Trace.
112
114
  with_ui: Whether to deploy with UI.
115
+ verbosity: The verbosity level of the CLI.
116
+ session_db_url: The database URL to connect the session.
113
117
  """
114
118
  app_name = app_name or os.path.basename(agent_folder)
115
119
 
@@ -142,6 +146,9 @@ def to_cloud_run(
142
146
  port=port,
143
147
  command='web' if with_ui else 'api_server',
144
148
  install_agent_deps=install_agent_deps,
149
+ session_db_option=f'--session_db_url={session_db_url}'
150
+ if session_db_url
151
+ else '',
145
152
  trace_to_cloud_option='--trace_to_cloud' if trace_to_cloud else '',
146
153
  )
147
154
  dockerfile_path = os.path.join(temp_folder, 'Dockerfile')
@@ -169,6 +176,8 @@ def to_cloud_run(
169
176
  *region_options,
170
177
  '--port',
171
178
  str(port),
179
+ '--verbosity',
180
+ verbosity,
172
181
  '--labels',
173
182
  'created-by=adk',
174
183
  ],
@@ -112,14 +112,14 @@ def get_evaluation_criteria_or_default(
112
112
 
113
113
 
114
114
  def get_root_agent(agent_module_file_path: str) -> Agent:
115
- """Returns root agent given the agetn module."""
115
+ """Returns root agent given the agent module."""
116
116
  agent_module = _get_agent_module(agent_module_file_path)
117
117
  root_agent = agent_module.agent.root_agent
118
118
  return root_agent
119
119
 
120
120
 
121
121
  def try_get_reset_func(agent_module_file_path: str) -> Any:
122
- """Returns reset function for the agent, if present, given the agetn module."""
122
+ """Returns reset function for the agent, if present, given the agent module."""
123
123
  agent_module = _get_agent_module(agent_module_file_path)
124
124
  reset_func = getattr(agent_module.agent, "reset_data", None)
125
125
  return reset_func
@@ -256,7 +256,7 @@ def run_evals(
256
256
  )
257
257
 
258
258
  if final_eval_status == EvalStatus.PASSED:
259
- result = "✅ Passsed"
259
+ result = "✅ Passed"
260
260
  else:
261
261
  result = "❌ Failed"
262
262
 
@@ -24,6 +24,7 @@ import click
24
24
  from fastapi import FastAPI
25
25
  import uvicorn
26
26
 
27
+ from . import cli_create
27
28
  from . import cli_deploy
28
29
  from .cli import run_cli
29
30
  from .cli_eval import MISSING_EVAL_DEPENDENCIES_MESSAGE
@@ -42,10 +43,59 @@ def main():
42
43
 
43
44
  @main.group()
44
45
  def deploy():
45
- """Deploy Agent."""
46
+ """Deploys agent to hosted environments."""
46
47
  pass
47
48
 
48
49
 
50
+ @main.command("create")
51
+ @click.option(
52
+ "--model",
53
+ type=str,
54
+ help="Optional. The model used for the root agent.",
55
+ )
56
+ @click.option(
57
+ "--api_key",
58
+ type=str,
59
+ help=(
60
+ "Optional. The API Key needed to access the model, e.g. Google AI API"
61
+ " Key."
62
+ ),
63
+ )
64
+ @click.option(
65
+ "--project",
66
+ type=str,
67
+ help="Optional. The Google Cloud Project for using VertexAI as backend.",
68
+ )
69
+ @click.option(
70
+ "--region",
71
+ type=str,
72
+ help="Optional. The Google Cloud Region for using VertexAI as backend.",
73
+ )
74
+ @click.argument("app_name", type=str, required=True)
75
+ def cli_create_cmd(
76
+ app_name: str,
77
+ model: Optional[str],
78
+ api_key: Optional[str],
79
+ project: Optional[str],
80
+ region: Optional[str],
81
+ ):
82
+ """Creates a new app in the current folder with prepopulated agent template.
83
+
84
+ APP_NAME: required, the folder of the agent source code.
85
+
86
+ Example:
87
+
88
+ adk create path/to/my_app
89
+ """
90
+ cli_create.run_cmd(
91
+ app_name,
92
+ model=model,
93
+ google_api_key=api_key,
94
+ google_cloud_project=project,
95
+ google_cloud_region=region,
96
+ )
97
+
98
+
49
99
  @main.command("run")
50
100
  @click.option(
51
101
  "--save_session",
@@ -62,7 +112,7 @@ def deploy():
62
112
  ),
63
113
  )
64
114
  def cli_run(agent: str, save_session: bool):
65
- """Run an interactive CLI for a certain agent.
115
+ """Runs an interactive CLI for a certain agent.
66
116
 
67
117
  AGENT: The path to the agent source code folder.
68
118
 
@@ -195,12 +245,13 @@ def cli_eval(
195
245
  @click.option(
196
246
  "--session_db_url",
197
247
  help=(
198
- "Optional. The database URL to store the session.\n\n - Use"
199
- " 'agentengine://<agent_engine_resource_id>' to connect to Vertex"
200
- " managed session service.\n\n - Use 'sqlite://<path_to_sqlite_file>'"
201
- " to connect to a SQLite DB.\n\n - See"
202
- " https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls"
203
- " for more details on supported DB URLs."
248
+ """Optional. The database URL to store the session.
249
+
250
+ - Use 'agentengine://<agent_engine_resource_id>' to connect to Agent Engine sessions.
251
+
252
+ - Use 'sqlite://<path_to_sqlite_file>' to connect to a SQLite DB.
253
+
254
+ - See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls for more details on supported DB URLs."""
204
255
  ),
205
256
  )
206
257
  @click.option(
@@ -244,7 +295,7 @@ def cli_eval(
244
295
  type=click.Path(
245
296
  exists=True, dir_okay=True, file_okay=False, resolve_path=True
246
297
  ),
247
- default=os.getcwd(),
298
+ default=os.getcwd,
248
299
  )
249
300
  def cli_web(
250
301
  agents_dir: str,
@@ -255,7 +306,7 @@ def cli_web(
255
306
  port: int = 8000,
256
307
  trace_to_cloud: bool = False,
257
308
  ):
258
- """Start a FastAPI server with Web UI for agents.
309
+ """Starts a FastAPI server with Web UI for agents.
259
310
 
260
311
  AGENTS_DIR: The directory of agents, where each sub-directory is a single
261
312
  agent, containing at least `__init__.py` and `agent.py` files.
@@ -274,7 +325,7 @@ def cli_web(
274
325
  @asynccontextmanager
275
326
  async def _lifespan(app: FastAPI):
276
327
  click.secho(
277
- f"""\
328
+ f"""
278
329
  +-----------------------------------------------------------------------------+
279
330
  | ADK Web Server started |
280
331
  | |
@@ -285,7 +336,7 @@ def cli_web(
285
336
  )
286
337
  yield # Startup is done, now app is running
287
338
  click.secho(
288
- """\
339
+ """
289
340
  +-----------------------------------------------------------------------------+
290
341
  | ADK Web Server shutting down... |
291
342
  +-----------------------------------------------------------------------------+
@@ -316,12 +367,13 @@ def cli_web(
316
367
  @click.option(
317
368
  "--session_db_url",
318
369
  help=(
319
- "Optional. The database URL to store the session.\n\n - Use"
320
- " 'agentengine://<agent_engine_resource_id>' to connect to Vertex"
321
- " managed session service.\n\n - Use 'sqlite://<path_to_sqlite_file>'"
322
- " to connect to a SQLite DB.\n\n - See"
323
- " https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls"
324
- " for more details on supported DB URLs."
370
+ """Optional. The database URL to store the session.
371
+
372
+ - Use 'agentengine://<agent_engine_resource_id>' to connect to Agent Engine sessions.
373
+
374
+ - Use 'sqlite://<path_to_sqlite_file>' to connect to a SQLite DB.
375
+
376
+ - See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls for more details on supported DB URLs."""
325
377
  ),
326
378
  )
327
379
  @click.option(
@@ -378,7 +430,7 @@ def cli_api_server(
378
430
  port: int = 8000,
379
431
  trace_to_cloud: bool = False,
380
432
  ):
381
- """Start a FastAPI server for agents.
433
+ """Starts a FastAPI server for agents.
382
434
 
383
435
  AGENTS_DIR: The directory of agents, where each sub-directory is a single
384
436
  agent, containing at least `__init__.py` and `agent.py` files.
@@ -483,6 +535,26 @@ def cli_api_server(
483
535
  " (default: a timestamped folder in the system temp directory)."
484
536
  ),
485
537
  )
538
+ @click.option(
539
+ "--verbosity",
540
+ type=click.Choice(
541
+ ["debug", "info", "warning", "error", "critical"], case_sensitive=False
542
+ ),
543
+ default="WARNING",
544
+ help="Optional. Override the default verbosity level.",
545
+ )
546
+ @click.option(
547
+ "--session_db_url",
548
+ help=(
549
+ """Optional. The database URL to store the session.
550
+
551
+ - Use 'agentengine://<agent_engine_resource_id>' to connect to Agent Engine sessions.
552
+
553
+ - Use 'sqlite://<path_to_sqlite_file>' to connect to a SQLite DB.
554
+
555
+ - See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls for more details on supported DB URLs."""
556
+ ),
557
+ )
486
558
  @click.argument(
487
559
  "agent",
488
560
  type=click.Path(
@@ -499,6 +571,8 @@ def cli_deploy_cloud_run(
499
571
  port: int,
500
572
  trace_to_cloud: bool,
501
573
  with_ui: bool,
574
+ verbosity: str,
575
+ session_db_url: str,
502
576
  ):
503
577
  """Deploys an agent to Cloud Run.
504
578
 
@@ -519,6 +593,8 @@ def cli_deploy_cloud_run(
519
593
  port=port,
520
594
  trace_to_cloud=trace_to_cloud,
521
595
  with_ui=with_ui,
596
+ verbosity=verbosity,
597
+ session_db_url=session_db_url,
522
598
  )
523
599
  except Exception as e:
524
600
  click.secho(f"Deploy failed: {e}", fg="red", err=True)