google-adk 0.0.1__py3-none-any.whl → 0.0.2__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/__init__.py +20 -0
- google/adk/agents/__init__.py +32 -0
- google/adk/agents/active_streaming_tool.py +38 -0
- google/adk/agents/base_agent.py +345 -0
- google/adk/agents/callback_context.py +112 -0
- google/adk/agents/invocation_context.py +181 -0
- google/adk/agents/langgraph_agent.py +140 -0
- google/adk/agents/live_request_queue.py +64 -0
- google/adk/agents/llm_agent.py +376 -0
- google/adk/agents/loop_agent.py +62 -0
- google/adk/agents/parallel_agent.py +96 -0
- google/adk/agents/readonly_context.py +46 -0
- google/adk/agents/remote_agent.py +50 -0
- google/adk/agents/run_config.py +87 -0
- google/adk/agents/sequential_agent.py +45 -0
- google/adk/agents/transcription_entry.py +34 -0
- google/adk/artifacts/__init__.py +23 -0
- google/adk/artifacts/base_artifact_service.py +128 -0
- google/adk/artifacts/gcs_artifact_service.py +195 -0
- google/adk/artifacts/in_memory_artifact_service.py +133 -0
- google/adk/auth/__init__.py +22 -0
- google/adk/auth/auth_credential.py +220 -0
- google/adk/auth/auth_handler.py +268 -0
- google/adk/auth/auth_preprocessor.py +116 -0
- google/adk/auth/auth_schemes.py +67 -0
- google/adk/auth/auth_tool.py +55 -0
- google/adk/cli/__init__.py +15 -0
- google/adk/cli/__main__.py +18 -0
- google/adk/cli/agent_graph.py +122 -0
- google/adk/cli/browser/adk_favicon.svg +17 -0
- google/adk/cli/browser/assets/audio-processor.js +51 -0
- google/adk/cli/browser/assets/config/runtime-config.json +3 -0
- google/adk/cli/browser/index.html +33 -0
- google/adk/cli/browser/main-XUU6OGCC.js +75 -0
- google/adk/cli/browser/polyfills-FFHMD2TL.js +18 -0
- google/adk/cli/browser/styles-4VDSPQ37.css +17 -0
- google/adk/cli/cli.py +181 -0
- google/adk/cli/cli_deploy.py +181 -0
- google/adk/cli/cli_eval.py +282 -0
- google/adk/cli/cli_tools_click.py +479 -0
- google/adk/cli/fast_api.py +774 -0
- google/adk/cli/media_streamer/__init__.py +19 -0
- google/adk/cli/media_streamer/index.html +228 -0
- google/adk/cli/utils/__init__.py +49 -0
- google/adk/cli/utils/envs.py +57 -0
- google/adk/cli/utils/evals.py +93 -0
- google/adk/cli/utils/logs.py +72 -0
- google/adk/code_executors/__init__.py +49 -0
- google/adk/code_executors/base_code_executor.py +97 -0
- google/adk/code_executors/code_execution_utils.py +256 -0
- google/adk/code_executors/code_executor_context.py +202 -0
- google/adk/code_executors/container_code_executor.py +196 -0
- google/adk/code_executors/unsafe_local_code_executor.py +71 -0
- google/adk/code_executors/vertex_ai_code_executor.py +234 -0
- google/adk/evaluation/__init__.py +31 -0
- google/adk/evaluation/agent_evaluator.py +329 -0
- google/adk/evaluation/evaluation_constants.py +24 -0
- google/adk/evaluation/evaluation_generator.py +270 -0
- google/adk/evaluation/response_evaluator.py +135 -0
- google/adk/evaluation/trajectory_evaluator.py +184 -0
- google/adk/events/__init__.py +21 -0
- google/adk/events/event.py +130 -0
- google/adk/events/event_actions.py +55 -0
- google/adk/examples/__init__.py +28 -0
- google/adk/examples/base_example_provider.py +35 -0
- google/adk/examples/example.py +27 -0
- google/adk/examples/example_util.py +123 -0
- google/adk/examples/vertex_ai_example_store.py +104 -0
- google/adk/flows/__init__.py +14 -0
- google/adk/flows/llm_flows/__init__.py +20 -0
- google/adk/flows/llm_flows/_base_llm_processor.py +52 -0
- google/adk/flows/llm_flows/_code_execution.py +458 -0
- google/adk/flows/llm_flows/_nl_planning.py +129 -0
- google/adk/flows/llm_flows/agent_transfer.py +132 -0
- google/adk/flows/llm_flows/audio_transcriber.py +109 -0
- google/adk/flows/llm_flows/auto_flow.py +49 -0
- google/adk/flows/llm_flows/base_llm_flow.py +559 -0
- google/adk/flows/llm_flows/basic.py +72 -0
- google/adk/flows/llm_flows/contents.py +370 -0
- google/adk/flows/llm_flows/functions.py +486 -0
- google/adk/flows/llm_flows/identity.py +47 -0
- google/adk/flows/llm_flows/instructions.py +137 -0
- google/adk/flows/llm_flows/single_flow.py +57 -0
- google/adk/memory/__init__.py +35 -0
- google/adk/memory/base_memory_service.py +74 -0
- google/adk/memory/in_memory_memory_service.py +62 -0
- google/adk/memory/vertex_ai_rag_memory_service.py +177 -0
- google/adk/models/__init__.py +31 -0
- google/adk/models/anthropic_llm.py +243 -0
- google/adk/models/base_llm.py +87 -0
- google/adk/models/base_llm_connection.py +76 -0
- google/adk/models/gemini_llm_connection.py +200 -0
- google/adk/models/google_llm.py +331 -0
- google/adk/models/lite_llm.py +673 -0
- google/adk/models/llm_request.py +98 -0
- google/adk/models/llm_response.py +111 -0
- google/adk/models/registry.py +102 -0
- google/adk/planners/__init__.py +23 -0
- google/adk/planners/base_planner.py +66 -0
- google/adk/planners/built_in_planner.py +75 -0
- google/adk/planners/plan_re_act_planner.py +208 -0
- google/adk/runners.py +456 -0
- google/adk/sessions/__init__.py +41 -0
- google/adk/sessions/base_session_service.py +133 -0
- google/adk/sessions/database_session_service.py +522 -0
- google/adk/sessions/in_memory_session_service.py +206 -0
- google/adk/sessions/session.py +54 -0
- google/adk/sessions/state.py +71 -0
- google/adk/sessions/vertex_ai_session_service.py +356 -0
- google/adk/telemetry.py +189 -0
- google/adk/tests/__init__.py +14 -0
- google/adk/tests/integration/.env.example +10 -0
- google/adk/tests/integration/__init__.py +18 -0
- google/adk/tests/integration/conftest.py +119 -0
- google/adk/tests/integration/fixture/__init__.py +14 -0
- google/adk/tests/integration/fixture/agent_with_config/__init__.py +15 -0
- google/adk/tests/integration/fixture/agent_with_config/agent.py +88 -0
- google/adk/tests/integration/fixture/callback_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/callback_agent/agent.py +105 -0
- google/adk/tests/integration/fixture/context_update_test/OWNERS +1 -0
- google/adk/tests/integration/fixture/context_update_test/__init__.py +15 -0
- google/adk/tests/integration/fixture/context_update_test/agent.py +43 -0
- google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +582 -0
- google/adk/tests/integration/fixture/context_variable_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/context_variable_agent/agent.py +115 -0
- google/adk/tests/integration/fixture/customer_support_ma/__init__.py +15 -0
- google/adk/tests/integration/fixture/customer_support_ma/agent.py +172 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +338 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +69 -0
- google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +6 -0
- google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +15 -0
- google/adk/tests/integration/fixture/flow_complex_spark/agent.py +182 -0
- google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +243 -0
- google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +190 -0
- google/adk/tests/integration/fixture/hello_world_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/hello_world_agent/agent.py +95 -0
- google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +24 -0
- google/adk/tests/integration/fixture/hello_world_agent/test_config.json +6 -0
- google/adk/tests/integration/fixture/home_automation_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/home_automation_agent/agent.py +304 -0
- google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_config.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +18 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +17 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +6 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +18 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +17 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +5 -0
- google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +5 -0
- google/adk/tests/integration/fixture/tool_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/tool_agent/agent.py +218 -0
- google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
- google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +15 -0
- google/adk/tests/integration/fixture/trip_planner_agent/agent.py +110 -0
- google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +13 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +5 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +13 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +5 -0
- google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +7 -0
- google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +19 -0
- google/adk/tests/integration/models/__init__.py +14 -0
- google/adk/tests/integration/models/test_google_llm.py +65 -0
- google/adk/tests/integration/test_callback.py +70 -0
- google/adk/tests/integration/test_context_variable.py +67 -0
- google/adk/tests/integration/test_evalute_agent_in_fixture.py +76 -0
- google/adk/tests/integration/test_multi_agent.py +28 -0
- google/adk/tests/integration/test_multi_turn.py +42 -0
- google/adk/tests/integration/test_single_agent.py +23 -0
- google/adk/tests/integration/test_sub_agent.py +26 -0
- google/adk/tests/integration/test_system_instruction.py +177 -0
- google/adk/tests/integration/test_tools.py +287 -0
- google/adk/tests/integration/test_with_test_file.py +34 -0
- google/adk/tests/integration/tools/__init__.py +14 -0
- google/adk/tests/integration/utils/__init__.py +16 -0
- google/adk/tests/integration/utils/asserts.py +75 -0
- google/adk/tests/integration/utils/test_runner.py +97 -0
- google/adk/tests/unittests/__init__.py +14 -0
- google/adk/tests/unittests/agents/__init__.py +14 -0
- google/adk/tests/unittests/agents/test_base_agent.py +407 -0
- google/adk/tests/unittests/agents/test_langgraph_agent.py +191 -0
- google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +138 -0
- google/adk/tests/unittests/agents/test_llm_agent_fields.py +231 -0
- google/adk/tests/unittests/agents/test_loop_agent.py +136 -0
- google/adk/tests/unittests/agents/test_parallel_agent.py +92 -0
- google/adk/tests/unittests/agents/test_sequential_agent.py +114 -0
- google/adk/tests/unittests/artifacts/__init__.py +14 -0
- google/adk/tests/unittests/artifacts/test_artifact_service.py +276 -0
- google/adk/tests/unittests/auth/test_auth_handler.py +575 -0
- google/adk/tests/unittests/conftest.py +73 -0
- google/adk/tests/unittests/fast_api/__init__.py +14 -0
- google/adk/tests/unittests/fast_api/test_fast_api.py +269 -0
- google/adk/tests/unittests/flows/__init__.py +14 -0
- google/adk/tests/unittests/flows/llm_flows/__init__.py +14 -0
- google/adk/tests/unittests/flows/llm_flows/_test_examples.py +142 -0
- google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +311 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +244 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +346 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +93 -0
- google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +258 -0
- google/adk/tests/unittests/flows/llm_flows/test_identity.py +66 -0
- google/adk/tests/unittests/flows/llm_flows/test_instructions.py +164 -0
- google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +142 -0
- google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +46 -0
- google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +269 -0
- google/adk/tests/unittests/models/__init__.py +14 -0
- google/adk/tests/unittests/models/test_google_llm.py +224 -0
- google/adk/tests/unittests/models/test_litellm.py +804 -0
- google/adk/tests/unittests/models/test_models.py +60 -0
- google/adk/tests/unittests/sessions/__init__.py +14 -0
- google/adk/tests/unittests/sessions/test_session_service.py +227 -0
- google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +246 -0
- google/adk/tests/unittests/streaming/__init__.py +14 -0
- google/adk/tests/unittests/streaming/test_streaming.py +50 -0
- google/adk/tests/unittests/tools/__init__.py +14 -0
- google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +499 -0
- google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +204 -0
- google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +600 -0
- google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +630 -0
- google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +345 -0
- google/adk/tests/unittests/tools/google_api_tool/__init__.py +13 -0
- google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +657 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +145 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +68 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +153 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +196 -0
- google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +573 -0
- google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +436 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +1367 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +628 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +139 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +406 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +966 -0
- google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +201 -0
- google/adk/tests/unittests/tools/retrieval/__init__.py +14 -0
- google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +147 -0
- google/adk/tests/unittests/tools/test_agent_tool.py +167 -0
- google/adk/tests/unittests/tools/test_base_tool.py +141 -0
- google/adk/tests/unittests/tools/test_build_function_declaration.py +277 -0
- google/adk/tests/unittests/utils.py +304 -0
- google/adk/tools/__init__.py +51 -0
- google/adk/tools/_automatic_function_calling_util.py +346 -0
- google/adk/tools/agent_tool.py +176 -0
- google/adk/tools/apihub_tool/__init__.py +19 -0
- google/adk/tools/apihub_tool/apihub_toolset.py +209 -0
- google/adk/tools/apihub_tool/clients/__init__.py +13 -0
- google/adk/tools/apihub_tool/clients/apihub_client.py +332 -0
- google/adk/tools/apihub_tool/clients/secret_client.py +115 -0
- google/adk/tools/application_integration_tool/__init__.py +19 -0
- google/adk/tools/application_integration_tool/application_integration_toolset.py +230 -0
- google/adk/tools/application_integration_tool/clients/connections_client.py +903 -0
- google/adk/tools/application_integration_tool/clients/integration_client.py +253 -0
- google/adk/tools/base_tool.py +144 -0
- google/adk/tools/built_in_code_execution_tool.py +59 -0
- google/adk/tools/crewai_tool.py +72 -0
- google/adk/tools/example_tool.py +62 -0
- google/adk/tools/exit_loop_tool.py +23 -0
- google/adk/tools/function_parameter_parse_util.py +307 -0
- google/adk/tools/function_tool.py +87 -0
- google/adk/tools/get_user_choice_tool.py +28 -0
- google/adk/tools/google_api_tool/__init__.py +14 -0
- google/adk/tools/google_api_tool/google_api_tool.py +59 -0
- google/adk/tools/google_api_tool/google_api_tool_set.py +107 -0
- google/adk/tools/google_api_tool/google_api_tool_sets.py +55 -0
- google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +521 -0
- google/adk/tools/google_search_tool.py +68 -0
- google/adk/tools/langchain_tool.py +86 -0
- google/adk/tools/load_artifacts_tool.py +113 -0
- google/adk/tools/load_memory_tool.py +58 -0
- google/adk/tools/load_web_page.py +41 -0
- google/adk/tools/long_running_tool.py +39 -0
- google/adk/tools/mcp_tool/__init__.py +42 -0
- google/adk/tools/mcp_tool/conversion_utils.py +161 -0
- google/adk/tools/mcp_tool/mcp_tool.py +113 -0
- google/adk/tools/mcp_tool/mcp_toolset.py +272 -0
- google/adk/tools/openapi_tool/__init__.py +21 -0
- google/adk/tools/openapi_tool/auth/__init__.py +19 -0
- google/adk/tools/openapi_tool/auth/auth_helpers.py +498 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +25 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +105 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +55 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +117 -0
- google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +97 -0
- google/adk/tools/openapi_tool/common/__init__.py +19 -0
- google/adk/tools/openapi_tool/common/common.py +300 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +32 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +231 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +144 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +260 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +496 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +268 -0
- google/adk/tools/preload_memory_tool.py +72 -0
- google/adk/tools/retrieval/__init__.py +36 -0
- google/adk/tools/retrieval/base_retrieval_tool.py +37 -0
- google/adk/tools/retrieval/files_retrieval.py +33 -0
- google/adk/tools/retrieval/llama_index_retrieval.py +41 -0
- google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +107 -0
- google/adk/tools/tool_context.py +90 -0
- google/adk/tools/toolbox_tool.py +46 -0
- google/adk/tools/transfer_to_agent_tool.py +21 -0
- google/adk/tools/vertex_ai_search_tool.py +96 -0
- google/adk/version.py +16 -0
- google_adk-0.0.1.dist-info/LICENSE.txt → google_adk-0.0.2.dist-info/LICENSE +32 -0
- google_adk-0.0.2.dist-info/METADATA +73 -0
- google_adk-0.0.2.dist-info/RECORD +308 -0
- {google_adk-0.0.1.dist-info → google_adk-0.0.2.dist-info}/WHEEL +1 -2
- google_adk-0.0.2.dist-info/entry_points.txt +3 -0
- agent_kit/__init__.py +0 -0
- google_adk-0.0.1.dist-info/METADATA +0 -15
- google_adk-0.0.1.dist-info/RECORD +0 -6
- google_adk-0.0.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,287 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
import json
|
16
|
+
|
17
|
+
import pytest
|
18
|
+
|
19
|
+
# Skip until fixed.
|
20
|
+
pytest.skip(allow_module_level=True)
|
21
|
+
|
22
|
+
from .fixture import tool_agent
|
23
|
+
from .utils import TestRunner
|
24
|
+
|
25
|
+
|
26
|
+
@pytest.mark.parametrize(
|
27
|
+
"agent_runner",
|
28
|
+
[{"agent": tool_agent.agent.single_function_agent}],
|
29
|
+
indirect=True,
|
30
|
+
)
|
31
|
+
def test_single_function_calls_success(agent_runner: TestRunner):
|
32
|
+
_call_function_and_assert(
|
33
|
+
agent_runner,
|
34
|
+
"simple_function",
|
35
|
+
"test",
|
36
|
+
"success",
|
37
|
+
)
|
38
|
+
|
39
|
+
|
40
|
+
@pytest.mark.parametrize(
|
41
|
+
"agent_runner",
|
42
|
+
[{"agent": tool_agent.agent.root_agent}],
|
43
|
+
indirect=True,
|
44
|
+
)
|
45
|
+
def test_multiple_function_calls_success(agent_runner: TestRunner):
|
46
|
+
_call_function_and_assert(
|
47
|
+
agent_runner,
|
48
|
+
"simple_function",
|
49
|
+
"test",
|
50
|
+
"success",
|
51
|
+
)
|
52
|
+
_call_function_and_assert(
|
53
|
+
agent_runner,
|
54
|
+
"no_param_function",
|
55
|
+
None,
|
56
|
+
"Called no param function successfully",
|
57
|
+
)
|
58
|
+
_call_function_and_assert(
|
59
|
+
agent_runner,
|
60
|
+
"no_output_function",
|
61
|
+
"test",
|
62
|
+
"",
|
63
|
+
)
|
64
|
+
_call_function_and_assert(
|
65
|
+
agent_runner,
|
66
|
+
"multiple_param_types_function",
|
67
|
+
["test", 1, 2.34, True],
|
68
|
+
"success",
|
69
|
+
)
|
70
|
+
_call_function_and_assert(
|
71
|
+
agent_runner,
|
72
|
+
"return_list_str_function",
|
73
|
+
"test",
|
74
|
+
"success",
|
75
|
+
)
|
76
|
+
_call_function_and_assert(
|
77
|
+
agent_runner,
|
78
|
+
"list_str_param_function",
|
79
|
+
["test", "test2", "test3", "test4"],
|
80
|
+
"success",
|
81
|
+
)
|
82
|
+
|
83
|
+
|
84
|
+
@pytest.mark.skip(reason="Currently failing with 400 on MLDev.")
|
85
|
+
@pytest.mark.parametrize(
|
86
|
+
"agent_runner",
|
87
|
+
[{"agent": tool_agent.agent.root_agent}],
|
88
|
+
indirect=True,
|
89
|
+
)
|
90
|
+
def test_complex_function_calls_success(agent_runner: TestRunner):
|
91
|
+
param1 = {"name": "Test", "count": 3}
|
92
|
+
param2 = [
|
93
|
+
{"name": "Function", "count": 2},
|
94
|
+
{"name": "Retrieval", "count": 1},
|
95
|
+
]
|
96
|
+
_call_function_and_assert(
|
97
|
+
agent_runner,
|
98
|
+
"complex_function_list_dict",
|
99
|
+
[param1, param2],
|
100
|
+
"test",
|
101
|
+
)
|
102
|
+
|
103
|
+
|
104
|
+
@pytest.mark.parametrize(
|
105
|
+
"agent_runner",
|
106
|
+
[{"agent": tool_agent.agent.root_agent}],
|
107
|
+
indirect=True,
|
108
|
+
)
|
109
|
+
def test_repetive_call_success(agent_runner: TestRunner):
|
110
|
+
_call_function_and_assert(
|
111
|
+
agent_runner,
|
112
|
+
"repetive_call_1",
|
113
|
+
"test",
|
114
|
+
"test_repetive",
|
115
|
+
)
|
116
|
+
|
117
|
+
|
118
|
+
@pytest.mark.parametrize(
|
119
|
+
"agent_runner",
|
120
|
+
[{"agent": tool_agent.agent.root_agent}],
|
121
|
+
indirect=True,
|
122
|
+
)
|
123
|
+
def test_function_calls_fail(agent_runner: TestRunner):
|
124
|
+
_call_function_and_assert(
|
125
|
+
agent_runner,
|
126
|
+
"throw_error_function",
|
127
|
+
"test",
|
128
|
+
None,
|
129
|
+
ValueError,
|
130
|
+
)
|
131
|
+
|
132
|
+
|
133
|
+
@pytest.mark.parametrize(
|
134
|
+
"agent_runner",
|
135
|
+
[{"agent": tool_agent.agent.root_agent}],
|
136
|
+
indirect=True,
|
137
|
+
)
|
138
|
+
def test_agent_tools_success(agent_runner: TestRunner):
|
139
|
+
_call_function_and_assert(
|
140
|
+
agent_runner,
|
141
|
+
"no_schema_agent",
|
142
|
+
"Hi",
|
143
|
+
"Hi",
|
144
|
+
)
|
145
|
+
_call_function_and_assert(
|
146
|
+
agent_runner,
|
147
|
+
"schema_agent",
|
148
|
+
"Agent_tools",
|
149
|
+
"Agent_tools_success",
|
150
|
+
)
|
151
|
+
_call_function_and_assert(
|
152
|
+
agent_runner, "no_input_schema_agent", "Tools", "Tools_success"
|
153
|
+
)
|
154
|
+
_call_function_and_assert(agent_runner, "no_output_schema_agent", "Hi", "Hi")
|
155
|
+
|
156
|
+
|
157
|
+
@pytest.mark.parametrize(
|
158
|
+
"agent_runner",
|
159
|
+
[{"agent": tool_agent.agent.root_agent}],
|
160
|
+
indirect=True,
|
161
|
+
)
|
162
|
+
def test_files_retrieval_success(agent_runner: TestRunner):
|
163
|
+
_call_function_and_assert(
|
164
|
+
agent_runner,
|
165
|
+
"test_case_retrieval",
|
166
|
+
"What is the testing strategy of agent 2.0?",
|
167
|
+
"test",
|
168
|
+
)
|
169
|
+
# For non relevant query, the agent should still be running fine, just return
|
170
|
+
# response might be different for different calls, so we don't compare the
|
171
|
+
# response here.
|
172
|
+
_call_function_and_assert(
|
173
|
+
agent_runner,
|
174
|
+
"test_case_retrieval",
|
175
|
+
"What is the whether in bay area?",
|
176
|
+
"",
|
177
|
+
)
|
178
|
+
|
179
|
+
|
180
|
+
@pytest.mark.parametrize(
|
181
|
+
"agent_runner",
|
182
|
+
[{"agent": tool_agent.agent.root_agent}],
|
183
|
+
indirect=True,
|
184
|
+
)
|
185
|
+
def test_rag_retrieval_success(agent_runner: TestRunner):
|
186
|
+
_call_function_and_assert(
|
187
|
+
agent_runner,
|
188
|
+
"valid_rag_retrieval",
|
189
|
+
"What is the testing strategy of agent 2.0?",
|
190
|
+
"test",
|
191
|
+
)
|
192
|
+
_call_function_and_assert(
|
193
|
+
agent_runner,
|
194
|
+
"valid_rag_retrieval",
|
195
|
+
"What is the whether in bay area?",
|
196
|
+
"No",
|
197
|
+
)
|
198
|
+
|
199
|
+
|
200
|
+
@pytest.mark.parametrize(
|
201
|
+
"agent_runner",
|
202
|
+
[{"agent": tool_agent.agent.root_agent}],
|
203
|
+
indirect=True,
|
204
|
+
)
|
205
|
+
def test_rag_retrieval_fail(agent_runner: TestRunner):
|
206
|
+
_call_function_and_assert(
|
207
|
+
agent_runner,
|
208
|
+
"invalid_rag_retrieval",
|
209
|
+
"What is the testing strategy of agent 2.0?",
|
210
|
+
None,
|
211
|
+
ValueError,
|
212
|
+
)
|
213
|
+
_call_function_and_assert(
|
214
|
+
agent_runner,
|
215
|
+
"non_exist_rag_retrieval",
|
216
|
+
"What is the whether in bay area?",
|
217
|
+
None,
|
218
|
+
ValueError,
|
219
|
+
)
|
220
|
+
|
221
|
+
|
222
|
+
@pytest.mark.parametrize(
|
223
|
+
"agent_runner",
|
224
|
+
[{"agent": tool_agent.agent.root_agent}],
|
225
|
+
indirect=True,
|
226
|
+
)
|
227
|
+
def test_langchain_tool_success(agent_runner: TestRunner):
|
228
|
+
_call_function_and_assert(
|
229
|
+
agent_runner,
|
230
|
+
"terminal",
|
231
|
+
"Run the following shell command 'echo test!'",
|
232
|
+
"test",
|
233
|
+
)
|
234
|
+
|
235
|
+
|
236
|
+
@pytest.mark.parametrize(
|
237
|
+
"agent_runner",
|
238
|
+
[{"agent": tool_agent.agent.root_agent}],
|
239
|
+
indirect=True,
|
240
|
+
)
|
241
|
+
def test_crewai_tool_success(agent_runner: TestRunner):
|
242
|
+
_call_function_and_assert(
|
243
|
+
agent_runner,
|
244
|
+
"direcotry_read_tool",
|
245
|
+
"Find all the file paths",
|
246
|
+
"file",
|
247
|
+
)
|
248
|
+
|
249
|
+
|
250
|
+
def _call_function_and_assert(
|
251
|
+
agent_runner: TestRunner,
|
252
|
+
function_name: str,
|
253
|
+
params,
|
254
|
+
expected=None,
|
255
|
+
exception: Exception = None,
|
256
|
+
):
|
257
|
+
param_section = (
|
258
|
+
" with params"
|
259
|
+
f" {params if isinstance(params, str) else json.dumps(params)}"
|
260
|
+
if params is not None
|
261
|
+
else ""
|
262
|
+
)
|
263
|
+
query = f"Call {function_name}{param_section} and show me the result"
|
264
|
+
if exception:
|
265
|
+
_assert_raises(agent_runner, query, exception)
|
266
|
+
return
|
267
|
+
|
268
|
+
_assert_function_output(agent_runner, query, expected)
|
269
|
+
|
270
|
+
|
271
|
+
def _assert_raises(agent_runner: TestRunner, query: str, exception: Exception):
|
272
|
+
with pytest.raises(exception):
|
273
|
+
agent_runner.run(query)
|
274
|
+
|
275
|
+
|
276
|
+
def _assert_function_output(agent_runner: TestRunner, query: str, expected):
|
277
|
+
agent_runner.run(query)
|
278
|
+
|
279
|
+
# Retrieve the latest model response event
|
280
|
+
model_response_event = agent_runner.get_events()[-1]
|
281
|
+
|
282
|
+
# Assert the response content
|
283
|
+
assert model_response_event.content.role == "model"
|
284
|
+
assert (
|
285
|
+
expected.lower()
|
286
|
+
in model_response_event.content.parts[0].text.strip().lower()
|
287
|
+
)
|
@@ -0,0 +1,34 @@
|
|
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 google.adk.evaluation import AgentEvaluator
|
16
|
+
|
17
|
+
|
18
|
+
def test_with_single_test_file():
|
19
|
+
"""Test the agent's basic ability via session file."""
|
20
|
+
AgentEvaluator.evaluate(
|
21
|
+
agent_module="tests.integration.fixture.home_automation_agent",
|
22
|
+
eval_dataset_file_path_or_dir="tests/integration/fixture/home_automation_agent/simple_test.test.json",
|
23
|
+
)
|
24
|
+
|
25
|
+
|
26
|
+
def test_with_folder_of_test_files_long_running():
|
27
|
+
"""Test the agent's basic ability via a folder of session files."""
|
28
|
+
AgentEvaluator.evaluate(
|
29
|
+
agent_module="tests.integration.fixture.home_automation_agent",
|
30
|
+
eval_dataset_file_path_or_dir=(
|
31
|
+
"tests/integration/fixture/home_automation_agent/test_files"
|
32
|
+
),
|
33
|
+
num_runs=4,
|
34
|
+
)
|
@@ -0,0 +1,14 @@
|
|
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
|
+
|
@@ -0,0 +1,16 @@
|
|
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 .asserts import *
|
16
|
+
from .test_runner import TestRunner
|
@@ -0,0 +1,75 @@
|
|
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 typing import TypedDict
|
16
|
+
|
17
|
+
from .test_runner import TestRunner
|
18
|
+
|
19
|
+
|
20
|
+
class Message(TypedDict):
|
21
|
+
agent_name: str
|
22
|
+
expected_text: str
|
23
|
+
|
24
|
+
|
25
|
+
def assert_current_agent_is(agent_name: str, *, agent_runner: TestRunner):
|
26
|
+
assert agent_runner.get_current_agent_name() == agent_name
|
27
|
+
|
28
|
+
|
29
|
+
def assert_agent_says(
|
30
|
+
expected_text: str, *, agent_name: str, agent_runner: TestRunner
|
31
|
+
):
|
32
|
+
for event in reversed(agent_runner.get_events()):
|
33
|
+
if event.author == agent_name and event.content.parts[0].text:
|
34
|
+
assert event.content.parts[0].text.strip() == expected_text
|
35
|
+
return
|
36
|
+
|
37
|
+
|
38
|
+
def assert_agent_says_in_order(
|
39
|
+
expected_conversaction: list[Message], agent_runner: TestRunner
|
40
|
+
):
|
41
|
+
expected_conversaction_idx = len(expected_conversaction) - 1
|
42
|
+
for event in reversed(agent_runner.get_events()):
|
43
|
+
if event.content.parts and event.content.parts[0].text:
|
44
|
+
assert (
|
45
|
+
event.author
|
46
|
+
== expected_conversaction[expected_conversaction_idx]['agent_name']
|
47
|
+
)
|
48
|
+
assert (
|
49
|
+
event.content.parts[0].text.strip()
|
50
|
+
== expected_conversaction[expected_conversaction_idx]['expected_text']
|
51
|
+
)
|
52
|
+
expected_conversaction_idx -= 1
|
53
|
+
if expected_conversaction_idx < 0:
|
54
|
+
return
|
55
|
+
|
56
|
+
|
57
|
+
def assert_agent_transfer_path(
|
58
|
+
expected_path: list[str], *, agent_runner: TestRunner
|
59
|
+
):
|
60
|
+
events = agent_runner.get_events()
|
61
|
+
idx_in_expected_path = len(expected_path) - 1
|
62
|
+
# iterate events in reverse order
|
63
|
+
for event in reversed(events):
|
64
|
+
function_calls = event.get_function_calls()
|
65
|
+
if (
|
66
|
+
len(function_calls) == 1
|
67
|
+
and function_calls[0].name == 'transfer_to_agent'
|
68
|
+
):
|
69
|
+
assert (
|
70
|
+
function_calls[0].args['agent_name']
|
71
|
+
== expected_path[idx_in_expected_path]
|
72
|
+
)
|
73
|
+
idx_in_expected_path -= 1
|
74
|
+
if idx_in_expected_path < 0:
|
75
|
+
return
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
import importlib
|
16
|
+
from typing import Optional
|
17
|
+
|
18
|
+
from google.adk import Agent
|
19
|
+
from google.adk import Runner
|
20
|
+
from google.adk.artifacts import BaseArtifactService
|
21
|
+
from google.adk.artifacts import InMemoryArtifactService
|
22
|
+
from google.adk.events import Event
|
23
|
+
from google.adk.sessions import BaseSessionService
|
24
|
+
from google.adk.sessions import InMemorySessionService
|
25
|
+
from google.adk.sessions import Session
|
26
|
+
from google.genai import types
|
27
|
+
|
28
|
+
|
29
|
+
class TestRunner:
|
30
|
+
"""Agents runner for testings."""
|
31
|
+
|
32
|
+
app_name = "test_app"
|
33
|
+
user_id = "test_user"
|
34
|
+
|
35
|
+
def __init__(
|
36
|
+
self,
|
37
|
+
agent: Agent,
|
38
|
+
artifact_service: BaseArtifactService = InMemoryArtifactService(),
|
39
|
+
session_service: BaseSessionService = InMemorySessionService(),
|
40
|
+
) -> None:
|
41
|
+
self.agent = agent
|
42
|
+
self.agent_client = Runner(
|
43
|
+
app_name=self.app_name,
|
44
|
+
agent=agent,
|
45
|
+
artifact_service=artifact_service,
|
46
|
+
session_service=session_service,
|
47
|
+
)
|
48
|
+
self.session_service = session_service
|
49
|
+
self.current_session_id = session_service.create_session(
|
50
|
+
app_name=self.app_name, user_id=self.user_id
|
51
|
+
).id
|
52
|
+
|
53
|
+
def new_session(self, session_id: Optional[str] = None) -> None:
|
54
|
+
self.current_session_id = self.session_service.create_session(
|
55
|
+
app_name=self.app_name, user_id=self.user_id, session_id=session_id
|
56
|
+
).id
|
57
|
+
|
58
|
+
def run(self, prompt: str) -> list[Event]:
|
59
|
+
current_session = self.session_service.get_session(
|
60
|
+
app_name=self.app_name,
|
61
|
+
user_id=self.user_id,
|
62
|
+
session_id=self.current_session_id,
|
63
|
+
)
|
64
|
+
assert current_session is not None
|
65
|
+
|
66
|
+
return list(
|
67
|
+
self.agent_client.run(
|
68
|
+
user_id=current_session.user_id,
|
69
|
+
session_id=current_session.id,
|
70
|
+
new_message=types.Content(
|
71
|
+
role="user",
|
72
|
+
parts=[types.Part.from_text(text=prompt)],
|
73
|
+
),
|
74
|
+
)
|
75
|
+
)
|
76
|
+
|
77
|
+
def get_current_session(self) -> Optional[Session]:
|
78
|
+
return self.session_service.get_session(
|
79
|
+
app_name=self.app_name,
|
80
|
+
user_id=self.user_id,
|
81
|
+
session_id=self.current_session_id,
|
82
|
+
)
|
83
|
+
|
84
|
+
def get_events(self) -> list[Event]:
|
85
|
+
return self.get_current_session().events
|
86
|
+
|
87
|
+
@classmethod
|
88
|
+
def from_agent_name(cls, agent_name: str):
|
89
|
+
agent_module_path = f"tests.integration.fixture.{agent_name}"
|
90
|
+
agent_module = importlib.import_module(agent_module_path)
|
91
|
+
agent: Agent = agent_module.agent.root_agent
|
92
|
+
return cls(agent)
|
93
|
+
|
94
|
+
def get_current_agent_name(self) -> str:
|
95
|
+
return self.agent_client._find_agent_to_run(
|
96
|
+
self.get_current_session(), self.agent
|
97
|
+
).name
|
@@ -0,0 +1,14 @@
|
|
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
|
+
|
@@ -0,0 +1,14 @@
|
|
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
|
+
|