feat: 支持非流式传输
This commit is contained in:
@@ -9,11 +9,13 @@ using Newtonsoft.Json.Serialization;
|
||||
using OpenAI.Chat;
|
||||
using Volo.Abp.Domain.Services;
|
||||
using Yi.Framework.AiHub.Application.Contracts.Dtos;
|
||||
using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
using Yi.Framework.AiHub.Domain.AiChat;
|
||||
using Yi.Framework.AiHub.Domain.Entities;
|
||||
using Yi.Framework.AiHub.Domain.Entities.Model;
|
||||
using Yi.Framework.AiHub.Domain.Shared.Dtos;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
using Usage = Yi.Framework.AiHub.Application.Contracts.Dtos.Usage;
|
||||
|
||||
namespace Yi.Framework.AiHub.Domain.Managers;
|
||||
|
||||
@@ -107,7 +109,7 @@ public class AiGateWayManager : DomainService
|
||||
await using var writer = new StreamWriter(response.Body, Encoding.UTF8, leaveOpen: true);
|
||||
var modelDescribe = await GetModelAsync(modelId);
|
||||
var chatService = LazyServiceProvider.GetRequiredKeyedService<IChatService>(modelDescribe.HandlerName);
|
||||
var output = await chatService.CompleteChatAsync(modelDescribe, messages, cancellationToken);
|
||||
var data = await chatService.CompleteChatAsync(modelDescribe, messages, cancellationToken);
|
||||
if (userId is not null)
|
||||
{
|
||||
await _aiMessageManager.CreateUserMessageAsync(userId.Value, sessionId,
|
||||
@@ -115,22 +117,23 @@ public class AiGateWayManager : DomainService
|
||||
{
|
||||
Content = messages.LastOrDefault().Content.FirstOrDefault()?.Text ?? string.Empty,
|
||||
ModelId = modelId,
|
||||
TokenUsage = output.TokenUsage,
|
||||
TokenUsage = data.TokenUsage,
|
||||
});
|
||||
|
||||
await _aiMessageManager.CreateSystemMessageAsync(userId.Value, sessionId,
|
||||
new MessageInputDto
|
||||
{
|
||||
Content = output.Content,
|
||||
Content = data.Content,
|
||||
ModelId = modelId,
|
||||
TokenUsage = output.TokenUsage
|
||||
TokenUsage = data.TokenUsage
|
||||
});
|
||||
|
||||
await _usageStatisticsManager.SetUsageAsync(userId.Value, modelId, output.TokenUsage.InputTokenCount,
|
||||
output.TokenUsage.OutputTokenCount);
|
||||
await _usageStatisticsManager.SetUsageAsync(userId.Value, modelId, data.TokenUsage.InputTokenCount,
|
||||
data.TokenUsage.OutputTokenCount);
|
||||
}
|
||||
|
||||
var body = JsonConvert.SerializeObject(output, new JsonSerializerSettings
|
||||
var result = MapToChatCompletions(modelId, data.Content);
|
||||
var body = JsonConvert.SerializeObject(result, new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
});
|
||||
@@ -261,9 +264,9 @@ public class AiGateWayManager : DomainService
|
||||
}
|
||||
|
||||
|
||||
private SendMessageOutputDto MapToMessage(string modelId, string content)
|
||||
private SendMessageStreamOutputDto MapToMessage(string modelId, string content)
|
||||
{
|
||||
var output = new SendMessageOutputDto
|
||||
var output = new SendMessageStreamOutputDto
|
||||
{
|
||||
Id = "chatcmpl-BotYP3BlN5T4g9YPnW0fBSBvKzXdd",
|
||||
Object = "chat.completion.chunk",
|
||||
@@ -338,4 +341,75 @@ public class AiGateWayManager : DomainService
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private ChatCompletionsOutput MapToChatCompletions(string modelId, string content)
|
||||
{
|
||||
return new ChatCompletionsOutput
|
||||
{
|
||||
Id = "resp_67ccd2bed1ec8190b14f964abc0542670bb6a6b452d3795b",
|
||||
Object = "response",
|
||||
CreatedAt = 1741476542,
|
||||
Status = "completed",
|
||||
Error = null,
|
||||
IncompleteDetails = null,
|
||||
Instructions = null,
|
||||
MaxOutputTokens = null,
|
||||
Model = modelId,
|
||||
Output = new List<Output>()
|
||||
{
|
||||
new Output
|
||||
{
|
||||
Type = "message",
|
||||
Id = "msg_67ccd2bf17f0819081ff3bb2cf6508e60bb6a6b452d3795b",
|
||||
Status = "completed",
|
||||
Role = "assistant",
|
||||
Content = new List<Content>
|
||||
{
|
||||
new Content
|
||||
{
|
||||
Type = "output_text",
|
||||
Text = content,
|
||||
Annotations = new List<object>()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ParallelToolCalls = true,
|
||||
PreviousResponseId = null,
|
||||
Reasoning = new Reasoning
|
||||
{
|
||||
Effort = null,
|
||||
Summary = null
|
||||
},
|
||||
Store = true,
|
||||
Temperature = 0,
|
||||
Text = new Text
|
||||
{
|
||||
Format = new Format
|
||||
{
|
||||
Type = "text"
|
||||
}
|
||||
},
|
||||
ToolChoice = "auto",
|
||||
Tools = new List<object>(),
|
||||
TopP = 1.0,
|
||||
Truncation = "disabled",
|
||||
Usage = new Application.Contracts.Dtos.OpenAi.Usage
|
||||
{
|
||||
InputTokens = 0,
|
||||
InputTokensDetails = new InputTokensDetails
|
||||
{
|
||||
CachedTokens = 0
|
||||
},
|
||||
OutputTokens = 0,
|
||||
OutputTokensDetails = new OutputTokensDetails
|
||||
{
|
||||
ReasoningTokens = 0
|
||||
},
|
||||
TotalTokens = 0
|
||||
},
|
||||
User = null,
|
||||
Metadata = null
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user