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