legate 0.1.0

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 (317) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +345 -0
  4. data/bin/legate +13 -0
  5. data/examples/00_quickstart.rb +51 -0
  6. data/examples/01_simple_agent.rb +105 -0
  7. data/examples/02_multi_tool_agent.rb +140 -0
  8. data/examples/03_custom_tool.rb +93 -0
  9. data/examples/04_agent_instructions.rb +84 -0
  10. data/examples/05_state_and_sessions.rb +91 -0
  11. data/examples/06_callbacks.rb +186 -0
  12. data/examples/07_async_jobs.rb +112 -0
  13. data/examples/08_loop_agent.rb +197 -0
  14. data/examples/09_sequential_workflow.rb +40 -0
  15. data/examples/10_parallel_workflow.rb +34 -0
  16. data/examples/11_agent_delegation.rb +24 -0
  17. data/examples/12_http_client_tool.rb +156 -0
  18. data/examples/13_authentication.rb +220 -0
  19. data/examples/14_mcp_client.rb +154 -0
  20. data/examples/15_mcp_server.rb +79 -0
  21. data/examples/16_webhooks.rb +91 -0
  22. data/examples/README_sequential_agents.md +164 -0
  23. data/examples/advanced/auth/cookie_auth_tool.rb +146 -0
  24. data/examples/advanced/auth/custom_auth_flows_example.rb +626 -0
  25. data/examples/advanced/auth/excon_middleware.rb +317 -0
  26. data/examples/advanced/auth/excon_middleware_auth.rb +399 -0
  27. data/examples/advanced/auth/fiber_auth_example.rb +281 -0
  28. data/examples/advanced/auth/fiber_oidc_example.rb +403 -0
  29. data/examples/advanced/auth/httpbin_bearer_tool.rb +159 -0
  30. data/examples/advanced/auth/oauth2_auth.rb +419 -0
  31. data/examples/advanced/auth/oidc_auth.rb +514 -0
  32. data/examples/advanced/auth/openweather_api.rb +251 -0
  33. data/examples/advanced/auth/openweather_tool.rb +153 -0
  34. data/examples/advanced/auth/query_param_middleware_test.rb +138 -0
  35. data/examples/advanced/auth/service_account.rb +135 -0
  36. data/examples/advanced/auth/test_with_httpbin.rb +202 -0
  37. data/examples/advanced/auth/token_lifecycle_example.rb +428 -0
  38. data/examples/advanced/callback_monitoring.rb +679 -0
  39. data/examples/advanced/mas/fixed_delegation_example.rb +191 -0
  40. data/examples/advanced/mas/loop_workflow.rb +28 -0
  41. data/examples/advanced/mas/mock_planner.rb +77 -0
  42. data/examples/advanced/mas/proper_delegation_example.rb +276 -0
  43. data/examples/advanced/mcp/legate_mcp_server_resource_example.rb +182 -0
  44. data/examples/advanced/mcp/mcp_resource_server_example.rb +309 -0
  45. data/examples/advanced/mcp/mcp_server_async.rb +76 -0
  46. data/examples/advanced/mcp/mcp_server_async_tools.rb +122 -0
  47. data/examples/advanced/mcp/mcp_server_legate_agent.rb +95 -0
  48. data/examples/advanced/mcp/mcp_server_rack.rb +89 -0
  49. data/examples/advanced/random_calculator.rb +104 -0
  50. data/examples/advanced/sleep_agent.rb +153 -0
  51. data/examples/advanced/webhooks/webhook_e2e_runner.rb +110 -0
  52. data/examples/advanced/webhooks/webhook_receiver_agent.rb +58 -0
  53. data/examples/advanced/workflows/task_refinement_loop_agent.rb +278 -0
  54. data/examples/advanced/workflows/travel_planner_auto_sequential.rb +444 -0
  55. data/examples/advanced/workflows/travel_planner_parallel.rb +656 -0
  56. data/examples/advanced/workflows/travel_planner_sequential.rb +512 -0
  57. data/examples/tools/oauth2_example.rb +136 -0
  58. data/examples/tools/sleepy_tool.rb +42 -0
  59. data/lib/legate/activity_log.rb +71 -0
  60. data/lib/legate/agent.rb +959 -0
  61. data/lib/legate/agent_code_generator.rb +185 -0
  62. data/lib/legate/agent_definition.rb +812 -0
  63. data/lib/legate/agentic/decision.rb +49 -0
  64. data/lib/legate/agentic/loop.rb +134 -0
  65. data/lib/legate/agentic.rb +5 -0
  66. data/lib/legate/agents/loop_agent.rb +248 -0
  67. data/lib/legate/agents/parallel_agent.rb +163 -0
  68. data/lib/legate/agents/sequential_agent.rb +190 -0
  69. data/lib/legate/agents.rb +14 -0
  70. data/lib/legate/auth/config.rb +148 -0
  71. data/lib/legate/auth/coordinator.rb +218 -0
  72. data/lib/legate/auth/coordinators/oauth2_coordinator.rb +99 -0
  73. data/lib/legate/auth/coordinators/oidc_coordinator.rb +68 -0
  74. data/lib/legate/auth/coordinators/service_account_coordinator.rb +122 -0
  75. data/lib/legate/auth/credential.rb +157 -0
  76. data/lib/legate/auth/encryption.rb +108 -0
  77. data/lib/legate/auth/error.rb +94 -0
  78. data/lib/legate/auth/exchanged_credential.rb +180 -0
  79. data/lib/legate/auth/excon_middleware.rb +285 -0
  80. data/lib/legate/auth/http_client_utils.rb +364 -0
  81. data/lib/legate/auth/manager.rb +531 -0
  82. data/lib/legate/auth/manager_store.rb +394 -0
  83. data/lib/legate/auth/middleware_factory.rb +290 -0
  84. data/lib/legate/auth/runner.rb +279 -0
  85. data/lib/legate/auth/scheme.rb +125 -0
  86. data/lib/legate/auth/schemes/api_key.rb +212 -0
  87. data/lib/legate/auth/schemes/google_service_account.rb +108 -0
  88. data/lib/legate/auth/schemes/http_bearer.rb +98 -0
  89. data/lib/legate/auth/schemes/oauth2.rb +396 -0
  90. data/lib/legate/auth/schemes/openid_connect.rb +346 -0
  91. data/lib/legate/auth/schemes/service_account.rb +388 -0
  92. data/lib/legate/auth/schemes.rb +40 -0
  93. data/lib/legate/auth/token_manager.rb +362 -0
  94. data/lib/legate/auth/token_store.rb +86 -0
  95. data/lib/legate/auth/tool_context_extension.rb +97 -0
  96. data/lib/legate/auth/tool_integration.rb +188 -0
  97. data/lib/legate/auth/url_guard.rb +81 -0
  98. data/lib/legate/auth.rb +453 -0
  99. data/lib/legate/callbacks/callback_context.rb +71 -0
  100. data/lib/legate/cli/agent_commands.rb +950 -0
  101. data/lib/legate/cli/auth_commands.rb +520 -0
  102. data/lib/legate/cli/base_command.rb +24 -0
  103. data/lib/legate/cli/deployment_commands.rb +934 -0
  104. data/lib/legate/cli/output_helper.rb +108 -0
  105. data/lib/legate/cli/session_commands.rb +138 -0
  106. data/lib/legate/cli/skaffold_commands.rb +223 -0
  107. data/lib/legate/cli/tool_commands.rb +261 -0
  108. data/lib/legate/cli/web_commands.rb +182 -0
  109. data/lib/legate/cli.rb +40 -0
  110. data/lib/legate/configuration/webhooks.rb +113 -0
  111. data/lib/legate/configuration.rb +39 -0
  112. data/lib/legate/definition_store.rb +23 -0
  113. data/lib/legate/errors.rb +118 -0
  114. data/lib/legate/event.rb +161 -0
  115. data/lib/legate/gemini_ai_beta_patch.rb +39 -0
  116. data/lib/legate/generators/agent_generator.rb +412 -0
  117. data/lib/legate/generators/code_validator.rb +48 -0
  118. data/lib/legate/generators/legate/install_generator.rb +35 -0
  119. data/lib/legate/generators/legate/templates/create_legate_tables.rb.tt +36 -0
  120. data/lib/legate/generators/legate/templates/initializer.rb +18 -0
  121. data/lib/legate/generators/runtime_tool_loader.rb +76 -0
  122. data/lib/legate/generators/tool_generator.rb +408 -0
  123. data/lib/legate/generators.rb +11 -0
  124. data/lib/legate/global_definition_registry.rb +506 -0
  125. data/lib/legate/global_tool_manager.rb +135 -0
  126. data/lib/legate/llm/adapter.rb +69 -0
  127. data/lib/legate/llm/gemini.rb +172 -0
  128. data/lib/legate/llm/ollama.rb +80 -0
  129. data/lib/legate/llm.rb +34 -0
  130. data/lib/legate/mcp/client.rb +320 -0
  131. data/lib/legate/mcp/connection/sse.rb +292 -0
  132. data/lib/legate/mcp/connection/stdio.rb +273 -0
  133. data/lib/legate/mcp/connection_manager.rb +103 -0
  134. data/lib/legate/mcp/server/legate_agent_adapter.rb +170 -0
  135. data/lib/legate/mcp/server/legate_direct_agent_adapter.rb +140 -0
  136. data/lib/legate/mcp/server/legate_tool_adapter.rb +119 -0
  137. data/lib/legate/mcp/tool_wrapper.rb +138 -0
  138. data/lib/legate/mcp/util/schema_converter.rb +134 -0
  139. data/lib/legate/mcp.rb +23 -0
  140. data/lib/legate/plan_executor.rb +375 -0
  141. data/lib/legate/planner.rb +839 -0
  142. data/lib/legate/rails/railtie.rb +43 -0
  143. data/lib/legate/rails.rb +9 -0
  144. data/lib/legate/redaction.rb +32 -0
  145. data/lib/legate/session.rb +299 -0
  146. data/lib/legate/session_service/active_record.rb +300 -0
  147. data/lib/legate/session_service/base.rb +68 -0
  148. data/lib/legate/session_service/event_broadcast.rb +74 -0
  149. data/lib/legate/session_service/in_memory.rb +188 -0
  150. data/lib/legate/tool/metadata_dsl.rb +122 -0
  151. data/lib/legate/tool.rb +276 -0
  152. data/lib/legate/tool_code_generator.rb +103 -0
  153. data/lib/legate/tool_context.rb +350 -0
  154. data/lib/legate/tool_loader.rb +39 -0
  155. data/lib/legate/tool_registry.rb +73 -0
  156. data/lib/legate/tool_result.rb +61 -0
  157. data/lib/legate/tools/agent_tool.rb +187 -0
  158. data/lib/legate/tools/base/http_client.rb +319 -0
  159. data/lib/legate/tools/base/safe_url.rb +56 -0
  160. data/lib/legate/tools/base_async_job_tool.rb +91 -0
  161. data/lib/legate/tools/calculator.rb +89 -0
  162. data/lib/legate/tools/cat_facts.rb +81 -0
  163. data/lib/legate/tools/check_job_status_tool.rb +48 -0
  164. data/lib/legate/tools/current_time_tool.rb +64 -0
  165. data/lib/legate/tools/echo.rb +43 -0
  166. data/lib/legate/tools/http_request_tool.rb +105 -0
  167. data/lib/legate/tools/random_number_tool.rb +64 -0
  168. data/lib/legate/tools/read_webpage_tool.rb +92 -0
  169. data/lib/legate/tools/sleepy_tool.rb +74 -0
  170. data/lib/legate/tools/webhook_tool.rb +146 -0
  171. data/lib/legate/version.rb +5 -0
  172. data/lib/legate/web/app.rb +984 -0
  173. data/lib/legate/web/public/css/main.css +4980 -0
  174. data/lib/legate/web/public/images/favicon-256.png +0 -0
  175. data/lib/legate/web/public/images/favicon-32.png +0 -0
  176. data/lib/legate/web/public/images/legate-logo-dark.png +0 -0
  177. data/lib/legate/web/public/images/legate-logo-light.png +0 -0
  178. data/lib/legate/web/public/js/legate.js +616 -0
  179. data/lib/legate/web/public/styles/main.scss +4402 -0
  180. data/lib/legate/web/routes/agent_authentication_routes.rb +530 -0
  181. data/lib/legate/web/routes/agent_definition_routes.rb +803 -0
  182. data/lib/legate/web/routes/agent_generator_routes.rb +80 -0
  183. data/lib/legate/web/routes/agent_interaction_routes.rb +734 -0
  184. data/lib/legate/web/routes/agent_runtime_routes.rb +323 -0
  185. data/lib/legate/web/routes/api_routes.rb +56 -0
  186. data/lib/legate/web/routes/authentication_routes.rb +1541 -0
  187. data/lib/legate/web/routes/core_routes.rb +111 -0
  188. data/lib/legate/web/routes/documentation_routes.rb +220 -0
  189. data/lib/legate/web/routes/tool_generator_routes.rb +81 -0
  190. data/lib/legate/web/routes/tools_ui_routes.rb +207 -0
  191. data/lib/legate/web/sass_compiler.rb +73 -0
  192. data/lib/legate/web/views/_active_session_info.slim +25 -0
  193. data/lib/legate/web/views/_activity_list.slim +55 -0
  194. data/lib/legate/web/views/_agent_card.slim +56 -0
  195. data/lib/legate/web/views/_agent_generator_modal.slim +382 -0
  196. data/lib/legate/web/views/_agent_status_controls.slim +71 -0
  197. data/lib/legate/web/views/_agent_tool_table.slim +74 -0
  198. data/lib/legate/web/views/_chat_message.slim +95 -0
  199. data/lib/legate/web/views/_display_agent_configuration.slim +26 -0
  200. data/lib/legate/web/views/_display_agent_description.slim +11 -0
  201. data/lib/legate/web/views/_display_agent_fallback.slim +15 -0
  202. data/lib/legate/web/views/_display_agent_hierarchy.slim +93 -0
  203. data/lib/legate/web/views/_display_agent_instruction.slim +17 -0
  204. data/lib/legate/web/views/_display_agent_mcp.slim +13 -0
  205. data/lib/legate/web/views/_display_agent_model.slim +17 -0
  206. data/lib/legate/web/views/_display_agent_name.slim +42 -0
  207. data/lib/legate/web/views/_display_agent_output_key.slim +26 -0
  208. data/lib/legate/web/views/_display_agent_type.slim +65 -0
  209. data/lib/legate/web/views/_edit_agent_configuration.slim +74 -0
  210. data/lib/legate/web/views/_edit_agent_description.slim +16 -0
  211. data/lib/legate/web/views/_edit_agent_fallback.slim +25 -0
  212. data/lib/legate/web/views/_edit_agent_hierarchy.slim +98 -0
  213. data/lib/legate/web/views/_edit_agent_instruction.slim +49 -0
  214. data/lib/legate/web/views/_edit_agent_mcp.slim +33 -0
  215. data/lib/legate/web/views/_edit_agent_model.slim +23 -0
  216. data/lib/legate/web/views/_edit_agent_output_key.slim +36 -0
  217. data/lib/legate/web/views/_edit_agent_tools.slim +40 -0
  218. data/lib/legate/web/views/_edit_agent_type.slim +67 -0
  219. data/lib/legate/web/views/_session_error.slim +4 -0
  220. data/lib/legate/web/views/_skeleton.slim +69 -0
  221. data/lib/legate/web/views/_tool_card.slim +9 -0
  222. data/lib/legate/web/views/_tool_generator_modal.slim +311 -0
  223. data/lib/legate/web/views/agent.slim +436 -0
  224. data/lib/legate/web/views/agent_auth.slim +562 -0
  225. data/lib/legate/web/views/agents.slim +369 -0
  226. data/lib/legate/web/views/auth.slim +112 -0
  227. data/lib/legate/web/views/auth_credential_detail.slim +327 -0
  228. data/lib/legate/web/views/auth_credentials.slim +261 -0
  229. data/lib/legate/web/views/auth_debug.slim +94 -0
  230. data/lib/legate/web/views/auth_mapping_detail.slim +151 -0
  231. data/lib/legate/web/views/auth_mapping_new.slim +123 -0
  232. data/lib/legate/web/views/auth_mappings.slim +120 -0
  233. data/lib/legate/web/views/auth_scheme_detail.slim +274 -0
  234. data/lib/legate/web/views/auth_schemes.slim +259 -0
  235. data/lib/legate/web/views/auth_test.slim +418 -0
  236. data/lib/legate/web/views/chat.slim +192 -0
  237. data/lib/legate/web/views/docs_index.slim +105 -0
  238. data/lib/legate/web/views/docs_show.slim +105 -0
  239. data/lib/legate/web/views/error_404.slim +5 -0
  240. data/lib/legate/web/views/index.slim +148 -0
  241. data/lib/legate/web/views/layout.slim +144 -0
  242. data/lib/legate/web/views/tool_detail.slim +87 -0
  243. data/lib/legate/web/views/tools.slim +50 -0
  244. data/lib/legate/web/webhook_listener.rb +367 -0
  245. data/lib/legate/web.rb +9 -0
  246. data/lib/legate.rb +220 -0
  247. data/public/docs/advanced/callbacks.md +828 -0
  248. data/public/docs/advanced/mcp_schema_conversion.md +59 -0
  249. data/public/docs/authentication/api_reference/config.md +210 -0
  250. data/public/docs/authentication/api_reference/credential.md +246 -0
  251. data/public/docs/authentication/api_reference/encryption.md +218 -0
  252. data/public/docs/authentication/api_reference/exchanged_credential.md +271 -0
  253. data/public/docs/authentication/api_reference/excon_middleware.md +175 -0
  254. data/public/docs/authentication/api_reference/index.md +30 -0
  255. data/public/docs/authentication/api_reference/scheme.md +250 -0
  256. data/public/docs/authentication/api_reference/schemes/api_key.md +175 -0
  257. data/public/docs/authentication/api_reference/schemes/google_service_account.md +221 -0
  258. data/public/docs/authentication/api_reference/schemes/http_bearer.md +169 -0
  259. data/public/docs/authentication/api_reference/schemes/oauth2.md +343 -0
  260. data/public/docs/authentication/api_reference/schemes/oidc.md +73 -0
  261. data/public/docs/authentication/api_reference/schemes/openid_connect.md +311 -0
  262. data/public/docs/authentication/api_reference/schemes/service_account.md +287 -0
  263. data/public/docs/authentication/api_reference/token_manager.md +221 -0
  264. data/public/docs/authentication/api_reference/token_store.md +146 -0
  265. data/public/docs/authentication/api_reference/tool_context_extension.md +166 -0
  266. data/public/docs/authentication/guides/api_key.md +190 -0
  267. data/public/docs/authentication/guides/bearer.md +172 -0
  268. data/public/docs/authentication/guides/configuration.md +255 -0
  269. data/public/docs/authentication/guides/custom_flow.md +523 -0
  270. data/public/docs/authentication/guides/index.md +24 -0
  271. data/public/docs/authentication/guides/migration.md +435 -0
  272. data/public/docs/authentication/guides/oauth2.md +252 -0
  273. data/public/docs/authentication/guides/oidc.md +241 -0
  274. data/public/docs/authentication/guides/overview.md +155 -0
  275. data/public/docs/authentication/guides/secure_storage.md +301 -0
  276. data/public/docs/authentication/guides/service_account.md +228 -0
  277. data/public/docs/authentication/guides/token_lifecycle.md +295 -0
  278. data/public/docs/authentication/guides/web_ui_integration.md +504 -0
  279. data/public/docs/authentication/index.md +58 -0
  280. data/public/docs/authentication/troubleshooting/credential_storage.md +550 -0
  281. data/public/docs/authentication/troubleshooting/environment_variables.md +540 -0
  282. data/public/docs/authentication/troubleshooting/index.md +11 -0
  283. data/public/docs/authentication/troubleshooting/oauth2_issues.md +220 -0
  284. data/public/docs/authentication/troubleshooting/oidc_issues.md +412 -0
  285. data/public/docs/authentication/troubleshooting/token_refresh.md +338 -0
  286. data/public/docs/cli/legate_cli_usage.md +363 -0
  287. data/public/docs/core_concepts/legate_agent_lifecycle.md +124 -0
  288. data/public/docs/core_concepts/legate_architecture_overview.md +110 -0
  289. data/public/docs/core_concepts/legate_configuration.md +116 -0
  290. data/public/docs/core_concepts/legate_definition_store.md +102 -0
  291. data/public/docs/core_concepts/legate_planner.md +94 -0
  292. data/public/docs/core_concepts/legate_session_service.md +104 -0
  293. data/public/docs/error_handling/legate_error_handling.md +122 -0
  294. data/public/docs/examples.md +199 -0
  295. data/public/docs/getting_started.md +111 -0
  296. data/public/docs/guides/agentic_agents.md +137 -0
  297. data/public/docs/guides/ai_code_generators.md +437 -0
  298. data/public/docs/guides/auto_loading.md +326 -0
  299. data/public/docs/guides/configuring_agent_webhooks.md +219 -0
  300. data/public/docs/guides/http_client_usage.md +264 -0
  301. data/public/docs/guides/llm_providers.md +137 -0
  302. data/public/docs/guides/mcp_client_integration.md +232 -0
  303. data/public/docs/guides/mcp_server_exposure.md +206 -0
  304. data/public/docs/guides/rails_integration.md +128 -0
  305. data/public/docs/guides/sending_outbound_webhooks.md +227 -0
  306. data/public/docs/guides/streaming.md +112 -0
  307. data/public/docs/guides/webhooks.md +288 -0
  308. data/public/docs/introduction.md +51 -0
  309. data/public/docs/multi_agent_systems/advanced_features.md +57 -0
  310. data/public/docs/multi_agent_systems/agent_delegation.md +190 -0
  311. data/public/docs/multi_agent_systems/agent_hierarchy.md +49 -0
  312. data/public/docs/multi_agent_systems/state_management.md +47 -0
  313. data/public/docs/multi_agent_systems/workflow_agents.md +72 -0
  314. data/public/docs/tools/legate_built_in_tools.md +332 -0
  315. data/public/docs/tools/legate_tools_and_registry.md +263 -0
  316. data/public/docs/web_ui/legate_web_ui.md +137 -0
  317. metadata +823 -0
