mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-02 07:25:26 +08:00
157 lines
4.8 KiB
Go
157 lines
4.8 KiB
Go
package config
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type Config struct {
|
|
Keys []string `json:"keys,omitempty"`
|
|
APIKeys []APIKey `json:"api_keys,omitempty"`
|
|
Accounts []Account `json:"accounts,omitempty"`
|
|
Proxies []Proxy `json:"proxies,omitempty"`
|
|
ClaudeMapping map[string]string `json:"claude_mapping,omitempty"`
|
|
ClaudeModelMap map[string]string `json:"claude_model_mapping,omitempty"`
|
|
ModelAliases map[string]string `json:"model_aliases,omitempty"`
|
|
Admin AdminConfig `json:"admin,omitempty"`
|
|
Runtime RuntimeConfig `json:"runtime,omitempty"`
|
|
Compat CompatConfig `json:"compat,omitempty"`
|
|
Responses ResponsesConfig `json:"responses,omitempty"`
|
|
Embeddings EmbeddingsConfig `json:"embeddings,omitempty"`
|
|
AutoDelete AutoDeleteConfig `json:"auto_delete"`
|
|
HistorySplit HistorySplitConfig `json:"history_split"`
|
|
VercelSyncHash string `json:"_vercel_sync_hash,omitempty"`
|
|
VercelSyncTime int64 `json:"_vercel_sync_time,omitempty"`
|
|
AdditionalFields map[string]any `json:"-"`
|
|
}
|
|
|
|
type Account struct {
|
|
Name string `json:"name,omitempty"`
|
|
Remark string `json:"remark,omitempty"`
|
|
Email string `json:"email,omitempty"`
|
|
Mobile string `json:"mobile,omitempty"`
|
|
Password string `json:"password,omitempty"`
|
|
Token string `json:"token,omitempty"`
|
|
ProxyID string `json:"proxy_id,omitempty"`
|
|
}
|
|
|
|
type APIKey struct {
|
|
Key string `json:"key"`
|
|
Name string `json:"name,omitempty"`
|
|
Remark string `json:"remark,omitempty"`
|
|
}
|
|
|
|
type Proxy struct {
|
|
ID string `json:"id,omitempty"`
|
|
Name string `json:"name,omitempty"`
|
|
Type string `json:"type,omitempty"`
|
|
Host string `json:"host,omitempty"`
|
|
Port int `json:"port,omitempty"`
|
|
Username string `json:"username,omitempty"`
|
|
Password string `json:"password,omitempty"`
|
|
}
|
|
|
|
func NormalizeProxy(p Proxy) Proxy {
|
|
p.ID = strings.TrimSpace(p.ID)
|
|
p.Name = strings.TrimSpace(p.Name)
|
|
p.Type = strings.ToLower(strings.TrimSpace(p.Type))
|
|
p.Host = strings.TrimSpace(p.Host)
|
|
p.Username = strings.TrimSpace(p.Username)
|
|
p.Password = strings.TrimSpace(p.Password)
|
|
if p.ID == "" {
|
|
p.ID = StableProxyID(p)
|
|
}
|
|
if p.Name == "" && p.Host != "" && p.Port > 0 {
|
|
p.Name = fmt.Sprintf("%s:%d", p.Host, p.Port)
|
|
}
|
|
return p
|
|
}
|
|
|
|
func StableProxyID(p Proxy) string {
|
|
sum := sha1.Sum([]byte(strings.ToLower(strings.TrimSpace(p.Type)) + "|" + strings.ToLower(strings.TrimSpace(p.Host)) + "|" + fmt.Sprintf("%d", p.Port) + "|" + strings.TrimSpace(p.Username)))
|
|
return "proxy_" + hex.EncodeToString(sum[:6])
|
|
}
|
|
|
|
func (c *Config) ClearAccountTokens() {
|
|
if c == nil {
|
|
return
|
|
}
|
|
for i := range c.Accounts {
|
|
c.Accounts[i].Token = ""
|
|
}
|
|
}
|
|
|
|
func (c *Config) NormalizeCredentials() {
|
|
if c == nil {
|
|
return
|
|
}
|
|
normalizedAPIKeys := normalizeAPIKeys(c.APIKeys)
|
|
if len(normalizedAPIKeys) > 0 {
|
|
c.APIKeys = normalizedAPIKeys
|
|
c.Keys = apiKeysToStrings(c.APIKeys)
|
|
} else {
|
|
c.Keys = normalizeKeys(c.Keys)
|
|
c.APIKeys = apiKeysFromStrings(c.Keys, nil)
|
|
}
|
|
|
|
for i := range c.Accounts {
|
|
c.Accounts[i].Name = strings.TrimSpace(c.Accounts[i].Name)
|
|
c.Accounts[i].Remark = strings.TrimSpace(c.Accounts[i].Remark)
|
|
}
|
|
}
|
|
|
|
// DropInvalidAccounts removes accounts that cannot be addressed by admin APIs
|
|
// (no email and no normalizable mobile). This prevents legacy token-only
|
|
// records from becoming orphaned empty entries after token stripping.
|
|
func (c *Config) DropInvalidAccounts() {
|
|
if c == nil || len(c.Accounts) == 0 {
|
|
return
|
|
}
|
|
kept := make([]Account, 0, len(c.Accounts))
|
|
for _, acc := range c.Accounts {
|
|
if acc.Identifier() == "" {
|
|
continue
|
|
}
|
|
kept = append(kept, acc)
|
|
}
|
|
c.Accounts = kept
|
|
}
|
|
|
|
type CompatConfig struct {
|
|
WideInputStrictOutput *bool `json:"wide_input_strict_output,omitempty"`
|
|
StripReferenceMarkers *bool `json:"strip_reference_markers,omitempty"`
|
|
}
|
|
|
|
type AdminConfig struct {
|
|
PasswordHash string `json:"password_hash,omitempty"`
|
|
JWTExpireHours int `json:"jwt_expire_hours,omitempty"`
|
|
JWTValidAfterUnix int64 `json:"jwt_valid_after_unix,omitempty"`
|
|
}
|
|
|
|
type RuntimeConfig struct {
|
|
AccountMaxInflight int `json:"account_max_inflight,omitempty"`
|
|
AccountMaxQueue int `json:"account_max_queue,omitempty"`
|
|
GlobalMaxInflight int `json:"global_max_inflight,omitempty"`
|
|
TokenRefreshIntervalHours int `json:"token_refresh_interval_hours,omitempty"`
|
|
}
|
|
|
|
type ResponsesConfig struct {
|
|
StoreTTLSeconds int `json:"store_ttl_seconds,omitempty"`
|
|
}
|
|
|
|
type EmbeddingsConfig struct {
|
|
Provider string `json:"provider,omitempty"`
|
|
}
|
|
|
|
type AutoDeleteConfig struct {
|
|
Mode string `json:"mode,omitempty"`
|
|
Sessions bool `json:"sessions,omitempty"`
|
|
}
|
|
|
|
type HistorySplitConfig struct {
|
|
Enabled *bool `json:"enabled,omitempty"`
|
|
TriggerAfterTurns *int `json:"trigger_after_turns,omitempty"`
|
|
}
|