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,116 @@
|
|
|
1
|
+
# Legate Configuration
|
|
2
|
+
|
|
3
|
+
This document explains how to configure the global settings for the Legate framework using the `Legate.configure` block.
|
|
4
|
+
|
|
5
|
+
## 1. Overview
|
|
6
|
+
|
|
7
|
+
Many aspects of the Legate's behavior, such as logging, session management, and webhook settings, can be customized globally. This is typically done once during your application's initialization phase (e.g., in `config/initializers/legate.rb` for Rails/Sinatra, or near the start of a standalone script).
|
|
8
|
+
|
|
9
|
+
The configuration is managed through a singleton `Legate::Configuration` object, accessed via `Legate.configure` or `Legate.config`.
|
|
10
|
+
|
|
11
|
+
## 2. Using `Legate.configure`
|
|
12
|
+
|
|
13
|
+
The primary way to set configuration is using the `Legate.configure` block:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
# config/initializers/legate.rb or similar
|
|
17
|
+
require 'legate'
|
|
18
|
+
|
|
19
|
+
Legate.configure do |config|
|
|
20
|
+
# Note: log level is NOT configured here. It is controlled exclusively by
|
|
21
|
+
# the LEGATE_LOG_LEVEL environment variable (see section 4.1 / 5).
|
|
22
|
+
|
|
23
|
+
# Configure the session service (see legate_session_service)
|
|
24
|
+
# Sessions are always in-memory
|
|
25
|
+
config.session_service = Legate::SessionService::InMemory.new
|
|
26
|
+
|
|
27
|
+
# Configure Webhook settings (see webhooks)
|
|
28
|
+
config.webhooks.listener_enabled = true
|
|
29
|
+
config.webhooks.listen_address = "0.0.0.0"
|
|
30
|
+
config.webhooks.listen_port = 9293
|
|
31
|
+
config.webhooks.base_path = "/legate-hooks"
|
|
32
|
+
config.webhooks.enable_dynamic_agent_handler = true
|
|
33
|
+
# Register custom webhook validators...
|
|
34
|
+
# config.webhooks.register_validator(:my_validator) { |req, secret| ... }
|
|
35
|
+
|
|
36
|
+
# Configure other settings as they become available...
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
* The `Legate.configure` method yields the singleton `Legate::Configuration` instance.
|
|
41
|
+
* You modify the attributes of this `config` object within the block.
|
|
42
|
+
* This block should typically run only once during application startup.
|
|
43
|
+
|
|
44
|
+
## 3. Accessing Configuration (`Legate.config`)
|
|
45
|
+
|
|
46
|
+
After the initial configuration, you can access the current settings using `Legate.config`:
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
# Get the configured session service later in your code
|
|
50
|
+
service = Legate.config.session_service
|
|
51
|
+
|
|
52
|
+
# Get the webhook base path
|
|
53
|
+
base_path = Legate.config.webhooks.base_path
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 4. Key Configuration Areas
|
|
57
|
+
|
|
58
|
+
### 4.1. Logging (`LEGATE_LOG_LEVEL`)
|
|
59
|
+
|
|
60
|
+
* The log level is **not** a `Legate::Configuration` attribute and cannot be set inside the `Legate.configure` block. Assigning `config.log_level` raises `NoMethodError`.
|
|
61
|
+
* The minimum severity level for messages logged by `Legate.logger` is controlled **only** by the `LEGATE_LOG_LEVEL` environment variable (falling back to a default derived from `RACK_ENV` when unset).
|
|
62
|
+
* Accepts: `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`, `NONE`, `SILENT`.
|
|
63
|
+
* See `legate.rb` for the eager initialization logic of the logger.
|
|
64
|
+
|
|
65
|
+
### 4.2. Session Service (`config.session_service`)
|
|
66
|
+
|
|
67
|
+
* Assign an instance of a session service implementation (`Legate::SessionService::InMemory.new`).
|
|
68
|
+
* This instance will be used by default when agents need to interact with sessions, unless a different service is explicitly passed.
|
|
69
|
+
* See `public/docs/core_concepts/legate_session_service.md` for details.
|
|
70
|
+
|
|
71
|
+
### 4.3. Webhooks (`config.webhooks`)
|
|
72
|
+
|
|
73
|
+
* Accessed via `config.webhooks`, which returns an `Legate::Configuration::Webhooks` instance.
|
|
74
|
+
* Controls the built-in webhook listener and dynamic agent triggering.
|
|
75
|
+
* Settings include `listener_enabled`, `listen_address`, `listen_port`, `base_path`, `enable_dynamic_agent_handler`, etc.
|
|
76
|
+
* Also provides methods to `register_validator` for webhook security.
|
|
77
|
+
* See `public/docs/guides/webhooks.md` and `public/docs/guides/configuring_agent_webhooks.md` for details.
|
|
78
|
+
|
|
79
|
+
### 4.4. Runtime Tool Loading (`config.allow_runtime_tool_load`)
|
|
80
|
+
|
|
81
|
+
Controls whether the Web UI's AI **tool** builder may load a generated custom tool
|
|
82
|
+
into the **running** process ("Add Tool to Legion"). Because this executes
|
|
83
|
+
LLM-generated Ruby in-process, it is gated:
|
|
84
|
+
|
|
85
|
+
* **Default:** ON outside production, OFF in production
|
|
86
|
+
(`ENV['RACK_ENV'] != 'production'`).
|
|
87
|
+
* Override explicitly:
|
|
88
|
+
```ruby
|
|
89
|
+
Legate.configure { |config| config.allow_runtime_tool_load = false }
|
|
90
|
+
```
|
|
91
|
+
* When enabled, installing a tool also writes `tools/<name>.rb` (durable and
|
|
92
|
+
auditable; re-loaded on next boot). When disabled, the builder offers Download
|
|
93
|
+
only — place the file in `tools/` and restart to activate it.
|
|
94
|
+
* **Security:** the generated source is re-validated server-side
|
|
95
|
+
(`CodeValidator`, a *denylist* — not a sandbox), the UI requires an explicit
|
|
96
|
+
per-tool confirmation, and the web UI sits behind Basic Auth. Ruby has no true
|
|
97
|
+
in-process sandbox, so only enable this where you trust the operators. See
|
|
98
|
+
[AI-Powered Code Generators](../guides/ai_code_generators).
|
|
99
|
+
|
|
100
|
+
## 5. Environment Variables
|
|
101
|
+
|
|
102
|
+
Several configuration options can also be influenced by environment variables, which are often loaded via `.env` files using the `dotenv` gem (loaded by `Legate.load_environment`). Environment variables typically take precedence during initial setup:
|
|
103
|
+
|
|
104
|
+
* `LEGATE_LOG_LEVEL`: Sets the initial log level (`DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`, `NONE`, `SILENT`).
|
|
105
|
+
* `GOOGLE_API_KEY`: The API key for Gemini LLM integration.
|
|
106
|
+
* `RACK_ENV`: `development` / `production`. Among other things it sets the default
|
|
107
|
+
of `allow_runtime_tool_load` (OFF in production) and enables secure session cookies.
|
|
108
|
+
* Other environment variables might be used internally by specific components or within your application's Legate configuration block (e.g., `ENV['NOTIFICATION_API_URL']` in custom tool examples).
|
|
109
|
+
|
|
110
|
+
It's common practice to use environment variables for settings that differ between development, testing, and production environments (like API keys, etc.).
|
|
111
|
+
|
|
112
|
+
## Further Reading
|
|
113
|
+
|
|
114
|
+
* [`legate_architecture_overview`](./legate_architecture_overview)
|
|
115
|
+
* [`legate_session_service`](./legate_session_service)
|
|
116
|
+
* [`webhooks`](../guides/webhooks)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Legate Definition Store
|
|
2
|
+
|
|
3
|
+
This document explains the purpose and usage of the Definition Store in the Legate framework, which is responsible for persisting and retrieving agent definitions.
|
|
4
|
+
|
|
5
|
+
## 1. Purpose
|
|
6
|
+
|
|
7
|
+
An agent's definition contains its core configuration: name, instructions, description, associated tools, model configuration, webhook settings, etc. While agents can be defined purely in code, storing these definitions externally allows:
|
|
8
|
+
|
|
9
|
+
* Creating and managing agents via tools like the Legate CLI or Web UI without modifying application code.
|
|
10
|
+
* Dynamically loading agent configurations at runtime.
|
|
11
|
+
|
|
12
|
+
The `GlobalDefinitionRegistry` provides the in-memory storage for agent definitions.
|
|
13
|
+
|
|
14
|
+
## 2. Architecture Overview
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
graph LR
|
|
18
|
+
UserInteraction["Legate CLI / Web UI"] -- Creates/Updates --> DefinitionStore["Legate::GlobalDefinitionRegistry"]
|
|
19
|
+
AgentLoader["Agent Loading Logic (e.g., Web App)"] -- Loads Definition --> DefinitionStore
|
|
20
|
+
DefinitionStore -- Reads/Writes --> Storage["Storage: In-Memory"]
|
|
21
|
+
AgentLoader -- Uses Definition --> Agent["Legate::Agent Instance"]
|
|
22
|
+
|
|
23
|
+
style DefinitionStore fill:#fcc,stroke:#333,stroke-width:2px
|
|
24
|
+
style Storage fill:#ffc,stroke:#333,stroke-width:2px
|
|
25
|
+
style Agent fill:#ccf,stroke:#333,stroke-width:2px
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
* User interfaces (like the Legate CLI or Web UI) interact with the `GlobalDefinitionRegistry` to save, update, or list agent definitions.
|
|
29
|
+
* Application components that need to run specific agents (like the Legate Web App or a custom script) use the `GlobalDefinitionRegistry` to retrieve the definition by name.
|
|
30
|
+
* The retrieved definition data is then used to initialize an `Legate::Agent` instance.
|
|
31
|
+
* All definitions are stored in-memory via `Legate::GlobalDefinitionRegistry`.
|
|
32
|
+
|
|
33
|
+
## 3. `Legate::GlobalDefinitionRegistry`
|
|
34
|
+
|
|
35
|
+
This is the primary implementation provided by Legate. It stores all agent definitions in-memory.
|
|
36
|
+
|
|
37
|
+
### 3.1. Initialization
|
|
38
|
+
|
|
39
|
+
The `GlobalDefinitionRegistry` is a module with class-level methods, so no instantiation is needed. Definitions are registered directly:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
# Register a definition
|
|
43
|
+
definition = Legate::AgentDefinition.new.define do |a|
|
|
44
|
+
a.name :my_agent
|
|
45
|
+
a.description 'My agent'
|
|
46
|
+
a.instruction 'Be helpful.'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
Legate::GlobalDefinitionRegistry.register(definition)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 3.2. Core Methods
|
|
53
|
+
|
|
54
|
+
* **`register(definition)`**: Registers an `AgentDefinition` in the registry.
|
|
55
|
+
* **`find(agent_name) -> AgentDefinition | nil`**: Retrieves the definition for a given agent name. Returns `nil` if not found.
|
|
56
|
+
* **`all -> Array<AgentDefinition>`**: Returns an array of all registered agent definitions.
|
|
57
|
+
* **`definition_exists?(agent_name) -> Boolean`**: Checks if a definition exists for the given name.
|
|
58
|
+
* **`delete_definition(agent_name)`**: Removes an agent definition from the registry.
|
|
59
|
+
* **`clear!`**: Clears all registered definitions (primarily used in testing).
|
|
60
|
+
|
|
61
|
+
## 4. Usage Examples
|
|
62
|
+
|
|
63
|
+
### Registering a New Definition
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
definition = Legate::AgentDefinition.new.define do |a|
|
|
67
|
+
a.name :my_new_agent
|
|
68
|
+
a.description "An agent created via the registry."
|
|
69
|
+
a.instruction "Be helpful."
|
|
70
|
+
a.use_tool :calculator
|
|
71
|
+
a.use_tool :echo
|
|
72
|
+
a.model_name "gemini-2.0-flash"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
Legate::GlobalDefinitionRegistry.register(definition)
|
|
76
|
+
puts "Agent definition registered."
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Retrieving and Using a Definition
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
agent_name = :my_new_agent
|
|
83
|
+
|
|
84
|
+
definition = Legate::GlobalDefinitionRegistry.find(agent_name)
|
|
85
|
+
|
|
86
|
+
if definition
|
|
87
|
+
puts "Found definition: #{definition.inspect}"
|
|
88
|
+
|
|
89
|
+
# Instantiate the agent using the definition object
|
|
90
|
+
agent_instance = Legate::Agent.new(definition: definition)
|
|
91
|
+
puts "Agent instance created: #{agent_instance.name}"
|
|
92
|
+
# agent_instance.start # Start the agent if needed
|
|
93
|
+
else
|
|
94
|
+
puts "Agent definition '#{agent_name}' not found."
|
|
95
|
+
end
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Further Reading
|
|
99
|
+
|
|
100
|
+
* [`legate_architecture_overview`](./legate_architecture_overview)
|
|
101
|
+
* [`legate_agent_lifecycle`](./legate_agent_lifecycle)
|
|
102
|
+
* [`legate_configuration`](./legate_configuration)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Legate Planner
|
|
2
|
+
|
|
3
|
+
This document describes the role and function of the `Legate::Planner` within the Legate framework. The Planner is a key component responsible for determining the sequence of actions (tool calls) an agent should take to fulfill a user's request.
|
|
4
|
+
|
|
5
|
+
## 1. Purpose
|
|
6
|
+
|
|
7
|
+
When an agent receives a user task, it often needs a strategy to achieve the goal, especially if the task requires multiple steps or the use of tools. The `Legate::Planner`'s primary purpose is to:
|
|
8
|
+
|
|
9
|
+
* Analyze the user's request in the context of the agent's instructions and conversation history.
|
|
10
|
+
* Consider the tools available to the agent (provided via `Legate::ToolRegistry`).
|
|
11
|
+
* Generate a step-by-step plan, usually consisting of tool calls with specific parameters.
|
|
12
|
+
* Handle situations where planning might fail or need revision based on tool results.
|
|
13
|
+
|
|
14
|
+
Legate's default planner leverages a Language Model (LLM) to perform this reasoning and plan generation, making use of the descriptive metadata provided by each tool.
|
|
15
|
+
|
|
16
|
+
## 2. Interaction with Agent
|
|
17
|
+
|
|
18
|
+
The `Legate::Agent` delegates planning to the `Planner` during the `run_task` execution flow.
|
|
19
|
+
|
|
20
|
+
```mermaid
|
|
21
|
+
graph LR
|
|
22
|
+
Agent[Legate::Agent] -- Requests Plan --> Planner[Legate::Planner]
|
|
23
|
+
Planner -- Needs Context --> Agent
|
|
24
|
+
Agent -- Provides --> Instructions[Agent Instructions]
|
|
25
|
+
Agent -- Provides --> History[Session History]
|
|
26
|
+
Agent -- Provides --> ToolRegistry[Agent's ToolRegistry]
|
|
27
|
+
|
|
28
|
+
Planner -- Uses --> ToolRegistry
|
|
29
|
+
Planner -- Sends Context & Tool Schemas --> LLM[Language Model]
|
|
30
|
+
LLM -- Returns Plan --> Planner
|
|
31
|
+
Planner -- Returns Plan --> Agent
|
|
32
|
+
|
|
33
|
+
style Agent fill:#ccf,stroke:#333,stroke-width:2px
|
|
34
|
+
style Planner fill:#cff,stroke:#333,stroke-width:2px
|
|
35
|
+
style LLM fill:#f9f,stroke:#333,stroke-width:2px
|
|
36
|
+
style ToolRegistry fill:#cfc,stroke:#333,stroke-width:2px
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
1. The Agent calls `planner.plan(user_input, invocation_id)`.
|
|
40
|
+
2. The Agent provides the necessary context: its core `instruction` prompt, the current `session_history` (from the `SessionService`), and access to its `ToolRegistry`.
|
|
41
|
+
3. The Planner retrieves the metadata (name, description, parameters) for all available tools from the `ToolRegistry`.
|
|
42
|
+
4. The Planner constructs a prompt for the LLM, including the user request, agent instructions, conversation history, and the formatted list of available tools and their schemas.
|
|
43
|
+
5. The LLM processes this prompt and generates a plan, typically formatted as a list of tool calls with arguments.
|
|
44
|
+
6. The Planner parses the LLM's response into a structured plan object (e.g., an array of step hashes).
|
|
45
|
+
7. The Planner returns this structured plan to the Agent.
|
|
46
|
+
8. The Agent then proceeds to execute the steps in the plan.
|
|
47
|
+
|
|
48
|
+
## 3. Planning Process & LLM Interaction
|
|
49
|
+
|
|
50
|
+
The planner talks to the LLM through a pluggable adapter (`Legate::LLM::Adapter`). **Gemini is the default**, and a local **Ollama** adapter ships in the box; you can point Legate at any provider — or your own implementation — without changing your agents. See the [LLM Providers guide](../guides/llm_providers) for how to select or implement a provider.
|
|
51
|
+
|
|
52
|
+
The effectiveness of the planner heavily relies on the quality of the prompt sent to the LLM and the LLM's ability to reason and follow instructions.
|
|
53
|
+
|
|
54
|
+
* **Tool Descriptions:** Clear and accurate `description` fields in your `Legate::Tool` metadata are crucial. The LLM uses these descriptions to understand when and how to use each tool.
|
|
55
|
+
* **Parameter Schemas:** Well-defined `parameters` in the tool metadata allow the LLM to determine the necessary arguments for each tool call in the plan.
|
|
56
|
+
* **Agent Instructions:** The agent's main `instruction` prompt sets the overall context and constraints for the LLM's planning process.
|
|
57
|
+
* **History:** Providing conversation history allows the planner to consider previous interactions when creating the current plan.
|
|
58
|
+
* **LLM Choice:** The specific LLM used (configured via the agent's `model_name`) significantly impacts planning capabilities.
|
|
59
|
+
|
|
60
|
+
## 4. Plan Structure
|
|
61
|
+
|
|
62
|
+
While the exact internal representation might vary, a plan generated by the `Legate::Planner` typically consists of a sequence of steps, where each step represents an action, most commonly a tool call. A step usually includes:
|
|
63
|
+
|
|
64
|
+
The `plan` method returns a Hash with two keys:
|
|
65
|
+
|
|
66
|
+
* **`thought_process` (String):** The LLM's reasoning about how to approach the request.
|
|
67
|
+
* **`steps` (Array\<Hash\>):** The sequence of tool execution steps.
|
|
68
|
+
|
|
69
|
+
Each step Hash contains:
|
|
70
|
+
|
|
71
|
+
* **`tool` (Symbol):** The name of the tool to execute.
|
|
72
|
+
* **`params` (Hash):** The arguments to pass to the tool's `execute` method.
|
|
73
|
+
* **`reason` (String):** A brief explanation of why this step is needed.
|
|
74
|
+
|
|
75
|
+
## 5. Re-planning and Error Handling
|
|
76
|
+
|
|
77
|
+
Planning isn't always a single-shot process:
|
|
78
|
+
|
|
79
|
+
* **Tool Errors:** If a tool execution fails during plan execution, the Agent might ask the `Planner` to revise the plan based on the error.
|
|
80
|
+
* **Ambiguity:** If the initial plan is insufficient or based on incomplete information, the agent might engage in further interaction (possibly involving the planner again) to clarify before proceeding.
|
|
81
|
+
* **No Plan:** If the LLM fails to generate a valid plan, the Planner communicates this back to the Agent, which then decides how to proceed based on its `fallback_mode`.
|
|
82
|
+
|
|
83
|
+
## 6. Configuration and Customization (Future)
|
|
84
|
+
|
|
85
|
+
Currently, the default planner's behavior is largely determined by the agent's configuration (instructions, tools, model). Future versions of Legate might introduce:
|
|
86
|
+
|
|
87
|
+
* Explicit planner configuration options.
|
|
88
|
+
* Support for different planning strategies or planner implementations beyond the default LLM-based approach.
|
|
89
|
+
|
|
90
|
+
## Further Reading
|
|
91
|
+
|
|
92
|
+
* [`legate_architecture_overview`](./legate_architecture_overview)
|
|
93
|
+
* [`legate_agent_lifecycle`](./legate_agent_lifecycle)
|
|
94
|
+
* [`legate_tools_and_registry`](../tools/legate_tools_and_registry)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Legate Session Service
|
|
2
|
+
|
|
3
|
+
This document explains the role and functionality of the Session Service within the Legate framework. The Session Service is responsible for managing the state and history of conversations between users and agents.
|
|
4
|
+
|
|
5
|
+
## 1. Purpose
|
|
6
|
+
|
|
7
|
+
Agents often need to maintain context over multiple turns of a conversation. This includes remembering:
|
|
8
|
+
|
|
9
|
+
* Past user inputs.
|
|
10
|
+
* Agent responses.
|
|
11
|
+
* Tools called and their results.
|
|
12
|
+
* Temporary state data relevant to the ongoing task.
|
|
13
|
+
|
|
14
|
+
The Session Service provides a persistent or in-memory store for this information, encapsulated within `Legate::Session` objects.
|
|
15
|
+
|
|
16
|
+
## 2. Architecture Overview
|
|
17
|
+
|
|
18
|
+
```mermaid
|
|
19
|
+
graph LR
|
|
20
|
+
Agent[Legate::Agent] -- Uses --> SessionService[Legate::SessionService]
|
|
21
|
+
SessionService -- Manages --> SessionObjects[Legate::Session Objects]
|
|
22
|
+
SessionObjects -- Contain --> Events[Legate::Event History]
|
|
23
|
+
SessionObjects -- Contain --> State[Session State]
|
|
24
|
+
SessionService -- Persists/Retrieves --> Storage[(Storage: In-Memory)]
|
|
25
|
+
|
|
26
|
+
style Agent fill:#ccf,stroke:#333,stroke-width:2px
|
|
27
|
+
style SessionService fill:#fcc,stroke:#333,stroke-width:2px
|
|
28
|
+
style SessionObjects fill:#eef,stroke:#333,stroke-width:1px
|
|
29
|
+
style Storage fill:#ffc,stroke:#333,stroke-width:2px
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
* The `Legate::Agent` interacts with a configured `SessionService` implementation.
|
|
33
|
+
* The `SessionService` is responsible for creating, retrieving, saving, and deleting `Legate::Session` instances.
|
|
34
|
+
* Each `Legate::Session` holds the list of `Legate::Event`s constituting the conversation history and a key-value store for session-specific state.
|
|
35
|
+
* The `SessionService` implementation dictates how Sessions are stored (in memory).
|
|
36
|
+
|
|
37
|
+
## 3. Core Interface (`Legate::SessionService::Base`)
|
|
38
|
+
|
|
39
|
+
All session service implementations should adhere to the interface defined by `Legate::SessionService::Base` (though Ruby doesn't enforce interfaces strictly). Key methods include:
|
|
40
|
+
|
|
41
|
+
* **`persistent?() -> Boolean`**: Returns whether this service persists state.
|
|
42
|
+
* **`save_scoped_state(scope, key, value)`**: Saves a key-value pair within a specific scope (e.g., `'user'`, `'app'`, `'temp'`).
|
|
43
|
+
* **`load_scoped_state(scope, key) -> Object | nil`**: Retrieves a value associated with a specific key within a given scope.
|
|
44
|
+
* **`clear_scoped_state(scope, key)`**: Clears a key within a specific scope.
|
|
45
|
+
* **`append_event(session_id:, event:)`**: Adds a new `Legate::Event` to the specified session's history.
|
|
46
|
+
* **`set_state(session_id:, key:, value:)`**: Sets a key-value pair in the state associated with a session.
|
|
47
|
+
* **`get_state(session_id:, key:) -> Object | nil`**: Retrieves a value from the state associated with a session.
|
|
48
|
+
|
|
49
|
+
Note: The concrete implementation `Legate::SessionService::InMemory` also provides additional methods such as `create_session`, `get_session`, and `delete_session` for full session lifecycle management.
|
|
50
|
+
|
|
51
|
+
## 4. Implementation
|
|
52
|
+
|
|
53
|
+
Legate provides an in-memory session service:
|
|
54
|
+
|
|
55
|
+
* **`Legate::SessionService::InMemory`**: Stores all session data directly in the Ruby process's memory using `Concurrent::Map` for thread safety.
|
|
56
|
+
* **Pros:** Simple, no external dependencies, fast, thread-safe.
|
|
57
|
+
* **Cons:** Data is lost when the process restarts. Not suitable for multi-process or distributed deployments.
|
|
58
|
+
|
|
59
|
+
## 5. Configuration
|
|
60
|
+
|
|
61
|
+
You configure the session service implementation when setting up the Legate, typically within the `Legate.configure` block:
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
require 'legate/session_service/in_memory'
|
|
65
|
+
|
|
66
|
+
Legate.configure do |config|
|
|
67
|
+
# Use In-Memory session service
|
|
68
|
+
config.session_service = Legate::SessionService::InMemory.new
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Access the configured instance later:
|
|
72
|
+
service = Legate.config.session_service
|
|
73
|
+
session = service.create_session(app_name: 'my_app', user_id: 'user123')
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 6. Interaction with `Legate::Agent`
|
|
77
|
+
|
|
78
|
+
The `Legate::Agent` relies heavily on the configured Session Service during `run_task`:
|
|
79
|
+
|
|
80
|
+
1. It calls `get_session` (or `create_session` implicitly if needed) to load the session context.
|
|
81
|
+
2. It passes the `session_service` instance within the `Legate::ToolContext` to tools, allowing them potential access.
|
|
82
|
+
3. It uses `add_event_to_session` to record user input, tool requests, tool results, and agent responses, thus building the conversation history.
|
|
83
|
+
4. The `Legate::Planner` typically receives the session history (retrieved via `get_session_history` by the agent) to inform its planning process.
|
|
84
|
+
|
|
85
|
+
## 7. Scoped State (`user:`, `app:`, `temp:`)
|
|
86
|
+
|
|
87
|
+
The session service supports *scoped state* via key prefixes. This allows organizing key-value data by scope:
|
|
88
|
+
|
|
89
|
+
* **`user:<key>`**: Data scoped to a specific `(app_name, user_id)` pair. It is shared across all of that user's sessions within the same application, but **not** across different applications.
|
|
90
|
+
* **`app:<key>`**: Data scoped to a specific `app_name`. It is shared across all users and sessions of that application.
|
|
91
|
+
* **`temp:<key>`**: Data scoped to a single session (keyed by the session `id`).
|
|
92
|
+
|
|
93
|
+
When using `set_state`, `get_state`, or `delete_state` with a key containing a valid prefix (e.g., `'user:preference'`), the value is persisted through the session **service's** scoped-state store (`save_scoped_state` / `load_scoped_state` / `clear_scoped_state`), not through the session's internal `@state` map. Plain keys without a prefix remain in the session's internal state.
|
|
94
|
+
|
|
95
|
+
## 8. Serialization
|
|
96
|
+
|
|
97
|
+
`Legate::Session` and `Legate::Event` objects provide `to_h` methods to convert their state into Ruby Hashes suitable for JSON serialization. Correspondingly, they have `from_h` class methods to reconstruct objects from these Hash representations.
|
|
98
|
+
|
|
99
|
+
(See `Legate::Session` and `Legate::Event` for details on their attributes and serializable format).
|
|
100
|
+
|
|
101
|
+
## Further Reading
|
|
102
|
+
|
|
103
|
+
* [`legate_architecture_overview`](./legate_architecture_overview)
|
|
104
|
+
* [`legate_agent_lifecycle`](./legate_agent_lifecycle)
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Legate Error Handling
|
|
2
|
+
|
|
3
|
+
This guide covers common Legate-specific exception classes and provides an overview of potential error scenarios and how they are typically handled within the framework.
|
|
4
|
+
|
|
5
|
+
## Philosophy
|
|
6
|
+
|
|
7
|
+
Legate aims to use specific error classes to help developers pinpoint the source and nature of issues. When tools encounter problems, they should generally raise an appropriate `Legate::ToolError` subclass rather than returning an error status in their result hash. The Legate agent runtime is designed to catch these exceptions and format them into a standard error event for the LLM.
|
|
8
|
+
|
|
9
|
+
## Core Exception Hierarchy
|
|
10
|
+
|
|
11
|
+
Most Legate-specific errors inherit from `Legate::Error < StandardError`.
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
graph TD
|
|
15
|
+
A[StandardError] --> B(Legate::Error)
|
|
16
|
+
|
|
17
|
+
B --> C1(Legate::ConfigurationError)
|
|
18
|
+
B --> C3(Legate::ToolError)
|
|
19
|
+
B --> C5(Legate::StoreError)
|
|
20
|
+
B --> C6(Legate::Mcp::Error)
|
|
21
|
+
B --> C8(Legate::WebhookConfigurationError)
|
|
22
|
+
B --> C9(Legate::InvalidPrefixError)
|
|
23
|
+
B --> C10(Legate::SerializationError)
|
|
24
|
+
|
|
25
|
+
C3 --> T1(Legate::ToolArgumentError)
|
|
26
|
+
C3 --> T2(Legate::ToolNetworkError)
|
|
27
|
+
C3 --> T3(Legate::ToolTimeoutError)
|
|
28
|
+
C3 --> T4(Legate::ToolHttpError)
|
|
29
|
+
T2 --> T2a(Legate::ToolCertificateError)
|
|
30
|
+
|
|
31
|
+
B --> DS1(Legate::DefinitionStore::Error)
|
|
32
|
+
DS1 --> DS3(Legate::DefinitionStore::StoreError)
|
|
33
|
+
DS1 --> DS4(Legate::DefinitionStore::NotFoundError)
|
|
34
|
+
|
|
35
|
+
C6 --> M1(Legate::Mcp::ConnectionError)
|
|
36
|
+
C6 --> M2(Legate::Mcp::ProtocolError)
|
|
37
|
+
C6 --> M4(Legate::Mcp::RemoteToolError)
|
|
38
|
+
|
|
39
|
+
style B fill:#f9f,stroke:#333,stroke-width:2px
|
|
40
|
+
style C3 fill:#ccf,stroke:#333,stroke-width:1px
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> **Note:** `Legate::DefinitionStore::Error` inherits directly from `Legate::Error`; it is not a subclass of `Legate::StoreError`.
|
|
44
|
+
|
|
45
|
+
## Key Legate Exception Classes
|
|
46
|
+
|
|
47
|
+
### 1. `Legate::ConfigurationError`
|
|
48
|
+
* **Purpose**: Raised when there's an issue with the Legate framework's configuration. This could be due to missing required settings, invalid values for configuration parameters (e.g., in `Legate.configure` blocks or environment variables that Legate relies on).
|
|
49
|
+
* **Example Scenarios**: Missing API key, misconfigured session service type.
|
|
50
|
+
* **Typically Handled By**: Application startup checks; often fatal if core services cannot be initialized.
|
|
51
|
+
|
|
52
|
+
### 2. State Errors (`Legate::InvalidPrefixError`, `Legate::SerializationError`)
|
|
53
|
+
* **`Legate::InvalidPrefixError`**: Raised when an invalid prefix is used in a state key (the recognized scoped prefixes are `user:`, `app:`, and `temp:`).
|
|
54
|
+
* **`Legate::SerializationError`**: Raised when a state value cannot be serialized for persistence.
|
|
55
|
+
* **Typically Handled By**: Session state management logic when reading or writing scoped state.
|
|
56
|
+
|
|
57
|
+
### 3. `Legate::ToolError` (and its subclasses)
|
|
58
|
+
This is a broad category for errors originating from within an Legate tool's execution.
|
|
59
|
+
|
|
60
|
+
* **`Legate::ToolError` (Base)**
|
|
61
|
+
* **Purpose**: Generic error during a tool's execution that doesn't fit a more specific subclass. Often used to wrap unexpected exceptions within a tool.
|
|
62
|
+
* **Attributes**: Can have a `cause` attribute storing the original exception.
|
|
63
|
+
* **`Legate::ToolArgumentError < Legate::ToolError`**
|
|
64
|
+
* **Purpose**: Raised when the parameters provided to a tool are invalid (e.g., missing required parameters, incorrect data types, values out of allowed range).
|
|
65
|
+
* **Example Scenarios**: Calculator tool receiving a string for `operand1`, WebhookTool missing the `url`.
|
|
66
|
+
* **`Legate::ToolNetworkError < Legate::ToolError`**
|
|
67
|
+
* **Purpose**: General network-related issues encountered by a tool (often an HTTP-based tool). This excludes timeouts or specific HTTP error statuses.
|
|
68
|
+
* **Example Scenarios**: DNS resolution failure, TCP connection refused (not due to timeout).
|
|
69
|
+
* **`Legate::ToolCertificateError < Legate::ToolNetworkError`**
|
|
70
|
+
* **Purpose**: Specifically for SSL/TLS certificate validation failures during an HTTPS request by a tool.
|
|
71
|
+
* **`Legate::ToolTimeoutError < Legate::ToolError`**
|
|
72
|
+
* **Purpose**: Raised when a tool operation (typically a network request) exceeds its allowed timeout.
|
|
73
|
+
* **Example Scenarios**: HTTP request taking too long to connect or receive a response.
|
|
74
|
+
* **`Legate::ToolHttpError < Legate::ToolError`**
|
|
75
|
+
* **Purpose**: Raised when an HTTP request made by a tool results in an unsuccessful HTTP status code (e.g., 4xx client errors, 5xx server errors).
|
|
76
|
+
* **Attributes**: Contains a `response` attribute holding the HTTP response object (e.g., `Excon::Response`), allowing access to status, headers, and body.
|
|
77
|
+
* **Example Scenarios**: Tool calling an API that returns a 404 Not Found or 500 Internal Server Error.
|
|
78
|
+
* **Typically Handled By**: The `Legate::Agent` catches these. The agent typically creates an error event containing the exception message, which is then presented to the LLM. The LLM might then inform the user or attempt a corrective action.
|
|
79
|
+
|
|
80
|
+
### 4. `Legate::StoreError` and `Legate::DefinitionStore` Errors
|
|
81
|
+
* **`Legate::StoreError`**: Base error for failures in persistence layers used for sessions or agent definitions.
|
|
82
|
+
* **`Legate::DefinitionStore::Error`**: Base for errors specific to the agent definition store (inherits directly from `Legate::Error`).
|
|
83
|
+
* **`Legate::DefinitionStore::StoreError`**: General errors interacting with the definition store backend.
|
|
84
|
+
* **`Legate::DefinitionStore::NotFoundError`**: A specific agent definition could not be found in the store.
|
|
85
|
+
* **Example Scenarios**: Trying to load a non-existent agent from the `GlobalDefinitionRegistry`.
|
|
86
|
+
* **Typically Handled By**: Agent loading/management logic (e.g., in the Web UI or CLI); may prevent an agent from starting or being used.
|
|
87
|
+
|
|
88
|
+
### 5. `Legate::Mcp::Error` (and its subclasses)
|
|
89
|
+
Errors related to the Model Context Protocol (MCP) for tool communication with external tool servers.
|
|
90
|
+
* **`Legate::Mcp::ConnectionError`**: Problems establishing a connection to an MCP server (including handshake/initialization failures).
|
|
91
|
+
* **`Legate::Mcp::ProtocolError`**: Violations of the MCP JSON-RPC specifications.
|
|
92
|
+
* **`Legate::Mcp::RemoteToolError`**: An error reported by the remote MCP server during the execution of one of its tools. Carries optional `code` and `data` attributes from the remote error.
|
|
93
|
+
* **Example Scenarios**: MCP server is down, malformed JSON-RPC message, tool on MCP server fails.
|
|
94
|
+
* **Typically Handled By**: MCP client logic within Legate; often results in a `ToolError` if an agent was trying to use an MCP-hosted tool.
|
|
95
|
+
|
|
96
|
+
### 6. `Legate::WebhookConfigurationError`
|
|
97
|
+
* **Purpose**: Raised for webhook configuration or processing errors within the inbound webhook listener (e.g., from a `webhook_transformer` or `webhook_session_extractor` Proc).
|
|
98
|
+
* **Example Scenarios**: A webhook payload is missing required fields, or a session ID cannot be extracted.
|
|
99
|
+
* **Typically Handled By**: The webhook listener, which translates it into an HTTP error response (e.g., `400 Bad Request`).
|
|
100
|
+
|
|
101
|
+
## General Error Handling in Agents
|
|
102
|
+
|
|
103
|
+
When an agent executes a tool and the tool raises one of these exceptions (especially `Legate::ToolError` subclasses):
|
|
104
|
+
1. The `Legate::Agent` runtime catches the exception.
|
|
105
|
+
2. It logs the error.
|
|
106
|
+
3. It constructs an `Legate::Event` of type `:error` (or `:tool_error`). This event typically includes:
|
|
107
|
+
* The name of the tool that failed.
|
|
108
|
+
* The error message from the exception.
|
|
109
|
+
* The class name of the exception.
|
|
110
|
+
* Sometimes, additional details or the original `cause`.
|
|
111
|
+
4. This error event is added to the session history.
|
|
112
|
+
5. The error event (or a summary) is then provided back to the Large Language Model as part of the context for its next turn.
|
|
113
|
+
6. The LLM can then decide how to proceed, which might involve:
|
|
114
|
+
* Informing the user of the failure.
|
|
115
|
+
* Trying a different tool or approach.
|
|
116
|
+
* Asking the user for clarification.
|
|
117
|
+
|
|
118
|
+
## HTTP Client Error Handling (`Legate::Tools::Base::HttpClient`)
|
|
119
|
+
|
|
120
|
+
Tools that use the `Legate::Tools::Base::HttpClient` mixin (like `CatFacts` or `WebhookTool`) benefit from standardized error handling for HTTP operations. This mixin automatically wraps common `Excon::Error` exceptions into the more specific `Legate::ToolNetworkError`, `Legate::ToolCertificateError`, `Legate::ToolTimeoutError`, or `Legate::ToolHttpError`.
|
|
121
|
+
|
|
122
|
+
This ensures consistent error reporting from tools that make external HTTP calls.
|