From 858798a5b2407093bb023ec6cfdf74624e9b2b32 Mon Sep 17 00:00:00 2001 From: colin Date: Fri, 11 Sep 2026 18:12:55 +0800 Subject: [PATCH] feat: Add AI Module --- Directory.Packages.props | 3 + aspnet-core/LINGYUN.MicroService.Aspire.slnx | 6 + .../WorkflowServiceModule.Configure.cs | 3 + .../WorkflowServiceModule.cs | 2 + .../appsettings.Development.json | 24 ++- .../LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xml | 3 + .../LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xsd | 30 +++ .../LINGYUN.Abp.ElsaNext.AI.csproj | 24 +++ .../Abp/ElsaNext/AI/AbpElsaNextAIModule.cs | 23 ++ .../AI/Extensions/ModuleExtensions.cs | 14 ++ .../Abp/ElsaNext/AI/Features/AbpAIFeature.cs | 44 ++++ .../AbpElsaNextStudioAIBlazorModule.cs | 49 +++++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 +++ ...NGYUN.Abp.ElsaNext.Studio.AI.Blazor.csproj | 31 +++ .../Localization/Resources/AIBlazor/en.json | 7 + .../Resources/AIBlazor/zh-Hans.json | 7 + .../Navigation/ElsaStudioAIMenuContributor.cs | 27 +++ .../Pages/Weaver.razor | 11 + .../_Imports.razor | 5 + .../wwwroot/weaver.css | 196 ++++++++++++++++++ 21 files changed, 541 insertions(+), 1 deletion(-) create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xml create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xsd create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN.Abp.ElsaNext.AI.csproj create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/AbpElsaNextAIModule.cs create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Extensions/ModuleExtensions.cs create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Features/AbpAIFeature.cs create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/AbpElsaNextStudioAIBlazorModule.cs create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xml create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xsd create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.csproj create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/en.json create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/zh-Hans.json create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Navigation/ElsaStudioAIMenuContributor.cs create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Pages/Weaver.razor create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/_Imports.razor create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/wwwroot/weaver.css diff --git a/Directory.Packages.props b/Directory.Packages.props index 78f1efe86..c56454e95 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -244,6 +244,8 @@ + + @@ -267,6 +269,7 @@ + diff --git a/aspnet-core/LINGYUN.MicroService.Aspire.slnx b/aspnet-core/LINGYUN.MicroService.Aspire.slnx index 122c96e61..7cd80886c 100644 --- a/aspnet-core/LINGYUN.MicroService.Aspire.slnx +++ b/aspnet-core/LINGYUN.MicroService.Aspire.slnx @@ -555,19 +555,25 @@ + + + + + + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.Configure.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.Configure.cs index ae24f9e1d..419496663 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.Configure.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.Configure.cs @@ -1,5 +1,7 @@ using DotNetCore.CAP; using Elsa.Agents; +using Elsa.AI.Persistence.EFCore.Features; +using Elsa.AI.Persistence.EFCore.Sqlite.Extensions; using Elsa.Extensions; using Elsa.Features.Services; using Elsa.Persistence.EFCore.Extensions; @@ -158,6 +160,7 @@ public partial class WorkflowServiceModule { options.IsBlazorWebApp = true; }); + services.AddAIPersistenceStores(options => options.UseSqlite()); PreConfigure(elsa => { elsa.UseWorkflowManagement(management => diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.cs index ad2d1d861..922e5d874 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.cs @@ -13,6 +13,7 @@ using LINGYUN.Abp.ElsaNext.Labels; using LINGYUN.Abp.ElsaNext.Notifications; using LINGYUN.Abp.ElsaNext.Secrets.Blazor; using LINGYUN.Abp.ElsaNext.Server; +using LINGYUN.Abp.ElsaNext.Studio.AI.Blazor; using LINGYUN.Abp.ElsaNext.Studio.Blazor; using LINGYUN.Abp.ElsaNext.Studio.Dashboard.Blazor; using LINGYUN.Abp.ElsaNext.Studio.Diagnostics.OpenTelemetry.Blazor; @@ -74,6 +75,7 @@ namespace LINGYUN.Abp.MicroService.WorkflowService; typeof(AbpElsaNextStudioBlazorModule), typeof(AbpElsaNextAgentsBlazorModule), typeof(AbpElsaNextSecretsBlazorModule), + typeof(AbpElsaNextStudioAIBlazorModule), typeof(AbpElsaNextStudioDashboardBlazorModule), typeof(AbpElsaNextStudioDiagnosticsOpenTelemetryBlazorModule), typeof(AbpElsaNextStudioDiagnosticsStructuredLogsBlazorModule), diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/appsettings.Development.json b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/appsettings.Development.json index 4c1ded63c..a3bb2eec7 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/appsettings.Development.json +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/appsettings.Development.json @@ -33,6 +33,25 @@ } }, "Elsa": { + "AI": { + "Host": { + "DefaultProviderName": "copilot", + "Providers": [ + { + "Name": "copilot", + "Provider": "copilot", + "Model": "GPT-5 mini", + "Enabled": true + } + ] + }, + "Copilot": { + "EnableStreaming": true, + "Model": "GPT-5 mini", + "WorkingDirectory": "copilot", + "BaseDirectory": "./workspace" + } + }, "Http": { "BaseUrl": "http://localhost:30050" }, @@ -60,7 +79,10 @@ "RemoteServices": { "BlobManagement": { "BaseUrl": "http://localhost:30025", - "IdentityClient": "InternalServiceClient", + "UseCurrentAccessToken": false + }, + "Platform": { + "BaseUrl": "http://localhost:30025", "UseCurrentAccessToken": false } }, diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xml b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xml new file mode 100644 index 000000000..5d6962159 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xsd b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN.Abp.ElsaNext.AI.csproj b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN.Abp.ElsaNext.AI.csproj new file mode 100644 index 000000000..9d149eb73 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN.Abp.ElsaNext.AI.csproj @@ -0,0 +1,24 @@ + + + + + + + net10.0 + LINGYUN.Abp.ElsaNext.AI + LINGYUN.Abp.ElsaNext.AI + false + false + false + + + + + + + + + + + + diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/AbpElsaNextAIModule.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/AbpElsaNextAIModule.cs new file mode 100644 index 000000000..0570b6f44 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/AbpElsaNextAIModule.cs @@ -0,0 +1,23 @@ +using Elsa.Features.Services; +using LINGYUN.Abp.ElsaNext.AI.Extensions; +using Microsoft.Extensions.Configuration; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.ElsaNext.AI; + +[DependsOn(typeof(AbpElsaNextModule))] +public class AbpElsaNextAIModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Configuration.GetSection("Elsa:AI"); + PreConfigure(elsa => + { + elsa.UseAbpAI(ai => + { + ai.ConfigureOptions = options => configuration.GetSection("Host").Bind(options); + ai.ConfigureCopilotOptions = options => configuration.GetSection("Copilot").Bind(options); + }); + }); + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Extensions/ModuleExtensions.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Extensions/ModuleExtensions.cs new file mode 100644 index 000000000..6f651b2a9 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Extensions/ModuleExtensions.cs @@ -0,0 +1,14 @@ +using Elsa.Extensions; +using Elsa.Features.Services; +using LINGYUN.Abp.ElsaNext.AI.Features; +using System; + +namespace LINGYUN.Abp.ElsaNext.AI.Extensions; + +public static class ModuleExtensions +{ + public static IModule UseAbpAI(this IModule module, Action? configure = null) + { + return module.Use(configure); + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Features/AbpAIFeature.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Features/AbpAIFeature.cs new file mode 100644 index 000000000..689dbda46 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Features/AbpAIFeature.cs @@ -0,0 +1,44 @@ +using Elsa.AI.Copilot.Options; +using Elsa.AI.Host.Features; +using Elsa.AI.Host.Options; +using Elsa.AI.Host.Services; +using Elsa.Extensions; +using Elsa.Features.Abstractions; +using Elsa.Features.Services; +using Microsoft.Extensions.DependencyInjection; +using System; + +namespace LINGYUN.Abp.ElsaNext.AI.Features; + +public class AbpAIFeature(IModule module) : FeatureBase(module) +{ + public Action? ConfigureOptions { get; set; } + public Action? ConfigureCopilotOptions { get; set; } + public Action? ConfigureToolEnablement { get; set; } + + public override void Configure() + { + Module.AddFastEndpointsAssembly(); + } + + public override void Apply() + { + Services.AddAIHostServices(ConfigureOptions); + Services.AddCopilotAIProvider(ConfigureCopilotOptions); + if (ConfigureToolEnablement != null) + { + Services.AddSingleton(ConfigureToolEnablement); + } + Module.AddFastEndpointsFromModule(); + } + + public AbpAIFeature EnableWorkflowProposalTools() + { + ConfigureToolEnablement += enablement => + { + enablement.Enable("workflows.proposeCreate"); + enablement.Enable("workflows.proposeUpdate"); + }; + return this; + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/AbpElsaNextStudioAIBlazorModule.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/AbpElsaNextStudioAIBlazorModule.cs new file mode 100644 index 000000000..0d14d6fde --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/AbpElsaNextStudioAIBlazorModule.cs @@ -0,0 +1,49 @@ +using Elsa.Studio.AI.Extensions; +using LINGYUN.Abp.ElsaNext.AI; +using LINGYUN.Abp.ElsaNext.Localization; +using LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.Navigation; +using LINGYUN.Abp.ElsaNext.Studio.Blazor; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Components.Web.Theming.MudBlazor.Routing; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.UI.Navigation; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.ElsaNext.Studio.AI.Blazor; + +[DependsOn( + typeof(AbpElsaNextAIModule), + typeof(AbpElsaNextStudioBlazorModule))] +public class AbpElsaNextStudioAIBlazorModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Configuration.GetSection("Elsa:Studio"); + + Configure(options => + { + options.AdditionalAssemblies.Add(typeof(AbpElsaNextStudioAIBlazorModule).Assembly); + }); + + Configure(options => + { + options.MenuContributors.Add(new ElsaStudioAIMenuContributor()); + }); + + Configure(options => + { + options.FileSets.AddEmbedded("LINGYUN.Abp.ElsaNext.Studio.AI.Blazor"); + }); + + Configure(options => + { + options.Resources + .Get() + .AddVirtualJson("/Localization/Resources/AIBlazor"); + }); + var elsaNextStudioBlazoeOptions = context.Services.ExecutePreConfiguredActions(); + + context.Services.AddWeaverModule(elsaNextStudioBlazoeOptions.BackendApiConfig); + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xml b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xml new file mode 100644 index 000000000..5d6962159 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xsd b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.csproj b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.csproj new file mode 100644 index 000000000..a9b00d7d4 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.csproj @@ -0,0 +1,31 @@ + + + + + + + net10.0 + enable + enable + LINGYUN.Abp.ElsaNext.Studio.AI.Blazor + LINGYUN.Abp.ElsaNext.Studio.AI.Blazor + false + false + false + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/en.json b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/en.json new file mode 100644 index 000000000..a6c727672 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/en.json @@ -0,0 +1,7 @@ +{ + "culture": "en", + "texts": { + "Menu:AI": "AI", + "AI": "AI" + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/zh-Hans.json b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/zh-Hans.json new file mode 100644 index 000000000..5b82fa625 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/zh-Hans.json @@ -0,0 +1,7 @@ +{ + "culture": "zh-Hans", + "texts": { + "Menu:AI": "AI", + "AI": "AI" + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Navigation/ElsaStudioAIMenuContributor.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Navigation/ElsaStudioAIMenuContributor.cs new file mode 100644 index 000000000..31f6010ac --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Navigation/ElsaStudioAIMenuContributor.cs @@ -0,0 +1,27 @@ +using LINGYUN.Abp.ElsaNext.Localization; +using LINGYUN.Abp.ElsaNext.Studio.Blazor.Navigation; +using Volo.Abp.UI.Navigation; + +namespace LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.Navigation; + +public class ElsaStudioAIMenuContributor : IMenuContributor +{ + public Task ConfigureMenuAsync(MenuConfigurationContext context) + { + if (context.Menu.Name == StandardMenus.Main) + { + var menu = context.Menu; + var l = context.GetLocalizer(); + + var group = menu.GetMenuItemOrNull(ElsaStudioMenus.GroupName); + group?.AddItem(new ApplicationMenuItem( + ElsaStudioMenus.GroupName + ".AI", + l["Menu:AI"], + url: "/ai/weaver", + icon: "fa fa-openai", + order: 6)); + } + + return Task.CompletedTask; + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Pages/Weaver.razor b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Pages/Weaver.razor new file mode 100644 index 000000000..62ef6a33e --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Pages/Weaver.razor @@ -0,0 +1,11 @@ +@page "/ai/weaver" +@attribute [Authorize] +@inherits StudioComponentBase +@using Elsa.Studio.AI.UI.Pages + + + @* *@ + + + + diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/_Imports.razor b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/_Imports.razor new file mode 100644 index 000000000..6a4064616 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/_Imports.razor @@ -0,0 +1,5 @@ +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Web +@using Elsa.Studio.Components +@using Elsa.Studio.Localization +@using MudBlazor diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/wwwroot/weaver.css b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/wwwroot/weaver.css new file mode 100644 index 000000000..61ffa893e --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/wwwroot/weaver.css @@ -0,0 +1,196 @@ +.weaver-page { + height: calc(100vh - 72px); + display: flex; + flex-direction: column; + gap: 12px; +} + +.weaver-heading, +.weaver-thread-header, +.weaver-panel-title, +.weaver-composer-actions, +.weaver-tool, +.weaver-activity { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} + +.weaver-workspace { + min-height: 0; + display: grid; + grid-template-columns: minmax(0, 1fr) 360px; + gap: 12px; + flex: 1; +} + +.weaver-main, +.weaver-side, +.weaver-thread { + min-height: 0; +} + +.weaver-thread, +.weaver-panel { + border: 1px solid var(--mud-palette-lines-default); + border-radius: 8px; + background: var(--mud-palette-surface); +} + +.weaver-thread { + height: 100%; + display: grid; + grid-template-rows: auto minmax(0, 1fr) auto auto; + gap: 12px; + padding: 12px; +} + +.weaver-message-list, +.weaver-activity-list, +.weaver-tool-list { + min-height: 0; + overflow: auto; +} + +.weaver-message-list { + display: flex; + flex-direction: column; + gap: 10px; +} + +.weaver-message { + max-width: 78%; + border: 1px solid var(--mud-palette-lines-default); + border-radius: 8px; + padding: 10px 12px; + background: var(--mud-palette-background); +} + + .weaver-message.is-user { + align-self: flex-end; + background: var(--mud-palette-primary-hover); + } + + .weaver-message.is-assistant { + align-self: flex-start; + } + +.weaver-message-meta { + font-size: 0.72rem; + color: var(--mud-palette-text-secondary); + margin-bottom: 4px; +} + +.weaver-message-text { + white-space: pre-wrap; +} + +.weaver-empty { + margin: auto; + text-align: center; +} + +.weaver-composer { + border-top: 1px solid var(--mud-palette-lines-default); + padding-top: 10px; + display: grid; + gap: 8px; +} + +.weaver-attachments { + min-height: 28px; + flex-wrap: wrap; +} + +.weaver-agent-select { + width: 160px; +} + +.weaver-context-kind { + width: 190px; +} + +.weaver-reference-input { + width: 220px; +} + +.weaver-side { + display: grid; + grid-template-rows: auto minmax(160px, 1fr) minmax(120px, 1fr) auto; + gap: 12px; +} + +.weaver-panel { + padding: 12px; + overflow: auto; +} + +.weaver-capability-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + margin-top: 10px; +} + +.weaver-capability-pill { + display: flex; + align-items: center; + gap: 6px; + border: 1px solid var(--mud-palette-lines-default); + border-radius: 6px; + padding: 6px 8px; + font-size: 0.82rem; +} + + .weaver-capability-pill.is-enabled { + color: var(--mud-palette-success); + } + + .weaver-capability-pill.is-disabled { + color: var(--mud-palette-text-secondary); + } + +.weaver-activity-list, +.weaver-tool-list { + display: grid; + gap: 8px; + margin-top: 10px; +} + +.weaver-activity, +.weaver-tool, +.weaver-proposal { + border: 1px solid var(--mud-palette-lines-default); + border-radius: 8px; + padding: 8px; +} + +@media (max-width: 960px) { + .weaver-page { + height: auto; + } + + .weaver-workspace { + grid-template-columns: 1fr; + } + + .weaver-side { + grid-template-rows: none; + } + + .weaver-message { + max-width: 100%; + } + + .weaver-composer-actions { + align-items: stretch; + flex-direction: column; + } + + .weaver-agent-select, + .weaver-context-kind, + .weaver-reference-input { + width: 100%; + } +}