Browse Source

Merge pull request #1464 from colinin/ai

feat(ai): Optimize the default options of ChatClientBuilder
pull/1467/head
yx lin 1 month ago
committed by GitHub
parent
commit
0475bfeed9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      Directory.Packages.props
  2. 2
      apps/vben5/packages/@abp/ai-management/src/components/conversations/index.vue
  3. 21
      aspnet-core/LINGYUN.MicroService.SingleProject.sln
  4. 25
      aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/AIServiceModule.Configure.cs
  5. 5821
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql/Migrations/20260330065618_Add-AI-Tool-Definition-Record.Designer.cs
  6. 63
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql/Migrations/20260330065618_Add-AI-Tool-Definition-Record.cs
  7. 72
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql/Migrations/SingleMigrationsDbContextModelSnapshot.cs
  8. 5826
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/Migrations/20260330065549_Add-AI-Tool-Definition-Record.Designer.cs
  9. 63
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/Migrations/20260330065549_Add-AI-Tool-Definition-Record.cs
  10. 72
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/Migrations/SingleMigrationsDbContextModelSnapshot.cs
  11. 3
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/SingleMigrationsDbContext.cs
  12. 5
      aspnet-core/modules/ai/LINGYUN.Abp.AI.Agent/LINGYUN/Abp/AI/Agent/AbpAIAgentOptions.cs
  13. 7
      aspnet-core/modules/ai/LINGYUN.Abp.AI.Agent/LINGYUN/Abp/AI/Agent/AgentFactory.cs
  14. 4
      aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/AbpAICoreOptions.cs
  15. 9
      aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/OpenAIChatClientProvider.cs
  16. 9
      aspnet-core/modules/ai/LINGYUN.Abp.AI.Ollama/LINGYUN/Abp/AI/Ollama/OllamaChatClientProvider.cs
  17. 50
      aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/AbpAIToolsModule.cs
  18. 9
      aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/IWorkspaceAIToolFinder.cs
  19. 52
      aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/WorkspaceAIToolFinder.cs
  20. 2
      aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain.Shared/LINGYUN/Abp/AIManagement/Localization/Resources/en.json
  21. 2
      aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain.Shared/LINGYUN/Abp/AIManagement/Localization/Resources/zh-Hans.json
  22. 28
      aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationChangeNameHandler.cs
  23. 2
      aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj
  24. 29
      aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs
  25. 6
      aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs

2
Directory.Packages.props

@ -28,6 +28,8 @@
<PackageVersion Include="Volo.Abp.Account.Web.OpenIddict" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Components.Web.Theming" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Components.WebAssembly.Theming" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.MultiTenancy" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.Client.Common" Version="$(VoloAbpPackageVersion)" />

2
apps/vben5/packages/@abp/ai-management/src/components/conversations/index.vue

@ -233,7 +233,9 @@ const updateConversationFn = useInterval(10_000, {
});
conversations.value = updateConversations;
if (dayJs(conversation.expiredAt).isBefore(dayJs())) {
content.value = $t('AIManagement.ConversationsExpiredWarnMessage');
agentRequestDisabled.value = true;
updateConversationFn.pause();
}
}
},

21
aspnet-core/LINGYUN.MicroService.SingleProject.sln

