google-adk 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. google/adk/__init__.py +20 -0
  2. google/adk/agents/__init__.py +32 -0
  3. google/adk/agents/active_streaming_tool.py +38 -0
  4. google/adk/agents/base_agent.py +345 -0
  5. google/adk/agents/callback_context.py +112 -0
  6. google/adk/agents/invocation_context.py +181 -0
  7. google/adk/agents/langgraph_agent.py +140 -0
  8. google/adk/agents/live_request_queue.py +64 -0
  9. google/adk/agents/llm_agent.py +376 -0
  10. google/adk/agents/loop_agent.py +62 -0
  11. google/adk/agents/parallel_agent.py +96 -0
  12. google/adk/agents/readonly_context.py +46 -0
  13. google/adk/agents/remote_agent.py +50 -0
  14. google/adk/agents/run_config.py +87 -0
  15. google/adk/agents/sequential_agent.py +45 -0
  16. google/adk/agents/transcription_entry.py +34 -0
  17. google/adk/artifacts/__init__.py +23 -0
  18. google/adk/artifacts/base_artifact_service.py +128 -0
  19. google/adk/artifacts/gcs_artifact_service.py +195 -0
  20. google/adk/artifacts/in_memory_artifact_service.py +133 -0
  21. google/adk/auth/__init__.py +22 -0
  22. google/adk/auth/auth_credential.py +220 -0
  23. google/adk/auth/auth_handler.py +268 -0
  24. google/adk/auth/auth_preprocessor.py +116 -0
  25. google/adk/auth/auth_schemes.py +67 -0
  26. google/adk/auth/auth_tool.py +55 -0
  27. google/adk/cli/__init__.py +15 -0
  28. google/adk/cli/__main__.py +18 -0
  29. google/adk/cli/agent_graph.py +122 -0
  30. google/adk/cli/browser/adk_favicon.svg +17 -0
  31. google/adk/cli/browser/assets/audio-processor.js +51 -0
  32. google/adk/cli/browser/assets/config/runtime-config.json +3 -0
  33. google/adk/cli/browser/index.html +33 -0
  34. google/adk/cli/browser/main-XUU6OGCC.js +75 -0
  35. google/adk/cli/browser/polyfills-FFHMD2TL.js +18 -0
  36. google/adk/cli/browser/styles-4VDSPQ37.css +17 -0
  37. google/adk/cli/cli.py +181 -0
  38. google/adk/cli/cli_deploy.py +181 -0
  39. google/adk/cli/cli_eval.py +282 -0
  40. google/adk/cli/cli_tools_click.py +479 -0
  41. google/adk/cli/fast_api.py +774 -0
  42. google/adk/cli/media_streamer/__init__.py +19 -0
  43. google/adk/cli/media_streamer/index.html +228 -0
  44. google/adk/cli/utils/__init__.py +49 -0
  45. google/adk/cli/utils/envs.py +57 -0
  46. google/adk/cli/utils/evals.py +93 -0
  47. google/adk/cli/utils/logs.py +72 -0
  48. google/adk/code_executors/__init__.py +49 -0
  49. google/adk/code_executors/base_code_executor.py +97 -0
  50. google/adk/code_executors/code_execution_utils.py +256 -0
  51. google/adk/code_executors/code_executor_context.py +202 -0
  52. google/adk/code_executors/container_code_executor.py +196 -0
  53. google/adk/code_executors/unsafe_local_code_executor.py +71 -0
  54. google/adk/code_executors/vertex_ai_code_executor.py +234 -0
  55. google/adk/evaluation/__init__.py +31 -0
  56. google/adk/evaluation/agent_evaluator.py +329 -0
  57. google/adk/evaluation/evaluation_constants.py +24 -0
  58. google/adk/evaluation/evaluation_generator.py +270 -0
  59. google/adk/evaluation/response_evaluator.py +135 -0
  60. google/adk/evaluation/trajectory_evaluator.py +184 -0
  61. google/adk/events/__init__.py +21 -0
  62. google/adk/events/event.py +130 -0
  63. google/adk/events/event_actions.py +55 -0
  64. google/adk/examples/__init__.py +28 -0
  65. google/adk/examples/base_example_provider.py +35 -0
  66. google/adk/examples/example.py +27 -0
  67. google/adk/examples/example_util.py +123 -0
  68. google/adk/examples/vertex_ai_example_store.py +104 -0
  69. google/adk/flows/__init__.py +14 -0
  70. google/adk/flows/llm_flows/__init__.py +20 -0
  71. google/adk/flows/llm_flows/_base_llm_processor.py +52 -0
  72. google/adk/flows/llm_flows/_code_execution.py +458 -0
  73. google/adk/flows/llm_flows/_nl_planning.py +129 -0
  74. google/adk/flows/llm_flows/agent_transfer.py +132 -0
  75. google/adk/flows/llm_flows/audio_transcriber.py +109 -0
  76. google/adk/flows/llm_flows/auto_flow.py +49 -0
  77. google/adk/flows/llm_flows/base_llm_flow.py +559 -0
  78. google/adk/flows/llm_flows/basic.py +72 -0
  79. google/adk/flows/llm_flows/contents.py +370 -0
  80. google/adk/flows/llm_flows/functions.py +486 -0
  81. google/adk/flows/llm_flows/identity.py +47 -0
  82. google/adk/flows/llm_flows/instructions.py +137 -0
  83. google/adk/flows/llm_flows/single_flow.py +57 -0
  84. google/adk/memory/__init__.py +35 -0
  85. google/adk/memory/base_memory_service.py +74 -0
  86. google/adk/memory/in_memory_memory_service.py +62 -0
  87. google/adk/memory/vertex_ai_rag_memory_service.py +177 -0
  88. google/adk/models/__init__.py +31 -0
  89. google/adk/models/anthropic_llm.py +243 -0
  90. google/adk/models/base_llm.py +87 -0
  91. google/adk/models/base_llm_connection.py +76 -0
  92. google/adk/models/gemini_llm_connection.py +200 -0
  93. google/adk/models/google_llm.py +331 -0
  94. google/adk/models/lite_llm.py +673 -0
  95. google/adk/models/llm_request.py +98 -0
  96. google/adk/models/llm_response.py +111 -0
  97. google/adk/models/registry.py +102 -0
  98. google/adk/planners/__init__.py +23 -0
  99. google/adk/planners/base_planner.py +66 -0
  100. google/adk/planners/built_in_planner.py +75 -0
  101. google/adk/planners/plan_re_act_planner.py +208 -0
  102. google/adk/runners.py +456 -0
  103. google/adk/sessions/__init__.py +41 -0
  104. google/adk/sessions/base_session_service.py +133 -0
  105. google/adk/sessions/database_session_service.py +522 -0
  106. google/adk/sessions/in_memory_session_service.py +206 -0
  107. google/adk/sessions/session.py +54 -0
  108. google/adk/sessions/state.py +71 -0
  109. google/adk/sessions/vertex_ai_session_service.py +356 -0
  110. google/adk/telemetry.py +189 -0
  111. google/adk/tests/__init__.py +14 -0
  112. google/adk/tests/integration/.env.example +10 -0
  113. google/adk/tests/integration/__init__.py +18 -0
  114. google/adk/tests/integration/conftest.py +119 -0
  115. google/adk/tests/integration/fixture/__init__.py +14 -0
  116. google/adk/tests/integration/fixture/agent_with_config/__init__.py +15 -0
  117. google/adk/tests/integration/fixture/agent_with_config/agent.py +88 -0
  118. google/adk/tests/integration/fixture/callback_agent/__init__.py +15 -0
  119. google/adk/tests/integration/fixture/callback_agent/agent.py +105 -0
  120. google/adk/tests/integration/fixture/context_update_test/OWNERS +1 -0
  121. google/adk/tests/integration/fixture/context_update_test/__init__.py +15 -0
  122. google/adk/tests/integration/fixture/context_update_test/agent.py +43 -0
  123. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +582 -0
  124. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +15 -0
  125. google/adk/tests/integration/fixture/context_variable_agent/agent.py +115 -0
  126. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +15 -0
  127. google/adk/tests/integration/fixture/customer_support_ma/agent.py +172 -0
  128. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +15 -0
  129. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +338 -0
  130. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +69 -0
  131. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +6 -0
  132. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +15 -0
  133. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +182 -0
  134. google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +243 -0
  135. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +190 -0
  136. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +15 -0
  137. google/adk/tests/integration/fixture/hello_world_agent/agent.py +95 -0
  138. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +24 -0
  139. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +6 -0
  140. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +15 -0
  141. google/adk/tests/integration/fixture/home_automation_agent/agent.py +304 -0
  142. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +5 -0
  143. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +5 -0
  144. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +5 -0
  145. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +18 -0
  146. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +17 -0
  147. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +6 -0
  148. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +18 -0
  149. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +17 -0
  150. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +5 -0
  151. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +5 -0
  152. google/adk/tests/integration/fixture/tool_agent/__init__.py +15 -0
  153. google/adk/tests/integration/fixture/tool_agent/agent.py +218 -0
  154. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  155. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +15 -0
  156. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +110 -0
  157. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +13 -0
  158. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +5 -0
  159. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +13 -0
  160. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +5 -0
  161. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +7 -0
  162. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +19 -0
  163. google/adk/tests/integration/models/__init__.py +14 -0
  164. google/adk/tests/integration/models/test_google_llm.py +65 -0
  165. google/adk/tests/integration/test_callback.py +70 -0
  166. google/adk/tests/integration/test_context_variable.py +67 -0
  167. google/adk/tests/integration/test_evalute_agent_in_fixture.py +76 -0
  168. google/adk/tests/integration/test_multi_agent.py +28 -0
  169. google/adk/tests/integration/test_multi_turn.py +42 -0
  170. google/adk/tests/integration/test_single_agent.py +23 -0
  171. google/adk/tests/integration/test_sub_agent.py +26 -0
  172. google/adk/tests/integration/test_system_instruction.py +177 -0
  173. google/adk/tests/integration/test_tools.py +287 -0
  174. google/adk/tests/integration/test_with_test_file.py +34 -0
  175. google/adk/tests/integration/tools/__init__.py +14 -0
  176. google/adk/tests/integration/utils/__init__.py +16 -0
  177. google/adk/tests/integration/utils/asserts.py +75 -0
  178. google/adk/tests/integration/utils/test_runner.py +97 -0
  179. google/adk/tests/unittests/__init__.py +14 -0
  180. google/adk/tests/unittests/agents/__init__.py +14 -0
  181. google/adk/tests/unittests/agents/test_base_agent.py +407 -0
  182. google/adk/tests/unittests/agents/test_langgraph_agent.py +191 -0
  183. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +138 -0
  184. google/adk/tests/unittests/agents/test_llm_agent_fields.py +231 -0
  185. google/adk/tests/unittests/agents/test_loop_agent.py +136 -0
  186. google/adk/tests/unittests/agents/test_parallel_agent.py +92 -0
  187. google/adk/tests/unittests/agents/test_sequential_agent.py +114 -0
  188. google/adk/tests/unittests/artifacts/__init__.py +14 -0
  189. google/adk/tests/unittests/artifacts/test_artifact_service.py +276 -0
  190. google/adk/tests/unittests/auth/test_auth_handler.py +575 -0
  191. google/adk/tests/unittests/conftest.py +73 -0
  192. google/adk/tests/unittests/fast_api/__init__.py +14 -0
  193. google/adk/tests/unittests/fast_api/test_fast_api.py +269 -0
  194. google/adk/tests/unittests/flows/__init__.py +14 -0
  195. google/adk/tests/unittests/flows/llm_flows/__init__.py +14 -0
  196. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +142 -0
  197. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +311 -0
  198. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +244 -0
  199. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +346 -0
  200. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +93 -0
  201. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +258 -0
  202. google/adk/tests/unittests/flows/llm_flows/test_identity.py +66 -0
  203. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +164 -0
  204. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +142 -0
  205. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +46 -0
  206. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +269 -0
  207. google/adk/tests/unittests/models/__init__.py +14 -0
  208. google/adk/tests/unittests/models/test_google_llm.py +224 -0
  209. google/adk/tests/unittests/models/test_litellm.py +804 -0
  210. google/adk/tests/unittests/models/test_models.py +60 -0
  211. google/adk/tests/unittests/sessions/__init__.py +14 -0
  212. google/adk/tests/unittests/sessions/test_session_service.py +227 -0
  213. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +246 -0
  214. google/adk/tests/unittests/streaming/__init__.py +14 -0
  215. google/adk/tests/unittests/streaming/test_streaming.py +50 -0
  216. google/adk/tests/unittests/tools/__init__.py +14 -0
  217. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +499 -0
  218. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +204 -0
  219. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +600 -0
  220. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +630 -0
  221. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +345 -0
  222. google/adk/tests/unittests/tools/google_api_tool/__init__.py +13 -0
  223. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +657 -0
  224. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +145 -0
  225. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +68 -0
  226. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +153 -0
  227. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +196 -0
  228. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +573 -0
  229. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +436 -0
  230. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +1367 -0
  231. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +628 -0
  232. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +139 -0
  233. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +406 -0
  234. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +966 -0
  235. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +201 -0
  236. google/adk/tests/unittests/tools/retrieval/__init__.py +14 -0
  237. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +147 -0
  238. google/adk/tests/unittests/tools/test_agent_tool.py +167 -0
  239. google/adk/tests/unittests/tools/test_base_tool.py +141 -0
  240. google/adk/tests/unittests/tools/test_build_function_declaration.py +277 -0
  241. google/adk/tests/unittests/utils.py +304 -0
  242. google/adk/tools/__init__.py +51 -0
  243. google/adk/tools/_automatic_function_calling_util.py +346 -0
  244. google/adk/tools/agent_tool.py +176 -0
  245. google/adk/tools/apihub_tool/__init__.py +19 -0
  246. google/adk/tools/apihub_tool/apihub_toolset.py +209 -0
  247. google/adk/tools/apihub_tool/clients/__init__.py +13 -0
  248. google/adk/tools/apihub_tool/clients/apihub_client.py +332 -0
  249. google/adk/tools/apihub_tool/clients/secret_client.py +115 -0
  250. google/adk/tools/application_integration_tool/__init__.py +19 -0
  251. google/adk/tools/application_integration_tool/application_integration_toolset.py +230 -0
  252. google/adk/tools/application_integration_tool/clients/connections_client.py +903 -0
  253. google/adk/tools/application_integration_tool/clients/integration_client.py +253 -0
  254. google/adk/tools/base_tool.py +144 -0
  255. google/adk/tools/built_in_code_execution_tool.py +59 -0
  256. google/adk/tools/crewai_tool.py +72 -0
  257. google/adk/tools/example_tool.py +62 -0
  258. google/adk/tools/exit_loop_tool.py +23 -0
  259. google/adk/tools/function_parameter_parse_util.py +307 -0
  260. google/adk/tools/function_tool.py +87 -0
  261. google/adk/tools/get_user_choice_tool.py +28 -0
  262. google/adk/tools/google_api_tool/__init__.py +14 -0
  263. google/adk/tools/google_api_tool/google_api_tool.py +59 -0
  264. google/adk/tools/google_api_tool/google_api_tool_set.py +107 -0
  265. google/adk/tools/google_api_tool/google_api_tool_sets.py +55 -0
  266. google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +521 -0
  267. google/adk/tools/google_search_tool.py +68 -0
  268. google/adk/tools/langchain_tool.py +86 -0
  269. google/adk/tools/load_artifacts_tool.py +113 -0
  270. google/adk/tools/load_memory_tool.py +58 -0
  271. google/adk/tools/load_web_page.py +41 -0
  272. google/adk/tools/long_running_tool.py +39 -0
  273. google/adk/tools/mcp_tool/__init__.py +42 -0
  274. google/adk/tools/mcp_tool/conversion_utils.py +161 -0
  275. google/adk/tools/mcp_tool/mcp_tool.py +113 -0
  276. google/adk/tools/mcp_tool/mcp_toolset.py +272 -0
  277. google/adk/tools/openapi_tool/__init__.py +21 -0
  278. google/adk/tools/openapi_tool/auth/__init__.py +19 -0
  279. google/adk/tools/openapi_tool/auth/auth_helpers.py +498 -0
  280. google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +25 -0
  281. google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +105 -0
  282. google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +55 -0
  283. google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +117 -0
  284. google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +97 -0
  285. google/adk/tools/openapi_tool/common/__init__.py +19 -0
  286. google/adk/tools/openapi_tool/common/common.py +300 -0
  287. google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +32 -0
  288. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +231 -0
  289. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +144 -0
  290. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +260 -0
  291. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +496 -0
  292. google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +268 -0
  293. google/adk/tools/preload_memory_tool.py +72 -0
  294. google/adk/tools/retrieval/__init__.py +36 -0
  295. google/adk/tools/retrieval/base_retrieval_tool.py +37 -0
  296. google/adk/tools/retrieval/files_retrieval.py +33 -0
  297. google/adk/tools/retrieval/llama_index_retrieval.py +41 -0
  298. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +107 -0
  299. google/adk/tools/tool_context.py +90 -0
  300. google/adk/tools/toolbox_tool.py +46 -0
  301. google/adk/tools/transfer_to_agent_tool.py +21 -0
  302. google/adk/tools/vertex_ai_search_tool.py +96 -0
  303. google/adk/version.py +16 -0
  304. google_adk-0.0.1.dist-info/LICENSE.txt → google_adk-0.0.2.dist-info/LICENSE +32 -0
  305. google_adk-0.0.2.dist-info/METADATA +73 -0
  306. google_adk-0.0.2.dist-info/RECORD +308 -0
  307. {google_adk-0.0.1.dist-info → google_adk-0.0.2.dist-info}/WHEEL +1 -2
  308. google_adk-0.0.2.dist-info/entry_points.txt +3 -0
  309. agent_kit/__init__.py +0 -0
  310. google_adk-0.0.1.dist-info/METADATA +0 -15
  311. google_adk-0.0.1.dist-info/RECORD +0 -6
  312. google_adk-0.0.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,19 @@
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 streamlit.components.v1 as components
16
+
17
+ media_streamer = components.declare_component(
18
+ name='media_streamer', path='./media_streamer'
19
+ )
@@ -0,0 +1,228 @@
1
+ <!--
2
+ Copyright 2025 Google LLC
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ -->
16
+
17
+ <html>
18
+ <head>
19
+ <style type="text/css">
20
+ body {
21
+ font-family: sans-serif;
22
+ padding: 10px;
23
+ }
24
+ button {
25
+ font-size: 16px;
26
+ padding: 10px 15px;
27
+ margin-right: 10px;
28
+ }
29
+ #status {
30
+ font-weight: bold;
31
+ }
32
+ /* Mirror the preview video */
33
+ #videoPreview {
34
+ border: 1px solid #ccc;
35
+ transform: scaleX(-1);
36
+ }
37
+ </style>
38
+ </head>
39
+ <body>
40
+ <h2>Audio &amp; Video Recorder Component</h2>
41
+ <!-- Video preview -->
42
+ <video id="videoPreview" autoplay muted playsinline width="320" height="240"></video>
43
+ <br/>
44
+ <!-- Unified start/stop buttons -->
45
+ <button id="startButton" onclick="startRecording()">Start Streaming</button>
46
+ <button id="stopButton" onclick="stopRecording()" disabled>Stop Streaming</button>
47
+ <span id="status">Idle</span>
48
+
49
+ <script type="text/javascript">
50
+ // --- Streamlit component lifecycle constants ---
51
+ const SET_COMPONENT_VALUE = "streamlit:setComponentValue";
52
+ const COMPONENT_READY = "streamlit:componentReady";
53
+ const SET_FRAME_HEIGHT = "streamlit:setFrameHeight";
54
+ const RENDER = "streamlit:render";
55
+
56
+ // Helper function to send messages to the Streamlit host.
57
+ function _sendMessage(type, data) {
58
+ const outboundData = Object.assign({ isStreamlitMessage: true, type: type }, data);
59
+ window.parent.postMessage(outboundData, "*");
60
+ }
61
+ function setFrameHeight(height) {
62
+ _sendMessage(SET_FRAME_HEIGHT, { height: height });
63
+ }
64
+ // This function sends the combined data.
65
+ function notifyHost(data) {
66
+ _sendMessage(SET_COMPONENT_VALUE, data);
67
+ }
68
+ function initialize() {
69
+ _sendMessage(COMPONENT_READY, { apiVersion: 1 });
70
+ window.addEventListener("load", function() {
71
+ setTimeout(() => setFrameHeight(document.documentElement.clientHeight), 0);
72
+ });
73
+ }
74
+ initialize();
75
+
76
+ // --- Global Variables ---
77
+ let isRecording = false;
78
+ let audioContext;
79
+ let scriptProcessor;
80
+ let audioAccumulatedChunks = [];
81
+ let audioFlushIntervalId = null;
82
+ let videoCaptureIntervalId = null;
83
+ const SAMPLE_RATE = 16000;
84
+ const BUFFER_SIZE = 4096;
85
+ let mediaStream = null; // for video (and optionally audio if needed)
86
+
87
+ // Global object to hold combined recording data.
88
+ let recordingData = {};
89
+
90
+ // Instead of calling notifyHost directly, update our combined data and send.
91
+ function sendCombinedUpdate(key, value) {
92
+ recordingData[key] = value;
93
+ notifyHost({
94
+ value: recordingData,
95
+ dataType: "json"
96
+ });
97
+ }
98
+
99
+ const videoElement = document.getElementById("videoPreview");
100
+ const statusSpan = document.getElementById("status");
101
+ const startButton = document.getElementById("startButton");
102
+ const stopButton = document.getElementById("stopButton");
103
+
104
+ // --- Start Recording: Capture both audio and video ---
105
+ async function startRecording() {
106
+ if (isRecording) return;
107
+ isRecording = true;
108
+ startButton.disabled = true;
109
+ stopButton.disabled = false;
110
+ statusSpan.innerText = "Streaming...";
111
+
112
+ // --- Setup audio recording ---
113
+ try {
114
+ audioContext = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: SAMPLE_RATE });
115
+ let audioStream = await navigator.mediaDevices.getUserMedia({ audio: true });
116
+ let mediaStreamSource = audioContext.createMediaStreamSource(audioStream);
117
+ scriptProcessor = audioContext.createScriptProcessor(BUFFER_SIZE, 1, 1);
118
+ scriptProcessor.onaudioprocess = function(event) {
119
+ let inputBuffer = event.inputBuffer;
120
+ let inputData = inputBuffer.getChannelData(0);
121
+ let pcmData = new Int16Array(inputData.length);
122
+ for (let i = 0; i < inputData.length; i++) {
123
+ let s = Math.max(-1, Math.min(1, inputData[i]));
124
+ pcmData[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
125
+ }
126
+ audioAccumulatedChunks.push(pcmData);
127
+ };
128
+ mediaStreamSource.connect(scriptProcessor);
129
+ scriptProcessor.connect(audioContext.destination);
130
+ } catch (err) {
131
+ console.error("Error accessing microphone:", err);
132
+ statusSpan.innerText = "Audio Error: " + err;
133
+ }
134
+
135
+ // --- Setup video recording ---
136
+ try {
137
+ let videoStream = await navigator.mediaDevices.getUserMedia({ video: true });
138
+ videoElement.srcObject = videoStream;
139
+ // Save the video stream so we can stop it later.
140
+ mediaStream = videoStream;
141
+ } catch (err) {
142
+ console.error("Error accessing camera:", err);
143
+ statusSpan.innerText = "Video Error: " + err;
144
+ }
145
+
146
+ // --- Start interval timers for flushing audio and capturing video ---
147
+ videoCaptureIntervalId = setInterval(captureVideoFrame, 250); // every 250ms
148
+ audioFlushIntervalId = setInterval(flushAudioChunks, 250); // every 250ms
149
+ }
150
+
151
+ // --- Stop Recording ---
152
+ function stopRecording() {
153
+ if (!isRecording) return;
154
+ isRecording = false;
155
+ startButton.disabled = false;
156
+ stopButton.disabled = true;
157
+ statusSpan.innerText = "Stopped.";
158
+
159
+ // Stop audio processing
160
+ if (scriptProcessor) {
161
+ scriptProcessor.disconnect();
162
+ scriptProcessor = null;
163
+ }
164
+ if (audioContext) {
165
+ audioContext.close();
166
+ audioContext = null;
167
+ }
168
+ if (audioFlushIntervalId) {
169
+ clearInterval(audioFlushIntervalId);
170
+ audioFlushIntervalId = null;
171
+ }
172
+
173
+ // Stop video stream
174
+ if (mediaStream) {
175
+ mediaStream.getTracks().forEach(track => track.stop());
176
+ mediaStream = null;
177
+ }
178
+ if (videoCaptureIntervalId) {
179
+ clearInterval(videoCaptureIntervalId);
180
+ videoCaptureIntervalId = null;
181
+ }
182
+
183
+ // Flush any remaining audio chunks
184
+ flushAudioChunks();
185
+
186
+ // Final notification that recording has stopped.
187
+ sendCombinedUpdate("message", "Recording stopped");
188
+ sendCombinedUpdate("isRecording", false);
189
+ }
190
+
191
+ // --- Flush accumulated audio chunks ---
192
+ function flushAudioChunks() {
193
+ if (audioAccumulatedChunks.length === 0) return;
194
+ // Combine all audio chunks into one array.
195
+ let totalLength = audioAccumulatedChunks.reduce((sum, chunk) => sum + chunk.length, 0);
196
+ let combined = new Int16Array(totalLength);
197
+ let offset = 0;
198
+ for (let chunk of audioAccumulatedChunks) {
199
+ combined.set(chunk, offset);
200
+ offset += chunk.length;
201
+ }
202
+ audioAccumulatedChunks = []; // clear accumulator
203
+
204
+ // Convert combined PCM data to a Blob.
205
+ let blob = new Blob([combined.buffer], { type: 'application/octet-stream' });
206
+ let reader = new FileReader();
207
+ reader.onloadend = function() {
208
+ // Instead of sending only audio, update the combined data.
209
+ sendCombinedUpdate("audioChunk", reader.result);
210
+ };
211
+ reader.readAsDataURL(blob);
212
+ }
213
+
214
+ // --- Capture a single video frame ---
215
+ function captureVideoFrame() {
216
+ if (!videoElement.srcObject) return;
217
+ const canvas = document.createElement("canvas");
218
+ canvas.width = videoElement.videoWidth || 320;
219
+ canvas.height = videoElement.videoHeight || 240;
220
+ const ctx = canvas.getContext("2d");
221
+ ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
222
+ let dataUrl = canvas.toDataURL("image/jpeg");
223
+ // Instead of a separate notifyHost call, update the combined data.
224
+ sendCombinedUpdate("videoFrame", dataUrl);
225
+ }
226
+ </script>
227
+ </body>
228
+ </html>
@@ -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