2025-05-06 23:25:16 +08:00
|
|
|
package operation_setting
|
|
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
import (
|
|
|
|
|
"strings"
|
2025-05-06 23:25:16 +08:00
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
"github.com/QuantumNous/new-api/setting/config"
|
2025-09-16 12:47:59 +08:00
|
|
|
)
|
|
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// Tool call prices ($/1K calls, admin-configurable)
|
|
|
|
|
// DB keys: tool_price_setting.prices
|
|
|
|
|
// ---------------------------------------------------------------------------
|
2025-06-07 12:26:23 +08:00
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
var defaultToolPrices = map[string]float64{
|
|
|
|
|
"web_search": 10.0,
|
|
|
|
|
"web_search_high": 25.0,
|
|
|
|
|
"claude_web_search": 10.0,
|
|
|
|
|
"file_search": 2.5,
|
|
|
|
|
}
|
2025-07-15 18:57:22 +08:00
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
// ToolPriceSetting is managed by config.GlobalConfig.Register.
|
|
|
|
|
type ToolPriceSetting struct {
|
|
|
|
|
Prices map[string]float64 `json:"prices"`
|
2025-07-15 18:57:22 +08:00
|
|
|
}
|
|
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
var toolPriceSetting = ToolPriceSetting{
|
|
|
|
|
Prices: func() map[string]float64 {
|
|
|
|
|
m := make(map[string]float64, len(defaultToolPrices))
|
|
|
|
|
for k, v := range defaultToolPrices {
|
|
|
|
|
m[k] = v
|
|
|
|
|
}
|
|
|
|
|
return m
|
|
|
|
|
}(),
|
2025-05-06 23:25:16 +08:00
|
|
|
}
|
2025-05-06 23:57:22 +08:00
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
func init() {
|
|
|
|
|
config.GlobalConfig.Register("tool_price_setting", &toolPriceSetting)
|
2025-05-06 23:57:22 +08:00
|
|
|
}
|
2025-06-07 12:26:23 +08:00
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
// GetToolPrice returns the configured price for a tool key ($/1K calls),
|
|
|
|
|
// falling back to hardcoded default if not overridden.
|
|
|
|
|
func GetToolPrice(key string) float64 {
|
|
|
|
|
if v, ok := toolPriceSetting.Prices[key]; ok {
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
if v, ok := defaultToolPrices[key]; ok {
|
|
|
|
|
return v
|
2025-06-07 12:26:23 +08:00
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|
2025-09-16 12:47:59 +08:00
|
|
|
|
2026-03-17 15:29:43 +08:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// GPT Image 1 per-call pricing (special: depends on quality + size)
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
GPTImage1Low1024x1024 = 0.011
|
|
|
|
|
GPTImage1Low1024x1536 = 0.016
|
|
|
|
|
GPTImage1Low1536x1024 = 0.016
|
|
|
|
|
GPTImage1Medium1024x1024 = 0.042
|
|
|
|
|
GPTImage1Medium1024x1536 = 0.063
|
|
|
|
|
GPTImage1Medium1536x1024 = 0.063
|
|
|
|
|
GPTImage1High1024x1024 = 0.167
|
|
|
|
|
GPTImage1High1024x1536 = 0.25
|
|
|
|
|
GPTImage1High1536x1024 = 0.25
|
|
|
|
|
)
|
|
|
|
|
|
2025-09-16 12:47:59 +08:00
|
|
|
func GetGPTImage1PriceOnceCall(quality string, size string) float64 {
|
|
|
|
|
prices := map[string]map[string]float64{
|
|
|
|
|
"low": {
|
|
|
|
|
"1024x1024": GPTImage1Low1024x1024,
|
|
|
|
|
"1024x1536": GPTImage1Low1024x1536,
|
|
|
|
|
"1536x1024": GPTImage1Low1536x1024,
|
|
|
|
|
},
|
|
|
|
|
"medium": {
|
|
|
|
|
"1024x1024": GPTImage1Medium1024x1024,
|
|
|
|
|
"1024x1536": GPTImage1Medium1024x1536,
|
|
|
|
|
"1536x1024": GPTImage1Medium1536x1024,
|
|
|
|
|
},
|
|
|
|
|
"high": {
|
|
|
|
|
"1024x1024": GPTImage1High1024x1024,
|
|
|
|
|
"1024x1536": GPTImage1High1024x1536,
|
|
|
|
|
"1536x1024": GPTImage1High1536x1024,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if qualityMap, exists := prices[quality]; exists {
|
|
|
|
|
if price, exists := qualityMap[size]; exists {
|
|
|
|
|
return price
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return GPTImage1High1024x1024
|
|
|
|
|
}
|
2026-03-17 15:29:43 +08:00
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// Gemini audio input pricing (per-million tokens, model-specific)
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
Gemini25FlashPreviewInputAudioPrice = 1.00
|
|
|
|
|
Gemini25FlashProductionInputAudioPrice = 1.00
|
|
|
|
|
Gemini25FlashLitePreviewInputAudioPrice = 0.50
|
|
|
|
|
Gemini25FlashNativeAudioInputAudioPrice = 3.00
|
|
|
|
|
Gemini20FlashInputAudioPrice = 0.70
|
|
|
|
|
GeminiRoboticsER15InputAudioPrice = 1.00
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func GetGeminiInputAudioPricePerMillionTokens(modelName string) float64 {
|
|
|
|
|
if strings.HasPrefix(modelName, "gemini-2.5-flash-preview-native-audio") {
|
|
|
|
|
return Gemini25FlashNativeAudioInputAudioPrice
|
|
|
|
|
} else if strings.HasPrefix(modelName, "gemini-2.5-flash-preview-lite") {
|
|
|
|
|
return Gemini25FlashLitePreviewInputAudioPrice
|
|
|
|
|
} else if strings.HasPrefix(modelName, "gemini-2.5-flash-preview") {
|
|
|
|
|
return Gemini25FlashPreviewInputAudioPrice
|
|
|
|
|
} else if strings.HasPrefix(modelName, "gemini-2.5-flash") {
|
|
|
|
|
return Gemini25FlashProductionInputAudioPrice
|
|
|
|
|
} else if strings.HasPrefix(modelName, "gemini-2.0-flash") {
|
|
|
|
|
return Gemini20FlashInputAudioPrice
|
|
|
|
|
} else if strings.HasPrefix(modelName, "gemini-robotics-er-1.5") {
|
|
|
|
|
return GeminiRoboticsER15InputAudioPrice
|
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|