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,350 @@
|
|
|
1
|
+
# File: lib/legate/tool_context.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Legate
|
|
5
|
+
# Provides contextual information to Legate::Tool#perform_execution
|
|
6
|
+
# Includes session details and a reference to the agent's tool registry.
|
|
7
|
+
# Read-only.
|
|
8
|
+
class ToolContext
|
|
9
|
+
attr_reader :session_id, :user_id, :app_name, :tool_registry, :session_service, :logger, :invocation_id
|
|
10
|
+
|
|
11
|
+
# Expose pending state delta for inspection but not direct modification
|
|
12
|
+
attr_reader :pending_state_delta
|
|
13
|
+
|
|
14
|
+
# Agent-specific authentication configuration
|
|
15
|
+
# @return [Hash, nil] The agent's auth config or nil if not configured
|
|
16
|
+
attr_reader :agent_auth_config
|
|
17
|
+
|
|
18
|
+
# @param session_id [String] The ID of the current session.
|
|
19
|
+
# @param user_id [String] The user ID associated with the session.
|
|
20
|
+
# @param app_name [String] The application/agent name associated with the session.
|
|
21
|
+
# @param tool_registry [Legate::ToolRegistry] The tool registry instance of the agent executing the tool.
|
|
22
|
+
# @param session_service [Legate::SessionService::Base, nil] The session service instance.
|
|
23
|
+
# @param logger [Logger, nil] The logger instance.
|
|
24
|
+
# @param invocation_id [String, nil] The ID of the current agent invocation.
|
|
25
|
+
# @param agent_auth_config [Hash, nil] Agent-specific authentication configuration.
|
|
26
|
+
def initialize(session_id:, user_id:, app_name:, tool_registry: nil, session_service: nil, logger: Legate.logger, invocation_id: nil, agent_auth_config: nil)
|
|
27
|
+
@session_id = session_id
|
|
28
|
+
@user_id = user_id
|
|
29
|
+
@app_name = app_name
|
|
30
|
+
@tool_registry = tool_registry
|
|
31
|
+
@session_service = session_service
|
|
32
|
+
@invocation_id = invocation_id
|
|
33
|
+
@pending_state_delta = {}
|
|
34
|
+
@token_manager = nil
|
|
35
|
+
@agent_auth_config = agent_auth_config
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Retrieves a value from the session state via the session_service.
|
|
39
|
+
# @param key [Symbol, String] The key to retrieve
|
|
40
|
+
# @return [Object, nil] The value or nil if not found
|
|
41
|
+
def state_get(key)
|
|
42
|
+
unless @session_service
|
|
43
|
+
Legate.logger.warn { '[ToolContext] state_get called but no session_service available.' }
|
|
44
|
+
return nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
Legate.logger.debug { "[ToolContext] state_get for key: #{key} in session: #{@session_id}" }
|
|
48
|
+
@session_service.get_state(session_id: @session_id, key: key)
|
|
49
|
+
rescue StandardError => e
|
|
50
|
+
Legate.logger.error { "[ToolContext] Error in state_get for key '#{key}': #{e.message}" }
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Sets a value in the pending state delta for this context.
|
|
55
|
+
# @param key [Symbol, String] The key to set
|
|
56
|
+
# @param value [Object] The value to store (should be serializable)
|
|
57
|
+
def state_set(key, value)
|
|
58
|
+
Legate.logger.debug { "[ToolContext] state_set for key: #{key} to value: #{value.inspect} (pending)" }
|
|
59
|
+
@pending_state_delta[key.to_sym] = value
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Merges a hash into the pending state delta for this context.
|
|
63
|
+
# @param hash_to_merge [Hash] The hash to merge into the pending state delta
|
|
64
|
+
def state_update(hash_to_merge)
|
|
65
|
+
unless hash_to_merge.is_a?(Hash)
|
|
66
|
+
Legate.logger.warn { "[ToolContext] state_update called with non-hash: #{hash_to_merge.class}" }
|
|
67
|
+
return
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
Legate.logger.debug { "[ToolContext] state_update with hash: #{hash_to_merge.inspect} (pending)" }
|
|
71
|
+
@pending_state_delta.merge!(hash_to_merge.transform_keys(&:to_sym))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Clears any accumulated pending state changes within this context instance.
|
|
75
|
+
def clear_pending_state_delta!
|
|
76
|
+
@pending_state_delta = {}
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Authentication-related methods
|
|
80
|
+
|
|
81
|
+
# Apply authentication to a request using the specified scheme and credential
|
|
82
|
+
# @param request [Hash] The request to authenticate
|
|
83
|
+
# @param scheme [Legate::Auth::Scheme] The authentication scheme to use
|
|
84
|
+
# @param credential [Legate::Auth::Credential] The credential to use
|
|
85
|
+
# @return [Hash] The authenticated request
|
|
86
|
+
def authenticate_request(request, scheme, credential)
|
|
87
|
+
require_relative 'auth/tool_integration'
|
|
88
|
+
|
|
89
|
+
# Try to use token manager if available
|
|
90
|
+
token_manager = get_token_manager
|
|
91
|
+
if token_manager
|
|
92
|
+
# First get the token from token manager
|
|
93
|
+
token = token_manager.get_token(scheme, credential, force_refresh: false)
|
|
94
|
+
|
|
95
|
+
# Then apply authentication
|
|
96
|
+
return Legate::Auth::ToolIntegration.apply_authentication(
|
|
97
|
+
request,
|
|
98
|
+
scheme,
|
|
99
|
+
credential,
|
|
100
|
+
nil,
|
|
101
|
+
token_manager
|
|
102
|
+
)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Fall back to token store if token manager not available
|
|
106
|
+
token_store = get_token_store
|
|
107
|
+
|
|
108
|
+
# Apply authentication
|
|
109
|
+
Legate::Auth::ToolIntegration.apply_authentication(request, scheme, credential, token_store)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Check if a response indicates an authentication error
|
|
113
|
+
# @param response [Hash] The response to check
|
|
114
|
+
# @return [Boolean] True if the response indicates an authentication error
|
|
115
|
+
def authentication_error?(response)
|
|
116
|
+
require_relative 'auth/tool_integration'
|
|
117
|
+
Legate::Auth::ToolIntegration.authentication_error?(response)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Check if a request likely requires authentication
|
|
121
|
+
# @param request [Hash] The request to check
|
|
122
|
+
# @return [Boolean] True if the request likely requires authentication
|
|
123
|
+
def requires_authentication?(request)
|
|
124
|
+
require_relative 'auth/tool_integration'
|
|
125
|
+
Legate::Auth::ToolIntegration.requires_authentication?(request)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Get an authentication token from the session cache
|
|
129
|
+
# @param scheme [Legate::Auth::Scheme] The authentication scheme
|
|
130
|
+
# @param credential [Legate::Auth::Credential] The credential
|
|
131
|
+
# @param force_refresh [Boolean] Whether to force a token refresh
|
|
132
|
+
# @return [Legate::Auth::ExchangedCredential, nil] The token if available
|
|
133
|
+
def get_token(scheme, credential, force_refresh: false)
|
|
134
|
+
# Try to use token manager if available
|
|
135
|
+
token_manager = get_token_manager
|
|
136
|
+
return token_manager.get_token(scheme, credential, force_refresh: force_refresh) if token_manager
|
|
137
|
+
|
|
138
|
+
# Fall back to old mechanism if token manager not available
|
|
139
|
+
token_store = get_token_store
|
|
140
|
+
return nil unless token_store
|
|
141
|
+
|
|
142
|
+
require_relative 'auth/tool_integration'
|
|
143
|
+
cache_key = Legate::Auth::ToolIntegration.generate_cache_key(scheme, credential)
|
|
144
|
+
token_store.get(cache_key)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Refresh an authentication token
|
|
148
|
+
# @param scheme [Legate::Auth::Scheme] The authentication scheme
|
|
149
|
+
# @param credential [Legate::Auth::Credential] The credential
|
|
150
|
+
# @param token [Legate::Auth::ExchangedCredential, nil] The current token, if available
|
|
151
|
+
# @return [Legate::Auth::ExchangedCredential, nil] The refreshed token if successful
|
|
152
|
+
def refresh_token(scheme, credential, token = nil)
|
|
153
|
+
# Try to use token manager if available
|
|
154
|
+
token_manager = get_token_manager
|
|
155
|
+
return token_manager.refresh_token(scheme, credential, token) if token_manager
|
|
156
|
+
|
|
157
|
+
# Fall back to direct refresh if token manager not available
|
|
158
|
+
if token && scheme.supports_refresh? && token.refreshable?
|
|
159
|
+
begin
|
|
160
|
+
refreshed = scheme.refresh_token(token, credential)
|
|
161
|
+
store_token(scheme, credential, refreshed)
|
|
162
|
+
return refreshed
|
|
163
|
+
rescue Legate::Auth::TokenRefreshError => e
|
|
164
|
+
Legate.logger.error("Failed to refresh token: #{e.message}")
|
|
165
|
+
return nil
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
nil
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Store an authentication token in the session cache
|
|
173
|
+
# @param scheme [Legate::Auth::Scheme] The authentication scheme
|
|
174
|
+
# @param credential [Legate::Auth::Credential] The credential
|
|
175
|
+
# @param token [Legate::Auth::ExchangedCredential] The token to cache
|
|
176
|
+
# @return [Boolean] True if the token was stored successfully
|
|
177
|
+
def store_token(scheme, credential, token)
|
|
178
|
+
token_store = get_token_store
|
|
179
|
+
return false unless token_store
|
|
180
|
+
|
|
181
|
+
require_relative 'auth/tool_integration'
|
|
182
|
+
cache_key = Legate::Auth::ToolIntegration.generate_cache_key(scheme, credential)
|
|
183
|
+
token_store.store(cache_key, token)
|
|
184
|
+
true
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Clear a cached authentication token
|
|
188
|
+
# @param scheme [Legate::Auth::Scheme] The authentication scheme
|
|
189
|
+
# @param credential [Legate::Auth::Credential] The credential
|
|
190
|
+
# @return [Boolean] True if the token was cleared successfully
|
|
191
|
+
def clear_token(scheme, credential)
|
|
192
|
+
token_store = get_token_store
|
|
193
|
+
return false unless token_store
|
|
194
|
+
|
|
195
|
+
require_relative 'auth/tool_integration'
|
|
196
|
+
cache_key = Legate::Auth::ToolIntegration.generate_cache_key(scheme, credential)
|
|
197
|
+
token_store.clear(cache_key)
|
|
198
|
+
true
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Revoke a token with the authentication provider
|
|
202
|
+
# @param scheme [Legate::Auth::Scheme] The authentication scheme
|
|
203
|
+
# @param credential [Legate::Auth::Credential] The credential
|
|
204
|
+
# @param token [Legate::Auth::ExchangedCredential] The token to revoke
|
|
205
|
+
# @return [Boolean] True if the token was revoked successfully
|
|
206
|
+
def revoke_token(scheme, credential, token)
|
|
207
|
+
# Try to use token manager if available
|
|
208
|
+
token_manager = get_token_manager
|
|
209
|
+
return token_manager.revoke_token(scheme, credential, token) if token_manager
|
|
210
|
+
|
|
211
|
+
# Fall back to direct revocation if token manager not available
|
|
212
|
+
unless scheme.respond_to?(:revoke_token)
|
|
213
|
+
Legate.logger.warn("Scheme #{scheme.scheme_type} does not support token revocation")
|
|
214
|
+
return false
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
begin
|
|
218
|
+
result = scheme.revoke_token(token, credential)
|
|
219
|
+
clear_token(scheme, credential) if result
|
|
220
|
+
result
|
|
221
|
+
rescue Legate::Auth::Error => e
|
|
222
|
+
Legate.logger.error("Failed to revoke token: #{e.message}")
|
|
223
|
+
false
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Handle authentication for a request, automatically selecting the appropriate scheme and credential
|
|
228
|
+
# Checks agent-specific auth config first, then falls back to global Auth::Manager
|
|
229
|
+
# @param request [Hash] The request to authenticate
|
|
230
|
+
# @param options [Hash] Options for authentication (e.g., credential_name, scheme_type)
|
|
231
|
+
# @return [Hash] The authenticated request or the original request if authentication not possible
|
|
232
|
+
def handle_request_auth(request, options = {})
|
|
233
|
+
# Skip if request doesn't need authentication
|
|
234
|
+
return request unless requires_authentication?(request)
|
|
235
|
+
|
|
236
|
+
require_relative 'auth/manager'
|
|
237
|
+
|
|
238
|
+
begin
|
|
239
|
+
auth_manager = Legate::Auth::Manager.instance
|
|
240
|
+
scheme = nil
|
|
241
|
+
credential = nil
|
|
242
|
+
|
|
243
|
+
# First, check agent-specific URL mappings
|
|
244
|
+
if @agent_auth_config && @agent_auth_config[:url_mappings]&.any?
|
|
245
|
+
scheme, credential = find_agent_auth_for_url(request[:url], auth_manager)
|
|
246
|
+
if scheme && credential
|
|
247
|
+
Legate.logger.debug { "[ToolContext] Using agent-specific auth for URL: #{request[:url]}" }
|
|
248
|
+
return authenticate_request(request, scheme, credential)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Fall back to global Auth::Manager lookup
|
|
253
|
+
scheme, credential = auth_manager.find_scheme_and_credential(
|
|
254
|
+
url: request[:url],
|
|
255
|
+
scheme_type: options[:scheme_type],
|
|
256
|
+
credential_name: options[:credential_name]
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# Apply authentication if found
|
|
260
|
+
return authenticate_request(request, scheme, credential) if scheme && credential
|
|
261
|
+
rescue StandardError => e
|
|
262
|
+
Legate.logger.error("Error in automatic authentication: #{e.message}")
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# Return the original request if no authentication applied
|
|
266
|
+
request
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Find authentication for a URL using agent-specific mappings
|
|
270
|
+
# @param url [String] The URL to find authentication for
|
|
271
|
+
# @param auth_manager [Legate::Auth::Manager] The auth manager to resolve schemes/credentials
|
|
272
|
+
# @return [Array<Legate::Auth::Scheme, Legate::Auth::Credential>, nil] The scheme and credential, or nil if not found
|
|
273
|
+
def find_agent_auth_for_url(url, auth_manager)
|
|
274
|
+
return nil unless @agent_auth_config && @agent_auth_config[:url_mappings]
|
|
275
|
+
|
|
276
|
+
@agent_auth_config[:url_mappings].each do |mapping|
|
|
277
|
+
pattern = mapping[:pattern]
|
|
278
|
+
next unless pattern
|
|
279
|
+
|
|
280
|
+
matched = if pattern.is_a?(Regexp)
|
|
281
|
+
!!(url =~ pattern)
|
|
282
|
+
elsif pattern.is_a?(String)
|
|
283
|
+
if pattern.include?('*')
|
|
284
|
+
# Convert glob pattern to regex
|
|
285
|
+
regex = Regexp.new('^' + Regexp.escape(pattern).gsub('\\*', '.*') + '$')
|
|
286
|
+
!!(url =~ regex)
|
|
287
|
+
else
|
|
288
|
+
url == pattern || url.start_with?(pattern)
|
|
289
|
+
end
|
|
290
|
+
else
|
|
291
|
+
false
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
next unless matched
|
|
295
|
+
|
|
296
|
+
scheme_name = mapping[:scheme_name]
|
|
297
|
+
credential_name = mapping[:credential_name]
|
|
298
|
+
|
|
299
|
+
# Resolve from Auth::Manager
|
|
300
|
+
scheme = auth_manager.get_scheme(scheme_name)
|
|
301
|
+
credential = auth_manager.get_credential(credential_name)
|
|
302
|
+
|
|
303
|
+
return [scheme, credential] if scheme && credential
|
|
304
|
+
|
|
305
|
+
Legate.logger.warn { "[ToolContext] Agent auth mapping matched but scheme '#{scheme_name}' or credential '#{credential_name}' not found in Auth::Manager" }
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
nil
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Create or get the token manager for this context
|
|
312
|
+
# @return [Legate::Auth::TokenManager, nil] The token manager if available
|
|
313
|
+
def get_token_manager
|
|
314
|
+
return @token_manager if @token_manager
|
|
315
|
+
|
|
316
|
+
token_store = get_token_store
|
|
317
|
+
return nil unless token_store
|
|
318
|
+
|
|
319
|
+
require_relative 'auth/token_manager'
|
|
320
|
+
@token_manager = Legate::Auth::TokenManager.new(token_store)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def to_h
|
|
324
|
+
{
|
|
325
|
+
session_id: @session_id,
|
|
326
|
+
user_id: @user_id,
|
|
327
|
+
app_name: @app_name,
|
|
328
|
+
invocation_id: @invocation_id,
|
|
329
|
+
tool_registry_object_id: @tool_registry&.object_id,
|
|
330
|
+
session_service_present: !@session_service.nil?
|
|
331
|
+
}
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
private
|
|
335
|
+
|
|
336
|
+
# Get the token store for caching authentication tokens
|
|
337
|
+
# @return [Legate::Auth::TokenStore, nil] The token store if available
|
|
338
|
+
def get_token_store
|
|
339
|
+
return nil unless @session_service
|
|
340
|
+
|
|
341
|
+
# TokenStore works with any session service that supports save_scoped_state/load_scoped_state
|
|
342
|
+
if @session_service.respond_to?(:save_scoped_state) && @session_service.respond_to?(:load_scoped_state)
|
|
343
|
+
require_relative 'auth/token_store'
|
|
344
|
+
return Legate::Auth::TokenStore.new(@session_service)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
nil
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
module Legate
|
|
6
|
+
# Responsible for discovering and loading tool definition files from the filesystem.
|
|
7
|
+
# This decouples filesystem traversal and file loading from the Agent execution logic.
|
|
8
|
+
module ToolLoader
|
|
9
|
+
# Discovers and loads tool definition files from specified paths.
|
|
10
|
+
# @param paths [Array<String>] An array of directory paths to search.
|
|
11
|
+
# @return [void]
|
|
12
|
+
def self.load_from_paths(paths)
|
|
13
|
+
return if paths.nil? || paths.empty?
|
|
14
|
+
|
|
15
|
+
Legate.logger.debug("Starting tool discovery in paths: #{paths.inspect}")
|
|
16
|
+
|
|
17
|
+
paths.each do |path|
|
|
18
|
+
absolute_dir_path = File.expand_path(path, Dir.pwd)
|
|
19
|
+
|
|
20
|
+
unless Dir.exist?(absolute_dir_path)
|
|
21
|
+
Legate.logger.warn("Tool discovery path does not exist or is not a directory: '#{path}' (resolved to '#{absolute_dir_path}'). Skipping.")
|
|
22
|
+
next
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Dir.glob(File.join(absolute_dir_path, '*.rb')).each do |absolute_file_path|
|
|
26
|
+
Legate.logger.debug("Attempting to load tool file using 'require': #{absolute_file_path}")
|
|
27
|
+
# Use require instead of load to prevent re-registration issues
|
|
28
|
+
require absolute_file_path
|
|
29
|
+
Legate.logger.debug("Successfully required (or already required): #{absolute_file_path}")
|
|
30
|
+
rescue LoadError, SyntaxError => e
|
|
31
|
+
Legate.logger.error("Failed to require/eval tool file '#{absolute_file_path}': #{e.class} - #{e.message}")
|
|
32
|
+
rescue StandardError => e
|
|
33
|
+
Legate.logger.error("Error encountered while requiring/processing tool file '#{absolute_file_path}': #{e.class} - #{e.message}")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
Legate.logger.debug('Finished tool discovery.')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# File: lib/legate/tool_registry.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# require 'logger' # Not needed directly if only using Legate.logger
|
|
5
|
+
|
|
6
|
+
module Legate
|
|
7
|
+
# Manages a collection of tool definitions for a specific agent instance.
|
|
8
|
+
class ToolRegistry
|
|
9
|
+
attr_reader :tools # Make tools readable
|
|
10
|
+
|
|
11
|
+
# Initialize an empty tool registry.
|
|
12
|
+
def initialize
|
|
13
|
+
@tools = {} # Stores { name_symbol => tool_class } for this instance
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Register a tool class with this registry instance.
|
|
17
|
+
# @param name [Symbol] The symbolic name of the tool.
|
|
18
|
+
# @param klass [Class] The tool class (must inherit from Legate::Tool).
|
|
19
|
+
def register(name, klass)
|
|
20
|
+
logger = Legate.logger # Get the central logger instance
|
|
21
|
+
|
|
22
|
+
unless klass < Legate::Tool
|
|
23
|
+
logger.error("ToolRegistry: Attempted to register non-tool class: #{klass.inspect} for name '#{name}'.")
|
|
24
|
+
return false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
name_symbol = name.to_sym # Ensure it's a symbol
|
|
28
|
+
|
|
29
|
+
if @tools.key?(name_symbol)
|
|
30
|
+
# Use the local variable 'logger'
|
|
31
|
+
logger.warn("ToolRegistry: Tool '#{name_symbol}' is already registered in this registry. Overwriting with class #{klass}.")
|
|
32
|
+
else
|
|
33
|
+
# Use the local variable 'logger'
|
|
34
|
+
logger.info("ToolRegistry: Registering tool '#{name_symbol}' with class #{klass} in this registry.")
|
|
35
|
+
end
|
|
36
|
+
@tools[name_symbol] = klass
|
|
37
|
+
true # Indicate success
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Find a tool class by its name symbol within this registry.
|
|
41
|
+
# @param name_symbol [Symbol] The symbolic name of the tool.
|
|
42
|
+
# @return [Class, nil] The tool class or nil if not found.
|
|
43
|
+
def find_class(name_symbol)
|
|
44
|
+
found_class = @tools[name_symbol.to_sym]
|
|
45
|
+
Legate.logger.debug("[ToolRegistry #{@object_id}] find_class(#{name_symbol.inspect}): Found class in @tools: #{found_class.inspect}")
|
|
46
|
+
found_class
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Create an instance of a tool by its name symbol using the class registered here.
|
|
50
|
+
# @param name_symbol [Symbol] The symbolic name of the tool.
|
|
51
|
+
# @return [Legate::Tool, nil] An instance of the tool or nil if instantiation fails or class not found.
|
|
52
|
+
def create_instance(name_symbol)
|
|
53
|
+
klass = find_class(name_symbol)
|
|
54
|
+
Legate.logger.debug("[ToolRegistry #{@object_id}] create_instance(#{name_symbol.inspect}): Found class: #{klass.inspect}")
|
|
55
|
+
klass&.new
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Get the set of registered tool name symbols.
|
|
59
|
+
# @return [Array<Symbol>] The registered tool names.
|
|
60
|
+
def available_tool_names
|
|
61
|
+
@tools.keys
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Get a list of available tools registered in this instance with basic info.
|
|
65
|
+
# @return [Array<Hash>] An array of hashes, each with :name and :description.
|
|
66
|
+
def list_tools
|
|
67
|
+
@tools.values.map do |klass|
|
|
68
|
+
metadata = klass.tool_metadata # Get the full { name:, description:, parameters: } hash
|
|
69
|
+
metadata # Return the full hash
|
|
70
|
+
end.sort_by { |t| t[:name].to_s }
|
|
71
|
+
end
|
|
72
|
+
end # End ToolRegistry class
|
|
73
|
+
end # End Legate module
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# File: lib/legate/tool_result.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Legate
|
|
5
|
+
# A typed, immutable result a tool's #perform_execution may return instead of
|
|
6
|
+
# building the canonical `{ status:, result:/error_message:/job_id: }` hash by
|
|
7
|
+
# hand (R11, additive). Tool#execute normalizes it to that hash, so everything
|
|
8
|
+
# downstream is unchanged — this is purely an authoring convenience.
|
|
9
|
+
#
|
|
10
|
+
# def perform_execution(params, _context)
|
|
11
|
+
# ToolResult.success("Hello, #{params[:name]}!")
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# Pairs with the Event#answer / #success? / #error? accessors.
|
|
15
|
+
ToolResult = Data.define(:status, :result, :error_message, :job_id, :message) do
|
|
16
|
+
# @return [ToolResult] a successful result carrying an optional value
|
|
17
|
+
def self.success(value = nil)
|
|
18
|
+
new(status: :success, result: value, error_message: nil, job_id: nil, message: nil)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [ToolResult] an error result
|
|
22
|
+
def self.error(message)
|
|
23
|
+
new(status: :error, result: nil, error_message: message.to_s, job_id: nil, message: nil)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @return [ToolResult] a pending (async) result referencing a job
|
|
27
|
+
def self.pending(job_id:, message: nil)
|
|
28
|
+
new(status: :pending, result: nil, error_message: nil, job_id: job_id, message: message)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def success?
|
|
32
|
+
status == :success
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def error?
|
|
36
|
+
status == :error
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def pending?
|
|
40
|
+
status == :pending
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The canonical result hash the rest of Legate speaks. Only the keys relevant
|
|
44
|
+
# to the status are included, matching what hand-built tool hashes produce.
|
|
45
|
+
# @return [Hash]
|
|
46
|
+
def to_h
|
|
47
|
+
case status
|
|
48
|
+
when :success
|
|
49
|
+
{ status: :success, result: result }
|
|
50
|
+
when :error
|
|
51
|
+
{ status: :error, error_message: error_message }
|
|
52
|
+
when :pending
|
|
53
|
+
out = { status: :pending, job_id: job_id }
|
|
54
|
+
out[:message] = message unless message.nil?
|
|
55
|
+
out
|
|
56
|
+
else
|
|
57
|
+
{ status: status }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|