feat: Thor搭建

This commit is contained in:
ccnetcore
2025-07-17 23:10:26 +08:00
parent 10f7499066
commit e593f2cba4
54 changed files with 2526 additions and 867 deletions

View File

@@ -12,6 +12,7 @@ using OpenAI.Chat;
using Volo.Abp.Application.Services;
using Volo.Abp.Users;
using Yi.Framework.AiHub.Application.Contracts.Dtos;
using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
using Yi.Framework.AiHub.Domain.Entities;
using Yi.Framework.AiHub.Domain.Entities.Model;
using Yi.Framework.AiHub.Domain.Extensions;
@@ -92,7 +93,8 @@ public class AiChatService : ApplicationService
/// </summary>
/// <param name="input"></param>
/// <param name="cancellationToken"></param>
public async Task PostSendAsync(SendMessageInput input, CancellationToken cancellationToken)
public async Task PostSendAsync([FromBody] ThorChatCompletionsRequest input, [FromQuery] Guid sessionId,
CancellationToken cancellationToken)
{
//除了免费模型,其他的模型都要校验
if (!input.Model.Contains("DeepSeek-R1"))
@@ -111,22 +113,8 @@ public class AiChatService : ApplicationService
throw new UserFriendlyException("未登录用户只能使用未加速的DeepSeek-R1请登录后重试");
}
}
var history = new List<ChatMessage>();
foreach (var aiChatContextDto in input.Messages)
{
if (aiChatContextDto.Role == "assistant")
{
history.Add(ChatMessage.CreateAssistantMessage(aiChatContextDto.Content));
}
else if (aiChatContextDto.Role == "user")
{
history.Add(ChatMessage.CreateUserMessage(aiChatContextDto.Content));
}
}
//ai网关代理httpcontext
await _aiGateWayManager.CompleteChatStreamForStatisticsAsync(_httpContextAccessor.HttpContext, input.Model, history,
CurrentUser.Id, input.SessionId, cancellationToken);
await _aiGateWayManager.CompleteChatStreamForStatisticsAsync(_httpContextAccessor.HttpContext, input,
CurrentUser.Id, sessionId, cancellationToken);
}
}

View File

@@ -1,12 +1,10 @@
using Dm.util;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using OpenAI.Chat;
using SqlSugar;
using Volo.Abp.Application.Services;
using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAiDto;
using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
using Yi.Framework.AiHub.Domain.Entities.Model;
using Yi.Framework.AiHub.Domain.Extensions;
using Yi.Framework.AiHub.Domain.Managers;
using Yi.Framework.SqlSugarCore.Abstractions;
@@ -37,45 +35,22 @@ public class OpenApiService : ApplicationService
/// <param name="input"></param>
/// <param name="cancellationToken"></param>
[HttpPost("openApi/v1/chat/completions")]
public async Task ChatCompletionsAsync([FromBody] ChatCompletionsInput input, CancellationToken cancellationToken)
public async Task ChatCompletionsAsync([FromBody] ThorChatCompletionsRequest input,
CancellationToken cancellationToken)
{
//前面都是校验,后面才是真正的调用
var httpContext = this._httpContextAccessor.HttpContext;
var userId = await _tokenManager.GetUserIdAsync(GetTokenByHttpContext(httpContext));
var history = new List<ChatMessage>();
if (!string.IsNullOrWhiteSpace(input.Prompt))
{
history.add(ChatMessage.CreateSystemMessage(input.Prompt));
}
foreach (var aiChatContextDto in input.Messages)
{
if (aiChatContextDto.Role == "assistant")
{
history.Add(ChatMessage.CreateAssistantMessage(aiChatContextDto.ConvertContent()));
}
else if (aiChatContextDto.Role == "user")
{
history.Add(ChatMessage.CreateUserMessage(aiChatContextDto.ConvertContent()));
}
else if (aiChatContextDto.Role == "system")
{
history.Add(ChatMessage.CreateSystemMessage(aiChatContextDto.ConvertContent()));
}
}
//是否使用流式传输
//ai网关代理httpcontext
if (input.Stream == true)
{
//ai网关代理httpcontext
await _aiGateWayManager.CompleteChatStreamForStatisticsAsync(_httpContextAccessor.HttpContext, input.Model,
history,
await _aiGateWayManager.CompleteChatStreamForStatisticsAsync(_httpContextAccessor.HttpContext, input,
userId, null, cancellationToken);
}
else
{
await _aiGateWayManager.CompleteChatForStatisticsAsync(_httpContextAccessor.HttpContext, input.Model,
history, userId, null,
await _aiGateWayManager.CompleteChatForStatisticsAsync(_httpContextAccessor.HttpContext, input, userId,
null,
cancellationToken);
}
}
@@ -85,19 +60,20 @@ public class OpenApiService : ApplicationService
/// </summary>
/// <returns></returns>
[HttpGet("openApi/v1/models")]
public async Task<ModelGetOutput> ModelsAsync()
public async Task<ModelsListDto> ModelsAsync()
{
var data = await _aiModelRepository._DbQueryable
.OrderByDescending(x => x.OrderNum)
.Select(x => new ModelDataOutput
.Select(x => new ModelsDataDto
{
ModelId = x.ModelId,
Object = "model",
Owned_by = "organization-owner",
Permission = new List<string>()
Id = x.ModelId,
@object = "model",
Created = DateTime.Now.ToUnixTimeSeconds(),
OwnedBy = "organization-owner",
Type = x.ModelId
}).ToListAsync();
return new ModelGetOutput()
return new ModelsListDto()
{
Data = data
};