google-adk 1.2.1__py3-none-any.whl → 1.4.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/a2a/__init__.py +13 -0
- google/adk/a2a/converters/__init__.py +13 -0
- google/adk/a2a/converters/part_converter.py +166 -0
- google/adk/agents/invocation_context.py +2 -0
- google/adk/agents/llm_agent.py +1 -6
- google/adk/agents/run_config.py +11 -0
- google/adk/auth/auth_credential.py +5 -0
- google/adk/auth/auth_handler.py +22 -96
- google/adk/auth/auth_preprocessor.py +3 -3
- google/adk/auth/auth_tool.py +46 -0
- google/adk/auth/credential_manager.py +265 -0
- google/adk/auth/credential_service/__init__.py +13 -0
- google/adk/auth/credential_service/base_credential_service.py +75 -0
- google/adk/auth/credential_service/in_memory_credential_service.py +64 -0
- google/adk/auth/exchanger/__init__.py +23 -0
- google/adk/auth/exchanger/base_credential_exchanger.py +57 -0
- google/adk/auth/exchanger/credential_exchanger_registry.py +58 -0
- google/adk/auth/exchanger/oauth2_credential_exchanger.py +104 -0
- google/adk/auth/exchanger/service_account_credential_exchanger.py +104 -0
- google/adk/auth/oauth2_credential_util.py +107 -0
- google/adk/auth/refresher/__init__.py +21 -0
- google/adk/auth/refresher/base_credential_refresher.py +74 -0
- google/adk/auth/refresher/credential_refresher_registry.py +59 -0
- google/adk/auth/refresher/oauth2_credential_refresher.py +154 -0
- google/adk/cli/agent_graph.py +34 -32
- google/adk/cli/browser/index.html +2 -2
- google/adk/cli/browser/main-JAAWEV7F.js +92 -0
- google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
- google/adk/cli/cli.py +10 -0
- google/adk/cli/cli_deploy.py +80 -21
- google/adk/cli/cli_tools_click.py +132 -61
- google/adk/cli/fast_api.py +46 -41
- google/adk/cli/utils/agent_loader.py +15 -2
- google/adk/code_executors/container_code_executor.py +10 -6
- google/adk/code_executors/vertex_ai_code_executor.py +8 -2
- google/adk/evaluation/_eval_set_results_manager_utils.py +44 -0
- google/adk/evaluation/_eval_sets_manager_utils.py +108 -0
- google/adk/evaluation/eval_metrics.py +0 -5
- google/adk/evaluation/eval_result.py +12 -7
- google/adk/evaluation/eval_set_results_manager.py +6 -1
- google/adk/evaluation/gcs_eval_set_results_manager.py +121 -0
- google/adk/evaluation/gcs_eval_sets_manager.py +196 -0
- google/adk/evaluation/local_eval_set_results_manager.py +6 -18
- google/adk/evaluation/local_eval_sets_manager.py +27 -78
- google/adk/flows/llm_flows/basic.py +9 -0
- google/adk/models/anthropic_llm.py +1 -1
- google/adk/models/gemini_llm_connection.py +2 -0
- google/adk/models/google_llm.py +57 -16
- google/adk/models/lite_llm.py +2 -1
- google/adk/platform/__init__.py +13 -0
- google/adk/platform/internal/__init__.py +15 -0
- google/adk/platform/internal/thread.py +30 -0
- google/adk/platform/thread.py +31 -0
- google/adk/runners.py +8 -2
- google/adk/sessions/in_memory_session_service.py +12 -1
- google/adk/sessions/vertex_ai_session_service.py +71 -50
- google/adk/tools/__init__.py +2 -0
- google/adk/tools/_automatic_function_calling_util.py +1 -0
- google/adk/tools/_forwarding_artifact_service.py +96 -0
- google/adk/tools/_function_parameter_parse_util.py +1 -0
- google/adk/tools/agent_tool.py +5 -39
- google/adk/tools/application_integration_tool/integration_connector_tool.py +2 -2
- google/adk/tools/authenticated_function_tool.py +107 -0
- google/adk/tools/base_authenticated_tool.py +107 -0
- google/adk/tools/bigquery/bigquery_credentials.py +6 -4
- google/adk/tools/bigquery/bigquery_tool.py +22 -9
- google/adk/tools/bigquery/bigquery_toolset.py +9 -3
- google/adk/tools/bigquery/client.py +7 -3
- google/adk/tools/bigquery/config.py +46 -0
- google/adk/tools/bigquery/metadata_tool.py +114 -91
- google/adk/tools/bigquery/query_tool.py +141 -23
- google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +7 -4
- google/adk/tools/google_search_tool.py +0 -1
- google/adk/tools/mcp_tool/__init__.py +6 -0
- google/adk/tools/mcp_tool/mcp_session_manager.py +271 -149
- google/adk/tools/mcp_tool/mcp_tool.py +79 -22
- google/adk/tools/mcp_tool/mcp_toolset.py +32 -29
- google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +3 -3
- google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +56 -33
- google/adk/tools/retrieval/files_retrieval.py +7 -1
- google/adk/tools/url_context_tool.py +61 -0
- google/adk/tools/vertex_ai_search_tool.py +13 -2
- google/adk/utils/feature_decorator.py +175 -0
- google/adk/version.py +1 -1
- {google_adk-1.2.1.dist-info → google_adk-1.4.0.dist-info}/METADATA +10 -2
- {google_adk-1.2.1.dist-info → google_adk-1.4.0.dist-info}/RECORD +89 -58
- google/adk/cli/browser/main-CS5OLUMF.js +0 -91
- google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -17
- {google_adk-1.2.1.dist-info → google_adk-1.4.0.dist-info}/WHEEL +0 -0
- {google_adk-1.2.1.dist-info → google_adk-1.4.0.dist-info}/entry_points.txt +0 -0
- {google_adk-1.2.1.dist-info → google_adk-1.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -417,28 +417,87 @@ def cli_eval(
|
|
417
417
|
print(eval_result.model_dump_json(indent=2))
|
418
418
|
|
419
419
|
|
420
|
-
def
|
421
|
-
"""Decorator to add
|
420
|
+
def adk_services_options():
|
421
|
+
"""Decorator to add ADK services options to click commands."""
|
422
422
|
|
423
423
|
def decorator(func):
|
424
424
|
@click.option(
|
425
|
-
"--
|
425
|
+
"--session_service_uri",
|
426
426
|
help=(
|
427
|
-
"""Optional. The
|
427
|
+
"""Optional. The URI of the session service.
|
428
428
|
- Use 'agentengine://<agent_engine_resource_id>' to connect to Agent Engine sessions.
|
429
429
|
- Use 'sqlite://<path_to_sqlite_file>' to connect to a SQLite DB.
|
430
|
-
- See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls for more details on supported
|
430
|
+
- See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls for more details on supported database URIs."""
|
431
431
|
),
|
432
432
|
)
|
433
433
|
@click.option(
|
434
|
-
"--
|
434
|
+
"--artifact_service_uri",
|
435
435
|
type=str,
|
436
436
|
help=(
|
437
|
-
"Optional. The
|
437
|
+
"Optional. The URI of the artifact service,"
|
438
438
|
" supported URIs: gs://<bucket name> for GCS artifact service."
|
439
439
|
),
|
440
440
|
default=None,
|
441
441
|
)
|
442
|
+
@click.option(
|
443
|
+
"--memory_service_uri",
|
444
|
+
type=str,
|
445
|
+
help=(
|
446
|
+
"""Optional. The URI of the memory service.
|
447
|
+
- Use 'rag://<rag_corpus_id>' to connect to Vertex AI Rag Memory Service."""
|
448
|
+
),
|
449
|
+
default=None,
|
450
|
+
)
|
451
|
+
@functools.wraps(func)
|
452
|
+
def wrapper(*args, **kwargs):
|
453
|
+
return func(*args, **kwargs)
|
454
|
+
|
455
|
+
return wrapper
|
456
|
+
|
457
|
+
return decorator
|
458
|
+
|
459
|
+
|
460
|
+
def deprecated_adk_services_options():
|
461
|
+
"""Depracated ADK services options."""
|
462
|
+
|
463
|
+
def warn(alternative_param, ctx, param, value):
|
464
|
+
if value:
|
465
|
+
click.echo(
|
466
|
+
click.style(
|
467
|
+
f"WARNING: Deprecated option {param.name} is used. Please use"
|
468
|
+
f" {alternative_param} instead.",
|
469
|
+
fg="yellow",
|
470
|
+
),
|
471
|
+
err=True,
|
472
|
+
)
|
473
|
+
return value
|
474
|
+
|
475
|
+
def decorator(func):
|
476
|
+
@click.option(
|
477
|
+
"--session_db_url",
|
478
|
+
help="Deprecated. Use --session_service_uri instead.",
|
479
|
+
callback=functools.partial(warn, "--session_service_uri"),
|
480
|
+
)
|
481
|
+
@click.option(
|
482
|
+
"--artifact_storage_uri",
|
483
|
+
type=str,
|
484
|
+
help="Deprecated. Use --artifact_service_uri instead.",
|
485
|
+
callback=functools.partial(warn, "--artifact_service_uri"),
|
486
|
+
default=None,
|
487
|
+
)
|
488
|
+
@functools.wraps(func)
|
489
|
+
def wrapper(*args, **kwargs):
|
490
|
+
return func(*args, **kwargs)
|
491
|
+
|
492
|
+
return wrapper
|
493
|
+
|
494
|
+
return decorator
|
495
|
+
|
496
|
+
|
497
|
+
def fast_api_common_options():
|
498
|
+
"""Decorator to add common fast api options to click commands."""
|
499
|
+
|
500
|
+
def decorator(func):
|
442
501
|
@click.option(
|
443
502
|
"--host",
|
444
503
|
type=str,
|
@@ -489,6 +548,8 @@ def fast_api_common_options():
|
|
489
548
|
|
490
549
|
@main.command("web")
|
491
550
|
@fast_api_common_options()
|
551
|
+
@adk_services_options()
|
552
|
+
@deprecated_adk_services_options()
|
492
553
|
@click.argument(
|
493
554
|
"agents_dir",
|
494
555
|
type=click.Path(
|
@@ -498,14 +559,17 @@ def fast_api_common_options():
|
|
498
559
|
)
|
499
560
|
def cli_web(
|
500
561
|
agents_dir: str,
|
501
|
-
session_db_url: str = "",
|
502
|
-
artifact_storage_uri: Optional[str] = None,
|
503
562
|
log_level: str = "INFO",
|
504
563
|
allow_origins: Optional[list[str]] = None,
|
505
564
|
host: str = "127.0.0.1",
|
506
565
|
port: int = 8000,
|
507
566
|
trace_to_cloud: bool = False,
|
508
567
|
reload: bool = True,
|
568
|
+
session_service_uri: Optional[str] = None,
|
569
|
+
artifact_service_uri: Optional[str] = None,
|
570
|
+
memory_service_uri: Optional[str] = None,
|
571
|
+
session_db_url: Optional[str] = None, # Deprecated
|
572
|
+
artifact_storage_uri: Optional[str] = None, # Deprecated
|
509
573
|
):
|
510
574
|
"""Starts a FastAPI server with Web UI for agents.
|
511
575
|
|
@@ -514,7 +578,7 @@ def cli_web(
|
|
514
578
|
|
515
579
|
Example:
|
516
580
|
|
517
|
-
adk web --
|
581
|
+
adk web --session_service_uri=[uri] --port=[port] path/to/agents_dir
|
518
582
|
"""
|
519
583
|
logs.setup_adk_logger(getattr(logging, log_level.upper()))
|
520
584
|
|
@@ -540,10 +604,13 @@ def cli_web(
|
|
540
604
|
fg="green",
|
541
605
|
)
|
542
606
|
|
607
|
+
session_service_uri = session_service_uri or session_db_url
|
608
|
+
artifact_service_uri = artifact_service_uri or artifact_storage_uri
|
543
609
|
app = get_fast_api_app(
|
544
610
|
agents_dir=agents_dir,
|
545
|
-
|
546
|
-
|
611
|
+
session_service_uri=session_service_uri,
|
612
|
+
artifact_service_uri=artifact_service_uri,
|
613
|
+
memory_service_uri=memory_service_uri,
|
547
614
|
allow_origins=allow_origins,
|
548
615
|
web=True,
|
549
616
|
trace_to_cloud=trace_to_cloud,
|
@@ -571,16 +638,21 @@ def cli_web(
|
|
571
638
|
default=os.getcwd(),
|
572
639
|
)
|
573
640
|
@fast_api_common_options()
|
641
|
+
@adk_services_options()
|
642
|
+
@deprecated_adk_services_options()
|
574
643
|
def cli_api_server(
|
575
644
|
agents_dir: str,
|
576
|
-
session_db_url: str = "",
|
577
|
-
artifact_storage_uri: Optional[str] = None,
|
578
645
|
log_level: str = "INFO",
|
579
646
|
allow_origins: Optional[list[str]] = None,
|
580
647
|
host: str = "127.0.0.1",
|
581
648
|
port: int = 8000,
|
582
649
|
trace_to_cloud: bool = False,
|
583
650
|
reload: bool = True,
|
651
|
+
session_service_uri: Optional[str] = None,
|
652
|
+
artifact_service_uri: Optional[str] = None,
|
653
|
+
memory_service_uri: Optional[str] = None,
|
654
|
+
session_db_url: Optional[str] = None, # Deprecated
|
655
|
+
artifact_storage_uri: Optional[str] = None, # Deprecated
|
584
656
|
):
|
585
657
|
"""Starts a FastAPI server for agents.
|
586
658
|
|
@@ -589,15 +661,18 @@ def cli_api_server(
|
|
589
661
|
|
590
662
|
Example:
|
591
663
|
|
592
|
-
adk api_server --
|
664
|
+
adk api_server --session_service_uri=[uri] --port=[port] path/to/agents_dir
|
593
665
|
"""
|
594
666
|
logs.setup_adk_logger(getattr(logging, log_level.upper()))
|
595
667
|
|
668
|
+
session_service_uri = session_service_uri or session_db_url
|
669
|
+
artifact_service_uri = artifact_service_uri or artifact_storage_uri
|
596
670
|
config = uvicorn.Config(
|
597
671
|
get_fast_api_app(
|
598
672
|
agents_dir=agents_dir,
|
599
|
-
|
600
|
-
|
673
|
+
session_service_uri=session_service_uri,
|
674
|
+
artifact_service_uri=artifact_service_uri,
|
675
|
+
memory_service_uri=memory_service_uri,
|
601
676
|
allow_origins=allow_origins,
|
602
677
|
web=False,
|
603
678
|
trace_to_cloud=trace_to_cloud,
|
@@ -689,27 +764,6 @@ def cli_api_server(
|
|
689
764
|
default="WARNING",
|
690
765
|
help="Optional. Override the default verbosity level.",
|
691
766
|
)
|
692
|
-
@click.option(
|
693
|
-
"--session_db_url",
|
694
|
-
help=(
|
695
|
-
"""Optional. The database URL to store the session.
|
696
|
-
|
697
|
-
- Use 'agentengine://<agent_engine_resource_id>' to connect to Agent Engine sessions.
|
698
|
-
|
699
|
-
- Use 'sqlite://<path_to_sqlite_file>' to connect to a SQLite DB.
|
700
|
-
|
701
|
-
- See https://docs.sqlalchemy.org/en/20/core/engines.html#backend-specific-urls for more details on supported DB URLs."""
|
702
|
-
),
|
703
|
-
)
|
704
|
-
@click.option(
|
705
|
-
"--artifact_storage_uri",
|
706
|
-
type=str,
|
707
|
-
help=(
|
708
|
-
"Optional. The artifact storage URI to store the artifacts, supported"
|
709
|
-
" URIs: gs://<bucket name> for GCS artifact service."
|
710
|
-
),
|
711
|
-
default=None,
|
712
|
-
)
|
713
767
|
@click.argument(
|
714
768
|
"agent",
|
715
769
|
type=click.Path(
|
@@ -726,6 +780,8 @@ def cli_api_server(
|
|
726
780
|
" version in the dev environment)"
|
727
781
|
),
|
728
782
|
)
|
783
|
+
@adk_services_options()
|
784
|
+
@deprecated_adk_services_options()
|
729
785
|
def cli_deploy_cloud_run(
|
730
786
|
agent: str,
|
731
787
|
project: Optional[str],
|
@@ -737,9 +793,12 @@ def cli_deploy_cloud_run(
|
|
737
793
|
trace_to_cloud: bool,
|
738
794
|
with_ui: bool,
|
739
795
|
verbosity: str,
|
740
|
-
session_db_url: str,
|
741
|
-
artifact_storage_uri: Optional[str],
|
742
796
|
adk_version: str,
|
797
|
+
session_service_uri: Optional[str] = None,
|
798
|
+
artifact_service_uri: Optional[str] = None,
|
799
|
+
memory_service_uri: Optional[str] = None,
|
800
|
+
session_db_url: Optional[str] = None, # Deprecated
|
801
|
+
artifact_storage_uri: Optional[str] = None, # Deprecated
|
743
802
|
):
|
744
803
|
"""Deploys an agent to Cloud Run.
|
745
804
|
|
@@ -749,6 +808,8 @@ def cli_deploy_cloud_run(
|
|
749
808
|
|
750
809
|
adk deploy cloud_run --project=[project] --region=[region] path/to/my_agent
|
751
810
|
"""
|
811
|
+
session_service_uri = session_service_uri or session_db_url
|
812
|
+
artifact_service_uri = artifact_service_uri or artifact_storage_uri
|
752
813
|
try:
|
753
814
|
cli_deploy.to_cloud_run(
|
754
815
|
agent_folder=agent,
|
@@ -761,9 +822,10 @@ def cli_deploy_cloud_run(
|
|
761
822
|
trace_to_cloud=trace_to_cloud,
|
762
823
|
with_ui=with_ui,
|
763
824
|
verbosity=verbosity,
|
764
|
-
session_db_url=session_db_url,
|
765
|
-
artifact_storage_uri=artifact_storage_uri,
|
766
825
|
adk_version=adk_version,
|
826
|
+
session_service_uri=session_service_uri,
|
827
|
+
artifact_service_uri=artifact_service_uri,
|
828
|
+
memory_service_uri=memory_service_uri,
|
767
829
|
)
|
768
830
|
except Exception as e:
|
769
831
|
click.secho(f"Deploy failed: {e}", fg="red", err=True)
|
@@ -773,12 +835,18 @@ def cli_deploy_cloud_run(
|
|
773
835
|
@click.option(
|
774
836
|
"--project",
|
775
837
|
type=str,
|
776
|
-
help=
|
838
|
+
help=(
|
839
|
+
"Required. Google Cloud project to deploy the agent. It will override"
|
840
|
+
" GOOGLE_CLOUD_PROJECT in the .env file (if it exists)."
|
841
|
+
),
|
777
842
|
)
|
778
843
|
@click.option(
|
779
844
|
"--region",
|
780
845
|
type=str,
|
781
|
-
help=
|
846
|
+
help=(
|
847
|
+
"Required. Google Cloud region to deploy the agent. It will override"
|
848
|
+
" GOOGLE_CLOUD_LOCATION in the .env file (if it exists)."
|
849
|
+
),
|
782
850
|
)
|
783
851
|
@click.option(
|
784
852
|
"--staging_bucket",
|
@@ -793,6 +861,20 @@ def cli_deploy_cloud_run(
|
|
793
861
|
default=False,
|
794
862
|
help="Optional. Whether to enable Cloud Trace for Agent Engine.",
|
795
863
|
)
|
864
|
+
@click.option(
|
865
|
+
"--display_name",
|
866
|
+
type=str,
|
867
|
+
show_default=True,
|
868
|
+
default="",
|
869
|
+
help="Optional. Display name of the agent in Agent Engine.",
|
870
|
+
)
|
871
|
+
@click.option(
|
872
|
+
"--description",
|
873
|
+
type=str,
|
874
|
+
show_default=True,
|
875
|
+
default="",
|
876
|
+
help="Optional. Description of the agent in Agent Engine.",
|
877
|
+
)
|
796
878
|
@click.option(
|
797
879
|
"--adk_app",
|
798
880
|
type=str,
|
@@ -847,6 +929,8 @@ def cli_deploy_agent_engine(
|
|
847
929
|
region: str,
|
848
930
|
staging_bucket: str,
|
849
931
|
trace_to_cloud: bool,
|
932
|
+
display_name: str,
|
933
|
+
description: str,
|
850
934
|
adk_app: str,
|
851
935
|
temp_folder: str,
|
852
936
|
env_file: str,
|
@@ -854,27 +938,12 @@ def cli_deploy_agent_engine(
|
|
854
938
|
):
|
855
939
|
"""Deploys an agent to Agent Engine.
|
856
940
|
|
857
|
-
|
858
|
-
agent (str): Required. The path to the agent to be deloyed.
|
859
|
-
project (str): Required. Google Cloud project to deploy the agent.
|
860
|
-
region (str): Required. Google Cloud region to deploy the agent.
|
861
|
-
staging_bucket (str): Required. GCS bucket for staging the deployment
|
862
|
-
artifacts.
|
863
|
-
trace_to_cloud (bool): Required. Whether to enable Cloud Trace.
|
864
|
-
adk_app (str): Required. Python file for defining the ADK application.
|
865
|
-
temp_folder (str): Required. The folder for the generated Agent Engine
|
866
|
-
files. If the folder already exists, its contents will be replaced.
|
867
|
-
env_file (str): Required. The filepath to the `.env` file for environment
|
868
|
-
variables. If it is an empty string, the `.env` file in the `agent`
|
869
|
-
directory will be used if it exists.
|
870
|
-
requirements_file (str): Required. The filepath to the `requirements.txt`
|
871
|
-
file to use. If it is an empty string, the `requirements.txt` file in the
|
872
|
-
`agent` directory will be used if exists.
|
941
|
+
AGENT: The path to the agent source code folder.
|
873
942
|
|
874
943
|
Example:
|
875
944
|
|
876
945
|
adk deploy agent_engine --project=[project] --region=[region]
|
877
|
-
--staging_bucket=[staging_bucket] path/to/my_agent
|
946
|
+
--staging_bucket=[staging_bucket] --display_name=[app_name] path/to/my_agent
|
878
947
|
"""
|
879
948
|
try:
|
880
949
|
cli_deploy.to_agent_engine(
|
@@ -883,6 +952,8 @@ def cli_deploy_agent_engine(
|
|
883
952
|
region=region,
|
884
953
|
staging_bucket=staging_bucket,
|
885
954
|
trace_to_cloud=trace_to_cloud,
|
955
|
+
display_name=display_name,
|
956
|
+
description=description,
|
886
957
|
adk_app=adk_app,
|
887
958
|
temp_folder=temp_folder,
|
888
959
|
env_file=env_file,
|
google/adk/cli/fast_api.py
CHANGED
@@ -57,6 +57,7 @@ from ..agents.llm_agent import Agent
|
|
57
57
|
from ..agents.run_config import StreamingMode
|
58
58
|
from ..artifacts.gcs_artifact_service import GcsArtifactService
|
59
59
|
from ..artifacts.in_memory_artifact_service import InMemoryArtifactService
|
60
|
+
from ..auth.credential_service.in_memory_credential_service import InMemoryCredentialService
|
60
61
|
from ..errors.not_found_error import NotFoundError
|
61
62
|
from ..evaluation.eval_case import EvalCase
|
62
63
|
from ..evaluation.eval_case import SessionInput
|
@@ -68,6 +69,7 @@ from ..evaluation.local_eval_set_results_manager import LocalEvalSetResultsManag
|
|
68
69
|
from ..evaluation.local_eval_sets_manager import LocalEvalSetsManager
|
69
70
|
from ..events.event import Event
|
70
71
|
from ..memory.in_memory_memory_service import InMemoryMemoryService
|
72
|
+
from ..memory.vertex_ai_rag_memory_service import VertexAiRagMemoryService
|
71
73
|
from ..runners import Runner
|
72
74
|
from ..sessions.database_session_service import DatabaseSessionService
|
73
75
|
from ..sessions.in_memory_session_service import InMemorySessionService
|
@@ -193,8 +195,9 @@ class GetEventGraphResult(common.BaseModel):
|
|
193
195
|
def get_fast_api_app(
|
194
196
|
*,
|
195
197
|
agents_dir: str,
|
196
|
-
|
197
|
-
|
198
|
+
session_service_uri: Optional[str] = None,
|
199
|
+
artifact_service_uri: Optional[str] = None,
|
200
|
+
memory_service_uri: Optional[str] = None,
|
198
201
|
allow_origins: Optional[list[str]] = None,
|
199
202
|
web: bool,
|
200
203
|
trace_to_cloud: bool = False,
|
@@ -257,38 +260,55 @@ def get_fast_api_app(
|
|
257
260
|
eval_set_results_manager = LocalEvalSetResultsManager(agents_dir=agents_dir)
|
258
261
|
|
259
262
|
# Build the Memory service
|
260
|
-
|
263
|
+
if memory_service_uri:
|
264
|
+
if memory_service_uri.startswith("rag://"):
|
265
|
+
rag_corpus = memory_service_uri.split("://")[1]
|
266
|
+
if not rag_corpus:
|
267
|
+
raise click.ClickException("Rag corpus can not be empty.")
|
268
|
+
envs.load_dotenv_for_agent("", agents_dir)
|
269
|
+
memory_service = VertexAiRagMemoryService(
|
270
|
+
rag_corpus=f'projects/{os.environ["GOOGLE_CLOUD_PROJECT"]}/locations/{os.environ["GOOGLE_CLOUD_LOCATION"]}/ragCorpora/{rag_corpus}'
|
271
|
+
)
|
272
|
+
else:
|
273
|
+
raise click.ClickException(
|
274
|
+
"Unsupported memory service URI: %s" % memory_service_uri
|
275
|
+
)
|
276
|
+
else:
|
277
|
+
memory_service = InMemoryMemoryService()
|
261
278
|
|
262
279
|
# Build the Session service
|
263
|
-
|
264
|
-
|
265
|
-
if session_db_url.startswith("agentengine://"):
|
280
|
+
if session_service_uri:
|
281
|
+
if session_service_uri.startswith("agentengine://"):
|
266
282
|
# Create vertex session service
|
267
|
-
agent_engine_id =
|
283
|
+
agent_engine_id = session_service_uri.split("://")[1]
|
268
284
|
if not agent_engine_id:
|
269
285
|
raise click.ClickException("Agent engine id can not be empty.")
|
270
286
|
envs.load_dotenv_for_agent("", agents_dir)
|
271
287
|
session_service = VertexAiSessionService(
|
272
|
-
os.environ["GOOGLE_CLOUD_PROJECT"],
|
273
|
-
os.environ["GOOGLE_CLOUD_LOCATION"],
|
288
|
+
project=os.environ["GOOGLE_CLOUD_PROJECT"],
|
289
|
+
location=os.environ["GOOGLE_CLOUD_LOCATION"],
|
290
|
+
agent_engine_id=agent_engine_id,
|
274
291
|
)
|
275
292
|
else:
|
276
|
-
session_service = DatabaseSessionService(db_url=
|
293
|
+
session_service = DatabaseSessionService(db_url=session_service_uri)
|
277
294
|
else:
|
278
295
|
session_service = InMemorySessionService()
|
279
296
|
|
280
297
|
# Build the Artifact service
|
281
|
-
if
|
282
|
-
if
|
283
|
-
gcs_bucket =
|
298
|
+
if artifact_service_uri:
|
299
|
+
if artifact_service_uri.startswith("gs://"):
|
300
|
+
gcs_bucket = artifact_service_uri.split("://")[1]
|
284
301
|
artifact_service = GcsArtifactService(bucket_name=gcs_bucket)
|
285
302
|
else:
|
286
303
|
raise click.ClickException(
|
287
|
-
"Unsupported artifact
|
304
|
+
"Unsupported artifact service URI: %s" % artifact_service_uri
|
288
305
|
)
|
289
306
|
else:
|
290
307
|
artifact_service = InMemoryArtifactService()
|
291
308
|
|
309
|
+
# Build the Credential service
|
310
|
+
credential_service = InMemoryCredentialService()
|
311
|
+
|
292
312
|
# initialize Agent Loader
|
293
313
|
agent_loader = AgentLoader(agents_dir)
|
294
314
|
|
@@ -341,8 +361,6 @@ def get_fast_api_app(
|
|
341
361
|
async def get_session(
|
342
362
|
app_name: str, user_id: str, session_id: str
|
343
363
|
) -> Session:
|
344
|
-
# Connect to managed session if agent_engine_id is set.
|
345
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
346
364
|
session = await session_service.get_session(
|
347
365
|
app_name=app_name, user_id=user_id, session_id=session_id
|
348
366
|
)
|
@@ -355,8 +373,6 @@ def get_fast_api_app(
|
|
355
373
|
response_model_exclude_none=True,
|
356
374
|
)
|
357
375
|
async def list_sessions(app_name: str, user_id: str) -> list[Session]:
|
358
|
-
# Connect to managed session if agent_engine_id is set.
|
359
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
360
376
|
list_sessions_response = await session_service.list_sessions(
|
361
377
|
app_name=app_name, user_id=user_id
|
362
378
|
)
|
@@ -377,8 +393,6 @@ def get_fast_api_app(
|
|
377
393
|
session_id: str,
|
378
394
|
state: Optional[dict[str, Any]] = None,
|
379
395
|
) -> Session:
|
380
|
-
# Connect to managed session if agent_engine_id is set.
|
381
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
382
396
|
if (
|
383
397
|
await session_service.get_session(
|
384
398
|
app_name=app_name, user_id=user_id, session_id=session_id
|
@@ -402,14 +416,19 @@ def get_fast_api_app(
|
|
402
416
|
app_name: str,
|
403
417
|
user_id: str,
|
404
418
|
state: Optional[dict[str, Any]] = None,
|
419
|
+
events: Optional[list[Event]] = None,
|
405
420
|
) -> Session:
|
406
|
-
# Connect to managed session if agent_engine_id is set.
|
407
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
408
421
|
logger.info("New session created")
|
409
|
-
|
422
|
+
session = await session_service.create_session(
|
410
423
|
app_name=app_name, user_id=user_id, state=state
|
411
424
|
)
|
412
425
|
|
426
|
+
if events:
|
427
|
+
for event in events:
|
428
|
+
await session_service.append_event(session=session, event=event)
|
429
|
+
|
430
|
+
return session
|
431
|
+
|
413
432
|
def _get_eval_set_file_path(app_name, agents_dir, eval_set_id) -> str:
|
414
433
|
return os.path.join(
|
415
434
|
agents_dir,
|
@@ -644,8 +663,6 @@ def get_fast_api_app(
|
|
644
663
|
|
645
664
|
@app.delete("/apps/{app_name}/users/{user_id}/sessions/{session_id}")
|
646
665
|
async def delete_session(app_name: str, user_id: str, session_id: str):
|
647
|
-
# Connect to managed session if agent_engine_id is set.
|
648
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
649
666
|
await session_service.delete_session(
|
650
667
|
app_name=app_name, user_id=user_id, session_id=session_id
|
651
668
|
)
|
@@ -661,7 +678,6 @@ def get_fast_api_app(
|
|
661
678
|
artifact_name: str,
|
662
679
|
version: Optional[int] = Query(None),
|
663
680
|
) -> Optional[types.Part]:
|
664
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
665
681
|
artifact = await artifact_service.load_artifact(
|
666
682
|
app_name=app_name,
|
667
683
|
user_id=user_id,
|
@@ -684,7 +700,6 @@ def get_fast_api_app(
|
|
684
700
|
artifact_name: str,
|
685
701
|
version_id: int,
|
686
702
|
) -> Optional[types.Part]:
|
687
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
688
703
|
artifact = await artifact_service.load_artifact(
|
689
704
|
app_name=app_name,
|
690
705
|
user_id=user_id,
|
@@ -703,7 +718,6 @@ def get_fast_api_app(
|
|
703
718
|
async def list_artifact_names(
|
704
719
|
app_name: str, user_id: str, session_id: str
|
705
720
|
) -> list[str]:
|
706
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
707
721
|
return await artifact_service.list_artifact_keys(
|
708
722
|
app_name=app_name, user_id=user_id, session_id=session_id
|
709
723
|
)
|
@@ -715,7 +729,6 @@ def get_fast_api_app(
|
|
715
729
|
async def list_artifact_versions(
|
716
730
|
app_name: str, user_id: str, session_id: str, artifact_name: str
|
717
731
|
) -> list[int]:
|
718
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
719
732
|
return await artifact_service.list_versions(
|
720
733
|
app_name=app_name,
|
721
734
|
user_id=user_id,
|
@@ -729,7 +742,6 @@ def get_fast_api_app(
|
|
729
742
|
async def delete_artifact(
|
730
743
|
app_name: str, user_id: str, session_id: str, artifact_name: str
|
731
744
|
):
|
732
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
733
745
|
await artifact_service.delete_artifact(
|
734
746
|
app_name=app_name,
|
735
747
|
user_id=user_id,
|
@@ -739,10 +751,8 @@ def get_fast_api_app(
|
|
739
751
|
|
740
752
|
@app.post("/run", response_model_exclude_none=True)
|
741
753
|
async def agent_run(req: AgentRunRequest) -> list[Event]:
|
742
|
-
# Connect to managed session if agent_engine_id is set.
|
743
|
-
app_name = agent_engine_id if agent_engine_id else req.app_name
|
744
754
|
session = await session_service.get_session(
|
745
|
-
app_name=app_name, user_id=req.user_id, session_id=req.session_id
|
755
|
+
app_name=req.app_name, user_id=req.user_id, session_id=req.session_id
|
746
756
|
)
|
747
757
|
if not session:
|
748
758
|
raise HTTPException(status_code=404, detail="Session not found")
|
@@ -760,11 +770,9 @@ def get_fast_api_app(
|
|
760
770
|
|
761
771
|
@app.post("/run_sse")
|
762
772
|
async def agent_run_sse(req: AgentRunRequest) -> StreamingResponse:
|
763
|
-
# Connect to managed session if agent_engine_id is set.
|
764
|
-
app_name = agent_engine_id if agent_engine_id else req.app_name
|
765
773
|
# SSE endpoint
|
766
774
|
session = await session_service.get_session(
|
767
|
-
app_name=app_name, user_id=req.user_id, session_id=req.session_id
|
775
|
+
app_name=req.app_name, user_id=req.user_id, session_id=req.session_id
|
768
776
|
)
|
769
777
|
if not session:
|
770
778
|
raise HTTPException(status_code=404, detail="Session not found")
|
@@ -802,8 +810,6 @@ def get_fast_api_app(
|
|
802
810
|
async def get_event_graph(
|
803
811
|
app_name: str, user_id: str, session_id: str, event_id: str
|
804
812
|
):
|
805
|
-
# Connect to managed session if agent_engine_id is set.
|
806
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
807
813
|
session = await session_service.get_session(
|
808
814
|
app_name=app_name, user_id=user_id, session_id=session_id
|
809
815
|
)
|
@@ -859,8 +865,6 @@ def get_fast_api_app(
|
|
859
865
|
) -> None:
|
860
866
|
await websocket.accept()
|
861
867
|
|
862
|
-
# Connect to managed session if agent_engine_id is set.
|
863
|
-
app_name = agent_engine_id if agent_engine_id else app_name
|
864
868
|
session = await session_service.get_session(
|
865
869
|
app_name=app_name, user_id=user_id, session_id=session_id
|
866
870
|
)
|
@@ -924,11 +928,12 @@ def get_fast_api_app(
|
|
924
928
|
return runner_dict[app_name]
|
925
929
|
root_agent = agent_loader.load_agent(app_name)
|
926
930
|
runner = Runner(
|
927
|
-
app_name=
|
931
|
+
app_name=app_name,
|
928
932
|
agent=root_agent,
|
929
933
|
artifact_service=artifact_service,
|
930
934
|
session_service=session_service,
|
931
935
|
memory_service=memory_service,
|
936
|
+
credential_service=credential_service,
|
932
937
|
)
|
933
938
|
runner_dict[app_name] = runner
|
934
939
|
return runner
|
@@ -76,7 +76,12 @@ class AgentLoader:
|
|
76
76
|
e.msg = f"Fail to load '{agent_name}' module. " + e.msg
|
77
77
|
raise e
|
78
78
|
except Exception as e:
|
79
|
-
e
|
79
|
+
if hasattr(e, "msg"):
|
80
|
+
e.msg = f"Fail to load '{agent_name}' module. " + e.msg
|
81
|
+
raise e
|
82
|
+
e.args = (
|
83
|
+
f"Fail to load '{agent_name}' module. {e.args[0] if e.args else ''}",
|
84
|
+
) + e.args[1:]
|
80
85
|
raise e
|
81
86
|
|
82
87
|
return None
|
@@ -110,7 +115,15 @@ class AgentLoader:
|
|
110
115
|
e.msg = f"Fail to load '{agent_name}.agent' module. " + e.msg
|
111
116
|
raise e
|
112
117
|
except Exception as e:
|
113
|
-
e
|
118
|
+
if hasattr(e, "msg"):
|
119
|
+
e.msg = f"Fail to load '{agent_name}.agent' module. " + e.msg
|
120
|
+
raise e
|
121
|
+
e.args = (
|
122
|
+
(
|
123
|
+
f"Fail to load '{agent_name}.agent' module."
|
124
|
+
f" {e.args[0] if e.args else ''}"
|
125
|
+
),
|
126
|
+
) + e.args[1:]
|
114
127
|
raise e
|
115
128
|
|
116
129
|
return None
|
@@ -12,7 +12,10 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
16
|
+
|
15
17
|
import atexit
|
18
|
+
import logging
|
16
19
|
import os
|
17
20
|
from typing import Optional
|
18
21
|
|
@@ -27,6 +30,7 @@ from .base_code_executor import BaseCodeExecutor
|
|
27
30
|
from .code_execution_utils import CodeExecutionInput
|
28
31
|
from .code_execution_utils import CodeExecutionResult
|
29
32
|
|
33
|
+
logger = logging.getLogger('google_adk.' + __name__)
|
30
34
|
DEFAULT_IMAGE_TAG = 'adk-code-executor:latest'
|
31
35
|
|
32
36
|
|
@@ -151,13 +155,13 @@ class ContainerCodeExecutor(BaseCodeExecutor):
|
|
151
155
|
if not os.path.exists(self.docker_path):
|
152
156
|
raise FileNotFoundError(f'Invalid Docker path: {self.docker_path}')
|
153
157
|
|
154
|
-
|
158
|
+
logger.info('Building Docker image...')
|
155
159
|
self._client.images.build(
|
156
160
|
path=self.docker_path,
|
157
161
|
tag=self.image,
|
158
162
|
rm=True,
|
159
163
|
)
|
160
|
-
|
164
|
+
logger.info('Docker image: %s built.', self.image)
|
161
165
|
|
162
166
|
def _verify_python_installation(self):
|
163
167
|
"""Verifies the container has python3 installed."""
|
@@ -173,13 +177,13 @@ class ContainerCodeExecutor(BaseCodeExecutor):
|
|
173
177
|
if self.docker_path:
|
174
178
|
self._build_docker_image()
|
175
179
|
|
176
|
-
|
180
|
+
logger.info('Starting container for ContainerCodeExecutor...')
|
177
181
|
self._container = self._client.containers.run(
|
178
182
|
image=self.image,
|
179
183
|
detach=True,
|
180
184
|
tty=True,
|
181
185
|
)
|
182
|
-
|
186
|
+
logger.info('Container %s started.', self._container.id)
|
183
187
|
|
184
188
|
# Verify the container is able to run python3.
|
185
189
|
self._verify_python_installation()
|
@@ -189,7 +193,7 @@ class ContainerCodeExecutor(BaseCodeExecutor):
|
|
189
193
|
if not self._container:
|
190
194
|
return
|
191
195
|
|
192
|
-
|
196
|
+
logger.info('[Cleanup] Stopping the container...')
|
193
197
|
self._container.stop()
|
194
198
|
self._container.remove()
|
195
|
-
|
199
|
+
logger.info('Container %s stopped and removed.', self._container.id)
|