@@ -0,0 +1,72 @@
1
+ # Workflow Agents
2
+
3
+ Workflow Agents are specialized agents designed to orchestrate other agents in specific patterns. They extend the base `Legate::Agent` class.
4
+
5
+ ## Sequential Agent
6
+
7
+ Executes a list of sub-agents in a strict order. The output of one agent can be used as context for the next.
8
+
9
+ **Configuration:**
10
+ ```ruby
11
+ Legate::Agent.define do |agent|
12
+ agent.name :content_pipeline
13
+ agent.agent_type :sequential
14
+ agent.instruction "Process content."
15
+
16
+ # Define execution order
17
+ agent.sequential_sub_agents :researcher, :drafter, :editor
18
+ end
19
+ ```
20
+
21
+ **Behavior:**
22
+ 1. Executes `:researcher`.
23
+ 2. Passes result to `:drafter`.
24
+ 3. Passes result to `:editor`.
25
+ 4. Returns the final result from `:editor`.
26
+
27
+ ## Parallel Agent
28
+
29
+ Executes multiple sub-agents concurrently. Useful for independent tasks.
30
+
31
+ **Configuration:**
32
+ ```ruby
33
+ Legate::Agent.define do |agent|
34
+ agent.name :market_analysis
35
+ agent.agent_type :parallel
36
+ agent.instruction "Analyze market sectors."
37
+
38
+ # Define agents to run in parallel
39
+ agent.parallel_sub_agents :tech_analyst, :finance_analyst, :healthcare_analyst
40
+ end
41
+ ```
42
+
43
+ **Behavior:**
44
+ 1. Starts all sub-agents simultaneously.
45
+ 2. Waits for all to complete.
46
+ 3. Returns a combined result containing outputs from all agents.
47
+
48
+ ## Loop Agent
49
+
50
+ Executes a sub-agent (or a sequence of sub-agents) repeatedly until a condition is met or a maximum iteration count is reached.
51
+
52
+ **Configuration:**
53
+ ```ruby
54
+ Legate::Agent.define do |agent|
55
+ agent.name :refiner
56
+ agent.agent_type :loop
57
+ agent.instruction "Refine the text until it meets quality standards."
58
+
59
+ agent.loop_sub_agents :editor
60
+
61
+ # Stop after 5 iterations
62
+ agent.loop_max_iterations 5
63
+
64
+ # OR stop when state key :quality_approved is true
65
+ agent.loop_condition :quality_approved, true
66
+ end
67
+ ```
68
+
69
+ **Behavior:**
70
+ 1. Executes the sub-agents.
71
+ 2. Checks the loop condition (state key).
72
+ 3. Repeats if condition not met and max iterations not reached.
@@ -0,0 +1,332 @@
1
+ # Legate Built-in Tools
2
+
3
+ This document serves as a reference guide for the common tools included with the Legate. These tools are available for agents to use once registered.
4
+
5
+ ## General Usage Notes
6
+
7
+ * **Tool Naming**: When adding tools to an agent definition, you typically use their inferred snake_case name (e.g., `:calculator`, `:echo_tool`) unless an `explicit_tool_name` is specified in the tool's class.
8
+ * **Parameters**: Each tool defines its expected parameters, including their type and whether they are required.
9
+ * **Return Value**: Successful tool executions generally return a hash with `status: :success` and a `result` field. Errors usually result in an `Legate::ToolError` or return a hash with `status: :error` and an `error_message`.
10
+
11
+ ---
12
+
13
+ ## Calculator
14
+
15
+ * **Tool Name**: `:calculator` (inferred)
16
+ * **Purpose**: Calculates the result of an arithmetic operation.
17
+ * **Parameters**:
18
+ * `operand1` (numeric, required): The first number for the calculation.
19
+ * `operand2` (numeric, required): The second number for the calculation.
20
+ * `operation` (string, required): The operation to perform (e.g., "add", "subtract", "multiply", "divide", or symbols `+`, `-`, `*`, `/`).
21
+ * **Example Invocation (Conceptual)**:
22
+ ```json
23
+ {
24
+ "tool_name": "calculator",
25
+ "parameters": {
26
+ "operand1": 10,
27
+ "operand2": 5,
28
+ "operation": "multiply"
29
+ }
30
+ }
31
+ ```
32
+ * **Example Success Response**:
33
+ ```json
34
+ {
35
+ "status": "success",
36
+ "result": 50
37
+ }
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Echo
43
+
44
+ * **Tool Name**: `:echo` (inferred from class `Echo` -> `Legate::Tools::Echo`)
45
+ * **Purpose**: Echoes back the provided message.
46
+ * **Parameters**:
47
+ * `message` (string, required): The message to echo.
48
+ * **Example Invocation (Conceptual)**:
49
+ ```json
50
+ {
51
+ "tool_name": "echo",
52
+ "parameters": {
53
+ "message": "Hello, world!"
54
+ }
55
+ }
56
+ ```
57
+ * **Example Success Response**:
58
+ ```json
59
+ {
60
+ "status": "success",
61
+ "result": "Hello, world!"
62
+ }
63
+ ```
64
+
65
+ ---
66
+
67
+ ## CatFacts
68
+
69
+ * **Tool Name**: `:cat_facts` (inferred)
70
+ * **Purpose**: Fetches a random cat fact from an online API (`https://catfact.ninja`).
71
+ * **Parameters**: None.
72
+ * **Example Invocation (Conceptual)**:
73
+ ```json
74
+ {
75
+ "tool_name": "cat_facts",
76
+ "parameters": {}
77
+ }
78
+ ```
79
+ * **Example Success Response**:
80
+ ```json
81
+ {
82
+ "status": "success",
83
+ "result": "Cats have over 20 muscles that control their ears."
84
+ }
85
+ ```
86
+
87
+ ---
88
+
89
+ ## WebhookTool
90
+
91
+ * **Tool Name**: `:webhook_tool` (explicitly set)
92
+ * **Purpose**: Sends an HTTP POST request with a JSON payload to a specified webhook URL. Can optionally sign the request using HMAC-SHA256.
93
+ * **Parameters**:
94
+ * `url` (string, required): The target webhook URL.
95
+ * `payload` (hash or string, required): The data payload to send. Hash payloads are automatically JSON-encoded with `Content-Type: application/json`.
96
+ * `secret` (string, optional): Optional secret key for calculating HMAC-SHA256 signature (sent in `X-Hub-Signature-256` header).
97
+ * `headers` (hash, optional): Optional custom headers to include (e.g., `Content-Type` for string payloads).
98
+ * **Example Invocation (Conceptual)**:
99
+ ```json
100
+ {
101
+ "tool_name": "webhook_tool",
102
+ "parameters": {
103
+ "url": "https://example.com/my-hook",
104
+ "payload": {"data": "some_value", "event": "item_created"},
105
+ "secret": "mysecretkey"
106
+ }
107
+ }
108
+ ```
109
+ * **Example Success Response**:
110
+ ```json
111
+ {
112
+ "status": "success",
113
+ "result": {
114
+ "response_status": 200,
115
+ "response_body": "Webhook received successfully"
116
+ }
117
+ }
118
+ ```
119
+
120
+ ---
121
+
122
+ ## HttpRequest
123
+
124
+ * **Tool Name**: `:http_request` (inferred)
125
+ * **Purpose**: Makes an HTTP request to a URL and returns the status code, headers, and body. Supports `GET` (default), `POST`, `PUT`, `PATCH`, `DELETE`, and `HEAD`.
126
+ * **Security**: SSRF-safe — requests to loopback, link-local, private, CGNAT, and `0.0.0.0/8` addresses (e.g. cloud metadata at `169.254.169.254`) are blocked, and the connection is pinned to the validated IP to prevent DNS rebinding. Set `LEGATE_ALLOW_PRIVATE_TOOL_URLS=1` to reach private hosts in development.
127
+ * **Auth-aware**: Configured authentication (URL → scheme/credential mappings) is applied automatically for matching URLs. Pass `headers` for manual auth.
128
+ * **Parameters**:
129
+ * `url` (string, required): The full URL to request (must be `http` or `https`).
130
+ * `method` (string, optional): HTTP method. Defaults to `GET`.
131
+ * `headers` (hash, optional): Request headers.
132
+ * `body` (hash or string, optional): Request body. A Hash is JSON-encoded with `Content-Type: application/json`.
133
+ * `query` (hash, optional): Query-string parameters.
134
+ * **Notes**: A non-2xx response is returned as a normal result (with its `status_code`) so an agent can inspect it; only network/SSRF/timeout failures are errors. Bodies are capped at 1 MB (`truncated: true` when cut).
135
+ * **Example Success Response**:
136
+ ```json
137
+ {
138
+ "status": "success",
139
+ "result": {
140
+ "url": "https://api.example.com/v1/items",
141
+ "status_code": 200,
142
+ "headers": { "content-type": "application/json" },
143
+ "body": "{\"items\": []}",
144
+ "truncated": false
145
+ }
146
+ }
147
+ ```
148
+
149
+ ---
150
+
151
+ ## ReadWebpage
152
+
153
+ * **Tool Name**: `:read_webpage` (inferred)
154
+ * **Purpose**: Fetches a web page and returns its title and readable text content with HTML markup removed (script/style stripped, entities decoded, whitespace collapsed). The backbone of research/RAG agents.
155
+ * **Security**: SSRF-safe, identical guards to `http_request`.
156
+ * **Parameters**:
157
+ * `url` (string, required): The URL of the page to read (`http` or `https`).
158
+ * `max_chars` (integer, optional): Maximum characters of text to return (default 20,000, hard cap 200,000).
159
+ * **Example Success Response**:
160
+ ```json
161
+ {
162
+ "status": "success",
163
+ "result": {
164
+ "url": "https://example.com",
165
+ "title": "Example Domain",
166
+ "text": "Example Domain This domain is for use in illustrative examples...",
167
+ "truncated": false
168
+ }
169
+ }
170
+ ```
171
+
172
+ ---
173
+
174
+ ## CurrentTime
175
+
176
+ * **Tool Name**: `:current_time` (inferred)
177
+ * **Purpose**: Returns the current date and time. Language models don't know the current time, so this is a common building block for scheduling, freshness checks, and "how long ago" reasoning.
178
+ * **Parameters**:
179
+ * `timezone` (string, optional): `"UTC"` (default), `"local"`, or a fixed UTC offset such as `"+05:30"` or `"-0800"`. Named IANA zones (e.g. `America/New_York`) are intentionally not supported (no timezone-database dependency).
180
+ * `format` (string, optional): A strftime format (e.g. `"%A, %B %-d, %Y"`). Defaults to ISO 8601.
181
+ * **Example Success Response**:
182
+ ```json
183
+ {
184
+ "status": "success",
185
+ "result": {
186
+ "iso8601": "2026-06-14T14:05:09Z",
187
+ "formatted": "2026-06-14T14:05:09Z",
188
+ "epoch": 1781445909,
189
+ "timezone": "UTC"
190
+ }
191
+ }
192
+ ```
193
+
194
+ ---
195
+
196
+ ## AgentTool (Delegate Task)
197
+
198
+ * **Tool Name**: `:delegate_task` (explicitly set, class `AgentTool`)
199
+ * **Purpose**: Delegates a specified task to another agent identified by its unique name. This is useful when a specific, pre-defined agent is better suited for a sub-task.
200
+ * **Parameters**:
201
+ * `target_agent_name` (string, required): The unique name of the agent definition (must be findable by `Legate::GlobalDefinitionRegistry`) to delegate the task to.
202
+ * `task` (string, required): The specific task description to be executed by the target agent.
203
+ * **Example Invocation (Conceptual)**:
204
+ ```json
205
+ {
206
+ "tool_name": "delegate_task",
207
+ "parameters": {
208
+ "target_agent_name": "customer_service_agent",
209
+ "task": "The user is asking for a refund for order 12345. Please process this."
210
+ }
211
+ }
212
+ ```
213
+ * **Example Success Response** (depends on the target agent's response):
214
+ ```json
215
+ {
216
+ "status": "success",
217
+ "result": "The refund for order 12345 has been processed successfully."
218
+ }
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Asynchronous Operations Tools
224
+
225
+ Legate provides a mechanism for tools to initiate long-running tasks as background threads using `Concurrent::Promises.future`. This typically involves two tools: one to start the job and one to check its status.
226
+
227
+ ### BaseAsyncJobTool (Developer Note)
228
+ This is an abstract base class (`Legate::Tools::BaseAsyncJobTool`) and not directly invoked by an agent. Developers creating new asynchronous tools would inherit from it. It handles the common logic of running tasks in background threads and storing job results in an in-memory `Concurrent::Map`.
229
+
230
+ ### SleepyTool (Example Async Tool)
231
+
232
+ * **Tool Name**: `:start_sleepy_job` (explicitly set, class `SleepyTool`)
233
+ * **Purpose**: Starts a background task that simply sleeps for a specified duration and then records a message. This tool is primarily an example of an asynchronous tool.
234
+ * **Parameters**:
235
+ * `duration` (integer, required): How many seconds the task should sleep.
236
+ * `message` (string, required): A message to include in the final result upon task completion.
237
+ * **Invocation Result**: When this tool is called, it starts a background thread via `Concurrent::Promises.future`.
238
+ * **Example Success Response (Job Enqueued)**:
239
+ ```json
240
+ {
241
+ "status": "pending",
242
+ "job_id": "abcdef1234567890"
243
+ }
244
+ ```
245
+ * **Getting the Actual Result**: Use the `check_job_status` tool with the returned `job_id`.
246
+
247
+ ### CheckJobStatusTool
248
+
249
+ * **Tool Name**: `:check_job_status` (explicitly set, class `CheckJobStatusTool`)
250
+ * **Purpose**: Checks the status and retrieves the result of a previously started background task using its `job_id`.
251
+ * **Parameters**:
252
+ * `job_id` (string, required): The ID of the job to check (obtained from a tool like `start_sleepy_job`).
253
+ * **Response Scenarios**:
254
+ * **Job Pending**:
255
+ ```json
256
+ {
257
+ "status": "pending",
258
+ "job_id": "abcdef1234567890",
259
+ "message": "Job is queued or currently running."
260
+ }
261
+ ```
262
+ * **Job Succeeded** (result from in-memory store):
263
+ ```json
264
+ {
265
+ "status": "success",
266
+ "job_id": "abcdef1234567890",
267
+ "result": "Slept for 10 seconds. Your message: Hello from async job."
268
+ }
269
+ ```
270
+ * **Job Errored** (error from in-memory store):
271
+ ```json
272
+ {
273
+ "status": "error",
274
+ "job_id": "abcdef1234567890",
275
+ "error_message": "Something went wrong during the job.",
276
+ "error_details": "Optional details about the error, like exception class."
277
+ }
278
+ ```
279
+ * **Job Failed**: The tool call itself might raise an `Legate::ToolError` or return a generic error status.
280
+ * **Job Not Found/Expired**: The tool call might raise an `Legate::ToolError` or return an error status indicating the result is unavailable.
281
+
282
+ ```mermaid
283
+ graph LR
284
+ subgraph "Async Tool Flow"
285
+ A[Agent] -- Calls --> B(Start Async Job Tool <br> e.g., :start_sleepy_job)
286
+ B -- Starts Thread --> C[Concurrent::Promises.future]
287
+ B -- Returns job_id --> A
288
+ C -- Executes --> D(Background Thread)
289
+ D -- Writes Result/Error --> E[Concurrent::Map]
290
+ A -- Calls with job_id --> F(Check Job Status Tool <br> :check_job_status)
291
+ F -- Reads from --> E
292
+ F -- Returns Status/Result --> A
293
+ end
294
+
295
+ style A fill:#cde,stroke:#333
296
+ style B fill:#fdc,stroke:#333
297
+ style C fill:#def,stroke:#333
298
+ style D fill:#fdd,stroke:#333
299
+ style E fill:#fcf,stroke:#333
300
+ style F fill:#dfd,stroke:#333
301
+ ```
302
+
303
+ ---
304
+
305
+ ## RandomNumberTool (demo tool — not registered by default)
306
+
307
+ > `random_number` ships with Legate but is **not registered as a default tool**.
308
+ > It's a demo. Opt in with `Legate::GlobalToolManager.register_tool(Legate::Tools::RandomNumberTool)`
309
+ > before an agent can `use_tool :random_number`.
310
+
311
+ * **Tool Name**: `:random_number` (explicitly set, class `RandomNumberTool`)
312
+ * **Purpose**: Generates a random integer between a minimum and maximum value (inclusive). Defaults to generating a number between 1 and 100 if no parameters are provided.
313
+ * **Parameters**:
314
+ * `min` (integer, optional): The minimum value for the random number (inclusive). Defaults to 1.
315
+ * `max` (integer, optional): The maximum value for the random number (inclusive). Defaults to 100.
316
+ * **Example Invocation (Conceptual)**:
317
+ ```json
318
+ {
319
+ "tool_name": "random_number",
320
+ "parameters": {
321
+ "min": 10,
322
+ "max": 20
323
+ }
324
+ }
325
+ ```
326
+ * **Example Success Response**:
327
+ ```json
328
+ {
329
+ "status": "success",
330
+ "result": 15
331
+ }
332
+ ```
@@ -0,0 +1,263 @@
1
+ # Legate Tools and Registry
2
+
3
+ This document describes the tool system in Legate, including how tools are defined, registered, and made available to agents.
4
+
5
+ ## Overview
6
+
7
+ Legate provides a robust tool system that allows agents to perform actions beyond simple text generation. Tools are Ruby classes that encapsulate specific functionality like performing calculations, making HTTP requests, or delegating tasks to other agents.
8
+
9
+ ```mermaid
10
+ graph TB
11
+ subgraph Registration
12
+ ToolClass[Tool Class Definition] --> GTM[GlobalToolManager]
13
+ end
14
+
15
+ subgraph AgentSetup
16
+ AgentDef[AgentDefinition] -->|use_tool :name| Agent
17
+ Agent -->|creates| TR[ToolRegistry]
18
+ GTM -->|populates| TR
19
+ end
20
+
21
+ subgraph Execution
22
+ Agent -->|execute| Tool[Tool Instance]
23
+ Tool -->|with| TC[ToolContext]
24
+ end
25
+
26
+ style GTM fill:#cfc,stroke:#333
27
+ style TR fill:#cfc,stroke:#333
28
+ style Tool fill:#ccf,stroke:#333
29
+ ```
30
+
31
+ ## Core Components
32
+
33
+ ### 1. GlobalToolManager
34
+
35
+ The `Legate::GlobalToolManager` is a global registry where all tool classes are registered. It provides a central place to discover available tools.
36
+
37
+ **Key Methods:**
38
+
39
+ | Method | Description |
40
+ |--------|-------------|
41
+ | `register_tool(tool_class)` | Register a tool class globally |
42
+ | `find_class(name_symbol)` | Find a tool class by its symbolic name |
43
+ | `list_all_tools` | Get metadata for all registered tools |
44
+ | `registered_tool_names` | Get an array of all registered tool name symbols |
45
+ | `create_instance(name_symbol)` | Create a new instance of a tool by name |
46
+
47
+ **Example:**
48
+ ```ruby
49
+ # Registration (typically automatic via inheritance)
50
+ Legate::GlobalToolManager.register_tool(MyCustomTool)
51
+
52
+ # Discovery
53
+ available_tools = Legate::GlobalToolManager.list_all_tools
54
+ # => [{name: :my_custom_tool, description: "...", parameters: [...]}]
55
+
56
+ # Instantiation
57
+ tool = Legate::GlobalToolManager.create_instance(:calculator)
58
+ ```
59
+
60
+ ### 2. ToolRegistry
61
+
62
+ The `Legate::ToolRegistry` is an instance-specific collection of tools available to a particular agent. Each agent has its own ToolRegistry, populated from the GlobalToolManager based on the agent's definition.
63
+
64
+ **Key Methods:**
65
+
66
+ | Method | Description |
67
+ |--------|-------------|
68
+ | `register(name, klass)` | Register a tool class with this registry |
69
+ | `find_class(name_symbol)` | Find a tool class by name in this registry |
70
+ | `create_instance(name_symbol)` | Create a tool instance |
71
+ | `list_tools` | Get metadata for tools in this registry |
72
+
73
+ **Relationship to Agent:**
74
+ ```ruby
75
+ # When an agent is initialized, its ToolRegistry is populated
76
+ definition.tool_names.each do |tool_name|
77
+ klass = Legate::GlobalToolManager.find_class(tool_name)
78
+ agent.tool_registry.register(tool_name, klass)
79
+ end
80
+ ```
81
+
82
+ ## Defining Tools
83
+
84
+ Tools are defined by creating a class that inherits from `Legate::Tool` and uses the metadata DSL.
85
+
86
+ ```ruby
87
+ class WeatherTool < Legate::Tool
88
+ # Description shown to the LLM planner
89
+ tool_description 'Get current weather for a location'
90
+
91
+ # Define parameters the tool accepts
92
+ parameter :location,
93
+ type: :string,
94
+ description: 'City name or coordinates',
95
+ required: true
96
+
97
+ parameter :units,
98
+ type: :string,
99
+ description: 'Temperature units: celsius or fahrenheit',
100
+ required: false
101
+
102
+ private
103
+
104
+ def perform_execution(params, context)
105
+ location = params[:location]
106
+ units = params[:units] || 'celsius'
107
+
108
+ # Tool logic here...
109
+
110
+ Legate::ToolResult.success("Weather for #{location}: 72°")
111
+ end
112
+ end
113
+
114
+ # Register the tool (automatic if file is auto-loaded)
115
+ Legate::GlobalToolManager.register_tool(WeatherTool)
116
+ ```
117
+
118
+ ### Return values
119
+
120
+ `perform_execution` returns either a typed `Legate::ToolResult` or the
121
+ equivalent canonical hash — both work:
122
+
123
+ ```ruby
124
+ Legate::ToolResult.success(value) # { status: :success, result: value }
125
+ Legate::ToolResult.error('not found') # { status: :error, error_message: 'not found' }
126
+ Legate::ToolResult.pending(job_id: id) # { status: :pending, job_id: id }
127
+
128
+ # Equivalent hashes (unchanged, still supported):
129
+ { status: :success, result: value }
130
+ ```
131
+
132
+ `Tool#execute` normalizes a `ToolResult` to the hash, so the rest of the
133
+ pipeline is unchanged. The typed form avoids hand-built hashes and mirrors the
134
+ `Event#answer` / `#success?` accessors you read results with.
135
+
136
+ ### Tool Metadata DSL
137
+
138
+ The `Legate::Tool::MetadataDsl` module provides class-level methods for defining tool metadata:
139
+
140
+ | DSL Method | Purpose |
141
+ |------------|---------|
142
+ | `tool_name` | Explicitly set the tool's symbolic name |
143
+ | `tool_description` | Provide a description for the LLM |
144
+ | `parameter(name, options)` | Define an input parameter |
145
+
146
+ **Parameter Options:**
147
+
148
+ | Option | Type | Description |
149
+ |--------|------|-------------|
150
+ | `type` | Symbol | `:string`, `:integer`, `:float`/`:numeric`, `:boolean`, `:array`, `:hash` |
151
+ | `description` | String | Description for the LLM |
152
+ | `required` | Boolean | Whether the parameter is required |
153
+ | `enum` | Array | Allowed values (optional) |
154
+
155
+ ### Tool Name Inference
156
+
157
+ If `tool_name` is not explicitly set, Legate infers it from the class name:
158
+
159
+ - `MyCustomTool` → `:my_custom_tool`
160
+ - `Calculator` → `:calculator`
161
+ - `Legate::Tools::CatFacts` → `:cat_facts`
162
+
163
+ ## Using Tools in Agents
164
+
165
+ Tools are associated with agents via the `use_tool` method in the agent definition:
166
+
167
+ ```ruby
168
+ Legate::AgentDefinition.new.define do |a|
169
+ a.name :my_agent
170
+ # instruction is optional — defaults from the name/description if omitted
171
+
172
+ # Reference a registered tool by name (Symbol or String)…
173
+ a.use_tool :calculator
174
+ a.use_tool 'echo'
175
+
176
+ # …or pass the class directly: this registers AND selects it in one step,
177
+ # so you don't need a separate GlobalToolManager.register_tool call.
178
+ a.use_tool WeatherTool
179
+ end
180
+ ```
181
+
182
+ `use_tool` accepts a Symbol, a String (both coerced to a Symbol), or a
183
+ `Legate::Tool` subclass. A name that matches no registered tool produces a
184
+ warning with a "did you mean?" suggestion and the list of available tools (it
185
+ stays non-fatal — MCP tools register when the agent connects).
186
+
187
+ You can list what's registered with `Legate.tools` (or `legate tool list` /
188
+ `legate tool info NAME` from the CLI).
189
+
190
+ ## Tool Execution Flow
191
+
192
+ When an agent executes a tool:
193
+
194
+ ```mermaid
195
+ sequenceDiagram
196
+ participant Agent
197
+ participant TR as ToolRegistry
198
+ participant Tool
199
+ participant TC as ToolContext
200
+
201
+ Agent->>TR: find_class(:tool_name)
202
+ TR-->>Agent: ToolClass
203
+ Agent->>Tool: new()
204
+ Agent->>TC: new(session_info)
205
+ Agent->>Tool: execute(params, context)
206
+ Tool->>Tool: validate_parameters
207
+ Tool->>Tool: perform_execution
208
+ Tool-->>Agent: {status: :success, result: ...}
209
+ ```
210
+
211
+ 1. The agent looks up the tool class in its ToolRegistry
212
+ 2. It creates an instance of the tool
213
+ 3. It creates a ToolContext with session information
214
+ 4. It calls `execute(params, context)` on the tool
215
+ 5. The tool validates parameters and runs `perform_execution`
216
+ 6. The tool returns a result hash
217
+
218
+ ## ToolContext
219
+
220
+ The `Legate::ToolContext` object provides tools with access to:
221
+
222
+ - Session state (`state_get`, `state_set`)
223
+ - Session ID, user ID, app name
224
+ - Invocation ID for tracking
225
+ - Authentication helpers (for tools using the auth module)
226
+
227
+ ```ruby
228
+ def perform_execution(params, context)
229
+ # Access session state
230
+ previous_value = context.state_get(:some_key)
231
+
232
+ # Set state (applied after tool completes)
233
+ context.state_set(:result_key, 'new value')
234
+
235
+ { status: :success, result: 'Done' }
236
+ end
237
+ ```
238
+
239
+ ## Built-in Tools
240
+
241
+ Legate provides several built-in tools:
242
+
243
+ | Tool Name | Description |
244
+ |-----------|-------------|
245
+ | `:http_request` | SSRF-safe, auth-aware HTTP client |
246
+ | `:read_webpage` | Fetches a page as readable text |
247
+ | `:current_time` | Current date/time (ISO 8601 / epoch / strftime) |
248
+ | `:calculator` | Performs arithmetic operations |
249
+ | `:echo` | Echoes back the input message |
250
+ | `:cat_facts` | Fetches random cat facts |
251
+ | `:webhook_tool` | Sends outbound webhooks |
252
+ | `:delegate_task` | Delegates to another agent |
253
+ | `:check_job_status` | Checks async job status |
254
+ | `:start_sleepy_job` | Demo async/background job |
255
+
256
+ See [Built-in Tools Reference](./legate_built_in_tools) for detailed documentation.
257
+
258
+ ## Further Reading
259
+
260
+ * [`legate_architecture_overview`](../core_concepts/legate_architecture_overview)
261
+ * [`legate_built_in_tools`](./legate_built_in_tools)
262
+ * [`auto_loading`](../guides/auto_loading)
263
+ * [`ai_code_generators`](../guides/ai_code_generators)