Browse Source

feat: Add AI Module

pull/1568/head
colin 2 weeks ago
parent
commit
858798a5b2
  1. 3
      Directory.Packages.props
  2. 6
      aspnet-core/LINGYUN.MicroService.Aspire.slnx
  3. 3
      aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.Configure.cs
  4. 2
      aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.cs
  5. 24
      aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/appsettings.Development.json
  6. 3
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xml
  7. 30
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xsd
  8. 24
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN.Abp.ElsaNext.AI.csproj
  9. 23
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/AbpElsaNextAIModule.cs
  10. 14
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Extensions/ModuleExtensions.cs
  11. 44
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN/Abp/ElsaNext/AI/Features/AbpAIFeature.cs
  12. 49
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/AbpElsaNextStudioAIBlazorModule.cs
  13. 3
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xml
  14. 30
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xsd
  15. 31
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.csproj
  16. 7
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/en.json
  17. 7
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Localization/Resources/AIBlazor/zh-Hans.json
  18. 27
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Navigation/ElsaStudioAIMenuContributor.cs
  19. 11
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/Pages/Weaver.razor
  20. 5
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/_Imports.razor
  21. 196
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/wwwroot/weaver.css

3
Directory.Packages.props

@ -244,6 +244,8 @@
<PackageVersion Include="Elsa.Agents.Core" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Agents.OpenAI" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Agents.Persistence.EFCore.Sqlite" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.AI.Copilot" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.AI.Persistence.EFCore.Sqlite" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Api.Client" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Dashboard.Api" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Diagnostics.OpenTelemetry" Version="$(ElsaNextPackageVersion)" />
@ -267,6 +269,7 @@
<PackageVersion Include="Elsa.Studio.Secrets" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Studio" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Studio.Agents" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Studio.AI" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Studio.Authentication.Abstractions" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Studio.Authentication.ElsaIdentity.BlazorServer" Version="$(ElsaNextPackageVersion)" />
<PackageVersion Include="Elsa.Studio.Authentication.ElsaIdentity.BlazorWasm" Version="$(ElsaNextPackageVersion)" />

6
aspnet-core/LINGYUN.MicroService.Aspire.slnx

@ -555,19 +555,25 @@
<Folder Name="/modules/workflow/elsa3/">
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Agents.Blazor/LINGYUN.Abp.ElsaNext.Agents.Blazor.csproj" Id="fc82705b-186b-4d0d-80d2-473f08596b48" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Agents/LINGYUN.Abp.ElsaNext.Agents.csproj" Id="8699b2ee-5d73-4e7e-9f52-4ec02e5c8c52" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN.Abp.ElsaNext.AI.csproj" Id="d90d0e07-be50-45d5-aa45-1a917203cc3b" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.BlobStoring/LINGYUN.Abp.ElsaNext.BlobStoring.csproj" Id="ab3ed7c4-918e-40ae-84d6-f98d9ff9c6b1" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Email/LINGYUN.Abp.ElsaNext.Email.csproj" Id="c8cd2bd2-05f2-44b7-ab7b-7943f00f849e" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Labels/LINGYUN.Abp.ElsaNext.Labels.csproj" Id="b2b88f48-e8a2-4760-85f5-d5a3ffffa6f8" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN.Abp.ElsaNext.Notifications.csproj" Id="8a530668-d1be-4383-a344-c8fdb00f1df3" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Secrets.Blazor/LINGYUN.Abp.ElsaNext.Secrets.Blazor.csproj" Id="14b89b15-df06-4965-bd5d-2beaeb0179a6" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Secrets/LINGYUN.Abp.ElsaNext.Secrets.csproj" Id="f49baa76-12c5-4294-b942-fc6f5d49d3e6" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Server/LINGYUN.Abp.ElsaNext.Server.csproj" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.csproj" Id="3246ab91-4cdc-4349-9eb6-e65eef1da0bd" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Blazor/LINGYUN.Abp.ElsaNext.Studio.Blazor.csproj" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Dashboard.Blazor/LINGYUN.Abp.ElsaNext.Studio.Dashboard.Blazor.csproj" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Diagnostics.OpenTelemetry.Blazor/LINGYUN.Abp.ElsaNext.Studio.Diagnostics.OpenTelemetry.Blazor.csproj" Id="86b1ee1c-6266-4003-8ab2-67aa497ea217" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Diagnostics.StructuredLogs.Blazor/LINGYUN.Abp.ElsaNext.Studio.Diagnostics.StructuredLogs.Blazor.csproj" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Identity.Blazor/LINGYUN.Abp.ElsaNext.Studio.Identity.Blazor.csproj" Id="ae638de1-60e9-4bb4-bdd0-1b0206c8e03d" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Labels.Blazor/LINGYUN.Abp.ElsaNext.Studio.Labels.Blazor.csproj" Id="c53b5b3d-ebd9-4016-8c43-1c1e791b59bc" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Notifications.Blazor/LINGYUN.Abp.ElsaNext.Studio.Notifications.Blazor.csproj" Id="70479aa8-ebb8-45bf-b728-f98e161c97de" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Saas.Blazor/LINGYUN.Abp.ElsaNext.Studio.Saas.Blazor.csproj" Id="2f6a0752-670b-4b73-99fe-c5489e516c8b" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.csproj" Id="aead7a25-2ff0-43ad-a68d-31b7f2763056" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN.Abp.ElsaNext.Webhooks.csproj" Id="4fc14100-23c9-41cf-be70-78cd969de95f" />
<Project Path="modules/elsa/LINGYUN.Abp.ElsaNext/LINGYUN.Abp.ElsaNext.csproj" />
</Folder>
<Folder Name="/tests/">

