diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/MessageCreatedOutput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/MessageCreatedOutput.cs
new file mode 100644
index 00000000..e0ec14f7
--- /dev/null
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/MessageCreatedOutput.cs
@@ -0,0 +1,47 @@
+using System.Reflection;
+using System.Text.Json.Serialization;
+
+namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Chat;
+
+///
+/// 消息创建结果输出
+///
+public class MessageCreatedOutput
+{
+ ///
+ /// 消息类型
+ ///
+ [JsonIgnore]
+ public ChatMessageTypeEnum TypeEnum { get; set; }
+
+ ///
+ /// 消息类型
+ ///
+ public string Type => TypeEnum.ToString();
+
+ ///
+ /// 消息ID
+ ///
+ public Guid MessageId { get; set; }
+
+ ///
+ /// 消息创建时间
+ ///
+ public DateTime CreationTime { get; set; }
+}
+
+///
+/// 消息类型枚举
+///
+public enum ChatMessageTypeEnum
+{
+ ///
+ /// 用户消息
+ ///
+ UserMessage,
+
+ ///
+ /// 系统消息
+ ///
+ SystemMessage
+}
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs
index 0feb8e26..f789241a 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs
@@ -23,6 +23,7 @@ using Yi.Framework.AiHub.Domain.Shared.Dtos.OpenAi.Embeddings;
using Yi.Framework.AiHub.Domain.Shared.Dtos.OpenAi.Images;
using Yi.Framework.AiHub.Domain.Shared.Dtos.OpenAi.Responses;
using Yi.Framework.AiHub.Domain.Shared.Enums;
+using Yi.Framework.AiHub.Application.Contracts.Dtos.Chat;
using Yi.Framework.AiHub.Domain.Shared.Extensions;
using Yi.Framework.Core.Extensions;
using Yi.Framework.SqlSugarCore.Abstractions;
@@ -1207,12 +1208,9 @@ public class AiGateWayManager : DomainService
throw new UserFriendlyException($"不支持的API类型: {apiType}");
}
- // 标记完成并等待消费任务结束
- isComplete = true;
- await outputTask;
-
+
// 统一的统计处理
- await _aiMessageManager.CreateUserMessageAsync(userId, sessionId,
+ var userMessageId = await _aiMessageManager.CreateUserMessageAsync(userId, sessionId,
new MessageInputDto
{
Content = sessionId is null ? "不予存储" : processResult?.UserContent ?? string.Empty,
@@ -1220,7 +1218,7 @@ public class AiGateWayManager : DomainService
TokenUsage = processResult?.TokenUsage,
}, tokenId,createTime:startTime);
- await _aiMessageManager.CreateSystemMessageAsync(userId, sessionId,
+ var systemMessageId = await _aiMessageManager.CreateSystemMessageAsync(userId, sessionId,
new MessageInputDto
{
Content = sessionId is null ? "不予存储" : processResult?.SystemContent ?? string.Empty,
@@ -1228,6 +1226,29 @@ public class AiGateWayManager : DomainService
TokenUsage = processResult?.TokenUsage
}, tokenId);
+ // 流式返回消息ID
+ var now = DateTime.Now;
+ var userMessageOutput = new MessageCreatedOutput
+ {
+ TypeEnum = ChatMessageTypeEnum.UserMessage,
+ MessageId = userMessageId,
+ CreationTime = startTime
+ };
+ messageQueue.Enqueue($"data: {JsonSerializer.Serialize(userMessageOutput, ThorJsonSerializer.DefaultOptions)}\n\n");
+
+ var systemMessageOutput = new MessageCreatedOutput
+ {
+ TypeEnum = ChatMessageTypeEnum.SystemMessage,
+ MessageId = systemMessageId,
+ CreationTime = now
+ };
+ messageQueue.Enqueue($"data: {JsonSerializer.Serialize(systemMessageOutput, ThorJsonSerializer.DefaultOptions)}\n\n");
+
+ // 标记完成并等待消费任务结束
+ messageQueue.Enqueue("data: [DONE]\n\n");
+ isComplete = true;
+ await outputTask;
+
await _usageStatisticsManager.SetUsageAsync(userId, sourceModelId, processResult?.TokenUsage, tokenId);
// 扣减尊享token包用量
@@ -1325,8 +1346,7 @@ public class AiGateWayManager : DomainService
});
messageQueue.Enqueue($"data: {errorMessage}\n\n");
}
-
- messageQueue.Enqueue("data: [DONE]\n\n");
+
return new StreamProcessResult
{
UserContent = userContent,
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiMessageManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiMessageManager.cs
index b8310d66..90509246 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiMessageManager.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiMessageManager.cs
@@ -24,11 +24,12 @@ public class AiMessageManager : DomainService
/// 消息输入
/// Token Id(Web端传Guid.Empty)
///
- public async Task CreateSystemMessageAsync(Guid? userId, Guid? sessionId, MessageInputDto input, Guid? tokenId = null)
+ public async Task CreateSystemMessageAsync(Guid? userId, Guid? sessionId, MessageInputDto input, Guid? tokenId = null)
{
input.Role = "system";
var message = new MessageAggregateRoot(userId, sessionId, input.Content, input.Role, input.ModelId, input.TokenUsage, tokenId);
await _repository.InsertAsync(message);
+ return message.Id;
}
///
@@ -40,7 +41,7 @@ public class AiMessageManager : DomainService
/// Token Id(Web端传Guid.Empty)
///
///
- public async Task CreateUserMessageAsync( Guid? userId, Guid? sessionId, MessageInputDto input, Guid? tokenId = null,DateTime? createTime=null)
+ public async Task CreateUserMessageAsync( Guid? userId, Guid? sessionId, MessageInputDto input, Guid? tokenId = null,DateTime? createTime=null)
{
input.Role = "user";
var message = new MessageAggregateRoot(userId, sessionId, input.Content, input.Role, input.ModelId, input.TokenUsage, tokenId)
@@ -48,5 +49,6 @@ public class AiMessageManager : DomainService
CreationTime = createTime??DateTime.Now
};
await _repository.InsertAsync(message);
+ return message.Id;
}
}
\ No newline at end of file