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,192 @@
|
|
|
1
|
+
/ File: lib/legate/web/views/chat.slim
|
|
2
|
+
/ Agent chat / run view — 3 zones: header (name·model·status·sessions) ·
|
|
3
|
+
/ transcript + composer · Run Details inspector. HTMX wires preserved.
|
|
4
|
+
- agent_name = @agent_data[:name]
|
|
5
|
+
- is_running = @agent_data[:running]
|
|
6
|
+
- chat_model = (@agent_data[:model] && !@agent_data[:model].to_s.empty?) ? @agent_data[:model] : Legate::Agent::DEFAULT_MODEL
|
|
7
|
+
- configured_tools = @agent_data[:configured_tools] || []
|
|
8
|
+
- sessions_to_list = (@previous_sessions_list || []).reject { |s| @active_session_details && s.id == @active_session_details.id }
|
|
9
|
+
|
|
10
|
+
div#chat_interface_wrapper
|
|
11
|
+
.chat-shell
|
|
12
|
+
.chat-main
|
|
13
|
+
/ --- Header bar ---
|
|
14
|
+
.chat-header
|
|
15
|
+
a.chat-back(href="/agents/#{agent_name}" title="Back to agent")
|
|
16
|
+
span.icon
|
|
17
|
+
i.fas.fa-arrow-left
|
|
18
|
+
.chat-header-titles
|
|
19
|
+
h2.chat-agent-name= agent_name
|
|
20
|
+
span.mono-chip.model-chip(title="Language model")
|
|
21
|
+
span.icon.is-small
|
|
22
|
+
i.fas.fa-microchip
|
|
23
|
+
span= chat_model
|
|
24
|
+
.chat-header-actions
|
|
25
|
+
div#agent-chat-panel-status-display
|
|
26
|
+
p
|
|
27
|
+
span.tag.is-rounded class=(is_running ? 'is-success' : 'is-danger')
|
|
28
|
+
= is_running ? 'Running' : 'Stopped'
|
|
29
|
+
button.chat-new-session-btn#start-new-chat-button(hx-post="/agents/#{agent_name}/chat/session/new" hx-target="#chat_interface_wrapper" hx-indicator="#start-new-chat-button")
|
|
30
|
+
span.icon.is-small
|
|
31
|
+
i.fas.fa-plus
|
|
32
|
+
span New Session
|
|
33
|
+
span.icon.is-small.htmx-indicator
|
|
34
|
+
i.fas.fa-spinner.fa-pulse
|
|
35
|
+
.dropdown.is-right.chat-sessions-dropdown(_="on click toggle .is-active on the closest .dropdown")
|
|
36
|
+
.dropdown-trigger
|
|
37
|
+
button.chat-sessions-btn(type="button" aria-haspopup="true")
|
|
38
|
+
span.icon.is-small
|
|
39
|
+
i.fas.fa-clock-rotate-left
|
|
40
|
+
span Sessions
|
|
41
|
+
span.icon.is-small
|
|
42
|
+
i.fas.fa-angle-down
|
|
43
|
+
.dropdown-menu(role="menu")
|
|
44
|
+
.dropdown-content
|
|
45
|
+
- if @active_session_details
|
|
46
|
+
.chat-session-current
|
|
47
|
+
.chat-session-line
|
|
48
|
+
span.chat-session-tag Current session
|
|
49
|
+
form(hx-delete="/agents/#{agent_name}/chat/session/#{@active_session_details.id}" hx-target="#chat_interface_wrapper" hx-confirm="Delete this chat session? This cannot be undone.")
|
|
50
|
+
button.chat-session-del(type="submit" title="Delete session")
|
|
51
|
+
i.fas.fa-trash-alt
|
|
52
|
+
p.chat-session-summary= summarize_session(@active_session_details)
|
|
53
|
+
- if sessions_to_list.any?
|
|
54
|
+
hr.dropdown-divider
|
|
55
|
+
- sessions_to_list.each do |session_item|
|
|
56
|
+
form.chat-session-switch(hx-post="/agents/#{agent_name}/chat/session/switch" hx-target="#chat_interface_wrapper")
|
|
57
|
+
input type="hidden" name="legate_session_to_switch_to" value="#{session_item.id}"
|
|
58
|
+
button.chat-session-switch-btn(type="submit")
|
|
59
|
+
span.icon.is-small
|
|
60
|
+
i.fas.fa-comment-dots
|
|
61
|
+
span= summarize_session(session_item)
|
|
62
|
+
- elsif !@active_session_details
|
|
63
|
+
p.dropdown-item.has-text-grey No previous sessions.
|
|
64
|
+
|
|
65
|
+
/ Session operation error display (hidden until HTMX swaps an error in)
|
|
66
|
+
div#session-operation-error.notification.is-danger.is-hidden.mb-3
|
|
67
|
+
|
|
68
|
+
/ --- Transcript ---
|
|
69
|
+
#chat-log-container.chat-transcript(
|
|
70
|
+
hx-on::after-swap="this.scrollTop = this.scrollHeight"
|
|
71
|
+
_="init set my scrollTop to my scrollHeight end"
|
|
72
|
+
)
|
|
73
|
+
- if @chat_history_events && !@chat_history_events.empty?
|
|
74
|
+
- @chat_history_events.each do |event|
|
|
75
|
+
- if event.role == :user
|
|
76
|
+
.message.is-link.is-small.mb-2.user-message(id="event-#{event.event_id}")
|
|
77
|
+
.message-header
|
|
78
|
+
p You
|
|
79
|
+
.message-body= event.content
|
|
80
|
+
- elsif event.role == :agent
|
|
81
|
+
- agent_response_content = event.content
|
|
82
|
+
- is_complex_content = (agent_response_content.is_a?(Hash) && agent_response_content.key?(:status)) || (agent_response_content.is_a?(Array) && agent_response_content.first.is_a?(Hash) && agent_response_content.first.key?(:status))
|
|
83
|
+
- msg_class = 'is-light'
|
|
84
|
+
- if is_complex_content
|
|
85
|
+
- status = agent_response_content.is_a?(Array) ? agent_response_content.first[:status] : agent_response_content[:status]
|
|
86
|
+
- case status
|
|
87
|
+
- when :error
|
|
88
|
+
- msg_class = 'is-danger'
|
|
89
|
+
- when :pending
|
|
90
|
+
- msg_class = 'is-warning'
|
|
91
|
+
- else
|
|
92
|
+
- msg_class = 'is-success'
|
|
93
|
+
- else
|
|
94
|
+
- msg_class = 'is-success'
|
|
95
|
+
|
|
96
|
+
.message class="#{msg_class} agent-message is-small mb-4" id="event-#{event.event_id}"
|
|
97
|
+
.message-header
|
|
98
|
+
p Agent (#{@agent_data[:name]})
|
|
99
|
+
- raw_json_content = agent_response_content.to_json rescue "{}"
|
|
100
|
+
- unless raw_json_content.empty? || raw_json_content == "{}"
|
|
101
|
+
button.button.is-light.is-small.ml-auto( onclick="var el = document.getElementById('raw-#{event.event_id}'); el.style.display = (el.style.display == 'none' ? 'block' : 'none');" )
|
|
102
|
+
| Raw JSON
|
|
103
|
+
.message-body
|
|
104
|
+
div style="white-space: pre-wrap; word-break: break-word; margin-bottom: 0.5rem;" = format_historical_agent_content(agent_response_content)
|
|
105
|
+
|
|
106
|
+
- if agent_response_content.is_a?(Hash) && agent_response_content[:plan_details].is_a?(Array) && !agent_response_content[:plan_details].empty?
|
|
107
|
+
details.execution-plan-details
|
|
108
|
+
summary.execution-plan-summary
|
|
109
|
+
| Execution Plan (#{agent_response_content[:plan_details].size} step#{'s' if agent_response_content[:plan_details].size != 1})
|
|
110
|
+
.execution-plan-steps
|
|
111
|
+
- agent_response_content[:plan_details].each_with_index do |step_detail, index|
|
|
112
|
+
.execution-plan-step
|
|
113
|
+
p.step-title Step #{index + 1}: #{step_detail[:tool_name]}
|
|
114
|
+
p.step-params-label Parameters:
|
|
115
|
+
pre.step-params-pre= JSON.pretty_generate(step_detail[:params] || {})
|
|
116
|
+
|
|
117
|
+
- result_status = step_detail.dig(:result, :status)
|
|
118
|
+
- result_class = case result_status when :success then 'has-text-success-dark' when :error then 'has-text-danger-dark' when :pending then 'has-text-warning-dark' else 'has-text-grey' end
|
|
119
|
+
|
|
120
|
+
p class="step-result-label #{result_class}" Result (#{result_status || "unknown"}):
|
|
121
|
+
pre class="step-result-pre #{result_class}"= JSON.pretty_generate(step_detail[:result] || {}) rescue "{}"
|
|
122
|
+
|
|
123
|
+
- raw_json_content = agent_response_content.to_json rescue "{}"
|
|
124
|
+
- unless raw_json_content.empty? || raw_json_content == "{}"
|
|
125
|
+
div.raw-json-container id="raw-#{event.event_id}" style="display: none;"
|
|
126
|
+
pre.raw-json-pre= raw_json_content
|
|
127
|
+
- elsif event.role == :tool_request || event.role == :tool_result
|
|
128
|
+
/ Hidden for a cleaner history; details live in the agent message's execution plan.
|
|
129
|
+
- else
|
|
130
|
+
p.notification.is-warning.is-light Unknown event role: #{event.role}
|
|
131
|
+
- else
|
|
132
|
+
.chat-empty-state
|
|
133
|
+
.chat-empty-emblem
|
|
134
|
+
i.fas.fa-gem
|
|
135
|
+
p.chat-empty-title Start a conversation
|
|
136
|
+
p.chat-empty-hint
|
|
137
|
+
- if is_running
|
|
138
|
+
= "Send a message to #{agent_name} below to begin."
|
|
139
|
+
- else
|
|
140
|
+
| Start the agent from its page to begin chatting.
|
|
141
|
+
|
|
142
|
+
/ --- Composer ---
|
|
143
|
+
.chat-composer
|
|
144
|
+
form#chat-form(
|
|
145
|
+
hx-post="/agents/#{agent_name}/chat"
|
|
146
|
+
hx-target="#chat-log-container"
|
|
147
|
+
hx-swap="beforeend"
|
|
148
|
+
hx-indicator="#send-button-indicator"
|
|
149
|
+
_="on htmx:afterRequest call me.reset() then get #chat-log-container then set its scrollTop to its scrollHeight"
|
|
150
|
+
)
|
|
151
|
+
.chat-composer-row
|
|
152
|
+
.control.is-expanded.chat-input-wrap
|
|
153
|
+
input.input#chat-input(
|
|
154
|
+
type="text"
|
|
155
|
+
name="message"
|
|
156
|
+
placeholder="Message #{agent_name}…"
|
|
157
|
+
required=true
|
|
158
|
+
autofocus
|
|
159
|
+
disabled=(!is_running || !@active_session_details)
|
|
160
|
+
)
|
|
161
|
+
span.icon.is-small.is-right.htmx-indicator.chat-input-spinner
|
|
162
|
+
i.fas.fa-spinner.fa-spin
|
|
163
|
+
button.button.is-primary#send-button(
|
|
164
|
+
type="submit"
|
|
165
|
+
disabled=(!is_running || !@active_session_details)
|
|
166
|
+
)
|
|
167
|
+
span Send
|
|
168
|
+
span.icon.is-small.ml-1
|
|
169
|
+
i.fas.fa-paper-plane
|
|
170
|
+
span.icon.is-small#send-button-indicator.htmx-indicator.ml-1
|
|
171
|
+
i.fas.fa-spinner.fa-pulse
|
|
172
|
+
|
|
173
|
+
#chat-status-help-container.mt-2
|
|
174
|
+
- if @agent_data && !is_running
|
|
175
|
+
p.help.is-danger#chat-not-running-help Agent must be running to chat.
|
|
176
|
+
- elsif @agent_data && is_running && !@active_session_details
|
|
177
|
+
p.help.is-warning#chat-no-active-session-help No active chat session. Start a new session above.
|
|
178
|
+
- else
|
|
179
|
+
p.help.is-hidden No issues.
|
|
180
|
+
|
|
181
|
+
/ --- Run Details inspector ---
|
|
182
|
+
aside.chat-inspector
|
|
183
|
+
h3.inspector-title Run Details
|
|
184
|
+
== slim :_active_session_info, locals: { active_session_details: @active_session_details }
|
|
185
|
+
.inspector-section
|
|
186
|
+
.inspector-label Available Tools
|
|
187
|
+
- if configured_tools.any?
|
|
188
|
+
.inspector-tools
|
|
189
|
+
- configured_tools.each do |t|
|
|
190
|
+
span.tool-chip= t
|
|
191
|
+
- else
|
|
192
|
+
p.inspector-empty No tools configured
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/ File: lib/legate/web/views/docs_index.slim
|
|
2
|
+
|
|
3
|
+
.content.mb-5
|
|
4
|
+
h1.title.is-2 Legate Documentation
|
|
5
|
+
p.subtitle Browse available documentation for Legate.
|
|
6
|
+
|
|
7
|
+
- if @categorized_documents.nil? || @categorized_documents.empty?
|
|
8
|
+
.notification.is-warning
|
|
9
|
+
p No documentation files found in
|
|
10
|
+
code public/docs
|
|
11
|
+
p or an error occurred while listing them.
|
|
12
|
+
- else
|
|
13
|
+
.field.mb-4
|
|
14
|
+
.control.has-icons-left.search-with-shortcut
|
|
15
|
+
input.input#doc-search-input type="text" placeholder="Search documentation..." onkeyup="filterDocs()"
|
|
16
|
+
span.icon.is-left
|
|
17
|
+
i.fas.fa-search
|
|
18
|
+
span.keyboard-hint
|
|
19
|
+
kbd ⌘K
|
|
20
|
+
|
|
21
|
+
- @categorized_documents.each do |category, documents|
|
|
22
|
+
- unless documents.empty?
|
|
23
|
+
h3.title.is-4.mt-5 = category
|
|
24
|
+
.box.p-0
|
|
25
|
+
.table-container
|
|
26
|
+
table.table.is-fullwidth.is-hoverable.is-striped.documentation-index-table
|
|
27
|
+
thead
|
|
28
|
+
tr
|
|
29
|
+
th Document
|
|
30
|
+
th Description
|
|
31
|
+
th.has-text-centered.action-column
|
|
32
|
+
tbody class="doc-category-body" data-category=category.downcase
|
|
33
|
+
- documents.each do |doc|
|
|
34
|
+
tr.doc-row data-title=doc[:title].downcase data-summary=doc[:summary].downcase data-path=doc[:path]
|
|
35
|
+
td
|
|
36
|
+
a.doc-title href="/docs/#{doc[:path]}" = doc[:title]
|
|
37
|
+
td
|
|
38
|
+
.doc-summary
|
|
39
|
+
= doc[:summary]
|
|
40
|
+
- if doc[:summary].empty?
|
|
41
|
+
em.has-text-grey-light [No summary available]
|
|
42
|
+
td.has-text-centered
|
|
43
|
+
a.button.is-small.is-link.is-outlined href="/docs/#{doc[:path]}"
|
|
44
|
+
span.icon.is-small
|
|
45
|
+
i.fas.fa-book
|
|
46
|
+
span Read
|
|
47
|
+
|
|
48
|
+
javascript:
|
|
49
|
+
function filterDocs() {
|
|
50
|
+
const input = document.getElementById('doc-search-input');
|
|
51
|
+
const filter = input.value.toLowerCase().trim();
|
|
52
|
+
const allRows = document.querySelectorAll('#doc-table-body .doc-row, .doc-category-body .doc-row'); // Select all rows
|
|
53
|
+
const categoryTitles = document.querySelectorAll('h3.title.is-4'); // Select all category titles
|
|
54
|
+
|
|
55
|
+
if (filter === '') {
|
|
56
|
+
// Show all rows and categories if search is empty
|
|
57
|
+
allRows.forEach(row => {
|
|
58
|
+
row.style.display = '';
|
|
59
|
+
});
|
|
60
|
+
categoryTitles.forEach(title => {
|
|
61
|
+
title.style.display = '';
|
|
62
|
+
const table = title.nextElementSibling.querySelector('table');
|
|
63
|
+
if(table) table.style.display = '';
|
|
64
|
+
});
|
|
65
|
+
input.placeholder = 'Search documentation...';
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let totalFoundCount = 0;
|
|
70
|
+
|
|
71
|
+
document.querySelectorAll('.doc-category-body').forEach(tableBody => {
|
|
72
|
+
let categoryFoundCount = 0;
|
|
73
|
+
const categoryRows = tableBody.querySelectorAll('.doc-row');
|
|
74
|
+
const selector = 'h3.title.is-4[data-category="' + tableBody.dataset.category + '"]';
|
|
75
|
+
const categoryTitleElement = document.querySelector(selector) ||
|
|
76
|
+
Array.from(categoryTitles).find(ct => ct.textContent.toLowerCase() === tableBody.dataset.category);
|
|
77
|
+
|
|
78
|
+
categoryRows.forEach(row => {
|
|
79
|
+
const title = row.getAttribute('data-title');
|
|
80
|
+
const summary = row.getAttribute('data-summary');
|
|
81
|
+
|
|
82
|
+
if (title.includes(filter) || summary.includes(filter)) {
|
|
83
|
+
row.style.display = '';
|
|
84
|
+
categoryFoundCount++;
|
|
85
|
+
totalFoundCount++;
|
|
86
|
+
} else {
|
|
87
|
+
row.style.display = 'none';
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Show/hide category title and table based on whether any docs in it matched
|
|
92
|
+
if (categoryTitleElement) {
|
|
93
|
+
const associatedTableContainer = categoryTitleElement.nextElementSibling; // Assuming .box.p-0 is next
|
|
94
|
+
if (categoryFoundCount > 0) {
|
|
95
|
+
categoryTitleElement.style.display = '';
|
|
96
|
+
if (associatedTableContainer) associatedTableContainer.style.display = '';
|
|
97
|
+
} else {
|
|
98
|
+
categoryTitleElement.style.display = 'none';
|
|
99
|
+
if (associatedTableContainer) associatedTableContainer.style.display = 'none';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
input.placeholder = `${totalFoundCount} result${totalFoundCount !== 1 ? 's' : ''} found`;
|
|
105
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/ File: lib/legate/web/views/docs_show.slim
|
|
2
|
+
|
|
3
|
+
.container
|
|
4
|
+
nav.breadcrumb.has-arrow-separator.p-4.has-background-info-light
|
|
5
|
+
ul
|
|
6
|
+
li
|
|
7
|
+
a href="/docs" Documentation
|
|
8
|
+
li.is-active
|
|
9
|
+
a href="#" aria-current="page" = @doc_title || "Document"
|
|
10
|
+
|
|
11
|
+
.content.mb-5
|
|
12
|
+
h1.title.is-2.mt-4 = @doc_title || "Document"
|
|
13
|
+
|
|
14
|
+
.box.documentation-content
|
|
15
|
+
/ Add a table of contents for longer documents
|
|
16
|
+
- if @doc_html_content && !@doc_html_content.empty?
|
|
17
|
+
.columns
|
|
18
|
+
.column.is-9.pr-5
|
|
19
|
+
.content
|
|
20
|
+
== @doc_html_content
|
|
21
|
+
.column.is-3.is-hidden-mobile
|
|
22
|
+
.toc-container.is-sticky style="top: 80px; max-height: calc(100vh - 100px); overflow-y: auto; padding-right: 15px;"
|
|
23
|
+
.has-text-weight-bold.mb-2 Table of Contents
|
|
24
|
+
.table-of-contents
|
|
25
|
+
/ This will be populated by JavaScript
|
|
26
|
+
- else
|
|
27
|
+
.notification.is-danger
|
|
28
|
+
p Error: Document content could not be loaded or rendered.
|
|
29
|
+
|
|
30
|
+
/ Add JavaScript to generate a table of contents from headings
|
|
31
|
+
javascript:
|
|
32
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
33
|
+
// Generate table of contents from headings
|
|
34
|
+
const content = document.querySelector('.documentation-content .content');
|
|
35
|
+
const toc = document.querySelector('.table-of-contents');
|
|
36
|
+
|
|
37
|
+
if (content && toc) {
|
|
38
|
+
const headings = content.querySelectorAll('h2, h3, h4');
|
|
39
|
+
|
|
40
|
+
if (headings.length > 0) {
|
|
41
|
+
const tocList = document.createElement('ul');
|
|
42
|
+
tocList.className = 'toc-list';
|
|
43
|
+
|
|
44
|
+
headings.forEach((heading, index) => {
|
|
45
|
+
// Add ID to heading if it doesn't have one
|
|
46
|
+
if (!heading.id) {
|
|
47
|
+
heading.id = 'heading-' + index;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const listItem = document.createElement('li');
|
|
51
|
+
listItem.className = 'toc-item toc-' + heading.tagName.toLowerCase();
|
|
52
|
+
|
|
53
|
+
const link = document.createElement('a');
|
|
54
|
+
link.href = '#' + heading.id;
|
|
55
|
+
link.textContent = heading.textContent;
|
|
56
|
+
|
|
57
|
+
listItem.appendChild(link);
|
|
58
|
+
tocList.appendChild(listItem);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
toc.appendChild(tocList);
|
|
62
|
+
|
|
63
|
+
// Add styles for TOC items
|
|
64
|
+
const style = document.createElement('style');
|
|
65
|
+
style.textContent = `
|
|
66
|
+
.toc-list {
|
|
67
|
+
list-style: none;
|
|
68
|
+
padding-left: 0;
|
|
69
|
+
margin-top: 0.5rem;
|
|
70
|
+
}
|
|
71
|
+
.toc-item {
|
|
72
|
+
margin-bottom: 0.5rem;
|
|
73
|
+
font-size: 0.9rem;
|
|
74
|
+
}
|
|
75
|
+
.toc-h3 {
|
|
76
|
+
padding-left: 1rem;
|
|
77
|
+
font-size: 0.85rem;
|
|
78
|
+
}
|
|
79
|
+
.toc-h4 {
|
|
80
|
+
padding-left: 2rem;
|
|
81
|
+
font-size: 0.8rem;
|
|
82
|
+
}
|
|
83
|
+
.toc-item a {
|
|
84
|
+
color: #4a4a4a;
|
|
85
|
+
text-decoration: none;
|
|
86
|
+
display: block;
|
|
87
|
+
padding: 0.2rem 0;
|
|
88
|
+
border-left: 2px solid transparent;
|
|
89
|
+
padding-left: 0.5rem;
|
|
90
|
+
}
|
|
91
|
+
.toc-item a:hover {
|
|
92
|
+
color: #3273dc;
|
|
93
|
+
border-left: 2px solid #3273dc;
|
|
94
|
+
}
|
|
95
|
+
.is-sticky {
|
|
96
|
+
position: sticky;
|
|
97
|
+
}
|
|
98
|
+
`;
|
|
99
|
+
document.head.appendChild(style);
|
|
100
|
+
} else {
|
|
101
|
+
// If no headings, hide the TOC
|
|
102
|
+
document.querySelector('.toc-container').style.display = 'none';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/ File: lib/legate/web/views/index.slim
|
|
2
|
+
|
|
3
|
+
/ Hero Welcome Section
|
|
4
|
+
section.hero-welcome.mb-6
|
|
5
|
+
.hero-content
|
|
6
|
+
.hero-main
|
|
7
|
+
.hero-badge
|
|
8
|
+
i.fas.fa-gem
|
|
9
|
+
.hero-text
|
|
10
|
+
p.hero-eyebrow Legion Commander
|
|
11
|
+
h1.hero-title Command your AI legion
|
|
12
|
+
p.hero-subtitle Build, orchestrate, and run powerful AI agents in elegant Ruby.
|
|
13
|
+
button.hero-pronounce(type="button" title="Say it out loud" aria-label="Pronounce Legate")
|
|
14
|
+
span.respell
|
|
15
|
+
strong Legate
|
|
16
|
+
span.phon= "/ˈle·jit/"
|
|
17
|
+
span.pronounce-wink yep, like “legit” 😎
|
|
18
|
+
span.icon.pronounce-speaker
|
|
19
|
+
i.fas.fa-volume-up
|
|
20
|
+
.hero-actions
|
|
21
|
+
a.button.is-hero-primary.is-medium(href="/agents")
|
|
22
|
+
span.icon
|
|
23
|
+
i.fas.fa-plus
|
|
24
|
+
span Create Agent
|
|
25
|
+
a.button.is-hero-secondary.is-medium(href="/docs")
|
|
26
|
+
span.icon
|
|
27
|
+
i.fas.fa-book
|
|
28
|
+
span Documentation
|
|
29
|
+
|
|
30
|
+
.columns.is-centered.is-multiline.index-dashboard-cards
|
|
31
|
+
.column.is-one-quarter
|
|
32
|
+
.card.dashboard-card.agents-card.has-text-centered
|
|
33
|
+
.card-content
|
|
34
|
+
span.icon.is-large.mb-3
|
|
35
|
+
i.fas.fa-robot.fa-3x style="color: var(--color-primary);"
|
|
36
|
+
h2.title.is-4 Agents
|
|
37
|
+
- if @running_count && @running_count > 0
|
|
38
|
+
p.is-size-2.has-text-weight-bold style="color: var(--color-primary);"
|
|
39
|
+
= @running_count
|
|
40
|
+
p.subtitle.is-6.mb-2 Running
|
|
41
|
+
p.is-size-7.has-text-grey
|
|
42
|
+
= "#{@agent_count} total defined"
|
|
43
|
+
- elsif @agent_count && @agent_count > 0
|
|
44
|
+
p.is-size-2.has-text-weight-bold style="color: var(--color-text-muted);"
|
|
45
|
+
= @agent_count
|
|
46
|
+
p.subtitle.is-6.mb-2 Defined
|
|
47
|
+
p.is-size-7.has-text-grey None running
|
|
48
|
+
- else
|
|
49
|
+
p.has-text-grey-light.is-italic.mb-2 No agents defined yet
|
|
50
|
+
p.is-size-7.has-text-grey Create your first agent
|
|
51
|
+
.card-footer
|
|
52
|
+
a.card-footer-item(href="/agents")
|
|
53
|
+
span View Agents
|
|
54
|
+
span.icon.is-small.ml-1
|
|
55
|
+
i.fas.fa-arrow-right
|
|
56
|
+
a.card-footer-item.quick-action(href="/agents" title="Create new agent")
|
|
57
|
+
span.icon
|
|
58
|
+
i.fas.fa-plus
|
|
59
|
+
|
|
60
|
+
.column.is-one-quarter
|
|
61
|
+
.card.dashboard-card.tools-card.has-text-centered
|
|
62
|
+
.card-content
|
|
63
|
+
span.icon.is-large.mb-3
|
|
64
|
+
i.fas.fa-wrench.fa-3x style="color: var(--color-primary);"
|
|
65
|
+
h2.title.is-4 Tools
|
|
66
|
+
- if @tool_count && @tool_count > 0
|
|
67
|
+
p.is-size-2.has-text-weight-bold style="color: var(--color-primary);"
|
|
68
|
+
= @tool_count
|
|
69
|
+
p.subtitle.is-6.mb-2 Available
|
|
70
|
+
- else
|
|
71
|
+
p.has-text-grey-light.is-italic.mb-2 No tools loaded
|
|
72
|
+
.card-footer
|
|
73
|
+
a.card-footer-item(href="/tools")
|
|
74
|
+
span View Tools
|
|
75
|
+
span.icon.is-small.ml-1
|
|
76
|
+
i.fas.fa-arrow-right
|
|
77
|
+
a.card-footer-item.quick-action(href="/tools" title="Build new tool with AI")
|
|
78
|
+
span.icon
|
|
79
|
+
i.fas.fa-plus
|
|
80
|
+
|
|
81
|
+
.column.is-one-quarter
|
|
82
|
+
.card.dashboard-card.auth-card.has-text-centered
|
|
83
|
+
.card-content
|
|
84
|
+
span.icon.is-large.mb-3
|
|
85
|
+
i.fas.fa-key.fa-3x style="color: var(--color-primary);"
|
|
86
|
+
h2.title.is-4 Authentication
|
|
87
|
+
- if @auth_scheme_count && @auth_scheme_count > 0
|
|
88
|
+
p.is-size-2.has-text-weight-bold style="color: var(--color-primary);"
|
|
89
|
+
= @auth_scheme_count
|
|
90
|
+
p.subtitle.is-6.mb-2 Schemes
|
|
91
|
+
- else
|
|
92
|
+
p.has-text-grey-light.is-italic.mb-2 Configure auth
|
|
93
|
+
.card-footer
|
|
94
|
+
a.card-footer-item(href="/auth")
|
|
95
|
+
span View Authentication
|
|
96
|
+
span.icon.is-small.ml-1
|
|
97
|
+
i.fas.fa-arrow-right
|
|
98
|
+
|
|
99
|
+
.column.is-one-quarter
|
|
100
|
+
.card.dashboard-card.docs-card.has-text-centered
|
|
101
|
+
.card-content
|
|
102
|
+
span.icon.is-large.mb-3
|
|
103
|
+
i.fas.fa-book-open.fa-3x style="color: var(--color-primary);"
|
|
104
|
+
h2.title.is-4 Documentation
|
|
105
|
+
p.has-text-grey Read guides and concepts about Legate.
|
|
106
|
+
.card-footer
|
|
107
|
+
a.card-footer-item(href="/docs")
|
|
108
|
+
span Read Docs
|
|
109
|
+
span.icon.is-small.ml-1
|
|
110
|
+
i.fas.fa-arrow-right
|
|
111
|
+
|
|
112
|
+
/ Activity Stream Section
|
|
113
|
+
.box.activity-stream-box.mt-5
|
|
114
|
+
.level.mb-4
|
|
115
|
+
.level-left
|
|
116
|
+
h3.title.is-5.mb-0
|
|
117
|
+
span.icon.mr-2
|
|
118
|
+
i.fas.fa-stream
|
|
119
|
+
| Recent Activity
|
|
120
|
+
.level-right
|
|
121
|
+
button.button.is-small.is-light(hx-get="/activity/recent" hx-target="#activity-list" hx-swap="innerHTML" title="Refresh activity")
|
|
122
|
+
span.icon.is-small
|
|
123
|
+
i.fas.fa-sync-alt
|
|
124
|
+
|
|
125
|
+
#activity-list
|
|
126
|
+
== slim :_activity_list
|
|
127
|
+
|
|
128
|
+
javascript:
|
|
129
|
+
(function () {
|
|
130
|
+
var btn = document.querySelector('.hero-pronounce');
|
|
131
|
+
if (!btn) return;
|
|
132
|
+
btn.addEventListener('click', function () {
|
|
133
|
+
btn.classList.remove('is-saying');
|
|
134
|
+
// restart the wink animation
|
|
135
|
+
void btn.offsetWidth;
|
|
136
|
+
btn.classList.add('is-saying');
|
|
137
|
+
try {
|
|
138
|
+
if ('speechSynthesis' in window) {
|
|
139
|
+
window.speechSynthesis.cancel();
|
|
140
|
+
var u = new SpeechSynthesisUtterance('Legate. Say it like legit.');
|
|
141
|
+
u.rate = 0.95;
|
|
142
|
+
u.pitch = 1.05;
|
|
143
|
+
window.speechSynthesis.speak(u);
|
|
144
|
+
}
|
|
145
|
+
} catch (e) { /* no audio, the wink still fires */ }
|
|
146
|
+
setTimeout(function () { btn.classList.remove('is-saying'); }, 900);
|
|
147
|
+
});
|
|
148
|
+
})();
|