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,98 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import Optional
18
+
19
+ from google.genai import types
20
+ from pydantic import BaseModel
21
+ from pydantic import ConfigDict
22
+ from pydantic import Field
23
+
24
+ from ..tools.base_tool import BaseTool
25
+
26
+
27
+ class LlmRequest(BaseModel):
28
+ """LLM request class that allows passing in tools, output schema and system
29
+
30
+ instructions to the model.
31
+
32
+ Attributes:
33
+ model: The model name.
34
+ contents: The contents to send to the model.
35
+ config: Additional config for the generate content request.
36
+ tools_dict: The tools dictionary.
37
+ """
38
+
39
+ model_config = ConfigDict(arbitrary_types_allowed=True)
40
+ """The model config."""
41
+
42
+ model: Optional[str] = None
43
+ """The model name."""
44
+
45
+ contents: list[types.Content] = Field(default_factory=list)
46
+ """The contents to send to the model."""
47
+
48
+ config: Optional[types.GenerateContentConfig] = None
49
+ live_connect_config: types.LiveConnectConfig = types.LiveConnectConfig()
50
+ """Additional config for the generate content request.
51
+
52
+ tools in generate_content_config should not be set.
53
+ """
54
+ tools_dict: dict[str, BaseTool] = Field(default_factory=dict, exclude=True)
55
+ """The tools dictionary."""
56
+
57
+ def append_instructions(self, instructions: list[str]) -> None:
58
+ """Appends instructions to the system instruction.
59
+
60
+ Args:
61
+ instructions: The instructions to append.
62
+ """
63
+
64
+ if self.config.system_instruction:
65
+ self.config.system_instruction += '\n\n' + '\n\n'.join(instructions)
66
+ else:
67
+ self.config.system_instruction = '\n\n'.join(instructions)
68
+
69
+ def append_tools(self, tools: list[BaseTool]) -> None:
70
+ """Appends tools to the request.
71
+
72
+ Args:
73
+ tools: The tools to append.
74
+ """
75
+
76
+ if not tools:
77
+ return
78
+ declarations = []
79
+ for tool in tools:
80
+ if isinstance(tool, BaseTool):
81
+ declaration = tool._get_declaration()
82
+ else:
83
+ declaration = tool.get_declaration()
84
+ if declaration:
85
+ declarations.append(declaration)
86
+ self.tools_dict[tool.name] = tool
87
+ if declarations:
88
+ self.config.tools.append(types.Tool(function_declarations=declarations))
89
+
90
+ def set_output_schema(self, base_model: type[BaseModel]) -> None:
91
+ """Sets the output schema for the request.
92
+
93
+ Args:
94
+ base_model: The pydantic base model to set the output schema to.
95
+ """
96
+
97
+ self.config.response_schema = base_model
98
+ self.config.response_mime_type = 'application/json'
@@ -0,0 +1,111 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import Optional
18
+
19
+ from google.genai import types
20
+ from pydantic import BaseModel
21
+ from pydantic import ConfigDict
22
+
23
+
24
+ class LlmResponse(BaseModel):
25
+ """LLM response class that provides the first candidate response from the
26
+
27
+ model if available. Otherwise, returns error code and message.
28
+
29
+ Attributes:
30
+ content: The content of the response.
31
+ grounding_metadata: The grounding metadata of the response.
32
+ partial: Indicates whether the text content is part of a unfinished text
33
+ stream. Only used for streaming mode and when the content is plain text.
34
+ turn_complete: Indicates whether the response from the model is complete.
35
+ Only used for streaming mode.
36
+ error_code: Error code if the response is an error. Code varies by model.
37
+ error_message: Error message if the response is an error.
38
+ interrupted: Flag indicating that LLM was interrupted when generating the
39
+ content. Usually it's due to user interruption during a bidi streaming.
40
+ """
41
+
42
+ model_config = ConfigDict(extra='forbid')
43
+ """The model config."""
44
+
45
+ content: Optional[types.Content] = None
46
+ """The content of the response."""
47
+
48
+ grounding_metadata: Optional[types.GroundingMetadata] = None
49
+ """The grounding metadata of the response."""
50
+
51
+ partial: Optional[bool] = None
52
+ """Indicates whether the text content is part of a unfinished text stream.
53
+
54
+ Only used for streaming mode and when the content is plain text.
55
+ """
56
+
57
+ turn_complete: Optional[bool] = None
58
+ """Indicates whether the response from the model is complete.
59
+
60
+ Only used for streaming mode.
61
+ """
62
+
63
+ error_code: Optional[str] = None
64
+ """Error code if the response is an error. Code varies by model."""
65
+
66
+ error_message: Optional[str] = None
67
+ """Error message if the response is an error."""
68
+
69
+ interrupted: Optional[bool] = None
70
+ """Flag indicating that LLM was interrupted when generating the content.
71
+ Usually it's due to user interruption during a bidi streaming.
72
+ """
73
+
74
+ @staticmethod
75
+ def create(
76
+ generate_content_response: types.GenerateContentResponse,
77
+ ) -> 'LlmResponse':
78
+ """Creates an LlmResponse from a GenerateContentResponse.
79
+
80
+ Args:
81
+ generate_content_response: The GenerateContentResponse to create the
82
+ LlmResponse from.
83
+
84
+ Returns:
85
+ The LlmResponse.
86
+ """
87
+
88
+ if generate_content_response.candidates:
89
+ candidate = generate_content_response.candidates[0]
90
+ if candidate.content and candidate.content.parts:
91
+ return LlmResponse(
92
+ content=candidate.content,
93
+ grounding_metadata=candidate.grounding_metadata,
94
+ )
95
+ else:
96
+ return LlmResponse(
97
+ error_code=candidate.finish_reason,
98
+ error_message=candidate.finish_message,
99
+ )
100
+ else:
101
+ if generate_content_response.prompt_feedback:
102
+ prompt_feedback = generate_content_response.prompt_feedback
103
+ return LlmResponse(
104
+ error_code=prompt_feedback.block_reason,
105
+ error_message=prompt_feedback.block_reason_message,
106
+ )
107
+ else:
108
+ return LlmResponse(
109
+ error_code='UNKNOWN_ERROR',
110
+ error_message='Unknown error.',
111
+ )
@@ -0,0 +1,102 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """The registry class for model."""
16
+
17
+ from __future__ import annotations
18
+
19
+ from functools import lru_cache
20
+ import logging
21
+ import re
22
+ from typing import TYPE_CHECKING
23
+
24
+ if TYPE_CHECKING:
25
+ from .base_llm import BaseLlm
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+
30
+ _llm_registry_dict: dict[str, type[BaseLlm]] = {}
31
+ """Registry for LLMs.
32
+
33
+ Key is the regex that matches the model name.
34
+ Value is the class that implements the model.
35
+ """
36
+
37
+
38
+ class LLMRegistry:
39
+ """Registry for LLMs."""
40
+
41
+ @staticmethod
42
+ def new_llm(model: str) -> BaseLlm:
43
+ """Creates a new LLM instance.
44
+
45
+ Args:
46
+ model: The model name.
47
+
48
+ Returns:
49
+ The LLM instance.
50
+ """
51
+
52
+ return LLMRegistry.resolve(model)(model=model)
53
+
54
+ @staticmethod
55
+ def _register(model_name_regex: str, llm_cls: type[BaseLlm]):
56
+ """Registers a new LLM class.
57
+
58
+ Args:
59
+ model_name_regex: The regex that matches the model name.
60
+ llm_cls: The class that implements the model.
61
+ """
62
+
63
+ if model_name_regex in _llm_registry_dict:
64
+ logger.info(
65
+ 'Updating LLM class for %s from %s to %s',
66
+ model_name_regex,
67
+ _llm_registry_dict[model_name_regex],
68
+ llm_cls,
69
+ )
70
+
71
+ _llm_registry_dict[model_name_regex] = llm_cls
72
+
73
+ @staticmethod
74
+ def register(llm_cls: type[BaseLlm]):
75
+ """Registers a new LLM class.
76
+
77
+ Args:
78
+ llm_cls: The class that implements the model.
79
+ """
80
+
81
+ for regex in llm_cls.supported_models():
82
+ LLMRegistry._register(regex, llm_cls)
83
+
84
+ @staticmethod
85
+ @lru_cache(maxsize=32)
86
+ def resolve(model: str) -> type[BaseLlm]:
87
+ """Resolves the model to a BaseLlm subclass.
88
+
89
+ Args:
90
+ model: The model name.
91
+
92
+ Returns:
93
+ The BaseLlm subclass.
94
+ Raises:
95
+ ValueError: If the model is not found.
96
+ """
97
+
98
+ for regex, llm_class in _llm_registry_dict.items():
99
+ if re.compile(regex).fullmatch(model):
100
+ return llm_class
101
+
102
+ raise ValueError(f'Model {model} not found.')
@@ -0,0 +1,23 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from .base_planner import BasePlanner
16
+ from .built_in_planner import BuiltInPlanner
17
+ from .plan_re_act_planner import PlanReActPlanner
18
+
19
+ __all__ = [
20
+ 'BasePlanner',
21
+ 'BuiltInPlanner',
22
+ 'PlanReActPlanner',
23
+ ]
@@ -0,0 +1,66 @@
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 abc import ABC
17
+ from typing import List
18
+ from typing import Optional
19
+
20
+ from google.genai import types
21
+
22
+ from ..agents.callback_context import CallbackContext
23
+ from ..agents.readonly_context import ReadonlyContext
24
+ from ..models.llm_request import LlmRequest
25
+
26
+
27
+ class BasePlanner(ABC):
28
+ """Abstract base class for all planners.
29
+
30
+ The planner allows the agent to generate plans for the queries to guide its
31
+ action.
32
+ """
33
+
34
+ @abc.abstractmethod
35
+ def build_planning_instruction(
36
+ self,
37
+ readonly_context: ReadonlyContext,
38
+ llm_request: LlmRequest,
39
+ ) -> Optional[str]:
40
+ """Builds the system instruction to be appended to the LLM request for planning.
41
+
42
+ Args:
43
+ readonly_context: The readonly context of the invocation.
44
+ llm_request: The LLM request. Readonly.
45
+
46
+ Returns:
47
+ The planning system instruction, or None if no instruction is needed.
48
+ """
49
+ pass
50
+
51
+ @abc.abstractmethod
52
+ def process_planning_response(
53
+ self,
54
+ callback_context: CallbackContext,
55
+ response_parts: List[types.Part],
56
+ ) -> Optional[List[types.Part]]:
57
+ """Processes the LLM response for planning.
58
+
59
+ Args:
60
+ callback_context: The callback context of the invocation.
61
+ response_parts: The LLM response parts. Readonly.
62
+
63
+ Returns:
64
+ The processed response parts, or None if no processing is needed.
65
+ """
66
+ pass
@@ -0,0 +1,75 @@
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 List
16
+ from typing import Optional
17
+
18
+ from google.genai import types
19
+ from typing_extensions import override
20
+
21
+ from ..agents.callback_context import CallbackContext
22
+ from ..agents.readonly_context import ReadonlyContext
23
+ from ..models.llm_request import LlmRequest
24
+ from .base_planner import BasePlanner
25
+
26
+
27
+ class BuiltInPlanner(BasePlanner):
28
+ """The built-in planner that uses model's built-in thinking features.
29
+
30
+ Attributes:
31
+ thinking_config: Config for model built-in thinking features. An error
32
+ will be returned if this field is set for models that don't support
33
+ thinking.
34
+ """
35
+
36
+ thinking_config: types.ThinkingConfig
37
+ """
38
+ Config for model built-in thinking features. An error will be returned if this
39
+ field is set for models that don't support thinking.
40
+ """
41
+
42
+ def __init__(self, *, thinking_config: types.ThinkingConfig):
43
+ """Initializes the built-in planner.
44
+
45
+ Args:
46
+ thinking_config: Config for model built-in thinking features. An error
47
+ will be returned if this field is set for models that don't support
48
+ thinking.
49
+ """
50
+ self.thinking_config = thinking_config
51
+
52
+ def apply_thinking_config(self, llm_request: LlmRequest) -> None:
53
+ """Applies the thinking config to the LLM request.
54
+
55
+ Args:
56
+ llm_request: The LLM request to apply the thinking config to.
57
+ """
58
+ if self.thinking_config:
59
+ llm_request.config.thinking_config = self.thinking_config
60
+
61
+ @override
62
+ def build_planning_instruction(
63
+ self,
64
+ readonly_context: ReadonlyContext,
65
+ llm_request: LlmRequest,
66
+ ) -> Optional[str]:
67
+ return
68
+
69
+ @override
70
+ def process_planning_response(
71
+ self,
72
+ callback_context: CallbackContext,
73
+ response_parts: List[types.Part],
74
+ ) -> Optional[List[types.Part]]:
75
+ return
@@ -0,0 +1,208 @@
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 List
16
+ from typing import Optional
17
+
18
+ from google.genai import types
19
+ from typing_extensions import override
20
+
21
+ from ..agents.callback_context import CallbackContext
22
+ from ..agents.readonly_context import ReadonlyContext
23
+ from ..models.llm_request import LlmRequest
24
+ from .base_planner import BasePlanner
25
+
26
+ PLANNING_TAG = '/*PLANNING*/'
27
+ REPLANNING_TAG = '/*REPLANNING*/'
28
+ REASONING_TAG = '/*REASONING*/'
29
+ ACTION_TAG = '/*ACTION*/'
30
+ FINAL_ANSWER_TAG = '/*FINAL_ANSWER*/'
31
+
32
+
33
+ class PlanReActPlanner(BasePlanner):
34
+ """Plan-Re-Act planner that constraints the LLM response to generate a plan before any action/observation.
35
+
36
+ Note: this planner does not require the model to support buil-in thinking
37
+ features or setting the thinking config.
38
+ """
39
+
40
+ @override
41
+ def build_planning_instruction(
42
+ self,
43
+ readonly_context: ReadonlyContext,
44
+ llm_request: LlmRequest,
45
+ ) -> str:
46
+ return self._build_nl_planner_instruction()
47
+
48
+ @override
49
+ def process_planning_response(
50
+ self,
51
+ callback_context: CallbackContext,
52
+ response_parts: List[types.Part],
53
+ ) -> Optional[List[types.Part]]:
54
+ if not response_parts:
55
+ return None
56
+
57
+ preserved_parts = []
58
+ first_fc_part_index = -1
59
+ for i in range(len(response_parts)):
60
+ # Stop at the first (group of) function calls.
61
+ if response_parts[i].function_call:
62
+ # Ignore and filter out function calls with empty names.
63
+ if not response_parts[i].function_call.name:
64
+ continue
65
+ preserved_parts.append(response_parts[i])
66
+ first_fc_part_index = i
67
+ break
68
+
69
+ # Split the response into reasoning and final answer parts.
70
+ self._handle_non_function_call_parts(response_parts[i], preserved_parts)
71
+
72
+ if first_fc_part_index > 0:
73
+ j = first_fc_part_index + 1
74
+ while j < len(response_parts):
75
+ if response_parts[j].function_call:
76
+ preserved_parts.append(response_parts[j])
77
+ j += 1
78
+ else:
79
+ break
80
+
81
+ return preserved_parts
82
+
83
+ def _split_by_last_pattern(self, text, separator):
84
+ """Splits the text by the last occurrence of the separator.
85
+
86
+ Args:
87
+ text: The text to split.
88
+ separator: The separator to split on.
89
+
90
+ Returns:
91
+ A tuple containing the text before the last separator and the text after
92
+ the last separator.
93
+ """
94
+ index = text.rfind(separator)
95
+ if index == -1:
96
+ return text, ''
97
+ return text[: index + len(separator)], text[index + len(separator) :]
98
+
99
+ def _handle_non_function_call_parts(
100
+ self, response_part: types.Part, preserved_parts: list[types.Part]
101
+ ):
102
+ """Handles non-function-call parts of the response.
103
+
104
+ Args:
105
+ response_part: The response part to handle.
106
+ preserved_parts: The mutable list of parts to store the processed parts
107
+ in.
108
+ """
109
+ if response_part.text and FINAL_ANSWER_TAG in response_part.text:
110
+ reasoning_text, final_answer_text = self._split_by_last_pattern(
111
+ response_part.text, FINAL_ANSWER_TAG
112
+ )
113
+ if reasoning_text:
114
+ reasoning_part = types.Part(text=reasoning_text)
115
+ self._mark_as_thought(reasoning_part)
116
+ preserved_parts.append(reasoning_part)
117
+ if final_answer_text:
118
+ preserved_parts.append(
119
+ types.Part(
120
+ text=final_answer_text,
121
+ )
122
+ )
123
+ else:
124
+ response_text = response_part.text or ''
125
+ # If the part is a text part with a planning/reasoning/action tag,
126
+ # label it as reasoning.
127
+ if response_text and (
128
+ any(
129
+ response_text.startswith(tag)
130
+ for tag in [
131
+ PLANNING_TAG,
132
+ REASONING_TAG,
133
+ ACTION_TAG,
134
+ REPLANNING_TAG,
135
+ ]
136
+ )
137
+ ):
138
+ self._mark_as_thought(response_part)
139
+ preserved_parts.append(response_part)
140
+
141
+ def _mark_as_thought(self, response_part: types.Part):
142
+ """Marks the response part as thought.
143
+
144
+ Args:
145
+ response_part: The mutable response part to mark as thought.
146
+ """
147
+ if response_part.text:
148
+ response_part.thought = True
149
+ return
150
+
151
+ def _build_nl_planner_instruction(self) -> str:
152
+ """Builds the NL planner instruction for the Plan-Re-Act planner.
153
+
154
+ Returns:
155
+ NL planner system instruction.
156
+ """
157
+
158
+ high_level_preamble = f"""
159
+ When answering the question, try to leverage the available tools to gather the information instead of your memorized knowledge.
160
+
161
+ Follow this process when answering the question: (1) first come up with a plan in natural language text format; (2) Then use tools to execute the plan and provide reasoning between tool code snippets to make a summary of current state and next step. Tool code snippets and reasoning should be interleaved with each other. (3) In the end, return one final answer.
162
+
163
+ Follow this format when answering the question: (1) The planning part should be under {PLANNING_TAG}. (2) The tool code snippets should be under {ACTION_TAG}, and the reasoning parts should be under {REASONING_TAG}. (3) The final answer part should be under {FINAL_ANSWER_TAG}.
164
+ """
165
+
166
+ planning_preamble = f"""
167
+ Below are the requirements for the planning:
168
+ The plan is made to answer the user query if following the plan. The plan is coherent and covers all aspects of information from user query, and only involves the tools that are accessible by the agent. The plan contains the decomposed steps as a numbered list where each step should use one or multiple available tools. By reading the plan, you can intuitively know which tools to trigger or what actions to take.
169
+ If the initial plan cannot be successfully executed, you should learn from previous execution results and revise your plan. The revised plan should be be under {REPLANNING_TAG}. Then use tools to follow the new plan.
170
+ """
171
+
172
+ reasoning_preamble = """
173
+ Below are the requirements for the reasoning:
174
+ The reasoning makes a summary of the current trajectory based on the user query and tool outputs. Based on the tool outputs and plan, the reasoning also comes up with instructions to the next steps, making the trajectory closer to the final answer.
175
+ """
176
+
177
+ final_answer_preamble = """
178
+ Below are the requirements for the final answer:
179
+ The final answer should be precise and follow query formatting requirements. Some queries may not be answerable with the available tools and information. In those cases, inform the user why you cannot process their query and ask for more information.
180
+ """
181
+
182
+ # Only contains the requirements for custom tool/libraries.
183
+ tool_code_without_python_libraries_preamble = """
184
+ Below are the requirements for the tool code:
185
+
186
+ **Custom Tools:** The available tools are described in the context and can be directly used.
187
+ - Code must be valid self-contained Python snippets with no imports and no references to tools or Python libraries that are not in the context.
188
+ - You cannot use any parameters or fields that are not explicitly defined in the APIs in the context.
189
+ - The code snippets should be readable, efficient, and directly relevant to the user query and reasoning steps.
190
+ - When using the tools, you should use the library name together with the function name, e.g., vertex_search.search().
191
+ - If Python libraries are not provided in the context, NEVER write your own code other than the function calls using the provided tools.
192
+ """
193
+
194
+ user_input_preamble = """
195
+ VERY IMPORTANT instruction that you MUST follow in addition to the above instructions:
196
+
197
+ You should ask for clarification if you need more information to answer the question.
198
+ You should prefer using the information available in the context instead of repeated tool use.
199
+ """
200
+
201
+ return '\n\n'.join([
202
+ high_level_preamble,
203
+ planning_preamble,
204
+ reasoning_preamble,
205
+ final_answer_preamble,
206
+ tool_code_without_python_libraries_preamble,
207
+ user_input_preamble,
208
+ ])