feat: 兼容了用量使用显示
This commit is contained in:
@@ -108,33 +108,33 @@ public class AzureDatabricksChatCompletionsService(ILogger<AzureDatabricksChatCo
|
||||
continue;
|
||||
}
|
||||
|
||||
var content = result?.Choices?.FirstOrDefault()?.Delta;
|
||||
|
||||
if (first && content?.Content == OpenAIConstant.ThinkStart)
|
||||
{
|
||||
isThink = true;
|
||||
continue;
|
||||
// 需要将content的内容转换到其他字段
|
||||
}
|
||||
|
||||
if (isThink && content?.Content?.Contains(OpenAIConstant.ThinkEnd) == true)
|
||||
{
|
||||
isThink = false;
|
||||
// 需要将content的内容转换到其他字段
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isThink && result?.Choices != null)
|
||||
{
|
||||
// 需要将content的内容转换到其他字段
|
||||
foreach (var choice in result.Choices)
|
||||
{
|
||||
choice.Delta.ReasoningContent = choice.Delta.Content;
|
||||
choice.Delta.Content = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
first = false;
|
||||
// var content = result?.Choices?.FirstOrDefault()?.Delta;
|
||||
//
|
||||
// if (first && content?.Content == OpenAIConstant.ThinkStart)
|
||||
// {
|
||||
// isThink = true;
|
||||
// continue;
|
||||
// // 需要将content的内容转换到其他字段
|
||||
// }
|
||||
//
|
||||
// if (isThink && content?.Content?.Contains(OpenAIConstant.ThinkEnd) == true)
|
||||
// {
|
||||
// isThink = false;
|
||||
// // 需要将content的内容转换到其他字段
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (isThink && result?.Choices != null)
|
||||
// {
|
||||
// // 需要将content的内容转换到其他字段
|
||||
// foreach (var choice in result.Choices)
|
||||
// {
|
||||
// choice.Delta.ReasoningContent = choice.Delta.Content;
|
||||
// choice.Delta.Content = string.Empty;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// first = false;
|
||||
|
||||
yield return result;
|
||||
}
|
||||
|
||||
@@ -93,36 +93,36 @@ public sealed class DeepSeekChatCompletionsService(ILogger<DeepSeekChatCompletio
|
||||
var result = JsonSerializer.Deserialize<ThorChatCompletionsResponse>(line,
|
||||
ThorJsonSerializer.DefaultOptions);
|
||||
|
||||
var content = result?.Choices?.FirstOrDefault()?.Delta;
|
||||
|
||||
if (first && string.IsNullOrWhiteSpace(content?.Content) && string.IsNullOrEmpty(content?.ReasoningContent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (first && content.Content == OpenAIConstant.ThinkStart)
|
||||
{
|
||||
isThink = true;
|
||||
//continue;
|
||||
// 需要将content的内容转换到其他字段
|
||||
}
|
||||
|
||||
if (isThink && content.Content.Contains(OpenAIConstant.ThinkEnd))
|
||||
{
|
||||
isThink = false;
|
||||
// 需要将content的内容转换到其他字段
|
||||
//continue;
|
||||
}
|
||||
|
||||
if (isThink)
|
||||
{
|
||||
// 需要将content的内容转换到其他字段
|
||||
foreach (var choice in result.Choices)
|
||||
{
|
||||
//choice.Delta.ReasoningContent = choice.Delta.Content;
|
||||
//choice.Delta.Content = string.Empty;
|
||||
}
|
||||
}
|
||||
// var content = result?.Choices?.FirstOrDefault()?.Delta;
|
||||
//
|
||||
// // if (first && string.IsNullOrWhiteSpace(content?.Content) && string.IsNullOrEmpty(content?.ReasoningContent))
|
||||
// // {
|
||||
// // continue;
|
||||
// // }
|
||||
//
|
||||
// if (first && content.Content == OpenAIConstant.ThinkStart)
|
||||
// {
|
||||
// isThink = true;
|
||||
// //continue;
|
||||
// // 需要将content的内容转换到其他字段
|
||||
// }
|
||||
//
|
||||
// if (isThink && content.Content.Contains(OpenAIConstant.ThinkEnd))
|
||||
// {
|
||||
// isThink = false;
|
||||
// // 需要将content的内容转换到其他字段
|
||||
// //continue;
|
||||
// }
|
||||
//
|
||||
// if (isThink)
|
||||
// {
|
||||
// // 需要将content的内容转换到其他字段
|
||||
// foreach (var choice in result.Choices)
|
||||
// {
|
||||
// //choice.Delta.ReasoningContent = choice.Delta.Content;
|
||||
// //choice.Delta.Content = string.Empty;
|
||||
// }
|
||||
// }
|
||||
|
||||
// first = false;
|
||||
|
||||
|
||||
@@ -29,10 +29,18 @@ public class MessageAggregateRoot : FullAuditedAggregateRoot<Guid>
|
||||
ModelId = modelId;
|
||||
if (tokenUsage is not null)
|
||||
{
|
||||
long inputTokenCount = tokenUsage.PromptTokens
|
||||
?? tokenUsage.InputTokens
|
||||
?? 0;
|
||||
|
||||
long outputTokenCount = tokenUsage.CompletionTokens
|
||||
?? tokenUsage.OutputTokens
|
||||
?? 0;
|
||||
|
||||
this.TokenUsage = new TokenUsageValueObject
|
||||
{
|
||||
OutputTokenCount = tokenUsage.OutputTokens ?? 0,
|
||||
InputTokenCount = tokenUsage.InputTokens ?? 0,
|
||||
OutputTokenCount = outputTokenCount,
|
||||
InputTokenCount = inputTokenCount,
|
||||
TotalTokenCount = tokenUsage.TotalTokens ?? 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -37,22 +37,22 @@ public class UsageStatisticsAggregateRoot : FullAuditedAggregateRoot<Guid>
|
||||
/// <summary>
|
||||
/// 使用输出token总数
|
||||
/// </summary>
|
||||
public int UsageOutputTokenCount { get; set; }
|
||||
public long UsageOutputTokenCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用输入总数
|
||||
/// </summary>
|
||||
public int UsageInputTokenCount { get; set; }
|
||||
public long UsageInputTokenCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总token使用数量
|
||||
/// </summary>
|
||||
public int TotalTokenCount { get; set; }
|
||||
public long TotalTokenCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 新增一次聊天统计
|
||||
/// </summary>
|
||||
public void AddOnceChat(int inputTokenCount, int outputTokenCount)
|
||||
public void AddOnceChat(long inputTokenCount, long outputTokenCount)
|
||||
{
|
||||
UsageTotalNumber += 1;
|
||||
UsageOutputTokenCount += outputTokenCount;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
public class TokenUsageValueObject
|
||||
{
|
||||
public int OutputTokenCount { get; set; }
|
||||
public long OutputTokenCount { get; set; }
|
||||
|
||||
public int InputTokenCount { get; set; }
|
||||
public long InputTokenCount { get; set; }
|
||||
|
||||
public long TotalTokenCount { get; set; }
|
||||
}
|
||||
@@ -132,8 +132,7 @@ public class AiGateWayManager : DomainService
|
||||
TokenUsage = data.Usage
|
||||
});
|
||||
|
||||
await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, data.Usage.InputTokens ?? 0,
|
||||
data.Usage.OutputTokens ?? 0);
|
||||
await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, data.Usage);
|
||||
}
|
||||
|
||||
await response.WriteAsJsonAsync(data, cancellationToken);
|
||||
@@ -200,7 +199,7 @@ public class AiGateWayManager : DomainService
|
||||
{
|
||||
await foreach (var data in completeChatResponse)
|
||||
{
|
||||
if (data.Usage is not null && data.Usage.TotalTokens is not null)
|
||||
if (data.Usage is not null)
|
||||
{
|
||||
tokenUsage = data.Usage;
|
||||
}
|
||||
@@ -261,8 +260,7 @@ public class AiGateWayManager : DomainService
|
||||
TokenUsage = tokenUsage
|
||||
});
|
||||
|
||||
await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, tokenUsage.InputTokens ?? 0,
|
||||
tokenUsage.OutputTokens ?? 0);
|
||||
await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, tokenUsage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Medallion.Threading;
|
||||
using Volo.Abp.Domain.Services;
|
||||
using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
using Yi.Framework.AiHub.Domain.Entities;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
@@ -17,8 +18,16 @@ public class UsageStatisticsManager : DomainService
|
||||
private IDistributedLockProvider DistributedLock =>
|
||||
LazyServiceProvider.LazyGetRequiredService<IDistributedLockProvider>();
|
||||
|
||||
public async Task SetUsageAsync(Guid userId, string modelId, int inputTokenCount, int outputTokenCount)
|
||||
public async Task SetUsageAsync(Guid userId, string modelId, ThorUsageResponse? tokenUsage)
|
||||
{
|
||||
long inputTokenCount = tokenUsage?.PromptTokens
|
||||
?? tokenUsage.InputTokens
|
||||
?? 0;
|
||||
|
||||
long outputTokenCount = tokenUsage?.CompletionTokens
|
||||
?? tokenUsage.OutputTokens
|
||||
?? 0;
|
||||
|
||||
await using (await DistributedLock.AcquireLockAsync($"UsageStatistics:{userId.ToString()}"))
|
||||
{
|
||||
var entity = await _repository._DbQueryable.FirstAsync(x => x.UserId == userId && x.ModelId == modelId);
|
||||
@@ -37,8 +46,4 @@ public class UsageStatisticsManager : DomainService
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class LazyServiceProvider
|
||||
{
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Volo.Abp.Domain;
|
||||
using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi;
|
||||
using Yi.Framework.AiHub.Domain.AiGateWay;
|
||||
using Yi.Framework.AiHub.Domain.AiGateWay.Impl.ThorAzureDatabricks.Chats;
|
||||
using Yi.Framework.AiHub.Domain.AiGateWay.Impl.ThorAzureOpenAI.Chats;
|
||||
@@ -48,6 +49,16 @@ namespace Yi.Framework.AiHub.Domain
|
||||
request.Temperature = null;
|
||||
}
|
||||
});
|
||||
options.Handles.Add(request =>
|
||||
{
|
||||
if (request.Stream == true)
|
||||
{
|
||||
request.StreamOptions = new ThorStreamOptions()
|
||||
{
|
||||
IncludeUsage = true
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user