refactor llm cost

This commit is contained in:
Jicheng Lu 2025-04-21 11:19:56 -05:00
parent d53b028b25
commit fd89a995d1
19 changed files with 244 additions and 108 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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)
]

View file

@ -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,

View file

@ -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
});
}

View file

@ -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
});
}

View file

@ -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();

View file

@ -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
});
}

View file

@ -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
});
}

View file

@ -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
});
}

View file

@ -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
});
}

View file

@ -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;
}

View file

@ -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")
});
}

View file

@ -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

View file

@ -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
});
}

View file

@ -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")
{
@ -565,6 +560,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")
@ -585,13 +583,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
});
}
}
@ -612,13 +615,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
});
}
}

View file

@ -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();

View file

@ -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
});
}

View file

@ -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
}
}
]
}