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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +345 -0
- data/bin/legate +13 -0
- data/examples/00_quickstart.rb +51 -0
- data/examples/01_simple_agent.rb +105 -0
- data/examples/02_multi_tool_agent.rb +140 -0
- data/examples/03_custom_tool.rb +93 -0
- data/examples/04_agent_instructions.rb +84 -0
- data/examples/05_state_and_sessions.rb +91 -0
- data/examples/06_callbacks.rb +186 -0
- data/examples/07_async_jobs.rb +112 -0
- data/examples/08_loop_agent.rb +197 -0
- data/examples/09_sequential_workflow.rb +40 -0
- data/examples/10_parallel_workflow.rb +34 -0
- data/examples/11_agent_delegation.rb +24 -0
- data/examples/12_http_client_tool.rb +156 -0
- data/examples/13_authentication.rb +220 -0
- data/examples/14_mcp_client.rb +154 -0
- data/examples/15_mcp_server.rb +79 -0
- data/examples/16_webhooks.rb +91 -0
- data/examples/README_sequential_agents.md +164 -0
- data/examples/advanced/auth/cookie_auth_tool.rb +146 -0
- data/examples/advanced/auth/custom_auth_flows_example.rb +626 -0
- data/examples/advanced/auth/excon_middleware.rb +317 -0
- data/examples/advanced/auth/excon_middleware_auth.rb +399 -0
- data/examples/advanced/auth/fiber_auth_example.rb +281 -0
- data/examples/advanced/auth/fiber_oidc_example.rb +403 -0
- data/examples/advanced/auth/httpbin_bearer_tool.rb +159 -0
- data/examples/advanced/auth/oauth2_auth.rb +419 -0
- data/examples/advanced/auth/oidc_auth.rb +514 -0
- data/examples/advanced/auth/openweather_api.rb +251 -0
- data/examples/advanced/auth/openweather_tool.rb +153 -0
- data/examples/advanced/auth/query_param_middleware_test.rb +138 -0
- data/examples/advanced/auth/service_account.rb +135 -0
- data/examples/advanced/auth/test_with_httpbin.rb +202 -0
- data/examples/advanced/auth/token_lifecycle_example.rb +428 -0
- data/examples/advanced/callback_monitoring.rb +679 -0
- data/examples/advanced/mas/fixed_delegation_example.rb +191 -0
- data/examples/advanced/mas/loop_workflow.rb +28 -0
- data/examples/advanced/mas/mock_planner.rb +77 -0
- data/examples/advanced/mas/proper_delegation_example.rb +276 -0
- data/examples/advanced/mcp/legate_mcp_server_resource_example.rb +182 -0
- data/examples/advanced/mcp/mcp_resource_server_example.rb +309 -0
- data/examples/advanced/mcp/mcp_server_async.rb +76 -0
- data/examples/advanced/mcp/mcp_server_async_tools.rb +122 -0
- data/examples/advanced/mcp/mcp_server_legate_agent.rb +95 -0
- data/examples/advanced/mcp/mcp_server_rack.rb +89 -0
- data/examples/advanced/random_calculator.rb +104 -0
- data/examples/advanced/sleep_agent.rb +153 -0
- data/examples/advanced/webhooks/webhook_e2e_runner.rb +110 -0
- data/examples/advanced/webhooks/webhook_receiver_agent.rb +58 -0
- data/examples/advanced/workflows/task_refinement_loop_agent.rb +278 -0
- data/examples/advanced/workflows/travel_planner_auto_sequential.rb +444 -0
- data/examples/advanced/workflows/travel_planner_parallel.rb +656 -0
- data/examples/advanced/workflows/travel_planner_sequential.rb +512 -0
- data/examples/tools/oauth2_example.rb +136 -0
- data/examples/tools/sleepy_tool.rb +42 -0
- data/lib/legate/activity_log.rb +71 -0
- data/lib/legate/agent.rb +959 -0
- data/lib/legate/agent_code_generator.rb +185 -0
- data/lib/legate/agent_definition.rb +812 -0
- data/lib/legate/agentic/decision.rb +49 -0
- data/lib/legate/agentic/loop.rb +134 -0
- data/lib/legate/agentic.rb +5 -0
- data/lib/legate/agents/loop_agent.rb +248 -0
- data/lib/legate/agents/parallel_agent.rb +163 -0
- data/lib/legate/agents/sequential_agent.rb +190 -0
- data/lib/legate/agents.rb +14 -0
- data/lib/legate/auth/config.rb +148 -0
- data/lib/legate/auth/coordinator.rb +218 -0
- data/lib/legate/auth/coordinators/oauth2_coordinator.rb +99 -0
- data/lib/legate/auth/coordinators/oidc_coordinator.rb +68 -0
- data/lib/legate/auth/coordinators/service_account_coordinator.rb +122 -0
- data/lib/legate/auth/credential.rb +157 -0
- data/lib/legate/auth/encryption.rb +108 -0
- data/lib/legate/auth/error.rb +94 -0
- data/lib/legate/auth/exchanged_credential.rb +180 -0
- data/lib/legate/auth/excon_middleware.rb +285 -0
- data/lib/legate/auth/http_client_utils.rb +364 -0
- data/lib/legate/auth/manager.rb +531 -0
- data/lib/legate/auth/manager_store.rb +394 -0
- data/lib/legate/auth/middleware_factory.rb +290 -0
- data/lib/legate/auth/runner.rb +279 -0
- data/lib/legate/auth/scheme.rb +125 -0
- data/lib/legate/auth/schemes/api_key.rb +212 -0
- data/lib/legate/auth/schemes/google_service_account.rb +108 -0
- data/lib/legate/auth/schemes/http_bearer.rb +98 -0
- data/lib/legate/auth/schemes/oauth2.rb +396 -0
- data/lib/legate/auth/schemes/openid_connect.rb +346 -0
- data/lib/legate/auth/schemes/service_account.rb +388 -0
- data/lib/legate/auth/schemes.rb +40 -0
- data/lib/legate/auth/token_manager.rb +362 -0
- data/lib/legate/auth/token_store.rb +86 -0
- data/lib/legate/auth/tool_context_extension.rb +97 -0
- data/lib/legate/auth/tool_integration.rb +188 -0
- data/lib/legate/auth/url_guard.rb +81 -0
- data/lib/legate/auth.rb +453 -0
- data/lib/legate/callbacks/callback_context.rb +71 -0
- data/lib/legate/cli/agent_commands.rb +950 -0
- data/lib/legate/cli/auth_commands.rb +520 -0
- data/lib/legate/cli/base_command.rb +24 -0
- data/lib/legate/cli/deployment_commands.rb +934 -0
- data/lib/legate/cli/output_helper.rb +108 -0
- data/lib/legate/cli/session_commands.rb +138 -0
- data/lib/legate/cli/skaffold_commands.rb +223 -0
- data/lib/legate/cli/tool_commands.rb +261 -0
- data/lib/legate/cli/web_commands.rb +182 -0
- data/lib/legate/cli.rb +40 -0
- data/lib/legate/configuration/webhooks.rb +113 -0
- data/lib/legate/configuration.rb +39 -0
- data/lib/legate/definition_store.rb +23 -0
- data/lib/legate/errors.rb +118 -0
- data/lib/legate/event.rb +161 -0
- data/lib/legate/gemini_ai_beta_patch.rb +39 -0
- data/lib/legate/generators/agent_generator.rb +412 -0
- data/lib/legate/generators/code_validator.rb +48 -0
- data/lib/legate/generators/legate/install_generator.rb +35 -0
- data/lib/legate/generators/legate/templates/create_legate_tables.rb.tt +36 -0
- data/lib/legate/generators/legate/templates/initializer.rb +18 -0
- data/lib/legate/generators/runtime_tool_loader.rb +76 -0
- data/lib/legate/generators/tool_generator.rb +408 -0
- data/lib/legate/generators.rb +11 -0
- data/lib/legate/global_definition_registry.rb +506 -0
- data/lib/legate/global_tool_manager.rb +135 -0
- data/lib/legate/llm/adapter.rb +69 -0
- data/lib/legate/llm/gemini.rb +172 -0
- data/lib/legate/llm/ollama.rb +80 -0
- data/lib/legate/llm.rb +34 -0
- data/lib/legate/mcp/client.rb +320 -0
- data/lib/legate/mcp/connection/sse.rb +292 -0
- data/lib/legate/mcp/connection/stdio.rb +273 -0
- data/lib/legate/mcp/connection_manager.rb +103 -0
- data/lib/legate/mcp/server/legate_agent_adapter.rb +170 -0
- data/lib/legate/mcp/server/legate_direct_agent_adapter.rb +140 -0
- data/lib/legate/mcp/server/legate_tool_adapter.rb +119 -0
- data/lib/legate/mcp/tool_wrapper.rb +138 -0
- data/lib/legate/mcp/util/schema_converter.rb +134 -0
- data/lib/legate/mcp.rb +23 -0
- data/lib/legate/plan_executor.rb +375 -0
- data/lib/legate/planner.rb +839 -0
- data/lib/legate/rails/railtie.rb +43 -0
- data/lib/legate/rails.rb +9 -0
- data/lib/legate/redaction.rb +32 -0
- data/lib/legate/session.rb +299 -0
- data/lib/legate/session_service/active_record.rb +300 -0
- data/lib/legate/session_service/base.rb +68 -0
- data/lib/legate/session_service/event_broadcast.rb +74 -0
- data/lib/legate/session_service/in_memory.rb +188 -0
- data/lib/legate/tool/metadata_dsl.rb +122 -0
- data/lib/legate/tool.rb +276 -0
- data/lib/legate/tool_code_generator.rb +103 -0
- data/lib/legate/tool_context.rb +350 -0
- data/lib/legate/tool_loader.rb +39 -0
- data/lib/legate/tool_registry.rb +73 -0
- data/lib/legate/tool_result.rb +61 -0
- data/lib/legate/tools/agent_tool.rb +187 -0
- data/lib/legate/tools/base/http_client.rb +319 -0
- data/lib/legate/tools/base/safe_url.rb +56 -0
- data/lib/legate/tools/base_async_job_tool.rb +91 -0
- data/lib/legate/tools/calculator.rb +89 -0
- data/lib/legate/tools/cat_facts.rb +81 -0
- data/lib/legate/tools/check_job_status_tool.rb +48 -0
- data/lib/legate/tools/current_time_tool.rb +64 -0
- data/lib/legate/tools/echo.rb +43 -0
- data/lib/legate/tools/http_request_tool.rb +105 -0
- data/lib/legate/tools/random_number_tool.rb +64 -0
- data/lib/legate/tools/read_webpage_tool.rb +92 -0
- data/lib/legate/tools/sleepy_tool.rb +74 -0
- data/lib/legate/tools/webhook_tool.rb +146 -0
- data/lib/legate/version.rb +5 -0
- data/lib/legate/web/app.rb +984 -0
- data/lib/legate/web/public/css/main.css +4980 -0
- data/lib/legate/web/public/images/favicon-256.png +0 -0
- data/lib/legate/web/public/images/favicon-32.png +0 -0
- data/lib/legate/web/public/images/legate-logo-dark.png +0 -0
- data/lib/legate/web/public/images/legate-logo-light.png +0 -0
- data/lib/legate/web/public/js/legate.js +616 -0
- data/lib/legate/web/public/styles/main.scss +4402 -0
- data/lib/legate/web/routes/agent_authentication_routes.rb +530 -0
- data/lib/legate/web/routes/agent_definition_routes.rb +803 -0
- data/lib/legate/web/routes/agent_generator_routes.rb +80 -0
- data/lib/legate/web/routes/agent_interaction_routes.rb +734 -0
- data/lib/legate/web/routes/agent_runtime_routes.rb +323 -0
- data/lib/legate/web/routes/api_routes.rb +56 -0
- data/lib/legate/web/routes/authentication_routes.rb +1541 -0
- data/lib/legate/web/routes/core_routes.rb +111 -0
- data/lib/legate/web/routes/documentation_routes.rb +220 -0
- data/lib/legate/web/routes/tool_generator_routes.rb +81 -0
- data/lib/legate/web/routes/tools_ui_routes.rb +207 -0
- data/lib/legate/web/sass_compiler.rb +73 -0
- data/lib/legate/web/views/_active_session_info.slim +25 -0
- data/lib/legate/web/views/_activity_list.slim +55 -0
- data/lib/legate/web/views/_agent_card.slim +56 -0
- data/lib/legate/web/views/_agent_generator_modal.slim +382 -0
- data/lib/legate/web/views/_agent_status_controls.slim +71 -0
- data/lib/legate/web/views/_agent_tool_table.slim +74 -0
- data/lib/legate/web/views/_chat_message.slim +95 -0
- data/lib/legate/web/views/_display_agent_configuration.slim +26 -0
- data/lib/legate/web/views/_display_agent_description.slim +11 -0
- data/lib/legate/web/views/_display_agent_fallback.slim +15 -0
- data/lib/legate/web/views/_display_agent_hierarchy.slim +93 -0
- data/lib/legate/web/views/_display_agent_instruction.slim +17 -0
- data/lib/legate/web/views/_display_agent_mcp.slim +13 -0
- data/lib/legate/web/views/_display_agent_model.slim +17 -0
- data/lib/legate/web/views/_display_agent_name.slim +42 -0
- data/lib/legate/web/views/_display_agent_output_key.slim +26 -0
- data/lib/legate/web/views/_display_agent_type.slim +65 -0
- data/lib/legate/web/views/_edit_agent_configuration.slim +74 -0
- data/lib/legate/web/views/_edit_agent_description.slim +16 -0
- data/lib/legate/web/views/_edit_agent_fallback.slim +25 -0
- data/lib/legate/web/views/_edit_agent_hierarchy.slim +98 -0
- data/lib/legate/web/views/_edit_agent_instruction.slim +49 -0
- data/lib/legate/web/views/_edit_agent_mcp.slim +33 -0
- data/lib/legate/web/views/_edit_agent_model.slim +23 -0
- data/lib/legate/web/views/_edit_agent_output_key.slim +36 -0
- data/lib/legate/web/views/_edit_agent_tools.slim +40 -0
- data/lib/legate/web/views/_edit_agent_type.slim +67 -0
- data/lib/legate/web/views/_session_error.slim +4 -0
- data/lib/legate/web/views/_skeleton.slim +69 -0
- data/lib/legate/web/views/_tool_card.slim +9 -0
- data/lib/legate/web/views/_tool_generator_modal.slim +311 -0
- data/lib/legate/web/views/agent.slim +436 -0
- data/lib/legate/web/views/agent_auth.slim +562 -0
- data/lib/legate/web/views/agents.slim +369 -0
- data/lib/legate/web/views/auth.slim +112 -0
- data/lib/legate/web/views/auth_credential_detail.slim +327 -0
- data/lib/legate/web/views/auth_credentials.slim +261 -0
- data/lib/legate/web/views/auth_debug.slim +94 -0
- data/lib/legate/web/views/auth_mapping_detail.slim +151 -0
- data/lib/legate/web/views/auth_mapping_new.slim +123 -0
- data/lib/legate/web/views/auth_mappings.slim +120 -0
- data/lib/legate/web/views/auth_scheme_detail.slim +274 -0
- data/lib/legate/web/views/auth_schemes.slim +259 -0
- data/lib/legate/web/views/auth_test.slim +418 -0
- data/lib/legate/web/views/chat.slim +192 -0
- data/lib/legate/web/views/docs_index.slim +105 -0
- data/lib/legate/web/views/docs_show.slim +105 -0
- data/lib/legate/web/views/error_404.slim +5 -0
- data/lib/legate/web/views/index.slim +148 -0
- data/lib/legate/web/views/layout.slim +144 -0
- data/lib/legate/web/views/tool_detail.slim +87 -0
- data/lib/legate/web/views/tools.slim +50 -0
- data/lib/legate/web/webhook_listener.rb +367 -0
- data/lib/legate/web.rb +9 -0
- data/lib/legate.rb +220 -0
- data/public/docs/advanced/callbacks.md +828 -0
- data/public/docs/advanced/mcp_schema_conversion.md +59 -0
- data/public/docs/authentication/api_reference/config.md +210 -0
- data/public/docs/authentication/api_reference/credential.md +246 -0
- data/public/docs/authentication/api_reference/encryption.md +218 -0
- data/public/docs/authentication/api_reference/exchanged_credential.md +271 -0
- data/public/docs/authentication/api_reference/excon_middleware.md +175 -0
- data/public/docs/authentication/api_reference/index.md +30 -0
- data/public/docs/authentication/api_reference/scheme.md +250 -0
- data/public/docs/authentication/api_reference/schemes/api_key.md +175 -0
- data/public/docs/authentication/api_reference/schemes/google_service_account.md +221 -0
- data/public/docs/authentication/api_reference/schemes/http_bearer.md +169 -0
- data/public/docs/authentication/api_reference/schemes/oauth2.md +343 -0
- data/public/docs/authentication/api_reference/schemes/oidc.md +73 -0
- data/public/docs/authentication/api_reference/schemes/openid_connect.md +311 -0
- data/public/docs/authentication/api_reference/schemes/service_account.md +287 -0
- data/public/docs/authentication/api_reference/token_manager.md +221 -0
- data/public/docs/authentication/api_reference/token_store.md +146 -0
- data/public/docs/authentication/api_reference/tool_context_extension.md +166 -0
- data/public/docs/authentication/guides/api_key.md +190 -0
- data/public/docs/authentication/guides/bearer.md +172 -0
- data/public/docs/authentication/guides/configuration.md +255 -0
- data/public/docs/authentication/guides/custom_flow.md +523 -0
- data/public/docs/authentication/guides/index.md +24 -0
- data/public/docs/authentication/guides/migration.md +435 -0
- data/public/docs/authentication/guides/oauth2.md +252 -0
- data/public/docs/authentication/guides/oidc.md +241 -0
- data/public/docs/authentication/guides/overview.md +155 -0
- data/public/docs/authentication/guides/secure_storage.md +301 -0
- data/public/docs/authentication/guides/service_account.md +228 -0
- data/public/docs/authentication/guides/token_lifecycle.md +295 -0
- data/public/docs/authentication/guides/web_ui_integration.md +504 -0
- data/public/docs/authentication/index.md +58 -0
- data/public/docs/authentication/troubleshooting/credential_storage.md +550 -0
- data/public/docs/authentication/troubleshooting/environment_variables.md +540 -0
- data/public/docs/authentication/troubleshooting/index.md +11 -0
- data/public/docs/authentication/troubleshooting/oauth2_issues.md +220 -0
- data/public/docs/authentication/troubleshooting/oidc_issues.md +412 -0
- data/public/docs/authentication/troubleshooting/token_refresh.md +338 -0
- data/public/docs/cli/legate_cli_usage.md +363 -0
- data/public/docs/core_concepts/legate_agent_lifecycle.md +124 -0
- data/public/docs/core_concepts/legate_architecture_overview.md +110 -0
- data/public/docs/core_concepts/legate_configuration.md +116 -0
- data/public/docs/core_concepts/legate_definition_store.md +102 -0
- data/public/docs/core_concepts/legate_planner.md +94 -0
- data/public/docs/core_concepts/legate_session_service.md +104 -0
- data/public/docs/error_handling/legate_error_handling.md +122 -0
- data/public/docs/examples.md +199 -0
- data/public/docs/getting_started.md +111 -0
- data/public/docs/guides/agentic_agents.md +137 -0
- data/public/docs/guides/ai_code_generators.md +437 -0
- data/public/docs/guides/auto_loading.md +326 -0
- data/public/docs/guides/configuring_agent_webhooks.md +219 -0
- data/public/docs/guides/http_client_usage.md +264 -0
- data/public/docs/guides/llm_providers.md +137 -0
- data/public/docs/guides/mcp_client_integration.md +232 -0
- data/public/docs/guides/mcp_server_exposure.md +206 -0
- data/public/docs/guides/rails_integration.md +128 -0
- data/public/docs/guides/sending_outbound_webhooks.md +227 -0
- data/public/docs/guides/streaming.md +112 -0
- data/public/docs/guides/webhooks.md +288 -0
- data/public/docs/introduction.md +51 -0
- data/public/docs/multi_agent_systems/advanced_features.md +57 -0
- data/public/docs/multi_agent_systems/agent_delegation.md +190 -0
- data/public/docs/multi_agent_systems/agent_hierarchy.md +49 -0
- data/public/docs/multi_agent_systems/state_management.md +47 -0
- data/public/docs/multi_agent_systems/workflow_agents.md +72 -0
- data/public/docs/tools/legate_built_in_tools.md +332 -0
- data/public/docs/tools/legate_tools_and_registry.md +263 -0
- data/public/docs/web_ui/legate_web_ui.md +137 -0
- 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)
|