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,118 @@
|
|
|
1
|
+
# File: lib/legate/errors.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Single authoritative error hierarchy for the Legate framework.
|
|
5
|
+
# All Legate error classes are defined here.
|
|
6
|
+
|
|
7
|
+
module Legate
|
|
8
|
+
# Base error class for all Legate errors.
|
|
9
|
+
class Error < StandardError; end
|
|
10
|
+
|
|
11
|
+
# --- Configuration Errors ---
|
|
12
|
+
|
|
13
|
+
# Raised when a required configuration is missing or invalid.
|
|
14
|
+
class ConfigurationError < Error; end
|
|
15
|
+
|
|
16
|
+
# --- State Errors ---
|
|
17
|
+
|
|
18
|
+
# Raised when an invalid prefix is used in state keys.
|
|
19
|
+
class InvalidPrefixError < Error; end
|
|
20
|
+
|
|
21
|
+
# Raised when state value cannot be serialized.
|
|
22
|
+
class SerializationError < Error; end
|
|
23
|
+
|
|
24
|
+
# --- Tool Errors ---
|
|
25
|
+
|
|
26
|
+
# Base class for errors raised during tool execution.
|
|
27
|
+
# Supports wrapping an original cause exception for debugging.
|
|
28
|
+
class ToolError < Error
|
|
29
|
+
# @param message [String] The error message.
|
|
30
|
+
# @param cause [Exception, nil] The original exception that triggered this error.
|
|
31
|
+
def initialize(message = nil, cause: nil)
|
|
32
|
+
super(message)
|
|
33
|
+
@cause = cause
|
|
34
|
+
set_backtrace(cause.backtrace) if cause&.backtrace
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# The explicit wrapped cause if one was passed, otherwise Ruby's implicit
|
|
38
|
+
# cause (set automatically when the error is raised inside a rescue). Falling
|
|
39
|
+
# back to `super` means a caller that does `raise ToolError, msg` inside a
|
|
40
|
+
# rescue still surfaces the real cause instead of nil.
|
|
41
|
+
# @return [Exception, nil] The original exception that caused this error.
|
|
42
|
+
def cause
|
|
43
|
+
@cause || super
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Raised when tool arguments are invalid (e.g., missing, wrong type).
|
|
48
|
+
class ToolArgumentError < ToolError; end
|
|
49
|
+
|
|
50
|
+
# Raised when a tool encounters a network-related issue (connection failures, DNS, SSL errors).
|
|
51
|
+
class ToolNetworkError < ToolError; end
|
|
52
|
+
|
|
53
|
+
# Raised when SSL/TLS certificate verification fails during an HTTP request.
|
|
54
|
+
class ToolCertificateError < ToolNetworkError; end
|
|
55
|
+
|
|
56
|
+
# Raised when a tool operation times out (connection, read, or write timeout).
|
|
57
|
+
class ToolTimeoutError < ToolError; end
|
|
58
|
+
|
|
59
|
+
# Raised when an HTTP request receives an unsuccessful status code (4xx or 5xx).
|
|
60
|
+
class ToolHttpError < ToolError
|
|
61
|
+
# @return [Object, nil] The HTTP response object (provides status, headers, body).
|
|
62
|
+
attr_reader :response
|
|
63
|
+
|
|
64
|
+
# @param message [String] The error message.
|
|
65
|
+
# @param response [Object, nil] The HTTP response object.
|
|
66
|
+
# @param cause [Exception, nil] The original exception.
|
|
67
|
+
def initialize(message = nil, response: nil, cause: nil)
|
|
68
|
+
super(message, cause: cause)
|
|
69
|
+
@response = response
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# --- Webhook Errors ---
|
|
74
|
+
|
|
75
|
+
# Raised for webhook configuration or processing errors within the listener.
|
|
76
|
+
class WebhookConfigurationError < Error; end
|
|
77
|
+
|
|
78
|
+
# --- Storage Errors ---
|
|
79
|
+
|
|
80
|
+
# Raised for definition or session storage operation failures.
|
|
81
|
+
class StoreError < Error; end
|
|
82
|
+
|
|
83
|
+
# --- Definition Store Errors ---
|
|
84
|
+
module DefinitionStore
|
|
85
|
+
class Error < Legate::Error; end
|
|
86
|
+
class StoreError < Error; end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# --- MCP Errors ---
|
|
90
|
+
module Mcp
|
|
91
|
+
# Base class for MCP-specific errors.
|
|
92
|
+
class Error < Legate::Error; end
|
|
93
|
+
|
|
94
|
+
# Raised when an MCP connection cannot be established.
|
|
95
|
+
class ConnectionError < Error; end
|
|
96
|
+
|
|
97
|
+
# Raised for MCP protocol violations or JSON-RPC formatting errors.
|
|
98
|
+
class ProtocolError < Error; end
|
|
99
|
+
|
|
100
|
+
# Error received from a remote MCP server during a tool call.
|
|
101
|
+
class RemoteToolError < Error
|
|
102
|
+
attr_reader :code, :data
|
|
103
|
+
|
|
104
|
+
def initialize(message, code = nil, data = nil)
|
|
105
|
+
super(message)
|
|
106
|
+
@code = code
|
|
107
|
+
@data = data
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def to_s
|
|
111
|
+
str = super
|
|
112
|
+
str += " (Code: #{@code})" if @code
|
|
113
|
+
str += " Data: #{@data.inspect}" if @data
|
|
114
|
+
str
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
data/lib/legate/event.rb
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# File: lib/legate/event.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'time'
|
|
5
|
+
require 'json' # Needed for serialization examples/potential
|
|
6
|
+
require 'securerandom' # Required for SecureRandom
|
|
7
|
+
|
|
8
|
+
module Legate
|
|
9
|
+
# Represents a single interaction or step within a Session's history.
|
|
10
|
+
# Immutable object after creation.
|
|
11
|
+
#
|
|
12
|
+
# @!attribute [r] role
|
|
13
|
+
# @return [Symbol] The origin of the event (:user, :agent, :tool_request, :tool_result).
|
|
14
|
+
# @!attribute [r] content
|
|
15
|
+
# @return [String, Hash] The payload of the event (e.g., user text, agent text, tool params, tool result hash).
|
|
16
|
+
# @!attribute [r] timestamp
|
|
17
|
+
# @return [Time] The UTC time the event occurred.
|
|
18
|
+
# @!attribute [r] tool_name
|
|
19
|
+
# @return [Symbol, nil] The name of the tool involved (for :tool_request, :tool_result roles).
|
|
20
|
+
# @!attribute [r] state_delta
|
|
21
|
+
# @return [Hash, nil] Optional hash representing state changes associated with this event. Keys should be symbols.
|
|
22
|
+
# @!attribute [r] event_id
|
|
23
|
+
# @return [String] A unique ID for this specific event instance.
|
|
24
|
+
Event = Struct.new(:role, :content, :timestamp, :tool_name, :state_delta, :event_id, keyword_init: true) do
|
|
25
|
+
# @param role [Symbol] :user, :agent, :tool_request, :tool_result
|
|
26
|
+
# @param content [String, Hash] Event payload. Should be JSON-serializable.
|
|
27
|
+
# @param timestamp [Time, nil] Timestamp (defaults to Time.now.utc).
|
|
28
|
+
# @param tool_name [Symbol, nil] Name of the tool if role is tool related.
|
|
29
|
+
# @param state_delta [Hash, nil] State changes to apply with this event.
|
|
30
|
+
# @param event_id [String, nil] Unique event ID (defaults to SecureRandom.uuid).
|
|
31
|
+
def initialize(role:, content:, timestamp: nil, tool_name: nil, state_delta: nil, event_id: nil)
|
|
32
|
+
# Basic validation
|
|
33
|
+
raise ArgumentError, "Invalid role: #{role}. Must be :user, :agent, :tool_request, or :tool_result." unless %i[user agent tool_request tool_result].include?(role)
|
|
34
|
+
|
|
35
|
+
Legate.logger.warn("Event: :#{role} event created without a valid :tool_name symbol.") if %i[tool_request tool_result].include?(role) && (tool_name.nil? || !tool_name.is_a?(Symbol))
|
|
36
|
+
|
|
37
|
+
# Validate state_delta is a Hash or nil
|
|
38
|
+
unless state_delta.nil? || state_delta.is_a?(Hash)
|
|
39
|
+
Legate.logger.warn("Event: :state_delta must be a Hash or nil, received #{state_delta.class}.")
|
|
40
|
+
state_delta = nil # Force to nil if invalid
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Ensure content is somewhat reasonable (avoids deep inspection for performance)
|
|
44
|
+
Legate.logger.warn("Event: Content is of unusual type (#{content.class}): #{content.inspect}") unless content.is_a?(String) || content.is_a?(Hash) || content.is_a?(Array) || content.is_a?(NilClass) || content.is_a?(Numeric) || content.is_a?(TrueClass) || content.is_a?(FalseClass)
|
|
45
|
+
|
|
46
|
+
super(
|
|
47
|
+
role: role,
|
|
48
|
+
content: deep_freeze(content),
|
|
49
|
+
timestamp: timestamp || Time.now.utc,
|
|
50
|
+
tool_name: tool_name,
|
|
51
|
+
state_delta: deep_freeze(state_delta&.transform_keys(&:to_sym)),
|
|
52
|
+
event_id: event_id || SecureRandom.uuid
|
|
53
|
+
)
|
|
54
|
+
freeze
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def deep_freeze(obj)
|
|
60
|
+
case obj
|
|
61
|
+
when Hash
|
|
62
|
+
obj.each_value { |v| deep_freeze(v) }
|
|
63
|
+
obj.freeze
|
|
64
|
+
when Array
|
|
65
|
+
obj.each { |v| deep_freeze(v) }
|
|
66
|
+
obj.freeze
|
|
67
|
+
when String
|
|
68
|
+
obj.freeze
|
|
69
|
+
else
|
|
70
|
+
obj
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
public
|
|
75
|
+
|
|
76
|
+
# Helper to check if the event represents a final agent response to the user.
|
|
77
|
+
# @return [Boolean]
|
|
78
|
+
def final_agent_response?
|
|
79
|
+
role == :agent
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# --- Result accessors ---
|
|
83
|
+
# Convenience readers over the standard { status:, result: / error_message: }
|
|
84
|
+
# content hash, so callers don't reach into it. Meaningful on a final agent
|
|
85
|
+
# event (e.g. the return of Agent#ask / #run_task); harmless elsewhere.
|
|
86
|
+
|
|
87
|
+
# @return [Boolean] true if this carries a successful result
|
|
88
|
+
def success?
|
|
89
|
+
content.is_a?(Hash) && content[:status] == :success
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @return [Boolean] true if this carries an error result
|
|
93
|
+
def error?
|
|
94
|
+
content.is_a?(Hash) && content[:status] == :error
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# The successful result value (nil on error). Non-Hash content is returned
|
|
98
|
+
# as-is (e.g. a scalar result stored directly).
|
|
99
|
+
# @return [Object, nil]
|
|
100
|
+
def answer
|
|
101
|
+
content.is_a?(Hash) ? content[:result] : content
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @return [String, nil] the error message, or nil when not an error
|
|
105
|
+
def error_message
|
|
106
|
+
content.is_a?(Hash) ? content[:error_message] : nil
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Basic serialization for storage (e.g., in Redis).
|
|
110
|
+
# @return [Hash] A hash representation suitable for JSON conversion.
|
|
111
|
+
def to_h
|
|
112
|
+
{
|
|
113
|
+
role: role,
|
|
114
|
+
content: content, # Assumes content is already JSON-serializable
|
|
115
|
+
timestamp: timestamp.iso8601(3), # Use ISO8601 format with milliseconds
|
|
116
|
+
tool_name: tool_name,
|
|
117
|
+
state_delta: state_delta, # Store the hash directly (must be JSON-serializable)
|
|
118
|
+
event_id: event_id
|
|
119
|
+
}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Basic deserialization from a hash (e.g., after reading from JSON).
|
|
123
|
+
# @param hash [Hash] The hash containing event data (uses symbolized keys).
|
|
124
|
+
# @return [Legate::Event] A new Event object.
|
|
125
|
+
def self.from_h(hash)
|
|
126
|
+
# Optimized: Extract fields manually to avoid full hash allocation via transform_keys
|
|
127
|
+
role = hash.key?(:role) ? hash[:role] : hash['role']
|
|
128
|
+
content = hash.key?(:content) ? hash[:content] : hash['content']
|
|
129
|
+
ts_val = hash.key?(:timestamp) ? hash[:timestamp] : hash['timestamp']
|
|
130
|
+
tool_name = hash.key?(:tool_name) ? hash[:tool_name] : hash['tool_name']
|
|
131
|
+
state_delta = hash.key?(:state_delta) ? hash[:state_delta] : hash['state_delta']
|
|
132
|
+
|
|
133
|
+
# Validate state_delta type to preserve strict behavior (fail on invalid type)
|
|
134
|
+
if state_delta && !state_delta.is_a?(Hash)
|
|
135
|
+
Legate.logger.error("Event.from_h: Type error during deserialization (check state_delta?): state_delta must be a Hash. Hash: #{hash.inspect}")
|
|
136
|
+
return nil
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
event_id = hash.key?(:event_id) ? hash[:event_id] : hash['event_id']
|
|
140
|
+
|
|
141
|
+
new(
|
|
142
|
+
role: role&.to_sym,
|
|
143
|
+
content: content,
|
|
144
|
+
# Safely parse timestamp
|
|
145
|
+
timestamp: ts_val ? Time.iso8601(ts_val) : Time.now.utc,
|
|
146
|
+
tool_name: tool_name&.to_sym,
|
|
147
|
+
# Pass state_delta directly; initialize handles validation and symbolization/copy
|
|
148
|
+
state_delta: state_delta,
|
|
149
|
+
event_id: event_id
|
|
150
|
+
)
|
|
151
|
+
rescue ArgumentError => e
|
|
152
|
+
Legate.logger.error("Event.from_h: Failed to parse timestamp or invalid role: #{e.message}. Hash: #{hash.inspect}")
|
|
153
|
+
# Decide on fallback: return nil, raise, or return partial object?
|
|
154
|
+
# Returning nil might be safest to signal deserialization failure.
|
|
155
|
+
nil
|
|
156
|
+
rescue TypeError, NoMethodError => e # Also rescue NoMethodError
|
|
157
|
+
Legate.logger.error("Event.from_h: Type error during deserialization (check state_delta?): #{e.message}. Hash: #{hash.inspect}")
|
|
158
|
+
nil
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Monkey patch for the gemini-ai gem to use the v1beta API endpoint, which
|
|
4
|
+
# exposes newer models. It reaches into gemini-ai's private @service /
|
|
5
|
+
# @service_version / @base_address ivars, so it is written defensively: if a
|
|
6
|
+
# future gemini-ai release renames those internals, the patch degrades to a
|
|
7
|
+
# logged warning instead of crashing planning at require time. gemini-ai is
|
|
8
|
+
# pinned (~> 4.2.0) to keep this stable.
|
|
9
|
+
|
|
10
|
+
require 'gemini-ai'
|
|
11
|
+
|
|
12
|
+
if defined?(Gemini::Controllers::Client)
|
|
13
|
+
module Gemini
|
|
14
|
+
module Controllers
|
|
15
|
+
class Client
|
|
16
|
+
# Store the original initialize method
|
|
17
|
+
alias original_initialize initialize
|
|
18
|
+
|
|
19
|
+
def initialize(config)
|
|
20
|
+
original_initialize(config)
|
|
21
|
+
|
|
22
|
+
# Force v1beta when talking to the generative-language API. Guard the
|
|
23
|
+
# ivar pokes so a gemini-ai internals change can't break construction.
|
|
24
|
+
return unless instance_variable_defined?(:@service) && @service == 'generative-language-api'
|
|
25
|
+
|
|
26
|
+
@service_version = 'v1beta'
|
|
27
|
+
@base_address = "https://generativelanguage.googleapis.com/#{@service_version}"
|
|
28
|
+
Legate.logger&.debug('Gemini AI Client patched to use v1beta API endpoint') if defined?(Legate)
|
|
29
|
+
rescue StandardError => e
|
|
30
|
+
Legate.logger&.warn("Gemini v1beta patch could not apply (gemini-ai internals may have changed): #{e.message}") if defined?(Legate)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
Legate.logger&.debug('Gemini AI Beta patch loaded - API will use v1beta endpoint') if defined?(Legate) && Legate.respond_to?(:logger)
|
|
37
|
+
elsif defined?(Legate)
|
|
38
|
+
Legate.logger&.warn('Gemini::Controllers::Client not found; skipping v1beta patch (gemini-ai may have changed).')
|
|
39
|
+
end
|