feat: improve model catalog aggregation
This commit is contained in:
@@ -3,6 +3,7 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -182,7 +183,7 @@ func (s *Store) PricingRuleSetBillingConfig(ctx context.Context, id string) (map
|
||||
return nil, nil
|
||||
}
|
||||
rows, err := s.pool.Query(ctx, `
|
||||
SELECT resource_type, base_price::float8, dynamic_weight
|
||||
SELECT resource_type, base_price::float8, dynamic_weight, formula_config
|
||||
FROM model_pricing_rules
|
||||
WHERE rule_set_id = $1::uuid
|
||||
AND status = 'active'
|
||||
@@ -197,15 +198,31 @@ ORDER BY priority ASC, resource_type ASC`, id)
|
||||
var resourceType string
|
||||
var basePrice float64
|
||||
var dynamicWeightBytes []byte
|
||||
if err := rows.Scan(&resourceType, &basePrice, &dynamicWeightBytes); err != nil {
|
||||
var formulaConfigBytes []byte
|
||||
if err := rows.Scan(&resourceType, &basePrice, &dynamicWeightBytes, &formulaConfigBytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dynamicWeight := decodeObject(dynamicWeightBytes)
|
||||
formulaConfig := decodeObject(formulaConfigBytes)
|
||||
switch resourceType {
|
||||
case "text_input":
|
||||
config["textInputPer1k"] = basePrice
|
||||
case "text_output":
|
||||
config["textOutputPer1k"] = basePrice
|
||||
case "text_total":
|
||||
inputPrice := basePrice
|
||||
if value, ok := pricingRuleNumberFromKeys(formulaConfig, "inputTokenPrice", "input_token_price", "textInputPer1k", "text_input"); ok {
|
||||
inputPrice = value
|
||||
}
|
||||
config["textInputPer1k"] = inputPrice
|
||||
if outputPrice, ok := pricingRuleNumberFromKeys(formulaConfig, "outputTokenPrice", "output_token_price", "textOutputPer1k", "text_output"); ok {
|
||||
config["textOutputPer1k"] = outputPrice
|
||||
}
|
||||
resourceConfig := pricingResourceConfig(basePrice, dynamicWeight)
|
||||
if len(formulaConfig) > 0 {
|
||||
resourceConfig["formulaConfig"] = formulaConfig
|
||||
}
|
||||
config["text_total"] = resourceConfig
|
||||
case "image":
|
||||
config["imageBase"] = basePrice
|
||||
config["image"] = pricingResourceConfig(basePrice, dynamicWeight)
|
||||
@@ -225,6 +242,45 @@ ORDER BY priority ASC, resource_type ASC`, id)
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func pricingRuleNumberFromKeys(config map[string]any, keys ...string) (float64, bool) {
|
||||
if len(config) == 0 {
|
||||
return 0, false
|
||||
}
|
||||
for _, key := range keys {
|
||||
if value, ok := pricingRuleNumberValue(config[key]); ok {
|
||||
return value, true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func pricingRuleNumberValue(value any) (float64, bool) {
|
||||
switch typed := value.(type) {
|
||||
case float64:
|
||||
return typed, true
|
||||
case float32:
|
||||
return float64(typed), true
|
||||
case int:
|
||||
return float64(typed), true
|
||||
case int64:
|
||||
return float64(typed), true
|
||||
case int32:
|
||||
return float64(typed), true
|
||||
case json.Number:
|
||||
number, err := typed.Float64()
|
||||
return number, err == nil
|
||||
case string:
|
||||
trimmed := strings.TrimSpace(typed)
|
||||
if trimmed == "" {
|
||||
return 0, false
|
||||
}
|
||||
number, err := strconv.ParseFloat(trimmed, 64)
|
||||
return number, err == nil
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
func pricingResourceConfig(basePrice float64, dynamicWeight map[string]any) map[string]any {
|
||||
config := map[string]any{"basePrice": basePrice}
|
||||
if len(dynamicWeight) > 0 {
|
||||
|
||||
Reference in New Issue
Block a user