feat: 新增openai对接接口

This commit is contained in:
chenchun
2024-07-19 18:17:36 +08:00
parent 58d1b62250
commit a0478279df
10 changed files with 146 additions and 5 deletions

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.ChatHub.Application.Dtos
{
public class AiChatContextDto
{
public AnswererTypeEnum AnswererType { get; set; }
public string Message { get; set; }
public int Number { get; set; }
}
public enum AnswererTypeEnum
{
Ai,
User
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Volo.Abp.Application.Services;
using Yi.Framework.ChatHub.Domain.Managers;
using Yi.Framework.ChatHub.Domain.Shared.Model;
using Yi.Framework.ChatHub.Domain.SignalRHubs;
namespace Yi.Framework.ChatHub.Application.Services
{
public class AiChatService : ApplicationService
{
private readonly AiManager _aiManager;
private readonly UserMessageManager _userMessageManager;
public AiChatService(AiManager aiManager, UserMessageManager userMessageManager) { _aiManager = aiManager; _userMessageManager = userMessageManager; }
[Authorize]
[HttpPost]
public async Task ChatAsync()
{
await foreach (var aiResult in _aiManager.ChatAsStreamAsync())
{
await _userMessageManager.SendMessageAsync(MessageContext.CreateAi(aiResult, CurrentUser.Id!.Value));
}
}
}
}

View File

@@ -9,7 +9,7 @@ namespace Yi.Framework.ChatHub.Domain.Shared.Enums
public enum MessageTypeEnum
{
Ai,
Personal,
Group,
All

View File

@@ -41,6 +41,12 @@ namespace Yi.Framework.ChatHub.Domain.Shared.Model
return new MessageContext() { MessageType = MessageTypeEnum.Personal, Content = content, ReceiveId = userId, SendUserId = sendUserId };
}
public static MessageContext CreateAi(string content, Guid receiveId)
{
return new MessageContext() { MessageType = MessageTypeEnum.Ai, Content = content, ReceiveId = receiveId };
}
public static MessageContext CreateAll(string content, Guid sendUserId)
{
return new MessageContext() { MessageType = MessageTypeEnum.All, Content = content, SendUserId = sendUserId };

View File

@@ -0,0 +1,8 @@
namespace Yi.Framework.ChatHub.Domain.Shared.Options
{
public class AiOptions
{
public string ApiKey { get; set; }
public string BaseDomain { get; set; }
}
}

View File

@@ -1,5 +1,7 @@
using Volo.Abp.Domain;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Domain;
using Yi.Framework.Bbs.Domain.Shared;
using Yi.Framework.ChatHub.Domain.Shared.Options;
namespace Yi.Framework.ChatHub.Domain.Shared
{
@@ -9,6 +11,10 @@ namespace Yi.Framework.ChatHub.Domain.Shared
typeof(YiFrameworkBbsDomainSharedModule))]
public class YiFrameworkChatHubDomainSharedModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AiOptions>(configuration.GetSection("AiOptions"));
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using OpenAI;
using OpenAI.Managers;
using OpenAI.ObjectModels;
using OpenAI.ObjectModels.RequestModels;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Services;
using Yi.Framework.ChatHub.Domain.Shared.Options;
namespace Yi.Framework.ChatHub.Domain.Managers
{
public class AiManager : DomainService, ISingletonDependency
{
public AiManager(IOptions<AiOptions> options)
{
this.OpenAIService = new OpenAIService(new OpenAiOptions()
{
ApiKey = options.Value.ApiKey,
BaseDomain = options.Value.BaseDomain
});
}
private OpenAIService OpenAIService { get; }
public async IAsyncEnumerable<string> ChatAsStreamAsync()
{
var completionResult = OpenAIService.ChatCompletion.CreateCompletionAsStream(new ChatCompletionCreateRequest
{
Messages = new List<ChatMessage>
{
ChatMessage.FromUser("特朗普是谁?"),
},
Model = Models.Gpt_4,
});
await foreach (var result in completionResult)
{
if (result.Successful)
{
yield return result.Choices.FirstOrDefault()?.Message.Content??string.Empty;
}
}
}
}
}

View File

@@ -48,6 +48,14 @@ namespace Yi.Framework.ChatHub.Domain.Managers
case MessageTypeEnum.All:
await _hubContext.Clients.All.SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context);
break;
case MessageTypeEnum.Ai:
var userModel2 = await GetUserAsync(context.ReceiveId.Value);
if (userModel2 is not null)
{
await _hubContext.Clients.Client(userModel2.ClientId).SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context);
}
break;
default:
break;
}

View File

@@ -7,7 +7,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Betalgo.OpenAI" Version="8.6.1" />
<PackageReference Include="Volo.Abp.AspNetCore.SignalR" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="$(AbpVersion)" />

View File

@@ -87,5 +87,12 @@
//开启定时数据库备份
"EnableDataBaseBackup": false
},
//OpenAi
"AiOptions": {
"ApiKey": "",
"BaseDomain": ""
}
}