google-adk 1.4.2__py3-none-any.whl → 1.5.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.
@@ -0,0 +1,90 @@
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
+ from __future__ import annotations
16
+
17
+ import sys
18
+ from typing import Any
19
+
20
+ try:
21
+ from a2a.server.agent_execution import RequestContext
22
+ except ImportError as e:
23
+ if sys.version_info < (3, 10):
24
+ raise ImportError(
25
+ 'A2A Tool requires Python 3.10 or above. Please upgrade your Python'
26
+ ' version.'
27
+ ) from e
28
+ else:
29
+ raise e
30
+
31
+ from google.genai import types as genai_types
32
+
33
+ from ...runners import RunConfig
34
+ from ...utils.feature_decorator import working_in_progress
35
+ from .part_converter import convert_a2a_part_to_genai_part
36
+ from .utils import _from_a2a_context_id
37
+ from .utils import _get_adk_metadata_key
38
+
39
+
40
+ def _get_user_id(request: RequestContext, user_id_from_context: str) -> str:
41
+ # Get user from call context if available (auth is enabled on a2a server)
42
+ if request.call_context and request.call_context.user:
43
+ return request.call_context.user.user_name
44
+
45
+ # Get user from context id if available
46
+ if user_id_from_context:
47
+ return user_id_from_context
48
+
49
+ # Get user from message metadata if available (client is an ADK agent)
50
+ if request.message.metadata:
51
+ user_id = request.message.metadata.get(_get_adk_metadata_key('user_id'))
52
+ if user_id:
53
+ return f'ADK_USER_{user_id}'
54
+
55
+ # Get user from task if available (client is a an ADK agent)
56
+ if request.current_task:
57
+ user_id = request.current_task.metadata.get(
58
+ _get_adk_metadata_key('user_id')
59
+ )
60
+ if user_id:
61
+ return f'ADK_USER_{user_id}'
62
+ return (
63
+ f'temp_user_{request.task_id}'
64
+ if request.task_id
65
+ else f'TEMP_USER_{request.message.messageId}'
66
+ )
67
+
68
+
69
+ @working_in_progress
70
+ def convert_a2a_request_to_adk_run_args(
71
+ request: RequestContext,
72
+ ) -> dict[str, Any]:
73
+
74
+ if not request.message:
75
+ raise ValueError('Request message cannot be None')
76
+
77
+ _, user_id, session_id = _from_a2a_context_id(request.context_id)
78
+
79
+ return {
80
+ 'user_id': _get_user_id(request, user_id),
81
+ 'session_id': session_id,
82
+ 'new_message': genai_types.Content(
83
+ role='user',
84
+ parts=[
85
+ convert_a2a_part_to_genai_part(part)
86
+ for part in request.message.parts
87
+ ],
88
+ ),
89
+ 'run_config': RunConfig(),
90
+ }
@@ -15,6 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  ADK_METADATA_KEY_PREFIX = "adk_"
18
+ ADK_CONTEXT_ID_PREFIX = "ADK"
18
19
 
19
20
 
20
21
  def _get_adk_metadata_key(key: str) -> str:
@@ -32,3 +33,39 @@ def _get_adk_metadata_key(key: str) -> str:
32
33
  if not key:
33
34
  raise ValueError("Metadata key cannot be empty or None")
34
35
  return f"{ADK_METADATA_KEY_PREFIX}{key}"
