Skip to content

Commit 73194c7

Browse files
Add cached input pricing support in cost calculations. Closes #1582
1 parent d0bff06 commit 73194c7

3 files changed

Lines changed: 22 additions & 5 deletions

File tree

DevProxy.Abstractions/LanguageModel/PricesData.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace DevProxy.Abstractions.LanguageModel;
99
public class ModelPrices
1010
{
1111
public double Input { get; set; }
12+
public double CachedInput { get; set; }
1213
public double Output { get; set; }
1314
}
1415

@@ -44,7 +45,7 @@ public bool TryGetModelPrices(string modelName, out ModelPrices? prices)
4445
return false;
4546
}
4647

47-
public (double Input, double Output) CalculateCost(string modelName, long inputTokens, long outputTokens)
48+
public (double Input, double Output) CalculateCost(string modelName, long inputTokens, long outputTokens, long cachedInputTokens = 0)
4849
{
4950
if (!TryGetModelPrices(modelName, out var prices))
5051
{
@@ -54,7 +55,14 @@ public bool TryGetModelPrices(string modelName, out ModelPrices? prices)
5455
Debug.Assert(prices != null, "Prices data should not be null here.");
5556

5657
// Prices in the data are per 1M tokens
57-
var inputCost = prices.Input * (inputTokens / 1_000_000.0);
58+
// When cached input pricing is available, separate cached tokens
59+
// from regular input tokens for accurate cost calculation
60+
var regularInputTokens = inputTokens - cachedInputTokens;
61+
var inputCost = prices.Input * (regularInputTokens / 1_000_000.0);
62+
if (cachedInputTokens > 0 && prices.CachedInput > 0)
63+
{
64+
inputCost += prices.CachedInput * (cachedInputTokens / 1_000_000.0);
65+
}
5866
var outputCost = prices.Output * (outputTokens / 1_000_000.0);
5967

6068
return (inputCost, outputCost);

DevProxy.Plugins/Inspection/LanguageModelPricingLoader.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,18 @@ protected override void LoadData(string fileContents)
4040
if (modelProperty.Value.TryGetProperty("input", out var inputElement) &&
4141
modelProperty.Value.TryGetProperty("output", out var outputElement))
4242
{
43-
pricesData[modelName] = new()
43+
var modelPrices = new ModelPrices
4444
{
4545
Input = inputElement.GetDouble(),
4646
Output = outputElement.GetDouble()
4747
};
48+
49+
if (modelProperty.Value.TryGetProperty("cached_input", out var cachedInputElement))
50+
{
51+
modelPrices.CachedInput = cachedInputElement.GetDouble();
52+
}
53+
54+
pricesData[modelName] = modelPrices;
4855
}
4956
}
5057

DevProxy.Plugins/Inspection/OpenAITelemetryPlugin.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,8 @@ private void RecordUsageMetrics(Activity activity, OpenAIRequest request, OpenAI
931931
return;
932932
}
933933

934-
var (inputCost, outputCost) = Configuration.Prices.CalculateCost(response.Model, usage.PromptTokens, usage.CompletionTokens);
934+
var cachedTokens = usage.PromptTokensDetails?.CachedTokens ?? 0L;
935+
var (inputCost, outputCost) = Configuration.Prices.CalculateCost(response.Model, usage.PromptTokens, usage.CompletionTokens, cachedTokens);
935936

936937
if (inputCost > 0)
937938
{
@@ -1042,7 +1043,8 @@ private List<OpenAITelemetryPluginReportModelUsageInformation> GetReportModelUsa
10421043
return usagePerModel;
10431044
}
10441045

1045-
var (inputCost, outputCost) = Configuration.Prices.CalculateCost(response.Model, usage.PromptTokens, usage.CompletionTokens);
1046+
var cachedTokens = usage.PromptTokensDetails?.CachedTokens ?? 0L;
1047+
var (inputCost, outputCost) = Configuration.Prices.CalculateCost(response.Model, usage.PromptTokens, usage.CompletionTokens, cachedTokens);
10461048

10471049
if (inputCost > 0)
10481050
{

0 commit comments

Comments
 (0)