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,437 @@
1
+ # AI-Powered Code Generators
2
+
3
+ This guide explains how to use the AI-powered code generators to quickly create agents and tools from natural language descriptions.
4
+
5
+ ## Overview
6
+
7
+ Legate includes two AI-powered generators that use Google's Gemini AI to create production-ready Ruby code:
8
+
9
+ 1. **Agent Generator** - Creates complete `AgentDefinition` code for any type of agent
10
+ 2. **Tool Generator** - Creates complete `Tool` class code with proper DSL and patterns
11
+
12
+ Both generators are accessible from the **Web UI** and the **CLI**, producing Ruby code that you can integrate into your projects.
13
+
14
+ ## CLI Commands
15
+
16
+ The AI generators are available via the command line, with full support for piping:
17
+
18
+ ### Agent Generation
19
+
20
+ ```bash
21
+ # Inline description
22
+ legate agent ai_generate -d "An agent that helps with customer support"
23
+
24
+ # From a file
25
+ legate agent ai_generate -f prompt.txt -o ./agents/support_agent.rb
26
+
27
+ # Via stdin (automatically outputs to stdout)
28
+ echo "A calculator agent" | legate agent ai_generate > calc_agent.rb
29
+ ```
30
+
31
+ ### Tool Generation
32
+
33
+ ```bash
34
+ # Inline description
35
+ legate tool ai_generate -d "A tool that converts temperatures"
36
+
37
+ # Via stdin (pipe-friendly)
38
+ echo "A URL status checker" | legate tool ai_generate > url_checker.rb
39
+ ```
40
+
41
+ ### CLI Options
42
+
43
+ | Option | Description |
44
+ |--------|-------------|
45
+ | `-d, --description` | Inline description |
46
+ | `-f, --prompt-file` | Read description from file |
47
+ | `-o, --output` | Output file path |
48
+ | `--stdout` | Force output to stdout |
49
+ | `--force` | Overwrite existing file |
50
+
51
+ > **Note:** When input comes from stdin, output automatically goes to stdout for pipe-friendly workflows.
52
+
53
+ ## Web UI - Agent Generator
54
+
55
+
56
+ ### Accessing the Generator
57
+
58
+ 1. Navigate to the **Agents** page (`/agents`)
59
+ 2. Click the **"Build with AI Builder"** button
60
+ 3. A modal opens. Describe your agent, then click **Generate**.
61
+
62
+ ### The build flow (live — no download or restart)
63
+
64
+ Unlike the CLI (which emits a `.rb` file you place yourself), the Web UI builder is
65
+ **live**:
66
+
67
+ 1. **Generate** — the AI returns a *structured* agent definition (name, model, type,
68
+ instruction, tools), not raw code.
69
+ 2. **Review & tweak** — an editable form is pre-filled. Adjust the name, model, agent
70
+ type, description, instruction, and tool selection.
71
+ 3. **Add to Legion** — registers the agent into the running instance immediately. It
72
+ shows up in the dashboard right away — nothing to download, place, or restart.
73
+ 4. **Export `.rb`** (optional) — expand *"View / export generated Ruby"* to copy or
74
+ download the equivalent definition for source control.
75
+
76
+ Agents added this way live in memory (like any agent created from the dashboard form)
77
+ until you persist them — see [Persisting runtime agents](#persisting-runtime-agents).
78
+
79
+ ### Describing Your Agent
80
+
81
+ Enter a natural language description of the agent you want to create. The AI understands:
82
+
83
+ - **Basic LLM agents**: "Create an agent that helps users with customer support questions"
84
+ - **Workflow agents**: "Create a sequential workflow that first researches a topic, then summarizes the findings"
85
+ - **Webhook-enabled agents**: "Create an agent triggered by GitHub webhooks that processes pull request events"
86
+ - **Agents with specific tools**: "Create an agent that can perform calculations and look up cat facts"
87
+
88
+ ### Example Descriptions
89
+
90
+ ```
91
+ Create an agent that helps users analyze CSV data files and
92
+ generate summary reports.
93
+ ```
94
+
95
+ ```
96
+ Create a sequential workflow agent that:
97
+ 1. First fetches data from an API
98
+ 2. Then processes and transforms the data
99
+ 3. Finally sends a notification with the results
100
+ ```
101
+
102
+ ```
103
+ Create a webhook-enabled agent that receives Stripe payment
104
+ events and updates customer records.
105
+ ```
106
+
107
+ ### Generated Code Structure
108
+
109
+ The generator produces complete Ruby code including:
110
+
111
+ ```ruby
112
+ # frozen_string_literal: true
113
+
114
+ require 'legate'
115
+
116
+ definition = Legate::AgentDefinition.new.define do |a|
117
+ a.name :my_agent
118
+ a.description 'Agent description'
119
+
120
+ a.instruction <<~INSTRUCTION
121
+ Detailed system prompt...
122
+ INSTRUCTION
123
+
124
+ # Tools configuration
125
+ a.use_tool :calculator
126
+ a.use_tool :echo
127
+
128
+ # Model configuration
129
+ a.model_name 'gemini-2.0-flash'
130
+ a.temperature 0.7
131
+ end
132
+
133
+ Legate::GlobalDefinitionRegistry.register(definition)
134
+ ```
135
+
136
+ ### Supported Agent Types
137
+
138
+ The generator can create:
139
+
140
+ | Type | Description | Key DSL Methods |
141
+ |------|-------------|-----------------|
142
+ | **LLM Agent** | Standard AI agent with tools | `use_tool`, `model_name`, `temperature` |
143
+ | **Sequential Agent** | Runs sub-agents in order | `agent_type :sequential`, `sequential_sub_agents(*names)` |
144
+ | **Parallel Agent** | Runs sub-agents concurrently | `agent_type :parallel`, `parallel_sub_agents(*names)` |
145
+ | **Loop Agent** | Repeats until condition met | `agent_type :loop`, `loop_sub_agents(*names)`, `loop_max_iterations(max)`, `loop_condition(key, value)` |
146
+ | **Webhook Agent** | Triggered by HTTP webhooks | `webhook_enabled`, `webhook_transformer`, `webhook_validator` |
147
+
148
+ ### Available Tools
149
+
150
+ The generator is given the full list of tools registered in your installation
151
+ (names, descriptions, and parameters). It is instructed to use only those, and any
152
+ tool it nonetheless invents is filtered out server-side — so an agent never ends up
153
+ referencing a tool that doesn't exist.
154
+
155
+ ### Suggested tools to create
156
+
157
+ If your description needs a capability that **no installed tool** provides, the
158
+ builder doesn't fake it — it lists the missing capability under **"Suggested tools to
159
+ create"** in the review step, each with a one-line description and a **Build →**
160
+ button. "Build →" opens the [Tool Generator](#tool-generator) pre-filled. Once you
161
+ build and install that tool, you're returned to the agent builder with the new tool
162
+ **added and checked**, ready to **Add to Legion**. This closes the loop:
163
+
164
+ > describe an agent → it spots a missing tool → build it inline → it loads live →
165
+ > the agent picks it up → Add to Legion.
166
+
167
+ ## Tool Generator
168
+
169
+ ### Accessing the Generator
170
+
171
+ 1. Navigate to the **Tools** page (`/tools`)
172
+ 2. Click the **"Generate with AI"** button
173
+ 3. A modal dialog will open with an input form
174
+
175
+ ### Describing Your Tool
176
+
177
+ Describe what you want the tool to do. The AI will automatically determine the best tool type:
178
+
179
+ - **Simple Tool**: Local computations, data transformations
180
+ - **HTTP API Tool**: External API calls with proper error handling
181
+ - **Async Tool**: Long-running background tasks via threaded execution
182
+
183
+ ### Example Descriptions
184
+
185
+ **Simple Tool:**
186
+ ```
187
+ Create a tool that converts temperatures between Celsius,
188
+ Fahrenheit, and Kelvin.
189
+ ```
190
+
191
+ **HTTP API Tool:**
192
+ ```
193
+ Create a tool that fetches weather data from OpenWeather API
194
+ for a given city name.
195
+ ```
196
+
197
+ **Async Tool:**
198
+ ```
199
+ Create a tool that processes large CSV files in the background
200
+ and returns a job ID for status checking.
201
+ ```
202
+
203
+ ### Generated Code Structure
204
+
205
+ #### Simple Tool
206
+
207
+ ```ruby
208
+ # frozen_string_literal: true
209
+
210
+ require 'legate/tool'
211
+
212
+ class TemperatureConverter < Legate::Tool
213
+ tool_description 'Converts temperatures between units'
214
+
215
+ parameter :value,
216
+ type: :numeric,
217
+ description: 'Temperature value to convert',
218
+ required: true
219
+
220
+ parameter :from_unit,
221
+ type: :string,
222
+ description: 'Source unit (celsius, fahrenheit, kelvin)',
223
+ required: true
224
+
225
+ parameter :to_unit,
226
+ type: :string,
227
+ description: 'Target unit (celsius, fahrenheit, kelvin)',
228
+ required: true
229
+
230
+ private
231
+
232
+ def perform_execution(params, context)
233
+ # Conversion logic...
234
+ { status: :success, result: converted_value }
235
+ rescue StandardError => e
236
+ { status: :error, error_message: e.message }
237
+ end
238
+ end
239
+
240
+ Legate::GlobalToolManager.register_tool(TemperatureConverter)
241
+ ```
242
+
243
+ #### HTTP API Tool
244
+
245
+ ```ruby
246
+ # frozen_string_literal: true
247
+
248
+ require 'legate/tool'
249
+ require 'legate/tools/base/http_client'
250
+
251
+ class WeatherTool < Legate::Tool
252
+ include Legate::Tools::Base::HttpClient
253
+
254
+ tool_description 'Fetches weather data from OpenWeather API'
255
+
256
+ parameter :city,
257
+ type: :string,
258
+ description: 'City name',
259
+ required: true
260
+
261
+ def initialize(**options)
262
+ super
263
+ setup_http_client(
264
+ base_url: 'https://api.openweathermap.org/data/2.5/',
265
+ headers: { 'Accept' => 'application/json' }
266
+ )
267
+ end
268
+
269
+ private
270
+
271
+ def perform_execution(params, context)
272
+ api_key = ENV['OPENWEATHER_API_KEY']
273
+ response = http_get('weather', query: {
274
+ q: params[:city],
275
+ appid: api_key
276
+ })
277
+
278
+ data = JSON.parse(response.body)
279
+ { status: :success, result: data }
280
+ rescue Legate::ToolHttpError => e
281
+ { status: :error, error_message: "API error: #{e.message}" }
282
+ end
283
+ end
284
+
285
+ Legate::GlobalToolManager.register_tool(WeatherTool)
286
+ ```
287
+
288
+ #### Async Tool
289
+
290
+ ```ruby
291
+ # frozen_string_literal: true
292
+
293
+ require 'legate/tools/base_async_job_tool'
294
+
295
+ class FileProcessorTool < Legate::Tools::BaseAsyncJobTool
296
+ tool_description 'Processes large files in the background'
297
+
298
+ parameter :file_path,
299
+ type: :string,
300
+ description: 'Path to the file to process',
301
+ required: true
302
+
303
+ # The worker class whose #perform method runs in the background thread.
304
+ def worker_class
305
+ FileProcessorWorker
306
+ end
307
+
308
+ # Build the (JSON-serializable) arguments passed to the worker's #perform,
309
+ # after the job id. The base class returns { status: :pending, job_id: ... }.
310
+ def prepare_job_arguments(params, _context)
311
+ [params[:file_path]]
312
+ end
313
+ end
314
+
315
+ # The worker performs the actual work and stores its status/result.
316
+ class FileProcessorWorker
317
+ def perform(jid, file_path)
318
+ Legate::Tools::BaseAsyncJobTool.store_job_pending(jid)
319
+ result = process_file(file_path) # your processing logic
320
+ Legate::Tools::BaseAsyncJobTool.store_job_result(jid, result)
321
+ rescue StandardError => e
322
+ Legate::Tools::BaseAsyncJobTool.store_job_error(jid, e.message, e.class.name)
323
+ end
324
+ end
325
+
326
+ Legate::GlobalToolManager.register_tool(FileProcessorTool)
327
+ ```
328
+
329
+ ## Adding generated code to a running instance
330
+
331
+ The Web UI builder is designed so you rarely need to download and place files.
332
+
333
+ ### Agents — "Add to Legion" (always live)
334
+
335
+ Adding a generated agent registers it straight into the running instance — it's pure
336
+ configuration, no code executes — and it appears in the dashboard immediately.
337
+
338
+ <a id="persisting-runtime-agents"></a>
339
+ #### Persisting runtime agents
340
+
341
+ Runtime-added agents (like any agent created from the dashboard form) live in memory
342
+ and are lost on restart. To make one durable, open the agent's detail page and use
343
+ **⋮ → Save to `agents/`**. This writes `agents/<name>.rb` (via the same generator as
344
+ *Download Ruby*), which the server re-loads automatically on the next start (see
345
+ [Auto-Loading Custom Code](auto_loading)).
346
+
347
+ ### Tools — "Add Tool to Legion" (gated live install)
348
+
349
+ A generated tool is a Ruby class with an LLM-written `perform_execution`, so loading
350
+ it **executes code in the server process**. The Tool builder therefore offers a live
351
+ **Add Tool to Legion** action only when enabled, behind an explicit confirmation:
352
+
353
+ * Controlled by `Legate.config.allow_runtime_tool_load` — **ON outside production,
354
+ OFF in production** by default (see
355
+ [Configuration → Runtime Tool Loading](../core_concepts/legate_configuration)).
356
+ * You must tick a confirmation acknowledging the code runs on the server.
357
+ * The source is re-validated server-side (`CodeValidator`) before loading, and a
358
+ failing tool is isolated so it can't crash the server.
359
+ * On install it writes `tools/<name>.rb` — durable, auditable, re-loaded next boot.
360
+ * When disabled, the builder offers **Download** instead: save the file under
361
+ `tools/` and restart to activate it.
362
+
363
+ > **Security:** `CodeValidator` is a *denylist*, not a sandbox, and Ruby cannot be
364
+ > meaningfully sandboxed in-process. Keep runtime tool loading enabled only where you
365
+ > trust whoever can reach the (Basic-Auth-protected) web UI.
366
+
367
+ ### Download / manual placement
368
+
369
+ Both builders keep **Copy** and **Download `.rb`** for source-control workflows. To
370
+ place files by hand:
371
+
372
+ - Tools: `lib/tools/` or `agents/lib/tools/` (or `tools/`)
373
+ - Agents: `lib/agents/` or `agents/lib/agents/` (or `agents/`)
374
+
375
+ The Legate web server **automatically loads** these on startup (see
376
+ [Auto-Loading Custom Code](auto_loading)), or you can `require` them yourself.
377
+
378
+ ### Customizing Generated Code
379
+
380
+ The generated code is a starting point. You may want to:
381
+
382
+ - Adjust the instruction/system prompt for your specific use case
383
+ - Add additional error handling
384
+ - Modify parameter validation
385
+ - Add authentication for API tools
386
+ - Customize the model and temperature settings
387
+
388
+ ## Best Practices
389
+
390
+ ### Writing Good Descriptions
391
+
392
+ 1. **Be specific** about what the agent/tool should do
393
+ 2. **Mention tools** you want the agent to use
394
+ 3. **Describe the workflow** for multi-step processes
395
+ 4. **Include constraints** or requirements (e.g., "must handle errors gracefully")
396
+
397
+ ### Security Considerations
398
+
399
+ - Generated code uses `ENV` variables for secrets - never hardcode API keys
400
+ - Review generated webhook validators before using in production
401
+ - Test generated HTTP tools against your actual APIs
402
+
403
+ ### Iterating on Designs
404
+
405
+ 1. Generate initial code from your description
406
+ 2. Review and identify improvements
407
+ 3. Click "Regenerate" with an updated description
408
+ 4. Repeat until satisfied
409
+
410
+ ## Troubleshooting
411
+
412
+ ### "AI service returned empty response"
413
+
414
+ The Gemini API may occasionally return empty responses. Click "Regenerate" to try again.
415
+
416
+ ### The agent needs a tool that doesn't exist
417
+
418
+ The Web UI agent builder filters out any tool that isn't installed, so a generated
419
+ agent never references a missing tool. The gap instead shows up under **"Suggested
420
+ tools to create"** in the review step with a **Build →** button — build and install
421
+ that tool, and it's added back to the agent. (The CLI/`.rb` path can't do this and
422
+ will note the gap in a code comment.)
423
+
424
+ ### API key errors
425
+
426
+ Ensure `GOOGLE_API_KEY` is set in your environment for the generator to work.
427
+
428
+ ## Related Documentation
429
+
430
+ - [Auto-Loading Custom Code](auto_loading) - How to auto-load your custom tools and agents
431
+ - [Built-in Tools](../tools/legate_built_in_tools) - Available tools for agents
432
+ - [Agent Lifecycle](../core_concepts/legate_agent_lifecycle) - Understanding agent execution
433
+ - [Webhooks](webhooks) - Configuring webhook-enabled agents
434
+
435
+
436
+
437
+