36
+
37
+
38
+ def _to_a2a_context_id(app_name: str, user_id: str, session_id: str) -> str:
39
+ """Converts app name, user id and session id to an A2A context id.
40
+
41
+ Args:
42
+ app_name: The app name.
43
+ user_id: The user id.
44
+ session_id: The session id.
45
+
46
+ Returns:
47
+ The A2A context id.
48
+ """
49
+ return [ADK_CONTEXT_ID_PREFIX, app_name, user_id, session_id].join("$")
50
+
51
+
52
+ def _from_a2a_context_id(context_id: str) -> tuple[str, str, str]:
53
+ """Converts an A2A context id to app name, user id and session id.
54
+ if context_id is None, return None, None, None
55
+ if context_id is not None, but not in the format of
56
+ ADK$app_name$user_id$session_id, return None, None, None
57
+
58
+ Args:
59
+ context_id: The A2A context id.
60
+
61
+ Returns:
62
+ The app name, user id and session id.
63
+ """
64
+ if not context_id:
65
+ return None, None, None
66
+
67
+ prefix, app_name, user_id, session_id = context_id.split("$")
68
+ if prefix == "ADK" and app_name and user_id and session_id:
69
+ return app_name, user_id, session_id
70
+
71
+ return None, None, None
@@ -161,10 +161,12 @@ class LlmAgent(BaseAgent):
161
161
  # LLM-based agent transfer configs - End
162
162
 
163
163
  include_contents: Literal['default', 'none'] = 'default'
164
- """Whether to include contents in the model request.
164
+ """Controls content inclusion in model requests.
165
165
 
166
- When set to 'none', the model request will not include any contents, such as
167
- user messages, tool results, etc.
166
+ Options:
167
+ default: Model receives relevant conversation history
168
+ none: Model receives no prior history, operates solely on current
169
+ instruction and input
168
170
  """
169
171
 
170
172
  # Controlled input/output configurations - Start
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """An artifact service implementation using Google Cloud Storage (GCS)."""
16
+ from __future__ import annotations
16
17
 
17
18
  import logging
18
19
  from typing import Optional
@@ -151,7 +152,7 @@ class GcsArtifactService(BaseArtifactService):
151
152
  self.bucket, prefix=session_prefix
152
153
  )
153
154
  for blob in session_blobs:
154
- _, _, _, filename, _ = blob.name.split("/")
155
+ *_, filename, _ = blob.name.split("/")
155
156
  filenames.add(filename)
156
157
 
157
158
  user_namespace_prefix = f"{app_name}/{user_id}/user/"
@@ -159,7 +160,7 @@ class GcsArtifactService(BaseArtifactService):
159
160
  self.bucket, prefix=user_namespace_prefix
160
161
  )
161
162
  for blob in user_namespace_blobs:
162
- _, _, _, filename, _ = blob.name.split("/")
163
+ *_, filename, _ = blob.name.split("/")
163
164
  filenames.add(filename)
164
165
 
165
166
  return sorted(list(filenames))
@@ -31,12 +31,12 @@ class AuthConfig(BaseModelWithConfig):
31
31
 
32
32
  auth_scheme: AuthScheme
33
33
  """The auth scheme used to collect credentials"""
34
- raw_auth_credential: AuthCredential = None
34
+ raw_auth_credential: Optional[AuthCredential] = None
35
35
  """The raw auth credential used to collect credentials. The raw auth
36
36
  credentials are used in some auth scheme that needs to exchange auth
37
37
  credentials. e.g. OAuth2 and OIDC. For other auth scheme, it could be None.
38
38
  """
39
- exchanged_auth_credential: AuthCredential = None
39
+ exchanged_auth_credential: Optional[AuthCredential] = None
40
40
  """The exchanged auth credential used to collect credentials. adk and client
41
41
  will work together to fill it. For those auth scheme that doesn't need to
42
42
  exchange auth credentials, e.g. API key, service account etc. It's filled by
