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,521 @@
|
|
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 argparse
|
16
|
+
import json
|
17
|
+
import logging
|
18
|
+
from typing import Any
|
19
|
+
from typing import Dict
|
20
|
+
from typing import List
|
21
|
+
from typing import Optional
|
22
|
+
from typing import Union
|
23
|
+
|
24
|
+
# Google API client
|
25
|
+
from googleapiclient.discovery import build
|
26
|
+
from googleapiclient.discovery import Resource
|
27
|
+
from googleapiclient.errors import HttpError
|
28
|
+
|
29
|
+
# Configure logging
|
30
|
+
logging.basicConfig(
|
31
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
32
|
+
)
|
33
|
+
logger = logging.getLogger(__name__)
|
34
|
+
|
35
|
+
|
36
|
+
class GoogleApiToOpenApiConverter:
|
37
|
+
"""Converts Google API Discovery documents to OpenAPI v3 format."""
|
38
|
+
|
39
|
+
def __init__(self, api_name: str, api_version: str):
|
40
|
+
"""Initialize the converter with the API name and version.
|
41
|
+
|
42
|
+
Args:
|
43
|
+
api_name: The name of the Google API (e.g., "calendar")
|
44
|
+
api_version: The version of the API (e.g., "v3")
|
45
|
+
"""
|
46
|
+
self.api_name = api_name
|
47
|
+
self.api_version = api_version
|
48
|
+
self.google_api_resource = None
|
49
|
+
self.google_api_spec = None
|
50
|
+
self.openapi_spec = {
|
51
|
+
"openapi": "3.0.0",
|
52
|
+
"info": {},
|
53
|
+
"servers": [],
|
54
|
+
"paths": {},
|
55
|
+
"components": {"schemas": {}, "securitySchemes": {}},
|
56
|
+
}
|
57
|
+
|
58
|
+
def fetch_google_api_spec(self) -> None:
|
59
|
+
"""Fetches the Google API specification using discovery service."""
|
60
|
+
try:
|
61
|
+
logger.info(
|
62
|
+
"Fetching Google API spec for %s %s", self.api_name, self.api_version
|
63
|
+
)
|
64
|
+
# Build a resource object for the specified API
|
65
|
+
self.google_api_resource = build(self.api_name, self.api_version)
|
66
|
+
|
67
|
+
# Access the underlying API discovery document
|
68
|
+
self.google_api_spec = self.google_api_resource._rootDesc
|
69
|
+
|
70
|
+
if not self.google_api_spec:
|
71
|
+
raise ValueError("Failed to retrieve API specification")
|
72
|
+
|
73
|
+
logger.info("Successfully fetched %s API specification", self.api_name)
|
74
|
+
except HttpError as e:
|
75
|
+
logger.error("HTTP Error: %s", e)
|
76
|
+
raise
|
77
|
+
except Exception as e:
|
78
|
+
logger.error("Error fetching API spec: %s", e)
|
79
|
+
raise
|
80
|
+
|
81
|
+
def convert(self) -> Dict[str, Any]:
|
82
|
+
"""Convert the Google API spec to OpenAPI v3 format.
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
Dict containing the converted OpenAPI v3 specification
|
86
|
+
"""
|
87
|
+
if not self.google_api_spec:
|
88
|
+
self.fetch_google_api_spec()
|
89
|
+
|
90
|
+
# Convert basic API information
|
91
|
+
self._convert_info()
|
92
|
+
|
93
|
+
# Convert server information
|
94
|
+
self._convert_servers()
|
95
|
+
|
96
|
+
# Convert authentication/authorization schemes
|
97
|
+
self._convert_security_schemes()
|
98
|
+
|
99
|
+
# Convert schemas (models)
|
100
|
+
self._convert_schemas()
|
101
|
+
|
102
|
+
# Convert endpoints/paths
|
103
|
+
self._convert_resources(self.google_api_spec.get("resources", {}))
|
104
|
+
|
105
|
+
# Convert top-level methods, if any
|
106
|
+
self._convert_methods(self.google_api_spec.get("methods", {}), "/")
|
107
|
+
|
108
|
+
return self.openapi_spec
|
109
|
+
|
110
|
+
def _convert_info(self) -> None:
|
111
|
+
"""Convert basic API information."""
|
112
|
+
self.openapi_spec["info"] = {
|
113
|
+
"title": self.google_api_spec.get("title", f"{self.api_name} API"),
|
114
|
+
"description": self.google_api_spec.get("description", ""),
|
115
|
+
"version": self.google_api_spec.get("version", self.api_version),
|
116
|
+
"contact": {},
|
117
|
+
"termsOfService": self.google_api_spec.get("documentationLink", ""),
|
118
|
+
}
|
119
|
+
|
120
|
+
# Add documentation links if available
|
121
|
+
docs_link = self.google_api_spec.get("documentationLink")
|
122
|
+
if docs_link:
|
123
|
+
self.openapi_spec["externalDocs"] = {
|
124
|
+
"description": "API Documentation",
|
125
|
+
"url": docs_link,
|
126
|
+
}
|
127
|
+
|
128
|
+
def _convert_servers(self) -> None:
|
129
|
+
"""Convert server information."""
|
130
|
+
base_url = self.google_api_spec.get(
|
131
|
+
"rootUrl", ""
|
132
|
+
) + self.google_api_spec.get("servicePath", "")
|
133
|
+
|
134
|
+
# Remove trailing slash if present
|
135
|
+
if base_url.endswith("/"):
|
136
|
+
base_url = base_url[:-1]
|
137
|
+
|
138
|
+
self.openapi_spec["servers"] = [{
|
139
|
+
"url": base_url,
|
140
|
+
"description": f"{self.api_name} {self.api_version} API",
|
141
|
+
}]
|
142
|
+
|
143
|
+
def _convert_security_schemes(self) -> None:
|
144
|
+
"""Convert authentication and authorization schemes."""
|
145
|
+
auth = self.google_api_spec.get("auth", {})
|
146
|
+
oauth2 = auth.get("oauth2", {})
|
147
|
+
|
148
|
+
if oauth2:
|
149
|
+
# Handle OAuth2
|
150
|
+
scopes = oauth2.get("scopes", {})
|
151
|
+
formatted_scopes = {}
|
152
|
+
|
153
|
+
for scope, scope_info in scopes.items():
|
154
|
+
formatted_scopes[scope] = scope_info.get("description", "")
|
155
|
+
|
156
|
+
self.openapi_spec["components"]["securitySchemes"]["oauth2"] = {
|
157
|
+
"type": "oauth2",
|
158
|
+
"description": "OAuth 2.0 authentication",
|
159
|
+
"flows": {
|
160
|
+
"authorizationCode": {
|
161
|
+
"authorizationUrl": (
|
162
|
+
"https://accounts.google.com/o/oauth2/auth"
|
163
|
+
),
|
164
|
+
"tokenUrl": "https://oauth2.googleapis.com/token",
|
165
|
+
"scopes": formatted_scopes,
|
166
|
+
}
|
167
|
+
},
|
168
|
+
}
|
169
|
+
|
170
|
+
# Add API key authentication (most Google APIs support this)
|
171
|
+
self.openapi_spec["components"]["securitySchemes"]["apiKey"] = {
|
172
|
+
"type": "apiKey",
|
173
|
+
"in": "query",
|
174
|
+
"name": "key",
|
175
|
+
"description": "API key for accessing this API",
|
176
|
+
}
|
177
|
+
|
178
|
+
# Create global security requirement
|
179
|
+
self.openapi_spec["security"] = [
|
180
|
+
{"oauth2": list(formatted_scopes.keys())} if oauth2 else {},
|
181
|
+
{"apiKey": []},
|
182
|
+
]
|
183
|
+
|
184
|
+
def _convert_schemas(self) -> None:
|
185
|
+
"""Convert schema definitions (models)."""
|
186
|
+
schemas = self.google_api_spec.get("schemas", {})
|
187
|
+
|
188
|
+
for schema_name, schema_def in schemas.items():
|
189
|
+
converted_schema = self._convert_schema_object(schema_def)
|
190
|
+
self.openapi_spec["components"]["schemas"][schema_name] = converted_schema
|
191
|
+
|
192
|
+
def _convert_schema_object(
|
193
|
+
self, schema_def: Dict[str, Any]
|
194
|
+
) -> Dict[str, Any]:
|
195
|
+
"""Recursively convert a Google API schema object to OpenAPI schema.
|
196
|
+
|
197
|
+
Args:
|
198
|
+
schema_def: Google API schema definition
|
199
|
+
|
200
|
+
Returns:
|
201
|
+
Converted OpenAPI schema object
|
202
|
+
"""
|
203
|
+
result = {}
|
204
|
+
|
205
|
+
# Convert the type
|
206
|
+
if "type" in schema_def:
|
207
|
+
gtype = schema_def["type"]
|
208
|
+
if gtype == "object":
|
209
|
+
result["type"] = "object"
|
210
|
+
|
211
|
+
# Handle properties
|
212
|
+
if "properties" in schema_def:
|
213
|
+
result["properties"] = {}
|
214
|
+
for prop_name, prop_def in schema_def["properties"].items():
|
215
|
+
result["properties"][prop_name] = self._convert_schema_object(
|
216
|
+
prop_def
|
217
|
+
)
|
218
|
+
|
219
|
+
# Handle required fields
|
220
|
+
required_fields = []
|
221
|
+
for prop_name, prop_def in schema_def.get("properties", {}).items():
|
222
|
+
if prop_def.get("required", False):
|
223
|
+
required_fields.append(prop_name)
|
224
|
+
if required_fields:
|
225
|
+
result["required"] = required_fields
|
226
|
+
|
227
|
+
elif gtype == "array":
|
228
|
+
result["type"] = "array"
|
229
|
+
if "items" in schema_def:
|
230
|
+
result["items"] = self._convert_schema_object(schema_def["items"])
|
231
|
+
|
232
|
+
elif gtype == "any":
|
233
|
+
# OpenAPI doesn't have direct "any" type
|
234
|
+
# Use oneOf with multiple options as alternative
|
235
|
+
result["oneOf"] = [
|
236
|
+
{"type": "object"},
|
237
|
+
{"type": "array"},
|
238
|
+
{"type": "string"},
|
239
|
+
{"type": "number"},
|
240
|
+
{"type": "boolean"},
|
241
|
+
{"type": "null"},
|
242
|
+
]
|
243
|
+
|
244
|
+
else:
|
245
|
+
# Handle other primitive types
|
246
|
+
result["type"] = gtype
|
247
|
+
|
248
|
+
# Handle references
|
249
|
+
if "$ref" in schema_def:
|
250
|
+
ref = schema_def["$ref"]
|
251
|
+
# Google refs use "#" at start, OpenAPI uses "#/components/schemas/"
|
252
|
+
if ref.startswith("#"):
|
253
|
+
ref = ref.replace("#", "#/components/schemas/")
|
254
|
+
else:
|
255
|
+
ref = "#/components/schemas/" + ref
|
256
|
+
result["$ref"] = ref
|
257
|
+
|
258
|
+
# Handle format
|
259
|
+
if "format" in schema_def:
|
260
|
+
result["format"] = schema_def["format"]
|
261
|
+
|
262
|
+
# Handle enum values
|
263
|
+
if "enum" in schema_def:
|
264
|
+
result["enum"] = schema_def["enum"]
|
265
|
+
|
266
|
+
# Handle description
|
267
|
+
if "description" in schema_def:
|
268
|
+
result["description"] = schema_def["description"]
|
269
|
+
|
270
|
+
# Handle pattern
|
271
|
+
if "pattern" in schema_def:
|
272
|
+
result["pattern"] = schema_def["pattern"]
|
273
|
+
|
274
|
+
# Handle default value
|
275
|
+
if "default" in schema_def:
|
276
|
+
result["default"] = schema_def["default"]
|
277
|
+
|
278
|
+
return result
|
279
|
+
|
280
|
+
def _convert_resources(
|
281
|
+
self, resources: Dict[str, Any], parent_path: str = ""
|
282
|
+
) -> None:
|
283
|
+
"""Recursively convert all resources and their methods.
|
284
|
+
|
285
|
+
Args:
|
286
|
+
resources: Dictionary of resources from the Google API spec
|
287
|
+
parent_path: The parent path prefix for nested resources
|
288
|
+
"""
|
289
|
+
for resource_name, resource_data in resources.items():
|
290
|
+
# Process methods for this resource
|
291
|
+
resource_path = f"{parent_path}/{resource_name}"
|
292
|
+
methods = resource_data.get("methods", {})
|
293
|
+
self._convert_methods(methods, resource_path)
|
294
|
+
|
295
|
+
# Process nested resources recursively
|
296
|
+
nested_resources = resource_data.get("resources", {})
|
297
|
+
if nested_resources:
|
298
|
+
self._convert_resources(nested_resources, resource_path)
|
299
|
+
|
300
|
+
def _convert_methods(
|
301
|
+
self, methods: Dict[str, Any], resource_path: str
|
302
|
+
) -> None:
|
303
|
+
"""Convert methods for a specific resource path.
|
304
|
+
|
305
|
+
Args:
|
306
|
+
methods: Dictionary of methods from the Google API spec
|
307
|
+
resource_path: The path of the resource these methods belong to
|
308
|
+
"""
|
309
|
+
for method_name, method_data in methods.items():
|
310
|
+
http_method = method_data.get("httpMethod", "GET").lower()
|
311
|
+
|
312
|
+
# Determine the actual endpoint path
|
313
|
+
# Google often has the format something like 'users.messages.list'
|
314
|
+
rest_path = method_data.get("path", "/")
|
315
|
+
if not rest_path.startswith("/"):
|
316
|
+
rest_path = "/" + rest_path
|
317
|
+
|
318
|
+
path_params = self._extract_path_parameters(rest_path)
|
319
|
+
|
320
|
+
# Create path entry if it doesn't exist
|
321
|
+
if rest_path not in self.openapi_spec["paths"]:
|
322
|
+
self.openapi_spec["paths"][rest_path] = {}
|
323
|
+
|
324
|
+
# Add the operation for this method
|
325
|
+
self.openapi_spec["paths"][rest_path][http_method] = (
|
326
|
+
self._convert_operation(method_data, path_params)
|
327
|
+
)
|
328
|
+
|
329
|
+
def _extract_path_parameters(self, path: str) -> List[str]:
|
330
|
+
"""Extract path parameters from a URL path.
|
331
|
+
|
332
|
+
Args:
|
333
|
+
path: The URL path with path parameters
|
334
|
+
|
335
|
+
Returns:
|
336
|
+
List of parameter names
|
337
|
+
"""
|
338
|
+
params = []
|
339
|
+
segments = path.split("/")
|
340
|
+
|
341
|
+
for segment in segments:
|
342
|
+
# Google APIs often use {param} format for path parameters
|
343
|
+
if segment.startswith("{") and segment.endswith("}"):
|
344
|
+
param_name = segment[1:-1]
|
345
|
+
params.append(param_name)
|
346
|
+
|
347
|
+
return params
|
348
|
+
|
349
|
+
def _convert_operation(
|
350
|
+
self, method_data: Dict[str, Any], path_params: List[str]
|
351
|
+
) -> Dict[str, Any]:
|
352
|
+
"""Convert a Google API method to an OpenAPI operation.
|
353
|
+
|
354
|
+
Args:
|
355
|
+
method_data: Google API method data
|
356
|
+
path_params: List of path parameter names
|
357
|
+
|
358
|
+
Returns:
|
359
|
+
OpenAPI operation object
|
360
|
+
"""
|
361
|
+
operation = {
|
362
|
+
"operationId": method_data.get("id", ""),
|
363
|
+
"summary": method_data.get("description", ""),
|
364
|
+
"description": method_data.get("description", ""),
|
365
|
+
"parameters": [],
|
366
|
+
"responses": {
|
367
|
+
"200": {"description": "Successful operation"},
|
368
|
+
"400": {"description": "Bad request"},
|
369
|
+
"401": {"description": "Unauthorized"},
|
370
|
+
"403": {"description": "Forbidden"},
|
371
|
+
"404": {"description": "Not found"},
|
372
|
+
"500": {"description": "Server error"},
|
373
|
+
},
|
374
|
+
}
|
375
|
+
|
376
|
+
# Add path parameters
|
377
|
+
for param_name in path_params:
|
378
|
+
param = {
|
379
|
+
"name": param_name,
|
380
|
+
"in": "path",
|
381
|
+
"required": True,
|
382
|
+
"schema": {"type": "string"},
|
383
|
+
}
|
384
|
+
operation["parameters"].append(param)
|
385
|
+
|
386
|
+
# Add query parameters
|
387
|
+
for param_name, param_data in method_data.get("parameters", {}).items():
|
388
|
+
# Skip parameters already included in path
|
389
|
+
if param_name in path_params:
|
390
|
+
continue
|
391
|
+
|
392
|
+
param = {
|
393
|
+
"name": param_name,
|
394
|
+
"in": "query",
|
395
|
+
"description": param_data.get("description", ""),
|
396
|
+
"required": param_data.get("required", False),
|
397
|
+
"schema": self._convert_parameter_schema(param_data),
|
398
|
+
}
|
399
|
+
operation["parameters"].append(param)
|
400
|
+
|
401
|
+
# Handle request body
|
402
|
+
if "request" in method_data:
|
403
|
+
request_ref = method_data.get("request", {}).get("$ref", "")
|
404
|
+
if request_ref:
|
405
|
+
if request_ref.startswith("#"):
|
406
|
+
# Convert Google's reference format to OpenAPI format
|
407
|
+
openapi_ref = request_ref.replace("#", "#/components/schemas/")
|
408
|
+
else:
|
409
|
+
openapi_ref = "#/components/schemas/" + request_ref
|
410
|
+
operation["requestBody"] = {
|
411
|
+
"description": "Request body",
|
412
|
+
"content": {"application/json": {"schema": {"$ref": openapi_ref}}},
|
413
|
+
"required": True,
|
414
|
+
}
|
415
|
+
|
416
|
+
# Handle response body
|
417
|
+
if "response" in method_data:
|
418
|
+
response_ref = method_data.get("response", {}).get("$ref", "")
|
419
|
+
if response_ref:
|
420
|
+
if response_ref.startswith("#"):
|
421
|
+
# Convert Google's reference format to OpenAPI format
|
422
|
+
openapi_ref = response_ref.replace("#", "#/components/schemas/")
|
423
|
+
else:
|
424
|
+
openapi_ref = "#/components/schemas/" + response_ref
|
425
|
+
operation["responses"]["200"]["content"] = {
|
426
|
+
"application/json": {"schema": {"$ref": openapi_ref}}
|
427
|
+
}
|
428
|
+
|
429
|
+
# Add scopes if available
|
430
|
+
scopes = method_data.get("scopes", [])
|
431
|
+
if scopes:
|
432
|
+
# Add method-specific security requirement if different from global
|
433
|
+
operation["security"] = [{"oauth2": scopes}]
|
434
|
+
|
435
|
+
return operation
|
436
|
+
|
437
|
+
def _convert_parameter_schema(
|
438
|
+
self, param_data: Dict[str, Any]
|
439
|
+
) -> Dict[str, Any]:
|
440
|
+
"""Convert a parameter definition to an OpenAPI schema.
|
441
|
+
|
442
|
+
Args:
|
443
|
+
param_data: Google API parameter data
|
444
|
+
|
445
|
+
Returns:
|
446
|
+
OpenAPI schema for the parameter
|
447
|
+
"""
|
448
|
+
schema = {}
|
449
|
+
|
450
|
+
# Convert type
|
451
|
+
param_type = param_data.get("type", "string")
|
452
|
+
schema["type"] = param_type
|
453
|
+
|
454
|
+
# Handle enum values
|
455
|
+
if "enum" in param_data:
|
456
|
+
schema["enum"] = param_data["enum"]
|
457
|
+
|
458
|
+
# Handle format
|
459
|
+
if "format" in param_data:
|
460
|
+
schema["format"] = param_data["format"]
|
461
|
+
|
462
|
+
# Handle default value
|
463
|
+
if "default" in param_data:
|
464
|
+
schema["default"] = param_data["default"]
|
465
|
+
|
466
|
+
# Handle pattern
|
467
|
+
if "pattern" in param_data:
|
468
|
+
schema["pattern"] = param_data["pattern"]
|
469
|
+
|
470
|
+
return schema
|
471
|
+
|
472
|
+
def save_openapi_spec(self, output_path: str) -> None:
|
473
|
+
"""Save the OpenAPI specification to a file.
|
474
|
+
|
475
|
+
Args:
|
476
|
+
output_path: Path where the OpenAPI spec should be saved
|
477
|
+
"""
|
478
|
+
with open(output_path, "w", encoding="utf-8") as f:
|
479
|
+
json.dump(self.openapi_spec, f, indent=2)
|
480
|
+
logger.info("OpenAPI specification saved to %s", output_path)
|
481
|
+
|
482
|
+
|
483
|
+
def main():
|
484
|
+
"""Command line interface for the converter."""
|
485
|
+
parser = argparse.ArgumentParser(
|
486
|
+
description=(
|
487
|
+
"Convert Google API Discovery documents to OpenAPI v3 specifications"
|
488
|
+
)
|
489
|
+
)
|
490
|
+
parser.add_argument(
|
491
|
+
"api_name", help="Name of the Google API (e.g., 'calendar')"
|
492
|
+
)
|
493
|
+
parser.add_argument("api_version", help="Version of the API (e.g., 'v3')")
|
494
|
+
parser.add_argument(
|
495
|
+
"--output",
|
496
|
+
"-o",
|
497
|
+
default="openapi_spec.json",
|
498
|
+
help="Output file path for the OpenAPI specification",
|
499
|
+
)
|
500
|
+
|
501
|
+
args = parser.parse_args()
|
502
|
+
|
503
|
+
try:
|
504
|
+
# Create and run the converter
|
505
|
+
converter = GoogleApiToOpenApiConverter(args.api_name, args.api_version)
|
506
|
+
converter.convert()
|
507
|
+
converter.save_openapi_spec(args.output)
|
508
|
+
print(
|
509
|
+
f"Successfully converted {args.api_name} {args.api_version} to"
|
510
|
+
" OpenAPI v3"
|
511
|
+
)
|
512
|
+
print(f"Output saved to {args.output}")
|
513
|
+
except Exception as e:
|
514
|
+
logger.error("Conversion failed: %s", e)
|
515
|
+
return 1
|
516
|
+
|
517
|
+
return 0
|
518
|
+
|
519
|
+
|
520
|
+
if __name__ == "__main__":
|
521
|
+
main()
|
@@ -0,0 +1,68 @@
|
|
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 typing import TYPE_CHECKING
|
18
|
+
|
19
|
+
from google.genai import types
|
20
|
+
from typing_extensions import override
|
21
|
+
|
22
|
+
from .base_tool import BaseTool
|
23
|
+
from .tool_context import ToolContext
|
24
|
+
|
25
|
+
if TYPE_CHECKING:
|
26
|
+
from ..models import LlmRequest
|
27
|
+
|
28
|
+
|
29
|
+
class GoogleSearchTool(BaseTool):
|
30
|
+
"""A built-in tool that is automatically invoked by Gemini 2 models to retrieve search results from Google Search.
|
31
|
+
|
32
|
+
This tool operates internally within the model and does not require or perform
|
33
|
+
local code execution.
|
34
|
+
"""
|
35
|
+
|
36
|
+
def __init__(self):
|
37
|
+
# Name and description are not used because this is a model built-in tool.
|
38
|
+
super().__init__(name='google_search', description='google_search')
|
39
|
+
|
40
|
+
@override
|
41
|
+
async def process_llm_request(
|
42
|
+
self,
|
43
|
+
*,
|
44
|
+
tool_context: ToolContext,
|
45
|
+
llm_request: LlmRequest,
|
46
|
+
) -> None:
|
47
|
+
llm_request.config = llm_request.config or types.GenerateContentConfig()
|
48
|
+
llm_request.config.tools = llm_request.config.tools or []
|
49
|
+
if llm_request.model and llm_request.model.startswith('gemini-1'):
|
50
|
+
if llm_request.config.tools:
|
51
|
+
print(llm_request.config.tools)
|
52
|
+
raise ValueError(
|
53
|
+
'Google search tool can not be used with other tools in Gemini 1.x.'
|
54
|
+
)
|
55
|
+
llm_request.config.tools.append(
|
56
|
+
types.Tool(google_search_retrieval=types.GoogleSearchRetrieval())
|
57
|
+
)
|
58
|
+
elif llm_request.model and llm_request.model.startswith('gemini-2'):
|
59
|
+
llm_request.config.tools.append(
|
60
|
+
types.Tool(google_search=types.GoogleSearch())
|
61
|
+
)
|
62
|
+
else:
|
63
|
+
raise ValueError(
|
64
|
+
f'Google search tool is not supported for model {llm_request.model}'
|
65
|
+
)
|
66
|
+
|
67
|
+
|
68
|
+
google_search = GoogleSearchTool()
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
from typing import Any
|
16
|
+
from typing import Callable
|
17
|
+
|
18
|
+
from google.genai import types
|
19
|
+
from pydantic import model_validator
|
20
|
+
from typing_extensions import override
|
21
|
+
|
22
|
+
from . import _automatic_function_calling_util
|
23
|
+
from .function_tool import FunctionTool
|
24
|
+
|
25
|
+
|
26
|
+
class LangchainTool(FunctionTool):
|
27
|
+
"""Use this class to wrap a langchain tool.
|
28
|
+
|
29
|
+
If the original tool name and description are not suitable, you can override
|
30
|
+
them in the constructor.
|
31
|
+
"""
|
32
|
+
|
33
|
+
tool: Any
|
34
|
+
"""The wrapped langchain tool."""
|
35
|
+
|
36
|
+
def __init__(self, tool: Any):
|
37
|
+
super().__init__(tool._run)
|
38
|
+
self.tool = tool
|
39
|
+
if tool.name:
|
40
|
+
self.name = tool.name
|
41
|
+
if tool.description:
|
42
|
+
self.description = tool.description
|
43
|
+
|
44
|
+
@model_validator(mode='before')
|
45
|
+
@classmethod
|
46
|
+
def populate_name(cls, data: Any) -> Any:
|
47
|
+
# Override this to not use function's signature name as it's
|
48
|
+
# mostly "run" or "invoke" for thir-party tools.
|
49
|
+
return data
|
50
|
+
|
51
|
+
@override
|
52
|
+
def _get_declaration(self) -> types.FunctionDeclaration:
|
53
|
+
"""Build the function declaration for the tool."""
|
54
|
+
from langchain.agents import Tool
|
55
|
+
from langchain_core.tools import BaseTool
|
56
|
+
|
57
|
+
# There are two types of tools:
|
58
|
+
# 1. BaseTool: the tool is defined in langchain.tools.
|
59
|
+
# 2. Other tools: the tool doesn't inherit any class but follow some
|
60
|
+
# conventions, like having a "run" method.
|
61
|
+
if isinstance(self.tool, BaseTool):
|
62
|
+
tool_wrapper = Tool(
|
63
|
+
name=self.name,
|
64
|
+
func=self.func,
|
65
|
+
description=self.description,
|
66
|
+
)
|
67
|
+
if self.tool.args_schema:
|
68
|
+
tool_wrapper.args_schema = self.tool.args_schema
|
69
|
+
function_declaration = _automatic_function_calling_util.build_function_declaration_for_langchain(
|
70
|
+
False,
|
71
|
+
self.name,
|
72
|
+
self.description,
|
73
|
+
tool_wrapper.func,
|
74
|
+
tool_wrapper.args,
|
75
|
+
)
|
76
|
+
return function_declaration
|
77
|
+
else:
|
78
|
+
# Need to provide a way to override the function names and descriptions
|
79
|
+
# as the original function names are mostly ".run" and the descriptions
|
80
|
+
# may not meet users' needs.
|
81
|
+
function_declaration = (
|
82
|
+
_automatic_function_calling_util.build_function_declaration(
|
83
|
+
func=self.tool.run,
|
84
|
+
)
|
85
|
+
)
|
86
|
+
return function_declaration
|