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