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,323 @@
|
|
|
1
|
+
# File: lib/legate/web/routes/agent_runtime_routes.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Legate
|
|
5
|
+
module Web
|
|
6
|
+
module AgentRuntimeRoutes
|
|
7
|
+
def self.registered(app)
|
|
8
|
+
# POST /agents/:name/start/detail - Start a runtime instance (from agent detail view).
|
|
9
|
+
app.post '/agents/:name/start/detail' do |name|
|
|
10
|
+
content_type :html
|
|
11
|
+
agent_instance = send(:_start_agent, name) # Renamed to avoid confusion
|
|
12
|
+
|
|
13
|
+
is_running = !agent_instance.nil?
|
|
14
|
+
agent_data_for_view = nil
|
|
15
|
+
definition_store = instance_variable_get(:@definition_store)
|
|
16
|
+
|
|
17
|
+
if agent_instance # Agent started successfully
|
|
18
|
+
# Ensure agent_data_for_view is a Hash, similar to the else block
|
|
19
|
+
definition = definition_store&.get_definition(name) # Re-fetch definition for consistency
|
|
20
|
+
agent_data_for_view = if definition
|
|
21
|
+
{
|
|
22
|
+
name: name,
|
|
23
|
+
description: definition[:description],
|
|
24
|
+
running: is_running,
|
|
25
|
+
model: definition[:model],
|
|
26
|
+
tool_count: definition[:tools]&.size || 0
|
|
27
|
+
}
|
|
28
|
+
else # Should not happen if agent started, but as a fallback
|
|
29
|
+
{ name: name, description: 'Started (Def error)', running: is_running,
|
|
30
|
+
model: 'N/A', tool_count: 0 }
|
|
31
|
+
end
|
|
32
|
+
elsif definition_store # Agent failed to start, fetch definition for display
|
|
33
|
+
begin
|
|
34
|
+
definition = definition_store.get_definition(name)
|
|
35
|
+
agent_data_for_view = if definition
|
|
36
|
+
{
|
|
37
|
+
name: name, description: definition[:description],
|
|
38
|
+
running: false, model: definition[:model],
|
|
39
|
+
tool_count: definition[:tools]&.size || 0
|
|
40
|
+
}
|
|
41
|
+
else
|
|
42
|
+
{ name: name, description: 'Error: Definition not found', running: false,
|
|
43
|
+
model: 'N/A', tool_count: 0 }
|
|
44
|
+
end
|
|
45
|
+
rescue Legate::DefinitionStore::StoreError => e
|
|
46
|
+
logger.error("Store error fetching definition after failed start for '#{name}' (from AgentRuntimeRoutes): #{e.message}")
|
|
47
|
+
agent_data_for_view = { name: name, description: 'Error retrieving definition', running: false,
|
|
48
|
+
model: 'N/A', tool_count: 0 }
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
agent_data_for_view = { name: name, description: 'Error: Store unavailable', running: false,
|
|
52
|
+
model: 'N/A', tool_count: 0 }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# agent_data_for_view is now consistently a Hash
|
|
56
|
+
# ... rest of the route uses agent_data_for_view[:running] ...
|
|
57
|
+
|
|
58
|
+
status_controls_html = slim(:_agent_status_controls, layout: false,
|
|
59
|
+
locals: { agent_data: agent_data_for_view })
|
|
60
|
+
|
|
61
|
+
execute_button_text = is_running ? 'Execute' : 'Execute (Requires Start)'
|
|
62
|
+
disabled_attr_string = is_running ? '' : 'disabled'
|
|
63
|
+
execute_button_oob_html = %(
|
|
64
|
+
<button class="button is-primary" id="execute-task-button" type="submit" #{disabled_attr_string} hx-swap-oob="outerHTML">
|
|
65
|
+
<span class="icon is-small"><i class="fas fa-play-circle"></i></span>
|
|
66
|
+
<span>#{execute_button_text}</span>
|
|
67
|
+
</button>
|
|
68
|
+
)
|
|
69
|
+
chat_input_oob_html = %(<input class="input" id="chat-input" type="text" name="message" placeholder="Enter your message..." required="true" autofocus #{disabled_attr_string} hx-swap-oob="outerHTML">)
|
|
70
|
+
chat_button_oob_html = %(<button class="button is-link" id="send-button" type="submit" #{disabled_attr_string} hx-swap-oob="outerHTML"><span>Send</span><span class="icon is-small htmx-indicator ml-2" id="send-button-indicator"><i class="fas fa-spinner fa-pulse"></i></span></button>)
|
|
71
|
+
|
|
72
|
+
# --- MODIFIED: Determine content for chat-status-help-container ---
|
|
73
|
+
new_chat_status_help_content = ''
|
|
74
|
+
if is_running # is_running reflects the new state of the agent
|
|
75
|
+
# Agent is running, attempt to ensure an active session for the help text
|
|
76
|
+
web_user_id = session[:web_user_id]
|
|
77
|
+
session_service = instance_variable_get(:@session_service)
|
|
78
|
+
active_session_object_for_help_check = nil
|
|
79
|
+
|
|
80
|
+
if web_user_id && session_service
|
|
81
|
+
# 1. Try to load session from Sinatra session store
|
|
82
|
+
stored_active_session_id = session.dig(:active_agent_sessions, name)
|
|
83
|
+
if stored_active_session_id
|
|
84
|
+
begin
|
|
85
|
+
potential_session = session_service.get_session(session_id: stored_active_session_id)
|
|
86
|
+
if potential_session && potential_session.user_id == web_user_id && potential_session.app_name == name
|
|
87
|
+
active_session_object_for_help_check = potential_session
|
|
88
|
+
logger.debug "OOB Chat Help (Start): Found valid session '#{stored_active_session_id}' from Sinatra session for agent '#{name}'."
|
|
89
|
+
else
|
|
90
|
+
logger.warn "OOB Chat Help (Start): Stored session ID '#{stored_active_session_id}' invalid/mismatched for agent '#{name}'. Clearing from Sinatra session."
|
|
91
|
+
session[:active_agent_sessions]&.delete(name)
|
|
92
|
+
end
|
|
93
|
+
rescue StandardError => e
|
|
94
|
+
logger.error("OOB Chat Help (Start): Error fetching stored session '#{stored_active_session_id}' for agent '#{name}': #{e.message}")
|
|
95
|
+
session[:active_agent_sessions]&.delete(name) # Clear if error
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# 2. If no valid session from Sinatra store, try to find latest or create new
|
|
100
|
+
unless active_session_object_for_help_check
|
|
101
|
+
logger.debug "OOB Chat Help (Start): No valid session from Sinatra store. Attempting to find/create for agent '#{name}', user '#{web_user_id}'."
|
|
102
|
+
begin
|
|
103
|
+
user_agent_sessions = session_service.list_sessions(app_name: name, user_id: web_user_id)
|
|
104
|
+
if user_agent_sessions && !user_agent_sessions.empty?
|
|
105
|
+
latest_session = user_agent_sessions.sort_by(&:updated_at).last
|
|
106
|
+
if latest_session
|
|
107
|
+
active_session_object_for_help_check = latest_session
|
|
108
|
+
logger.info "OOB Chat Help (Start): Found latest existing session '#{latest_session.id}' for agent '#{name}'."
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
unless active_session_object_for_help_check
|
|
113
|
+
new_session = session_service.create_session(app_name: name, user_id: web_user_id,
|
|
114
|
+
initial_state: {})
|
|
115
|
+
active_session_object_for_help_check = new_session
|
|
116
|
+
logger.info "OOB Chat Help (Start): Created new session '#{new_session.id}' for agent '#{name}'."
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Store the found/created session ID in Sinatra session
|
|
120
|
+
if active_session_object_for_help_check
|
|
121
|
+
session[:active_agent_sessions] ||= {}
|
|
122
|
+
session[:active_agent_sessions][name] = active_session_object_for_help_check.id
|
|
123
|
+
logger.debug "OOB Chat Help (Start): Stored session '#{active_session_object_for_help_check.id}' in Sinatra session for agent '#{name}'."
|
|
124
|
+
end
|
|
125
|
+
rescue StandardError => e
|
|
126
|
+
logger.error "OOB Chat Help (Start): Critical error finding/creating session for agent '#{name}', user '#{web_user_id}': #{e.message}"
|
|
127
|
+
# If session creation fails, active_session_object_for_help_check will remain nil
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
else
|
|
131
|
+
logger.error "OOB Chat Help (Start): web_user_id or session_service not available. Cannot manage session for help text for agent '#{name}'."
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Final determination of help content based on whether an active session is now established
|
|
135
|
+
new_chat_status_help_content = if active_session_object_for_help_check
|
|
136
|
+
%(<p class="help is-hidden">No issues.</p>)
|
|
137
|
+
else
|
|
138
|
+
# This branch means session_service might be down, or a user_id is missing, or find/create failed critically.
|
|
139
|
+
%(<p id="chat-no-active-session-help" class="help is-warning">Chat session not active. Please try starting a new chat or reloading the page.</p>)
|
|
140
|
+
end
|
|
141
|
+
else
|
|
142
|
+
# Agent is not running
|
|
143
|
+
new_chat_status_help_content = %(<p id="chat-not-running-help" class="help is-danger">Agent must be running to chat.</p>)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
chat_help_oob_html = %(<div id="chat-status-help-container" hx-swap-oob="innerHTML" class="mt-2">#{new_chat_status_help_content}</div>)
|
|
147
|
+
# --- END MODIFICATION ---
|
|
148
|
+
|
|
149
|
+
chat_panel_status_html = %(
|
|
150
|
+
<div id="agent-chat-panel-status-display" hx-swap-oob="innerHTML">
|
|
151
|
+
<p>
|
|
152
|
+
<strong>Status:</strong>
|
|
153
|
+
<span class="tag ml-2 #{agent_data_for_view[:running] ? 'is-success' : 'is-danger'}">
|
|
154
|
+
#{agent_data_for_view[:running] ? 'Running' : 'Stopped (Go to agent page to start)'}
|
|
155
|
+
</span>
|
|
156
|
+
</p>
|
|
157
|
+
</div>
|
|
158
|
+
)
|
|
159
|
+
status 200
|
|
160
|
+
status_controls_html + execute_button_oob_html + chat_input_oob_html + chat_button_oob_html + chat_help_oob_html + chat_panel_status_html
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# POST /agents/:name/stop/detail - Stop a runtime instance (from agent detail view).
|
|
164
|
+
app.post '/agents/:name/stop/detail' do |name|
|
|
165
|
+
content_type :html
|
|
166
|
+
send(:_stop_agent, name) # Call private helper
|
|
167
|
+
|
|
168
|
+
# Explicitly set status variables after stopping
|
|
169
|
+
is_running = false
|
|
170
|
+
disabled_attr_string = 'disabled'
|
|
171
|
+
execute_button_text = 'Execute (Requires Start)'
|
|
172
|
+
# Ensure agent_data_for_view reflects running: false (already done in previous step)
|
|
173
|
+
|
|
174
|
+
agent_data_for_view = nil
|
|
175
|
+
definition_store = instance_variable_get(:@definition_store)
|
|
176
|
+
if definition_store
|
|
177
|
+
begin
|
|
178
|
+
agent_definition = definition_store.get_definition(name)
|
|
179
|
+
agent_data_for_view = if agent_definition
|
|
180
|
+
{
|
|
181
|
+
name: name, description: agent_definition[:description],
|
|
182
|
+
running: is_running, # Use the explicitly set 'is_running'
|
|
183
|
+
model: agent_definition[:model],
|
|
184
|
+
tool_count: agent_definition[:tools]&.size || 0
|
|
185
|
+
}
|
|
186
|
+
else
|
|
187
|
+
{ name: name, description: 'Error: Definition not found', running: is_running,
|
|
188
|
+
model: 'N/A', tool_count: 0 }
|
|
189
|
+
end
|
|
190
|
+
rescue Legate::DefinitionStore::StoreError => e
|
|
191
|
+
logger.error("Store error fetching definition after stop detail for '#{name}' (from AgentRuntimeRoutes): #{e.message}")
|
|
192
|
+
agent_data_for_view = { name: name, description: 'Error retrieving definition', running: is_running,
|
|
193
|
+
model: 'N/A', tool_count: 0 }
|
|
194
|
+
end
|
|
195
|
+
else
|
|
196
|
+
agent_data_for_view = { name: name, description: 'Error: Store unavailable', running: is_running,
|
|
197
|
+
model: 'N/A', tool_count: 0 }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
status_controls_html = slim(:_agent_status_controls, layout: false,
|
|
201
|
+
locals: { agent_data: agent_data_for_view })
|
|
202
|
+
|
|
203
|
+
execute_button_oob_html = %(<button class="button is-link" id="execute-task-button" type="submit" #{disabled_attr_string} hx-swap-oob="outerHTML"> <span class="icon is-small htmx-indicator mr-1"><i class="fas fa-spinner fa-pulse"></i></span> <span class="icon is-small"><i class="fas fa-play-circle"></i></span> <span>#{execute_button_text}</span> </button>)
|
|
204
|
+
chat_input_oob_html = %(<input class="input" id="chat-input" type="text" name="message" placeholder="Enter your message..." required="true" autofocus #{disabled_attr_string} hx-swap-oob="outerHTML">)
|
|
205
|
+
chat_button_oob_html = %(<button class="button is-link" id="send-button" type="submit" #{disabled_attr_string} hx-swap-oob="outerHTML"><span>Send</span><span class="icon is-small htmx-indicator ml-2" id="send-button-indicator"><i class="fas fa-spinner fa-pulse"></i></span></button>)
|
|
206
|
+
|
|
207
|
+
# --- MODIFIED: Determine content for chat-status-help-container ---
|
|
208
|
+
# is_running is false in this context (agent stop)
|
|
209
|
+
new_chat_status_help_content = ''
|
|
210
|
+
if is_running # This will be false
|
|
211
|
+
# This block should ideally not be reached if is_running is false,
|
|
212
|
+
# but keeping structure for clarity, will be optimized by the 'else'.
|
|
213
|
+
web_user_id = session[:web_user_id]
|
|
214
|
+
session_service = instance_variable_get(:@session_service)
|
|
215
|
+
active_session_details = nil
|
|
216
|
+
# 'name' is the agent_name from the route parameter
|
|
217
|
+
|
|
218
|
+
if web_user_id && session_service
|
|
219
|
+
active_session_id = session.dig(:active_agent_sessions, name)
|
|
220
|
+
if active_session_id
|
|
221
|
+
begin
|
|
222
|
+
potential_session = session_service.get_session(session_id: active_session_id)
|
|
223
|
+
active_session_details = potential_session if potential_session && potential_session.user_id == web_user_id && potential_session.app_name == name
|
|
224
|
+
rescue StandardError => e
|
|
225
|
+
logger.error("OOB Chat Help (Stop - Running Path, Unexpected): Error fetching session #{active_session_id} for agent #{name}: #{e.message}")
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
new_chat_status_help_content = if active_session_details
|
|
231
|
+
%(<p class="help is-hidden">No issues.</p>)
|
|
232
|
+
else
|
|
233
|
+
%(<p id="chat-no-active-session-help" class="help is-warning">No active chat session. Please start a new chat from the sidebar.</p>)
|
|
234
|
+
end
|
|
235
|
+
else
|
|
236
|
+
# Agent is not running (this is the expected path for agent stop)
|
|
237
|
+
new_chat_status_help_content = %(<p id="chat-not-running-help" class="help is-danger">Agent must be running to chat.</p>)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
chat_help_oob_html = %(<div id="chat-status-help-container" hx-swap-oob="innerHTML" class="mt-2">#{new_chat_status_help_content}</div>)
|
|
241
|
+
# --- END MODIFICATION ---
|
|
242
|
+
|
|
243
|
+
chat_panel_status_html = %(
|
|
244
|
+
<div id="agent-chat-panel-status-display" hx-swap-oob="innerHTML">
|
|
245
|
+
<p>
|
|
246
|
+
<strong>Status:</strong>
|
|
247
|
+
<span class="tag ml-2 #{agent_data_for_view[:running] ? 'is-success' : 'is-danger'}">
|
|
248
|
+
#{agent_data_for_view[:running] ? 'Running' : 'Stopped (Go to agent page to start)'}
|
|
249
|
+
</span>
|
|
250
|
+
</p>
|
|
251
|
+
</div>
|
|
252
|
+
)
|
|
253
|
+
status 200
|
|
254
|
+
status_controls_html + execute_button_oob_html + chat_input_oob_html + chat_button_oob_html + chat_help_oob_html + chat_panel_status_html
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Start agent from main list view (hx-post from _agent_card.slim)
|
|
258
|
+
app.post '/agents/:name/start' do |name|
|
|
259
|
+
agent = send(:_start_agent, name)
|
|
260
|
+
definition_store = instance_variable_get(:@definition_store)
|
|
261
|
+
tool_manager = instance_variable_get(:@tool_manager)
|
|
262
|
+
available_tools = tool_manager&.tools&.map { |t| { name: t.name, description: t.description } } || []
|
|
263
|
+
|
|
264
|
+
# Re-fetch definition for display
|
|
265
|
+
agent_definition = definition_store&.get_definition(name) if definition_store
|
|
266
|
+
active_agents_hash = instance_variable_get(:@agents)
|
|
267
|
+
|
|
268
|
+
agent_data = if agent_definition
|
|
269
|
+
agent_definition.dup
|
|
270
|
+
else
|
|
271
|
+
{ name: name, description: 'N/A', model: 'N/A', tools: [], configured_tools: [] }
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
agent_data[:configured_tools] ||= agent_data[:tools] || []
|
|
275
|
+
# Running state is determined by in-memory @agents hash
|
|
276
|
+
agent_data[:running] = active_agents_hash.key?(name)
|
|
277
|
+
|
|
278
|
+
if agent
|
|
279
|
+
logger.info "Agent '#{name}' started from main list (from AgentRuntimeRoutes)."
|
|
280
|
+
else
|
|
281
|
+
logger.error "Failed to start agent '#{name}' from main list (from AgentRuntimeRoutes)."
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
status 200
|
|
285
|
+
content_type :html
|
|
286
|
+
slim :_agent_card, layout: false, locals: { agent_info: agent_data, available_tools: available_tools }
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Stop agent from main list view (hx-post from _agent_card.slim)
|
|
290
|
+
app.post '/agents/:name/stop' do |name|
|
|
291
|
+
success = send(:_stop_agent, name)
|
|
292
|
+
definition_store = instance_variable_get(:@definition_store)
|
|
293
|
+
tool_manager = instance_variable_get(:@tool_manager)
|
|
294
|
+
available_tools = tool_manager&.tools&.map { |t| { name: t.name, description: t.description } } || []
|
|
295
|
+
|
|
296
|
+
# Re-fetch definition for display
|
|
297
|
+
agent_definition = definition_store&.get_definition(name) if definition_store
|
|
298
|
+
active_agents_hash = instance_variable_get(:@agents)
|
|
299
|
+
|
|
300
|
+
agent_data = if agent_definition
|
|
301
|
+
agent_definition.dup
|
|
302
|
+
else
|
|
303
|
+
{ name: name, description: 'N/A', model: 'N/A', tools: [], configured_tools: [] }
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
agent_data[:configured_tools] ||= agent_data[:tools] || []
|
|
307
|
+
# Running state is determined by in-memory @agents hash
|
|
308
|
+
agent_data[:running] = active_agents_hash.key?(name)
|
|
309
|
+
|
|
310
|
+
if success
|
|
311
|
+
logger.info "Agent '#{name}' stopped from main list (from AgentRuntimeRoutes)."
|
|
312
|
+
else
|
|
313
|
+
logger.error "Failed to stop agent '#{name}' from main list (from AgentRuntimeRoutes)."
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
status 200
|
|
317
|
+
content_type :html
|
|
318
|
+
slim :_agent_card, layout: false, locals: { agent_info: agent_data, available_tools: available_tools }
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# File: lib/legate/web/routes/api_routes.rb
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Legate
|
|
5
|
+
module Web
|
|
6
|
+
module ApiRoutes
|
|
7
|
+
def self.registered(app)
|
|
8
|
+
# GET /api/agents - List all defined agents and their status.
|
|
9
|
+
app.get '/api/agents' do
|
|
10
|
+
content_type :json
|
|
11
|
+
agents_data = []
|
|
12
|
+
current_app_instance = self # Get current app instance
|
|
13
|
+
definition_store = current_app_instance.instance_variable_get(:@definition_store)
|
|
14
|
+
active_agents_hash = current_app_instance.instance_variable_get(:@agents)
|
|
15
|
+
|
|
16
|
+
if definition_store
|
|
17
|
+
begin
|
|
18
|
+
agent_summaries = definition_store.list_definitions
|
|
19
|
+
agents_data = agent_summaries.map do |summary|
|
|
20
|
+
agent_name = summary[:name]
|
|
21
|
+
# @agents is keyed by the agent's STRING name; summary[:name] is a Symbol.
|
|
22
|
+
running_key = agent_name.to_s
|
|
23
|
+
is_running = active_agents_hash.key?(running_key)
|
|
24
|
+
current_model = if is_running && active_agents_hash[running_key]
|
|
25
|
+
active_agents_hash[running_key].model_name
|
|
26
|
+
else
|
|
27
|
+
summary[:model]
|
|
28
|
+
end
|
|
29
|
+
{
|
|
30
|
+
name: agent_name,
|
|
31
|
+
description: summary[:description] || 'N/A',
|
|
32
|
+
running: is_running,
|
|
33
|
+
model: current_model
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
rescue Legate::DefinitionStore::StoreError => e
|
|
37
|
+
logger.error("Store error fetching agent list for API (from ApiRoutes): #{e.message}")
|
|
38
|
+
agents_data = []
|
|
39
|
+
end
|
|
40
|
+
else
|
|
41
|
+
logger.error('Definition Store unavailable during GET /api/agents (from ApiRoutes)')
|
|
42
|
+
end
|
|
43
|
+
json agents: agents_data.sort_by { |a| a[:name] }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# GET /api/tools - List all available *native* tools known to the GlobalToolManager.
|
|
47
|
+
# Does not include MCP tools.
|
|
48
|
+
# Returns JSON: `{"tools": [{"name": ..., "description": ..., "parameters": [...]}, ...]}`
|
|
49
|
+
app.get '/api/tools' do
|
|
50
|
+
content_type :json
|
|
51
|
+
json tools: Legate::GlobalToolManager.list_all_tools
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|