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,261 @@
1
+ # File: lib/legate/cli/tool_commands.rb
2
+ # frozen_string_literal: true
3
+
4
+ require 'thor'
5
+ require_relative 'base_command'
6
+ require_relative 'output_helper' # OutputHelper is included below
7
+ require_relative '../global_tool_manager' # Require the global manager
8
+ require_relative '../tool_context' # <--- ADDED require
9
+ require 'securerandom' # <-- ADDED require for dummy context
10
+
11
+ module Legate
12
+ module CLI
13
+ # CLI commands for tool management using ToolRegistry
14
+ class ToolCommands < BaseCommand
15
+ include OutputHelper
16
+
17
+ desc 'list', 'List available tools from the registry'
18
+ method_option :json, type: :boolean, default: false,
19
+ desc: 'Output result in JSON format'
20
+ def list
21
+ tools = Legate::GlobalToolManager.list_all_tools
22
+ if json_mode?
23
+ puts JSON.generate({ tools: tools.map { |t| { name: t[:name].to_s, description: t[:description] } } })
24
+ elsif tools.empty?
25
+ say 'No tools registered.'
26
+ else
27
+ say 'Available tools:', :bold
28
+ tools.each do |tool_info|
29
+ say "- #{tool_info[:name]}: #{tool_info[:description]}"
30
+ end
31
+ end
32
+ end
33
+
34
+ desc 'info NAME', 'Show information about a tool from the registry'
35
+ def info(name)
36
+ tool_name_sym = name.to_sym
37
+ tool = Legate::GlobalToolManager.create_instance(tool_name_sym) # Create instance to get params
38
+
39
+ if tool
40
+ say "Tool: #{tool.name}"
41
+ say "Description: #{tool.description}"
42
+ if tool.parameters.empty?
43
+ say "\nParameters: None"
44
+ else
45
+ say "\nParameters:"
46
+ tool.parameters.each do |param_name, param_info|
47
+ required = param_info[:required] ? 'required' : 'optional'
48
+ type = param_info[:type] || 'any'
49
+ say " - #{param_name} (#{type}, #{required})"
50
+ say " #{param_info[:description]}"
51
+ end
52
+ end
53
+ else
54
+ say "Tool '#{name}' not found in registry.", :red
55
+ end
56
+ end
57
+
58
+ desc 'execute NAME [param1=value1 param2=value2 ...]', 'Execute a tool directly using key=value arguments'
59
+ long_desc <<-LONGDESC
60
+ Executes a specified tool directly with key=value pair arguments.
61
+
62
+ Example:
63
+ legate tool execute calculator operand1=10 operand2=5 operation=add
64
+
65
+ Arguments should be provided as `key=value`. If a value contains spaces,
66
+ it might need quoting depending on your shell.
67
+
68
+ If the tool execution results in a :pending status (e.g., for an async job),
69
+ the job_id will be printed. Use the check_job_status tool
70
+ in a subsequent call to get the final result.
71
+ LONGDESC
72
+ method_option :quiet, type: :boolean, default: false, aliases: '-q',
73
+ desc: 'Suppress status messages, only output result'
74
+ method_option :json, type: :boolean, default: false,
75
+ desc: 'Output result in JSON format (implies --quiet)'
76
+ method_option :user_id, type: :string, default: 'cli_user', desc: 'User ID for the tool context'
77
+ def execute(name, *args)
78
+ # Suppress all logging in JSON mode for clean output
79
+ Legate.logger.level = Logger::FATAL if json_mode?
80
+
81
+ tool_name_sym = name.to_sym
82
+ tool = Legate::GlobalToolManager.create_instance(tool_name_sym)
83
+
84
+ unless tool
85
+ output_error("Tool '#{name}' not found in registry.", metadata: { tool: name })
86
+ exit(1)
87
+ end
88
+
89
+ params_to_execute = {}
90
+ valid_param_names = tool.parameters.keys.map(&:to_s)
91
+
92
+ args.each do |arg|
93
+ parts = arg.split('=', 2)
94
+ if parts.length == 2
95
+ key = parts[0].strip
96
+ value = parts[1]
97
+
98
+ unless valid_param_names.include?(key)
99
+ status_message("Warning: Provided parameter '#{key}' is not defined for tool '#{name}'. Ignoring.", :yellow)
100
+ next
101
+ end
102
+
103
+ params_to_execute[key.to_sym] = value # Store as symbol key
104
+ status_message(" Parsed: #{key} = '#{value}'")
105
+ elsif args.length == 1 && tool.parameters.length == 1 && tool.parameters.values.first[:required]
106
+ # Simplified single arg handling
107
+ single_key = tool.parameters.keys.first
108
+ status_message("Info: Assuming single argument '#{arg}' maps to required parameter '#{single_key}'.", :cyan)
109
+ params_to_execute[single_key] = arg
110
+ elsif !args.empty?
111
+ status_message("Warning: Argument '#{arg}' ignored. Please use 'key=value' format for parameters.", :yellow)
112
+ end
113
+ end
114
+
115
+ begin
116
+ status_message("Executing tool '#{name}' with parsed params: #{params_to_execute.inspect}")
117
+ # --- Create a dummy context for direct tool execution ---
118
+ dummy_context = Legate::ToolContext.new(session_id: "cli_direct_#{SecureRandom.hex(4)}", user_id: options[:user_id],
119
+ app_name: 'cli_tool_exec')
120
+
121
+ # --- Call execute with context ---
122
+ result_hash = tool.execute(params_to_execute, dummy_context)
123
+
124
+ status_message("\nResult:", :bold)
125
+ output_result(result_hash, metadata: { tool: name }, format_method: :format_tool_result)
126
+ rescue Legate::Error, ArgumentError => e
127
+ output_error(e, metadata: { tool: name })
128
+ exit(1)
129
+ rescue StandardError => e
130
+ output_error(e, metadata: { tool: name })
131
+ puts e.backtrace.first(5).join("\n") unless json_mode?
132
+ exit(1)
133
+ end
134
+ end # end execute
135
+
136
+ no_commands do
137
+ # Format tool result in human-readable format
138
+ def format_tool_result(result_hash)
139
+ if result_hash.is_a?(Hash) && result_hash.key?(:status)
140
+ case result_hash[:status]
141
+ when :success
142
+ say 'Success:', :green
143
+ say " Output: #{result_hash[:result]}"
144
+ when :pending
145
+ say 'Pending:', :yellow
146
+ say " Job ID: #{result_hash[:job_id]}"
147
+ say " Message: #{result_hash[:message]}" if result_hash[:message]
148
+ when :error
149
+ say 'Error:', :red
150
+ say " Message: #{result_hash[:error_message]}"
151
+ else
152
+ say 'Unknown Status:', :yellow
153
+ say " Data: #{result_hash.inspect}"
154
+ end
155
+ else
156
+ say 'Unknown Result Format:', :yellow
157
+ say " Data: #{result_hash.inspect}"
158
+ end
159
+ end
160
+ end
161
+
162
+ desc 'ai_generate', 'Generate tool class code using AI from a natural language description'
163
+ long_desc <<-LONGDESC
164
+ Uses AI (Gemini LLM) to generate a production-ready tool class based on
165
+ your natural language description. The AI automatically determines if the
166
+ tool should be a simple tool, HTTP API tool, or async tool.
167
+
168
+ Input sources (in priority order):
169
+ 1. --description / -d : Inline description
170
+ 2. --prompt-file / -f : Read description from a file
171
+ 3. stdin : Pipe description via stdin (auto-enables stdout output)
172
+
173
+ Output destinations:
174
+ - Default: Writes to ./<suggested_name>.rb
175
+ - --output / -o : Custom output file path
176
+ - --stdout : Output to stdout instead of file
177
+ - When reading from stdin: Auto-outputs to stdout
178
+
179
+ Examples:
180
+ legate tool ai_generate -d "A tool that converts temperatures between Celsius and Fahrenheit"
181
+ legate tool ai_generate -d "A tool that checks if a URL is reachable" -o ./tools/url_checker.rb
182
+ echo "A calculator that adds two numbers" | legate tool ai_generate
183
+ echo "A weather API tool" | legate tool ai_generate > weather_tool.rb
184
+
185
+ Requires GOOGLE_API_KEY environment variable to be set.
186
+ LONGDESC
187
+ method_option :description, aliases: '-d', type: :string, desc: 'Description of the tool to generate'
188
+ method_option :prompt_file, aliases: '-f', type: :string, desc: 'Read description from a file'
189
+ method_option :output, aliases: '-o', type: :string, desc: 'Output file path (default: ./<suggested_name>.rb)'
190
+ method_option :stdout, type: :boolean, default: false, desc: 'Output to stdout instead of file'
191
+ method_option :force, type: :boolean, default: false, desc: 'Overwrite existing file without prompting'
192
+ def ai_generate
193
+ require_relative '../generators'
194
+
195
+ description = nil
196
+ from_stdin = false
197
+
198
+ # Priority: --description > --prompt-file > stdin
199
+ if options[:description] && !options[:description].strip.empty?
200
+ description = options[:description].strip
201
+ elsif options[:prompt_file]
202
+ unless File.exist?(options[:prompt_file])
203
+ say "Error: Prompt file '#{options[:prompt_file]}' not found.", :red
204
+ exit(1)
205
+ end
206
+ description = File.read(options[:prompt_file]).strip
207
+ elsif !$stdin.tty?
208
+ # Reading from stdin (piped input)
209
+ description = $stdin.read.strip
210
+ from_stdin = true
211
+ end
212
+
213
+ if description.nil? || description.empty?
214
+ say 'Error: No description provided. Use --description, --prompt-file, or pipe via stdin.', :red
215
+ exit(1)
216
+ end
217
+
218
+ # Determine output mode
219
+ output_to_stdout = options[:stdout] || from_stdin
220
+
221
+ say 'Generating tool code via AI...', :cyan unless output_to_stdout
222
+
223
+ begin
224
+ result = Legate::Generators::ToolGenerator.generate(description: description)
225
+ code = result[:code]
226
+ suggested_name = result[:suggested_name]
227
+ tool_type = result[:tool_type]
228
+
229
+ if output_to_stdout
230
+ puts code
231
+ else
232
+ # Write to file
233
+ file_path = options[:output] || "./#{suggested_name}.rb"
234
+
235
+ if File.exist?(file_path) && !options[:force] && !yes?("File '#{file_path}' already exists. Overwrite? [y/N]", :yellow)
236
+ say 'Generation cancelled.', :yellow
237
+ exit(0)
238
+ end
239
+
240
+ File.write(file_path, code)
241
+ say "Tool code generated and saved to '#{file_path}'", :green
242
+ say " Suggested name: #{suggested_name}", :cyan
243
+ say " Tool type: #{tool_type}", :cyan
244
+ end
245
+ rescue Legate::Generators::ToolGenerator::ApiKeyMissingError => e
246
+ say "Error: #{e.message}", :red
247
+ exit(1)
248
+ rescue Legate::Generators::ToolGenerator::ApiError => e
249
+ say "Error: #{e.message}", :red
250
+ exit(1)
251
+ rescue Legate::Generators::ToolGenerator::GenerationError => e
252
+ say "Error: #{e.message}", :red
253
+ exit(1)
254
+ rescue StandardError => e
255
+ say "Unexpected error: #{e.class} - #{e.message}", :red
256
+ exit(1)
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rack' # Required for Rack::Builder
4
+ require 'rack/handler/puma' # Use Rack::Handler for Rack 2.x compatibility
5
+ require_relative '../web' # Loads the web UI (and core, if not already loaded)
6
+ require_relative 'base_command'
7
+ # Webhook listener required conditionally below
8
+
9
+ module Legate
10
+ module CLI
11
+ # CLI commands for web interface
12
+ class WebCommands < BaseCommand
13
+ # Conventional directories to scan for custom tools and agents
14
+ TOOL_DIRECTORIES = [
15
+ 'lib/tools',
16
+ 'agents/lib/tools',
17
+ 'tools'
18
+ ].freeze
19
+
20
+ AGENT_DIRECTORIES = [
21
+ 'lib/agents',
22
+ 'agents/lib/agents',
23
+ 'agents'
24
+ ].freeze
25
+
26
+ # Optional initializer file that runs before auto-loading
27
+ INIT_FILES = [
28
+ 'legate_init.rb',
29
+ 'config/legate_init.rb',
30
+ 'agents/legate_init.rb'
31
+ ].freeze
32
+
33
+ desc 'start', 'Start the web interface'
34
+ method_option :port, type: :numeric, default: 4567, desc: 'Port to listen on'
35
+ method_option :host, type: :string, default: 'localhost', desc: 'Host to bind to'
36
+ method_option :no_autoload, type: :boolean, default: false, desc: 'Disable auto-loading of custom tools and agents'
37
+ def start
38
+ # Auto-load custom tools and agents unless disabled
39
+ unless options[:no_autoload]
40
+ load_custom_initializer
41
+ load_custom_tools
42
+ load_custom_agents
43
+ end
44
+
45
+ # Access config early
46
+ webhook_config = Legate.config.webhooks
47
+ listener_enabled = webhook_config.listener_enabled
48
+ listener_base_path = webhook_config.base_path
49
+
50
+ # Build the Rack application stack
51
+ app = Rack::Builder.new do
52
+ # Conditionally mount the Webhook Listener
53
+ if listener_enabled
54
+ Legate.logger.info "Webhook listener enabled, mounting at #{listener_base_path}"
55
+ begin
56
+ require_relative '../web/webhook_listener'
57
+ map listener_base_path do
58
+ run Legate::Web::WebhookListener.new
59
+ end
60
+ rescue LoadError => e
61
+ Legate.logger.error "Failed to load WebhookListener: #{e.message}. Listener will not be mounted."
62
+ rescue StandardError => e
63
+ Legate.logger.error "Error initializing WebhookListener: #{e.message}. Listener will not be mounted."
64
+ end
65
+ else
66
+ Legate.logger.debug 'Webhook listener is disabled.'
67
+ end
68
+
69
+ # Mount the main Legate Web App at the root
70
+ run Legate::Web::App.new
71
+ end.to_app # Convert builder block to a Rack app
72
+
73
+ # Start the server using Rack::Handler::Puma (Rack 2.x compatible)
74
+ say "Starting Legate web interface on http://#{options[:host]}:#{options[:port]}"
75
+ Rack::Handler::Puma.run(
76
+ app,
77
+ Host: options[:host],
78
+ Port: options[:port],
79
+ Silent: false
80
+ )
81
+ end
82
+
83
+ private
84
+
85
+ # Load optional initializer file if present
86
+ def load_custom_initializer
87
+ INIT_FILES.each do |init_file|
88
+ full_path = File.expand_path(init_file, Dir.pwd)
89
+ next unless File.exist?(full_path)
90
+
91
+ Legate.logger.info "Loading custom initializer: #{full_path}"
92
+ begin
93
+ require full_path
94
+ Legate.logger.info "Successfully loaded initializer: #{init_file}"
95
+ break # Only load the first one found
96
+ rescue LoadError, StandardError => e
97
+ Legate.logger.error "Error loading initializer #{init_file}: #{e.class} - #{e.message}"
98
+ Legate.logger.debug e.backtrace.first(5).join("\n") if e.backtrace
99
+ end
100
+ end
101
+ end
102
+
103
+ # Auto-discover and load custom tools from conventional directories
104
+ def load_custom_tools
105
+ tools_loaded = 0
106
+ base_dir = Dir.pwd
107
+
108
+ TOOL_DIRECTORIES.each do |tool_dir|
109
+ full_dir = File.join(base_dir, tool_dir)
110
+ next unless Dir.exist?(full_dir)
111
+
112
+ # Find all .rb files in the directory (and subdirectories)
113
+ Dir.glob(File.join(full_dir, '**', '*.rb')).sort.each do |tool_file|
114
+ # Skip files that look like tests or specs
115
+ next if tool_file.include?('_spec.rb') || tool_file.include?('_test.rb')
116
+
117
+ begin
118
+ require tool_file
119
+ tools_loaded += 1
120
+ Legate.logger.debug "Loaded custom tool file: #{tool_file}"
121
+ rescue LoadError, StandardError => e
122
+ Legate.logger.warn "Failed to load tool file #{tool_file}: #{e.class} - #{e.message}"
123
+ Legate.logger.debug e.backtrace.first(3).join("\n") if e.backtrace
124
+ end
125
+ end
126
+ end
127
+
128
+ return unless tools_loaded.positive?
129
+
130
+ Legate.logger.info "Auto-loaded #{tools_loaded} custom tool file(s). " \
131
+ "Registered tools: #{Legate::GlobalToolManager.registered_tool_names.inspect}"
132
+ end
133
+
134
+ # Auto-discover and load custom agent definitions from conventional directories
135
+ def load_custom_agents
136
+ agents_loaded = 0
137
+ base_dir = Dir.pwd
138
+
139
+ AGENT_DIRECTORIES.each do |agent_dir|
140
+ full_dir = File.join(base_dir, agent_dir)
141
+ next unless Dir.exist?(full_dir)
142
+
143
+ # Find all .rb files in the directory (and subdirectories)
144
+ Dir.glob(File.join(full_dir, '**', '*.rb')).sort.each do |agent_file|
145
+ # Skip files that look like tests, specs, or tools
146
+ next if agent_file.include?('_spec.rb') || agent_file.include?('_test.rb')
147
+ next if agent_file.include?('/tools/') # Don't load tools from agent directories
148
+
149
+ begin
150
+ require agent_file
151
+ agents_loaded += 1
152
+ Legate.logger.debug "Loaded custom agent file: #{agent_file}"
153
+ rescue LoadError, StandardError => e
154
+ Legate.logger.warn "Failed to load agent file #{agent_file}: #{e.class} - #{e.message}"
155
+ Legate.logger.debug e.backtrace.first(3).join("\n") if e.backtrace
156
+ end
157
+ end
158
+ end
159
+
160
+ return unless agents_loaded.positive?
161
+
162
+ registered_agents = begin
163
+ Legate::GlobalDefinitionRegistry.all.keys
164
+ rescue StandardError
165
+ []
166
+ end
167
+ Legate.logger.info "Auto-loaded #{agents_loaded} custom agent file(s). " \
168
+ "Registered agents: #{registered_agents.inspect}"
169
+
170
+ # Sync loaded agents to the definition store so they appear in the Web UI
171
+ sync_agents_to_definition_store
172
+ end
173
+
174
+ # Agents auto-loaded from files are already in GlobalDefinitionRegistry,
175
+ # which serves as the definition store. No sync needed.
176
+ def sync_agents_to_definition_store
177
+ # No-op: GlobalDefinitionRegistry is the sole definition store.
178
+ Legate.logger.debug 'Agents are already in GlobalDefinitionRegistry (in-memory definition store).'
179
+ end
180
+ end
181
+ end
182
+ end
data/lib/legate/cli.rb ADDED
@@ -0,0 +1,40 @@
1
+ # File: lib/legate/cli.rb
2
+ # frozen_string_literal: true
3
+
4
+ require 'thor'
5
+ # Require the files that DEFINE the command classes first
6
+ require_relative 'cli/base_command'
7
+ require_relative 'cli/output_helper'
8
+ require_relative 'cli/agent_commands'
9
+ require_relative 'cli/tool_commands'
10
+ require_relative 'cli/web_commands'
11
+ require_relative 'cli/session_commands'
12
+ require_relative 'cli/deployment_commands'
13
+ require_relative 'cli/skaffold_commands'
14
+ require_relative 'cli/auth_commands'
15
+
16
+ module Legate
17
+ module CLI
18
+ # Main CLI class that provides the entry point for all Legate commands
19
+ class Main < BaseCommand
20
+ desc 'version', 'Display the Legate version'
21
+ def version
22
+ puts "Legate version #{Legate::VERSION}"
23
+ end
24
+
25
+ # Register subcommands
26
+ register(AgentCommands, 'agent', 'agent <command>',
27
+ 'Manage Legate agents and execution (list, save, delete, generate, execute, start)')
28
+ register(ToolCommands, 'tool', 'tool <command>', 'Manage Legate tools')
29
+ register(WebCommands, 'web', 'web <command>', 'Manage Legate web interface')
30
+ register(SessionCommands, 'session', 'session <command>', 'Manage Legate sessions')
31
+ register(DeploymentCommands, 'deployment', 'deployment <command>',
32
+ 'Generate deployment assets for cloud platforms')
33
+ register(SkaffoldCommands, 'skaffold', 'skaffold [PROJECT_NAME]',
34
+ 'Generate a new Legate project structure (alias: new, init)')
35
+ register(AuthCommands, 'auth', 'auth <command>',
36
+ 'Manage authentication schemes, credentials, and URL mappings')
37
+ end
38
+ # --- End Main class definition ---
39
+ end # End CLI module
40
+ end # End Legate module
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legate/session_service/base'
4
+
5
+ module Legate
6
+ class Configuration
7
+ # Configuration settings for the inbound webhook listener and processing.
8
+ class Webhooks
9
+ # @return [Boolean] Whether the webhook listener is enabled. Defaults to false.
10
+ attr_accessor :listener_enabled
11
+
12
+ # @return [String] The IP address the listener should bind to. Defaults to '127.0.0.1'.
13
+ attr_accessor :listen_address
14
+
15
+ # @return [Integer] The port the listener should bind to. Defaults to 9292.
16
+ attr_accessor :listen_port
17
+
18
+ # @return [String] The base path for all webhook routes. Defaults to '/webhooks'.
19
+ attr_accessor :base_path
20
+
21
+ # @return [Boolean] Whether the dynamic agent handler route is enabled. Defaults to false.
22
+ attr_accessor :enable_dynamic_agent_handler
23
+
24
+ # @return [String] The path pattern for the dynamic agent handler. Defaults to '/agents/:agent_name/trigger'.
25
+ attr_accessor :dynamic_agent_route_pattern
26
+
27
+ # @return [Symbol, Proc, nil] A global validator to apply if an agent doesn't specify one.
28
+ attr_accessor :global_validator
29
+
30
+ # @return [String, nil] The secret key used by the global validator (e.g., for HMAC).
31
+ attr_accessor :global_secret
32
+
33
+ # @return [Legate::SessionService::Base, nil] The default session service instance to use in the webhook worker.
34
+ attr_accessor :default_session_service
35
+
36
+ def initialize
37
+ @listener_enabled = true # Enable listener by default for easier testing/use
38
+ @listen_address = '127.0.0.1' # Default to loopback for security
39
+ @listen_port = 9292
40
+ @base_path = '/webhooks'
41
+ @enable_dynamic_agent_handler = true # Enable dynamic handler by default for easier testing
42
+ @dynamic_agent_route_pattern = '/agents/:agent_name/trigger'
43
+ @global_validator = nil
44
+ @global_secret = nil
45
+ @default_session_service = nil
46
+ @validators = {}
47
+ @static_routes = {} # Store static routes: path -> RouteConfig
48
+ end
49
+
50
+ # Registers a named validator proc/lambda.
51
+ #
52
+ # @param name [Symbol] The name to register the validator under.
53
+ # @yield [request, secret] The block that performs validation.
54
+ # @yieldparam request The Rack request object.
55
+ # @yieldparam secret [String, nil] The secret associated with the route/agent.
56
+ # @yieldreturn [Boolean] True if the request is valid, false otherwise.
57
+ # @raise [ArgumentError] If the name is already registered or no block is given.
58
+ def register_validator(name, &block)
59
+ raise ArgumentError, "Validator name :#{name} is already registered." if @validators.key?(name)
60
+ raise ArgumentError, 'Validator requires a block.' unless block_given?
61
+
62
+ @validators[name] = block
63
+ end
64
+
65
+ # Finds a registered validator by name.
66
+ #
67
+ # @param name [Symbol] The name of the validator.
68
+ # @return [Proc, nil] The validator proc or nil if not found.
69
+ def find_validator(name)
70
+ @validators[name]
71
+ end
72
+
73
+ # Registers a static webhook route.
74
+ # Primarily intended for simple, non-agent-related endpoints like health checks.
75
+ # Agent-related webhooks should typically use the dynamic agent handler.
76
+ #
77
+ # @param path [String] The HTTP method and path pattern (e.g., "GET /system/health", "POST /simple").
78
+ # @yield [route_config] The block to configure the route.
79
+ # @yieldparam route_config [RouteConfig] The configuration object for this route.
80
+ # @raise [ArgumentError] If the path is already registered or no block is given.
81
+ def register_route(path)
82
+ raise ArgumentError, "Route path \"#{path}\" is already registered." if @static_routes.key?(path)
83
+ raise ArgumentError, 'Route registration requires a block.' unless block_given?
84
+
85
+ config = RouteConfig.new
86
+ yield config
87
+ @static_routes[path] = config
88
+ end
89
+
90
+ # Retrieves the configurations for all registered static routes.
91
+ # @return [Hash{String => RouteConfig}] A hash mapping path patterns to their configurations.
92
+ def static_routes
93
+ @static_routes.dup # Return a copy to prevent external modification
94
+ end
95
+
96
+ # Internal class to hold configuration for a single static route.
97
+ class RouteConfig
98
+ # @return [Proc, nil] The handler proc for the route. Should return a Rack response array.
99
+ attr_accessor :handler
100
+ # @return [Symbol, Proc, nil] A specific validator for this static route.
101
+ attr_accessor :validator
102
+ # @return [String, nil] The secret key for this static route's validator.
103
+ attr_accessor :secret
104
+
105
+ def initialize
106
+ @handler = nil
107
+ @validator = nil
108
+ @secret = nil
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legate/agent'
4
+ require_relative 'session_service/in_memory'
5
+ require 'legate/configuration/webhooks'
6
+
7
+ module Legate
8
+ # Central configuration object for the Legate framework.
9
+ # Access via `Legate.config` after calling `Legate.configure`.
10
+ class Configuration
11
+ # @return [Legate::SessionService::Base] The service used to manage agent session state.
12
+ attr_accessor :session_service
13
+
14
+ # @return [Symbol] Default model name to use if not specified in agent definition.
15
+ attr_accessor :default_model_name
16
+
17
+ # @return [Float] Default temperature to use if not specified in agent definition.
18
+ attr_accessor :default_temperature
19
+
20
+ # @return [Legate::Configuration::Webhooks] Webhook configuration.
21
+ attr_reader :webhooks
22
+
23
+ # @return [Boolean] Whether the web UI may load AI-generated custom tools into
24
+ # the running process (this executes LLM-generated Ruby — see
25
+ # Legate::Generators::RuntimeToolLoader). Defaults to ON outside production
26
+ # and OFF in production. Override explicitly via
27
+ # `Legate.configure { |c| c.allow_runtime_tool_load = true/false }`.
28
+ attr_accessor :allow_runtime_tool_load
29
+
30
+ def initialize
31
+ # Always use in-memory session service (Redis dependency removed)
32
+ @session_service = Legate::SessionService::InMemory.new
33
+ @default_model_name = 'gemini-3.5-flash'
34
+ @default_temperature = 0.7
35
+ @webhooks = Legate::Configuration::Webhooks.new
36
+ @allow_runtime_tool_load = ENV['RACK_ENV'] != 'production'
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ # File: lib/legate/definition_store.rb
2
+ # frozen_string_literal: true
3
+
4
+ module Legate
5
+ # Module responsible for persisting and retrieving agent definitions.
6
+ # Implementations should provide methods for CRUD operations on definitions.
7
+ module DefinitionStore
8
+ # NOTE: Base error classes (Error, ConfigurationError, StoreError)
9
+ # are defined in lib/legate/errors.rb and inherit from Legate::Error.
10
+
11
+ # Error raised when a definition is not found
12
+ # Inherits from Legate::DefinitionStore::Error defined in errors.rb
13
+ class NotFoundError < Error; end # Use the base Error defined in errors.rb (Legate::DefinitionStore::Error)
14
+
15
+ # Removing redundant/conflicting definitions:
16
+ # class StoreError < StandardError; end
17
+ # class ConfigurationError < StoreError; end
18
+
19
+ # Potential future: Define abstract methods or rely on duck typing for implementations.
20
+
21
+ # Definitions are stored in-memory via GlobalDefinitionRegistry.
22
+ end
23
+ end