Merge pull request #1024 from iceljc/features/refactor-llm-cost
Features/refactor llm cost
This commit is contained in:
commit
4de62cb41e
|
|
@ -5,8 +5,14 @@ public class TokenStatsModel
|
|||
public string Provider { get; set; }
|
||||
public string Model { get; set; }
|
||||
public string Prompt { get; set; }
|
||||
public int PromptCount { get; set; }
|
||||
public int CachedPromptCount { get; set; }
|
||||
public int CompletionCount { get; set; }
|
||||
public int TextInputTokens { get; set; }
|
||||
public int CachedTextInputTokens { get; set; }
|
||||
public int AudioInputTokens { get; set; }
|
||||
public int CachedAudioInputTokens { get; set; }
|
||||
public int TextOutputTokens { get; set; }
|
||||
public int AudioOutputTokens { get; set; }
|
||||
public AgentLlmConfig LlmConfig { get; set; }
|
||||
|
||||
public int TotalInputTokens => TextInputTokens + CachedTextInputTokens + AudioInputTokens + CachedAudioInputTokens;
|
||||
public int TotalOutputTokens => TextOutputTokens + AudioOutputTokens;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,22 +42,12 @@ public class LlmModelSetting
|
|||
/// </summary>
|
||||
public bool ImageGeneration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prompt cost per 1K token
|
||||
/// </summary>
|
||||
public float PromptCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Completion cost per 1K token
|
||||
/// </summary>
|
||||
public float CompletionCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Embedding dimension
|
||||
/// </summary>
|
||||
public int Dimension { get; set; }
|
||||
|
||||
public LlmCost AdditionalCost { get; set; } = new();
|
||||
public LlmCost Cost { get; set; } = new();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
|
@ -65,12 +55,20 @@ public class LlmModelSetting
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cost per 1K tokens
|
||||
/// </summary>
|
||||
public class LlmCost
|
||||
{
|
||||
public float CachedPromptCost { get; set; } = 0f;
|
||||
public float AudioPromptCost { get; set; } = 0f;
|
||||
public float ReasoningCompletionCost { get; } = 0f;
|
||||
public float AudioCompletionCost { get; } = 0f;
|
||||
// Input
|
||||
public float TextInputCost { get; set; } = 0f;
|
||||
public float CachedTextInputCost { get; set; } = 0f;
|
||||
public float AudioInputCost { get; set; } = 0f;
|
||||
public float CachedAudioInputCost { get; set; } = 0f;
|
||||
|
||||
// Output
|
||||
public float TextOutputCost { get; set; } = 0f;
|
||||
public float AudioOutputCost { get; set; } = 0f;
|
||||
}
|
||||
|
||||
public enum LlmModelType
|
||||
|
|
|
|||
|
|
@ -35,28 +35,33 @@ public class TokenStatistics : ITokenStatistics
|
|||
public void AddToken(TokenStatsModel stats, RoleDialogModel message)
|
||||
{
|
||||
_model = stats.Model;
|
||||
_promptTokenCount += stats.PromptCount;
|
||||
_completionTokenCount += stats.CompletionCount;
|
||||
_promptTokenCount += stats.TotalInputTokens;
|
||||
_completionTokenCount += stats.TotalOutputTokens;
|
||||
|
||||
var settingsService = _services.GetRequiredService<ILlmProviderService>();
|
||||
var settings = settingsService.GetSetting(stats.Provider, _model);
|
||||
|
||||
var deltaPromptCost = (stats.PromptCount - stats.CachedPromptCount) / 1000f * settings.PromptCost;
|
||||
var deltaCachedPromptCost = stats.CachedPromptCount / 1000f * (settings.AdditionalCost?.CachedPromptCost ?? 0f);
|
||||
var deltaCompletionCost = stats.CompletionCount / 1000f * settings.CompletionCost;
|
||||
var deltaTextInputCost = stats.TextInputTokens / 1000f * (settings.Cost?.TextInputCost ?? 0f);
|
||||
var deltaCachedTextInputCost = stats.CachedTextInputTokens / 1000f * (settings.Cost?.CachedTextInputCost ?? 0f);
|
||||
var deltaAudioInputCost = stats.AudioInputTokens / 1000f * (settings.Cost?.AudioInputCost ?? 0f);
|
||||
var deltaCachedAudioInputCost = stats.CachedAudioInputTokens / 1000f * (settings.Cost?.CachedAudioInputCost ?? 0f);
|
||||
|
||||
var deltaTotal = deltaPromptCost + deltaCachedPromptCost + deltaCompletionCost;
|
||||
var deltaTextOutputCost = stats.TextOutputTokens / 1000f * (settings.Cost?.TextOutputCost ?? 0f);
|
||||
var deltaAudioOutputCost = stats.AudioOutputTokens / 1000f * (settings.Cost?.AudioOutputCost ?? 0f);
|
||||
|
||||
var deltaPromptCost = deltaTextInputCost + deltaCachedTextInputCost + deltaAudioInputCost + deltaCachedAudioInputCost;
|
||||
var deltaCompletionCost = deltaTextOutputCost + deltaAudioOutputCost;
|
||||
|
||||
var deltaTotal = deltaPromptCost + deltaCompletionCost;
|
||||
_promptCost += deltaPromptCost;
|
||||
_completionCost += deltaCompletionCost;
|
||||
|
||||
// Accumulated Token
|
||||
var stat = _services.GetRequiredService<IConversationStateService>();
|
||||
var inputCount = int.Parse(stat.GetState("prompt_total", "0"));
|
||||
stat.SetState("prompt_total", stats.PromptCount + inputCount, isNeedVersion: false, source: StateSource.Application);
|
||||
stat.SetState("prompt_total", stats.TotalInputTokens + inputCount, isNeedVersion: false, source: StateSource.Application);
|
||||
var outputCount = int.Parse(stat.GetState("completion_total", "0"));
|
||||
stat.SetState("completion_total", stats.CompletionCount + outputCount, isNeedVersion: false, source: StateSource.Application);
|
||||
var cachedCount = int.Parse(stat.GetState("cached_prompt_total", "0"));
|
||||
stat.SetState("cached_prompt_total", stats.CachedPromptCount + cachedCount, isNeedVersion: false, source: StateSource.Application);
|
||||
stat.SetState("completion_total", stats.TotalOutputTokens + outputCount, isNeedVersion: false, source: StateSource.Application);
|
||||
|
||||
// Total cost
|
||||
var total_cost = float.Parse(stat.GetState("llm_total_cost", "0"));
|
||||
|
|
@ -76,8 +81,8 @@ public class TokenStatistics : ITokenStatistics
|
|||
RecordTime = DateTime.UtcNow,
|
||||
IntervalType = StatsInterval.Day,
|
||||
Data = [
|
||||
new StatsKeyValuePair("prompt_token_count_total", stats.PromptCount),
|
||||
new StatsKeyValuePair("completion_token_count_total", stats.CompletionCount),
|
||||
new StatsKeyValuePair("prompt_token_count_total", stats.TotalInputTokens),
|
||||
new StatsKeyValuePair("completion_token_count_total", stats.TotalOutputTokens),
|
||||
new StatsKeyValuePair("prompt_cost_total", deltaPromptCost),
|
||||
new StatsKeyValuePair("completion_cost_total", deltaCompletionCost)
|
||||
]
|
||||
|
|
|
|||
|
|
@ -551,8 +551,8 @@ public class InstructModeController : ControllerBase
|
|||
|
||||
try
|
||||
{
|
||||
var auditData = FileUtility.BuildFileDataFromFile(file);
|
||||
var content = await fileInstruct.SpeechToText(new InstructFileModel { FileData = auditData }, text, new InstructOptions
|
||||
var audioData = FileUtility.BuildFileDataFromFile(file);
|
||||
var content = await fileInstruct.SpeechToText(new InstructFileModel { FileData = audioData }, text, new InstructOptions
|
||||
{
|
||||
Provider = provider,
|
||||
Model = model,
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Usage?.InputTokens ?? 0,
|
||||
CompletionCount = response.Usage?.OutputTokens ?? 0
|
||||
TextInputTokens = response.Usage?.InputTokens ?? 0,
|
||||
TextOutputTokens = response.Usage?.OutputTokens ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Azure;
|
||||
using BotSharp.Abstraction.Files.Utilities;
|
||||
using OpenAI.Chat;
|
||||
using System.ClientModel;
|
||||
|
|
@ -40,12 +41,13 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
var chatClient = client.GetChatClient(_model);
|
||||
var (prompt, messages, options) = PrepareOptions(agent, conversations);
|
||||
|
||||
ClientResult<ChatCompletion>? response = null;
|
||||
ChatCompletion value = default;
|
||||
RoleDialogModel responseMessage;
|
||||
|
||||
try
|
||||
{
|
||||
var response = chatClient.CompleteChat(messages, options);
|
||||
response = chatClient.CompleteChat(messages, options);
|
||||
value = response.Value;
|
||||
|
||||
var reason = value.FinishReason;
|
||||
|
|
@ -101,6 +103,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
};
|
||||
}
|
||||
|
||||
var tokenUsage = response?.Value?.Usage;
|
||||
var inputTokenDetails = response?.Value?.Usage?.InputTokenDetails;
|
||||
|
||||
// After chat completion hook
|
||||
foreach (var hook in contentHooks)
|
||||
{
|
||||
|
|
@ -109,8 +114,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = value?.Usage?.InputTokenCount ?? 0,
|
||||
CompletionCount = value?.Usage?.OutputTokenCount ?? 0
|
||||
TextInputTokens = (tokenUsage?.InputTokenCount ?? 0) - (inputTokenDetails?.CachedTokenCount ?? 0),
|
||||
CachedTextInputTokens = inputTokenDetails?.CachedTokenCount ?? 0,
|
||||
TextOutputTokens = tokenUsage?.OutputTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -146,6 +152,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
RenderedInstruction = string.Join("\r\n", renderedInstructions)
|
||||
};
|
||||
|
||||
var tokenUsage = response?.Value?.Usage;
|
||||
var inputTokenDetails = response?.Value?.Usage?.InputTokenDetails;
|
||||
|
||||
// After chat completion hook
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
|
|
@ -154,8 +163,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Value?.Usage?.InputTokenCount ?? 0,
|
||||
CompletionCount = response.Value?.Usage?.OutputTokenCount ?? 0
|
||||
TextInputTokens = (tokenUsage?.InputTokenCount ?? 0) - (inputTokenDetails?.CachedTokenCount ?? 0),
|
||||
CachedTextInputTokens = inputTokenDetails?.CachedTokenCount ?? 0,
|
||||
TextOutputTokens = tokenUsage?.OutputTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,14 +78,15 @@ public class TextCompletionProvider : ITextCompletion
|
|||
CurrentAgentId = agentId,
|
||||
MessageId = messageId
|
||||
};
|
||||
|
||||
Task.WaitAll(contentHooks.Select(hook =>
|
||||
hook.AfterGenerated(responseMessage, new TokenStatsModel
|
||||
{
|
||||
Prompt = text,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Usage?.PromptTokens ?? default,
|
||||
CompletionCount = response.Usage?.CompletionTokens ?? default
|
||||
TextInputTokens = response?.Usage?.PromptTokens ?? 0,
|
||||
TextOutputTokens = response?.Usage?.CompletionTokens ?? 0
|
||||
})).ToArray());
|
||||
|
||||
return completion.Trim();
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
};
|
||||
}
|
||||
|
||||
var tokenUsage = response?.Value?.Usage;
|
||||
var inputTokenDetails = response?.Value?.Usage?.InputTokenDetails;
|
||||
|
||||
// After chat completion hook
|
||||
foreach (var hook in contentHooks)
|
||||
{
|
||||
|
|
@ -81,8 +84,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Value?.Usage?.InputTokenCount ?? 0,
|
||||
CompletionCount = response.Value?.Usage?.OutputTokenCount ?? 0
|
||||
TextInputTokens = (tokenUsage?.InputTokenCount ?? 0) - (inputTokenDetails?.CachedTokenCount ?? 0),
|
||||
CachedTextInputTokens = inputTokenDetails?.CachedTokenCount ?? 0,
|
||||
TextOutputTokens = tokenUsage?.OutputTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -115,6 +119,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
RenderedInstruction = string.Join("\r\n", renderedInstructions)
|
||||
};
|
||||
|
||||
var tokenUsage = response?.Value?.Usage;
|
||||
var inputTokenDetails = response?.Value?.Usage?.InputTokenDetails;
|
||||
|
||||
// After chat completion hook
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
|
|
@ -123,8 +130,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Value?.Usage?.InputTokenCount ?? 0,
|
||||
CompletionCount = response.Value?.Usage?.OutputTokenCount ?? 0
|
||||
TextInputTokens = (tokenUsage?.InputTokenCount ?? 0) - (inputTokenDetails?.CachedTokenCount ?? 0),
|
||||
CachedTextInputTokens = inputTokenDetails?.CachedTokenCount ?? 0,
|
||||
TextOutputTokens = tokenUsage?.OutputTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@ public class TextCompletionProvider : ITextCompletion
|
|||
MessageId = messageId
|
||||
};
|
||||
|
||||
var tokenUsage = response?.Value?.Usage;
|
||||
var inputTokenDetails = response?.Value?.Usage?.InputTokenDetails;
|
||||
|
||||
foreach (var hook in contentHooks)
|
||||
{
|
||||
await hook.AfterGenerated(responseMessage, new TokenStatsModel
|
||||
|
|
@ -68,8 +71,9 @@ public class TextCompletionProvider : ITextCompletion
|
|||
Prompt = text,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response?.Value?.Usage?.InputTokenCount ?? default,
|
||||
CompletionCount = response?.Value?.Usage?.OutputTokenCount ?? default
|
||||
TextInputTokens = (tokenUsage?.InputTokenCount ?? 0) - (inputTokenDetails?.CachedTokenCount ?? 0),
|
||||
CachedTextInputTokens = inputTokenDetails?.CachedTokenCount ?? 0,
|
||||
TextOutputTokens = tokenUsage?.OutputTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,9 +81,8 @@ public class GeminiChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.UsageMetadata?.PromptTokenCount ?? 0,
|
||||
CachedPromptCount = response.UsageMetadata?.CachedContentTokenCount ?? 0,
|
||||
CompletionCount = response.UsageMetadata?.CandidatesTokenCount ?? 0
|
||||
TextInputTokens = response?.UsageMetadata?.PromptTokenCount ?? 0,
|
||||
TextOutputTokens = response?.UsageMetadata?.CandidatesTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -124,9 +123,8 @@ public class GeminiChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response?.UsageMetadata?.PromptTokenCount ?? 0,
|
||||
CachedPromptCount = response.UsageMetadata?.CachedContentTokenCount ?? 0,
|
||||
CompletionCount = response.UsageMetadata?.CandidatesTokenCount ?? 0
|
||||
TextInputTokens = response?.UsageMetadata?.PromptTokenCount ?? 0,
|
||||
TextOutputTokens = response?.UsageMetadata?.CandidatesTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,9 +64,8 @@ public class GeminiTextCompletionProvider : ITextCompletion
|
|||
Prompt = text,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.UsageMetadata?.PromptTokenCount ?? 0,
|
||||
CachedPromptCount = response.UsageMetadata?.CachedContentTokenCount ?? 0,
|
||||
CompletionCount = response.UsageMetadata?.CandidatesTokenCount ?? 0
|
||||
TextInputTokens = response?.UsageMetadata?.PromptTokenCount ?? 0,
|
||||
TextOutputTokens = response?.UsageMetadata?.CandidatesTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,14 +46,14 @@ namespace BotSharp.Plugin.VertexAI.Providers
|
|||
};
|
||||
|
||||
Task.WaitAll(contentHooks.Select(hook =>
|
||||
hook.AfterGenerated(responseMessage, new TokenStatsModel
|
||||
{
|
||||
Prompt = text,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Usage.TotalTokens,
|
||||
CompletionCount = response.Usage.OutputTokens
|
||||
})).ToArray());
|
||||
hook.AfterGenerated(responseMessage, new TokenStatsModel
|
||||
{
|
||||
Prompt = text,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
TextInputTokens = response.Usage.InputTokens,
|
||||
TextOutputTokens = response.Usage.OutputTokens
|
||||
})).ToArray());
|
||||
|
||||
return response.LastMessageContent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.usage.GetValueOrDefault("prompt_tokens"),
|
||||
CompletionCount = response.usage.GetValueOrDefault("completion_tokens")
|
||||
TextInputTokens = response.usage.GetValueOrDefault("prompt_tokens"),
|
||||
TextOutputTokens = response.usage.GetValueOrDefault("completion_tokens")
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,45 @@ public class ModelTokenUsage
|
|||
|
||||
[JsonPropertyName("output_tokens")]
|
||||
public int OutputTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("input_token_details")]
|
||||
public InputTokenDetail? InputTokenDetails { get; set; }
|
||||
|
||||
[JsonPropertyName("output_token_details")]
|
||||
public OutputTokenDetail? OutputTokenDetails { get; set; }
|
||||
}
|
||||
|
||||
public class InputTokenDetail
|
||||
{
|
||||
[JsonPropertyName("text_tokens")]
|
||||
public int? TextTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("audio_tokens")]
|
||||
public int? AudioTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("cached_tokens")]
|
||||
public int? CachedTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("cached_tokens_details")]
|
||||
public CachedTokenDetail? CachedTokenDetails { get; set; }
|
||||
}
|
||||
|
||||
public class CachedTokenDetail
|
||||
{
|
||||
[JsonPropertyName("text_tokens")]
|
||||
public int? TextTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("audio_tokens")]
|
||||
public int? AudioTokens { get; set; }
|
||||
}
|
||||
|
||||
public class OutputTokenDetail
|
||||
{
|
||||
[JsonPropertyName("text_tokens")]
|
||||
public int? TextTokens { get; set; }
|
||||
|
||||
[JsonPropertyName("audio_tokens")]
|
||||
public int? AudioTokens { get; set; }
|
||||
}
|
||||
|
||||
public class ModelResponseDoneOutput
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
};
|
||||
}
|
||||
|
||||
var tokenUsage = response.Value?.Usage;
|
||||
var inputTokenDetails = response.Value?.Usage?.InputTokenDetails;
|
||||
|
||||
// After chat completion hook
|
||||
foreach (var hook in contentHooks)
|
||||
{
|
||||
|
|
@ -82,9 +85,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Value?.Usage?.InputTokenCount ?? 0,
|
||||
CachedPromptCount = response.Value?.Usage?.InputTokenDetails?.CachedTokenCount ?? 0,
|
||||
CompletionCount = response.Value?.Usage?.OutputTokenCount ?? 0
|
||||
TextInputTokens = (tokenUsage?.InputTokenCount ?? 0) - (inputTokenDetails?.CachedTokenCount ?? 0),
|
||||
CachedTextInputTokens = inputTokenDetails?.CachedTokenCount ?? 0,
|
||||
TextOutputTokens = tokenUsage?.OutputTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -120,6 +123,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
RenderedInstruction = string.Join("\r\n", renderedInstructions)
|
||||
};
|
||||
|
||||
var tokenUsage = response?.Value?.Usage;
|
||||
var inputTokenDetails = response?.Value?.Usage?.InputTokenDetails;
|
||||
|
||||
// After chat completion hook
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
|
|
@ -128,8 +134,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Value?.Usage?.InputTokenCount ?? 0,
|
||||
CompletionCount = response.Value?.Usage?.OutputTokenCount ?? 0
|
||||
TextInputTokens = (tokenUsage?.InputTokenCount ?? 0) - (inputTokenDetails?.CachedTokenCount ?? 0),
|
||||
CachedTextInputTokens = inputTokenDetails?.CachedTokenCount ?? 0,
|
||||
TextOutputTokens = tokenUsage?.OutputTokenCount ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -178,11 +178,6 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
_logger.LogDebug($"{response.Type}: {receivedText}");
|
||||
onModelAudioDeltaReceived(audio.Delta, audio.ItemId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogDebug($"{response.Type}: {receivedText}");
|
||||
onModelAudioDeltaReceived(audio.Delta, audio.ItemId);
|
||||
}
|
||||
}
|
||||
else if (response.Type == "response.audio.done")
|
||||
{
|
||||
|
|
@ -571,6 +566,9 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
|
||||
var contentHooks = _services.GetServices<IContentGeneratingHook>().ToList();
|
||||
|
||||
var inputTokenDetails = data.Usage?.InputTokenDetails;
|
||||
var outputTokenDetails = data.Usage?.OutputTokenDetails;
|
||||
|
||||
foreach (var output in data.Outputs)
|
||||
{
|
||||
if (output.Type == "function_call")
|
||||
|
|
@ -591,13 +589,18 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
await hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, $"{output.Name}\r\n{output.Arguments}")
|
||||
{
|
||||
CurrentAgentId = conn.CurrentAgentId
|
||||
}, new TokenStatsModel
|
||||
},
|
||||
new TokenStatsModel
|
||||
{
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
Prompt = $"{output.Name}\r\n{output.Arguments}",
|
||||
CompletionCount = data.Usage.OutputTokens,
|
||||
PromptCount = data.Usage.InputTokens
|
||||
TextInputTokens = inputTokenDetails?.TextTokens ?? 0 - inputTokenDetails?.CachedTokenDetails?.TextTokens ?? 0,
|
||||
CachedTextInputTokens = data.Usage?.InputTokenDetails?.CachedTokenDetails?.TextTokens ?? 0,
|
||||
AudioInputTokens = inputTokenDetails?.AudioTokens ?? 0 - inputTokenDetails?.CachedTokenDetails?.AudioTokens ?? 0,
|
||||
CachedAudioInputTokens = inputTokenDetails?.CachedTokenDetails?.AudioTokens ?? 0,
|
||||
TextOutputTokens = outputTokenDetails?.TextTokens ?? 0,
|
||||
AudioOutputTokens = outputTokenDetails?.AudioTokens ?? 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -618,13 +621,18 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
await hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, content.Transcript)
|
||||
{
|
||||
CurrentAgentId = conn.CurrentAgentId
|
||||
}, new TokenStatsModel
|
||||
},
|
||||
new TokenStatsModel
|
||||
{
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
Prompt = content.Transcript,
|
||||
CompletionCount = data.Usage.OutputTokens,
|
||||
PromptCount = data.Usage.InputTokens
|
||||
TextInputTokens = inputTokenDetails?.TextTokens ?? 0 - inputTokenDetails?.CachedTokenDetails?.TextTokens ?? 0,
|
||||
CachedTextInputTokens = data.Usage?.InputTokenDetails?.CachedTokenDetails?.TextTokens ?? 0,
|
||||
AudioInputTokens = inputTokenDetails?.AudioTokens ?? 0 - inputTokenDetails?.CachedTokenDetails?.AudioTokens ?? 0,
|
||||
CachedAudioInputTokens = inputTokenDetails?.CachedTokenDetails?.AudioTokens ?? 0,
|
||||
TextOutputTokens = outputTokenDetails?.TextTokens ?? 0,
|
||||
AudioOutputTokens = outputTokenDetails?.AudioTokens ?? 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ public class TextCompletionProvider : ITextCompletion
|
|||
Prompt = text,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Usage?.PromptTokens ?? default,
|
||||
CompletionCount = response.Usage?.CompletionTokens ?? default
|
||||
TextInputTokens = response.Usage?.PromptTokens ?? 0,
|
||||
TextOutputTokens = response.Usage?.CompletionTokens ?? 0
|
||||
})).ToArray());
|
||||
|
||||
return completion.Trim();
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Usage.PromptTokens,
|
||||
CompletionCount = response.Usage.CompletionTokens
|
||||
TextInputTokens = response.Usage.PromptTokens,
|
||||
TextOutputTokens = response.Usage.CompletionTokens
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -108,8 +108,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
Prompt = prompt,
|
||||
Provider = Provider,
|
||||
Model = _model,
|
||||
PromptCount = response.Usage.PromptTokens,
|
||||
CompletionCount = response.Usage.CompletionTokens
|
||||
TextInputTokens = response.Usage.PromptTokens,
|
||||
TextOutputTokens = response.Usage.CompletionTokens
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,8 +58,14 @@
|
|||
"ApiKey": "",
|
||||
"Endpoint": "https://gpt-35-turbo-instruct.openai.azure.com/",
|
||||
"Type": "text",
|
||||
"PromptCost": 0.0015,
|
||||
"CompletionCost": 0.002
|
||||
"Cost": {
|
||||
"TextInputCost": 0.0015,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.002,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -91,8 +97,14 @@
|
|||
{
|
||||
"Name": "gpt-35-turbo",
|
||||
"Type": "chat",
|
||||
"PromptCost": 0.0015,
|
||||
"CompletionCost": 0.002
|
||||
"Cost": {
|
||||
"TextInputCost": 0.0015,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.002,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -102,8 +114,14 @@
|
|||
{
|
||||
"Name": "chatglm3_6b",
|
||||
"Type": "chat",
|
||||
"PromptCost": 0.0015,
|
||||
"CompletionCost": 0.002
|
||||
"Cost": {
|
||||
"TextInputCost": 0.0015,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.002,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -117,8 +135,14 @@
|
|||
"ApiKey": "",
|
||||
"Type": "chat",
|
||||
"MultiModal": true,
|
||||
"PromptCost": 0.00015,
|
||||
"CompletionCost": 0.0006
|
||||
"Cost": {
|
||||
"TextInputCost": 0.00015,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.0006,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": "gpt-4",
|
||||
|
|
@ -127,8 +151,14 @@
|
|||
"ApiKey": "",
|
||||
"Type": "chat",
|
||||
"MultiModal": true,
|
||||
"PromptCost": 0.0025,
|
||||
"CompletionCost": 0.01
|
||||
"Cost": {
|
||||
"TextInputCost": 0.0025,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.01,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": "gpt-4",
|
||||
|
|
@ -138,8 +168,14 @@
|
|||
"Type": "chat",
|
||||
"MultiModal": true,
|
||||
"RealTime": true,
|
||||
"PromptCost": 0.0025,
|
||||
"CompletionCost": 0.01
|
||||
"Cost": {
|
||||
"TextInputCost": 0.0025,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.01,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": "text-embedding-3",
|
||||
|
|
@ -147,8 +183,7 @@
|
|||
"Version": "3-small",
|
||||
"ApiKey": "",
|
||||
"Type": "embedding",
|
||||
"Dimension": 1536,
|
||||
"PromptCost": 0.00002
|
||||
"Dimension": 1536
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -160,8 +195,14 @@
|
|||
"ApiKey": "",
|
||||
"Endpoint": "https://api.deepseek.com/v1/",
|
||||
"Type": "chat",
|
||||
"PromptCost": 0.0015,
|
||||
"CompletionCost": 0.002
|
||||
"Cost": {
|
||||
"TextInputCost": 0.0015,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.002,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -173,16 +214,28 @@
|
|||
"ApiKey": "",
|
||||
"Type": "chat",
|
||||
"MultiModal": true,
|
||||
"PromptCost": 0.0015,
|
||||
"CompletionCost": 0.002
|
||||
"Cost": {
|
||||
"TextInputCost": 0.0015,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.002,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "gemini-2.0-flash-exp",
|
||||
"ApiKey": "",
|
||||
"Type": "realtime",
|
||||
"MultiModal": true,
|
||||
"PromptCost": 0.0015,
|
||||
"CompletionCost": 0.002
|
||||
"Cost": {
|
||||
"TextInputCost": 0.0015,
|
||||
"CachedTextInputCost": 0,
|
||||
"AudioInputCost": 0,
|
||||
"CachedAudioInputCost": 0,
|
||||
"TextOutputCost": 0.002,
|
||||
"AudioOutputCost": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue