google-adk 0.0.1__py3-none-any.whl → 0.0.2__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.
Files changed (312) hide show
  1. google/adk/__init__.py +20 -0
  2. google/adk/agents/__init__.py +32 -0
  3. google/adk/agents/active_streaming_tool.py +38 -0
  4. google/adk/agents/base_agent.py +345 -0
  5. google/adk/agents/callback_context.py +112 -0
  6. google/adk/agents/invocation_context.py +181 -0
  7. google/adk/agents/langgraph_agent.py +140 -0
  8. google/adk/agents/live_request_queue.py +64 -0
  9. google/adk/agents/llm_agent.py +376 -0
  10. google/adk/agents/loop_agent.py +62 -0
  11. google/adk/agents/parallel_agent.py +96 -0
  12. google/adk/agents/readonly_context.py +46 -0
  13. google/adk/agents/remote_agent.py +50 -0
  14. google/adk/agents/run_config.py +87 -0
  15. google/adk/agents/sequential_agent.py +45 -0
  16. google/adk/agents/transcription_entry.py +34 -0
  17. google/adk/artifacts/__init__.py +23 -0
  18. google/adk/artifacts/base_artifact_service.py +128 -0
  19. google/adk/artifacts/gcs_artifact_service.py +195 -0
  20. google/adk/artifacts/in_memory_artifact_service.py +133 -0
  21. google/adk/auth/__init__.py +22 -0
  22. google/adk/auth/auth_credential.py +220 -0
  23. google/adk/auth/auth_handler.py +268 -0
  24. google/adk/auth/auth_preprocessor.py +116 -0
  25. google/adk/auth/auth_schemes.py +67 -0
  26. google/adk/auth/auth_tool.py +55 -0
  27. google/adk/cli/__init__.py +15 -0
  28. google/adk/cli/__main__.py +18 -0
  29. google/adk/cli/agent_graph.py +122 -0
  30. google/adk/cli/browser/adk_favicon.svg +17 -0
  31. google/adk/cli/browser/assets/audio-processor.js +51 -0
  32. google/adk/cli/browser/assets/config/runtime-config.json +3 -0
  33. google/adk/cli/browser/index.html +33 -0
  34. google/adk/cli/browser/main-XUU6OGCC.js +75 -0
  35. google/adk/cli/browser/polyfills-FFHMD2TL.js +18 -0
  36. google/adk/cli/browser/styles-4VDSPQ37.css +17 -0
  37. google/adk/cli/cli.py +181 -0
  38. google/adk/cli/cli_deploy.py +181 -0
  39. google/adk/cli/cli_eval.py +282 -0
  40. google/adk/cli/cli_tools_click.py +479 -0
  41. google/adk/cli/fast_api.py +774 -0
  42. google/adk/cli/media_streamer/__init__.py +19 -0
  43. google/adk/cli/media_streamer/index.html +228 -0
  44. google/adk/cli/utils/__init__.py +49 -0
  45. google/adk/cli/utils/envs.py +57 -0
  46. google/adk/cli/utils/evals.py +93 -0
  47. google/adk/cli/utils/logs.py +72 -0
  48. google/adk/code_executors/__init__.py +49 -0
  49. google/adk/code_executors/base_code_executor.py +97 -0
  50. google/adk/code_executors/code_execution_utils.py +256 -0
  51. google/adk/code_executors/code_executor_context.py +202 -0
  52. google/adk/code_executors/container_code_executor.py +196 -0
  53. google/adk/code_executors/unsafe_local_code_executor.py +71 -0
  54. google/adk/code_executors/vertex_ai_code_executor.py +234 -0
  55. google/adk/evaluation/__init__.py +31 -0
  56. google/adk/evaluation/agent_evaluator.py +329 -0
  57. google/adk/evaluation/evaluation_constants.py +24 -0
  58. google/adk/evaluation/evaluation_generator.py +270 -0
  59. google/adk/evaluation/response_evaluator.py +135 -0
  60. google/adk/evaluation/trajectory_evaluator.py +184 -0
  61. google/adk/events/__init__.py +21 -0
  62. google/adk/events/event.py +130 -0
  63. google/adk/events/event_actions.py +55 -0
  64. google/adk/examples/__init__.py +28 -0
  65. google/adk/examples/base_example_provider.py +35 -0
  66. google/adk/examples/example.py +27 -0
  67. google/adk/examples/example_util.py +123 -0
  68. google/adk/examples/vertex_ai_example_store.py +104 -0
  69. google/adk/flows/__init__.py +14 -0
  70. google/adk/flows/llm_flows/__init__.py +20 -0
  71. google/adk/flows/llm_flows/_base_llm_processor.py +52 -0
  72. google/adk/flows/llm_flows/_code_execution.py +458 -0
  73. google/adk/flows/llm_flows/_nl_planning.py +129 -0
  74. google/adk/flows/llm_flows/agent_transfer.py +132 -0
  75. google/adk/flows/llm_flows/audio_transcriber.py +109 -0
  76. google/adk/flows/llm_flows/auto_flow.py +49 -0
  77. google/adk/flows/llm_flows/base_llm_flow.py +559 -0
  78. google/adk/flows/llm_flows/basic.py +72 -0
  79. google/adk/flows/llm_flows/contents.py +370 -0
  80. google/adk/flows/llm_flows/functions.py +486 -0
  81. google/adk/flows/llm_flows/identity.py +47 -0
  82. google/adk/flows/llm_flows/instructions.py +137 -0
  83. google/adk/flows/llm_flows/single_flow.py +57 -0
  84. google/adk/memory/__init__.py +35 -0
  85. google/adk/memory/base_memory_service.py +74 -0
  86. google/adk/memory/in_memory_memory_service.py +62 -0
  87. google/adk/memory/vertex_ai_rag_memory_service.py +177 -0
  88. google/adk/models/__init__.py +31 -0
  89. google/adk/models/anthropic_llm.py +243 -0
  90. google/adk/models/base_llm.py +87 -0
  91. google/adk/models/base_llm_connection.py +76 -0
  92. google/adk/models/gemini_llm_connection.py +200 -0
  93. google/adk/models/google_llm.py +331 -0
  94. google/adk/models/lite_llm.py +673 -0
  95. google/adk/models/llm_request.py +98 -0
  96. google/adk/models/llm_response.py +111 -0
  97. google/adk/models/registry.py +102 -0
  98. google/adk/planners/__init__.py +23 -0
  99. google/adk/planners/base_planner.py +66 -0
  100. google/adk/planners/built_in_planner.py +75 -0
  101. google/adk/planners/plan_re_act_planner.py +208 -0
  102. google/adk/runners.py +456 -0
  103. google/adk/sessions/__init__.py +41 -0
  104. google/adk/sessions/base_session_service.py +133 -0
  105. google/adk/sessions/database_session_service.py +522 -0
  106. google/adk/sessions/in_memory_session_service.py +206 -0
  107. google/adk/sessions/session.py +54 -0
  108. google/adk/sessions/state.py +71 -0
  109. google/adk/sessions/vertex_ai_session_service.py +356 -0
  110. google/adk/telemetry.py +189 -0
  111. google/adk/tests/__init__.py +14 -0
  112. google/adk/tests/integration/.env.example +10 -0
  113. google/adk/tests/integration/__init__.py +18 -0
  114. google/adk/tests/integration/conftest.py +119 -0
  115. google/adk/tests/integration/fixture/__init__.py +14 -0
  116. google/adk/tests/integration/fixture/agent_with_config/__init__.py +15 -0
  117. google/adk/tests/integration/fixture/agent_with_config/agent.py +88 -0
  118. google/adk/tests/integration/fixture/callback_agent/__init__.py +15 -0
  119. google/adk/tests/integration/fixture/callback_agent/agent.py +105 -0
  120. google/adk/tests/integration/fixture/context_update_test/OWNERS +1 -0
  121. google/adk/tests/integration/fixture/context_update_test/__init__.py +15 -0
  122. google/adk/tests/integration/fixture/context_update_test/agent.py +43 -0
  123. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +582 -0
  124. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +15 -0
  125. google/adk/tests/integration/fixture/context_variable_agent/agent.py +115 -0
  126. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +15 -0
  127. google/adk/tests/integration/fixture/customer_support_ma/agent.py +172 -0
  128. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +15 -0
  129. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +338 -0
  130. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +69 -0
  131. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +6 -0
  132. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +15 -0
  133. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +182 -0
  134. google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +243 -0
  135. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +190 -0
  136. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +15 -0
  137. google/adk/tests/integration/fixture/hello_world_agent/agent.py +95 -0
  138. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +24 -0
  139. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +6 -0
  140. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +15 -0
  141. google/adk/tests/integration/fixture/home_automation_agent/agent.py +304 -0
  142. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +5 -0
  143. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +5 -0
  144. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +5 -0
  145. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +18 -0
  146. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +17 -0
  147. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +6 -0
  148. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +18 -0
  149. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +17 -0
  150. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +5 -0
  151. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +5 -0
  152. google/adk/tests/integration/fixture/tool_agent/__init__.py +15 -0
  153. google/adk/tests/integration/fixture/tool_agent/agent.py +218 -0
  154. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  155. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +15 -0
  156. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +110 -0
  157. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +13 -0
  158. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +5 -0
  159. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +13 -0
  160. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +5 -0
  161. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +7 -0
  162. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +19 -0
  163. google/adk/tests/integration/models/__init__.py +14 -0
  164. google/adk/tests/integration/models/test_google_llm.py +65 -0
  165. google/adk/tests/integration/test_callback.py +70 -0
  166. google/adk/tests/integration/test_context_variable.py +67 -0
  167. google/adk/tests/integration/test_evalute_agent_in_fixture.py +76 -0
  168. google/adk/tests/integration/test_multi_agent.py +28 -0
  169. google/adk/tests/integration/test_multi_turn.py +42 -0
  170. google/adk/tests/integration/test_single_agent.py +23 -0
  171. google/adk/tests/integration/test_sub_agent.py +26 -0
  172. google/adk/tests/integration/test_system_instruction.py +177 -0
  173. google/adk/tests/integration/test_tools.py +287 -0
  174. google/adk/tests/integration/test_with_test_file.py +34 -0
  175. google/adk/tests/integration/tools/__init__.py +14 -0
  176. google/adk/tests/integration/utils/__init__.py +16 -0
  177. google/adk/tests/integration/utils/asserts.py +75 -0
  178. google/adk/tests/integration/utils/test_runner.py +97 -0
  179. google/adk/tests/unittests/__init__.py +14 -0
  180. google/adk/tests/unittests/agents/__init__.py +14 -0
  181. google/adk/tests/unittests/agents/test_base_agent.py +407 -0
  182. google/adk/tests/unittests/agents/test_langgraph_agent.py +191 -0
  183. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +138 -0
  184. google/adk/tests/unittests/agents/test_llm_agent_fields.py +231 -0
  185. google/adk/tests/unittests/agents/test_loop_agent.py +136 -0
  186. google/adk/tests/unittests/agents/test_parallel_agent.py +92 -0
  187. google/adk/tests/unittests/agents/test_sequential_agent.py +114 -0
  188. google/adk/tests/unittests/artifacts/__init__.py +14 -0
  189. google/adk/tests/unittests/artifacts/test_artifact_service.py +276 -0
  190. google/adk/tests/unittests/auth/test_auth_handler.py +575 -0
  191. google/adk/tests/unittests/conftest.py +73 -0
  192. google/adk/tests/unittests/fast_api/__init__.py +14 -0
  193. google/adk/tests/unittests/fast_api/test_fast_api.py +269 -0
  194. google/adk/tests/unittests/flows/__init__.py +14 -0
  195. google/adk/tests/unittests/flows/llm_flows/__init__.py +14 -0
  196. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +142 -0
  197. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +311 -0
  198. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +244 -0
  199. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +346 -0
  200. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +93 -0
  201. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +258 -0
  202. google/adk/tests/unittests/flows/llm_flows/test_identity.py +66 -0
  203. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +164 -0
  204. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +142 -0
  205. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +46 -0
  206. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +269 -0
  207. google/adk/tests/unittests/models/__init__.py +14 -0
  208. google/adk/tests/unittests/models/test_google_llm.py +224 -0
  209. google/adk/tests/unittests/models/test_litellm.py +804 -0
  210. google/adk/tests/unittests/models/test_models.py +60 -0
  211. google/adk/tests/unittests/sessions/__init__.py +14 -0
  212. google/adk/tests/unittests/sessions/test_session_service.py +227 -0
  213. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +246 -0
  214. google/adk/tests/unittests/streaming/__init__.py +14 -0
  215. google/adk/tests/unittests/streaming/test_streaming.py +50 -0
  216. google/adk/tests/unittests/tools/__init__.py +14 -0
  217. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +499 -0
  218. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +204 -0
  219. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +600 -0
  220. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +630 -0
  221. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +345 -0
  222. google/adk/tests/unittests/tools/google_api_tool/__init__.py +13 -0
  223. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +657 -0
  224. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +145 -0
  225. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +68 -0
  226. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +153 -0
  227. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +196 -0
  228. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +573 -0
  229. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +436 -0
  230. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +1367 -0
  231. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +628 -0
  232. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +139 -0
  233. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +406 -0
  234. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +966 -0
  235. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +201 -0
  236. google/adk/tests/unittests/tools/retrieval/__init__.py +14 -0
  237. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +147 -0
  238. google/adk/tests/unittests/tools/test_agent_tool.py +167 -0
  239. google/adk/tests/unittests/tools/test_base_tool.py +141 -0
  240. google/adk/tests/unittests/tools/test_build_function_declaration.py +277 -0
  241. google/adk/tests/unittests/utils.py +304 -0
  242. google/adk/tools/__init__.py +51 -0
  243. google/adk/tools/_automatic_function_calling_util.py +346 -0
  244. google/adk/tools/agent_tool.py +176 -0
  245. google/adk/tools/apihub_tool/__init__.py +19 -0
  246. google/adk/tools/apihub_tool/apihub_toolset.py +209 -0
  247. google/adk/tools/apihub_tool/clients/__init__.py +13 -0
  248. google/adk/tools/apihub_tool/clients/apihub_client.py +332 -0
  249. google/adk/tools/apihub_tool/clients/secret_client.py +115 -0
  250. google/adk/tools/application_integration_tool/__init__.py +19 -0
  251. google/adk/tools/application_integration_tool/application_integration_toolset.py +230 -0
  252. google/adk/tools/application_integration_tool/clients/connections_client.py +903 -0
  253. google/adk/tools/application_integration_tool/clients/integration_client.py +253 -0
  254. google/adk/tools/base_tool.py +144 -0
  255. google/adk/tools/built_in_code_execution_tool.py +59 -0
  256. google/adk/tools/crewai_tool.py +72 -0
  257. google/adk/tools/example_tool.py +62 -0
  258. google/adk/tools/exit_loop_tool.py +23 -0
  259. google/adk/tools/function_parameter_parse_util.py +307 -0
  260. google/adk/tools/function_tool.py +87 -0
  261. google/adk/tools/get_user_choice_tool.py +28 -0
  262. google/adk/tools/google_api_tool/__init__.py +14 -0
  263. google/adk/tools/google_api_tool/google_api_tool.py +59 -0
  264. google/adk/tools/google_api_tool/google_api_tool_set.py +107 -0
  265. google/adk/tools/google_api_tool/google_api_tool_sets.py +55 -0
  266. google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +521 -0
  267. google/adk/tools/google_search_tool.py +68 -0
  268. google/adk/tools/langchain_tool.py +86 -0
  269. google/adk/tools/load_artifacts_tool.py +113 -0
  270. google/adk/tools/load_memory_tool.py +58 -0
  271. google/adk/tools/load_web_page.py +41 -0
  272. google/adk/tools/long_running_tool.py +39 -0
  273. google/adk/tools/mcp_tool/__init__.py +42 -0
  274. google/adk/tools/mcp_tool/conversion_utils.py +161 -0
  275. google/adk/tools/mcp_tool/mcp_tool.py +113 -0
  276. google/adk/tools/mcp_tool/mcp_toolset.py +272 -0
  277. google/adk/tools/openapi_tool/__init__.py +21 -0
  278. google/adk/tools/openapi_tool/auth/__init__.py +19 -0
  279. google/adk/tools/openapi_tool/auth/auth_helpers.py +498 -0
  280. google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +25 -0
  281. google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +105 -0
  282. google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +55 -0
  283. google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +117 -0
  284. google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +97 -0
  285. google/adk/tools/openapi_tool/common/__init__.py +19 -0
  286. google/adk/tools/openapi_tool/common/common.py +300 -0
  287. google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +32 -0
  288. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +231 -0
  289. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +144 -0
  290. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +260 -0
  291. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +496 -0
  292. google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +268 -0
  293. google/adk/tools/preload_memory_tool.py +72 -0
  294. google/adk/tools/retrieval/__init__.py +36 -0
  295. google/adk/tools/retrieval/base_retrieval_tool.py +37 -0
  296. google/adk/tools/retrieval/files_retrieval.py +33 -0
  297. google/adk/tools/retrieval/llama_index_retrieval.py +41 -0
  298. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +107 -0
  299. google/adk/tools/tool_context.py +90 -0
  300. google/adk/tools/toolbox_tool.py +46 -0
  301. google/adk/tools/transfer_to_agent_tool.py +21 -0
  302. google/adk/tools/vertex_ai_search_tool.py +96 -0
  303. google/adk/version.py +16 -0
  304. google_adk-0.0.1.dist-info/LICENSE.txt → google_adk-0.0.2.dist-info/LICENSE +32 -0
  305. google_adk-0.0.2.dist-info/METADATA +73 -0
  306. google_adk-0.0.2.dist-info/RECORD +308 -0
  307. {google_adk-0.0.1.dist-info → google_adk-0.0.2.dist-info}/WHEEL +1 -2
  308. google_adk-0.0.2.dist-info/entry_points.txt +3 -0
  309. agent_kit/__init__.py +0 -0
  310. google_adk-0.0.1.dist-info/METADATA +0 -15
  311. google_adk-0.0.1.dist-info/RECORD +0 -6
  312. 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