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,206 @@
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 copy
16
+ import time
17
+ from typing import Any
18
+ from typing import Optional
19
+ import uuid
20
+
21
+ from typing_extensions import override
22
+
23
+ from ..events.event import Event
24
+ from .base_session_service import BaseSessionService
25
+ from .base_session_service import GetSessionConfig
26
+ from .base_session_service import ListEventsResponse
27
+ from .base_session_service import ListSessionsResponse
28
+ from .session import Session
29
+ from .state import State
30
+
31
+
32
+ class InMemorySessionService(BaseSessionService):
33
+ """An in-memory implementation of the session service."""
34
+
35
+ def __init__(self):
36
+ # A map from app name to a map from user ID to a map from session ID to session.
37
+ self.sessions: dict[str, dict[str, dict[str, Session]]] = {}
38
+ # A map from app name to a map from user ID to a map from key to the value.
39
+ self.user_state: dict[str, dict[str, dict[str, Any]]] = {}
40
+ # A map from app name to a map from key to the value.
41
+ self.app_state: dict[str, dict[str, Any]] = {}
42
+
43
+ @override
44
+ def create_session(
45
+ self,
46
+ *,
47
+ app_name: str,
48
+ user_id: str,
49
+ state: Optional[dict[str, Any]] = None,
50
+ session_id: Optional[str] = None,
51
+ ) -> Session:
52
+ session_id = (
53
+ session_id.strip()
54
+ if session_id and session_id.strip()
55
+ else str(uuid.uuid4())
56
+ )
57
+ session = Session(
58
+ app_name=app_name,
59
+ user_id=user_id,
60
+ id=session_id,
61
+ state=state or {},
62
+ last_update_time=time.time(),
63
+ )
64
+
65
+ if app_name not in self.sessions:
66
+ self.sessions[app_name] = {}
67
+ if user_id not in self.sessions[app_name]:
68
+ self.sessions[app_name][user_id] = {}
69
+ self.sessions[app_name][user_id][session_id] = session
70
+
71
+ copied_session = copy.deepcopy(session)
72
+ return self._merge_state(app_name, user_id, copied_session)
73
+
74
+ @override
75
+ def get_session(
76
+ self,
77
+ *,
78
+ app_name: str,
79
+ user_id: str,
80
+ session_id: str,
81
+ config: Optional[GetSessionConfig] = None,
82
+ ) -> Session:
83
+ if app_name not in self.sessions:
84
+ return None
85
+ if user_id not in self.sessions[app_name]:
86
+ return None
87
+ if session_id not in self.sessions[app_name][user_id]:
88
+ return None
89
+
90
+ session = self.sessions[app_name][user_id].get(session_id)
91
+ copied_session = copy.deepcopy(session)
92
+
93
+ if config:
94
+ if config.num_recent_events:
95
+ copied_session.events = copied_session.events[
96
+ -config.num_recent_events :
97
+ ]
98
+ elif config.after_timestamp:
99
+ i = len(session.events) - 1
100
+ while i >= 0:
101
+ if copied_session.events[i].timestamp < config.after_timestamp:
102
+ break
103
+ i -= 1
104
+ if i >= 0:
105
+ copied_session.events = copied_session.events[i:]
106
+
107
+ return self._merge_state(app_name, user_id, copied_session)
108
+
109
+ def _merge_state(self, app_name: str, user_id: str, copied_session: Session):
110
+ # Merge app state
111
+ if app_name in self.app_state:
112
+ for key in self.app_state[app_name].keys():
113
+ copied_session.state[State.APP_PREFIX + key] = self.app_state[app_name][
114
+ key
115
+ ]
116
+
117
+ if (
118
+ app_name not in self.user_state
119
+ or user_id not in self.user_state[app_name]
120
+ ):
121
+ return copied_session
122
+
123
+ # Merge session state with user state.
124
+ for key in self.user_state[app_name][user_id].keys():
125
+ copied_session.state[State.USER_PREFIX + key] = self.user_state[app_name][
126
+ user_id
127
+ ][key]
128
+ return copied_session
129
+
130
+ @override
131
+ def list_sessions(
132
+ self, *, app_name: str, user_id: str
133
+ ) -> ListSessionsResponse:
134
+ empty_response = ListSessionsResponse()
135
+ if app_name not in self.sessions:
136
+ return empty_response
137
+ if user_id not in self.sessions[app_name]:
138
+ return empty_response
139
+
140
+ sessions_without_events = []
141
+ for session in self.sessions[app_name][user_id].values():
142
+ copied_session = copy.deepcopy(session)
143
+ copied_session.events = []
144
+ copied_session.state = {}
145
+ sessions_without_events.append(copied_session)
146
+ return ListSessionsResponse(sessions=sessions_without_events)
147
+
148
+ @override
149
+ def delete_session(
150
+ self, *, app_name: str, user_id: str, session_id: str
151
+ ) -> None:
152
+ if (
153
+ self.get_session(
154
+ app_name=app_name, user_id=user_id, session_id=session_id
155
+ )
156
+ is None
157
+ ):
158
+ return None
159
+
160
+ self.sessions[app_name][user_id].pop(session_id)
161
+
162
+ @override
163
+ def append_event(self, session: Session, event: Event) -> Event:
164
+ # Update the in-memory session.
165
+ super().append_event(session=session, event=event)
166
+ session.last_update_time = event.timestamp
167
+
168
+ # Update the storage session
169
+ app_name = session.app_name
170
+ user_id = session.user_id
171
+ session_id = session.id
172
+ if app_name not in self.sessions:
173
+ return event
174
+ if user_id not in self.sessions[app_name]:
175
+ return event
176
+ if session_id not in self.sessions[app_name][user_id]:
177
+ return event
178
+
179
+ if event.actions and event.actions.state_delta:
180
+ for key in event.actions.state_delta:
181
+ if key.startswith(State.APP_PREFIX):
182
+ self.app_state.setdefault(app_name, {})[
183
+ key.removeprefix(State.APP_PREFIX)
184
+ ] = event.actions.state_delta[key]
185
+
186
+ if key.startswith(State.USER_PREFIX):
187
+ self.user_state.setdefault(app_name, {}).setdefault(user_id, {})[
188
+ key.removeprefix(State.USER_PREFIX)
189
+ ] = event.actions.state_delta[key]
190
+
191
+ storage_session = self.sessions[app_name][user_id].get(session_id)
192
+ super().append_event(session=storage_session, event=event)
193
+
194
+ storage_session.last_update_time = event.timestamp
195
+
196
+ return event
197
+
198
+ @override
199
+ def list_events(
200
+ self,
201
+ *,
202
+ app_name: str,
203
+ user_id: str,
204
+ session_id: str,
205
+ ) -> ListEventsResponse:
206
+ raise NotImplementedError()
@@ -0,0 +1,54 @@
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 pydantic import BaseModel
18
+ from pydantic import ConfigDict
19
+ from pydantic import Field
20
+
21
+ from ..events.event import Event
22
+
23
+
24
+ class Session(BaseModel):
25
+ """Represents a series of interactions between a user and agents.
26
+
27
+ Attributes:
28
+ id: The unique identifier of the session.
29
+ app_name: The name of the app.
30
+ user_id: The id of the user.
31
+ state: The state of the session.
32
+ events: The events of the session, e.g. user input, model response, function
33
+ call/response, etc.
34
+ last_update_time: The last update time of the session.
35
+ """
36
+
37
+ model_config = ConfigDict(
38
+ extra='forbid',
39
+ arbitrary_types_allowed=True,
40
+ )
41
+
42
+ id: str
43
+ """The unique identifier of the session."""
44
+ app_name: str
45
+ """The name of the app."""
46
+ user_id: str
47
+ """The id of the user."""
48
+ state: dict[str, Any] = Field(default_factory=dict)
49
+ """The state of the session."""
50
+ events: list[Event] = Field(default_factory=list)
51
+ """The events of the session, e.g. user input, model response, function
52
+ call/response, etc."""
53
+ last_update_time: float = 0.0
54
+ """The last update time of the session."""
@@ -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 typing import Any
16
+
17
+
18
+ class State:
19
+ """A state dict that maintain the current value and the pending-commit delta."""
20
+
21
+ APP_PREFIX = "app:"
22
+ USER_PREFIX = "user:"
23
+ TEMP_PREFIX = "temp:"
24
+
25
+ def __init__(self, value: dict[str, Any], delta: dict[str, Any]):
26
+ """
27
+ Args:
28
+ value: The current value of the state dict.
29
+ delta: The delta change to the current value that hasn't been commited.
30
+ """
31
+ self._value = value
32
+ self._delta = delta
33
+
34
+ def __getitem__(self, key: str) -> Any:
35
+ """Returns the value of the state dict for the given key."""
36
+ if key in self._delta:
37
+ return self._delta[key]
38
+ return self._value[key]
39
+
40
+ def __setitem__(self, key: str, value: Any):
41
+ """Sets the value of the state dict for the given key."""
42
+ # TODO: make new change only store in delta, so that self._value is only
43
+ # updated at the storage commit time.
44
+ self._value[key] = value
45
+ self._delta[key] = value
46
+
47
+ def __contains__(self, key: str) -> bool:
48
+ """Whether the state dict contains the given key."""
49
+ return key in self._value or key in self._delta
50
+
51
+ def has_delta(self) -> bool:
52
+ """Whether the state has pending detla."""
53
+ return bool(self._delta)
54
+
55
+ def get(self, key: str, default: Any = None) -> Any:
56
+ """Returns the value of the state dict for the given key."""
57
+ if key not in self:
58
+ return default
59
+ return self[key]
60
+
61
+ def update(self, delta: dict[str, Any]):
62
+ """Updates the state dict with the given delta."""
63
+ self._value.update(delta)
64
+ self._delta.update(delta)
65
+
66
+ def to_dict(self) -> dict[str, Any]:
67
+ """Returns the state dict."""
68
+ result = {}
69
+ result.update(self._value)
70
+ result.update(self._delta)
71
+ return result
@@ -0,0 +1,356 @@
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
+ import logging
15
+ import re
16
+ import time
17
+ from typing import Any
18
+ from typing import Optional
19
+
20
+ from dateutil.parser import isoparse
21
+ from google import genai
22
+ from typing_extensions import override
23
+
24
+ from ..events.event import Event
25
+ from ..events.event_actions import EventActions
26
+ from .base_session_service import BaseSessionService
27
+ from .base_session_service import GetSessionConfig
28
+ from .base_session_service import ListEventsResponse
29
+ from .base_session_service import ListSessionsResponse
30
+ from .session import Session
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ class VertexAiSessionService(BaseSessionService):
36
+ """Connects to the managed Vertex AI Session Service."""
37
+
38
+ def __init__(
39
+ self,
40
+ project: str = None,
41
+ location: str = None,
42
+ ):
43
+ self.project = project
44
+ self.location = location
45
+
46
+ client = genai.Client(vertexai=True, project=project, location=location)
47
+ self.api_client = client._api_client
48
+
49
+ @override
50
+ def create_session(
51
+ self,
52
+ *,
53
+ app_name: str,
54
+ user_id: str,
55
+ state: Optional[dict[str, Any]] = None,
56
+ session_id: Optional[str] = None,
57
+ ) -> Session:
58
+ reasoning_engine_id = _parse_reasoning_engine_id(app_name)
59
+
60
+ session_json_dict = {'user_id': user_id}
61
+ if state:
62
+ session_json_dict['session_state'] = state
63
+
64
+ api_response = self.api_client.request(
65
+ http_method='POST',
66
+ path=f'reasoningEngines/{reasoning_engine_id}/sessions',
67
+ request_dict=session_json_dict,
68
+ )
69
+ logger.info(f'Create Session response {api_response}')
70
+
71
+ session_id = api_response['name'].split('/')[-3]
72
+ operation_id = api_response['name'].split('/')[-1]
73
+
74
+ max_retry_attempt = 5
75
+ while max_retry_attempt >= 0:
76
+ lro_response = self.api_client.request(
77
+ http_method='GET',
78
+ path=f'operations/{operation_id}',
79
+ request_dict={},
80
+ )
81
+
82
+ if lro_response.get('done', None):
83
+ break
84
+
85
+ time.sleep(1)
86
+ max_retry_attempt -= 1
87
+
88
+ # Get session resource
89
+ get_session_api_response = self.api_client.request(
90
+ http_method='GET',
91
+ path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
92
+ request_dict={},
93
+ )
94
+
95
+ update_timestamp = isoparse(
96
+ get_session_api_response['updateTime']
97
+ ).timestamp()
98
+ session = Session(
99
+ app_name=str(app_name),
100
+ user_id=str(user_id),
101
+ id=str(session_id),
102
+ state=get_session_api_response.get('sessionState', {}),
103
+ last_update_time=update_timestamp,
104
+ )
105
+ return session
106
+
107
+ @override
108
+ def get_session(
109
+ self,
110
+ *,
111
+ app_name: str,
112
+ user_id: str,
113
+ session_id: str,
114
+ config: Optional[GetSessionConfig] = None,
115
+ ) -> Session:
116
+ reasoning_engine_id = _parse_reasoning_engine_id(app_name)
117
+
118
+ # Get session resource
119
+ get_session_api_response = self.api_client.request(
120
+ http_method='GET',
121
+ path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
122
+ request_dict={},
123
+ )
124
+
125
+ session_id = get_session_api_response['name'].split('/')[-1]
126
+ update_timestamp = isoparse(
127
+ get_session_api_response['updateTime']
128
+ ).timestamp()
129
+ session = Session(
130
+ app_name=str(app_name),
131
+ user_id=str(user_id),
132
+ id=str(session_id),
133
+ state=get_session_api_response.get('sessionState', {}),
134
+ last_update_time=update_timestamp,
135
+ )
136
+
137
+ list_events_api_response = self.api_client.request(
138
+ http_method='GET',
139
+ path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}/events',
140
+ request_dict={},
141
+ )
142
+
143
+ # Handles empty response case
144
+ if list_events_api_response.get('httpHeaders', None):
145
+ return session
146
+
147
+ session.events = [
148
+ _from_api_event(event)
149
+ for event in list_events_api_response['sessionEvents']
150
+ ]
151
+ session.events = [
152
+ event for event in session.events if event.timestamp <= update_timestamp
153
+ ]
154
+ session.events.sort(key=lambda event: event.timestamp)
155
+
156
+ if config:
157
+ if config.num_recent_events:
158
+ session.events = session.events[-config.num_recent_events :]
159
+ elif config.after_timestamp:
160
+ i = len(session.events) - 1
161
+ while i >= 0:
162
+ if session.events[i].timestamp < config.after_timestamp:
163
+ break
164
+ i -= 1
165
+ if i >= 0:
166
+ session.events = session.events[i:]
167
+
168
+ return session
169
+
170
+ @override
171
+ def list_sessions(
172
+ self, *, app_name: str, user_id: str
173
+ ) -> ListSessionsResponse:
174
+ reasoning_engine_id = _parse_reasoning_engine_id(app_name)
175
+
176
+ api_response = self.api_client.request(
177
+ http_method='GET',
178
+ path=f'reasoningEngines/{reasoning_engine_id}/sessions?filter=user_id={user_id}',
179
+ request_dict={},
180
+ )
181
+
182
+ # Handles empty response case
183
+ if api_response.get('httpHeaders', None):
184
+ return ListSessionsResponse()
185
+
186
+ sessions = []
187
+ for api_session in api_response['sessions']:
188
+ session = Session(
189
+ app_name=app_name,
190
+ user_id=user_id,
191
+ id=api_session['name'].split('/')[-1],
192
+ state={},
193
+ last_update_time=isoparse(api_session['updateTime']).timestamp(),
194
+ )
195
+ sessions.append(session)
196
+ return ListSessionsResponse(sessions=sessions)
197
+
198
+ def delete_session(
199
+ self, *, app_name: str, user_id: str, session_id: str
200
+ ) -> None:
201
+ reasoning_engine_id = _parse_reasoning_engine_id(app_name)
202
+ self.api_client.request(
203
+ http_method='DELETE',
204
+ path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
205
+ request_dict={},
206
+ )
207
+
208
+ @override
209
+ def list_events(
210
+ self,
211
+ *,
212
+ app_name: str,
213
+ user_id: str,
214
+ session_id: str,
215
+ ) -> ListEventsResponse:
216
+ reasoning_engine_id = _parse_reasoning_engine_id(app_name)
217
+ api_response = self.api_client.request(
218
+ http_method='GET',
219
+ path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}/events',
220
+ request_dict={},
221
+ )
222
+
223
+ logger.info(f'List events response {api_response}')
224
+
225
+ # Handles empty response case
226
+ if api_response.get('httpHeaders', None):
227
+ return ListEventsResponse()
228
+
229
+ session_events = api_response['sessionEvents']
230
+
231
+ return ListEventsResponse(
232
+ events=[_from_api_event(event) for event in session_events]
233
+ )
234
+
235
+ @override
236
+ def append_event(self, session: Session, event: Event) -> Event:
237
+ # Update the in-memory session.
238
+ super().append_event(session=session, event=event)
239
+
240
+ reasoning_engine_id = _parse_reasoning_engine_id(session.app_name)
241
+ self.api_client.request(
242
+ http_method='POST',
243
+ path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session.id}:appendEvent',
244
+ request_dict=_convert_event_to_json(event),
245
+ )
246
+
247
+ return event
248
+
249
+
250
+ def _convert_event_to_json(event: Event):
251
+ metadata_json = {
252
+ 'partial': event.partial,
253
+ 'turn_complete': event.turn_complete,
254
+ 'interrupted': event.interrupted,
255
+ 'branch': event.branch,
256
+ 'long_running_tool_ids': (
257
+ list(event.long_running_tool_ids)
258
+ if event.long_running_tool_ids
259
+ else None
260
+ ),
261
+ }
262
+ if event.grounding_metadata:
263
+ metadata_json['grounding_metadata'] = event.grounding_metadata.model_dump(
264
+ exclude_none=True
265
+ )
266
+
267
+ event_json = {
268
+ 'author': event.author,
269
+ 'invocation_id': event.invocation_id,
270
+ 'timestamp': {
271
+ 'seconds': int(event.timestamp),
272
+ 'nanos': int(
273
+ (event.timestamp - int(event.timestamp)) * 1_000_000_000
274
+ ),
275
+ },
276
+ 'error_code': event.error_code,
277
+ 'error_message': event.error_message,
278
+ 'event_metadata': metadata_json,
279
+ }
280
+
281
+ if event.actions:
282
+ actions_json = {
283
+ 'skip_summarization': event.actions.skip_summarization,
284
+ 'state_delta': event.actions.state_delta,
285
+ 'artifact_delta': event.actions.artifact_delta,
286
+ 'transfer_agent': event.actions.transfer_to_agent,
287
+ 'escalate': event.actions.escalate,
288
+ 'requested_auth_configs': event.actions.requested_auth_configs,
289
+ }
290
+ event_json['actions'] = actions_json
291
+ if event.content:
292
+ event_json['content'] = event.content.model_dump(exclude_none=True)
293
+ if event.error_code:
294
+ event_json['error_code'] = event.error_code
295
+ if event.error_message:
296
+ event_json['error_message'] = event.error_message
297
+ return event_json
298
+
299
+
300
+ def _from_api_event(api_event: dict) -> Event:
301
+ event_actions = EventActions()
302
+ if api_event.get('actions', None):
303
+ event_actions = EventActions(
304
+ skip_summarization=api_event['actions'].get('skipSummarization', None),
305
+ state_delta=api_event['actions'].get('stateDelta', {}),
306
+ artifact_delta=api_event['actions'].get('artifactDelta', {}),
307
+ transfer_to_agent=api_event['actions'].get('transferAgent', None),
308
+ escalate=api_event['actions'].get('escalate', None),
309
+ requested_auth_configs=api_event['actions'].get(
310
+ 'requestedAuthConfigs', {}
311
+ ),
312
+ )
313
+
314
+ event = Event(
315
+ id=api_event['name'].split('/')[-1],
316
+ invocation_id=api_event['invocationId'],
317
+ author=api_event['author'],
318
+ actions=event_actions,
319
+ content=api_event.get('content', None),
320
+ timestamp=isoparse(api_event['timestamp']).timestamp(),
321
+ error_code=api_event.get('errorCode', None),
322
+ error_message=api_event.get('errorMessage', None),
323
+ )
324
+
325
+ if api_event.get('eventMetadata', None):
326
+ long_running_tool_ids_list = api_event['eventMetadata'].get(
327
+ 'longRunningToolIds', None
328
+ )
329
+ event.partial = api_event['eventMetadata'].get('partial', None)
330
+ event.turn_complete = api_event['eventMetadata'].get('turnComplete', None)
331
+ event.interrupted = api_event['eventMetadata'].get('interrupted', None)
332
+ event.branch = api_event['eventMetadata'].get('branch', None)
333
+ event.grounding_metadata = api_event['eventMetadata'].get(
334
+ 'groundingMetadata', None
335
+ )
336
+ event.long_running_tool_ids = (
337
+ set(long_running_tool_ids_list) if long_running_tool_ids_list else None
338
+ )
339
+
340
+ return event
341
+
342
+
343
+ def _parse_reasoning_engine_id(app_name: str):
344
+ if app_name.isdigit():
345
+ return app_name
346
+
347
+ pattern = r'^projects/([a-zA-Z0-9-_]+)/locations/([a-zA-Z0-9-_]+)/reasoningEngines/(\d+)$'
348
+ match = re.fullmatch(pattern, app_name)
349
+
350
+ if not bool(match):
351
+ raise ValueError(
352
+ f'App name {app_name} is not valid. It should either be the full'
353
+ ' ReasoningEngine resource name, or the reasoning engine id.'
354
+ )
355
+
356
+ return match.groups()[-1]