diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/ChatClientProvider.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/ChatClientProvider.cs index c15b7875f..fb03f68fa 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/ChatClientProvider.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/ChatClientProvider.cs @@ -1,4 +1,5 @@ -using LINGYUN.Abp.AI.Workspaces; +using LINGYUN.Abp.AI.Models; +using LINGYUN.Abp.AI.Workspaces; using Microsoft.Extensions.AI; using System; using System.Threading.Tasks; @@ -15,5 +16,7 @@ public abstract class ChatClientProvider : IChatClientProvider, ITransientDepend ServiceProvider = serviceProvider; } + public abstract ChatModel[] GetModels(); + public abstract Task CreateAsync(WorkspaceDefinition workspace); } diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/IChatClientProvider.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/IChatClientProvider.cs index bdf5aeeb7..a78f761b4 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/IChatClientProvider.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/IChatClientProvider.cs @@ -1,4 +1,5 @@ -using LINGYUN.Abp.AI.Workspaces; +using LINGYUN.Abp.AI.Models; +using LINGYUN.Abp.AI.Workspaces; using Microsoft.Extensions.AI; using System.Threading.Tasks; @@ -7,5 +8,7 @@ public interface IChatClientProvider { string Name { get; } + ChatModel[] GetModels(); + Task CreateAsync(WorkspaceDefinition workspace); } diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/DeepSeekChatClientProvider.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/DeepSeekChatClientProvider.cs index bc0863f33..d2af9d566 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/DeepSeekChatClientProvider.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/DeepSeekChatClientProvider.cs @@ -1,4 +1,5 @@ -using System; +using LINGYUN.Abp.AI.Models; +using System; namespace LINGYUN.Abp.AI.Internal; public class DeepSeekChatClientProvider : OpenAIChatClientProvider @@ -12,4 +13,12 @@ public class DeepSeekChatClientProvider : OpenAIChatClientProvider : base(serviceProvider) { } + + public override ChatModel[] GetModels() + { + return [ + new ChatModel("deepseek-chat", "DeepSeek-V3", "DeepSeek-Chat是全能高效的“快枪手”,擅长日常对话与通用任务"), + new ChatModel("deepseek-reasoner", "DeepSeek-R1", "DeepSeek-Reasoner是深思熟虑的“解题家”,专攻复杂推理与逻辑难题"), + ]; + } } diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/OpenAIChatClientProvider.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/OpenAIChatClientProvider.cs index 6f2ab1234..7e3bd4047 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/OpenAIChatClientProvider.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Internal/OpenAIChatClientProvider.cs @@ -1,4 +1,5 @@ -using LINGYUN.Abp.AI.Workspaces; +using LINGYUN.Abp.AI.Models; +using LINGYUN.Abp.AI.Workspaces; using Microsoft.Extensions.AI; using OpenAI; using System; @@ -18,6 +19,18 @@ public class OpenAIChatClientProvider : ChatClientProvider { } + public override ChatModel[] GetModels() + { + return [ + new ChatModel("gpt-4.1", "GPT-4.1", "Smartest non-reasoning model"), + new ChatModel("gpt-5", "GPT-5", "Previous intelligent reasoning model for coding and agentic tasks with configurable reasoning effort"), + new ChatModel("gpt-5-nano", "GPT-5 nano", "Fastest, most cost-efficient version of GPT-5"), + new ChatModel("gpt-5-mini", "GPT-5 mini", "Near-frontier intelligence for cost sensitive, low latency, high volume workloads"), + new ChatModel("gpt-5.4", "GPT-5.4", "Best intelligence at scale for agentic, coding, and professional workflows"), + new ChatModel("gpt-5.4-pro", "GPT-5.4 pro", "Version of GPT-5.4 that produces smarter and more precise responses."), + ]; + } + public override Task CreateAsync(WorkspaceDefinition workspace) { Check.NotNull(workspace, nameof(workspace)); diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Models/ChatModel.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Models/ChatModel.cs new file mode 100644 index 000000000..baa5a1d04 --- /dev/null +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Models/ChatModel.cs @@ -0,0 +1,14 @@ +namespace LINGYUN.Abp.AI.Models; + +public class ChatModel +{ + public string Id { get; } + public string Name { get; } + public string? Description { get; } + public ChatModel(string id, string name, string? description = null) + { + Id = id; + Name = name; + Description = description; + } +} diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Models/Conversation.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Models/Conversation.cs index 52943a7a1..e2752a3e8 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Models/Conversation.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Models/Conversation.cs @@ -5,18 +5,21 @@ public class Conversation { public Guid Id { get; private set; } public string Name { get; private set; } + public string Workspace { get; private set; } public DateTime CreatedAt { get; private set; } public DateTime? ExpiredAt { get; set; } public DateTime? UpdateAt { get; set; } public Conversation( Guid id, - string name, + string name, + string workspace, DateTime createdAt) { Id = id; Name = name; CreatedAt = createdAt; UpdateAt = createdAt; + Workspace = workspace; } public Conversation WithName(string name) diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Workspaces/Dtos/ChatClientProviderDto.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Workspaces/Dtos/ChatClientProviderDto.cs new file mode 100644 index 000000000..bbd2ea7e4 --- /dev/null +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Workspaces/Dtos/ChatClientProviderDto.cs @@ -0,0 +1,12 @@ +namespace LINGYUN.Abp.AIManagement.Workspaces.Dtos; + +public class ChatClientProviderDto +{ + public string Name { get; } + public string[] Models { get; } + public ChatClientProviderDto(string name, string[] models) + { + Name = name; + Models = models; + } +} diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Workspaces/IWorkspaceDefinitionAppService.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Workspaces/IWorkspaceDefinitionAppService.cs index 6ebb52c95..7f827538e 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Workspaces/IWorkspaceDefinitionAppService.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application.Contracts/LINGYUN/Abp/AIManagement/Workspaces/IWorkspaceDefinitionAppService.cs @@ -1,5 +1,7 @@ using LINGYUN.Abp.AIManagement.Workspaces.Dtos; using System; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace LINGYUN.Abp.AIManagement.Workspaces; @@ -11,4 +13,5 @@ public interface IWorkspaceDefinitionAppService : WorkspaceDefinitionRecordCreateDto, WorkspaceDefinitionRecordUpdateDto> { + Task> GetAvailableProvidersAsync(); } diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application/LINGYUN/Abp/AIManagement/Workspaces/WorkspaceDefinitionAppService.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application/LINGYUN/Abp/AIManagement/Workspaces/WorkspaceDefinitionAppService.cs index e249d025b..696b331b9 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application/LINGYUN/Abp/AIManagement/Workspaces/WorkspaceDefinitionAppService.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.Application/LINGYUN/Abp/AIManagement/Workspaces/WorkspaceDefinitionAppService.cs @@ -1,8 +1,13 @@ -using LINGYUN.Abp.AIManagement.Localization; +using LINGYUN.Abp.AI; +using LINGYUN.Abp.AIManagement.Localization; using LINGYUN.Abp.AIManagement.Workspaces.Dtos; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; +using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; using Volo.Abp.Data; using Volo.Abp.Security.Encryption; @@ -18,12 +23,15 @@ public class WorkspaceDefinitionAppService : WorkspaceDefinitionRecordUpdateDto>, IWorkspaceDefinitionAppService { + protected AbpAICoreOptions AIOptions { get; } protected IStringEncryptionService StringEncryptionService { get; } protected IWorkspaceDefinitionRecordRepository WorkspaceDefinitionRecordRepository { get; } public WorkspaceDefinitionAppService( + IOptions aiOptions, IStringEncryptionService stringEncryptionService, IWorkspaceDefinitionRecordRepository repository) : base(repository) { + AIOptions = aiOptions.Value; StringEncryptionService = stringEncryptionService; WorkspaceDefinitionRecordRepository = repository; @@ -31,6 +39,23 @@ public class WorkspaceDefinitionAppService : ObjectMapperContext = typeof(AbpAIManagementApplicationModule); } + public virtual Task> GetAvailableProvidersAsync() + { + var providers = AIOptions.ChatClientProviders + .Select(LazyServiceProvider.GetRequiredService) + .OfType() + .Select(provider => + { + var models = provider.GetModels(); + + return new ChatClientProviderDto( + provider.Name, + models.Select(model => model.Id).ToArray()); + }); + + return Task.FromResult(new ListResultDto(providers.ToImmutableArray())); + } + protected async override Task> CreateFilteredQueryAsync(WorkspaceDefinitionRecordGetListInput input) { var queryable = await base.CreateFilteredQueryAsync(input); @@ -40,9 +65,9 @@ public class WorkspaceDefinitionAppService : .WhereIf(!input.ModelName.IsNullOrWhiteSpace(), x => x.ModelName == input.ModelName) .WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.Provider.Contains(input.Filter!) || x.ModelName.Contains(input.Filter!) || x.DisplayName.Contains(input.Filter!) || - (!x.Description.IsNullOrWhiteSpace() && x.Description.Contains(input.Filter!)) || - (!x.SystemPrompt.IsNullOrWhiteSpace() && x.SystemPrompt.Contains(input.Filter!)) || - (!x.Instructions.IsNullOrWhiteSpace() && x.Instructions.Contains(input.Filter!))); + x.Description!.Contains(input.Filter!) || + x.SystemPrompt!.Contains(input.Filter!) || + x.Instructions!.Contains(input.Filter!)); } protected async override Task MapToEntityAsync(WorkspaceDefinitionRecordCreateDto createInput) diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/LINGYUN/Abp/AIManagement/Workspaces/WorkspaceDefinitionController.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/LINGYUN/Abp/AIManagement/Workspaces/WorkspaceDefinitionController.cs index 58444f420..0e7446fa7 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/LINGYUN/Abp/AIManagement/Workspaces/WorkspaceDefinitionController.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/LINGYUN/Abp/AIManagement/Workspaces/WorkspaceDefinitionController.cs @@ -20,6 +20,12 @@ public class WorkspaceDefinitionController : AbpControllerBase, IWorkspaceDefini _service = service; } + [HttpGet("available-providers")] + public virtual Task> GetAvailableProvidersAsync() + { + return _service.GetAvailableProvidersAsync(); + } + [HttpPost] public virtual Task CreateAsync(WorkspaceDefinitionRecordCreateDto input) {