@ -720,6 +720,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.AIManagement.Ht
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.AIManagement.HttpApi.Client", "modules\ai\LINGYUN.Abp.AIManagement.HttpApi.Client\LINGYUN.Abp.AIManagement.HttpApi.Client.csproj", "{44957812-548A-D14C-6C92-F9902DADDCDA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.AI.Tools", "modules\ai\LINGYUN.Abp.AI.Tools\LINGYUN.Abp.AI.Tools.csproj", "{A879CDFF-BC9F-C591-0D7E-3A4381489425}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.AI.Tools.Http", "modules\ai\LINGYUN.Abp.AI.Tools.Http\LINGYUN.Abp.AI.Tools.Http.csproj", "{1A02494C-AC35-C41C-3E89-2CB4FEF0A792}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.AI.Tools.Mcp", "modules\ai\LINGYUN.Abp.AI.Tools.Mcp\LINGYUN.Abp.AI.Tools.Mcp.csproj", "{A91A8E8C-7B2F-5278-B771-668E5292E9DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -1922,6 +1928,18 @@ Global
{44957812-548A-D14C-6C92-F9902DADDCDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44957812-548A-D14C-6C92-F9902DADDCDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44957812-548A-D14C-6C92-F9902DADDCDA}.Release|Any CPU.Build.0 = Release|Any CPU
{A879CDFF-BC9F-C591-0D7E-3A4381489425}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A879CDFF-BC9F-C591-0D7E-3A4381489425}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A879CDFF-BC9F-C591-0D7E-3A4381489425}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A879CDFF-BC9F-C591-0D7E-3A4381489425}.Release|Any CPU.Build.0 = Release|Any CPU
{1A02494C-AC35-C41C-3E89-2CB4FEF0A792}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A02494C-AC35-C41C-3E89-2CB4FEF0A792}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A02494C-AC35-C41C-3E89-2CB4FEF0A792}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A02494C-AC35-C41C-3E89-2CB4FEF0A792}.Release|Any CPU.Build.0 = Release|Any CPU
{A91A8E8C-7B2F-5278-B771-668E5292E9DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A91A8E8C-7B2F-5278-B771-668E5292E9DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A91A8E8C-7B2F-5278-B771-668E5292E9DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A91A8E8C-7B2F-5278-B771-668E5292E9DC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2273,6 +2291,9 @@ Global
{5AFC464A-9B1F-7415-2D2E-320D567ED818} = {E87F876B-EEC8-4A3B-9FF0-15EB38B4A7BC}
{3B618981-F1CB-9AEC-E90B-4B05B982C1FC} = {E87F876B-EEC8-4A3B-9FF0-15EB38B4A7BC}
{44957812-548A-D14C-6C92-F9902DADDCDA} = {E87F876B-EEC8-4A3B-9FF0-15EB38B4A7BC}
{A879CDFF-BC9F-C591-0D7E-3A4381489425} = {E87F876B-EEC8-4A3B-9FF0-15EB38B4A7BC}
{1A02494C-AC35-C41C-3E89-2CB4FEF0A792} = {E87F876B-EEC8-4A3B-9FF0-15EB38B4A7BC}
{A91A8E8C-7B2F-5278-B771-668E5292E9DC} = {E87F876B-EEC8-4A3B-9FF0-15EB38B4A7BC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {711A43C0-A2F8-4E5C-9B9F-F2551E4B3FF1}

25
aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/AIServiceModule.Configure.cs

@ -1,4 +1,6 @@
using DotNetCore.CAP;
using LINGYUN.Abp.AI;
using LINGYUN.Abp.AI.Agent;
using LINGYUN.Abp.AIManagement;
using LINGYUN.Abp.AIManagement.Chats;
using LINGYUN.Abp.Localization.CultureMap;
@ -8,9 +10,11 @@ using LINGYUN.Abp.TextTemplating;
using LINGYUN.Abp.Wrapper;
using Medallion.Threading;
using Medallion.Threading.Redis;
using Microsoft.Agents.AI;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
@ -121,6 +125,27 @@ public partial class AIServiceModule
private void ConfigureAIManagement()
{
Configure<AbpAICoreOptions>(options =>
{
options.ChatClientBuildActions.Add((_, __, builder) =>
{
return Task.FromResult(builder
.UseLogging()
.UseOpenTelemetry()
.UseDistributedCache());
});
});
Configure<AbpAIAgentOptions>(options =>
{
options.AgentBuildActions.Add((_, builder) =>
{
return Task.FromResult(builder
.UseLogging()
.UseOpenTelemetry());
});
});
Configure<AIManagementOptions>(options =>
{
options.IsDynamicWorkspaceStoreEnabled = true;

5821
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql/Migrations/20260330065618_Add-AI-Tool-Definition-Record.Designer.cs

File diff suppressed because it is too large

63
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql/Migrations/20260330065618_Add-AI-Tool-Definition-Record.cs

@ -0,0 +1,63 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql.Migrations
{
/// <inheritdoc />
public partial class AddAIToolDefinitionRecord : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Tools",
table: "AbpAIWorkspaceDefinitions",
type: "character varying(128)",
maxLength: 128,
nullable: true);
migrationBuilder.CreateTable(
name: "AbpAIAIToolDefinitionRecords",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: false),
Provider = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
Description = table.Column<string>(type: "character varying(1024)", maxLength: 1024, nullable: true),
IsEnabled = table.Column<bool>(type: "boolean", nullable: false),
IsSystem = table.Column<bool>(type: "boolean", nullable: false),
IsGlobal = table.Column<bool>(type: "boolean", nullable: false),
StateCheckers = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
ExtraProperties = table.Column<string>(type: "text", nullable: false),
ConcurrencyStamp = table.Column<string>(type: "character varying(40)", maxLength: 40, nullable: false),
CreationTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
CreatorId = table.Column<Guid>(type: "uuid", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
LastModifierId = table.Column<Guid>(type: "uuid", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAIAIToolDefinitionRecords", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_AbpAIAIToolDefinitionRecords_Name",
table: "AbpAIAIToolDefinitionRecords",
column: "Name",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpAIAIToolDefinitionRecords");
migrationBuilder.DropColumn(
name: "Tools",
table: "AbpAIWorkspaceDefinitions");
}
}
}

72
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql/Migrations/SingleMigrationsDbContextModelSnapshot.cs

@ -200,6 +200,74 @@ namespace LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql.Mig
b.ToTable("AbpAITokenUsages", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.AIManagement.Tools.AIToolDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("character varying(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uuid")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(1024)
.HasColumnType("character varying(1024)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("text")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsEnabled")
.HasColumnType("boolean");
b.Property<bool>("IsGlobal")
.HasColumnType("boolean");
b.Property<bool>("IsSystem")
.HasColumnType("boolean");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uuid")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<string>("Provider")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)");
b.Property<string>("StateCheckers")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpAIAIToolDefinitionRecords", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.AIManagement.Workspaces.WorkspaceDefinitionRecord", b =>
{
b.Property<Guid>("Id")
@ -295,6 +363,10 @@ namespace LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql.Mig
b.Property<float?>("Temperature")
.HasColumnType("real");
b.Property<string>("Tools")
.HasMaxLength(128)
.HasColumnType("character varying(128)");
b.HasKey("Id");
b.HasIndex("Name")

5826
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/Migrations/20260330065549_Add-AI-Tool-Definition-Record.Designer.cs

File diff suppressed because it is too large

63
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/Migrations/20260330065549_Add-AI-Tool-Definition-Record.cs

@ -0,0 +1,63 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.Migrations
{
/// <inheritdoc />
public partial class AddAIToolDefinitionRecord : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Tools",
table: "AbpAIWorkspaceDefinitions",
type: "nvarchar(128)",
maxLength: 128,
nullable: true);
migrationBuilder.CreateTable(
name: "AbpAIAIToolDefinitionRecords",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false),
Provider = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: false),
Description = table.Column<string>(type: "nvarchar(1024)", maxLength: 1024, nullable: true),
IsEnabled = table.Column<bool>(type: "bit", nullable: false),
IsSystem = table.Column<bool>(type: "bit", nullable: false),
IsGlobal = table.Column<bool>(type: "bit", nullable: false),
StateCheckers = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: false),
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: false),
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAIAIToolDefinitionRecords", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_AbpAIAIToolDefinitionRecords_Name",
table: "AbpAIAIToolDefinitionRecords",
column: "Name",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpAIAIToolDefinitionRecords");
migrationBuilder.DropColumn(
name: "Tools",
table: "AbpAIWorkspaceDefinitions");
}
}
}

