Detailed changes
@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"log"
+ "math"
"net/http"
"os"
"slices"
@@ -95,11 +96,15 @@ func hasField(s, field string) bool {
return false
}
+func roundCost(v float64) float64 {
+ return math.Round(v*1e5) / 1e5
+}
+
func parseFloat(p *float64) float64 {
if p == nil {
return 0
}
- return *p
+ return roundCost(*p)
}
func calculateMaxTokens(contextLength, maxOutput, factor int64) int64 {
@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"log"
+ "math"
"net/http"
"os"
"slices"
@@ -159,8 +160,8 @@ func main() {
// Calculate pricing (convert from per-token to per-1M tokens)
var costPer1MIn, costPer1MOut float64
if provider.Pricing != nil {
- costPer1MIn = provider.Pricing.Input
- costPer1MOut = provider.Pricing.Output
+ costPer1MIn = math.Round(provider.Pricing.Input*1e5) / 1e5
+ costPer1MOut = math.Round(provider.Pricing.Output*1e5) / 1e5
}
// Set default max tokens (conservative estimate)
@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"log"
+ "math"
"net/http"
"os"
"slices"
@@ -79,10 +80,11 @@ func main() {
}
// Convert token prices (per token) to cost per 1M tokens
- costPer1MIn := model.InputTokenPrice * 1_000_000
- costPer1MOut := model.OutputTokenPrice * 1_000_000
- costPer1MInCached := model.CacheReadTokenPrice * 1_000_000
- costPer1MOutCached := model.CacheWriteTokenPrice * 1_000_000
+ roundCost := func(v float64) float64 { return math.Round(v*1e5) / 1e5 }
+ costPer1MIn := roundCost(model.InputTokenPrice * 1_000_000)
+ costPer1MOut := roundCost(model.OutputTokenPrice * 1_000_000)
+ costPer1MInCached := roundCost(model.CacheReadTokenPrice * 1_000_000)
+ costPer1MOutCached := roundCost(model.CacheWriteTokenPrice * 1_000_000)
m := catwalk.Model{
ID: model.ID,
@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"log"
+ "math"
"net/http"
"os"
"slices"
@@ -101,29 +102,33 @@ type ModelPricing struct {
CostPer1MOutCached float64 `json:"cost_per_1m_out_cached"`
}
+func roundCost(v float64) float64 {
+ return math.Round(v*1e5) / 1e5
+}
+
func getPricing(model Model) ModelPricing {
pricing := ModelPricing{}
costPrompt, err := strconv.ParseFloat(model.Pricing.Prompt, 64)
if err != nil {
costPrompt = 0.0
}
- pricing.CostPer1MIn = costPrompt * 1_000_000
+ pricing.CostPer1MIn = roundCost(costPrompt * 1_000_000)
costCompletion, err := strconv.ParseFloat(model.Pricing.Completion, 64)
if err != nil {
costCompletion = 0.0
}
- pricing.CostPer1MOut = costCompletion * 1_000_000
+ pricing.CostPer1MOut = roundCost(costCompletion * 1_000_000)
costPromptCached, err := strconv.ParseFloat(model.Pricing.InputCacheWrite, 64)
if err != nil {
costPromptCached = 0.0
}
- pricing.CostPer1MInCached = costPromptCached * 1_000_000
+ pricing.CostPer1MInCached = roundCost(costPromptCached * 1_000_000)
costCompletionCached, err := strconv.ParseFloat(model.Pricing.InputCacheRead, 64)
if err != nil {
costCompletionCached = 0.0
}
- pricing.CostPer1MOutCached = costCompletionCached * 1_000_000
+ pricing.CostPer1MOutCached = roundCost(costCompletionCached * 1_000_000)
return pricing
}
@@ -334,23 +339,23 @@ func main() {
if err != nil {
costPrompt = 0.0
}
- pricing.CostPer1MIn = costPrompt * 1_000_000
+ pricing.CostPer1MIn = roundCost(costPrompt * 1_000_000)
costCompletion, err := strconv.ParseFloat(bestEndpoint.Pricing.Completion, 64)
if err != nil {
costCompletion = 0.0
}
- pricing.CostPer1MOut = costCompletion * 1_000_000
+ pricing.CostPer1MOut = roundCost(costCompletion * 1_000_000)
costPromptCached, err := strconv.ParseFloat(bestEndpoint.Pricing.InputCacheWrite, 64)
if err != nil {
costPromptCached = 0.0
}
- pricing.CostPer1MInCached = costPromptCached * 1_000_000
+ pricing.CostPer1MInCached = roundCost(costPromptCached * 1_000_000)
costCompletionCached, err := strconv.ParseFloat(bestEndpoint.Pricing.InputCacheRead, 64)
if err != nil {
costCompletionCached = 0.0
}
- pricing.CostPer1MOutCached = costCompletionCached * 1_000_000
+ pricing.CostPer1MOutCached = roundCost(costCompletionCached * 1_000_000)
canReason := slices.Contains(bestEndpoint.SupportedParams, "reasoning")
supportsImages := slices.Contains(model.Architecture.InputModalities, "image")
@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"log"
+ "math"
"net/http"
"os"
"slices"
@@ -64,12 +65,16 @@ func parsePrice(s string) float64 {
return v
}
+func roundCost(v float64) float64 {
+ return math.Round(v*1e5) / 1e5
+}
+
func getPricing(model Model) ModelPricing {
return ModelPricing{
- CostPer1MIn: parsePrice(model.Pricing.Prompt) * 1_000_000,
- CostPer1MOut: parsePrice(model.Pricing.Completion) * 1_000_000,
- CostPer1MInCached: parsePrice(model.Pricing.InputCacheReads) * 1_000_000,
- CostPer1MOutCached: parsePrice(model.Pricing.InputCacheReads) * 1_000_000,
+ CostPer1MIn: roundCost(parsePrice(model.Pricing.Prompt) * 1_000_000),
+ CostPer1MOut: roundCost(parsePrice(model.Pricing.Completion) * 1_000_000),
+ CostPer1MInCached: roundCost(parsePrice(model.Pricing.InputCacheReads) * 1_000_000),
+ CostPer1MOutCached: roundCost(parsePrice(model.Pricing.InputCacheReads) * 1_000_000),
}
}
@@ -225,11 +225,12 @@ func main() {
}
}
+ roundCost := func(v float64) float64 { return math.Round(v*1e5) / 1e5 }
m := catwalk.Model{
ID: model.ID,
Name: model.ModelSpec.Name,
- CostPer1MIn: model.ModelSpec.Pricing.Input.USD,
- CostPer1MOut: model.ModelSpec.Pricing.Output.USD,
+ CostPer1MIn: roundCost(model.ModelSpec.Pricing.Input.USD),
+ CostPer1MOut: roundCost(model.ModelSpec.Pricing.Output.USD),
CostPer1MInCached: 0,
CostPer1MOutCached: 0,
ContextWindow: contextWindow,
@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"log"
+ "math"
"net/http"
"os"
"slices"
@@ -107,6 +108,7 @@ func main() {
}
// Parse pricing
+ roundCost := func(v float64) float64 { return math.Round(v*1e5) / 1e5 }
costPer1MIn := 0.0
costPer1MOut := 0.0
costPer1MInCached := 0.0
@@ -115,28 +117,28 @@ func main() {
if model.Pricing.Input != "" {
costPrompt, err := strconv.ParseFloat(model.Pricing.Input, 64)
if err == nil {
- costPer1MIn = costPrompt * 1_000_000
+ costPer1MIn = roundCost(costPrompt * 1_000_000)
}
}
if model.Pricing.Output != "" {
costCompletion, err := strconv.ParseFloat(model.Pricing.Output, 64)
if err == nil {
- costPer1MOut = costCompletion * 1_000_000
+ costPer1MOut = roundCost(costCompletion * 1_000_000)
}
}
if model.Pricing.InputCacheRead != "" {
costCached, err := strconv.ParseFloat(model.Pricing.InputCacheRead, 64)
if err == nil {
- costPer1MInCached = costCached * 1_000_000
+ costPer1MInCached = roundCost(costCached * 1_000_000)
}
}
if model.Pricing.InputCacheWrite != "" {
costCacheWrite, err := strconv.ParseFloat(model.Pricing.InputCacheWrite, 64)
if err == nil {
- costPer1MOutCached = costCacheWrite * 1_000_000
+ costPer1MOutCached = roundCost(costCacheWrite * 1_000_000)
}
}