Merge branch 'main' into feat_subscribe_sp1

This commit is contained in:
Little Write
2025-10-20 22:36:33 +08:00
396 changed files with 28798 additions and 5948 deletions

View File

@@ -2,7 +2,8 @@ package setting
import (
"encoding/json"
"one-api/common"
"github.com/QuantumNous/new-api/common"
)
var Chats = []map[string]string{

View File

@@ -2,11 +2,12 @@ package config
import (
"encoding/json"
"one-api/common"
"reflect"
"strconv"
"strings"
"sync"
"github.com/QuantumNous/new-api/common"
)
// ConfigManager 统一管理所有配置

View File

@@ -1,6 +1,6 @@
package console_setting
import "one-api/setting/config"
import "github.com/QuantumNous/new-api/setting/config"
type ConsoleSetting struct {
ApiInfo string `json:"api_info"` // 控制台 API 信息 (JSON 数组字符串)

View File

@@ -2,7 +2,8 @@ package model_setting
import (
"net/http"
"one-api/setting/config"
"github.com/QuantumNous/new-api/setting/config"
)
//var claudeHeadersSettings = map[string][]string{}

View File

@@ -1,7 +1,7 @@
package model_setting
import (
"one-api/setting/config"
"github.com/QuantumNous/new-api/setting/config"
)
// GeminiSettings 定义Gemini模型的配置

View File

@@ -1,7 +1,7 @@
package model_setting
import (
"one-api/setting/config"
"github.com/QuantumNous/new-api/setting/config"
)
type GlobalSettings struct {

View File

@@ -1,18 +1,35 @@
package operation_setting
import "one-api/setting/config"
import "github.com/QuantumNous/new-api/setting/config"
// 额度展示类型
const (
QuotaDisplayTypeUSD = "USD"
QuotaDisplayTypeCNY = "CNY"
QuotaDisplayTypeTokens = "TOKENS"
QuotaDisplayTypeCustom = "CUSTOM"
)
type GeneralSetting struct {
DocsLink string `json:"docs_link"`
PingIntervalEnabled bool `json:"ping_interval_enabled"`
PingIntervalSeconds int `json:"ping_interval_seconds"`
// 当前站点额度展示类型USD / CNY / TOKENS
QuotaDisplayType string `json:"quota_display_type"`
// 自定义货币符号,用于 CUSTOM 展示类型
CustomCurrencySymbol string `json:"custom_currency_symbol"`
// 自定义货币与美元汇率1 USD = X Custom
CustomCurrencyExchangeRate float64 `json:"custom_currency_exchange_rate"`
}
// 默认配置
var generalSetting = GeneralSetting{
DocsLink: "https://docs.newapi.pro",
PingIntervalEnabled: false,
PingIntervalSeconds: 60,
DocsLink: "https://docs.newapi.pro",
PingIntervalEnabled: false,
PingIntervalSeconds: 60,
QuotaDisplayType: QuotaDisplayTypeUSD,
CustomCurrencySymbol: "¤",
CustomCurrencyExchangeRate: 1.0,
}
func init() {
@@ -23,3 +40,52 @@ func init() {
func GetGeneralSetting() *GeneralSetting {
return &generalSetting
}
// IsCurrencyDisplay 是否以货币形式展示(美元或人民币)
func IsCurrencyDisplay() bool {
return generalSetting.QuotaDisplayType != QuotaDisplayTypeTokens
}
// IsCNYDisplay 是否以人民币展示
func IsCNYDisplay() bool {
return generalSetting.QuotaDisplayType == QuotaDisplayTypeCNY
}
// GetQuotaDisplayType 返回额度展示类型
func GetQuotaDisplayType() string {
return generalSetting.QuotaDisplayType
}
// GetCurrencySymbol 返回当前展示类型对应符号
func GetCurrencySymbol() string {
switch generalSetting.QuotaDisplayType {
case QuotaDisplayTypeUSD:
return "$"
case QuotaDisplayTypeCNY:
return "¥"
case QuotaDisplayTypeCustom:
if generalSetting.CustomCurrencySymbol != "" {
return generalSetting.CustomCurrencySymbol
}
return "¤"
default:
return ""
}
}
// GetUsdToCurrencyRate 返回 1 USD = X <currency> 的 XTOKENS 不适用)
func GetUsdToCurrencyRate(usdToCny float64) float64 {
switch generalSetting.QuotaDisplayType {
case QuotaDisplayTypeUSD:
return 1
case QuotaDisplayTypeCNY:
return usdToCny
case QuotaDisplayTypeCustom:
if generalSetting.CustomCurrencyExchangeRate > 0 {
return generalSetting.CustomCurrencyExchangeRate
}
return 1
default:
return 1
}
}

View File

@@ -1,9 +1,10 @@
package operation_setting
import (
"one-api/setting/config"
"os"
"strconv"
"github.com/QuantumNous/new-api/setting/config"
)
type MonitorSetting struct {

View File

@@ -1,6 +1,6 @@
package operation_setting
import "one-api/setting/config"
import "github.com/QuantumNous/new-api/setting/config"
type PaymentSetting struct {
AmountOptions []int `json:"amount_options"`

View File

@@ -6,7 +6,7 @@ This file is the old version of the payment settings file. If you need to add ne
package operation_setting
import (
"one-api/common"
"github.com/QuantumNous/new-api/common"
)
var PayAddress = ""

View File

@@ -0,0 +1,21 @@
package operation_setting
import "github.com/QuantumNous/new-api/setting/config"
type QuotaSetting struct {
EnableFreeModelPreConsume bool `json:"enable_free_model_pre_consume"` // 是否对免费模型启用预消耗
}
// 默认配置
var quotaSetting = QuotaSetting{
EnableFreeModelPreConsume: true,
}
func init() {
// 注册到全局配置管理器
config.GlobalConfig.Register("quota_setting", &quotaSetting)
}
func GetQuotaSetting() *QuotaSetting {
return &quotaSetting
}

View File

@@ -29,6 +29,7 @@ const (
Gemini25FlashLitePreviewInputAudioPrice = 0.50
Gemini25FlashNativeAudioInputAudioPrice = 3.00
Gemini20FlashInputAudioPrice = 0.70
GeminiRoboticsER15InputAudioPrice = 1.00
)
const (
@@ -74,6 +75,8 @@ func GetGeminiInputAudioPricePerMillionTokens(modelName string) float64 {
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
}

View File

@@ -5,3 +5,4 @@ var StripeWebhookSecret = ""
var StripePriceId = ""
var StripeUnitPrice = 8.0
var StripeMinTopUp = 1
var StripePromotionCodesEnabled = false

View File

@@ -4,8 +4,9 @@ import (
"encoding/json"
"fmt"
"math"
"one-api/common"
"sync"
"github.com/QuantumNous/new-api/common"
)
var ModelRequestRateLimitEnabled = false

View File

@@ -2,8 +2,9 @@ package ratio_setting
import (
"encoding/json"
"one-api/common"
"sync"
"github.com/QuantumNous/new-api/common"
)
var defaultCacheRatio = map[string]float64{
@@ -52,6 +53,8 @@ var defaultCacheRatio = map[string]float64{
"claude-opus-4-20250514-thinking": 0.1,
"claude-opus-4-1-20250805": 0.1,
"claude-opus-4-1-20250805-thinking": 0.1,
"claude-sonnet-4-5-20250929": 0.1,
"claude-sonnet-4-5-20250929-thinking": 0.1,
}
var defaultCreateCacheRatio = map[string]float64{
@@ -69,6 +72,8 @@ var defaultCreateCacheRatio = map[string]float64{
"claude-opus-4-20250514-thinking": 1.25,
"claude-opus-4-1-20250805": 1.25,
"claude-opus-4-1-20250805-thinking": 1.25,
"claude-sonnet-4-5-20250929": 1.25,
"claude-sonnet-4-5-20250929-thinking": 1.25,
}
//var defaultCreateCacheRatio = map[string]float64{}

View File

@@ -3,8 +3,9 @@ package ratio_setting
import (
"encoding/json"
"errors"
"one-api/common"
"sync"
"github.com/QuantumNous/new-api/common"
)
var groupRatio = map[string]float64{

View File

@@ -2,10 +2,11 @@ package ratio_setting
import (
"encoding/json"
"one-api/common"
"one-api/setting/operation_setting"
"strings"
"sync"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/setting/operation_setting"
)
// from songquanpeng/one-api
@@ -141,6 +142,7 @@ var defaultModelRatio = map[string]float64{
"claude-3-7-sonnet-20250219": 1.5,
"claude-3-7-sonnet-20250219-thinking": 1.5,
"claude-sonnet-4-20250514": 1.5,
"claude-sonnet-4-5-20250929": 1.5,
"claude-3-opus-20240229": 7.5, // $15 / 1M tokens
"claude-opus-4-20250514": 7.5,
"claude-opus-4-1-20250805": 7.5,
@@ -178,6 +180,7 @@ var defaultModelRatio = map[string]float64{
"gemini-2.5-flash-lite-preview-thinking-*": 0.05,
"gemini-2.5-flash-lite-preview-06-17": 0.05,
"gemini-2.5-flash": 0.15,
"gemini-robotics-er-1.5-preview": 0.15,
"gemini-embedding-001": 0.075,
"text-embedding-004": 0.001,
"chatglm_turbo": 0.3572, // ¥0.005 / 1k tokens
@@ -251,6 +254,17 @@ var defaultModelRatio = map[string]float64{
"grok-vision-beta": 2.5,
"grok-3-fast-beta": 2.5,
"grok-3-mini-fast-beta": 0.3,
// submodel
"NousResearch/Hermes-4-405B-FP8": 0.8,
"Qwen/Qwen3-235B-A22B-Thinking-2507": 0.6,
"Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8": 0.8,
"Qwen/Qwen3-235B-A22B-Instruct-2507": 0.3,
"zai-org/GLM-4.5-FP8": 0.8,
"openai/gpt-oss-120b": 0.5,
"deepseek-ai/DeepSeek-R1-0528": 0.8,
"deepseek-ai/DeepSeek-R1": 0.8,
"deepseek-ai/DeepSeek-V3-0324": 0.8,
"deepseek-ai/DeepSeek-V3.1": 0.8,
}
var defaultModelPrice = map[string]float64{
@@ -277,6 +291,8 @@ var defaultModelPrice = map[string]float64{
"mj_upscale": 0.05,
"swap_face": 0.05,
"mj_upload": 0.05,
"sora-2": 0.3,
"sora-2-pro": 0.5,
}
var defaultAudioRatio = map[string]float64{
@@ -439,6 +455,10 @@ func GetDefaultModelRatioMap() map[string]float64 {
return defaultModelRatio
}
func GetDefaultModelPriceMap() map[string]float64 {
return defaultModelPrice
}
func GetDefaultImageRatioMap() map[string]float64 {
return defaultImageRatio
}
@@ -501,7 +521,6 @@ func GetCompletionRatio(name string) float64 {
}
func getHardcodedCompletionModelRatio(name string) (float64, bool) {
lowercaseName := strings.ToLower(name)
isReservedModel := strings.HasSuffix(name, "-all") || strings.HasSuffix(name, "-gizmo-*")
if isReservedModel {
@@ -576,6 +595,8 @@ func getHardcodedCompletionModelRatio(name string) (float64, bool) {
return 4, false
}
return 2.5 / 0.3, false
} else if strings.HasPrefix(name, "gemini-robotics-er-1.5") {
return 2.5 / 0.3, false
}
return 4, false
}
@@ -594,9 +615,6 @@ func getHardcodedCompletionModelRatio(name string) (float64, bool) {
}
}
// hint 只给官方上4倍率由于开源模型供应商自行定价不对其进行补全倍率进行强制对齐
if lowercaseName == "deepseek-chat" || lowercaseName == "deepseek-reasoner" {
return 4, true
}
if strings.HasPrefix(name, "ERNIE-Speed-") {
return 2, true
} else if strings.HasPrefix(name, "ERNIE-Lite-") {

View File

@@ -1,6 +1,6 @@
package system_setting
import "one-api/setting/config"
import "github.com/QuantumNous/new-api/setting/config"
type FetchSetting struct {
EnableSSRFProtection bool `json:"enable_ssrf_protection"` // 是否启用SSRF防护

View File

@@ -0,0 +1,21 @@
package system_setting
import "github.com/QuantumNous/new-api/setting/config"
type LegalSettings struct {
UserAgreement string `json:"user_agreement"`
PrivacyPolicy string `json:"privacy_policy"`
}
var defaultLegalSettings = LegalSettings{
UserAgreement: "",
PrivacyPolicy: "",
}
func init() {
config.GlobalConfig.Register("legal", &defaultLegalSettings)
}
func GetLegalSettings() *LegalSettings {
return &defaultLegalSettings
}

View File

@@ -1,6 +1,6 @@
package system_setting
import "one-api/setting/config"
import "github.com/QuantumNous/new-api/setting/config"
type OIDCSettings struct {
Enabled bool `json:"enabled"`

View File

@@ -0,0 +1,50 @@
package system_setting
import (
"net/url"
"strings"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/setting/config"
)
type PasskeySettings struct {
Enabled bool `json:"enabled"`
RPDisplayName string `json:"rp_display_name"`
RPID string `json:"rp_id"`
Origins string `json:"origins"`
AllowInsecureOrigin bool `json:"allow_insecure_origin"`
UserVerification string `json:"user_verification"`
AttachmentPreference string `json:"attachment_preference"`
}
var defaultPasskeySettings = PasskeySettings{
Enabled: false,
RPDisplayName: common.SystemName,
RPID: "",
Origins: "",
AllowInsecureOrigin: false,
UserVerification: "preferred",
AttachmentPreference: "",
}
func init() {
config.GlobalConfig.Register("passkey", &defaultPasskeySettings)
}
func GetPasskeySettings() *PasskeySettings {
if defaultPasskeySettings.RPID == "" && ServerAddress != "" {
// 从ServerAddress提取域名作为RPID
// ServerAddress可能是 "https://newapi.pro" 这种格式
serverAddr := strings.TrimSpace(ServerAddress)
if parsed, err := url.Parse(serverAddr); err == nil && parsed.Host != "" {
defaultPasskeySettings.RPID = parsed.Host
} else {
defaultPasskeySettings.RPID = serverAddr
}
}
if defaultPasskeySettings.Origins == "" || defaultPasskeySettings.Origins == "[]" {
defaultPasskeySettings.Origins = ServerAddress
}
return &defaultPasskeySettings
}

View File

@@ -2,8 +2,9 @@ package setting
import (
"encoding/json"
"one-api/common"
"sync"
"github.com/QuantumNous/new-api/common"
)
var userUsableGroups = map[string]string{