72
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer/Migrations/SingleMigrationsDbContextModelSnapshot.cs

@ -200,6 +200,74 @@ namespace LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.Migr
b.ToTable("AbpAITokenUsages", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.AIManagement.Tools.AIToolDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("Description")
.HasMaxLength(1024)
.HasColumnType("nvarchar(1024)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsEnabled")
.HasColumnType("bit");
b.Property<bool>("IsGlobal")
.HasColumnType("bit");
b.Property<bool>("IsSystem")
.HasColumnType("bit");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("Provider")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("nvarchar(20)");
b.Property<string>("StateCheckers")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpAIAIToolDefinitionRecords", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.AIManagement.Workspaces.WorkspaceDefinitionRecord", b =>
{
b.Property<Guid>("Id")
@ -295,6 +363,10 @@ namespace LY.MicroService.Applications.Single.EntityFrameworkCore.SqlServer.Migr
b.Property<float?>("Temperature")
.HasColumnType("real");
b.Property<string>("Tools")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.HasKey("Id");
b.HasIndex("Name")

3
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore/SingleMigrationsDbContext.cs

@ -1,6 +1,7 @@
using LINGYUN.Abp.AIManagement.Chats;
using LINGYUN.Abp.AIManagement.EntityFrameworkCore;
using LINGYUN.Abp.AIManagement.Tokens;
using LINGYUN.Abp.AIManagement.Tools;
using LINGYUN.Abp.AIManagement.Workspaces;
using LINGYUN.Abp.DataProtectionManagement;
using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore;
@ -239,6 +240,8 @@ public class SingleMigrationsDbContext :
public DbSet<WorkspaceDefinitionRecord> WorkspaceDefinitions { get; set; }
public DbSet<AIToolDefinitionRecord> AIToolDefinitions { get; set; }
public DbSet<TextChatMessageRecord> TextChatMessageRecords { get; set; }
public DbSet<ConversationRecord> ConversationRecords { get; set; }

5
aspnet-core/modules/ai/LINGYUN.Abp.AI.Agent/LINGYUN/Abp/AI/Agent/AbpAIAgentOptions.cs

@ -2,15 +2,16 @@
using Microsoft.Agents.AI;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace LINGYUN.Abp.AI.Agent;
public class AbpAIAgentOptions
{
public List<Action<WorkspaceDefinition?, AIAgentBuilder>> AgentBuildActions { get; }
public List<Func<WorkspaceDefinition?, AIAgentBuilder, Task<AIAgentBuilder>>> AgentBuildActions { get; }
public List<Action<WorkspaceDefinition?, ChatClientAgentOptions>> AgentOptionActions { get; }
public AbpAIAgentOptions()
{
AgentBuildActions = new List<Action<WorkspaceDefinition?, AIAgentBuilder>>();
AgentOptionActions = new List<Action<WorkspaceDefinition?, ChatClientAgentOptions>>();
AgentBuildActions = new List<Func<WorkspaceDefinition?, AIAgentBuilder, Task<AIAgentBuilder>>>();
}
}

7
aspnet-core/modules/ai/LINGYUN.Abp.AI.Agent/LINGYUN/Abp/AI/Agent/AgentFactory.cs

@ -90,13 +90,10 @@ public class AgentFactory : IAgentFactory, IScopedDependency
foreach (var handlerAction in AgentOptions.AgentBuildActions)
{
handlerAction(workspace, aiAgentBuilder);
aiAgentBuilder = await handlerAction(workspace, aiAgentBuilder);
}
var aiAgent = aiAgentBuilder
.UseLogging()
.UseOpenTelemetry()
.Build(ServiceProvider);
var aiAgent = aiAgentBuilder.Build(ServiceProvider);
return new WorkspaceAIAgent(aiAgent, workspace);
}

4
aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/AbpAICoreOptions.cs

@ -14,7 +14,7 @@ public class AbpAICoreOptions
public ITypeList<IKernelProvider> KernelProviders { get; }
public List<Action<WorkspaceDefinition, IKernelBuilder>> KernelBuildActions { get; }
public List<Func<WorkspaceDefinition, IServiceProvider, ChatClientBuilder, Task>> ChatClientBuildActions { get; }
public List<Func<WorkspaceDefinition, IServiceProvider, ChatClientBuilder, Task<ChatClientBuilder>>> ChatClientBuildActions { get; }
public HashSet<string> DeletedWorkspaces { get; }
@ -26,6 +26,6 @@ public class AbpAICoreOptions
DeletedWorkspaces = new HashSet<string>();
KernelBuildActions = new List<Action<WorkspaceDefinition, IKernelBuilder>>();
ChatClientBuildActions = new List<Func<WorkspaceDefinition, IServiceProvider, ChatClientBuilder, Task>>();
ChatClientBuildActions = new List<Func<WorkspaceDefinition, IServiceProvider, ChatClientBuilder, Task<ChatClientBuilder>>>();
}
}