@@ -0,0 +1,83 @@
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
+ from __future__ import annotations
16
+
17
+ from typing import Optional
18
+
19
+ from typing_extensions import override
20
+
21
+ from ...tools.tool_context import ToolContext
22
+ from ...utils.feature_decorator import experimental
23
+ from ..auth_credential import AuthCredential
24
+ from ..auth_tool import AuthConfig
25
+ from .base_credential_service import BaseCredentialService
26
+
27
+
28
+ @experimental
29
+ class SessionStateCredentialService(BaseCredentialService):
30
+ """Class for implementation of credential service using session state as the
31
+ store.
32
+ Note: store credential in session may not be secure, use at your own risk.
33
+ """
34
+
35
+ @override
36
+ async def load_credential(
37
+ self,
38
+ auth_config: AuthConfig,
39
+ tool_context: ToolContext,
40
+ ) -> Optional[AuthCredential]:
41
+ """
42
+ Loads the credential by auth config and current tool context from the
43
+ backend credential store.
44
+
45
+ Args:
46
+ auth_config: The auth config which contains the auth scheme and auth
47
+ credential information. auth_config.get_credential_key will be used to
48
+ build the key to load the credential.
49
+
50
+ tool_context: The context of the current invocation when the tool is
51
+ trying to load the credential.
52
+
53
+ Returns:
54
+ Optional[AuthCredential]: the credential saved in the store.
55
+
56
+ """
57
+ return tool_context.state.get(auth_config.credential_key)
58
+
59
+ @override
60
+ async def save_credential(
61
+ self,
62
+ auth_config: AuthConfig,
63
+ tool_context: ToolContext,
64
+ ) -> None:
65
+ """
66
+ Saves the exchanged_auth_credential in auth config to the backend credential
67
+ store.
68
+
69
+ Args:
70
+ auth_config: The auth config which contains the auth scheme and auth
71
+ credential information. auth_config.get_credential_key will be used to
72
+ build the key to save the credential.
73
+
74
+ tool_context: The context of the current invocation when the tool is
75
+ trying to save the credential.
76
+
77
+ Returns:
78
+ None
79
+ """
80
+
81
+ tool_context.state[auth_config.credential_key] = (
82
+ auth_config.exchanged_auth_credential
83
+ )
@@ -55,7 +55,7 @@ COPY "agents/{app_name}/" "/app/agents/{app_name}/"
55
55
 
56
56
  EXPOSE {port}
57
57
 
58
- CMD adk {command} --port={port} {host_option} {service_option} {trace_to_cloud_option} "/app/agents"
58
+ CMD adk {command} --port={port} {host_option} {service_option} {trace_to_cloud_option} {allow_origins_option} "/app/agents"
59
59
  """
60
60
 
61
61
  _AGENT_ENGINE_APP_TEMPLATE = """
