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.
- google/adk/agents/base_agent.py +76 -30
- google/adk/agents/callback_context.py +2 -6
- google/adk/agents/llm_agent.py +122 -30
- google/adk/agents/loop_agent.py +1 -1
- google/adk/agents/parallel_agent.py +7 -0
- google/adk/agents/readonly_context.py +8 -0
- google/adk/agents/run_config.py +1 -1
- google/adk/agents/sequential_agent.py +31 -0
- google/adk/agents/transcription_entry.py +4 -2
- google/adk/artifacts/gcs_artifact_service.py +1 -1
- google/adk/artifacts/in_memory_artifact_service.py +1 -1
- google/adk/auth/auth_credential.py +10 -2
- google/adk/auth/auth_preprocessor.py +7 -1
- google/adk/auth/auth_tool.py +3 -4
- google/adk/cli/agent_graph.py +5 -5
- google/adk/cli/browser/index.html +4 -4
- google/adk/cli/browser/{main-ULN5R5I5.js → main-PKDNKWJE.js} +59 -60
- google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
- google/adk/cli/cli.py +10 -9
- google/adk/cli/cli_deploy.py +7 -2
- google/adk/cli/cli_eval.py +109 -115
- google/adk/cli/cli_tools_click.py +179 -67
- google/adk/cli/fast_api.py +248 -197
- google/adk/cli/utils/agent_loader.py +137 -0
- google/adk/cli/utils/cleanup.py +40 -0
- google/adk/cli/utils/common.py +23 -0
- google/adk/cli/utils/evals.py +83 -0
- google/adk/cli/utils/logs.py +8 -5
- google/adk/code_executors/__init__.py +3 -1
- google/adk/code_executors/built_in_code_executor.py +52 -0
- google/adk/code_executors/code_execution_utils.py +2 -1
- google/adk/code_executors/container_code_executor.py +0 -1
- google/adk/code_executors/vertex_ai_code_executor.py +6 -8
- google/adk/evaluation/__init__.py +1 -1
- google/adk/evaluation/agent_evaluator.py +168 -128
- google/adk/evaluation/eval_case.py +104 -0
- google/adk/evaluation/eval_metrics.py +74 -0
- google/adk/evaluation/eval_result.py +86 -0
- google/adk/evaluation/eval_set.py +39 -0
- google/adk/evaluation/eval_set_results_manager.py +47 -0
- google/adk/evaluation/eval_sets_manager.py +43 -0
- google/adk/evaluation/evaluation_generator.py +88 -113
- google/adk/evaluation/evaluator.py +58 -0
- google/adk/evaluation/local_eval_set_results_manager.py +113 -0
- google/adk/evaluation/local_eval_sets_manager.py +264 -0
- google/adk/evaluation/response_evaluator.py +106 -1
- google/adk/evaluation/trajectory_evaluator.py +84 -2
- google/adk/events/event.py +6 -1
- google/adk/events/event_actions.py +6 -1
- google/adk/examples/base_example_provider.py +1 -0
- google/adk/examples/example_util.py +3 -2
- google/adk/flows/llm_flows/_code_execution.py +9 -1
- google/adk/flows/llm_flows/audio_transcriber.py +4 -3
- google/adk/flows/llm_flows/base_llm_flow.py +58 -21
- google/adk/flows/llm_flows/contents.py +3 -1
- google/adk/flows/llm_flows/functions.py +9 -8
- google/adk/flows/llm_flows/instructions.py +18 -80
- google/adk/flows/llm_flows/single_flow.py +2 -2
- google/adk/memory/__init__.py +1 -1
- google/adk/memory/_utils.py +23 -0
- google/adk/memory/base_memory_service.py +23 -21
- google/adk/memory/in_memory_memory_service.py +57 -25
- google/adk/memory/memory_entry.py +37 -0
- google/adk/memory/vertex_ai_rag_memory_service.py +38 -15
- google/adk/models/anthropic_llm.py +16 -9
- google/adk/models/base_llm.py +2 -1
- google/adk/models/base_llm_connection.py +2 -0
- google/adk/models/gemini_llm_connection.py +11 -11
- google/adk/models/google_llm.py +12 -2
- google/adk/models/lite_llm.py +80 -23
- google/adk/models/llm_response.py +16 -3
- google/adk/models/registry.py +1 -1
- google/adk/runners.py +98 -42
- google/adk/sessions/__init__.py +1 -1
- google/adk/sessions/_session_util.py +2 -1
- google/adk/sessions/base_session_service.py +6 -33
- google/adk/sessions/database_session_service.py +57 -67
- google/adk/sessions/in_memory_session_service.py +106 -24
- google/adk/sessions/session.py +3 -0
- google/adk/sessions/vertex_ai_session_service.py +44 -51
- google/adk/telemetry.py +7 -2
- google/adk/tools/__init__.py +4 -7
- google/adk/tools/_memory_entry_utils.py +30 -0
- google/adk/tools/agent_tool.py +10 -10
- google/adk/tools/apihub_tool/apihub_toolset.py +55 -74
- google/adk/tools/apihub_tool/clients/apihub_client.py +10 -3
- google/adk/tools/apihub_tool/clients/secret_client.py +1 -0
- google/adk/tools/application_integration_tool/application_integration_toolset.py +111 -85
- google/adk/tools/application_integration_tool/clients/connections_client.py +28 -1
- google/adk/tools/application_integration_tool/clients/integration_client.py +7 -5
- google/adk/tools/application_integration_tool/integration_connector_tool.py +69 -26
- google/adk/tools/base_toolset.py +96 -0
- google/adk/tools/bigquery/__init__.py +28 -0
- google/adk/tools/bigquery/bigquery_credentials.py +216 -0
- google/adk/tools/bigquery/bigquery_tool.py +116 -0
- google/adk/tools/{built_in_code_execution_tool.py → enterprise_search_tool.py} +17 -11
- google/adk/tools/function_parameter_parse_util.py +9 -2
- google/adk/tools/function_tool.py +33 -3
- google/adk/tools/get_user_choice_tool.py +1 -0
- google/adk/tools/google_api_tool/__init__.py +24 -70
- google/adk/tools/google_api_tool/google_api_tool.py +12 -6
- google/adk/tools/google_api_tool/{google_api_tool_set.py → google_api_toolset.py} +57 -55
- google/adk/tools/google_api_tool/google_api_toolsets.py +108 -0
- google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +40 -42
- google/adk/tools/google_search_tool.py +2 -2
- google/adk/tools/langchain_tool.py +96 -49
- google/adk/tools/load_memory_tool.py +14 -5
- google/adk/tools/mcp_tool/__init__.py +3 -2
- google/adk/tools/mcp_tool/conversion_utils.py +6 -2
- google/adk/tools/mcp_tool/mcp_session_manager.py +80 -69
- google/adk/tools/mcp_tool/mcp_tool.py +35 -32
- google/adk/tools/mcp_tool/mcp_toolset.py +99 -194
- google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +1 -3
- google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +6 -7
- google/adk/tools/openapi_tool/common/common.py +5 -1
- google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +7 -2
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +27 -7
- google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +36 -32
- google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +11 -1
- google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +1 -1
- google/adk/tools/preload_memory_tool.py +27 -18
- google/adk/tools/retrieval/__init__.py +1 -1
- google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +1 -1
- google/adk/tools/toolbox_toolset.py +107 -0
- google/adk/tools/transfer_to_agent_tool.py +0 -1
- google/adk/utils/__init__.py +13 -0
- google/adk/utils/instructions_utils.py +131 -0
- google/adk/version.py +1 -1
- {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/METADATA +18 -19
- google_adk-1.1.0.dist-info/RECORD +200 -0
- google/adk/agents/remote_agent.py +0 -50
- google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -18
- google/adk/cli/fast_api.py.orig +0 -728
- google/adk/tools/google_api_tool/google_api_tool_sets.py +0 -112
- google/adk/tools/toolbox_tool.py +0 -46
- google_adk-0.5.0.dist-info/RECORD +0 -180
- {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/WHEEL +0 -0
- {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/entry_points.txt +0 -0
- {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
|
-
|
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
|
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
|
-
|
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 =
|
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:
|
376
|
+
eval_result: EvalCaseResult
|
279
377
|
|
280
|
-
if eval_result.
|
281
|
-
eval_run_summary[eval_result.
|
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.
|
382
|
+
eval_run_summary[eval_result.eval_set_id][0] += 1
|
285
383
|
else:
|
286
|
-
eval_run_summary[eval_result.
|
384
|
+
eval_run_summary[eval_result.eval_set_id][1] += 1
|
287
385
|
print("Eval Run Summary")
|
288
|
-
for
|
386
|
+
for eval_set_id, pass_fail_count in eval_run_summary.items():
|
289
387
|
print(
|
290
|
-
f"{
|
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
|
-
|
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
|
-
|
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=
|
512
|
+
host=host,
|
409
513
|
port=port,
|
410
|
-
reload=
|
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
|
-
|
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
|
-
|
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=
|
610
|
+
host=host,
|
509
611
|
port=port,
|
510
|
-
reload=
|
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)
|