9
aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/OpenAIChatClientProvider.cs

@ -54,14 +54,9 @@ public class OpenAIChatClientProvider : ChatClientProvider
foreach (var handlerAction in options.ChatClientBuildActions)
{
await handlerAction(workspace, ServiceProvider, chatClientBuilder);
chatClientBuilder = await handlerAction(workspace, ServiceProvider, chatClientBuilder);
}
return chatClientBuilder
.UseLogging()
.UseOpenTelemetry()
.UseFunctionInvocation()
.UseDistributedCache()
.Build(ServiceProvider);
return chatClientBuilder.Build(ServiceProvider);
}
}

9
aspnet-core/modules/ai/LINGYUN.Abp.AI.Ollama/LINGYUN/Abp/AI/Ollama/OllamaChatClientProvider.cs

@ -34,15 +34,10 @@ public class OllamaChatClientProvider : ChatClientProvider
foreach (var handlerAction in options.ChatClientBuildActions)
{
await handlerAction(workspace, ServiceProvider, chatClientBuilder);
chatClientBuilder = await handlerAction(workspace, ServiceProvider, chatClientBuilder);
}
return chatClientBuilder
.UseLogging()
.UseOpenTelemetry()
.UseFunctionInvocation()
.UseDistributedCache()
.Build(ServiceProvider);
return chatClientBuilder.Build(ServiceProvider);
}
public override ChatModel[] GetModels()

