google-adk 0.0.1__py3-none-any.whl → 0.0.3__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/._version.py +0 -0
- 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 +148 -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-SY2WYYGV.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 +524 -0
- google/adk/cli/fast_api.py +784 -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/docs/Makefile +20 -0
- google/adk/docs/build/doctrees/google-adk.doctree +0 -0
- google/adk/docs/build/html/_sources/google-adk.rst.txt +98 -0
- google/adk/docs/build/html/_sources/index.rst.txt +7 -0
- google/adk/docs/build/html/_static/autodoc_pydantic.css +27 -0
- google/adk/docs/build/html/_static/basic.css +925 -0
- google/adk/docs/build/html/_static/debug.css +85 -0
- google/adk/docs/build/html/_static/doctools.js +156 -0
- google/adk/docs/build/html/_static/documentation_options.js +29 -0
- google/adk/docs/build/html/_static/file.png +0 -0
- google/adk/docs/build/html/_static/language_data.js +199 -0
- google/adk/docs/build/html/_static/minus.png +0 -0
- google/adk/docs/build/html/_static/plus.png +0 -0
- google/adk/docs/build/html/_static/pygments.css +274 -0
- google/adk/docs/build/html/_static/scripts/furo-extensions.js +16 -0
- google/adk/docs/build/html/_static/scripts/furo.js +19 -0
- google/adk/docs/build/html/_static/scripts/furo.js.LICENSE.txt +7 -0
- google/adk/docs/build/html/_static/scripts/furo.js.map +1 -0
- google/adk/docs/build/html/_static/searchtools.js +620 -0
- google/adk/docs/build/html/_static/skeleton.css +312 -0
- google/adk/docs/build/html/_static/sphinx_highlight.js +170 -0
- google/adk/docs/build/html/_static/styles/furo-extensions.css +18 -0
- google/adk/docs/build/html/_static/styles/furo-extensions.css.map +1 -0
- google/adk/docs/build/html/_static/styles/furo.css +18 -0
- google/adk/docs/build/html/_static/styles/furo.css.map +1 -0
- google/adk/docs/build/html/genindex.html +861 -0
- google/adk/docs/build/html/google-adk.html +5461 -0
- google/adk/docs/build/html/index.html +567 -0
- google/adk/docs/build/html/objects.inv +0 -0
- google/adk/docs/build/html/py-modindex.html +373 -0
- google/adk/docs/build/html/search.html +333 -0
- google/adk/docs/build/html/searchindex.js +17 -0
- google/adk/docs/source/conf.py +133 -0
- google/adk/docs/source/google-adk.rst +98 -0
- google/adk/docs/source/index.rst +7 -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.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.3.dist-info/METADATA +73 -0
- google_adk-0.0.3.dist-info/RECORD +340 -0
- {google_adk-0.0.1.dist-info → google_adk-0.0.3.dist-info}/WHEEL +1 -2
- google_adk-0.0.3.dist-info/entry_points.txt +3 -0
- agent_kit/__init__.py +0 -0
- google_adk-0.0.1.dist-info/LICENSE.txt +0 -170
- 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,138 @@
|
|
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 Any
|
16
|
+
from typing import Optional
|
17
|
+
|
18
|
+
from google.adk.agents.callback_context import CallbackContext
|
19
|
+
from google.adk.agents.llm_agent import Agent
|
20
|
+
from google.adk.models import LlmRequest
|
21
|
+
from google.adk.models import LlmResponse
|
22
|
+
from google.genai import types
|
23
|
+
from pydantic import BaseModel
|
24
|
+
import pytest
|
25
|
+
|
26
|
+
from .. import utils
|
27
|
+
|
28
|
+
|
29
|
+
class MockBeforeModelCallback(BaseModel):
|
30
|
+
mock_response: str
|
31
|
+
|
32
|
+
def __call__(
|
33
|
+
self,
|
34
|
+
callback_context: CallbackContext,
|
35
|
+
llm_request: LlmRequest,
|
36
|
+
) -> LlmResponse:
|
37
|
+
return LlmResponse(
|
38
|
+
content=utils.ModelContent(
|
39
|
+
[types.Part.from_text(text=self.mock_response)]
|
40
|
+
)
|
41
|
+
)
|
42
|
+
|
43
|
+
|
44
|
+
class MockAfterModelCallback(BaseModel):
|
45
|
+
mock_response: str
|
46
|
+
|
47
|
+
def __call__(
|
48
|
+
self,
|
49
|
+
callback_context: CallbackContext,
|
50
|
+
llm_response: LlmResponse,
|
51
|
+
) -> LlmResponse:
|
52
|
+
return LlmResponse(
|
53
|
+
content=utils.ModelContent(
|
54
|
+
[types.Part.from_text(text=self.mock_response)]
|
55
|
+
)
|
56
|
+
)
|
57
|
+
|
58
|
+
|
59
|
+
def noop_callback(**kwargs) -> Optional[LlmResponse]:
|
60
|
+
pass
|
61
|
+
|
62
|
+
|
63
|
+
@pytest.mark.asyncio
|
64
|
+
async def test_before_model_callback():
|
65
|
+
responses = ['model_response']
|
66
|
+
mock_model = utils.MockModel.create(responses=responses)
|
67
|
+
agent = Agent(
|
68
|
+
name='root_agent',
|
69
|
+
model=mock_model,
|
70
|
+
before_model_callback=MockBeforeModelCallback(
|
71
|
+
mock_response='before_model_callback'
|
72
|
+
),
|
73
|
+
)
|
74
|
+
|
75
|
+
runner = utils.TestInMemoryRunner(agent)
|
76
|
+
assert utils.simplify_events(
|
77
|
+
await runner.run_async_with_new_session('test')
|
78
|
+
) == [
|
79
|
+
('root_agent', 'before_model_callback'),
|
80
|
+
]
|
81
|
+
|
82
|
+
|
83
|
+
@pytest.mark.asyncio
|
84
|
+
async def test_before_model_callback_noop():
|
85
|
+
responses = ['model_response']
|
86
|
+
mock_model = utils.MockModel.create(responses=responses)
|
87
|
+
agent = Agent(
|
88
|
+
name='root_agent',
|
89
|
+
model=mock_model,
|
90
|
+
before_model_callback=noop_callback,
|
91
|
+
)
|
92
|
+
|
93
|
+
runner = utils.TestInMemoryRunner(agent)
|
94
|
+
assert utils.simplify_events(
|
95
|
+
await runner.run_async_with_new_session('test')
|
96
|
+
) == [
|
97
|
+
('root_agent', 'model_response'),
|
98
|
+
]
|
99
|
+
|
100
|
+
|
101
|
+
@pytest.mark.asyncio
|
102
|
+
async def test_before_model_callback_end():
|
103
|
+
responses = ['model_response']
|
104
|
+
mock_model = utils.MockModel.create(responses=responses)
|
105
|
+
agent = Agent(
|
106
|
+
name='root_agent',
|
107
|
+
model=mock_model,
|
108
|
+
before_model_callback=MockBeforeModelCallback(
|
109
|
+
mock_response='before_model_callback',
|
110
|
+
),
|
111
|
+
)
|
112
|
+
|
113
|
+
runner = utils.TestInMemoryRunner(agent)
|
114
|
+
assert utils.simplify_events(
|
115
|
+
await runner.run_async_with_new_session('test')
|
116
|
+
) == [
|
117
|
+
('root_agent', 'before_model_callback'),
|
118
|
+
]
|
119
|
+
|
120
|
+
|
121
|
+
@pytest.mark.asyncio
|
122
|
+
async def test_after_model_callback():
|
123
|
+
responses = ['model_response']
|
124
|
+
mock_model = utils.MockModel.create(responses=responses)
|
125
|
+
agent = Agent(
|
126
|
+
name='root_agent',
|
127
|
+
model=mock_model,
|
128
|
+
after_model_callback=MockAfterModelCallback(
|
129
|
+
mock_response='after_model_callback'
|
130
|
+
),
|
131
|
+
)
|
132
|
+
|
133
|
+
runner = utils.TestInMemoryRunner(agent)
|
134
|
+
assert utils.simplify_events(
|
135
|
+
await runner.run_async_with_new_session('test')
|
136
|
+
) == [
|
137
|
+
('root_agent', 'after_model_callback'),
|
138
|
+
]
|
@@ -0,0 +1,231 @@
|
|
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
|
+
"""Unit tests for canonical_xxx fields in LlmAgent."""
|
16
|
+
|
17
|
+
from typing import Any
|
18
|
+
from typing import Optional
|
19
|
+
|
20
|
+
from google.adk.agents.callback_context import CallbackContext
|
21
|
+
from google.adk.agents.invocation_context import InvocationContext
|
22
|
+
from google.adk.agents.llm_agent import LlmAgent
|
23
|
+
from google.adk.agents.loop_agent import LoopAgent
|
24
|
+
from google.adk.agents.readonly_context import ReadonlyContext
|
25
|
+
from google.adk.models.llm_request import LlmRequest
|
26
|
+
from google.adk.models.registry import LLMRegistry
|
27
|
+
from google.adk.sessions.in_memory_session_service import InMemorySessionService
|
28
|
+
from google.genai import types
|
29
|
+
from pydantic import BaseModel
|
30
|
+
import pytest
|
31
|
+
|
32
|
+
|
33
|
+
def _create_readonly_context(
|
34
|
+
agent: LlmAgent, state: Optional[dict[str, Any]] = None
|
35
|
+
) -> ReadonlyContext:
|
36
|
+
session_service = InMemorySessionService()
|
37
|
+
session = session_service.create_session(
|
38
|
+
app_name='test_app', user_id='test_user', state=state
|
39
|
+
)
|
40
|
+
invocation_context = InvocationContext(
|
41
|
+
invocation_id='test_id',
|
42
|
+
agent=agent,
|
43
|
+
session=session,
|
44
|
+
session_service=session_service,
|
45
|
+
)
|
46
|
+
return ReadonlyContext(invocation_context)
|
47
|
+
|
48
|
+
|
49
|
+
def test_canonical_model_empty():
|
50
|
+
agent = LlmAgent(name='test_agent')
|
51
|
+
|
52
|
+
with pytest.raises(ValueError):
|
53
|
+
_ = agent.canonical_model
|
54
|
+
|
55
|
+
|
56
|
+
def test_canonical_model_str():
|
57
|
+
agent = LlmAgent(name='test_agent', model='gemini-pro')
|
58
|
+
|
59
|
+
assert agent.canonical_model.model == 'gemini-pro'
|
60
|
+
|
61
|
+
|
62
|
+
def test_canonical_model_llm():
|
63
|
+
llm = LLMRegistry.new_llm('gemini-pro')
|
64
|
+
agent = LlmAgent(name='test_agent', model=llm)
|
65
|
+
|
66
|
+
assert agent.canonical_model == llm
|
67
|
+
|
68
|
+
|
69
|
+
def test_canonical_model_inherit():
|
70
|
+
sub_agent = LlmAgent(name='sub_agent')
|
71
|
+
parent_agent = LlmAgent(
|
72
|
+
name='parent_agent', model='gemini-pro', sub_agents=[sub_agent]
|
73
|
+
)
|
74
|
+
|
75
|
+
assert sub_agent.canonical_model == parent_agent.canonical_model
|
76
|
+
|
77
|
+
|
78
|
+
def test_canonical_instruction_str():
|
79
|
+
agent = LlmAgent(name='test_agent', instruction='instruction')
|
80
|
+
ctx = _create_readonly_context(agent)
|
81
|
+
|
82
|
+
assert agent.canonical_instruction(ctx) == 'instruction'
|
83
|
+
|
84
|
+
|
85
|
+
def test_canonical_instruction():
|
86
|
+
def _instruction_provider(ctx: ReadonlyContext) -> str:
|
87
|
+
return f'instruction: {ctx.state["state_var"]}'
|
88
|
+
|
89
|
+
agent = LlmAgent(name='test_agent', instruction=_instruction_provider)
|
90
|
+
ctx = _create_readonly_context(agent, state={'state_var': 'state_value'})
|
91
|
+
|
92
|
+
assert agent.canonical_instruction(ctx) == 'instruction: state_value'
|
93
|
+
|
94
|
+
|
95
|
+
def test_canonical_global_instruction_str():
|
96
|
+
agent = LlmAgent(name='test_agent', global_instruction='global instruction')
|
97
|
+
ctx = _create_readonly_context(agent)
|
98
|
+
|
99
|
+
assert agent.canonical_global_instruction(ctx) == 'global instruction'
|
100
|
+
|
101
|
+
|
102
|
+
def test_canonical_global_instruction():
|
103
|
+
def _global_instruction_provider(ctx: ReadonlyContext) -> str:
|
104
|
+
return f'global instruction: {ctx.state["state_var"]}'
|
105
|
+
|
106
|
+
agent = LlmAgent(
|
107
|
+
name='test_agent', global_instruction=_global_instruction_provider
|
108
|
+
)
|
109
|
+
ctx = _create_readonly_context(agent, state={'state_var': 'state_value'})
|
110
|
+
|
111
|
+
assert (
|
112
|
+
agent.canonical_global_instruction(ctx)
|
113
|
+
== 'global instruction: state_value'
|
114
|
+
)
|
115
|
+
|
116
|
+
|
117
|
+
def test_output_schema_will_disable_transfer(caplog: pytest.LogCaptureFixture):
|
118
|
+
with caplog.at_level('WARNING'):
|
119
|
+
|
120
|
+
class Schema(BaseModel):
|
121
|
+
pass
|
122
|
+
|
123
|
+
agent = LlmAgent(
|
124
|
+
name='test_agent',
|
125
|
+
output_schema=Schema,
|
126
|
+
)
|
127
|
+
|
128
|
+
# Transfer is automatically disabled
|
129
|
+
assert agent.disallow_transfer_to_parent
|
130
|
+
assert agent.disallow_transfer_to_peers
|
131
|
+
assert (
|
132
|
+
'output_schema cannot co-exist with agent transfer configurations.'
|
133
|
+
in caplog.text
|
134
|
+
)
|
135
|
+
|
136
|
+
|
137
|
+
def test_output_schema_with_sub_agents_will_throw():
|
138
|
+
class Schema(BaseModel):
|
139
|
+
pass
|
140
|
+
|
141
|
+
sub_agent = LlmAgent(
|
142
|
+
name='sub_agent',
|
143
|
+
)
|
144
|
+
|
145
|
+
with pytest.raises(ValueError):
|
146
|
+
_ = LlmAgent(
|
147
|
+
name='test_agent',
|
148
|
+
output_schema=Schema,
|
149
|
+
sub_agents=[sub_agent],
|
150
|
+
)
|
151
|
+
|
152
|
+
|
153
|
+
def test_output_schema_with_tools_will_throw():
|
154
|
+
class Schema(BaseModel):
|
155
|
+
pass
|
156
|
+
|
157
|
+
def _a_tool():
|
158
|
+
pass
|
159
|
+
|
160
|
+
with pytest.raises(ValueError):
|
161
|
+
_ = LlmAgent(
|
162
|
+
name='test_agent',
|
163
|
+
output_schema=Schema,
|
164
|
+
tools=[_a_tool],
|
165
|
+
)
|
166
|
+
|
167
|
+
|
168
|
+
def test_before_model_callback():
|
169
|
+
def _before_model_callback(
|
170
|
+
callback_context: CallbackContext,
|
171
|
+
llm_request: LlmRequest,
|
172
|
+
) -> None:
|
173
|
+
return None
|
174
|
+
|
175
|
+
agent = LlmAgent(
|
176
|
+
name='test_agent', before_model_callback=_before_model_callback
|
177
|
+
)
|
178
|
+
|
179
|
+
# TODO: add more logic assertions later.
|
180
|
+
assert agent.before_model_callback is not None
|
181
|
+
|
182
|
+
|
183
|
+
def test_validate_generate_content_config_thinking_config_throw():
|
184
|
+
with pytest.raises(ValueError):
|
185
|
+
_ = LlmAgent(
|
186
|
+
name='test_agent',
|
187
|
+
generate_content_config=types.GenerateContentConfig(
|
188
|
+
thinking_config=types.ThinkingConfig()
|
189
|
+
),
|
190
|
+
)
|
191
|
+
|
192
|
+
|
193
|
+
def test_validate_generate_content_config_tools_throw():
|
194
|
+
with pytest.raises(ValueError):
|
195
|
+
_ = LlmAgent(
|
196
|
+
name='test_agent',
|
197
|
+
generate_content_config=types.GenerateContentConfig(
|
198
|
+
tools=[types.Tool(function_declarations=[])]
|
199
|
+
),
|
200
|
+
)
|
201
|
+
|
202
|
+
|
203
|
+
def test_validate_generate_content_config_system_instruction_throw():
|
204
|
+
with pytest.raises(ValueError):
|
205
|
+
_ = LlmAgent(
|
206
|
+
name='test_agent',
|
207
|
+
generate_content_config=types.GenerateContentConfig(
|
208
|
+
system_instruction='system instruction'
|
209
|
+
),
|
210
|
+
)
|
211
|
+
|
212
|
+
|
213
|
+
def test_validate_generate_content_config_response_schema_throw():
|
214
|
+
class Schema(BaseModel):
|
215
|
+
pass
|
216
|
+
|
217
|
+
with pytest.raises(ValueError):
|
218
|
+
_ = LlmAgent(
|
219
|
+
name='test_agent',
|
220
|
+
generate_content_config=types.GenerateContentConfig(
|
221
|
+
response_schema=Schema
|
222
|
+
),
|
223
|
+
)
|
224
|
+
|
225
|
+
|
226
|
+
def test_allow_transfer_by_default():
|
227
|
+
sub_agent = LlmAgent(name='sub_agent')
|
228
|
+
agent = LlmAgent(name='test_agent', sub_agents=[sub_agent])
|
229
|
+
|
230
|
+
assert not agent.disallow_transfer_to_parent
|
231
|
+
assert not agent.disallow_transfer_to_peers
|
@@ -0,0 +1,136 @@
|
|
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
|
+
"""Testings for the SequentialAgent."""
|
16
|
+
|
17
|
+
from typing import AsyncGenerator
|
18
|
+
|
19
|
+
from google.adk.agents.base_agent import BaseAgent
|
20
|
+
from google.adk.agents.invocation_context import InvocationContext
|
21
|
+
from google.adk.agents.loop_agent import LoopAgent
|
22
|
+
from google.adk.events import Event
|
23
|
+
from google.adk.events import EventActions
|
24
|
+
from google.adk.sessions.in_memory_session_service import InMemorySessionService
|
25
|
+
from google.genai import types
|
26
|
+
import pytest
|
27
|
+
from typing_extensions import override
|
28
|
+
|
29
|
+
|
30
|
+
class _TestingAgent(BaseAgent):
|
31
|
+
|
32
|
+
@override
|
33
|
+
async def _run_async_impl(
|
34
|
+
self, ctx: InvocationContext
|
35
|
+
) -> AsyncGenerator[Event, None]:
|
36
|
+
yield Event(
|
37
|
+
author=self.name,
|
38
|
+
invocation_id=ctx.invocation_id,
|
39
|
+
content=types.Content(
|
40
|
+
parts=[types.Part(text=f'Hello, async {self.name}!')]
|
41
|
+
),
|
42
|
+
)
|
43
|
+
|
44
|
+
@override
|
45
|
+
async def _run_live_impl(
|
46
|
+
self, ctx: InvocationContext
|
47
|
+
) -> AsyncGenerator[Event, None]:
|
48
|
+
yield Event(
|
49
|
+
author=self.name,
|
50
|
+
invocation_id=ctx.invocation_id,
|
51
|
+
content=types.Content(
|
52
|
+
parts=[types.Part(text=f'Hello, live {self.name}!')]
|
53
|
+
),
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
class _TestingAgentWithEscalateAction(BaseAgent):
|
58
|
+
|
59
|
+
@override
|
60
|
+
async def _run_async_impl(
|
61
|
+
self, ctx: InvocationContext
|
62
|
+
) -> AsyncGenerator[Event, None]:
|
63
|
+
yield Event(
|
64
|
+
author=self.name,
|
65
|
+
invocation_id=ctx.invocation_id,
|
66
|
+
content=types.Content(
|
67
|
+
parts=[types.Part(text=f'Hello, async {self.name}!')]
|
68
|
+
),
|
69
|
+
actions=EventActions(escalate=True),
|
70
|
+
)
|
71
|
+
|
72
|
+
|
73
|
+
def _create_parent_invocation_context(
|
74
|
+
test_name: str, agent: BaseAgent
|
75
|
+
) -> InvocationContext:
|
76
|
+
session_service = InMemorySessionService()
|
77
|
+
session = session_service.create_session(
|
78
|
+
app_name='test_app', user_id='test_user'
|
79
|
+
)
|
80
|
+
return InvocationContext(
|
81
|
+
invocation_id=f'{test_name}_invocation_id',
|
82
|
+
agent=agent,
|
83
|
+
session=session,
|
84
|
+
session_service=session_service,
|
85
|
+
)
|
86
|
+
|
87
|
+
|
88
|
+
@pytest.mark.asyncio
|
89
|
+
async def test_run_async(request: pytest.FixtureRequest):
|
90
|
+
agent = _TestingAgent(name=f'{request.function.__name__}_test_agent')
|
91
|
+
loop_agent = LoopAgent(
|
92
|
+
name=f'{request.function.__name__}_test_loop_agent',
|
93
|
+
max_iterations=2,
|
94
|
+
sub_agents=[
|
95
|
+
agent,
|
96
|
+
],
|
97
|
+
)
|
98
|
+
parent_ctx = _create_parent_invocation_context(
|
99
|
+
request.function.__name__, loop_agent
|
100
|
+
)
|
101
|
+
events = [e async for e in loop_agent.run_async(parent_ctx)]
|
102
|
+
|
103
|
+
assert len(events) == 2
|
104
|
+
assert events[0].author == agent.name
|
105
|
+
assert events[1].author == agent.name
|
106
|
+
assert events[0].content.parts[0].text == f'Hello, async {agent.name}!'
|
107
|
+
assert events[1].content.parts[0].text == f'Hello, async {agent.name}!'
|
108
|
+
|
109
|
+
|
110
|
+
@pytest.mark.asyncio
|
111
|
+
async def test_run_async_with_escalate_action(request: pytest.FixtureRequest):
|
112
|
+
non_escalating_agent = _TestingAgent(
|
113
|
+
name=f'{request.function.__name__}_test_non_escalating_agent'
|
114
|
+
)
|
115
|
+
escalating_agent = _TestingAgentWithEscalateAction(
|
116
|
+
name=f'{request.function.__name__}_test_escalating_agent'
|
117
|
+
)
|
118
|
+
loop_agent = LoopAgent(
|
119
|
+
name=f'{request.function.__name__}_test_loop_agent',
|
120
|
+
sub_agents=[non_escalating_agent, escalating_agent],
|
121
|
+
)
|
122
|
+
parent_ctx = _create_parent_invocation_context(
|
123
|
+
request.function.__name__, loop_agent
|
124
|
+
)
|
125
|
+
events = [e async for e in loop_agent.run_async(parent_ctx)]
|
126
|
+
|
127
|
+
# Only two events are generated because the sub escalating_agent escalates.
|
128
|
+
assert len(events) == 2
|
129
|
+
assert events[0].author == non_escalating_agent.name
|
130
|
+
assert events[1].author == escalating_agent.name
|
131
|
+
assert events[0].content.parts[0].text == (
|
132
|
+
f'Hello, async {non_escalating_agent.name}!'
|
133
|
+
)
|
134
|
+
assert events[1].content.parts[0].text == (
|
135
|
+
f'Hello, async {escalating_agent.name}!'
|
136
|
+
)
|
@@ -0,0 +1,92 @@
|
|
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
|
+
"""Tests for the ParallelAgent."""
|
16
|
+
|
17
|
+
import asyncio
|
18
|
+
from typing import AsyncGenerator
|
19
|
+
|
20
|
+
from google.adk.agents.base_agent import BaseAgent
|
21
|
+
from google.adk.agents.invocation_context import InvocationContext
|
22
|
+
from google.adk.agents.parallel_agent import ParallelAgent
|
23
|
+
from google.adk.events import Event
|
24
|
+
from google.adk.sessions.in_memory_session_service import InMemorySessionService
|
25
|
+
from google.genai import types
|
26
|
+
import pytest
|
27
|
+
from typing_extensions import override
|
28
|
+
|
29
|
+
|
30
|
+
class _TestingAgent(BaseAgent):
|
31
|
+
|
32
|
+
delay: float = 0
|
33
|
+
"""The delay before the agent generates an event."""
|
34
|
+
|
35
|
+
@override
|
36
|
+
async def _run_async_impl(
|
37
|
+
self, ctx: InvocationContext
|
38
|
+
) -> AsyncGenerator[Event, None]:
|
39
|
+
await asyncio.sleep(self.delay)
|
40
|
+
yield Event(
|
41
|
+
author=self.name,
|
42
|
+
branch=ctx.branch,
|
43
|
+
invocation_id=ctx.invocation_id,
|
44
|
+
content=types.Content(
|
45
|
+
parts=[types.Part(text=f'Hello, async {self.name}!')]
|
46
|
+
),
|
47
|
+
)
|
48
|
+
|
49
|
+
|
50
|
+
def _create_parent_invocation_context(
|
51
|
+
test_name: str, agent: BaseAgent
|
52
|
+
) -> InvocationContext:
|
53
|
+
session_service = InMemorySessionService()
|
54
|
+
session = session_service.create_session(
|
55
|
+
app_name='test_app', user_id='test_user'
|
56
|
+
)
|
57
|
+
return InvocationContext(
|
58
|
+
invocation_id=f'{test_name}_invocation_id',
|
59
|
+
agent=agent,
|
60
|
+
session=session,
|
61
|
+
session_service=session_service,
|
62
|
+
)
|
63
|
+
|
64
|
+
|
65
|
+
@pytest.mark.asyncio
|
66
|
+
async def test_run_async(request: pytest.FixtureRequest):
|
67
|
+
agent1 = _TestingAgent(
|
68
|
+
name=f'{request.function.__name__}_test_agent_1',
|
69
|
+
delay=0.5,
|
70
|
+
)
|
71
|
+
agent2 = _TestingAgent(name=f'{request.function.__name__}_test_agent_2')
|
72
|
+
parallel_agent = ParallelAgent(
|
73
|
+
name=f'{request.function.__name__}_test_parallel_agent',
|
74
|
+
sub_agents=[
|
75
|
+
agent1,
|
76
|
+
agent2,
|
77
|
+
],
|
78
|
+
)
|
79
|
+
parent_ctx = _create_parent_invocation_context(
|
80
|
+
request.function.__name__, parallel_agent
|
81
|
+
)
|
82
|
+
events = [e async for e in parallel_agent.run_async(parent_ctx)]
|
83
|
+
|
84
|
+
assert len(events) == 2
|
85
|
+
# agent2 generates an event first, then agent1. Because they run in parallel
|
86
|
+
# and agent1 has a delay.
|
87
|
+
assert events[0].author == agent2.name
|
88
|
+
assert events[1].author == agent1.name
|
89
|
+
assert events[0].branch.endswith(agent2.name)
|
90
|
+
assert events[1].branch.endswith(agent1.name)
|
91
|
+
assert events[0].content.parts[0].text == f'Hello, async {agent2.name}!'
|
92
|
+
assert events[1].content.parts[0].text == f'Hello, async {agent1.name}!'
|
@@ -0,0 +1,114 @@
|
|
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
|
+
"""Testings for the SequentialAgent."""
|
16
|
+
|
17
|
+
from typing import AsyncGenerator
|
18
|
+
|
19
|
+
from google.adk.agents.base_agent import BaseAgent
|
20
|
+
from google.adk.agents.invocation_context import InvocationContext
|
21
|
+
from google.adk.agents.sequential_agent import SequentialAgent
|
22
|
+
from google.adk.events import Event
|
23
|
+
from google.adk.sessions.in_memory_session_service import InMemorySessionService
|
24
|
+
from google.genai import types
|
25
|
+
import pytest
|
26
|
+
from typing_extensions import override
|
27
|
+
|
28
|
+
|
29
|
+
class _TestingAgent(BaseAgent):
|
30
|
+
|
31
|
+
@override
|
32
|
+
async def _run_async_impl(
|
33
|
+
self, ctx: InvocationContext
|
34
|
+
) -> AsyncGenerator[Event, None]:
|
35
|
+
yield Event(
|
36
|
+
author=self.name,
|
37
|
+
invocation_id=ctx.invocation_id,
|
38
|
+
content=types.Content(
|
39
|
+
parts=[types.Part(text=f'Hello, async {self.name}!')]
|
40
|
+
),
|
41
|
+
)
|
42
|
+
|
43
|
+
@override
|
44
|
+
async def _run_live_impl(
|
45
|
+
self, ctx: InvocationContext
|
46
|
+
) -> AsyncGenerator[Event, None]:
|
47
|
+
yield Event(
|
48
|
+
author=self.name,
|
49
|
+
invocation_id=ctx.invocation_id,
|
50
|
+
content=types.Content(
|
51
|
+
parts=[types.Part(text=f'Hello, live {self.name}!')]
|
52
|
+
),
|
53
|
+
)
|
54
|
+
|
55
|
+
|
56
|
+
def _create_parent_invocation_context(
|
57
|
+
test_name: str, agent: BaseAgent
|
58
|
+
) -> InvocationContext:
|
59
|
+
session_service = InMemorySessionService()
|
60
|
+
session = session_service.create_session(
|
61
|
+
app_name='test_app', user_id='test_user'
|
62
|
+
)
|
63
|
+
return InvocationContext(
|
64
|
+
invocation_id=f'{test_name}_invocation_id',
|
65
|
+
agent=agent,
|
66
|
+
session=session,
|
67
|
+
session_service=session_service,
|
68
|
+
)
|
69
|
+
|
70
|
+
|
71
|
+
@pytest.mark.asyncio
|
72
|
+
async def test_run_async(request: pytest.FixtureRequest):
|
73
|
+
agent_1 = _TestingAgent(name=f'{request.function.__name__}_test_agent_1')
|
74
|
+
agent_2 = _TestingAgent(name=f'{request.function.__name__}_test_agent_2')
|
75
|
+
sequential_agent = SequentialAgent(
|
76
|
+
name=f'{request.function.__name__}_test_agent',
|
77
|
+
sub_agents=[
|
78
|
+
agent_1,
|
79
|
+
agent_2,
|
80
|
+
],
|
81
|
+
)
|
82
|
+
parent_ctx = _create_parent_invocation_context(
|
83
|
+
request.function.__name__, sequential_agent
|
84
|
+
)
|
85
|
+
events = [e async for e in sequential_agent.run_async(parent_ctx)]
|
86
|
+
|
87
|
+
assert len(events) == 2
|
88
|
+
assert events[0].author == agent_1.name
|
89
|
+
assert events[1].author == agent_2.name
|
90
|
+
assert events[0].content.parts[0].text == f'Hello, async {agent_1.name}!'
|
91
|
+
assert events[1].content.parts[0].text == f'Hello, async {agent_2.name}!'
|
92
|
+
|
93
|
+
|
94
|
+
@pytest.mark.asyncio
|
95
|
+
async def test_run_live(request: pytest.FixtureRequest):
|
96
|
+
agent_1 = _TestingAgent(name=f'{request.function.__name__}_test_agent_1')
|
97
|
+
agent_2 = _TestingAgent(name=f'{request.function.__name__}_test_agent_2')
|
98
|
+
sequential_agent = SequentialAgent(
|
99
|
+
name=f'{request.function.__name__}_test_agent',
|
100
|
+
sub_agents=[
|
101
|
+
agent_1,
|
102
|
+
agent_2,
|
103
|
+
],
|
104
|
+
)
|
105
|
+
parent_ctx = _create_parent_invocation_context(
|
106
|
+
request.function.__name__, sequential_agent
|
107
|
+
)
|
108
|
+
events = [e async for e in sequential_agent.run_live(parent_ctx)]
|
109
|
+
|
110
|
+
assert len(events) == 2
|
111
|
+
assert events[0].author == agent_1.name
|
112
|
+
assert events[1].author == agent_2.name
|
113
|
+
assert events[0].content.parts[0].text == f'Hello, live {agent_1.name}!'
|
114
|
+
assert events[1].content.parts[0].text == f'Hello, live {agent_2.name}!'
|