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,49 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
import re
|
16
|
+
from typing import Any
|
17
|
+
from typing import Optional
|
18
|
+
|
19
|
+
from ...agents.base_agent import BaseAgent
|
20
|
+
from ...agents.llm_agent import LlmAgent
|
21
|
+
|
22
|
+
__all__ = [
|
23
|
+
'create_empty_state',
|
24
|
+
]
|
25
|
+
|
26
|
+
|
27
|
+
def _create_empty_state(agent: BaseAgent, all_state: dict[str, Any]):
|
28
|
+
for sub_agent in agent.sub_agents:
|
29
|
+
_create_empty_state(sub_agent, all_state)
|
30
|
+
|
31
|
+
if (
|
32
|
+
isinstance(agent, LlmAgent)
|
33
|
+
and agent.instruction
|
34
|
+
and isinstance(agent.instruction, str)
|
35
|
+
):
|
36
|
+
for key in re.findall(r'{([\w]+)}', agent.instruction):
|
37
|
+
all_state[key] = ''
|
38
|
+
|
39
|
+
|
40
|
+
def create_empty_state(
|
41
|
+
agent: BaseAgent, initialized_states: Optional[dict[str, Any]] = None
|
42
|
+
) -> dict[str, Any]:
|
43
|
+
"""Creates empty str for non-initialized states."""
|
44
|
+
non_initialized_states = {}
|
45
|
+
_create_empty_state(agent, non_initialized_states)
|
46
|
+
for key in initialized_states or {}:
|
47
|
+
if key in non_initialized_states:
|
48
|
+
del non_initialized_states[key]
|
49
|
+
return non_initialized_states
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
import logging
|
16
|
+
import os
|
17
|
+
|
18
|
+
from dotenv import load_dotenv
|
19
|
+
|
20
|
+
logger = logging.getLogger(__file__)
|
21
|
+
|
22
|
+
|
23
|
+
def _walk_to_root_until_found(folder, filename) -> str:
|
24
|
+
checkpath = os.path.join(folder, filename)
|
25
|
+
if os.path.exists(checkpath) and os.path.isfile(checkpath):
|
26
|
+
return checkpath
|
27
|
+
|
28
|
+
parent_folder = os.path.dirname(folder)
|
29
|
+
if parent_folder == folder: # reached the root
|
30
|
+
return ''
|
31
|
+
|
32
|
+
return _walk_to_root_until_found(parent_folder, filename)
|
33
|
+
|
34
|
+
|
35
|
+
def load_dotenv_for_agent(
|
36
|
+
agent_name: str, agent_parent_folder: str, filename: str = '.env'
|
37
|
+
):
|
38
|
+
"""Lods the .env file for the agent module."""
|
39
|
+
|
40
|
+
# Gets the folder of agent_module as starting_folder
|
41
|
+
starting_folder = os.path.abspath(
|
42
|
+
os.path.join(agent_parent_folder, agent_name)
|
43
|
+
)
|
44
|
+
dotenv_file_path = _walk_to_root_until_found(starting_folder, filename)
|
45
|
+
if dotenv_file_path:
|
46
|
+
load_dotenv(dotenv_file_path, override=True, verbose=True)
|
47
|
+
logger.info(
|
48
|
+
'Loaded %s file for %s at %s',
|
49
|
+
filename,
|
50
|
+
agent_name,
|
51
|
+
dotenv_file_path,
|
52
|
+
)
|
53
|
+
logger.info(
|
54
|
+
'Reloaded %s file for %s at %s', filename, agent_name, dotenv_file_path
|
55
|
+
)
|
56
|
+
else:
|
57
|
+
logger.info('No %s file found for %s', filename, agent_name)
|
@@ -0,0 +1,93 @@
|
|
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
|
+
|
17
|
+
from ...sessions.session import Session
|
18
|
+
|
19
|
+
|
20
|
+
def convert_session_to_eval_format(session: Session) -> list[dict[str, Any]]:
|
21
|
+
"""Converts a session data into eval format.
|
22
|
+
|
23
|
+
Args:
|
24
|
+
session: The session that should be converted.
|
25
|
+
|
26
|
+
Returns:
|
27
|
+
list: A single evaluation dataset in the required format.
|
28
|
+
"""
|
29
|
+
eval_case = []
|
30
|
+
events = session.events if session and session.events else []
|
31
|
+
|
32
|
+
for event in events:
|
33
|
+
if event.author == 'user':
|
34
|
+
if not event.content or not event.content.parts:
|
35
|
+
continue
|
36
|
+
|
37
|
+
# Extract user query
|
38
|
+
content = event.content
|
39
|
+
parts = content.parts
|
40
|
+
|
41
|
+
query = parts[0].text or ''
|
42
|
+
|
43
|
+
# Find the corresponding tool usage or response for the query
|
44
|
+
expected_tool_use = []
|
45
|
+
intermediate_agent_responses = []
|
46
|
+
|
47
|
+
# Check subsequent events to extract tool uses or responses for this turn.
|
48
|
+
for subsequent_event in events[events.index(event) + 1 :]:
|
49
|
+
event_author = subsequent_event.author or 'agent'
|
50
|
+
if event_author == 'user':
|
51
|
+
# We found an event where the author was the user. This means that a
|
52
|
+
# new turn has started. So close this turn here.
|
53
|
+
break
|
54
|
+
|
55
|
+
if not subsequent_event.content or not subsequent_event.content.parts:
|
56
|
+
continue
|
57
|
+
|
58
|
+
for subsequent_part in subsequent_event.content.parts:
|
59
|
+
# Some events have both function call and reference
|
60
|
+
|
61
|
+
if subsequent_part.function_call:
|
62
|
+
tool_name = subsequent_part.function_call.name or ''
|
63
|
+
tool_input = subsequent_part.function_call.args or {}
|
64
|
+
expected_tool_use.append({
|
65
|
+
'tool_name': tool_name,
|
66
|
+
'tool_input': tool_input,
|
67
|
+
})
|
68
|
+
elif subsequent_part.text:
|
69
|
+
# Also keep track of all the natural langauge responses that
|
70
|
+
# agent (or sub agents) generated.
|
71
|
+
intermediate_agent_responses.append(
|
72
|
+
{'author': event_author, 'text': subsequent_part.text}
|
73
|
+
)
|
74
|
+
|
75
|
+
# If we are here then either we are done reading all the events or we
|
76
|
+
# encountered an event that had content authored by the end-user.
|
77
|
+
# This, basically means an end of turn.
|
78
|
+
# We assume that the last natural langauge intermediate response is the
|
79
|
+
# final response from the agent/model. We treat that as a reference.
|
80
|
+
eval_case.append({
|
81
|
+
'query': query,
|
82
|
+
'expected_tool_use': expected_tool_use,
|
83
|
+
'expected_intermediate_agent_responses': intermediate_agent_responses[
|
84
|
+
:-1
|
85
|
+
],
|
86
|
+
'reference': (
|
87
|
+
intermediate_agent_responses[-1]['text']
|
88
|
+
if intermediate_agent_responses
|
89
|
+
else ''
|
90
|
+
),
|
91
|
+
})
|
92
|
+
|
93
|
+
return eval_case
|
@@ -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
|
+
import logging
|
16
|
+
import os
|
17
|
+
import tempfile
|
18
|
+
import time
|
19
|
+
|
20
|
+
LOGGING_FORMAT = (
|
21
|
+
'%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s'
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
def log_to_stderr(level=logging.INFO):
|
26
|
+
logging.basicConfig(
|
27
|
+
level=level,
|
28
|
+
format=LOGGING_FORMAT,
|
29
|
+
)
|
30
|
+
|
31
|
+
|
32
|
+
def log_to_tmp_folder(
|
33
|
+
level=logging.INFO,
|
34
|
+
*,
|
35
|
+
sub_folder: str = 'agents_log',
|
36
|
+
log_file_prefix: str = 'agent',
|
37
|
+
log_file_timestamp: str = time.strftime('%Y%m%d_%H%M%S'),
|
38
|
+
):
|
39
|
+
"""Logs to system temp folder, instead of logging to stderr.
|
40
|
+
|
41
|
+
Args
|
42
|
+
sub_folder: str = 'agents_log',
|
43
|
+
log_file_prefix: str = 'agent',
|
44
|
+
log_file_timestamp: str = time.strftime('%Y%m%d_%H%M%S'),
|
45
|
+
|
46
|
+
Returns
|
47
|
+
the log file path.
|
48
|
+
"""
|
49
|
+
log_dir = os.path.join(tempfile.gettempdir(), sub_folder)
|
50
|
+
log_filename = f'{log_file_prefix}.{log_file_timestamp}.log'
|
51
|
+
log_filepath = os.path.join(log_dir, log_filename)
|
52
|
+
|
53
|
+
os.makedirs(log_dir, exist_ok=True)
|
54
|
+
|
55
|
+
file_handler = logging.FileHandler(log_filepath, mode='w')
|
56
|
+
file_handler.setLevel(level)
|
57
|
+
file_handler.setFormatter(logging.Formatter(LOGGING_FORMAT))
|
58
|
+
|
59
|
+
root_logger = logging.getLogger()
|
60
|
+
root_logger.setLevel(level)
|
61
|
+
root_logger.handlers = [] # Clear handles to disable logging to stderr
|
62
|
+
root_logger.addHandler(file_handler)
|
63
|
+
|
64
|
+
print(f'Log setup complete: {log_filepath}')
|
65
|
+
|
66
|
+
latest_log_link = os.path.join(log_dir, f'{log_file_prefix}.latest.log')
|
67
|
+
if os.path.islink(latest_log_link):
|
68
|
+
os.unlink(latest_log_link)
|
69
|
+
os.symlink(log_filepath, latest_log_link)
|
70
|
+
|
71
|
+
print(f'To access latest log: tail -F {latest_log_link}')
|
72
|
+
return log_filepath
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
import logging
|
16
|
+
|
17
|
+
from .base_code_executor import BaseCodeExecutor
|
18
|
+
from .code_executor_context import CodeExecutorContext
|
19
|
+
from .unsafe_local_code_executor import UnsafeLocalCodeExecutor
|
20
|
+
|
21
|
+
logger = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
__all__ = [
|
24
|
+
'BaseCodeExecutor',
|
25
|
+
'CodeExecutorContext',
|
26
|
+
'UnsafeLocalCodeExecutor',
|
27
|
+
]
|
28
|
+
|
29
|
+
try:
|
30
|
+
from .vertex_ai_code_executor import VertexAiCodeExecutor
|
31
|
+
|
32
|
+
__all__.append('VertexAiCodeExecutor')
|
33
|
+
except ImportError:
|
34
|
+
logger.debug(
|
35
|
+
'The Vertex sdk is not installed. If you want to use the Vertex Code'
|
36
|
+
' Interpreter with agents, please install it. If not, you can ignore this'
|
37
|
+
' warning.'
|
38
|
+
)
|
39
|
+
|
40
|
+
try:
|
41
|
+
from .container_code_executor import ContainerCodeExecutor
|
42
|
+
|
43
|
+
__all__.append('ContainerCodeExecutor')
|
44
|
+
except ImportError:
|
45
|
+
logger.debug(
|
46
|
+
'The docker sdk is not installed. If you want to use the Container Code'
|
47
|
+
' Executor with agents, please install it. If not, you can ignore this'
|
48
|
+
' warning.'
|
49
|
+
)
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
import abc
|
16
|
+
from typing import List
|
17
|
+
|
18
|
+
from pydantic import BaseModel
|
19
|
+
|
20
|
+
from ..agents.invocation_context import InvocationContext
|
21
|
+
from .code_execution_utils import CodeExecutionInput
|
22
|
+
from .code_execution_utils import CodeExecutionResult
|
23
|
+
|
24
|
+
|
25
|
+
class BaseCodeExecutor(BaseModel):
|
26
|
+
"""Abstract base class for all code executors.
|
27
|
+
|
28
|
+
The code executor allows the agent to execute code blocks from model responses
|
29
|
+
and incorporate the execution results into the final response.
|
30
|
+
|
31
|
+
Attributes:
|
32
|
+
optimize_data_file: If true, extract and process data files from the model
|
33
|
+
request and attach them to the code executor. Supported data file
|
34
|
+
MimeTypes are [text/csv]. Default to False.
|
35
|
+
stateful: Whether the code executor is stateful. Default to False.
|
36
|
+
error_retry_attempts: The number of attempts to retry on consecutive code
|
37
|
+
execution errors. Default to 2.
|
38
|
+
code_block_delimiters: The list of the enclosing delimiters to identify the
|
39
|
+
code blocks.
|
40
|
+
execution_result_delimiters: The delimiters to format the code execution
|
41
|
+
result.
|
42
|
+
"""
|
43
|
+
|
44
|
+
optimize_data_file: bool = False
|
45
|
+
"""
|
46
|
+
If true, extract and process data files from the model request
|
47
|
+
and attach them to the code executor.
|
48
|
+
Supported data file MimeTypes are [text/csv].
|
49
|
+
|
50
|
+
Default to False.
|
51
|
+
"""
|
52
|
+
|
53
|
+
stateful: bool = False
|
54
|
+
"""
|
55
|
+
Whether the code executor is stateful. Default to False.
|
56
|
+
"""
|
57
|
+
|
58
|
+
error_retry_attempts: int = 2
|
59
|
+
"""
|
60
|
+
The number of attempts to retry on consecutive code execution errors. Default to 2.
|
61
|
+
"""
|
62
|
+
|
63
|
+
code_block_delimiters: List[tuple[str, str]] = [
|
64
|
+
('```tool_code\n', '\n```'),
|
65
|
+
('```python\n', '\n```'),
|
66
|
+
]
|
67
|
+
"""
|
68
|
+
The list of the enclosing delimiters to identify the code blocks.
|
69
|
+
For example, the delimiter ('```python\n', '\n```') can be
|
70
|
+
used to identify code blocks with the following format:
|
71
|
+
|
72
|
+
```python
|
73
|
+
print("hello")
|
74
|
+
```
|
75
|
+
"""
|
76
|
+
|
77
|
+
execution_result_delimiters: tuple[str, str] = ('```tool_output\n', '\n```')
|
78
|
+
"""
|
79
|
+
The delimiters to format the code execution result.
|
80
|
+
"""
|
81
|
+
|
82
|
+
@abc.abstractmethod
|
83
|
+
def execute_code(
|
84
|
+
self,
|
85
|
+
invocation_context: InvocationContext,
|
86
|
+
code_execution_input: CodeExecutionInput,
|
87
|
+
) -> CodeExecutionResult:
|
88
|
+
"""Executes code and return the code execution result.
|
89
|
+
|
90
|
+
Args:
|
91
|
+
invocation_context: The invocation context of the code execution.
|
92
|
+
code_execution_input: The code execution input.
|
93
|
+
|
94
|
+
Returns:
|
95
|
+
The code execution result.
|
96
|
+
"""
|
97
|
+
pass
|
@@ -0,0 +1,256 @@
|
|
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
|
+
"""Utility functions for code execution."""
|
16
|
+
|
17
|
+
import base64
|
18
|
+
import binascii
|
19
|
+
import copy
|
20
|
+
import dataclasses
|
21
|
+
import re
|
22
|
+
from typing import List, Optional
|
23
|
+
|
24
|
+
from google.genai import types
|
25
|
+
|
26
|
+
|
27
|
+
@dataclasses.dataclass(frozen=True)
|
28
|
+
class File:
|
29
|
+
"""A structure that contains a file name and its content."""
|
30
|
+
|
31
|
+
name: str
|
32
|
+
"""
|
33
|
+
The name of the file with file extension (e.g., "file.csv").
|
34
|
+
"""
|
35
|
+
|
36
|
+
content: str
|
37
|
+
"""
|
38
|
+
The base64-encoded bytes of the file content.
|
39
|
+
"""
|
40
|
+
|
41
|
+
mime_type: str = 'text/plain'
|
42
|
+
"""
|
43
|
+
The mime type of the file (e.g., "image/png").
|
44
|
+
"""
|
45
|
+
|
46
|
+
|
47
|
+
@dataclasses.dataclass
|
48
|
+
class CodeExecutionInput:
|
49
|
+
"""A structure that contains the input of code execution."""
|
50
|
+
|
51
|
+
code: str
|
52
|
+
"""
|
53
|
+
The code to execute.
|
54
|
+
"""
|
55
|
+
|
56
|
+
input_files: list[File] = dataclasses.field(default_factory=list)
|
57
|
+
"""
|
58
|
+
The input files available to the code.
|
59
|
+
"""
|
60
|
+
|
61
|
+
execution_id: Optional[str] = None
|
62
|
+
"""
|
63
|
+
The execution ID for the stateful code execution.
|
64
|
+
"""
|
65
|
+
|
66
|
+
|
67
|
+
@dataclasses.dataclass
|
68
|
+
class CodeExecutionResult:
|
69
|
+
"""A structure that contains the result of code execution."""
|
70
|
+
|
71
|
+
stdout: str = ''
|
72
|
+
"""
|
73
|
+
The standard output of the code execution.
|
74
|
+
"""
|
75
|
+
|
76
|
+
stderr: str = ''
|
77
|
+
"""
|
78
|
+
The standard error of the code execution.
|
79
|
+
"""
|
80
|
+
|
81
|
+
output_files: list[File] = dataclasses.field(default_factory=list)
|
82
|
+
"""
|
83
|
+
The output files from the code execution.
|
84
|
+
"""
|
85
|
+
|
86
|
+
|
87
|
+
class CodeExecutionUtils:
|
88
|
+
"""Utility functions for code execution."""
|
89
|
+
|
90
|
+
@staticmethod
|
91
|
+
def get_encoded_file_content(data: bytes) -> bytes:
|
92
|
+
"""Gets the file content as a base64-encoded bytes.
|
93
|
+
|
94
|
+
Args:
|
95
|
+
data: The file content bytes.
|
96
|
+
|
97
|
+
Returns:
|
98
|
+
The file content as a base64-encoded bytes.
|
99
|
+
"""
|
100
|
+
|
101
|
+
def _is_base64_encoded(data: bytes) -> bool:
|
102
|
+
try:
|
103
|
+
return base64.b64encode(base64.b64decode(data)) == data
|
104
|
+
except binascii.Error:
|
105
|
+
return False
|
106
|
+
|
107
|
+
return data if _is_base64_encoded(data) else base64.b64encode(data)
|
108
|
+
|
109
|
+
@staticmethod
|
110
|
+
def extract_code_and_truncate_content(
|
111
|
+
content: types.Content,
|
112
|
+
code_block_delimiters: List[tuple[str, str]],
|
113
|
+
) -> Optional[str]:
|
114
|
+
"""Extracts the first code block from the content and truncate everything after it.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
content: The mutable content to extract the code from.
|
118
|
+
code_block_delimiters: The list of the enclosing delimiters to identify
|
119
|
+
the code blocks.
|
120
|
+
|
121
|
+
Returns:
|
122
|
+
The first code block if found, otherwise None.
|
123
|
+
"""
|
124
|
+
if not content or not content.parts:
|
125
|
+
return
|
126
|
+
|
127
|
+
# Extract the code from the executable code parts if there're no associated
|
128
|
+
# code execution result parts.
|
129
|
+
for idx, part in enumerate(content.parts):
|
130
|
+
if part.executable_code and (
|
131
|
+
idx == len(content.parts) - 1
|
132
|
+
or not content.parts[idx + 1].code_execution_result
|
133
|
+
):
|
134
|
+
content.parts = content.parts[: idx + 1]
|
135
|
+
return part.executable_code.code
|
136
|
+
|
137
|
+
# Extract the code from the text parts.
|
138
|
+
text_parts = [p for p in content.parts if p.text]
|
139
|
+
if not text_parts:
|
140
|
+
return
|
141
|
+
|
142
|
+
first_text_part = copy.deepcopy(text_parts[0])
|
143
|
+
response_text = '\n'.join([p.text for p in text_parts])
|
144
|
+
|
145
|
+
# Find the first code block.
|
146
|
+
leading_delimiter_pattern = '|'.join(d[0] for d in code_block_delimiters)
|
147
|
+
trailing_delimiter_pattern = '|'.join(d[1] for d in code_block_delimiters)
|
148
|
+
pattern = re.compile(
|
149
|
+
(
|
150
|
+
rf'(?P<prefix>.*?)({leading_delimiter_pattern})(?P<code>.*?)({trailing_delimiter_pattern})(?P<suffix>.*?)$'
|
151
|
+
).encode(),
|
152
|
+
re.DOTALL,
|
153
|
+
)
|
154
|
+
pattern_match = pattern.search(response_text.encode())
|
155
|
+
if pattern_match is None:
|
156
|
+
return
|
157
|
+
|
158
|
+
code_str = pattern_match.group('code').decode()
|
159
|
+
if not code_str:
|
160
|
+
return
|
161
|
+
|
162
|
+
content.parts = []
|
163
|
+
if pattern_match.group('prefix'):
|
164
|
+
first_text_part.text = pattern_match.group('prefix').decode()
|
165
|
+
content.parts.append(first_text_part)
|
166
|
+
content.parts.append(
|
167
|
+
CodeExecutionUtils.build_executable_code_part(code_str)
|
168
|
+
)
|
169
|
+
return pattern_match.group('code').decode()
|
170
|
+
|
171
|
+
@staticmethod
|
172
|
+
def build_executable_code_part(code: str) -> types.Part:
|
173
|
+
"""Builds an executable code part with code string.
|
174
|
+
|
175
|
+
Args:
|
176
|
+
code: The code string.
|
177
|
+
|
178
|
+
Returns:
|
179
|
+
The constructed executable code part.
|
180
|
+
"""
|
181
|
+
return types.Part.from_executable_code(
|
182
|
+
code=code,
|
183
|
+
language='PYTHON',
|
184
|
+
)
|
185
|
+
|
186
|
+
@staticmethod
|
187
|
+
def build_code_execution_result_part(
|
188
|
+
code_execution_result: CodeExecutionResult,
|
189
|
+
) -> types.Part:
|
190
|
+
"""Builds the code execution result part from the code execution result.
|
191
|
+
|
192
|
+
Args:
|
193
|
+
code_execution_result: The code execution result.
|
194
|
+
|
195
|
+
Returns:
|
196
|
+
The constructed code execution result part.
|
197
|
+
"""
|
198
|
+
if code_execution_result.stderr:
|
199
|
+
return types.Part.from_code_execution_result(
|
200
|
+
outcome='OUTCOME_FAILED',
|
201
|
+
output=code_execution_result.stderr,
|
202
|
+
)
|
203
|
+
final_result = []
|
204
|
+
if code_execution_result.stdout or not code_execution_result.output_files:
|
205
|
+
final_result.append(
|
206
|
+
'Code execution result:\n' + '%s\n' % code_execution_result.stdout
|
207
|
+
)
|
208
|
+
if code_execution_result.output_files:
|
209
|
+
final_result.append(
|
210
|
+
'Saved artifacts:\n'
|
211
|
+
+ ','.join(
|
212
|
+
['`%s`' % f.name for f in code_execution_result.output_files]
|
213
|
+
)
|
214
|
+
)
|
215
|
+
return types.Part.from_code_execution_result(
|
216
|
+
outcome='OUTCOME_OK',
|
217
|
+
output='\n\n'.join(final_result),
|
218
|
+
)
|
219
|
+
|
220
|
+
@staticmethod
|
221
|
+
def convert_code_execution_parts(
|
222
|
+
content: types.Content,
|
223
|
+
code_block_delimiter: tuple[str, str],
|
224
|
+
execution_result_delimiters: tuple[str, str],
|
225
|
+
):
|
226
|
+
"""Converts the code execution parts to text parts in a Content.
|
227
|
+
|
228
|
+
Args:
|
229
|
+
content: The mutable content to convert the code execution parts to text
|
230
|
+
parts.
|
231
|
+
code_block_delimiter: The delimiter to format the code block.
|
232
|
+
execution_result_delimiters: The delimiter to format the code execution
|
233
|
+
result.
|
234
|
+
"""
|
235
|
+
if not content.parts:
|
236
|
+
return
|
237
|
+
|
238
|
+
# Handle the conversion of trailing executable code parts.
|
239
|
+
if content.parts[-1].executable_code:
|
240
|
+
content.parts[-1] = types.Part(
|
241
|
+
text=(
|
242
|
+
code_block_delimiter[0]
|
243
|
+
+ content.parts[-1].executable_code.code
|
244
|
+
+ code_block_delimiter[1]
|
245
|
+
)
|
246
|
+
)
|
247
|
+
# Handle the conversion of trailing code execution result parts.
|
248
|
+
# Skip if the Content has multiple parts, which means the Content is
|
249
|
+
# likely generated by the model.
|
250
|
+
elif len(content.parts) == 1 and content.parts[-1].code_execution_result:
|
251
|
+
content.parts[-1] = types.Part(
|
252
|
+
text=execution_result_delimiters[0]
|
253
|
+
+ content.parts[-1].code_execution_result.output
|
254
|
+
+ execution_result_delimiters[1]
|
255
|
+
)
|
256
|
+
content.role = 'user'
|