50
aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/AbpAIToolsModule.cs

@ -1,9 +1,9 @@
using LINGYUN.Abp.AI.Localization;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@ -35,46 +35,20 @@ public class AbpAIToolsModule : AbpModule
{
options.ChatClientBuildActions.Add(async (workspace, sp, builder) =>
{
var useAITools = new List<AITool>();
var useAIToolDefinitions = new List<AIToolDefinition>();
var aiToolFactory = sp.GetRequiredService<IAIToolFactory>();
var aiToolDefinitionManager = sp.GetRequiredService<IAIToolDefinitionManager>();
var aiToolDefinitions = await aiToolDefinitionManager.GetAllAsync();
var workspaceAIToolFinder = sp.GetRequiredService<IWorkspaceAIToolFinder>();
var workspaceAITools = await workspaceAIToolFinder.GetToolsAsync(workspace);
if (workspace.Tools.Count > 0)
{
useAIToolDefinitions.AddRange(aiToolDefinitions.Where(aiTool => workspace.Tools.Contains(aiTool.Name)));
}
foreach (var globalAIToolDefinition in aiToolDefinitions.Where(aiTool => aiTool.IsGlobal))
{
if (!useAIToolDefinitions.Any(tool => tool.Name == globalAIToolDefinition.Name))
{
useAIToolDefinitions.Add(globalAIToolDefinition);
}
}
foreach (var aiToolDefinition in useAIToolDefinitions)
{
var aiTools = await aiToolFactory.CreateTool(aiToolDefinition);
if (aiTools.Length > 0)
return builder
.ConfigureOptions(config =>
{
useAITools.AddRange(aiTools);
}
}
config.ToolMode = ChatToolMode.Auto;
config.AllowMultipleToolCalls = true;
builder.ConfigureOptions(ai =>
{
ai.ToolMode = ChatToolMode.Auto;
ai.AllowMultipleToolCalls = true;
ai.Tools ??= [];
foreach (var aiTool in useAITools)
{
ai.Tools.Add(aiTool);
}
});
// 添加发现的工具
config.Tools = workspaceAITools;
})
// 启用以支持函数式工具
.UseFunctionInvocation();
});
});

9
aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/IWorkspaceAIToolFinder.cs

@ -0,0 +1,9 @@
using LINGYUN.Abp.AI.Workspaces;
using Microsoft.Extensions.AI;
using System.Threading.Tasks;
namespace LINGYUN.Abp.AI.Tools;
public interface IWorkspaceAIToolFinder
{
Task<AITool[]?> GetToolsAsync(WorkspaceDefinition workspace);
}

52
aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/WorkspaceAIToolFinder.cs

