google-adk 0.5.0__py3-none-any.whl → 1.1.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 (139) hide show
  1. google/adk/agents/base_agent.py +76 -30
  2. google/adk/agents/callback_context.py +2 -6
  3. google/adk/agents/llm_agent.py +122 -30
  4. google/adk/agents/loop_agent.py +1 -1
  5. google/adk/agents/parallel_agent.py +7 -0
  6. google/adk/agents/readonly_context.py +8 -0
  7. google/adk/agents/run_config.py +1 -1
  8. google/adk/agents/sequential_agent.py +31 -0
  9. google/adk/agents/transcription_entry.py +4 -2
  10. google/adk/artifacts/gcs_artifact_service.py +1 -1
  11. google/adk/artifacts/in_memory_artifact_service.py +1 -1
  12. google/adk/auth/auth_credential.py +10 -2
  13. google/adk/auth/auth_preprocessor.py +7 -1
  14. google/adk/auth/auth_tool.py +3 -4
  15. google/adk/cli/agent_graph.py +5 -5
  16. google/adk/cli/browser/index.html +4 -4
  17. google/adk/cli/browser/{main-ULN5R5I5.js → main-PKDNKWJE.js} +59 -60
  18. google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
  19. google/adk/cli/cli.py +10 -9
  20. google/adk/cli/cli_deploy.py +7 -2
  21. google/adk/cli/cli_eval.py +109 -115
  22. google/adk/cli/cli_tools_click.py +179 -67
  23. google/adk/cli/fast_api.py +248 -197
  24. google/adk/cli/utils/agent_loader.py +137 -0
  25. google/adk/cli/utils/cleanup.py +40 -0
  26. google/adk/cli/utils/common.py +23 -0
  27. google/adk/cli/utils/evals.py +83 -0
  28. google/adk/cli/utils/logs.py +8 -5
  29. google/adk/code_executors/__init__.py +3 -1
  30. google/adk/code_executors/built_in_code_executor.py +52 -0
  31. google/adk/code_executors/code_execution_utils.py +2 -1
  32. google/adk/code_executors/container_code_executor.py +0 -1
  33. google/adk/code_executors/vertex_ai_code_executor.py +6 -8
  34. google/adk/evaluation/__init__.py +1 -1
  35. google/adk/evaluation/agent_evaluator.py +168 -128
  36. google/adk/evaluation/eval_case.py +104 -0
  37. google/adk/evaluation/eval_metrics.py +74 -0
  38. google/adk/evaluation/eval_result.py +86 -0
  39. google/adk/evaluation/eval_set.py +39 -0
  40. google/adk/evaluation/eval_set_results_manager.py +47 -0
  41. google/adk/evaluation/eval_sets_manager.py +43 -0
  42. google/adk/evaluation/evaluation_generator.py +88 -113
  43. google/adk/evaluation/evaluator.py +58 -0
  44. google/adk/evaluation/local_eval_set_results_manager.py +113 -0
  45. google/adk/evaluation/local_eval_sets_manager.py +264 -0
  46. google/adk/evaluation/response_evaluator.py +106 -1
  47. google/adk/evaluation/trajectory_evaluator.py +84 -2
  48. google/adk/events/event.py +6 -1
  49. google/adk/events/event_actions.py +6 -1
  50. google/adk/examples/base_example_provider.py +1 -0
  51. google/adk/examples/example_util.py +3 -2
  52. google/adk/flows/llm_flows/_code_execution.py +9 -1
  53. google/adk/flows/llm_flows/audio_transcriber.py +4 -3
  54. google/adk/flows/llm_flows/base_llm_flow.py +58 -21
  55. google/adk/flows/llm_flows/contents.py +3 -1
  56. google/adk/flows/llm_flows/functions.py +9 -8
  57. google/adk/flows/llm_flows/instructions.py +18 -80
  58. google/adk/flows/llm_flows/single_flow.py +2 -2
  59. google/adk/memory/__init__.py +1 -1
  60. google/adk/memory/_utils.py +23 -0
  61. google/adk/memory/base_memory_service.py +23 -21
  62. google/adk/memory/in_memory_memory_service.py +57 -25
  63. google/adk/memory/memory_entry.py +37 -0
  64. google/adk/memory/vertex_ai_rag_memory_service.py +38 -15
  65. google/adk/models/anthropic_llm.py +16 -9
  66. google/adk/models/base_llm.py +2 -1
  67. google/adk/models/base_llm_connection.py +2 -0
  68. google/adk/models/gemini_llm_connection.py +11 -11
  69. google/adk/models/google_llm.py +12 -2
  70. google/adk/models/lite_llm.py +80 -23
  71. google/adk/models/llm_response.py +16 -3
  72. google/adk/models/registry.py +1 -1
  73. google/adk/runners.py +98 -42
  74. google/adk/sessions/__init__.py +1 -1
  75. google/adk/sessions/_session_util.py +2 -1
  76. google/adk/sessions/base_session_service.py +6 -33
  77. google/adk/sessions/database_session_service.py +57 -67
  78. google/adk/sessions/in_memory_session_service.py +106 -24
  79. google/adk/sessions/session.py +3 -0
  80. google/adk/sessions/vertex_ai_session_service.py +44 -51
  81. google/adk/telemetry.py +7 -2
  82. google/adk/tools/__init__.py +4 -7
  83. google/adk/tools/_memory_entry_utils.py +30 -0
  84. google/adk/tools/agent_tool.py +10 -10
  85. google/adk/tools/apihub_tool/apihub_toolset.py +55 -74
  86. google/adk/tools/apihub_tool/clients/apihub_client.py +10 -3
  87. google/adk/tools/apihub_tool/clients/secret_client.py +1 -0
  88. google/adk/tools/application_integration_tool/application_integration_toolset.py +111 -85
  89. google/adk/tools/application_integration_tool/clients/connections_client.py +28 -1
  90. google/adk/tools/application_integration_tool/clients/integration_client.py +7 -5
  91. google/adk/tools/application_integration_tool/integration_connector_tool.py +69 -26
  92. google/adk/tools/base_toolset.py +96 -0
  93. google/adk/tools/bigquery/__init__.py +28 -0
  94. google/adk/tools/bigquery/bigquery_credentials.py +216 -0
  95. google/adk/tools/bigquery/bigquery_tool.py +116 -0
  96. google/adk/tools/{built_in_code_execution_tool.py → enterprise_search_tool.py} +17 -11
  97. google/adk/tools/function_parameter_parse_util.py +9 -2
  98. google/adk/tools/function_tool.py +33 -3
  99. google/adk/tools/get_user_choice_tool.py +1 -0
  100. google/adk/tools/google_api_tool/__init__.py +24 -70
  101. google/adk/tools/google_api_tool/google_api_tool.py +12 -6
  102. google/adk/tools/google_api_tool/{google_api_tool_set.py → google_api_toolset.py} +57 -55
  103. google/adk/tools/google_api_tool/google_api_toolsets.py +108 -0
  104. google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +40 -42
  105. google/adk/tools/google_search_tool.py +2 -2
  106. google/adk/tools/langchain_tool.py +96 -49
  107. google/adk/tools/load_memory_tool.py +14 -5
  108. google/adk/tools/mcp_tool/__init__.py +3 -2
  109. google/adk/tools/mcp_tool/conversion_utils.py +6 -2
  110. google/adk/tools/mcp_tool/mcp_session_manager.py +80 -69
  111. google/adk/tools/mcp_tool/mcp_tool.py +35 -32
  112. google/adk/tools/mcp_tool/mcp_toolset.py +99 -194
  113. google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +1 -3
  114. google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +6 -7
  115. google/adk/tools/openapi_tool/common/common.py +5 -1
  116. google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +7 -2
  117. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +27 -7
  118. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +36 -32
  119. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +11 -1
  120. google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +1 -1
  121. google/adk/tools/preload_memory_tool.py +27 -18
  122. google/adk/tools/retrieval/__init__.py +1 -1
  123. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +1 -1
  124. google/adk/tools/toolbox_toolset.py +107 -0
  125. google/adk/tools/transfer_to_agent_tool.py +0 -1
  126. google/adk/utils/__init__.py +13 -0
  127. google/adk/utils/instructions_utils.py +131 -0
  128. google/adk/version.py +1 -1
  129. {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/METADATA +18 -19
  130. google_adk-1.1.0.dist-info/RECORD +200 -0
  131. google/adk/agents/remote_agent.py +0 -50
  132. google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -18
  133. google/adk/cli/fast_api.py.orig +0 -728
  134. google/adk/tools/google_api_tool/google_api_tool_sets.py +0 -112
  135. google/adk/tools/toolbox_tool.py +0 -46
  136. google_adk-0.5.0.dist-info/RECORD +0 -180
  137. {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/WHEEL +0 -0
  138. {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/entry_points.txt +0 -0
  139. {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import asyncio
16
+ import collections
16
17
  from contextlib import asynccontextmanager
17
18
  from datetime import datetime
18
19
  import logging
@@ -26,13 +27,60 @@ import uvicorn
26
27
 
27
28
  from . import cli_create
28
29
  from . import cli_deploy
30
+ from .. import version
31
+ from ..evaluation.local_eval_set_results_manager import LocalEvalSetResultsManager
32
+ from ..sessions.in_memory_session_service import InMemorySessionService
29
33
  from .cli import run_cli
30
34
  from .cli_eval import MISSING_EVAL_DEPENDENCIES_MESSAGE
31
35
  from .fast_api import get_fast_api_app
32
36
  from .utils import envs
33
37
  from .utils import logs
34
38
 
35
- logger = logging.getLogger(__name__)
39
+
40
+ class HelpfulCommand(click.Command):
41
+ """Command that shows full help on error instead of just the error message.
42
+
43
+ A custom Click Command class that overrides the default error handling
44
+ behavior to display the full help text when a required argument is missing,
45
+ followed by the error message. This provides users with better context
46
+ about command usage without needing to run a separate --help command.
47
+
48
+ Args:
49
+ *args: Variable length argument list to pass to the parent class.
50
+ **kwargs: Arbitrary keyword arguments to pass to the parent class.
51
+
52
+ Returns:
53
+ None. Inherits behavior from the parent Click Command class.
54
+
55
+ Returns:
56
+ """
57
+
58
+ def __init__(self, *args, **kwargs):
59
+ super().__init__(*args, **kwargs)
60
+
61
+ def parse_args(self, ctx, args):
62
+ """Override the parse_args method to show help text on error.
63
+
64
+ Args:
65
+ ctx: Click context object for the current command.
66
+ args: List of command-line arguments to parse.
67
+
68
+ Returns:
69
+ The parsed arguments as returned by the parent class's parse_args method.
70
+
71
+ Raises:
72
+ click.MissingParameter: When a required parameter is missing, but this
73
+ is caught and handled by displaying the help text before exiting.
74
+ """
75
+ try:
76
+ return super().parse_args(ctx, args)
77
+ except click.MissingParameter as exc:
78
+ click.echo(ctx.get_help())
79
+ click.secho(f"\nError: {str(exc)}", fg="red", err=True)
80
+ ctx.exit(2)
81
+
82
+
83
+ logger = logging.getLogger("google_adk." + __name__)
36
84
 
37
85
 
38
86
  @click.group(context_settings={"max_content_width": 240})
@@ -47,7 +95,7 @@ def deploy():
47
95
  pass
48
96
 
49
97
 
50
- @main.command("create")
98
+ @main.command("create", cls=HelpfulCommand)
51
99
  @click.option(
52
100
  "--model",
53
101
  type=str,
@@ -113,7 +161,7 @@ def validate_exclusive(ctx, param, value):
113
161
  return value
114
162
 
115
163
 
116
- @main.command("run")
164
+ @main.command("run", cls=HelpfulCommand)
117
165
  @click.option(
118
166
  "--save_session",
119
167
  type=bool,
@@ -122,6 +170,15 @@ def validate_exclusive(ctx, param, value):
122
170
  default=False,
123
171
  help="Optional. Whether to save the session to a json file on exit.",
124
172
  )
173
+ @click.option(
174
+ "--session_id",
175
+ type=str,
176
+ help=(
177
+ "Optional. The session ID to save the session to on exit when"
178
+ " --save_session is set to true. User will be prompted to enter a"
179
+ " session ID if not set."
180
+ ),
181
+ )
125
182
  @click.option(
126
183
  "--replay",
127
184
  type=click.Path(
@@ -156,6 +213,7 @@ def validate_exclusive(ctx, param, value):
156
213
  def cli_run(
157
214
  agent: str,
158
215
  save_session: bool,
216
+ session_id: Optional[str],
159
217
  replay: Optional[str],
160
218
  resume: Optional[str],
161
219
  ):
@@ -179,11 +237,12 @@ def cli_run(
179
237
  input_file=replay,
180
238
  saved_session_file=resume,
181
239
  save_session=save_session,
240
+ session_id=session_id,
182
241
  )
183
242
  )
184
243
 
185
244
 
186
- @main.command("eval")
245
+ @main.command("eval", cls=HelpfulCommand)
187
246
  @click.argument(
188
247
  "agent_module_file_path",
189
248
  type=click.Path(
@@ -231,8 +290,9 @@ def cli_eval(
231
290
  envs.load_dotenv_for_agent(agent_module_file_path, ".")
232
291
 
233
292
  try:
293
+ from ..evaluation.local_eval_sets_manager import load_eval_set_from_file
294
+ from .cli_eval import EvalCaseResult
234
295
  from .cli_eval import EvalMetric
235
- from .cli_eval import EvalResult
236
296
  from .cli_eval import EvalStatus
237
297
  from .cli_eval import get_evaluation_criteria_or_default
238
298
  from .cli_eval import get_root_agent
@@ -249,48 +309,94 @@ def cli_eval(
249
309
  EvalMetric(metric_name=metric_name, threshold=threshold)
250
310
  )
251
311
 
252
- print(f"Using evaluation creiteria: {evaluation_criteria}")
312
+ print(f"Using evaluation criteria: {evaluation_criteria}")
253
313
 
254
314
  root_agent = get_root_agent(agent_module_file_path)
255
315
  reset_func = try_get_reset_func(agent_module_file_path)
256
316
 
257
- eval_set_to_evals = parse_and_get_evals_to_run(eval_set_file_path)
317
+ eval_set_file_path_to_evals = parse_and_get_evals_to_run(eval_set_file_path)
318
+ eval_set_id_to_eval_cases = {}
319
+
320
+ # Read the eval_set files and get the cases.
321
+ for eval_set_file_path, eval_case_ids in eval_set_file_path_to_evals.items():
322
+ eval_set = load_eval_set_from_file(eval_set_file_path, eval_set_file_path)
323
+ eval_cases = eval_set.eval_cases
324
+
325
+ if eval_case_ids:
326
+ # There are eval_ids that we should select.
327
+ eval_cases = [
328
+ e for e in eval_set.eval_cases if e.eval_id in eval_case_ids
329
+ ]
330
+
331
+ eval_set_id_to_eval_cases[eval_set.eval_set_id] = eval_cases
332
+
333
+ async def _collect_eval_results() -> list[EvalCaseResult]:
334
+ session_service = InMemorySessionService()
335
+ eval_case_results = []
336
+ async for eval_case_result in run_evals(
337
+ eval_set_id_to_eval_cases,
338
+ root_agent,
339
+ reset_func,
340
+ eval_metrics,
341
+ session_service=session_service,
342
+ ):
343
+ eval_case_result.session_details = await session_service.get_session(
344
+ app_name=os.path.basename(agent_module_file_path),
345
+ user_id=eval_case_result.user_id,
346
+ session_id=eval_case_result.session_id,
347
+ )
348
+ eval_case_results.append(eval_case_result)
349
+ return eval_case_results
258
350
 
259
351
  try:
260
- eval_results = list(
261
- asyncio.run(
262
- run_evals(
263
- eval_set_to_evals,
264
- root_agent,
265
- reset_func,
266
- eval_metrics,
267
- print_detailed_results=print_detailed_results,
268
- )
269
- )
270
- )
352
+ eval_results = asyncio.run(_collect_eval_results())
271
353
  except ModuleNotFoundError:
272
354
  raise click.ClickException(MISSING_EVAL_DEPENDENCIES_MESSAGE)
273
355
 
356
+ # Write eval set results.
357
+ local_eval_set_results_manager = LocalEvalSetResultsManager(
358
+ agents_dir=os.path.dirname(agent_module_file_path)
359
+ )
360
+ eval_set_id_to_eval_results = collections.defaultdict(list)
361
+ for eval_case_result in eval_results:
362
+ eval_set_id = eval_case_result.eval_set_id
363
+ eval_set_id_to_eval_results[eval_set_id].append(eval_case_result)
364
+
365
+ for eval_set_id, eval_case_results in eval_set_id_to_eval_results.items():
366
+ local_eval_set_results_manager.save_eval_set_result(
367
+ app_name=os.path.basename(agent_module_file_path),
368
+ eval_set_id=eval_set_id,
369
+ eval_case_results=eval_case_results,
370
+ )
371
+
274
372
  print("*********************************************************************")
275
373
  eval_run_summary = {}
276
374
 
277
375
  for eval_result in eval_results:
278
- eval_result: EvalResult
376
+ eval_result: EvalCaseResult
279
377
 
280
- if eval_result.eval_set_file not in eval_run_summary:
281
- eval_run_summary[eval_result.eval_set_file] = [0, 0]
378
+ if eval_result.eval_set_id not in eval_run_summary:
379
+ eval_run_summary[eval_result.eval_set_id] = [0, 0]
282
380
 
283
381
  if eval_result.final_eval_status == EvalStatus.PASSED:
284
- eval_run_summary[eval_result.eval_set_file][0] += 1
382
+ eval_run_summary[eval_result.eval_set_id][0] += 1
285
383
  else:
286
- eval_run_summary[eval_result.eval_set_file][1] += 1
384
+ eval_run_summary[eval_result.eval_set_id][1] += 1
287
385
  print("Eval Run Summary")
288
- for eval_set_file, pass_fail_count in eval_run_summary.items():
386
+ for eval_set_id, pass_fail_count in eval_run_summary.items():
289
387
  print(
290
- f"{eval_set_file}:\n Tests passed: {pass_fail_count[0]}\n Tests"
388
+ f"{eval_set_id}:\n Tests passed: {pass_fail_count[0]}\n Tests"
291
389
  f" failed: {pass_fail_count[1]}"
292
390
  )
293
391
 
392
+ if print_detailed_results:
393
+ for eval_result in eval_results:
394
+ eval_result: EvalCaseResult
395
+ print(
396
+ "*********************************************************************"
397
+ )
398
+ print(eval_result.model_dump_json(indent=2))
399
+
294
400
 
295
401
  @main.command("web")
296
402
  @click.option(
@@ -305,6 +411,13 @@ def cli_eval(
305
411
  - See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls for more details on supported DB URLs."""
306
412
  ),
307
413
  )
414
+ @click.option(
415
+ "--host",
416
+ type=str,
417
+ help="Optional. The binding host of the server",
418
+ default="127.0.0.1",
419
+ show_default=True,
420
+ )
308
421
  @click.option(
309
422
  "--port",
310
423
  type=int,
@@ -324,16 +437,6 @@ def cli_eval(
324
437
  default="INFO",
325
438
  help="Optional. Set the logging level",
326
439
  )
327
- @click.option(
328
- "--log_to_tmp",
329
- is_flag=True,
330
- show_default=True,
331
- default=False,
332
- help=(
333
- "Optional. Whether to log to system temp folder instead of console."
334
- " This is useful for local debugging."
335
- ),
336
- )
337
440
  @click.option(
338
441
  "--trace_to_cloud",
339
442
  is_flag=True,
@@ -341,6 +444,11 @@ def cli_eval(
341
444
  default=False,
342
445
  help="Optional. Whether to enable cloud trace for telemetry.",
343
446
  )
447
+ @click.option(
448
+ "--reload/--no-reload",
449
+ default=True,
450
+ help="Optional. Whether to enable auto reload for server.",
451
+ )
344
452
  @click.argument(
345
453
  "agents_dir",
346
454
  type=click.Path(
@@ -350,12 +458,13 @@ def cli_eval(
350
458
  )
351
459
  def cli_web(
352
460
  agents_dir: str,
353
- log_to_tmp: bool,
354
461
  session_db_url: str = "",
355
462
  log_level: str = "INFO",
356
463
  allow_origins: Optional[list[str]] = None,
464
+ host: str = "127.0.0.1",
357
465
  port: int = 8000,
358
466
  trace_to_cloud: bool = False,
467
+ reload: bool = True,
359
468
  ):
360
469
  """Starts a FastAPI server with Web UI for agents.
361
470
 
@@ -366,12 +475,7 @@ def cli_web(
366
475
 
367
476
  adk web --session_db_url=[db_url] --port=[port] path/to/agents_dir
368
477
  """
369
- if log_to_tmp:
370
- logs.log_to_tmp_folder()
371
- else:
372
- logs.log_to_stderr()
373
-
374
- logging.getLogger().setLevel(log_level)
478
+ logs.setup_adk_logger(getattr(logging, log_level.upper()))
375
479
 
376
480
  @asynccontextmanager
377
481
  async def _lifespan(app: FastAPI):
@@ -396,7 +500,7 @@ def cli_web(
396
500
  )
397
501
 
398
502
  app = get_fast_api_app(
399
- agent_dir=agents_dir,
503
+ agents_dir=agents_dir,
400
504
  session_db_url=session_db_url,
401
505
  allow_origins=allow_origins,
402
506
  web=True,
@@ -405,9 +509,9 @@ def cli_web(
405
509
  )
406
510
  config = uvicorn.Config(
407
511
  app,
408
- host="0.0.0.0",
512
+ host=host,
409
513
  port=port,
410
- reload=True,
514
+ reload=reload,
411
515
  )
412
516
 
413
517
  server = uvicorn.Server(config)
@@ -427,6 +531,13 @@ def cli_web(
427
531
  - See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls for more details on supported DB URLs."""
428
532
  ),
429
533
  )
534
+ @click.option(
535
+ "--host",
536
+ type=str,
537
+ help="Optional. The binding host of the server",
538
+ default="127.0.0.1",
539
+ show_default=True,
540
+ )
430
541
  @click.option(
431
542
  "--port",
432
543
  type=int,
@@ -446,16 +557,6 @@ def cli_web(
446
557
  default="INFO",
447
558
  help="Optional. Set the logging level",
448
559
  )
449
- @click.option(
450
- "--log_to_tmp",
451
- is_flag=True,
452
- show_default=True,
453
- default=False,
454
- help=(
455
- "Optional. Whether to log to system temp folder instead of console."
456
- " This is useful for local debugging."
457
- ),
458
- )
459
560
  @click.option(
460
561
  "--trace_to_cloud",
461
562
  is_flag=True,
@@ -463,6 +564,11 @@ def cli_web(
463
564
  default=False,
464
565
  help="Optional. Whether to enable cloud trace for telemetry.",
465
566
  )
567
+ @click.option(
568
+ "--reload/--no-reload",
569
+ default=True,
570
+ help="Optional. Whether to enable auto reload for server.",
571
+ )
466
572
  # The directory of agents, where each sub-directory is a single agent.
467
573
  # By default, it is the current working directory
468
574
  @click.argument(
@@ -474,12 +580,13 @@ def cli_web(
474
580
  )
475
581
  def cli_api_server(
476
582
  agents_dir: str,
477
- log_to_tmp: bool,
478
583
  session_db_url: str = "",
479
584
  log_level: str = "INFO",
480
585
  allow_origins: Optional[list[str]] = None,
586
+ host: str = "127.0.0.1",
481
587
  port: int = 8000,
482
588
  trace_to_cloud: bool = False,
589
+ reload: bool = True,
483
590
  ):
484
591
  """Starts a FastAPI server for agents.
485
592
 
@@ -490,24 +597,19 @@ def cli_api_server(
490
597
 
491
598
  adk api_server --session_db_url=[db_url] --port=[port] path/to/agents_dir
492
599
  """
493
- if log_to_tmp:
494
- logs.log_to_tmp_folder()
495
- else:
496
- logs.log_to_stderr()
497
-
498
- logging.getLogger().setLevel(log_level)
600
+ logs.setup_adk_logger(getattr(logging, log_level.upper()))
499
601
 
500
602
  config = uvicorn.Config(
501
603
  get_fast_api_app(
502
- agent_dir=agents_dir,
604
+ agents_dir=agents_dir,
503
605
  session_db_url=session_db_url,
504
606
  allow_origins=allow_origins,
505
607
  web=False,
506
608
  trace_to_cloud=trace_to_cloud,
507
609
  ),
508
- host="0.0.0.0",
610
+ host=host,
509
611
  port=port,
510
- reload=True,
612
+ reload=reload,
511
613
  )
512
614
  server = uvicorn.Server(config)
513
615
  server.run()
@@ -556,7 +658,6 @@ def cli_api_server(
556
658
  )
557
659
  @click.option(
558
660
  "--trace_to_cloud",
559
- type=bool,
560
661
  is_flag=True,
561
662
  show_default=True,
562
663
  default=False,
@@ -564,7 +665,6 @@ def cli_api_server(
564
665
  )
565
666
  @click.option(
566
667
  "--with_ui",
567
- type=bool,
568
668
  is_flag=True,
569
669
  show_default=True,
570
670
  default=False,
@@ -612,6 +712,16 @@ def cli_api_server(
612
712
  exists=True, dir_okay=True, file_okay=False, resolve_path=True
613
713
  ),
614
714
  )
715
+ @click.option(
716
+ "--adk_version",
717
+ type=str,
718
+ default=version.__version__,
719
+ show_default=True,
720
+ help=(
721
+ "Optional. The ADK version used in Cloud Run deployment. (default: the"
722
+ " version in the dev environment)"
723
+ ),
724
+ )
615
725
  def cli_deploy_cloud_run(
616
726
  agent: str,
617
727
  project: Optional[str],
@@ -624,6 +734,7 @@ def cli_deploy_cloud_run(
624
734
  with_ui: bool,
625
735
  verbosity: str,
626
736
  session_db_url: str,
737
+ adk_version: str,
627
738
  ):
628
739
  """Deploys an agent to Cloud Run.
629
740
 
@@ -646,6 +757,7 @@ def cli_deploy_cloud_run(
646
757
  with_ui=with_ui,
647
758
  verbosity=verbosity,
648
759
  session_db_url=session_db_url,
760
+ adk_version=adk_version,
649
761
  )
650
762
  except Exception as e:
651
763
  click.secho(f"Deploy failed: {e}", fg="red", err=True)