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.
Files changed (345) hide show
  1. google/adk/._version.py +0 -0
  2. google/adk/__init__.py +20 -0
  3. google/adk/agents/__init__.py +32 -0
  4. google/adk/agents/active_streaming_tool.py +38 -0
  5. google/adk/agents/base_agent.py +345 -0
  6. google/adk/agents/callback_context.py +112 -0
  7. google/adk/agents/invocation_context.py +181 -0
  8. google/adk/agents/langgraph_agent.py +140 -0
  9. google/adk/agents/live_request_queue.py +64 -0
  10. google/adk/agents/llm_agent.py +376 -0
  11. google/adk/agents/loop_agent.py +62 -0
  12. google/adk/agents/parallel_agent.py +96 -0
  13. google/adk/agents/readonly_context.py +46 -0
  14. google/adk/agents/remote_agent.py +50 -0
  15. google/adk/agents/run_config.py +87 -0
  16. google/adk/agents/sequential_agent.py +45 -0
  17. google/adk/agents/transcription_entry.py +34 -0
  18. google/adk/artifacts/__init__.py +23 -0
  19. google/adk/artifacts/base_artifact_service.py +128 -0
  20. google/adk/artifacts/gcs_artifact_service.py +195 -0
  21. google/adk/artifacts/in_memory_artifact_service.py +133 -0
  22. google/adk/auth/__init__.py +22 -0
  23. google/adk/auth/auth_credential.py +220 -0
  24. google/adk/auth/auth_handler.py +268 -0
  25. google/adk/auth/auth_preprocessor.py +116 -0
  26. google/adk/auth/auth_schemes.py +67 -0
  27. google/adk/auth/auth_tool.py +55 -0
  28. google/adk/cli/__init__.py +15 -0
  29. google/adk/cli/__main__.py +18 -0
  30. google/adk/cli/agent_graph.py +148 -0
  31. google/adk/cli/browser/adk_favicon.svg +17 -0
  32. google/adk/cli/browser/assets/audio-processor.js +51 -0
  33. google/adk/cli/browser/assets/config/runtime-config.json +3 -0
  34. google/adk/cli/browser/index.html +33 -0
  35. google/adk/cli/browser/main-SY2WYYGV.js +75 -0
  36. google/adk/cli/browser/polyfills-FFHMD2TL.js +18 -0
  37. google/adk/cli/browser/styles-4VDSPQ37.css +17 -0
  38. google/adk/cli/cli.py +181 -0
  39. google/adk/cli/cli_deploy.py +181 -0
  40. google/adk/cli/cli_eval.py +282 -0
  41. google/adk/cli/cli_tools_click.py +524 -0
  42. google/adk/cli/fast_api.py +784 -0
  43. google/adk/cli/utils/__init__.py +49 -0
  44. google/adk/cli/utils/envs.py +57 -0
  45. google/adk/cli/utils/evals.py +93 -0
  46. google/adk/cli/utils/logs.py +72 -0
  47. google/adk/code_executors/__init__.py +49 -0
  48. google/adk/code_executors/base_code_executor.py +97 -0
  49. google/adk/code_executors/code_execution_utils.py +256 -0
  50. google/adk/code_executors/code_executor_context.py +202 -0
  51. google/adk/code_executors/container_code_executor.py +196 -0
  52. google/adk/code_executors/unsafe_local_code_executor.py +71 -0
  53. google/adk/code_executors/vertex_ai_code_executor.py +234 -0
  54. google/adk/docs/Makefile +20 -0
  55. google/adk/docs/build/doctrees/google-adk.doctree +0 -0
  56. google/adk/docs/build/html/_sources/google-adk.rst.txt +98 -0
  57. google/adk/docs/build/html/_sources/index.rst.txt +7 -0
  58. google/adk/docs/build/html/_static/autodoc_pydantic.css +27 -0
  59. google/adk/docs/build/html/_static/basic.css +925 -0
  60. google/adk/docs/build/html/_static/debug.css +85 -0
  61. google/adk/docs/build/html/_static/doctools.js +156 -0
  62. google/adk/docs/build/html/_static/documentation_options.js +29 -0
  63. google/adk/docs/build/html/_static/file.png +0 -0
  64. google/adk/docs/build/html/_static/language_data.js +199 -0
  65. google/adk/docs/build/html/_static/minus.png +0 -0
  66. google/adk/docs/build/html/_static/plus.png +0 -0
  67. google/adk/docs/build/html/_static/pygments.css +274 -0
  68. google/adk/docs/build/html/_static/scripts/furo-extensions.js +16 -0
  69. google/adk/docs/build/html/_static/scripts/furo.js +19 -0
  70. google/adk/docs/build/html/_static/scripts/furo.js.LICENSE.txt +7 -0
  71. google/adk/docs/build/html/_static/scripts/furo.js.map +1 -0
  72. google/adk/docs/build/html/_static/searchtools.js +620 -0
  73. google/adk/docs/build/html/_static/skeleton.css +312 -0
  74. google/adk/docs/build/html/_static/sphinx_highlight.js +170 -0
  75. google/adk/docs/build/html/_static/styles/furo-extensions.css +18 -0
  76. google/adk/docs/build/html/_static/styles/furo-extensions.css.map +1 -0
  77. google/adk/docs/build/html/_static/styles/furo.css +18 -0
  78. google/adk/docs/build/html/_static/styles/furo.css.map +1 -0
  79. google/adk/docs/build/html/genindex.html +861 -0
  80. google/adk/docs/build/html/google-adk.html +5461 -0
  81. google/adk/docs/build/html/index.html +567 -0
  82. google/adk/docs/build/html/objects.inv +0 -0
  83. google/adk/docs/build/html/py-modindex.html +373 -0
  84. google/adk/docs/build/html/search.html +333 -0
  85. google/adk/docs/build/html/searchindex.js +17 -0
  86. google/adk/docs/source/conf.py +133 -0
  87. google/adk/docs/source/google-adk.rst +98 -0
  88. google/adk/docs/source/index.rst +7 -0
  89. google/adk/evaluation/__init__.py +31 -0
  90. google/adk/evaluation/agent_evaluator.py +329 -0
  91. google/adk/evaluation/evaluation_constants.py +24 -0
  92. google/adk/evaluation/evaluation_generator.py +270 -0
  93. google/adk/evaluation/response_evaluator.py +135 -0
  94. google/adk/evaluation/trajectory_evaluator.py +184 -0
  95. google/adk/events/__init__.py +21 -0
  96. google/adk/events/event.py +130 -0
  97. google/adk/events/event_actions.py +55 -0
  98. google/adk/examples/__init__.py +28 -0
  99. google/adk/examples/base_example_provider.py +35 -0
  100. google/adk/examples/example.py +27 -0
  101. google/adk/examples/example_util.py +123 -0
  102. google/adk/examples/vertex_ai_example_store.py +104 -0
  103. google/adk/flows/__init__.py +14 -0
  104. google/adk/flows/llm_flows/__init__.py +20 -0
  105. google/adk/flows/llm_flows/_base_llm_processor.py +52 -0
  106. google/adk/flows/llm_flows/_code_execution.py +458 -0
  107. google/adk/flows/llm_flows/_nl_planning.py +129 -0
  108. google/adk/flows/llm_flows/agent_transfer.py +132 -0
  109. google/adk/flows/llm_flows/audio_transcriber.py +109 -0
  110. google/adk/flows/llm_flows/auto_flow.py +49 -0
  111. google/adk/flows/llm_flows/base_llm_flow.py +559 -0
  112. google/adk/flows/llm_flows/basic.py +72 -0
  113. google/adk/flows/llm_flows/contents.py +370 -0
  114. google/adk/flows/llm_flows/functions.py +486 -0
  115. google/adk/flows/llm_flows/identity.py +47 -0
  116. google/adk/flows/llm_flows/instructions.py +137 -0
  117. google/adk/flows/llm_flows/single_flow.py +57 -0
  118. google/adk/memory/__init__.py +35 -0
  119. google/adk/memory/base_memory_service.py +74 -0
  120. google/adk/memory/in_memory_memory_service.py +62 -0
  121. google/adk/memory/vertex_ai_rag_memory_service.py +177 -0
  122. google/adk/models/__init__.py +31 -0
  123. google/adk/models/anthropic_llm.py +243 -0
  124. google/adk/models/base_llm.py +87 -0
  125. google/adk/models/base_llm_connection.py +76 -0
  126. google/adk/models/gemini_llm_connection.py +200 -0
  127. google/adk/models/google_llm.py +331 -0
  128. google/adk/models/lite_llm.py +673 -0
  129. google/adk/models/llm_request.py +98 -0
  130. google/adk/models/llm_response.py +111 -0
  131. google/adk/models/registry.py +102 -0
  132. google/adk/planners/__init__.py +23 -0
  133. google/adk/planners/base_planner.py +66 -0
  134. google/adk/planners/built_in_planner.py +75 -0
  135. google/adk/planners/plan_re_act_planner.py +208 -0
  136. google/adk/runners.py +456 -0
  137. google/adk/sessions/__init__.py +41 -0
  138. google/adk/sessions/base_session_service.py +133 -0
  139. google/adk/sessions/database_session_service.py +522 -0
  140. google/adk/sessions/in_memory_session_service.py +206 -0
  141. google/adk/sessions/session.py +54 -0
  142. google/adk/sessions/state.py +71 -0
  143. google/adk/sessions/vertex_ai_session_service.py +356 -0
  144. google/adk/telemetry.py +189 -0
  145. google/adk/tests/__init__.py +14 -0
  146. google/adk/tests/integration/.env.example +10 -0
  147. google/adk/tests/integration/__init__.py +18 -0
  148. google/adk/tests/integration/conftest.py +119 -0
  149. google/adk/tests/integration/fixture/__init__.py +14 -0
  150. google/adk/tests/integration/fixture/agent_with_config/__init__.py +15 -0
  151. google/adk/tests/integration/fixture/agent_with_config/agent.py +88 -0
  152. google/adk/tests/integration/fixture/callback_agent/__init__.py +15 -0
  153. google/adk/tests/integration/fixture/callback_agent/agent.py +105 -0
  154. google/adk/tests/integration/fixture/context_update_test/OWNERS +1 -0
  155. google/adk/tests/integration/fixture/context_update_test/__init__.py +15 -0
  156. google/adk/tests/integration/fixture/context_update_test/agent.py +43 -0
  157. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +582 -0
  158. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +15 -0
  159. google/adk/tests/integration/fixture/context_variable_agent/agent.py +115 -0
  160. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +15 -0
  161. google/adk/tests/integration/fixture/customer_support_ma/agent.py +172 -0
  162. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +15 -0
  163. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +338 -0
  164. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +69 -0
  165. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +6 -0
  166. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +15 -0
  167. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +182 -0
  168. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +190 -0
  169. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +15 -0
  170. google/adk/tests/integration/fixture/hello_world_agent/agent.py +95 -0
  171. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +24 -0
  172. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +6 -0
  173. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +15 -0
  174. google/adk/tests/integration/fixture/home_automation_agent/agent.py +304 -0
  175. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +5 -0
  176. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +5 -0
  177. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +5 -0
  178. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +18 -0
  179. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +17 -0
  180. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +6 -0
  181. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +18 -0
  182. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +17 -0
  183. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +5 -0
  184. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +5 -0
  185. google/adk/tests/integration/fixture/tool_agent/__init__.py +15 -0
  186. google/adk/tests/integration/fixture/tool_agent/agent.py +218 -0
  187. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  188. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +15 -0
  189. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +110 -0
  190. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +13 -0
  191. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +5 -0
  192. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +13 -0
  193. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +5 -0
  194. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +7 -0
  195. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +19 -0
  196. google/adk/tests/integration/models/__init__.py +14 -0
  197. google/adk/tests/integration/models/test_google_llm.py +65 -0
  198. google/adk/tests/integration/test_callback.py +70 -0
  199. google/adk/tests/integration/test_context_variable.py +67 -0
  200. google/adk/tests/integration/test_evalute_agent_in_fixture.py +76 -0
  201. google/adk/tests/integration/test_multi_agent.py +28 -0
  202. google/adk/tests/integration/test_multi_turn.py +42 -0
  203. google/adk/tests/integration/test_single_agent.py +23 -0
  204. google/adk/tests/integration/test_sub_agent.py +26 -0
  205. google/adk/tests/integration/test_system_instruction.py +177 -0
  206. google/adk/tests/integration/test_tools.py +287 -0
  207. google/adk/tests/integration/test_with_test_file.py +34 -0
  208. google/adk/tests/integration/tools/__init__.py +14 -0
  209. google/adk/tests/integration/utils/__init__.py +16 -0
  210. google/adk/tests/integration/utils/asserts.py +75 -0
  211. google/adk/tests/integration/utils/test_runner.py +97 -0
  212. google/adk/tests/unittests/__init__.py +14 -0
  213. google/adk/tests/unittests/agents/__init__.py +14 -0
  214. google/adk/tests/unittests/agents/test_base_agent.py +407 -0
  215. google/adk/tests/unittests/agents/test_langgraph_agent.py +191 -0
  216. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +138 -0
  217. google/adk/tests/unittests/agents/test_llm_agent_fields.py +231 -0
  218. google/adk/tests/unittests/agents/test_loop_agent.py +136 -0
  219. google/adk/tests/unittests/agents/test_parallel_agent.py +92 -0
  220. google/adk/tests/unittests/agents/test_sequential_agent.py +114 -0
  221. google/adk/tests/unittests/artifacts/__init__.py +14 -0
  222. google/adk/tests/unittests/artifacts/test_artifact_service.py +276 -0
  223. google/adk/tests/unittests/auth/test_auth_handler.py +575 -0
  224. google/adk/tests/unittests/conftest.py +73 -0
  225. google/adk/tests/unittests/fast_api/__init__.py +14 -0
  226. google/adk/tests/unittests/fast_api/test_fast_api.py +269 -0
  227. google/adk/tests/unittests/flows/__init__.py +14 -0
  228. google/adk/tests/unittests/flows/llm_flows/__init__.py +14 -0
  229. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +142 -0
  230. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +311 -0
  231. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +244 -0
  232. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +346 -0
  233. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +93 -0
  234. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +258 -0
  235. google/adk/tests/unittests/flows/llm_flows/test_identity.py +66 -0
  236. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +164 -0
  237. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +142 -0
  238. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +46 -0
  239. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +269 -0
  240. google/adk/tests/unittests/models/__init__.py +14 -0
  241. google/adk/tests/unittests/models/test_google_llm.py +224 -0
  242. google/adk/tests/unittests/models/test_litellm.py +804 -0
  243. google/adk/tests/unittests/models/test_models.py +60 -0
  244. google/adk/tests/unittests/sessions/__init__.py +14 -0
  245. google/adk/tests/unittests/sessions/test_session_service.py +227 -0
  246. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +246 -0
  247. google/adk/tests/unittests/streaming/__init__.py +14 -0
  248. google/adk/tests/unittests/streaming/test_streaming.py +50 -0
  249. google/adk/tests/unittests/tools/__init__.py +14 -0
  250. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +499 -0
  251. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +204 -0
  252. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +600 -0
  253. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +630 -0
  254. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +345 -0
  255. google/adk/tests/unittests/tools/google_api_tool/__init__.py +13 -0
  256. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +657 -0
  257. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +145 -0
  258. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +68 -0
  259. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +153 -0
  260. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +196 -0
  261. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +573 -0
  262. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +436 -0
  263. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +1367 -0
  264. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +628 -0
  265. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +139 -0
  266. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +406 -0
  267. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +966 -0
  268. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +201 -0
  269. google/adk/tests/unittests/tools/retrieval/__init__.py +14 -0
  270. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +147 -0
  271. google/adk/tests/unittests/tools/test_agent_tool.py +167 -0
  272. google/adk/tests/unittests/tools/test_base_tool.py +141 -0
  273. google/adk/tests/unittests/tools/test_build_function_declaration.py +277 -0
  274. google/adk/tests/unittests/utils.py +304 -0
  275. google/adk/tools/__init__.py +51 -0
  276. google/adk/tools/_automatic_function_calling_util.py +346 -0
  277. google/adk/tools/agent_tool.py +176 -0
  278. google/adk/tools/apihub_tool/__init__.py +19 -0
  279. google/adk/tools/apihub_tool/apihub_toolset.py +209 -0
  280. google/adk/tools/apihub_tool/clients/__init__.py +13 -0
  281. google/adk/tools/apihub_tool/clients/apihub_client.py +332 -0
  282. google/adk/tools/apihub_tool/clients/secret_client.py +115 -0
  283. google/adk/tools/application_integration_tool/__init__.py +19 -0
  284. google/adk/tools/application_integration_tool/application_integration_toolset.py +230 -0
  285. google/adk/tools/application_integration_tool/clients/connections_client.py +903 -0
  286. google/adk/tools/application_integration_tool/clients/integration_client.py +253 -0
  287. google/adk/tools/base_tool.py +144 -0
  288. google/adk/tools/built_in_code_execution_tool.py +59 -0
  289. google/adk/tools/crewai_tool.py +72 -0
  290. google/adk/tools/example_tool.py +62 -0
  291. google/adk/tools/exit_loop_tool.py +23 -0
  292. google/adk/tools/function_parameter_parse_util.py +307 -0
  293. google/adk/tools/function_tool.py +87 -0
  294. google/adk/tools/get_user_choice_tool.py +28 -0
  295. google/adk/tools/google_api_tool/__init__.py +14 -0
  296. google/adk/tools/google_api_tool/google_api_tool.py +59 -0
  297. google/adk/tools/google_api_tool/google_api_tool_set.py +107 -0
  298. google/adk/tools/google_api_tool/google_api_tool_sets.py +55 -0
  299. google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +521 -0
  300. google/adk/tools/google_search_tool.py +68 -0
  301. google/adk/tools/langchain_tool.py +86 -0
  302. google/adk/tools/load_artifacts_tool.py +113 -0
  303. google/adk/tools/load_memory_tool.py +58 -0
  304. google/adk/tools/load_web_page.py +41 -0
  305. google/adk/tools/long_running_tool.py +39 -0
  306. google/adk/tools/mcp_tool/__init__.py +42 -0
  307. google/adk/tools/mcp_tool/conversion_utils.py +161 -0
  308. google/adk/tools/mcp_tool/mcp_tool.py +113 -0
  309. google/adk/tools/mcp_tool/mcp_toolset.py +272 -0
  310. google/adk/tools/openapi_tool/__init__.py +21 -0
  311. google/adk/tools/openapi_tool/auth/__init__.py +19 -0
  312. google/adk/tools/openapi_tool/auth/auth_helpers.py +498 -0
  313. google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +25 -0
  314. google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +105 -0
  315. google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +55 -0
  316. google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +117 -0
  317. google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +97 -0
  318. google/adk/tools/openapi_tool/common/__init__.py +19 -0
  319. google/adk/tools/openapi_tool/common/common.py +300 -0
  320. google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +32 -0
  321. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +231 -0
  322. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +144 -0
  323. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +260 -0
  324. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +496 -0
  325. google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +268 -0
  326. google/adk/tools/preload_memory_tool.py +72 -0
  327. google/adk/tools/retrieval/__init__.py +36 -0
  328. google/adk/tools/retrieval/base_retrieval_tool.py +37 -0
  329. google/adk/tools/retrieval/files_retrieval.py +33 -0
  330. google/adk/tools/retrieval/llama_index_retrieval.py +41 -0
  331. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +107 -0
  332. google/adk/tools/tool_context.py +90 -0
  333. google/adk/tools/toolbox_tool.py +46 -0
  334. google/adk/tools/transfer_to_agent_tool.py +21 -0
  335. google/adk/tools/vertex_ai_search_tool.py +96 -0
  336. google/adk/version.py +16 -0
  337. google_adk-0.0.3.dist-info/METADATA +73 -0
  338. google_adk-0.0.3.dist-info/RECORD +340 -0
  339. {google_adk-0.0.1.dist-info → google_adk-0.0.3.dist-info}/WHEEL +1 -2
  340. google_adk-0.0.3.dist-info/entry_points.txt +3 -0
  341. agent_kit/__init__.py +0 -0
  342. google_adk-0.0.1.dist-info/LICENSE.txt +0 -170
  343. google_adk-0.0.1.dist-info/METADATA +0 -15
  344. google_adk-0.0.1.dist-info/RECORD +0 -6
  345. google_adk-0.0.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,202 @@
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
+ """The persistent context used to configure the code executor."""
16
+
17
+ import copy
18
+ import dataclasses
19
+ import datetime
20
+ from typing import Any
21
+ from typing import Optional
22
+
23
+ from ..sessions.state import State
24
+ from .code_execution_utils import File
25
+
26
+ _CONTEXT_KEY = '_code_execution_context'
27
+ _SESSION_ID_KEY = 'execution_session_id'
28
+ _PROCESSED_FILE_NAMES_KEY = 'processed_input_files'
29
+ _INPUT_FILE_KEY = '_code_executor_input_files'
30
+ _ERROR_COUNT_KEY = '_code_executor_error_counts'
31
+
32
+ _CODE_EXECUTION_RESULTS_KEY = '_code_execution_results'
33
+
34
+
35
+ class CodeExecutorContext:
36
+ """The persistent context used to configure the code executor."""
37
+
38
+ _context: dict[str, Any]
39
+
40
+ def __init__(self, session_state: State):
41
+ """Initializes the code executor context.
42
+
43
+ Args:
44
+ session_state: The session state to get the code executor context from.
45
+ """
46
+ self._context = self._get_code_executor_context(session_state)
47
+ self._session_state = session_state
48
+
49
+ def get_state_delta(self) -> dict[str, Any]:
50
+ """Gets the state delta to update in the persistent session state.
51
+
52
+ Returns:
53
+ The state delta to update in the persistent session state.
54
+ """
55
+ context_to_update = copy.deepcopy(self._context)
56
+ return {_CONTEXT_KEY: context_to_update}
57
+
58
+ def get_execution_id(self) -> Optional[str]:
59
+ """Gets the session ID for the code executor.
60
+
61
+ Returns:
62
+ The session ID for the code executor context.
63
+ """
64
+ if _SESSION_ID_KEY not in self._context:
65
+ return None
66
+ return self._context[_SESSION_ID_KEY]
67
+
68
+ def set_execution_id(self, session_id: str):
69
+ """Sets the session ID for the code executor.
70
+
71
+ Args:
72
+ session_id: The session ID for the code executor.
73
+ """
74
+ self._context[_SESSION_ID_KEY] = session_id
75
+
76
+ def get_processed_file_names(self) -> list[str]:
77
+ """Gets the processed file names from the session state.
78
+
79
+ Returns:
80
+ A list of processed file names in the code executor context.
81
+ """
82
+ if _PROCESSED_FILE_NAMES_KEY not in self._context:
83
+ return []
84
+ return self._context[_PROCESSED_FILE_NAMES_KEY]
85
+
86
+ def add_processed_file_names(self, file_names: [str]):
87
+ """Adds the processed file name to the session state.
88
+
89
+ Args:
90
+ file_names: The processed file names to add to the session state.
91
+ """
92
+ if _PROCESSED_FILE_NAMES_KEY not in self._context:
93
+ self._context[_PROCESSED_FILE_NAMES_KEY] = []
94
+ self._context[_PROCESSED_FILE_NAMES_KEY].extend(file_names)
95
+
96
+ def get_input_files(self) -> list[File]:
97
+ """Gets the code executor input file names from the session state.
98
+
99
+ Returns:
100
+ A list of input files in the code executor context.
101
+ """
102
+ if _INPUT_FILE_KEY not in self._session_state:
103
+ return []
104
+ return [File(**file) for file in self._session_state[_INPUT_FILE_KEY]]
105
+
106
+ def add_input_files(
107
+ self,
108
+ input_files: list[File],
109
+ ):
110
+ """Adds the input files to the code executor context.
111
+
112
+ Args:
113
+ input_files: The input files to add to the code executor context.
114
+ """
115
+ if _INPUT_FILE_KEY not in self._session_state:
116
+ self._session_state[_INPUT_FILE_KEY] = []
117
+ for input_file in input_files:
118
+ self._session_state[_INPUT_FILE_KEY].append(
119
+ dataclasses.asdict(input_file)
120
+ )
121
+
122
+ def clear_input_files(self):
123
+ """Removes the input files and processed file names to the code executor context."""
124
+ if _INPUT_FILE_KEY in self._session_state:
125
+ self._session_state[_INPUT_FILE_KEY] = []
126
+ if _PROCESSED_FILE_NAMES_KEY in self._context:
127
+ self._context[_PROCESSED_FILE_NAMES_KEY] = []
128
+
129
+ def get_error_count(self, invocation_id: str) -> int:
130
+ """Gets the error count from the session state.
131
+
132
+ Args:
133
+ invocation_id: The invocation ID to get the error count for.
134
+
135
+ Returns:
136
+ The error count for the given invocation ID.
137
+ """
138
+ if _ERROR_COUNT_KEY not in self._session_state:
139
+ return 0
140
+ return self._session_state[_ERROR_COUNT_KEY].get(invocation_id, 0)
141
+
142
+ def increment_error_count(self, invocation_id: str):
143
+ """Increments the error count from the session state.
144
+
145
+ Args:
146
+ invocation_id: The invocation ID to increment the error count for.
147
+ """
148
+ if _ERROR_COUNT_KEY not in self._session_state:
149
+ self._session_state[_ERROR_COUNT_KEY] = {}
150
+ self._session_state[_ERROR_COUNT_KEY][invocation_id] = (
151
+ self.get_error_count(invocation_id) + 1
152
+ )
153
+
154
+ def reset_error_count(self, invocation_id: str):
155
+ """Resets the error count from the session state.
156
+
157
+ Args:
158
+ invocation_id: The invocation ID to reset the error count for.
159
+ """
160
+ if _ERROR_COUNT_KEY not in self._session_state:
161
+ return
162
+ if invocation_id in self._session_state[_ERROR_COUNT_KEY]:
163
+ del self._session_state[_ERROR_COUNT_KEY][invocation_id]
164
+
165
+ def update_code_execution_result(
166
+ self,
167
+ invocation_id: str,
168
+ code: str,
169
+ result_stdout: str,
170
+ result_stderr: str,
171
+ ):
172
+ """Updates the code execution result.
173
+
174
+ Args:
175
+ invocation_id: The invocation ID to update the code execution result for.
176
+ code: The code to execute.
177
+ result_stdout: The standard output of the code execution.
178
+ result_stderr: The standard error of the code execution.
179
+ """
180
+ if _CODE_EXECUTION_RESULTS_KEY not in self._session_state:
181
+ self._session_state[_CODE_EXECUTION_RESULTS_KEY] = {}
182
+ if invocation_id not in self._session_state[_CODE_EXECUTION_RESULTS_KEY]:
183
+ self._session_state[_CODE_EXECUTION_RESULTS_KEY][invocation_id] = []
184
+ self._session_state[_CODE_EXECUTION_RESULTS_KEY][invocation_id].append({
185
+ 'code': code,
186
+ 'result_stdout': result_stdout,
187
+ 'result_stderr': result_stderr,
188
+ 'timestamp': int(datetime.datetime.now().timestamp()),
189
+ })
190
+
191
+ def _get_code_executor_context(self, session_state: State) -> dict[str, Any]:
192
+ """Gets the code executor context from the session state.
193
+
194
+ Args:
195
+ session_state: The session state to get the code executor context from.
196
+
197
+ Returns:
198
+ A dict of code executor context.
199
+ """
200
+ if _CONTEXT_KEY not in session_state:
201
+ session_state[_CONTEXT_KEY] = {}
202
+ return session_state[_CONTEXT_KEY]
@@ -0,0 +1,196 @@
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 atexit
16
+ import os
17
+ from typing import Optional
18
+
19
+ import docker
20
+ from docker.client import DockerClient
21
+ from docker.models.containers import Container
22
+ from pydantic import Field
23
+ from typing_extensions import override
24
+
25
+ from ..agents.invocation_context import InvocationContext
26
+ from .base_code_executor import BaseCodeExecutor
27
+ from .code_execution_utils import CodeExecutionInput
28
+ from .code_execution_utils import CodeExecutionResult
29
+
30
+
31
+ DEFAULT_IMAGE_TAG = 'adk-code-executor:latest'
32
+
33
+
34
+ class ContainerCodeExecutor(BaseCodeExecutor):
35
+ """A code executor that uses a custom container to execute code.
36
+
37
+ Attributes:
38
+ base_url: Optional. The base url of the user hosted Docker client.
39
+ image: The tag of the predefined image or custom image to run on the
40
+ container. Either docker_path or image must be set.
41
+ docker_path: The path to the directory containing the Dockerfile. If set,
42
+ build the image from the dockerfile path instead of using the predefined
43
+ image. Either docker_path or image must be set.
44
+ """
45
+
46
+ base_url: Optional[str] = None
47
+ """
48
+ Optional. The base url of the user hosted Docker client.
49
+ """
50
+
51
+ image: str = None
52
+ """
53
+ The tag of the predefined image or custom image to run on the container.
54
+ Either docker_path or image must be set.
55
+ """
56
+
57
+ docker_path: str = None
58
+ """
59
+ The path to the directory containing the Dockerfile.
60
+ If set, build the image from the dockerfile path instead of using the
61
+ predefined image. Either docker_path or image must be set.
62
+ """
63
+
64
+ # Overrides the BaseCodeExecutor attribute: this executor cannot be stateful.
65
+ stateful: bool = Field(default=False, frozen=True, exclude=True)
66
+
67
+ # Overrides the BaseCodeExecutor attribute: this executor cannot
68
+ # optimize_data_file.
69
+ optimize_data_file: bool = Field(default=False, frozen=True, exclude=True)
70
+
71
+ _client: DockerClient = None
72
+ _container: Container = None
73
+
74
+ def __init__(
75
+ self,
76
+ base_url: Optional[str] = None,
77
+ image: Optional[str] = None,
78
+ docker_path: Optional[str] = None,
79
+ **data,
80
+ ):
81
+ """Initializes the ContainerCodeExecutor.
82
+
83
+ Args:
84
+ base_url: Optional. The base url of the user hosted Docker client.
85
+ image: The tag of the predefined image or custom image to run on the
86
+ container. Either docker_path or image must be set.
87
+ docker_path: The path to the directory containing the Dockerfile. If set,
88
+ build the image from the dockerfile path instead of using the predefined
89
+ image. Either docker_path or image must be set.
90
+ **data: The data to initialize the ContainerCodeExecutor.
91
+ """
92
+ if not image and not docker_path:
93
+ raise ValueError(
94
+ 'Either image or docker_path must be set for ContainerCodeExecutor.'
95
+ )
96
+ if 'stateful' in data and data['stateful']:
97
+ raise ValueError('Cannot set `stateful=True` in ContainerCodeExecutor.')
98
+ if 'optimize_data_file' in data and data['optimize_data_file']:
99
+ raise ValueError(
100
+ 'Cannot set `optimize_data_file=True` in ContainerCodeExecutor.'
101
+ )
102
+
103
+ super().__init__(**data)
104
+ self.base_url = base_url
105
+ self.image = image if image else DEFAULT_IMAGE_TAG
106
+ self.docker_path = os.path.abspath(docker_path) if docker_path else None
107
+
108
+ self._client = (
109
+ docker.from_env()
110
+ if not self.base_url
111
+ else docker.DockerClient(base_url=self.base_url)
112
+ )
113
+ # Initialize the container.
114
+ self.__init_container()
115
+
116
+ # Close the container when the on exit.
117
+ atexit.register(self.__cleanup_container)
118
+
119
+ @override
120
+ def execute_code(
121
+ self,
122
+ invocation_context: InvocationContext,
123
+ code_execution_input: CodeExecutionInput,
124
+ ) -> CodeExecutionResult:
125
+ output = ''
126
+ error = ''
127
+ exec_result = self._container.exec_run(
128
+ ['python3', '-c', code_execution_input.code],
129
+ demux=True,
130
+ )
131
+
132
+ if exec_result.output and exec_result.output[0]:
133
+ output = exec_result.output[0].decode('utf-8')
134
+ if (
135
+ exec_result.output
136
+ and len(exec_result.output) > 1
137
+ and exec_result.output[1]
138
+ ):
139
+ error = exec_result.output[1].decode('utf-8')
140
+
141
+ # Collect the final result.
142
+ return CodeExecutionResult(
143
+ stdout=output,
144
+ stderr=error,
145
+ output_files=[],
146
+ )
147
+
148
+ def _build_docker_image(self):
149
+ """Builds the Docker image."""
150
+ if not self.docker_path:
151
+ raise ValueError('Docker path is not set.')
152
+ if not os.path.exists(self.docker_path):
153
+ raise FileNotFoundError(f'Invalid Docker path: {self.docker_path}')
154
+
155
+ print('Building Docker image...')
156
+ self._client.images.build(
157
+ path=self.docker_path,
158
+ tag=self.image,
159
+ rm=True,
160
+ )
161
+ print(f'Docker image: {self.image} built.')
162
+
163
+ def _verify_python_installation(self):
164
+ """Verifies the container has python3 installed."""
165
+ exec_result = self._container.exec_run(['which', 'python3'])
166
+ if exec_result.exit_code != 0:
167
+ raise ValueError('python3 is not installed in the container.')
168
+
169
+ def __init_container(self):
170
+ """Initializes the container."""
171
+ if not self._client:
172
+ raise RuntimeError('Docker client is not initialized.')
173
+
174
+ if self.docker_path:
175
+ self._build_docker_image()
176
+
177
+ print('Starting container for ContainerCodeExecutor...')
178
+ self._container = self._client.containers.run(
179
+ image=self.image,
180
+ detach=True,
181
+ tty=True,
182
+ )
183
+ print(f'Container {self._container.id} started.')
184
+
185
+ # Verify the container is able to run python3.
186
+ self._verify_python_installation()
187
+
188
+ def __cleanup_container(self):
189
+ """Closes the container on exit."""
190
+ if not self._container:
191
+ return
192
+
193
+ print('[Cleanup] Stopping the container...')
194
+ self._container.stop()
195
+ self._container.remove()
196
+ print(f'Container {self._container.id} stopped and removed.')
@@ -0,0 +1,71 @@
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 contextlib import redirect_stdout
16
+ import io
17
+
18
+ from pydantic import Field
19
+ from typing_extensions import override
20
+
21
+ from ..agents.invocation_context import InvocationContext
22
+ from .base_code_executor import BaseCodeExecutor
23
+ from .code_execution_utils import CodeExecutionInput
24
+ from .code_execution_utils import CodeExecutionResult
25
+
26
+
27
+ class UnsafeLocalCodeExecutor(BaseCodeExecutor):
28
+ """A code executor that unsafely execute code in the current local context."""
29
+
30
+ # Overrides the BaseCodeExecutor attribute: this executor cannot be stateful.
31
+ stateful: bool = Field(default=False, frozen=True, exclude=True)
32
+
33
+ # Overrides the BaseCodeExecutor attribute: this executor cannot
34
+ # optimize_data_file.
35
+ optimize_data_file: bool = Field(default=False, frozen=True, exclude=True)
36
+
37
+ def __init__(self, **data):
38
+ """Initializes the UnsafeLocalCodeExecutor."""
39
+ if 'stateful' in data and data['stateful']:
40
+ raise ValueError('Cannot set `stateful=True` in UnsafeLocalCodeExecutor.')
41
+ if 'optimize_data_file' in data and data['optimize_data_file']:
42
+ raise ValueError(
43
+ 'Cannot set `optimize_data_file=True` in UnsafeLocalCodeExecutor.'
44
+ )
45
+ super().__init__(**data)
46
+
47
+ @override
48
+ def execute_code(
49
+ self,
50
+ invocation_context: InvocationContext,
51
+ code_execution_input: CodeExecutionInput,
52
+ ) -> CodeExecutionResult:
53
+ # Execute the code.
54
+ output = ''
55
+ error = ''
56
+ try:
57
+ globals_ = {}
58
+ locals_ = {}
59
+ stdout = io.StringIO()
60
+ with redirect_stdout(stdout):
61
+ exec(code_execution_input.code, globals_, locals_)
62
+ output = stdout.getvalue()
63
+ except Exception as e:
64
+ error = str(e)
65
+
66
+ # Collect the final result.
67
+ return CodeExecutionResult(
68
+ stdout=output,
69
+ stderr=error,
70
+ output_files=[],
71
+ )
@@ -0,0 +1,234 @@
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 datetime
16
+ import mimetypes
17
+ import os
18
+ from typing import Any, Optional
19
+
20
+ from typing_extensions import override
21
+ from vertexai.preview.extensions import Extension
22
+
23
+ from ..agents.invocation_context import InvocationContext
24
+ from .base_code_executor import BaseCodeExecutor
25
+ from .code_execution_utils import CodeExecutionInput
26
+ from .code_execution_utils import CodeExecutionResult
27
+ from .code_execution_utils import File
28
+
29
+ _SUPPORTED_IMAGE_TYPES = ['png', 'jpg', 'jpeg']
30
+ _SUPPORTED_DATA_FILE_TYPES = ['csv']
31
+
32
+ _IMPORTED_LIBRARIES = '''
33
+ import io
34
+ import math
35
+ import re
36
+
37
+ import matplotlib.pyplot as plt
38
+ import numpy as np
39
+ import pandas as pd
40
+ import scipy
41
+
42
+ def crop(s: str, max_chars: int = 64) -> str:
43
+ """Crops a string to max_chars characters."""
44
+ return s[: max_chars - 3] + '...' if len(s) > max_chars else s
45
+
46
+
47
+ def explore_df(df: pd.DataFrame) -> None:
48
+ """Prints some information about a pandas DataFrame."""
49
+
50
+ with pd.option_context(
51
+ 'display.max_columns', None, 'display.expand_frame_repr', False
52
+ ):
53
+ # Print the column names to never encounter KeyError when selecting one.
54
+ df_dtypes = df.dtypes
55
+
56
+ # Obtain information about data types and missing values.
57
+ df_nulls = (len(df) - df.isnull().sum()).apply(
58
+ lambda x: f'{x} / {df.shape[0]} non-null'
59
+ )
60
+
61
+ # Explore unique total values in columns using `.unique()`.
62
+ df_unique_count = df.apply(lambda x: len(x.unique()))
63
+
64
+ # Explore unique values in columns using `.unique()`.
65
+ df_unique = df.apply(lambda x: crop(str(list(x.unique()))))
66
+
67
+ df_info = pd.concat(
68
+ (
69
+ df_dtypes.rename('Dtype'),
70
+ df_nulls.rename('Non-Null Count'),
71
+ df_unique_count.rename('Unique Values Count'),
72
+ df_unique.rename('Unique Values'),
73
+ ),
74
+ axis=1,
75
+ )
76
+ df_info.index.name = 'Columns'
77
+ print(f"""Total rows: {df.shape[0]}
78
+ Total columns: {df.shape[1]}
79
+
80
+ {df_info}""")
81
+ '''
82
+
83
+
84
+ def _get_code_interpreter_extension(resource_name: str = None):
85
+ """Returns: Load or create the code interpreter extension."""
86
+ if not resource_name:
87
+ resource_name = os.environ.get('CODE_INTERPRETER_EXTENSION_NAME')
88
+ if resource_name:
89
+ new_code_interpreter = Extension(resource_name)
90
+ else:
91
+ print('No CODE_INTERPRETER_ID found in the environment. Create a new one.')
92
+ new_code_interpreter = Extension.from_hub('code_interpreter')
93
+ os.environ['CODE_INTERPRETER_EXTENSION_NAME'] = (
94
+ new_code_interpreter.gca_resource.name
95
+ )
96
+ return new_code_interpreter
97
+
98
+
99
+ class VertexAiCodeExecutor(BaseCodeExecutor):
100
+ """A code executor that uses Vertex Code Interpreter Extension to execute code.
101
+
102
+ Attributes:
103
+ resource_name: If set, load the existing resource name of the code
104
+ interpreter extension instead of creating a new one. Format:
105
+ projects/123/locations/us-central1/extensions/456
106
+ """
107
+
108
+ resource_name: str = None
109
+ """
110
+ If set, load the existing resource name of the code interpreter extension
111
+ instead of creating a new one.
112
+ Format: projects/123/locations/us-central1/extensions/456
113
+ """
114
+
115
+ _code_interpreter_extension: Extension
116
+
117
+ def __init__(
118
+ self,
119
+ resource_name: str = None,
120
+ **data,
121
+ ):
122
+ """Initializes the VertexAiCodeExecutor.
123
+
124
+ Args:
125
+ resource_name: If set, load the existing resource name of the code
126
+ interpreter extension instead of creating a new one. Format:
127
+ projects/123/locations/us-central1/extensions/456
128
+ **data: Additional keyword arguments to be passed to the base class.
129
+ """
130
+ super().__init__(**data)
131
+ self.resource_name = resource_name
132
+ self._code_interpreter_extension = _get_code_interpreter_extension(
133
+ self.resource_name
134
+ )
135
+
136
+ @override
137
+ def execute_code(
138
+ self,
139
+ invocation_context: InvocationContext,
140
+ code_execution_input: CodeExecutionInput,
141
+ ) -> CodeExecutionResult:
142
+ # Execute the code.
143
+ code_execution_result = self._execute_code_interpreter(
144
+ self._get_code_with_imports(code_execution_input.code),
145
+ code_execution_input.input_files,
146
+ code_execution_input.execution_id,
147
+ )
148
+
149
+ # Save output file as artifacts.
150
+ current_timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
151
+ file_name_prefix = '%s_' % str(current_timestamp)
152
+ saved_files = []
153
+ file_count = 0
154
+ for output_file in code_execution_result['output_files']:
155
+ file_type = output_file['name'].split('.')[-1]
156
+ file_name = file_name_prefix + '%d.%s' % (file_count, file_type)
157
+ if file_type in _SUPPORTED_IMAGE_TYPES:
158
+ file_count += 1
159
+ saved_files.append(
160
+ File(
161
+ name='plot_' + file_name,
162
+ content=output_file['contents'],
163
+ mime_type=f'image/{file_type}',
164
+ )
165
+ )
166
+ elif file_type in _SUPPORTED_DATA_FILE_TYPES:
167
+ file_count += 1
168
+ saved_files.append(
169
+ File(
170
+ name='data_' + file_name,
171
+ content=output_file['contents'],
172
+ mime_type=f'text/{file_type}',
173
+ )
174
+ )
175
+ else:
176
+ mime_type, _ = mimetypes.guess_type(file_name)
177
+ saved_files.append(
178
+ File(
179
+ name=file_name,
180
+ content=output_file['contents'],
181
+ mime_type=mime_type,
182
+ )
183
+ )
184
+
185
+ # Collect the final result.
186
+ return CodeExecutionResult(
187
+ stdout=code_execution_result.get('execution_result', ''),
188
+ stderr=code_execution_result.get('execution_error', ''),
189
+ output_files=saved_files,
190
+ )
191
+
192
+ def _execute_code_interpreter(
193
+ self,
194
+ code: str,
195
+ input_files: Optional[list[File]] = None,
196
+ session_id: Optional[str] = None,
197
+ ) -> dict[str, Any]:
198
+ """Executes the code interpreter extension.
199
+
200
+ Args:
201
+ code: The code to execute.
202
+ input_files: The input files to execute the code with.
203
+ session_id: The session ID to execute the code with.
204
+
205
+ Returns:
206
+ The response from the code interpreter extension.
207
+ """
208
+ operation_params = {'code': code}
209
+ if input_files:
210
+ operation_params['files'] = [
211
+ {'name': f.name, 'contents': f.content} for f in input_files
212
+ ]
213
+ if session_id:
214
+ operation_params['session_id'] = session_id
215
+ response = self._code_interpreter_extension.execute(
216
+ operation_id='execute',
217
+ operation_params=operation_params,
218
+ )
219
+ return response
220
+
221
+ def _get_code_with_imports(self, code: str) -> str:
222
+ """Builds the code string with built-in imports.
223
+
224
+ Args:
225
+ code: The code to execute.
226
+
227
+ Returns:
228
+ The code string with built-in imports.
229
+ """
230
+ return f"""
231
+ {_IMPORTED_LIBRARIES}
232
+
233
+ {code}
234
+ """