@ -0,0 +1,52 @@
using LINGYUN.Abp.AI.Workspaces;
using Microsoft.Extensions.AI;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.AI.Tools;
public class WorkspaceAIToolFinder : IWorkspaceAIToolFinder, ITransientDependency
{
private readonly IAIToolFactory _aiToolFactory;
private readonly IAIToolDefinitionManager _aiToolDefinitionManager;
public WorkspaceAIToolFinder(
IAIToolFactory aiToolFactory,
IAIToolDefinitionManager aiToolDefinitionManager)
{
_aiToolFactory = aiToolFactory;
_aiToolDefinitionManager = aiToolDefinitionManager;
}
public async virtual Task<AITool[]?> GetToolsAsync(WorkspaceDefinition workspace)
{
var useAITools = new List<AITool>();
var useAIToolDefinitions = new List<AIToolDefinition>();
var aiToolDefinitions = await _aiToolDefinitionManager.GetAllAsync();
if (workspace.Tools.Count > 0)
{
useAIToolDefinitions.AddRange(aiToolDefinitions.Where(aiTool => workspace.Tools.Contains(aiTool.Name)));
}
foreach (var globalAIToolDefinition in aiToolDefinitions.Where(aiTool => aiTool.IsGlobal))
{
if (!useAIToolDefinitions.Any(tool => tool.Name == globalAIToolDefinition.Name))
{
useAIToolDefinitions.Add(globalAIToolDefinition);
}
}
foreach (var aiToolDefinition in useAIToolDefinitions)
{
var aiTools = await _aiToolFactory.CreateTool(aiToolDefinition);
if (aiTools.Length > 0)
{
useAITools.AddRange(aiTools);
}
}
return useAITools.ToArray();
}
}

2
aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain.Shared/LINGYUN/Abp/AIManagement/Localization/Resources/en.json

@ -60,6 +60,6 @@
"Propertites": "Propertites",
"Tools:New": "New Tool",
"Tools:Edit": "Edit Tool",
"DesignConversationNamePrompt": "Based on the user's question, generate a concise and descriptive conversation title, with the length limited to 10 characters or less."
"DesignConversationNamePrompt": "Based on the user's question, generate a concise and descriptive conversation title, with the length limited to {0} characters or less."
}
}

2
aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain.Shared/LINGYUN/Abp/AIManagement/Localization/Resources/zh-Hans.json

@ -60,6 +60,6 @@
"Propertites": "属性",
"Tools:New": "新工具",
"Tools:Edit": "编辑工具",
"DesignConversationNamePrompt": "根据用户的提问, 生成一个简短且具有描述性的对话名称, 长度必须控制在10个字符以内."
"DesignConversationNamePrompt": "根据用户的提问, 生成一个简短且具有描述性的对话名称, 长度必须控制在 {0} 个字符以内."
}
}

28
aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Domain/LINGYUN/Abp/AIManagement/Chats/ConversationChangeNameHandler.cs