@@ -121,8 +121,10 @@ def to_cloud_run(
121
121
  port: int,
122
122
  trace_to_cloud: bool,
123
123
  with_ui: bool,
124
+ log_level: str,
124
125
  verbosity: str,
125
126
  adk_version: str,
127
+ allow_origins: Optional[list[str]] = None,
126
128
  session_service_uri: Optional[str] = None,
127
129
  artifact_service_uri: Optional[str] = None,
128
130
  memory_service_uri: Optional[str] = None,
@@ -150,6 +152,7 @@ def to_cloud_run(
150
152
  app_name: The name of the app, by default, it's basename of `agent_folder`.
151
153
  temp_folder: The temp folder for the generated Cloud Run source files.
152
154
  port: The port of the ADK api server.
155
+ allow_origins: The list of allowed origins for the ADK api server.
153
156
  trace_to_cloud: Whether to enable Cloud Trace.
154
157
  with_ui: Whether to deploy with UI.
155
158
  verbosity: The verbosity level of the CLI.
@@ -183,6 +186,9 @@ def to_cloud_run(
183
186
  # create Dockerfile
184
187
  click.echo('Creating Dockerfile...')
185
188
  host_option = '--host=0.0.0.0' if adk_version > '0.5.0' else ''
189
+ allow_origins_option = (
190
+ f'--allow_origins={",".join(allow_origins)}' if allow_origins else ''
191
+ )
186
192
  dockerfile_content = _DOCKERFILE_TEMPLATE.format(
187
193
  gcp_project_id=project,
188
194
  gcp_region=region,
@@ -197,6 +203,7 @@ def to_cloud_run(
197
203
  memory_service_uri,
198
204
  ),
199
205
  trace_to_cloud_option='--trace_to_cloud' if trace_to_cloud else '',
206
+ allow_origins_option=allow_origins_option,
200
207
  adk_version=adk_version,
201
208
  host_option=host_option,
202
209
  )
@@ -226,7 +233,7 @@ def to_cloud_run(
226
233
  '--port',
227
234
  str(port),
228
235
  '--verbosity',
229
- verbosity,
236
+ log_level.lower() if log_level else verbosity,
230
237
  '--labels',
231
238
  'created-by=adk',
232
239
  ],
@@ -31,14 +31,22 @@ import uvicorn
31
31
  from . import cli_create
32
32
  from . import cli_deploy
33
33
  from .. import version
34
+ from ..evaluation.gcs_eval_set_results_manager import GcsEvalSetResultsManager
35
+ from ..evaluation.gcs_eval_sets_manager import GcsEvalSetsManager
34
36
  from ..evaluation.local_eval_set_results_manager import LocalEvalSetResultsManager
35
37
  from ..sessions.in_memory_session_service import InMemorySessionService
36
38
  from .cli import run_cli
37
39
  from .cli_eval import MISSING_EVAL_DEPENDENCIES_MESSAGE
38
40
  from .fast_api import get_fast_api_app
39
41
  from .utils import envs
42
+ from .utils import evals
40
43
  from .utils import logs
41
44
 
45
+ LOG_LEVELS = click.Choice(
46
+ ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
47
+ case_sensitive=False,
48
+ )
49
+
42
50
 
43
51
  class HelpfulCommand(click.Command):
44
52
  """Command that shows full help on error instead of just the error message.
@@ -277,11 +285,21 @@ def cli_run(
277
285
  default=False,
278
286
  help="Optional. Whether to print detailed results on console or not.",
279
287
  )
288
+ @click.option(
289
+ "--eval_storage_uri",
290
+ type=str,
291
+ help=(
292
+ "Optional. The evals storage URI to store agent evals,"
293
+ " supported URIs: gs://<bucket name>."
294
+ ),
295
+ default=None,
296
+ )
280
297
  def cli_eval(
281
298
  agent_module_file_path: str,
282
- eval_set_file_path: tuple[str],
299
+ eval_set_file_path: list[str],
283
300
  config_file_path: str,
284
301
  print_detailed_results: bool,
302
+ eval_storage_uri: Optional[str] = None,
285
303
  ):
286
304
  """Evaluates an agent given the eval sets.
287
305
 
@@ -333,12 +351,33 @@ def cli_eval(
333
351
  root_agent = get_root_agent(agent_module_file_path)
334
352
  reset_func = try_get_reset_func(agent_module_file_path)
335
353
 
354
+ gcs_eval_sets_manager = None
355
+ eval_set_results_manager = None
356
+ if eval_storage_uri:
357
+ gcs_eval_managers = evals.create_gcs_eval_managers_from_uri(
358
+ eval_storage_uri
359
+ )
360
+ gcs_eval_sets_manager = gcs_eval_managers.eval_sets_manager
361
+ eval_set_results_manager = gcs_eval_managers.eval_set_results_manager
362
+ else:
363
+ eval_set_results_manager = LocalEvalSetResultsManager(
364
+ agents_dir=os.path.dirname(agent_module_file_path)
365
+ )
336
366
  eval_set_file_path_to_evals = parse_and_get_evals_to_run(eval_set_file_path)
337
367
  eval_set_id_to_eval_cases = {}
338
368
 
339
369
  # Read the eval_set files and get the cases.
340
370
  for eval_set_file_path, eval_case_ids in eval_set_file_path_to_evals.items():
341
- eval_set = load_eval_set_from_file(eval_set_file_path, eval_set_file_path)
371
+ if gcs_eval_sets_manager:
372
+ eval_set = gcs_eval_sets_manager._load_eval_set_from_blob(
373
+ eval_set_file_path
374
+ )
375
+ if not eval_set:
376
+ raise click.ClickException(
377
+ f"Eval set {eval_set_file_path} not found in GCS."
378
+ )
379
+ else:
380
+ eval_set = load_eval_set_from_file(eval_set_file_path, eval_set_file_path)
342
381
  eval_cases = eval_set.eval_cases
343
382
 
344
383
  if eval_case_ids:
@@ -373,16 +412,13 @@ def cli_eval(
373
412
  raise click.ClickException(MISSING_EVAL_DEPENDENCIES_MESSAGE)
374
413
 
375
414
  # Write eval set results.
376
- local_eval_set_results_manager = LocalEvalSetResultsManager(
377
- agents_dir=os.path.dirname(agent_module_file_path)
378
- )
379
415
  eval_set_id_to_eval_results = collections.defaultdict(list)
380
416
  for eval_case_result in eval_results:
381
417
  eval_set_id = eval_case_result.eval_set_id
382
418
  eval_set_id_to_eval_results[eval_set_id].append(eval_case_result)
383
419
 
384
420
  for eval_set_id, eval_case_results in eval_set_id_to_eval_results.items():
385
- local_eval_set_results_manager.save_eval_set_result(
421
+ eval_set_results_manager.save_eval_set_result(
386
422
  app_name=os.path.basename(agent_module_file_path),
387
423
  eval_set_id=eval_set_id,
388
424
  eval_case_results=eval_case_results,
@@ -439,12 +475,22 @@ def adk_services_options():
439
475
  ),
440
476
  default=None,
441
477
  )
478
+ @click.option(
479
+ "--eval_storage_uri",
480
+ type=str,
481
+ help=(
482
+ "Optional. The evals storage URI to store agent evals,"
483
+ " supported URIs: gs://<bucket name>."
484
+ ),
485
+ default=None,
486
+ )
442
487
  @click.option(
443
488
  "--memory_service_uri",
444
489
  type=str,
445
490
  help=(
446
491
  """Optional. The URI of the memory service.
447
- - Use 'rag://<rag_corpus_id>' to connect to Vertex AI Rag Memory Service."""
492
+ - Use 'rag://<rag_corpus_id>' to connect to Vertex AI Rag Memory Service.
493
+ - Use 'agentengine://<agent_engine_resource_id>' to connect to Vertex AI Memory Bank Service. e.g. agentengine://12345"""
448
494
  ),
449
495
  default=None,
450
496
  )
@@ -498,13 +544,6 @@ def fast_api_common_options():
498
544
  """Decorator to add common fast api options to click commands."""
499
545
 
500
546
  def decorator(func):
501
- @click.option(
502
- "--host",
503
- type=str,
504
- help="Optional. The binding host of the server",
505
- default="127.0.0.1",
506
- show_default=True,
507
- )
508
547
  @click.option(
509
548
  "--port",
510
549
  type=int,
@@ -518,10 +557,7 @@ def fast_api_common_options():
518
557
  )
519
558
  @click.option(
520
559
  "--log_level",
521
- type=click.Choice(
522
- ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
523
- case_sensitive=False,
524
- ),
560
+ type=LOG_LEVELS,
525
561
  default="INFO",
526
562
  help="Optional. Set the logging level",
527
563
  )
@@ -535,7 +571,10 @@ def fast_api_common_options():
535
571
  @click.option(
536
572
  "--reload/--no-reload",
537
573
  default=True,
538
- help="Optional. Whether to enable auto reload for server.",
574
+ help=(
575
+ "Optional. Whether to enable auto reload for server. Not supported"
576
+ " for Cloud Run."
577
+ ),
539
578
  )
540
579
  @functools.wraps(func)
541
580
  def wrapper(*args, **kwargs):
@@ -547,6 +586,13 @@ def fast_api_common_options():
547
586
 
548
587
 
549
588
  @main.command("web")
589
+ @click.option(
590
+ "--host",
591
+ type=str,
592
+ help="Optional. The binding host of the server",
593
+ default="127.0.0.1",
594
+ show_default=True,
595
+ )
550
596
  @fast_api_common_options()
551
597
  @adk_services_options()
552
598
  @deprecated_adk_services_options()
@@ -559,6 +605,7 @@ def fast_api_common_options():
559
605
  )
560
606
  def cli_web(
561
607
  agents_dir: str,
608
+ eval_storage_uri: Optional[str] = None,
562
609
  log_level: str = "INFO",
563
610
  allow_origins: Optional[list[str]] = None,
564
611
  host: str = "127.0.0.1",
@@ -578,7 +625,7 @@ def cli_web(
578
625
 
579
626
  Example:
580
627
 
581
- adk web --session_service_uri=[uri] --port=[port] path/to/agents_dir
628
+ adk web --port=[port] path/to/agents_dir
582
629
  """
583
630
  logs.setup_adk_logger(getattr(logging, log_level.upper()))
584
631
 
@@ -611,6 +658,7 @@ def cli_web(
611
658
  session_service_uri=session_service_uri,
612
659
  artifact_service_uri=artifact_service_uri,
613
660
  memory_service_uri=memory_service_uri,
661
+ eval_storage_uri=eval_storage_uri,
614
662
  allow_origins=allow_origins,
615
663
  web=True,
616
664
  trace_to_cloud=trace_to_cloud,
@@ -628,6 +676,16 @@ def cli_web(
628
676
 
629
677
 
630
678
  @main.command("api_server")
679
+ @click.option(
680
+ "--host",
681
+ type=str,
682
+ help="Optional. The binding host of the server",
683
+ default="127.0.0.1",
684
+ show_default=True,
685
+ )
686
+ @fast_api_common_options()
687
+ @adk_services_options()
688
+ @deprecated_adk_services_options()
631
689
  # The directory of agents, where each sub-directory is a single agent.
632
690
  # By default, it is the current working directory
633
691
  @click.argument(
@@ -637,11 +695,9 @@ def cli_web(
637
695
  ),
638
696
  default=os.getcwd(),
639
697
  )
640
- @fast_api_common_options()
641
- @adk_services_options()
642
- @deprecated_adk_services_options()
643
698
  def cli_api_server(
644
699
  agents_dir: str,
700
+ eval_storage_uri: Optional[str] = None,
645
701
  log_level: str = "INFO",
646
702
  allow_origins: Optional[list[str]] = None,
647
703
  host: str = "127.0.0.1",
@@ -661,7 +717,7 @@ def cli_api_server(
661
717
 
662
718
  Example:
663
719
 
664
- adk api_server --session_service_uri=[uri] --port=[port] path/to/agents_dir
720
+ adk api_server --port=[port] path/to/agents_dir
665
721
  """
666
722
  logs.setup_adk_logger(getattr(logging, log_level.upper()))
667
723
 
@@ -673,6 +729,7 @@ def cli_api_server(
673
729
  session_service_uri=session_service_uri,
674
730
  artifact_service_uri=artifact_service_uri,
675
731
  memory_service_uri=memory_service_uri,
732
+ eval_storage_uri=eval_storage_uri,
676
733
  allow_origins=allow_origins,
677
734
  web=False,
678
735
  trace_to_cloud=trace_to_cloud,
@@ -720,19 +777,7 @@ def cli_api_server(
720
777
  " of the AGENT source code)."
721
778
  ),
722
779
  )
723
- @click.option(
724
- "--port",
725
- type=int,
726
- default=8000,
727
- help="Optional. The port of the ADK API server (default: 8000).",
728
- )
729
- @click.option(
730
- "--trace_to_cloud",
731
- is_flag=True,
732
- show_default=True,
733
- default=False,
734
- help="Optional. Whether to enable Cloud Trace for cloud run.",
735
- )
780
+ @fast_api_common_options()
736
781
  @click.option(
737
782
  "--with_ui",
738
783
  is_flag=True,
@@ -743,6 +788,11 @@ def cli_api_server(
743
788
  " only)"
744
789
  ),
745
790
  )
791
+ @click.option(
792
+ "--verbosity",
793
+ type=LOG_LEVELS,
794
+ help="Deprecated. Use --log_level instead.",
795
+ )
746
796
  @click.option(
747
797
  "--temp_folder",
748
798
  type=str,
@@ -756,20 +806,6 @@ def cli_api_server(
756
806
  " (default: a timestamped folder in the system temp directory)."
757
807
  ),
758
808
  )
759
- @click.option(
760
- "--verbosity",
761
- type=click.Choice(
762
- ["debug", "info", "warning", "error", "critical"], case_sensitive=False
763
- ),
764
- default="WARNING",
765
- help="Optional. Override the default verbosity level.",
766
- )
767
- @click.argument(
768
- "agent",
769
- type=click.Path(
770
- exists=True, dir_okay=True, file_okay=False, resolve_path=True
771
- ),
772
- )
773
809
  @click.option(
774
810
  "--adk_version",
775
811
  type=str,
@@ -780,8 +816,23 @@ def cli_api_server(
780
816
  " version in the dev environment)"
781
817
  ),
782
818
  )
819
+ @click.option(
820
+ "--eval_storage_uri",
821
+ type=str,
822
+ help=(
823
+ "Optional. The evals storage URI to store agent evals,"
824
+ " supported URIs: gs://<bucket name>."
825
+ ),
826
+ default=None,
827
+ )
783
828
  @adk_services_options()
784
829
  @deprecated_adk_services_options()
830
+ @click.argument(
831
+ "agent",
832
+ type=click.Path(
833
+ exists=True, dir_okay=True, file_okay=False, resolve_path=True
834
+ ),
835
+ )
785
836
  def cli_deploy_cloud_run(
786
837
  agent: str,
787
838
  project: Optional[str],
@@ -792,11 +843,15 @@ def cli_deploy_cloud_run(
792
843
  port: int,
793
844
  trace_to_cloud: bool,
794
845
  with_ui: bool,
795
- verbosity: str,
796
846
  adk_version: str,
847
+ log_level: Optional[str] = None,
848
+ verbosity: str = "WARNING",
849
+ reload: bool = True,
850
+ allow_origins: Optional[list[str]] = None,
797
851
  session_service_uri: Optional[str] = None,
798
852
  artifact_service_uri: Optional[str] = None,
799
853
  memory_service_uri: Optional[str] = None,
854
+ eval_storage_uri: Optional[str] = None,
800
855
  session_db_url: Optional[str] = None, # Deprecated
801
856
  artifact_storage_uri: Optional[str] = None, # Deprecated
802
857
  ):
@@ -808,6 +863,7 @@ def cli_deploy_cloud_run(
808
863
 
809
864
  adk deploy cloud_run --project=[project] --region=[region] path/to/my_agent
810
865
  """
866
+ log_level = log_level or verbosity
811
867
  session_service_uri = session_service_uri or session_db_url
812
868
  artifact_service_uri = artifact_service_uri or artifact_storage_uri
813
869
  try:
@@ -820,7 +876,9 @@ def cli_deploy_cloud_run(
820
876
  temp_folder=temp_folder,
821
877
  port=port,
822
878
  trace_to_cloud=trace_to_cloud,
879
+ allow_origins=allow_origins,
823
880
  with_ui=with_ui,
881
+ log_level=log_level,
824
882
  verbosity=verbosity,
825
883
  adk_version=adk_version,
826
884
  session_service_uri=session_service_uri,