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,458 @@
|
|
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 Code Execution related logic."""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
import base64
|
20
|
+
import copy
|
21
|
+
import dataclasses
|
22
|
+
import os
|
23
|
+
import re
|
24
|
+
from typing import AsyncGenerator
|
25
|
+
from typing import Generator
|
26
|
+
from typing import Optional
|
27
|
+
from typing import TYPE_CHECKING
|
28
|
+
|
29
|
+
from google.genai import types
|
30
|
+
from typing_extensions import override
|
31
|
+
|
32
|
+
from ...agents.invocation_context import InvocationContext
|
33
|
+
from ...code_executors.base_code_executor import BaseCodeExecutor
|
34
|
+
from ...code_executors.code_execution_utils import CodeExecutionInput
|
35
|
+
from ...code_executors.code_execution_utils import CodeExecutionResult
|
36
|
+
from ...code_executors.code_execution_utils import CodeExecutionUtils
|
37
|
+
from ...code_executors.code_execution_utils import File
|
38
|
+
from ...code_executors.code_executor_context import CodeExecutorContext
|
39
|
+
from ...events.event import Event
|
40
|
+
from ...events.event_actions import EventActions
|
41
|
+
from ...models.llm_response import LlmResponse
|
42
|
+
from ._base_llm_processor import BaseLlmRequestProcessor
|
43
|
+
from ._base_llm_processor import BaseLlmResponseProcessor
|
44
|
+
|
45
|
+
if TYPE_CHECKING:
|
46
|
+
from ...models.llm_request import LlmRequest
|
47
|
+
|
48
|
+
|
49
|
+
@dataclasses.dataclass
|
50
|
+
class DataFileUtil:
|
51
|
+
"""A structure that contains a data file name and its content."""
|
52
|
+
|
53
|
+
extension: str
|
54
|
+
"""
|
55
|
+
The file extension (e.g., ".csv").
|
56
|
+
"""
|
57
|
+
|
58
|
+
loader_code_template: str
|
59
|
+
"""
|
60
|
+
The code template to load the data file.
|
61
|
+
"""
|
62
|
+
|
63
|
+
|
64
|
+
_DATA_FILE_UTIL_MAP = {
|
65
|
+
'text/csv': DataFileUtil(
|
66
|
+
extension='.csv',
|
67
|
+
loader_code_template="pd.read_csv('{filename}')",
|
68
|
+
),
|
69
|
+
}
|
70
|
+
|
71
|
+
_DATA_FILE_HELPER_LIB = '''
|
72
|
+
import pandas as pd
|
73
|
+
|
74
|
+
def explore_df(df: pd.DataFrame) -> None:
|
75
|
+
"""Prints some information about a pandas DataFrame."""
|
76
|
+
|
77
|
+
with pd.option_context(
|
78
|
+
'display.max_columns', None, 'display.expand_frame_repr', False
|
79
|
+
):
|
80
|
+
# Print the column names to never encounter KeyError when selecting one.
|
81
|
+
df_dtypes = df.dtypes
|
82
|
+
|
83
|
+
# Obtain information about data types and missing values.
|
84
|
+
df_nulls = (len(df) - df.isnull().sum()).apply(
|
85
|
+
lambda x: f'{x} / {df.shape[0]} non-null'
|
86
|
+
)
|
87
|
+
|
88
|
+
# Explore unique total values in columns using `.unique()`.
|
89
|
+
df_unique_count = df.apply(lambda x: len(x.unique()))
|
90
|
+
|
91
|
+
# Explore unique values in columns using `.unique()`.
|
92
|
+
df_unique = df.apply(lambda x: crop(str(list(x.unique()))))
|
93
|
+
|
94
|
+
df_info = pd.concat(
|
95
|
+
(
|
96
|
+
df_dtypes.rename('Dtype'),
|
97
|
+
df_nulls.rename('Non-Null Count'),
|
98
|
+
df_unique_count.rename('Unique Values Count'),
|
99
|
+
df_unique.rename('Unique Values'),
|
100
|
+
),
|
101
|
+
axis=1,
|
102
|
+
)
|
103
|
+
df_info.index.name = 'Columns'
|
104
|
+
print(f"""Total rows: {df.shape[0]}
|
105
|
+
Total columns: {df.shape[1]}
|
106
|
+
|
107
|
+
{df_info}""")
|
108
|
+
'''
|
109
|
+
|
110
|
+
|
111
|
+
class _CodeExecutionRequestProcessor(BaseLlmRequestProcessor):
|
112
|
+
"""Processes code execution requests."""
|
113
|
+
|
114
|
+
@override
|
115
|
+
async def run_async(
|
116
|
+
self, invocation_context: InvocationContext, llm_request: LlmRequest
|
117
|
+
) -> AsyncGenerator[Event, None]:
|
118
|
+
from ...agents.llm_agent import LlmAgent
|
119
|
+
|
120
|
+
if not isinstance(invocation_context.agent, LlmAgent):
|
121
|
+
return
|
122
|
+
if not invocation_context.agent.code_executor:
|
123
|
+
return
|
124
|
+
|
125
|
+
for event in _run_pre_processor(invocation_context, llm_request):
|
126
|
+
yield event
|
127
|
+
|
128
|
+
# Convert the code execution parts to text parts.
|
129
|
+
if not isinstance(invocation_context.agent.code_executor, BaseCodeExecutor):
|
130
|
+
return
|
131
|
+
for content in llm_request.contents:
|
132
|
+
CodeExecutionUtils.convert_code_execution_parts(
|
133
|
+
content,
|
134
|
+
invocation_context.agent.code_executor.code_block_delimiters[0]
|
135
|
+
if invocation_context.agent.code_executor.code_block_delimiters
|
136
|
+
else ('', ''),
|
137
|
+
invocation_context.agent.code_executor.execution_result_delimiters,
|
138
|
+
)
|
139
|
+
|
140
|
+
|
141
|
+
request_processor = _CodeExecutionRequestProcessor()
|
142
|
+
|
143
|
+
|
144
|
+
class _CodeExecutionResponseProcessor(BaseLlmResponseProcessor):
|
145
|
+
"""Processes code execution responses."""
|
146
|
+
|
147
|
+
@override
|
148
|
+
async def run_async(
|
149
|
+
self, invocation_context: InvocationContext, llm_response: LlmResponse
|
150
|
+
) -> AsyncGenerator[Event, None]:
|
151
|
+
# Skip if the response is partial (streaming).
|
152
|
+
if llm_response.partial:
|
153
|
+
return
|
154
|
+
|
155
|
+
for event in _run_post_processor(invocation_context, llm_response):
|
156
|
+
yield event
|
157
|
+
|
158
|
+
|
159
|
+
response_processor = _CodeExecutionResponseProcessor()
|
160
|
+
|
161
|
+
|
162
|
+
def _run_pre_processor(
|
163
|
+
invocation_context: InvocationContext,
|
164
|
+
llm_request: LlmRequest,
|
165
|
+
) -> Generator[Event, None, None]:
|
166
|
+
"""Pre-process the user message by adding the user message to the Colab notebook."""
|
167
|
+
from ...agents.llm_agent import LlmAgent
|
168
|
+
|
169
|
+
if not isinstance(invocation_context.agent, LlmAgent):
|
170
|
+
return
|
171
|
+
|
172
|
+
agent = invocation_context.agent
|
173
|
+
code_executor = agent.code_executor
|
174
|
+
|
175
|
+
if not code_executor or not isinstance(code_executor, BaseCodeExecutor):
|
176
|
+
return
|
177
|
+
if not code_executor.optimize_data_file:
|
178
|
+
return
|
179
|
+
|
180
|
+
code_executor_context = CodeExecutorContext(invocation_context.session.state)
|
181
|
+
|
182
|
+
# Skip if the error count exceeds the max retry attempts.
|
183
|
+
if (
|
184
|
+
code_executor_context.get_error_count(invocation_context.invocation_id)
|
185
|
+
>= code_executor.error_retry_attempts
|
186
|
+
):
|
187
|
+
return
|
188
|
+
|
189
|
+
# [Step 1] Extract data files from the session_history and store them in
|
190
|
+
# memory. Meanwhile, mutate the inline data file to text part in session
|
191
|
+
# history from all turns.
|
192
|
+
all_input_files = _extrac_and_replace_inline_files(
|
193
|
+
code_executor_context, llm_request
|
194
|
+
)
|
195
|
+
|
196
|
+
# [Step 2] Run Explore_Df code on the data files from the current turn. We
|
197
|
+
# only need to explore the new data files because the previous data files
|
198
|
+
# should already be explored and cached in the code execution runtime.
|
199
|
+
processed_file_names = set(code_executor_context.get_processed_file_names())
|
200
|
+
files_to_process = [
|
201
|
+
f for f in all_input_files if f.name not in processed_file_names
|
202
|
+
]
|
203
|
+
for file in files_to_process:
|
204
|
+
code_str = _get_data_file_preprocessing_code(file)
|
205
|
+
# Skip for unsupported file or executor types.
|
206
|
+
if not code_str:
|
207
|
+
return
|
208
|
+
|
209
|
+
# Emit the code to execute, and add it to the LLM request.
|
210
|
+
code_content = types.Content(
|
211
|
+
role='model',
|
212
|
+
parts=[
|
213
|
+
types.Part(text=f'Processing input file: `{file.name}`'),
|
214
|
+
CodeExecutionUtils.build_executable_code_part(code_str),
|
215
|
+
],
|
216
|
+
)
|
217
|
+
llm_request.contents.append(copy.deepcopy(code_content))
|
218
|
+
yield Event(
|
219
|
+
invocation_id=invocation_context.invocation_id,
|
220
|
+
author=agent.name,
|
221
|
+
branch=invocation_context.branch,
|
222
|
+
content=code_content,
|
223
|
+
)
|
224
|
+
|
225
|
+
code_execution_result = code_executor.execute_code(
|
226
|
+
invocation_context,
|
227
|
+
CodeExecutionInput(
|
228
|
+
code=code_str,
|
229
|
+
input_files=[file],
|
230
|
+
execution_id=_get_or_set_execution_id(
|
231
|
+
invocation_context, code_executor_context
|
232
|
+
),
|
233
|
+
),
|
234
|
+
)
|
235
|
+
# Update the processing results to code executor context.
|
236
|
+
code_executor_context.update_code_execution_result(
|
237
|
+
invocation_context.invocation_id,
|
238
|
+
code_str,
|
239
|
+
code_execution_result.stdout,
|
240
|
+
code_execution_result.stderr,
|
241
|
+
)
|
242
|
+
code_executor_context.add_processed_file_names([file.name])
|
243
|
+
|
244
|
+
# Emit the execution result, and add it to the LLM request.
|
245
|
+
execution_result_event = _post_process_code_execution_result(
|
246
|
+
invocation_context, code_executor_context, code_execution_result
|
247
|
+
)
|
248
|
+
yield execution_result_event
|
249
|
+
llm_request.contents.append(copy.deepcopy(execution_result_event.content))
|
250
|
+
|
251
|
+
|
252
|
+
def _run_post_processor(
|
253
|
+
invocation_context: InvocationContext,
|
254
|
+
llm_response,
|
255
|
+
) -> Generator[Event, None, None]:
|
256
|
+
"""Post-process the model response by extracting and executing the first code block."""
|
257
|
+
agent = invocation_context.agent
|
258
|
+
code_executor = agent.code_executor
|
259
|
+
|
260
|
+
if not code_executor or not isinstance(code_executor, BaseCodeExecutor):
|
261
|
+
return
|
262
|
+
if not llm_response or not llm_response.content:
|
263
|
+
return
|
264
|
+
|
265
|
+
code_executor_context = CodeExecutorContext(invocation_context.session.state)
|
266
|
+
# Skip if the error count exceeds the max retry attempts.
|
267
|
+
if (
|
268
|
+
code_executor_context.get_error_count(invocation_context.invocation_id)
|
269
|
+
>= code_executor.error_retry_attempts
|
270
|
+
):
|
271
|
+
return
|
272
|
+
|
273
|
+
# [Step 1] Extract code from the model predict response and truncate the
|
274
|
+
# content to the part with the first code block.
|
275
|
+
response_content = llm_response.content
|
276
|
+
code_str = CodeExecutionUtils.extract_code_and_truncate_content(
|
277
|
+
response_content, code_executor.code_block_delimiters
|
278
|
+
)
|
279
|
+
# Terminal state: no code to execute.
|
280
|
+
if not code_str:
|
281
|
+
return
|
282
|
+
|
283
|
+
# [Step 2] Executes the code and emit 2 Events for code and execution result.
|
284
|
+
yield Event(
|
285
|
+
invocation_id=invocation_context.invocation_id,
|
286
|
+
author=agent.name,
|
287
|
+
branch=invocation_context.branch,
|
288
|
+
content=response_content,
|
289
|
+
actions=EventActions(),
|
290
|
+
)
|
291
|
+
|
292
|
+
code_execution_result = code_executor.execute_code(
|
293
|
+
invocation_context,
|
294
|
+
CodeExecutionInput(
|
295
|
+
code=code_str,
|
296
|
+
input_files=code_executor_context.get_input_files(),
|
297
|
+
execution_id=_get_or_set_execution_id(
|
298
|
+
invocation_context, code_executor_context
|
299
|
+
),
|
300
|
+
),
|
301
|
+
)
|
302
|
+
code_executor_context.update_code_execution_result(
|
303
|
+
invocation_context.invocation_id,
|
304
|
+
code_str,
|
305
|
+
code_execution_result.stdout,
|
306
|
+
code_execution_result.stderr,
|
307
|
+
)
|
308
|
+
yield _post_process_code_execution_result(
|
309
|
+
invocation_context, code_executor_context, code_execution_result
|
310
|
+
)
|
311
|
+
|
312
|
+
# [Step 3] Skip processing the original model response
|
313
|
+
# to continue code generation loop.
|
314
|
+
llm_response.content = None
|
315
|
+
|
316
|
+
|
317
|
+
def _extrac_and_replace_inline_files(
|
318
|
+
code_executor_context: CodeExecutorContext,
|
319
|
+
llm_request: LlmRequest,
|
320
|
+
) -> list[File]:
|
321
|
+
"""Extracts and replaces inline files with file names in the LLM request."""
|
322
|
+
all_input_files = code_executor_context.get_input_files()
|
323
|
+
saved_file_names = set(f.name for f in all_input_files)
|
324
|
+
|
325
|
+
# [Step 1] Process input files from LlmRequest and cache them in CodeExecutor.
|
326
|
+
for i in range(len(llm_request.contents)):
|
327
|
+
content = llm_request.contents[i]
|
328
|
+
# Only process the user message.
|
329
|
+
if content.role != 'user' and not content.parts:
|
330
|
+
continue
|
331
|
+
|
332
|
+
for j in range(len(content.parts)):
|
333
|
+
part = content.parts[j]
|
334
|
+
# Skip if the inline data is not supported.
|
335
|
+
if (
|
336
|
+
not part.inline_data
|
337
|
+
or part.inline_data.mime_type not in _DATA_FILE_UTIL_MAP
|
338
|
+
):
|
339
|
+
continue
|
340
|
+
|
341
|
+
# Replace the inline data file with a file name placeholder.
|
342
|
+
mime_type = part.inline_data.mime_type
|
343
|
+
file_name = f'data_{i+1}_{j+1}' + _DATA_FILE_UTIL_MAP[mime_type].extension
|
344
|
+
llm_request.contents[i].parts[j] = types.Part(
|
345
|
+
text='\nAvailable file: `%s`\n' % file_name
|
346
|
+
)
|
347
|
+
|
348
|
+
# Add the inlne data as input file to the code executor context.
|
349
|
+
file = File(
|
350
|
+
name=file_name,
|
351
|
+
content=CodeExecutionUtils.get_encoded_file_content(
|
352
|
+
part.inline_data.data
|
353
|
+
).decode(),
|
354
|
+
mime_type=mime_type,
|
355
|
+
)
|
356
|
+
if file_name not in saved_file_names:
|
357
|
+
code_executor_context.add_input_files([file])
|
358
|
+
all_input_files.append(file)
|
359
|
+
|
360
|
+
return all_input_files
|
361
|
+
|
362
|
+
|
363
|
+
def _get_or_set_execution_id(
|
364
|
+
invocation_context: InvocationContext,
|
365
|
+
code_executor_context: CodeExecutorContext,
|
366
|
+
) -> Optional[str]:
|
367
|
+
"""Returns the ID for stateful code execution or None if not stateful."""
|
368
|
+
if not invocation_context.agent.code_executor.stateful:
|
369
|
+
return None
|
370
|
+
|
371
|
+
execution_id = code_executor_context.get_execution_id()
|
372
|
+
if not execution_id:
|
373
|
+
execution_id = invocation_context.session.id
|
374
|
+
code_executor_context.set_execution_id(execution_id)
|
375
|
+
return execution_id
|
376
|
+
|
377
|
+
|
378
|
+
def _post_process_code_execution_result(
|
379
|
+
invocation_context: InvocationContext,
|
380
|
+
code_executor_context: CodeExecutorContext,
|
381
|
+
code_execution_result: CodeExecutionResult,
|
382
|
+
) -> Event:
|
383
|
+
"""Post-process the code execution result and emit an Event."""
|
384
|
+
if invocation_context.artifact_service is None:
|
385
|
+
raise ValueError('Artifact service is not initialized.')
|
386
|
+
|
387
|
+
result_content = types.Content(
|
388
|
+
role='model',
|
389
|
+
parts=[
|
390
|
+
CodeExecutionUtils.build_code_execution_result_part(
|
391
|
+
code_execution_result
|
392
|
+
),
|
393
|
+
],
|
394
|
+
)
|
395
|
+
event_actions = EventActions(
|
396
|
+
state_delta=code_executor_context.get_state_delta()
|
397
|
+
)
|
398
|
+
|
399
|
+
# Handle code execution error retry.
|
400
|
+
if code_execution_result.stderr:
|
401
|
+
code_executor_context.increment_error_count(
|
402
|
+
invocation_context.invocation_id
|
403
|
+
)
|
404
|
+
else:
|
405
|
+
code_executor_context.reset_error_count(invocation_context.invocation_id)
|
406
|
+
|
407
|
+
# Handle output files.
|
408
|
+
for output_file in code_execution_result.output_files:
|
409
|
+
version = invocation_context.artifact_service.save_artifact(
|
410
|
+
app_name=invocation_context.app_name,
|
411
|
+
user_id=invocation_context.user_id,
|
412
|
+
session_id=invocation_context.session.id,
|
413
|
+
filename=output_file.name,
|
414
|
+
artifact=types.Part.from_bytes(
|
415
|
+
data=base64.b64decode(output_file.content),
|
416
|
+
mime_type=output_file.mime_type,
|
417
|
+
),
|
418
|
+
)
|
419
|
+
event_actions.artifact_delta[output_file.name] = version
|
420
|
+
|
421
|
+
return Event(
|
422
|
+
invocation_id=invocation_context.invocation_id,
|
423
|
+
author=invocation_context.agent.name,
|
424
|
+
branch=invocation_context.branch,
|
425
|
+
content=result_content,
|
426
|
+
actions=event_actions,
|
427
|
+
)
|
428
|
+
|
429
|
+
|
430
|
+
def _get_data_file_preprocessing_code(file: File) -> Optional[str]:
|
431
|
+
"""Returns the code to explore the data file."""
|
432
|
+
|
433
|
+
def _get_normalized_file_name(file_name: str) -> str:
|
434
|
+
var_name, _ = os.path.splitext(file_name)
|
435
|
+
# Replace non-alphanumeric characters with underscores
|
436
|
+
var_name = re.sub(r'[^a-zA-Z0-9_]', '_', var_name)
|
437
|
+
|
438
|
+
# If the filename starts with a digit, prepend an underscore
|
439
|
+
if var_name[0].isdigit():
|
440
|
+
var_name = '_' + var_name
|
441
|
+
return var_name
|
442
|
+
|
443
|
+
if file.mime_type not in _DATA_FILE_UTIL_MAP:
|
444
|
+
return
|
445
|
+
|
446
|
+
var_name = _get_normalized_file_name(file.name)
|
447
|
+
loader_code = _DATA_FILE_UTIL_MAP[file.mime_type].loader_code_template.format(
|
448
|
+
filename=file.name
|
449
|
+
)
|
450
|
+
return f"""
|
451
|
+
{_DATA_FILE_HELPER_LIB}
|
452
|
+
|
453
|
+
# Load the dataframe.
|
454
|
+
{var_name} = {loader_code}
|
455
|
+
|
456
|
+
# Use `explore_df` to guide my analysis.
|
457
|
+
explore_df({var_name})
|
458
|
+
"""
|
@@ -0,0 +1,129 @@
|
|
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 NL planning related logic."""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
from typing import AsyncGenerator
|
20
|
+
from typing import Generator
|
21
|
+
from typing import Optional
|
22
|
+
from typing import TYPE_CHECKING
|
23
|
+
|
24
|
+
from typing_extensions import override
|
25
|
+
|
26
|
+
from ...agents.callback_context import CallbackContext
|
27
|
+
from ...agents.invocation_context import InvocationContext
|
28
|
+
from ...agents.readonly_context import ReadonlyContext
|
29
|
+
from ...events.event import Event
|
30
|
+
from ...planners.plan_re_act_planner import PlanReActPlanner
|
31
|
+
from ._base_llm_processor import BaseLlmRequestProcessor
|
32
|
+
from ._base_llm_processor import BaseLlmResponseProcessor
|
33
|
+
|
34
|
+
if TYPE_CHECKING:
|
35
|
+
from ...models.llm_request import LlmRequest
|
36
|
+
from ...models.llm_response import LlmResponse
|
37
|
+
from ...planners.base_planner import BasePlanner
|
38
|
+
from ...planners.built_in_planner import BuiltInPlanner
|
39
|
+
|
40
|
+
|
41
|
+
class _NlPlanningRequestProcessor(BaseLlmRequestProcessor):
|
42
|
+
"""Processor for NL planning."""
|
43
|
+
|
44
|
+
async def run_async(
|
45
|
+
self, invocation_context: InvocationContext, llm_request: LlmRequest
|
46
|
+
) -> AsyncGenerator[Event, None]:
|
47
|
+
from ...planners.built_in_planner import BuiltInPlanner
|
48
|
+
|
49
|
+
planner = _get_planner(invocation_context)
|
50
|
+
if not planner:
|
51
|
+
return
|
52
|
+
|
53
|
+
if isinstance(planner, BuiltInPlanner):
|
54
|
+
planner.apply_thinking_config(llm_request)
|
55
|
+
|
56
|
+
planning_instruction = planner.build_planning_instruction(
|
57
|
+
ReadonlyContext(invocation_context), llm_request
|
58
|
+
)
|
59
|
+
if planning_instruction:
|
60
|
+
llm_request.append_instructions([planning_instruction])
|
61
|
+
|
62
|
+
_remove_thought_from_request(llm_request)
|
63
|
+
|
64
|
+
# Maintain async generator behavior
|
65
|
+
if False: # Ensures it behaves as a generator
|
66
|
+
yield # This is a no-op but maintains generator structure
|
67
|
+
|
68
|
+
|
69
|
+
request_processor = _NlPlanningRequestProcessor()
|
70
|
+
|
71
|
+
|
72
|
+
class _NlPlanningResponse(BaseLlmResponseProcessor):
|
73
|
+
|
74
|
+
@override
|
75
|
+
async def run_async(
|
76
|
+
self, invocation_context: InvocationContext, llm_response: LlmResponse
|
77
|
+
) -> AsyncGenerator[Event, None]:
|
78
|
+
if (
|
79
|
+
not llm_response
|
80
|
+
or not llm_response.content
|
81
|
+
or not llm_response.content.parts
|
82
|
+
):
|
83
|
+
return
|
84
|
+
|
85
|
+
planner = _get_planner(invocation_context)
|
86
|
+
if not planner:
|
87
|
+
return
|
88
|
+
|
89
|
+
# Postprocess the LLM response.
|
90
|
+
processed_parts = planner.process_planning_response(
|
91
|
+
CallbackContext(invocation_context), llm_response.content.parts
|
92
|
+
)
|
93
|
+
if processed_parts:
|
94
|
+
llm_response.content.parts = processed_parts
|
95
|
+
|
96
|
+
# Maintain async generator behavior
|
97
|
+
if False: # Ensures it behaves as a generator
|
98
|
+
yield # This is a no-op but maintains generator structure
|
99
|
+
|
100
|
+
|
101
|
+
response_processor = _NlPlanningResponse()
|
102
|
+
|
103
|
+
|
104
|
+
def _get_planner(
|
105
|
+
invocation_context: InvocationContext,
|
106
|
+
) -> Optional[BasePlanner]:
|
107
|
+
from ...agents.llm_agent import Agent
|
108
|
+
from ...planners.base_planner import BasePlanner
|
109
|
+
|
110
|
+
agent = invocation_context.agent
|
111
|
+
if not isinstance(agent, Agent):
|
112
|
+
return None
|
113
|
+
if not agent.planner:
|
114
|
+
return None
|
115
|
+
|
116
|
+
if isinstance(agent.planner, BasePlanner):
|
117
|
+
return agent.planner
|
118
|
+
return PlanReActPlanner()
|
119
|
+
|
120
|
+
|
121
|
+
def _remove_thought_from_request(llm_request: LlmRequest):
|
122
|
+
if not llm_request.contents:
|
123
|
+
return
|
124
|
+
|
125
|
+
for content in llm_request.contents:
|
126
|
+
if not content.parts:
|
127
|
+
continue
|
128
|
+
for part in content.parts:
|
129
|
+
part.thought = None
|