@ -3,6 +3,7 @@ using LINGYUN.Abp.AIManagement.Localization;
using LINGYUN.Abp.AIManagement.Tokens;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Localization;
using System;
using System.Globalization;
using System.Threading.Tasks;
using Volo.Abp.Data;
@ -20,6 +21,7 @@ public class ConversationChangeNameHandler :
IDistributedEventHandler<EntityCreatedEto<TextChatMessageRecordEto>>,
ITransientDependency
{
private readonly IServiceProvider _serviceProvider;
private readonly IGuidGenerator _guidGenerator;
private readonly IAbpDistributedLock _distributedLock;
private readonly IChatClientFactory _chatClientFactory;
@ -29,14 +31,16 @@ public class ConversationChangeNameHandler :
private readonly ITextChatMessageRecordRepository _textChatMessageRecordRepository;
public ConversationChangeNameHandler(
IServiceProvider serviceProvider,
IGuidGenerator guidGenerator,
IAbpDistributedLock distributedLock,
IChatClientFactory chatClientFactory,
IChatClientFactory chatClientFactory,
IStringLocalizer<AIManagementResource> stringLocalizer,
ITokenUsageRecordRepository tokenUsageRecordRepository,
IConversationRecordRepository conversationRecordRepository,
ITextChatMessageRecordRepository textChatMessageRecordRepository)
{
_serviceProvider = serviceProvider;
_guidGenerator = guidGenerator;
_distributedLock = distributedLock;
_chatClientFactory = chatClientFactory;
@ -91,19 +95,29 @@ public class ConversationChangeNameHandler :
using (CultureHelper.Use(currentCulture!))
{
var chatClient = await _chatClientFactory.CreateAsync(chatMessage.Workspace);
var instructions = _stringLocalizer["DesignConversationNamePrompt", ConversationRecordConsts.MaxNameLength].Value;
var aiAgent = chatClient
.AsBuilder()
.ConfigureOptions(options =>
{
// 不受工具影响
// 禁用工具
options.Tools = [];
})
.BuildAIAgent(_stringLocalizer["DesignConversationNamePrompt"].Value);
var agentRunRes = await aiAgent.RunAsync(chatMessage.Content);
conversation.SetName(agentRunRes.Text);
.BuildAIAgent(
instructions: instructions,
services: _serviceProvider);
var agentRunRes = await aiAgent.RunAsync([
new ChatMessage(ChatRole.System, instructions),
new ChatMessage(ChatRole.User, chatMessage.Content)]);
conversation.SetName(
agentRunRes.Text.Length > ConversationRecordConsts.MaxNameLength
? chatMessage.Content.Length > ConversationRecordConsts.MaxNameLength
? chatMessage.Content[..ConversationRecordConsts.MaxNameLength]
: chatMessage.Content
: agentRunRes.Text);
await _conversationRecordRepository.UpdateAsync(conversation);

2
aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj

@ -138,6 +138,8 @@
<ProjectReference Include="..\..\modules\account\LINGYUN.Abp.Account.HttpApi\LINGYUN.Abp.Account.HttpApi.csproj" />
<ProjectReference Include="..\..\modules\account\LINGYUN.Abp.Account.Web.OAuth\LINGYUN.Abp.Account.Web.OAuth.csproj" />
<ProjectReference Include="..\..\modules\account\LINGYUN.Abp.Account.Web.OpenIddict\LINGYUN.Abp.Account.Web.OpenIddict.csproj" />
<ProjectReference Include="..\..\modules\ai\LINGYUN.Abp.AI.Tools.Http\LINGYUN.Abp.AI.Tools.Http.csproj" />
<ProjectReference Include="..\..\modules\ai\LINGYUN.Abp.AI.Tools.Mcp\LINGYUN.Abp.AI.Tools.Mcp.csproj" />
<ProjectReference Include="..\..\modules\ai\LINGYUN.Abp.AIManagement.Application\LINGYUN.Abp.AIManagement.Application.csproj" />
<ProjectReference Include="..\..\modules\ai\LINGYUN.Abp.AIManagement.HttpApi\LINGYUN.Abp.AIManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\modules\auditing\LINGYUN.Abp.Auditing.Application.Contracts\LINGYUN.Abp.Auditing.Application.Contracts.csproj" />

29
aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs

@ -1,5 +1,9 @@
using LINGYUN.Abp.AI;
using LINGYUN.Abp.AI.Agent;
using LINGYUN.Abp.AIManagement;
using Microsoft.Agents.AI;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.AI;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling;
using VoloAbpExceptionHandlingOptions = Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingOptions;
@ -467,12 +471,37 @@ public partial class MicroServiceApplicationsSingleModule
private void ConfigureAIManagement(IConfiguration configuration)
{
Configure<AbpAICoreOptions>(options =>
{
options.ChatClientBuildActions.Add((_, __, builder) =>
{
return Task.FromResult(builder
.UseLogging()
.UseOpenTelemetry()
.UseDistributedCache());
});
});
Configure<AbpAIAgentOptions>(options =>
{
options.AgentBuildActions.Add((_, builder) =>
{
return Task.FromResult(builder
.UseLogging()
.UseOpenTelemetry());
});
});
if (configuration.GetValue<bool>("AIManagement:IsDynamicStoreEnabled"))
{
Configure<AIManagementOptions>(options =>
{
options.IsDynamicWorkspaceStoreEnabled = true;
options.SaveStaticWorkspacesToDatabase = true;
options.IsDynamicAIToolStoreEnabled = true;
options.SaveStaticAIToolsToDatabase = true;
});
}
}

6
aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs

@ -1,3 +1,5 @@
using LINGYUN.Abp.AI.Tools.Http;
using LINGYUN.Abp.AI.Tools.Mcp;
using LINGYUN.Abp.AIManagement;
using LINGYUN.Abp.SystemInfo;
@ -352,6 +354,10 @@ namespace LY.MicroService.Applications.Single;
// 微信模块 设置管理
typeof(AbpWeChatSettingManagementModule),
// AI管理模块 Http工具
typeof(AbpAIToolsHttpModule),
// AI管理模块 Mcp工具
typeof(AbpAIToolsMcpModule),
// AI管理模块 应用服务
typeof(AbpAIManagementApplicationModule),
// AI管理模块 控制器

Loading…
Cancel
Save