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,253 @@
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 json
16
+ from typing import Optional
17
+ from google.adk.tools.application_integration_tool.clients.connections_client import ConnectionsClient
18
+ import google.auth
19
+ from google.auth import default as default_service_credential
20
+ import google.auth.transport.requests
21
+ from google.auth.transport.requests import Request
22
+ from google.oauth2 import service_account
23
+ import requests
24
+
25
+
26
+ class IntegrationClient:
27
+ """A client for interacting with Google Cloud Application Integration.
28
+
29
+ This class provides methods for retrieving OpenAPI spec for an integration or
30
+ a connection.
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ project: str,
36
+ location: str,
37
+ integration: Optional[str] = None,
38
+ trigger: Optional[str] = None,
39
+ connection: Optional[str] = None,
40
+ entity_operations: Optional[dict[str, list[str]]] = None,
41
+ actions: Optional[list[str]] = None,
42
+ service_account_json: Optional[str] = None,
43
+ ):
44
+ """Initializes the ApplicationIntegrationClient.
45
+
46
+ Args:
47
+ project: The Google Cloud project ID.
48
+ location: The Google Cloud location (e.g., us-central1).
49
+ integration: The integration name.
50
+ trigger: The trigger ID for the integration.
51
+ connection: The connection name.
52
+ entity_operations: A dictionary mapping entity names to a list of
53
+ operations (e.g., LIST, CREATE, UPDATE, DELETE, GET).
54
+ actions: List of actions.
55
+ service_account_json: The service account configuration as a dictionary.
56
+ Required if not using default service credential. Used for fetching
57
+ connection details.
58
+ """
59
+ self.project = project
60
+ self.location = location
61
+ self.integration = integration
62
+ self.trigger = trigger
63
+ self.connection = connection
64
+ self.entity_operations = (
65
+ entity_operations if entity_operations is not None else {}
66
+ )
67
+ self.actions = actions if actions is not None else []
68
+ self.service_account_json = service_account_json
69
+ self.credential_cache = None
70
+
71
+ def get_openapi_spec_for_integration(self):
72
+ """Gets the OpenAPI spec for the integration.
73
+
74
+ Returns:
75
+ dict: The OpenAPI spec as a dictionary.
76
+ Raises:
77
+ PermissionError: If there are credential issues.
78
+ ValueError: If there's a request error or processing error.
79
+ Exception: For any other unexpected errors.
80
+ """
81
+ try:
82
+ url = f"https://{self.location}-integrations.googleapis.com/v1/projects/{self.project}/locations/{self.location}:generateOpenApiSpec"
83
+ headers = {
84
+ "Content-Type": "application/json",
85
+ "Authorization": f"Bearer {self._get_access_token()}",
86
+ }
87
+ data = {
88
+ "apiTriggerResources": [
89
+ {
90
+ "integrationResource": self.integration,
91
+ "triggerId": [self.trigger],
92
+ },
93
+ ],
94
+ "fileFormat": "JSON",
95
+ }
96
+ response = requests.post(url, headers=headers, json=data)
97
+ response.raise_for_status()
98
+ spec = response.json().get("openApiSpec", {})
99
+ return json.loads(spec)
100
+ except google.auth.exceptions.DefaultCredentialsError as e:
101
+ raise PermissionError(f"Credentials error: {e}") from e
102
+ except requests.exceptions.RequestException as e:
103
+ if (
104
+ "404" in str(e)
105
+ or "Not found" in str(e)
106
+ or "400" in str(e)
107
+ or "Bad request" in str(e)
108
+ ):
109
+ raise ValueError(
110
+ "Invalid request. Please check the provided values of"
111
+ f" project({self.project}), location({self.location}),"
112
+ f" integration({self.integration}) and trigger({self.trigger})."
113
+ ) from e
114
+ raise ValueError(f"Request error: {e}") from e
115
+ except Exception as e:
116
+ raise Exception(f"An unexpected error occurred: {e}") from e
117
+
118
+ def get_openapi_spec_for_connection(self, tool_name="", tool_instructions=""):
119
+ """Gets the OpenAPI spec for the connection.
120
+
121
+ Returns:
122
+ dict: The OpenAPI spec as a dictionary.
123
+ Raises:
124
+ ValueError: If there's an error retrieving the OpenAPI spec.
125
+ PermissionError: If there are credential issues.
126
+ Exception: For any other unexpected errors.
127
+ """
128
+ # Application Integration needs to be provisioned in the same region as connection and an integration with name "ExecuteConnection" and trigger "api_trigger/ExecuteConnection" should be created as per the documentation.
129
+ integration_name = "ExecuteConnection"
130
+ connections_client = ConnectionsClient(
131
+ self.project,
132
+ self.location,
133
+ self.connection,
134
+ self.service_account_json,
135
+ )
136
+ if not self.entity_operations and not self.actions:
137
+ raise ValueError(
138
+ "No entity operations or actions provided. Please provide at least"
139
+ " one of them."
140
+ )
141
+ connector_spec = connections_client.get_connector_base_spec()
142
+ for entity, operations in self.entity_operations.items():
143
+ schema, supported_operations = (
144
+ connections_client.get_entity_schema_and_operations(entity)
145
+ )
146
+ if not operations:
147
+ operations = supported_operations
148
+ json_schema_as_string = json.dumps(schema)
149
+ entity_lower = entity
150
+ connector_spec["components"]["schemas"][
151
+ f"connectorInputPayload_{entity_lower}"
152
+ ] = connections_client.connector_payload(schema)
153
+ for operation in operations:
154
+ operation_lower = operation.lower()
155
+ path = f"/v2/projects/{self.project}/locations/{self.location}/integrations/{integration_name}:execute?triggerId=api_trigger/{integration_name}#{operation_lower}_{entity_lower}"
156
+ if operation_lower == "create":
157
+ connector_spec["paths"][path] = connections_client.create_operation(
158
+ entity_lower, tool_name, tool_instructions
159
+ )
160
+ connector_spec["components"]["schemas"][
161
+ f"create_{entity_lower}_Request"
162
+ ] = connections_client.create_operation_request(entity_lower)
163
+ elif operation_lower == "update":
164
+ connector_spec["paths"][path] = connections_client.update_operation(
165
+ entity_lower, tool_name, tool_instructions
166
+ )
167
+ connector_spec["components"]["schemas"][
168
+ f"update_{entity_lower}_Request"
169
+ ] = connections_client.update_operation_request(entity_lower)
170
+ elif operation_lower == "delete":
171
+ connector_spec["paths"][path] = connections_client.delete_operation(
172
+ entity_lower, tool_name, tool_instructions
173
+ )
174
+ connector_spec["components"]["schemas"][
175
+ f"delete_{entity_lower}_Request"
176
+ ] = connections_client.delete_operation_request()
177
+ elif operation_lower == "list":
178
+ connector_spec["paths"][path] = connections_client.list_operation(
179
+ entity_lower, json_schema_as_string, tool_name, tool_instructions
180
+ )
181
+ connector_spec["components"]["schemas"][
182
+ f"list_{entity_lower}_Request"
183
+ ] = connections_client.list_operation_request()
184
+ elif operation_lower == "get":
185
+ connector_spec["paths"][path] = connections_client.get_operation(
186
+ entity_lower, json_schema_as_string, tool_name, tool_instructions
187
+ )
188
+ connector_spec["components"]["schemas"][
189
+ f"get_{entity_lower}_Request"
190
+ ] = connections_client.get_operation_request()
191
+ else:
192
+ raise ValueError(
193
+ f"Invalid operation: {operation} for entity: {entity}"
194
+ )
195
+ for action in self.actions:
196
+ action_details = connections_client.get_action_schema(action)
197
+ input_schema = action_details["inputSchema"]
198
+ output_schema = action_details["outputSchema"]
199
+ action_display_name = action_details["displayName"]
200
+ operation = "EXECUTE_ACTION"
201
+ if action == "ExecuteCustomQuery":
202
+ connector_spec["components"]["schemas"][
203
+ f"{action}_Request"
204
+ ] = connections_client.execute_custom_query_request()
205
+ operation = "EXECUTE_QUERY"
206
+ else:
207
+ connector_spec["components"]["schemas"][
208
+ f"{action_display_name}_Request"
209
+ ] = connections_client.action_request(action_display_name)
210
+ connector_spec["components"]["schemas"][
211
+ f"connectorInputPayload_{action_display_name}"
212
+ ] = connections_client.connector_payload(input_schema)
213
+ connector_spec["components"]["schemas"][
214
+ f"connectorOutputPayload_{action_display_name}"
215
+ ] = connections_client.connector_payload(output_schema)
216
+ connector_spec["components"]["schemas"][
217
+ f"{action_display_name}_Response"
218
+ ] = connections_client.action_response(action_display_name)
219
+ path = f"/v2/projects/{self.project}/locations/{self.location}/integrations/{integration_name}:execute?triggerId=api_trigger/{integration_name}#{action}"
220
+ connector_spec["paths"][path] = connections_client.get_action_operation(
221
+ action, operation, action_display_name, tool_name, tool_instructions
222
+ )
223
+ return connector_spec
224
+
225
+ def _get_access_token(self) -> str:
226
+ """Gets the access token for the service account or using default credentials.
227
+
228
+ Returns:
229
+ The access token.
230
+ """
231
+ if self.credential_cache and not self.credential_cache.expired:
232
+ return self.credential_cache.token
233
+
234
+ if self.service_account_json:
235
+ credentials = service_account.Credentials.from_service_account_info(
236
+ json.loads(self.service_account_json),
237
+ scopes=["https://www.googleapis.com/auth/cloud-platform"],
238
+ )
239
+ else:
240
+ try:
241
+ credentials, _ = default_service_credential()
242
+ except:
243
+ credentials = None
244
+
245
+ if not credentials:
246
+ raise ValueError(
247
+ "Please provide a service account that has the required permissions"
248
+ " to access the connection."
249
+ )
250
+
251
+ credentials.refresh(Request())
252
+ self.credential_cache = credentials
253
+ return credentials.token
@@ -0,0 +1,144 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ from abc import ABC
18
+ import os
19
+ from typing import Any
20
+ from typing import Optional
21
+ from typing import TYPE_CHECKING
22
+
23
+ from deprecated import deprecated
24
+ from google.genai import types
25
+
26
+ from .tool_context import ToolContext
27
+
28
+ if TYPE_CHECKING:
29
+ from ..models.llm_request import LlmRequest
30
+
31
+
32
+ class BaseTool(ABC):
33
+ """The base class for all tools."""
34
+
35
+ name: str
36
+ """The name of the tool."""
37
+ description: str
38
+ """The description of the tool."""
39
+
40
+ is_long_running: bool = False
41
+ """Whether the tool is a long running operation, which typically returns a
42
+ resource id first and finishes the operation later."""
43
+
44
+ def __init__(self, *, name, description, is_long_running: bool = False):
45
+ self.name = name
46
+ self.description = description
47
+ self.is_long_running = is_long_running
48
+
49
+ def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
50
+ """Gets the OpenAPI specification of this tool in the form of a FunctionDeclaration.
51
+
52
+ NOTE
53
+ - Required if subclass uses the default implementation of
54
+ `process_llm_request` to add function declaration to LLM request.
55
+ - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for
56
+ Gemini.
57
+
58
+ Returns:
59
+ The FunctionDeclaration of this tool, or None if it doesn't need to be
60
+ added to LlmRequest.config.
61
+ """
62
+ return None
63
+
64
+ async def run_async(
65
+ self, *, args: dict[str, Any], tool_context: ToolContext
66
+ ) -> Any:
67
+ """Runs the tool with the given arguments and context.
68
+
69
+ NOTE
70
+ - Required if this tool needs to run at the client side.
71
+ - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for
72
+ Gemini.
73
+
74
+ Args:
75
+ args: The LLM-filled arguments.
76
+ ctx: The context of the tool.
77
+
78
+ Returns:
79
+ The result of running the tool.
80
+ """
81
+ raise NotImplementedError(f'{type(self)} is not implemented')
82
+
83
+ async def process_llm_request(
84
+ self, *, tool_context: ToolContext, llm_request: LlmRequest
85
+ ) -> None:
86
+ """Processes the outgoing LLM request for this tool.
87
+
88
+ Use cases:
89
+ - Most common use case is adding this tool to the LLM request.
90
+ - Some tools may just preprocess the LLM request before it's sent out.
91
+
92
+ Args:
93
+ tool_context: The context of the tool.
94
+ llm_request: The outgoing LLM request, mutable this method.
95
+ """
96
+ if (function_declaration := self._get_declaration()) is None:
97
+ return
98
+
99
+ llm_request.tools_dict[self.name] = self
100
+ if tool_with_function_declarations := _find_tool_with_function_declarations(
101
+ llm_request
102
+ ):
103
+ if tool_with_function_declarations.function_declarations is None:
104
+ tool_with_function_declarations.function_declarations = []
105
+ tool_with_function_declarations.function_declarations.append(
106
+ function_declaration
107
+ )
108
+ else:
109
+ llm_request.config = (
110
+ types.GenerateContentConfig()
111
+ if not llm_request.config
112
+ else llm_request.config
113
+ )
114
+ llm_request.config.tools = (
115
+ [] if not llm_request.config.tools else llm_request.config.tools
116
+ )
117
+ llm_request.config.tools.append(
118
+ types.Tool(function_declarations=[function_declaration])
119
+ )
120
+
121
+ @property
122
+ def _api_variant(self) -> str:
123
+ use_vertexai = os.environ.get('GOOGLE_GENAI_USE_VERTEXAI', '0').lower() in [
124
+ 'true',
125
+ '1',
126
+ ]
127
+ return 'VERTEX_AI' if use_vertexai else 'GOOGLE_AI'
128
+
129
+
130
+ def _find_tool_with_function_declarations(
131
+ llm_request: LlmRequest,
132
+ ) -> Optional[types.Tool]:
133
+ # TODO: add individual tool with declaration and merge in google_llm.py
134
+ if not llm_request.config or not llm_request.config.tools:
135
+ return None
136
+
137
+ return next(
138
+ (
139
+ tool
140
+ for tool in llm_request.config.tools
141
+ if isinstance(tool, types.Tool) and tool.function_declarations
142
+ ),
143
+ None,
144
+ )
@@ -0,0 +1,59 @@
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 BuiltInCodeExecutionTool(BaseTool):
30
+ """A built-in code execution tool that is automatically invoked by Gemini 2 models.
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='code_execution', description='code_execution')
39
+
40
+ @override
41
+ async def process_llm_request(
42
+ self,
43
+ *,
44
+ tool_context: ToolContext,
45
+ llm_request: LlmRequest,
46
+ ) -> None:
47
+ if llm_request.model and llm_request.model.startswith('gemini-2'):
48
+ llm_request.config = llm_request.config or types.GenerateContentConfig()
49
+ llm_request.config.tools = llm_request.config.tools or []
50
+ llm_request.config.tools.append(
51
+ types.Tool(code_execution=types.ToolCodeExecution())
52
+ )
53
+ else:
54
+ raise ValueError(
55
+ f'Code execution tool is not supported for model {llm_request.model}'
56
+ )
57
+
58
+
59
+ built_in_code_execution = BuiltInCodeExecutionTool()
@@ -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
+ from __future__ import annotations
16
+
17
+ from google.genai import types
18
+ from typing_extensions import override
19
+
20
+ from . import _automatic_function_calling_util
21
+ from .function_tool import FunctionTool
22
+
23
+ try:
24
+ from crewai.tools import BaseTool as CrewaiBaseTool
25
+ except ImportError as e:
26
+ import sys
27
+
28
+ if sys.version_info < (3, 10):
29
+ raise ImportError(
30
+ "Crewai Tools require Python 3.10+. Please upgrade your Python version."
31
+ ) from e
32
+ else:
33
+ raise ImportError(
34
+ "Crewai Tools require pip install 'google-adk[extensions]'."
35
+ ) from e
36
+
37
+
38
+ class CrewaiTool(FunctionTool):
39
+ """Use this class to wrap a CrewAI tool.
40
+
41
+ If the original tool name and description are not suitable, you can override
42
+ them in the constructor.
43
+ """
44
+
45
+ tool: CrewaiBaseTool
46
+ """The wrapped CrewAI tool."""
47
+
48
+ def __init__(self, tool: CrewaiBaseTool, *, name: str, description: str):
49
+ super().__init__(tool.run)
50
+ self.tool = tool
51
+ if name:
52
+ self.name = name
53
+ elif tool.name:
54
+ # Right now, CrewAI tool name contains white spaces. White spaces are
55
+ # not supported in our framework. So we replace them with "_".
56
+ self.name = tool.name.replace(" ", "_").lower()
57
+ if description:
58
+ self.description = description
59
+ elif tool.description:
60
+ self.description = tool.description
61
+
62
+ @override
63
+ def _get_declaration(self) -> types.FunctionDeclaration:
64
+ """Build the function declaration for the tool."""
65
+ function_declaration = _automatic_function_calling_util.build_function_declaration_for_params_for_crewai(
66
+ False,
67
+ self.name,
68
+ self.description,
69
+ self.func,
70
+ self.tool.args_schema.model_json_schema(),
71
+ )
72
+ return function_declaration
@@ -0,0 +1,62 @@
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
+ from typing import Union
19
+
20
+ from pydantic import TypeAdapter
21
+ from typing_extensions import override
22
+
23
+ from ..examples import example_util
24
+ from ..examples.base_example_provider import BaseExampleProvider
25
+ from ..examples.example import Example
26
+ from .base_tool import BaseTool
27
+ from .tool_context import ToolContext
28
+
29
+ if TYPE_CHECKING:
30
+ from ..models.llm_request import LlmRequest
31
+
32
+
33
+ class ExampleTool(BaseTool):
34
+ """A tool that adds (few-shot) examples to the LLM request.
35
+
36
+ Attributes:
37
+ examples: The examples to add to the LLM request.
38
+ """
39
+
40
+ def __init__(self, examples: Union[list[Example], BaseExampleProvider]):
41
+ # Name and description are not used because this tool only changes
42
+ # llm_request.
43
+ super().__init__(name='example_tool', description='example tool')
44
+ self.examples = (
45
+ TypeAdapter(list[Example]).validate_python(examples)
46
+ if isinstance(examples, list)
47
+ else examples
48
+ )
49
+
50
+ @override
51
+ async def process_llm_request(
52
+ self, *, tool_context: ToolContext, llm_request: LlmRequest
53
+ ) -> None:
54
+ parts = tool_context.user_content.parts
55
+ if not parts or not parts[0].text:
56
+ return
57
+
58
+ llm_request.append_instructions([
59
+ example_util.build_example_si(
60
+ self.examples, parts[0].text, llm_request.model
61
+ )
62
+ ])
@@ -0,0 +1,23 @@
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 .tool_context import ToolContext
16
+
17
+
18
+ def exit_loop(tool_context: ToolContext):
19
+ """Exits the loop.
20
+
21
+ Call this function only when you are instructed to do so.
22
+ """
23
+ tool_context.actions.escalate = True