3
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<IModule>(elsa =>
{
elsa.UseWorkflowManagement(management =>

2
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),

24
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
}
},

3
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

24
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.AI/LINGYUN.Abp.ElsaNext.AI.csproj

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<AssemblyName>LINGYUN.Abp.ElsaNext.AI</AssemblyName>
<PackageId>LINGYUN.Abp.ElsaNext.AI</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Elsa.AI.Copilot" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.ElsaNext\LINGYUN.Abp.ElsaNext.csproj" />
</ItemGroup>
</Project>

23
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<IModule>(elsa =>
{
elsa.UseAbpAI(ai =>
{
ai.ConfigureOptions = options => configuration.GetSection("Host").Bind(options);
ai.ConfigureCopilotOptions = options => configuration.GetSection("Copilot").Bind(options);
});
});
}
}

14
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<AbpAIFeature>? configure = null)
{
return module.Use(configure);
}
}

44
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<AIHostOptions>? ConfigureOptions { get; set; }
public Action<CopilotOptions>? ConfigureCopilotOptions { get; set; }
public Action<AIToolEnablementService>? ConfigureToolEnablement { get; set; }
public override void Configure()
{
Module.AddFastEndpointsAssembly<AIFeature>();
}
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;
}
}

49
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<AbpRouterOptions>(options =>
{
options.AdditionalAssemblies.Add(typeof(AbpElsaNextStudioAIBlazorModule).Assembly);
});
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new ElsaStudioAIMenuContributor());
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpElsaNextStudioAIBlazorModule>("LINGYUN.Abp.ElsaNext.Studio.AI.Blazor");
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<ElsaNextResource>()
.AddVirtualJson("/Localization/Resources/AIBlazor");
});
var elsaNextStudioBlazoeOptions = context.Services.ExecutePreConfiguredActions<AbpElsaNextStudioBlazorOptions>();
context.Services.AddWeaverModule(elsaNextStudioBlazoeOptions.BackendApiConfig);
}
}

3
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

31
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor.csproj

@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AssemblyName>LINGYUN.Abp.ElsaNext.Studio.AI.Blazor</AssemblyName>
<PackageId>LINGYUN.Abp.ElsaNext.Studio.AI.Blazor</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
</PropertyGroup>
<ItemGroup>
<Content Remove="Localization\Resources\AIBlazor\*.json" />
<EmbeddedResource Include="Localization\Resources\AIBlazor\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Elsa.Studio.AI" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.ElsaNext.AI\LINGYUN.Abp.ElsaNext.AI.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.ElsaNext.Studio.Blazor\LINGYUN.Abp.ElsaNext.Studio.Blazor.csproj" />
</ItemGroup>
</Project>

7
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"
}
}

7
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"
}
}

27
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<ElsaNextResource>();
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;
}
}

11
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
<HeadContent>
@* <link rel="stylesheet" href="_content/Elsa.Studio.AI/Elsa.Studio.AI.bundle.scp.css" /> *@
<link rel="stylesheet" href="_content/LINGYUN.Abp.ElsaNext.Studio.AI.Blazor/weaver.css" />
</HeadContent>
<Weaver />

5
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

196
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%;
}
}
Loading…
Cancel
Save