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,559 @@
|
|
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 __future__ import annotations
|
16
|
+
|
17
|
+
from abc import ABC
|
18
|
+
import asyncio
|
19
|
+
import logging
|
20
|
+
from typing import AsyncGenerator
|
21
|
+
from typing import cast
|
22
|
+
from typing import Optional
|
23
|
+
from typing import TYPE_CHECKING
|
24
|
+
|
25
|
+
from websockets.exceptions import ConnectionClosedOK
|
26
|
+
|
27
|
+
from ...agents.base_agent import BaseAgent
|
28
|
+
from ...agents.callback_context import CallbackContext
|
29
|
+
from ...agents.invocation_context import InvocationContext
|
30
|
+
from ...agents.live_request_queue import LiveRequestQueue
|
31
|
+
from ...agents.run_config import StreamingMode
|
32
|
+
from ...agents.transcription_entry import TranscriptionEntry
|
33
|
+
from ...events.event import Event
|
34
|
+
from ...models.base_llm_connection import BaseLlmConnection
|
35
|
+
from ...models.llm_request import LlmRequest
|
36
|
+
from ...models.llm_response import LlmResponse
|
37
|
+
from ...telemetry import trace_call_llm
|
38
|
+
from ...telemetry import trace_send_data
|
39
|
+
from ...telemetry import tracer
|
40
|
+
from ...tools.tool_context import ToolContext
|
41
|
+
from . import functions
|
42
|
+
|
43
|
+
if TYPE_CHECKING:
|
44
|
+
from ...agents.llm_agent import LlmAgent
|
45
|
+
from ...models.base_llm import BaseLlm
|
46
|
+
from ._base_llm_processor import BaseLlmRequestProcessor
|
47
|
+
from ._base_llm_processor import BaseLlmResponseProcessor
|
48
|
+
|
49
|
+
logger = logging.getLogger(__name__)
|
50
|
+
|
51
|
+
|
52
|
+
class BaseLlmFlow(ABC):
|
53
|
+
"""A basic flow that calls the LLM in a loop until a final response is generated.
|
54
|
+
|
55
|
+
This flow ends when it transfer to another agent.
|
56
|
+
"""
|
57
|
+
|
58
|
+
def __init__(self):
|
59
|
+
self.request_processors: list[BaseLlmRequestProcessor] = []
|
60
|
+
self.response_processors: list[BaseLlmResponseProcessor] = []
|
61
|
+
|
62
|
+
async def run_live(
|
63
|
+
self,
|
64
|
+
invocation_context: InvocationContext,
|
65
|
+
) -> AsyncGenerator[Event, None]:
|
66
|
+
"""Runs the flow using live api."""
|
67
|
+
llm_request = LlmRequest()
|
68
|
+
event_id = Event.new_id()
|
69
|
+
|
70
|
+
# Preprocess before calling the LLM.
|
71
|
+
async for event in self._preprocess_async(invocation_context, llm_request):
|
72
|
+
yield event
|
73
|
+
if invocation_context.end_invocation:
|
74
|
+
return
|
75
|
+
|
76
|
+
llm = self.__get_llm(invocation_context)
|
77
|
+
logger.info(
|
78
|
+
'Establishing live connection for agent: %s with llm request: %s',
|
79
|
+
invocation_context.agent.name,
|
80
|
+
llm_request,
|
81
|
+
)
|
82
|
+
async with llm.connect(llm_request) as llm_connection:
|
83
|
+
if llm_request.contents:
|
84
|
+
# Sends the conversation history to the model.
|
85
|
+
with tracer.start_as_current_span('send_data'):
|
86
|
+
|
87
|
+
if invocation_context.transcription_cache:
|
88
|
+
from . import audio_transcriber
|
89
|
+
|
90
|
+
audio_transcriber = audio_transcriber.AudioTranscriber()
|
91
|
+
contents = audio_transcriber.transcribe_file(invocation_context)
|
92
|
+
logger.debug('Sending history to model: %s', contents)
|
93
|
+
await llm_connection.send_history(contents)
|
94
|
+
invocation_context.transcription_cache = None
|
95
|
+
trace_send_data(invocation_context, event_id, contents)
|
96
|
+
else:
|
97
|
+
await llm_connection.send_history(llm_request.contents)
|
98
|
+
trace_send_data(invocation_context, event_id, llm_request.contents)
|
99
|
+
|
100
|
+
send_task = asyncio.create_task(
|
101
|
+
self._send_to_model(llm_connection, invocation_context)
|
102
|
+
)
|
103
|
+
|
104
|
+
try:
|
105
|
+
async for event in self._receive_from_model(
|
106
|
+
llm_connection,
|
107
|
+
event_id,
|
108
|
+
invocation_context,
|
109
|
+
llm_request,
|
110
|
+
):
|
111
|
+
# Empty event means the queue is closed.
|
112
|
+
if not event:
|
113
|
+
break
|
114
|
+
logger.debug('Receive new event: %s', event)
|
115
|
+
yield event
|
116
|
+
# send back the function response
|
117
|
+
if event.get_function_responses():
|
118
|
+
logger.debug('Sending back last function resonse event: %s', event)
|
119
|
+
invocation_context.live_request_queue.send_content(event.content)
|
120
|
+
if (
|
121
|
+
event.content
|
122
|
+
and event.content.parts
|
123
|
+
and event.content.parts[0].function_response
|
124
|
+
and event.content.parts[0].function_response.name
|
125
|
+
== 'transfer_to_agent'
|
126
|
+
):
|
127
|
+
await asyncio.sleep(1)
|
128
|
+
# cancel the tasks that belongs to the closed connection.
|
129
|
+
send_task.cancel()
|
130
|
+
await llm_connection.close()
|
131
|
+
finally:
|
132
|
+
# Clean up
|
133
|
+
if not send_task.done():
|
134
|
+
send_task.cancel()
|
135
|
+
try:
|
136
|
+
await send_task
|
137
|
+
except asyncio.CancelledError:
|
138
|
+
pass
|
139
|
+
|
140
|
+
async def _send_to_model(
|
141
|
+
self,
|
142
|
+
llm_connection: BaseLlmConnection,
|
143
|
+
invocation_context: InvocationContext,
|
144
|
+
):
|
145
|
+
"""Sends data to model."""
|
146
|
+
while True:
|
147
|
+
live_request_queue = invocation_context.live_request_queue
|
148
|
+
try:
|
149
|
+
# Streamlit's execution model doesn't preemptively yield to the event
|
150
|
+
# loop. Therefore, we must explicitly introduce timeouts to allow the
|
151
|
+
# event loop to process events.
|
152
|
+
# TODO: revert back(remove timeout) once we move off streamlit.
|
153
|
+
live_request = await asyncio.wait_for(
|
154
|
+
live_request_queue.get(), timeout=0.25
|
155
|
+
)
|
156
|
+
# duplicate the live_request to all the active streams
|
157
|
+
logger.debug(
|
158
|
+
'Sending live request %s to active streams: %s',
|
159
|
+
live_request,
|
160
|
+
invocation_context.active_streaming_tools,
|
161
|
+
)
|
162
|
+
if invocation_context.active_streaming_tools:
|
163
|
+
for active_streaming_tool in (
|
164
|
+
invocation_context.active_streaming_tools
|
165
|
+
).values():
|
166
|
+
if active_streaming_tool.stream:
|
167
|
+
active_streaming_tool.stream.send(live_request)
|
168
|
+
await asyncio.sleep(0)
|
169
|
+
except asyncio.TimeoutError:
|
170
|
+
continue
|
171
|
+
if live_request.close:
|
172
|
+
await llm_connection.close()
|
173
|
+
return
|
174
|
+
if live_request.blob:
|
175
|
+
# Cache audio data here for transcription
|
176
|
+
if not invocation_context.transcription_cache:
|
177
|
+
invocation_context.transcription_cache = []
|
178
|
+
invocation_context.transcription_cache.append(
|
179
|
+
TranscriptionEntry(role='user', data=live_request.blob)
|
180
|
+
)
|
181
|
+
await llm_connection.send_realtime(live_request.blob)
|
182
|
+
if live_request.content:
|
183
|
+
await llm_connection.send_content(live_request.content)
|
184
|
+
|
185
|
+
async def _receive_from_model(
|
186
|
+
self,
|
187
|
+
llm_connection: BaseLlmConnection,
|
188
|
+
event_id: str,
|
189
|
+
invocation_context: InvocationContext,
|
190
|
+
llm_request: LlmRequest,
|
191
|
+
) -> AsyncGenerator[Event, None]:
|
192
|
+
"""Receive data from model and process events using BaseLlmConnection."""
|
193
|
+
assert invocation_context.live_request_queue
|
194
|
+
try:
|
195
|
+
while True:
|
196
|
+
async for llm_response in llm_connection.receive():
|
197
|
+
model_response_event = Event(
|
198
|
+
id=Event.new_id(),
|
199
|
+
invocation_id=invocation_context.invocation_id,
|
200
|
+
author=invocation_context.agent.name,
|
201
|
+
)
|
202
|
+
async for event in self._postprocess_live(
|
203
|
+
invocation_context,
|
204
|
+
llm_request,
|
205
|
+
llm_response,
|
206
|
+
model_response_event,
|
207
|
+
):
|
208
|
+
if (
|
209
|
+
event.content
|
210
|
+
and event.content.parts
|
211
|
+
and event.content.parts[0].text
|
212
|
+
and not event.partial
|
213
|
+
):
|
214
|
+
if not invocation_context.transcription_cache:
|
215
|
+
invocation_context.transcription_cache = []
|
216
|
+
invocation_context.transcription_cache.append(
|
217
|
+
TranscriptionEntry(role='model', data=event.content)
|
218
|
+
)
|
219
|
+
yield event
|
220
|
+
# Give opportunity for other tasks to run.
|
221
|
+
await asyncio.sleep(0)
|
222
|
+
except ConnectionClosedOK:
|
223
|
+
pass
|
224
|
+
|
225
|
+
async def run_async(
|
226
|
+
self, invocation_context: InvocationContext
|
227
|
+
) -> AsyncGenerator[Event, None]:
|
228
|
+
"""Runs the flow."""
|
229
|
+
while True:
|
230
|
+
last_event = None
|
231
|
+
async for event in self._run_one_step_async(invocation_context):
|
232
|
+
last_event = event
|
233
|
+
yield event
|
234
|
+
if not last_event or last_event.is_final_response():
|
235
|
+
break
|
236
|
+
|
237
|
+
async def _run_one_step_async(
|
238
|
+
self,
|
239
|
+
invocation_context: InvocationContext,
|
240
|
+
) -> AsyncGenerator[Event, None]:
|
241
|
+
"""One step means one LLM call."""
|
242
|
+
llm_request = LlmRequest()
|
243
|
+
|
244
|
+
# Preprocess before calling the LLM.
|
245
|
+
async for event in self._preprocess_async(invocation_context, llm_request):
|
246
|
+
yield event
|
247
|
+
if invocation_context.end_invocation:
|
248
|
+
return
|
249
|
+
|
250
|
+
# Calls the LLM.
|
251
|
+
model_response_event = Event(
|
252
|
+
id=Event.new_id(),
|
253
|
+
invocation_id=invocation_context.invocation_id,
|
254
|
+
author=invocation_context.agent.name,
|
255
|
+
branch=invocation_context.branch,
|
256
|
+
)
|
257
|
+
async for llm_response in self._call_llm_async(
|
258
|
+
invocation_context, llm_request, model_response_event
|
259
|
+
):
|
260
|
+
# Postprocess after calling the LLM.
|
261
|
+
async for event in self._postprocess_async(
|
262
|
+
invocation_context, llm_request, llm_response, model_response_event
|
263
|
+
):
|
264
|
+
yield event
|
265
|
+
|
266
|
+
async def _preprocess_async(
|
267
|
+
self, invocation_context: InvocationContext, llm_request: LlmRequest
|
268
|
+
) -> AsyncGenerator[Event, None]:
|
269
|
+
from ...agents.llm_agent import LlmAgent
|
270
|
+
|
271
|
+
agent = invocation_context.agent
|
272
|
+
if not isinstance(agent, LlmAgent):
|
273
|
+
return
|
274
|
+
|
275
|
+
# Runs processors.
|
276
|
+
for processor in self.request_processors:
|
277
|
+
async for event in processor.run_async(invocation_context, llm_request):
|
278
|
+
yield event
|
279
|
+
|
280
|
+
# Run processors for tools.
|
281
|
+
for tool in agent.canonical_tools:
|
282
|
+
tool_context = ToolContext(invocation_context)
|
283
|
+
await tool.process_llm_request(
|
284
|
+
tool_context=tool_context, llm_request=llm_request
|
285
|
+
)
|
286
|
+
|
287
|
+
async def _postprocess_async(
|
288
|
+
self,
|
289
|
+
invocation_context: InvocationContext,
|
290
|
+
llm_request: LlmRequest,
|
291
|
+
llm_response: LlmResponse,
|
292
|
+
model_response_event: Event,
|
293
|
+
) -> AsyncGenerator[Event, None]:
|
294
|
+
"""Postprocess after calling the LLM.
|
295
|
+
|
296
|
+
Args:
|
297
|
+
invocation_context: The invocation context.
|
298
|
+
llm_request: The original LLM request.
|
299
|
+
llm_response: The LLM response from the LLM call.
|
300
|
+
model_response_event: A mutable event for the LLM response.
|
301
|
+
|
302
|
+
Yields:
|
303
|
+
A generator of events.
|
304
|
+
"""
|
305
|
+
|
306
|
+
# Runs processors.
|
307
|
+
async for event in self._postprocess_run_processors_async(
|
308
|
+
invocation_context, llm_response
|
309
|
+
):
|
310
|
+
yield event
|
311
|
+
|
312
|
+
# Skip the model response event if there is no content and no error code.
|
313
|
+
# This is needed for the code executor to trigger another loop.
|
314
|
+
if (
|
315
|
+
not llm_response.content
|
316
|
+
and not llm_response.error_code
|
317
|
+
and not llm_response.interrupted
|
318
|
+
):
|
319
|
+
return
|
320
|
+
|
321
|
+
# Builds the event.
|
322
|
+
model_response_event = self._finalize_model_response_event(
|
323
|
+
llm_request, llm_response, model_response_event
|
324
|
+
)
|
325
|
+
yield model_response_event
|
326
|
+
|
327
|
+
# Handles function calls.
|
328
|
+
if model_response_event.get_function_calls():
|
329
|
+
async for event in self._postprocess_handle_function_calls_async(
|
330
|
+
invocation_context, model_response_event, llm_request
|
331
|
+
):
|
332
|
+
yield event
|
333
|
+
|
334
|
+
async def _postprocess_live(
|
335
|
+
self,
|
336
|
+
invocation_context: InvocationContext,
|
337
|
+
llm_request: LlmRequest,
|
338
|
+
llm_response: LlmResponse,
|
339
|
+
model_response_event: Event,
|
340
|
+
) -> AsyncGenerator[Event, None]:
|
341
|
+
"""Postprocess after calling the LLM asynchronously.
|
342
|
+
|
343
|
+
Args:
|
344
|
+
invocation_context: The invocation context.
|
345
|
+
llm_request: The original LLM request.
|
346
|
+
llm_response: The LLM response from the LLM call.
|
347
|
+
model_response_event: A mutable event for the LLM response.
|
348
|
+
|
349
|
+
Yields:
|
350
|
+
A generator of events.
|
351
|
+
"""
|
352
|
+
|
353
|
+
# Runs processors.
|
354
|
+
async for event in self._postprocess_run_processors_async(
|
355
|
+
invocation_context, llm_response
|
356
|
+
):
|
357
|
+
yield event
|
358
|
+
|
359
|
+
# Skip the model response event if there is no content and no error code.
|
360
|
+
# This is needed for the code executor to trigger another loop.
|
361
|
+
# But don't skip control events like turn_complete.
|
362
|
+
if (
|
363
|
+
not llm_response.content
|
364
|
+
and not llm_response.error_code
|
365
|
+
and not llm_response.interrupted
|
366
|
+
and not llm_response.turn_complete
|
367
|
+
):
|
368
|
+
return
|
369
|
+
|
370
|
+
# Builds the event.
|
371
|
+
model_response_event = self._finalize_model_response_event(
|
372
|
+
llm_request, llm_response, model_response_event
|
373
|
+
)
|
374
|
+
yield model_response_event
|
375
|
+
|
376
|
+
# Handles function calls.
|
377
|
+
if model_response_event.get_function_calls():
|
378
|
+
function_response_event = await functions.handle_function_calls_live(
|
379
|
+
invocation_context, model_response_event, llm_request.tools_dict
|
380
|
+
)
|
381
|
+
yield function_response_event
|
382
|
+
|
383
|
+
transfer_to_agent = function_response_event.actions.transfer_to_agent
|
384
|
+
if transfer_to_agent:
|
385
|
+
agent_to_run = self._get_agent_to_run(
|
386
|
+
invocation_context, transfer_to_agent
|
387
|
+
)
|
388
|
+
async for item in agent_to_run.run_live(invocation_context):
|
389
|
+
yield item
|
390
|
+
|
391
|
+
async def _postprocess_run_processors_async(
|
392
|
+
self, invocation_context: InvocationContext, llm_response: LlmResponse
|
393
|
+
) -> AsyncGenerator[Event, None]:
|
394
|
+
for processor in self.response_processors:
|
395
|
+
async for event in processor.run_async(invocation_context, llm_response):
|
396
|
+
yield event
|
397
|
+
|
398
|
+
async def _postprocess_handle_function_calls_async(
|
399
|
+
self,
|
400
|
+
invocation_context: InvocationContext,
|
401
|
+
function_call_event: Event,
|
402
|
+
llm_request: LlmRequest,
|
403
|
+
) -> AsyncGenerator[Event, None]:
|
404
|
+
if function_response_event := await functions.handle_function_calls_async(
|
405
|
+
invocation_context, function_call_event, llm_request.tools_dict
|
406
|
+
):
|
407
|
+
auth_event = functions.generate_auth_event(
|
408
|
+
invocation_context, function_response_event
|
409
|
+
)
|
410
|
+
if auth_event:
|
411
|
+
yield auth_event
|
412
|
+
|
413
|
+
yield function_response_event
|
414
|
+
transfer_to_agent = function_response_event.actions.transfer_to_agent
|
415
|
+
if transfer_to_agent:
|
416
|
+
agent_to_run = self._get_agent_to_run(
|
417
|
+
invocation_context, transfer_to_agent
|
418
|
+
)
|
419
|
+
async for event in agent_to_run.run_async(invocation_context):
|
420
|
+
yield event
|
421
|
+
|
422
|
+
def _get_agent_to_run(
|
423
|
+
self, invocation_context: InvocationContext, transfer_to_agent
|
424
|
+
) -> BaseAgent:
|
425
|
+
root_agent = invocation_context.agent.root_agent
|
426
|
+
agent_to_run = root_agent.find_agent(transfer_to_agent)
|
427
|
+
if not agent_to_run:
|
428
|
+
raise ValueError(
|
429
|
+
f'Agent {transfer_to_agent} not found in the agent tree.'
|
430
|
+
)
|
431
|
+
return agent_to_run
|
432
|
+
|
433
|
+
async def _call_llm_async(
|
434
|
+
self,
|
435
|
+
invocation_context: InvocationContext,
|
436
|
+
llm_request: LlmRequest,
|
437
|
+
model_response_event: Event,
|
438
|
+
) -> AsyncGenerator[LlmResponse, None]:
|
439
|
+
# Runs before_model_callback if it exists.
|
440
|
+
if response := self._handle_before_model_callback(
|
441
|
+
invocation_context, llm_request, model_response_event
|
442
|
+
):
|
443
|
+
yield response
|
444
|
+
return
|
445
|
+
|
446
|
+
# Calls the LLM.
|
447
|
+
llm = self.__get_llm(invocation_context)
|
448
|
+
with tracer.start_as_current_span('call_llm'):
|
449
|
+
if invocation_context.run_config.support_cfc:
|
450
|
+
invocation_context.live_request_queue = LiveRequestQueue()
|
451
|
+
async for llm_response in self.run_live(invocation_context):
|
452
|
+
# Runs after_model_callback if it exists.
|
453
|
+
if altered_llm_response := self._handle_after_model_callback(
|
454
|
+
invocation_context, llm_response, model_response_event
|
455
|
+
):
|
456
|
+
llm_response = altered_llm_response
|
457
|
+
# only yield partial response in SSE streaming mode
|
458
|
+
if (
|
459
|
+
invocation_context.run_config.streaming_mode == StreamingMode.SSE
|
460
|
+
or not llm_response.partial
|
461
|
+
):
|
462
|
+
yield llm_response
|
463
|
+
if llm_response.turn_complete:
|
464
|
+
invocation_context.live_request_queue.close()
|
465
|
+
else:
|
466
|
+
# Check if we can make this llm call or not. If the current call pushes
|
467
|
+
# the counter beyond the max set value, then the execution is stopped
|
468
|
+
# right here, and exception is thrown.
|
469
|
+
invocation_context.increment_llm_call_count()
|
470
|
+
async for llm_response in llm.generate_content_async(
|
471
|
+
llm_request,
|
472
|
+
stream=invocation_context.run_config.streaming_mode
|
473
|
+
== StreamingMode.SSE,
|
474
|
+
):
|
475
|
+
trace_call_llm(
|
476
|
+
invocation_context,
|
477
|
+
model_response_event.id,
|
478
|
+
llm_request,
|
479
|
+
llm_response,
|
480
|
+
)
|
481
|
+
# Runs after_model_callback if it exists.
|
482
|
+
if altered_llm_response := self._handle_after_model_callback(
|
483
|
+
invocation_context, llm_response, model_response_event
|
484
|
+
):
|
485
|
+
llm_response = altered_llm_response
|
486
|
+
|
487
|
+
yield llm_response
|
488
|
+
|
489
|
+
def _handle_before_model_callback(
|
490
|
+
self,
|
491
|
+
invocation_context: InvocationContext,
|
492
|
+
llm_request: LlmRequest,
|
493
|
+
model_response_event: Event,
|
494
|
+
) -> Optional[LlmResponse]:
|
495
|
+
from ...agents.llm_agent import LlmAgent
|
496
|
+
|
497
|
+
agent = invocation_context.agent
|
498
|
+
if not isinstance(agent, LlmAgent):
|
499
|
+
return
|
500
|
+
|
501
|
+
if not agent.before_model_callback:
|
502
|
+
return
|
503
|
+
|
504
|
+
callback_context = CallbackContext(
|
505
|
+
invocation_context, event_actions=model_response_event.actions
|
506
|
+
)
|
507
|
+
return agent.before_model_callback(
|
508
|
+
callback_context=callback_context, llm_request=llm_request
|
509
|
+
)
|
510
|
+
|
511
|
+
def _handle_after_model_callback(
|
512
|
+
self,
|
513
|
+
invocation_context: InvocationContext,
|
514
|
+
llm_response: LlmResponse,
|
515
|
+
model_response_event: Event,
|
516
|
+
) -> Optional[LlmResponse]:
|
517
|
+
from ...agents.llm_agent import LlmAgent
|
518
|
+
|
519
|
+
agent = invocation_context.agent
|
520
|
+
if not isinstance(agent, LlmAgent):
|
521
|
+
return
|
522
|
+
|
523
|
+
if not agent.after_model_callback:
|
524
|
+
return
|
525
|
+
|
526
|
+
callback_context = CallbackContext(
|
527
|
+
invocation_context, event_actions=model_response_event.actions
|
528
|
+
)
|
529
|
+
return agent.after_model_callback(
|
530
|
+
callback_context=callback_context, llm_response=llm_response
|
531
|
+
)
|
532
|
+
|
533
|
+
def _finalize_model_response_event(
|
534
|
+
self,
|
535
|
+
llm_request: LlmRequest,
|
536
|
+
llm_response: LlmResponse,
|
537
|
+
model_response_event: Event,
|
538
|
+
) -> Event:
|
539
|
+
model_response_event = Event.model_validate({
|
540
|
+
**model_response_event.model_dump(exclude_none=True),
|
541
|
+
**llm_response.model_dump(exclude_none=True),
|
542
|
+
})
|
543
|
+
|
544
|
+
if model_response_event.content:
|
545
|
+
function_calls = model_response_event.get_function_calls()
|
546
|
+
if function_calls:
|
547
|
+
functions.populate_client_function_call_id(model_response_event)
|
548
|
+
model_response_event.long_running_tool_ids = (
|
549
|
+
functions.get_long_running_function_calls(
|
550
|
+
function_calls, llm_request.tools_dict
|
551
|
+
)
|
552
|
+
)
|
553
|
+
|
554
|
+
return model_response_event
|
555
|
+
|
556
|
+
def __get_llm(self, invocation_context: InvocationContext) -> BaseLlm:
|
557
|
+
from ...agents.llm_agent import LlmAgent
|
558
|
+
|
559
|
+
return cast(LlmAgent, invocation_context.agent).canonical_model
|
@@ -0,0 +1,72 @@
|
|
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
|
+
"""Handles basic information to build the LLM request."""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
from typing import AsyncGenerator
|
20
|
+
from typing import Generator
|
21
|
+
|
22
|
+
from google.genai import types
|
23
|
+
from typing_extensions import override
|
24
|
+
|
25
|
+
from ...agents.invocation_context import InvocationContext
|
26
|
+
from ...events.event import Event
|
27
|
+
from ...models.llm_request import LlmRequest
|
28
|
+
from ._base_llm_processor import BaseLlmRequestProcessor
|
29
|
+
|
30
|
+
|
31
|
+
class _BasicLlmRequestProcessor(BaseLlmRequestProcessor):
|
32
|
+
|
33
|
+
@override
|
34
|
+
async def run_async(
|
35
|
+
self, invocation_context: InvocationContext, llm_request: LlmRequest
|
36
|
+
) -> AsyncGenerator[Event, None]:
|
37
|
+
from ...agents.llm_agent import LlmAgent
|
38
|
+
|
39
|
+
agent = invocation_context.agent
|
40
|
+
if not isinstance(agent, LlmAgent):
|
41
|
+
return
|
42
|
+
|
43
|
+
llm_request.model = (
|
44
|
+
agent.canonical_model
|
45
|
+
if isinstance(agent.canonical_model, str)
|
46
|
+
else agent.canonical_model.model
|
47
|
+
)
|
48
|
+
llm_request.config = (
|
49
|
+
agent.generate_content_config.model_copy(deep=True)
|
50
|
+
if agent.generate_content_config
|
51
|
+
else types.GenerateContentConfig()
|
52
|
+
)
|
53
|
+
if agent.output_schema:
|
54
|
+
llm_request.set_output_schema(agent.output_schema)
|
55
|
+
|
56
|
+
llm_request.live_connect_config.response_modalities = (
|
57
|
+
invocation_context.run_config.response_modalities
|
58
|
+
)
|
59
|
+
llm_request.live_connect_config.speech_config = (
|
60
|
+
invocation_context.run_config.speech_config
|
61
|
+
)
|
62
|
+
llm_request.live_connect_config.output_audio_transcription = (
|
63
|
+
invocation_context.run_config.output_audio_transcription
|
64
|
+
)
|
65
|
+
|
66
|
+
# TODO: handle tool append here, instead of in BaseTool.process_llm_request.
|
67
|
+
|
68
|
+
return
|
69
|
+
yield # Generator requires yield statement in function body.
|
70
|
+
|
71
|
+
|
72
|
+
request_processor = _BasicLlmRequestProcessor()
|