mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-03 13:00:52 +08:00
Merge pull request #69 from router-for-me/reload
Implement minimal incremental updates for models and keys
This commit is contained in:
@@ -194,7 +194,7 @@ func NewServer(cfg *config.Config, authManager *auth.Manager, accessManager *sdk
|
||||
loggerToggle: toggle,
|
||||
configFilePath: configFilePath,
|
||||
}
|
||||
s.applyAccessConfig(cfg)
|
||||
s.applyAccessConfig(nil, cfg)
|
||||
// Initialize management handler
|
||||
s.mgmt = managementHandlers.NewHandler(cfg, configFilePath, authManager)
|
||||
if optionState.localPassword != "" {
|
||||
@@ -547,16 +547,23 @@ func corsMiddleware() gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) applyAccessConfig(cfg *config.Config) {
|
||||
if s == nil || s.accessManager == nil {
|
||||
func (s *Server) applyAccessConfig(oldCfg, newCfg *config.Config) {
|
||||
if s == nil || s.accessManager == nil || newCfg == nil {
|
||||
return
|
||||
}
|
||||
providers, err := sdkaccess.BuildProviders(cfg)
|
||||
existing := s.accessManager.Providers()
|
||||
providers, added, updated, removed, err := sdkaccess.ReconcileProviders(oldCfg, newCfg, existing)
|
||||
if err != nil {
|
||||
log.Errorf("failed to update request auth providers: %v", err)
|
||||
log.Errorf("failed to reconcile request auth providers: %v", err)
|
||||
return
|
||||
}
|
||||
s.accessManager.SetProviders(providers)
|
||||
if len(added)+len(updated)+len(removed) > 0 {
|
||||
log.Debugf("auth providers reconciled (added=%d updated=%d removed=%d)", len(added), len(updated), len(removed))
|
||||
log.Debugf("auth provider changes details - added=%v updated=%v removed=%v", added, updated, removed)
|
||||
} else {
|
||||
log.Debug("auth providers unchanged after config update")
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateClients updates the server's client list and configuration.
|
||||
@@ -566,44 +573,60 @@ func (s *Server) applyAccessConfig(cfg *config.Config) {
|
||||
// - clients: The new slice of AI service clients
|
||||
// - cfg: The new application configuration
|
||||
func (s *Server) UpdateClients(cfg *config.Config) {
|
||||
oldCfg := s.cfg
|
||||
|
||||
// Update request logger enabled state if it has changed
|
||||
if s.requestLogger != nil && s.cfg.RequestLog != cfg.RequestLog {
|
||||
previousRequestLog := false
|
||||
if oldCfg != nil {
|
||||
previousRequestLog = oldCfg.RequestLog
|
||||
}
|
||||
if s.requestLogger != nil && (oldCfg == nil || previousRequestLog != cfg.RequestLog) {
|
||||
if s.loggerToggle != nil {
|
||||
s.loggerToggle(cfg.RequestLog)
|
||||
} else if toggler, ok := s.requestLogger.(interface{ SetEnabled(bool) }); ok {
|
||||
toggler.SetEnabled(cfg.RequestLog)
|
||||
}
|
||||
log.Debugf("request logging updated from %t to %t", s.cfg.RequestLog, cfg.RequestLog)
|
||||
}
|
||||
|
||||
if s.cfg.LoggingToFile != cfg.LoggingToFile {
|
||||
if err := logging.ConfigureLogOutput(cfg.LoggingToFile); err != nil {
|
||||
log.Errorf("failed to reconfigure log output: %v", err)
|
||||
if oldCfg != nil {
|
||||
log.Debugf("request logging updated from %t to %t", previousRequestLog, cfg.RequestLog)
|
||||
} else {
|
||||
log.Debugf("logging_to_file updated from %t to %t", s.cfg.LoggingToFile, cfg.LoggingToFile)
|
||||
log.Debugf("request logging toggled to %t", cfg.RequestLog)
|
||||
}
|
||||
}
|
||||
|
||||
if s.cfg == nil || s.cfg.UsageStatisticsEnabled != cfg.UsageStatisticsEnabled {
|
||||
if oldCfg != nil && oldCfg.LoggingToFile != cfg.LoggingToFile {
|
||||
if err := logging.ConfigureLogOutput(cfg.LoggingToFile); err != nil {
|
||||
log.Errorf("failed to reconfigure log output: %v", err)
|
||||
} else {
|
||||
log.Debugf("logging_to_file updated from %t to %t", oldCfg.LoggingToFile, cfg.LoggingToFile)
|
||||
}
|
||||
}
|
||||
|
||||
if oldCfg == nil || oldCfg.UsageStatisticsEnabled != cfg.UsageStatisticsEnabled {
|
||||
usage.SetStatisticsEnabled(cfg.UsageStatisticsEnabled)
|
||||
if s.cfg != nil {
|
||||
log.Debugf("usage_statistics_enabled updated from %t to %t", s.cfg.UsageStatisticsEnabled, cfg.UsageStatisticsEnabled)
|
||||
if oldCfg != nil {
|
||||
log.Debugf("usage_statistics_enabled updated from %t to %t", oldCfg.UsageStatisticsEnabled, cfg.UsageStatisticsEnabled)
|
||||
} else {
|
||||
log.Debugf("usage_statistics_enabled toggled to %t", cfg.UsageStatisticsEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
// Update log level dynamically when debug flag changes
|
||||
if s.cfg.Debug != cfg.Debug {
|
||||
if oldCfg == nil || oldCfg.Debug != cfg.Debug {
|
||||
util.SetLogLevel(cfg)
|
||||
log.Debugf("debug mode updated from %t to %t", s.cfg.Debug, cfg.Debug)
|
||||
if oldCfg != nil {
|
||||
log.Debugf("debug mode updated from %t to %t", oldCfg.Debug, cfg.Debug)
|
||||
} else {
|
||||
log.Debugf("debug mode toggled to %t", cfg.Debug)
|
||||
}
|
||||
}
|
||||
|
||||
s.applyAccessConfig(oldCfg, cfg)
|
||||
s.cfg = cfg
|
||||
s.handlers.UpdateClients(cfg)
|
||||
if s.mgmt != nil {
|
||||
s.mgmt.SetConfig(cfg)
|
||||
s.mgmt.SetAuthManager(s.handlers.AuthManager)
|
||||
}
|
||||
s.applyAccessConfig(cfg)
|
||||
|
||||
// Count client sources from configuration and auth directory
|
||||
authFiles := util.CountAuthFiles(cfg.AuthDir)
|
||||
|
||||
@@ -101,58 +101,267 @@ func (r *ModelRegistry) RegisterClient(clientID, clientProvider string, models [
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
|
||||
// Remove any existing registration for this client
|
||||
r.unregisterClientInternal(clientID)
|
||||
|
||||
provider := strings.ToLower(clientProvider)
|
||||
modelIDs := make([]string, 0, len(models))
|
||||
uniqueModelIDs := make([]string, 0, len(models))
|
||||
rawModelIDs := make([]string, 0, len(models))
|
||||
newModels := make(map[string]*ModelInfo, len(models))
|
||||
newCounts := make(map[string]int, len(models))
|
||||
for _, model := range models {
|
||||
if model == nil || model.ID == "" {
|
||||
continue
|
||||
}
|
||||
rawModelIDs = append(rawModelIDs, model.ID)
|
||||
newCounts[model.ID]++
|
||||
if _, exists := newModels[model.ID]; exists {
|
||||
continue
|
||||
}
|
||||
newModels[model.ID] = model
|
||||
uniqueModelIDs = append(uniqueModelIDs, model.ID)
|
||||
}
|
||||
|
||||
if len(uniqueModelIDs) == 0 {
|
||||
// No models supplied; unregister existing client state if present.
|
||||
r.unregisterClientInternal(clientID)
|
||||
delete(r.clientModels, clientID)
|
||||
delete(r.clientProviders, clientID)
|
||||
misc.LogCredentialSeparator()
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
for _, model := range models {
|
||||
modelIDs = append(modelIDs, model.ID)
|
||||
|
||||
if existing, exists := r.models[model.ID]; exists {
|
||||
// Model already exists, increment count
|
||||
existing.Count++
|
||||
existing.LastUpdated = now
|
||||
if existing.SuspendedClients == nil {
|
||||
existing.SuspendedClients = make(map[string]string)
|
||||
}
|
||||
if provider != "" {
|
||||
if existing.Providers == nil {
|
||||
existing.Providers = make(map[string]int)
|
||||
}
|
||||
existing.Providers[provider]++
|
||||
}
|
||||
log.Debugf("Incremented count for model %s, now %d clients", model.ID, existing.Count)
|
||||
oldModels, hadExisting := r.clientModels[clientID]
|
||||
oldProvider, _ := r.clientProviders[clientID]
|
||||
providerChanged := oldProvider != provider
|
||||
if !hadExisting {
|
||||
// Pure addition path.
|
||||
for _, modelID := range rawModelIDs {
|
||||
model := newModels[modelID]
|
||||
r.addModelRegistration(modelID, provider, model, now)
|
||||
}
|
||||
r.clientModels[clientID] = append([]string(nil), rawModelIDs...)
|
||||
if provider != "" {
|
||||
r.clientProviders[clientID] = provider
|
||||
} else {
|
||||
// New model, create registration
|
||||
registration := &ModelRegistration{
|
||||
Info: model,
|
||||
Count: 1,
|
||||
LastUpdated: now,
|
||||
QuotaExceededClients: make(map[string]*time.Time),
|
||||
SuspendedClients: make(map[string]string),
|
||||
}
|
||||
if provider != "" {
|
||||
registration.Providers = map[string]int{provider: 1}
|
||||
}
|
||||
r.models[model.ID] = registration
|
||||
log.Debugf("Registered new model %s from provider %s", model.ID, clientProvider)
|
||||
delete(r.clientProviders, clientID)
|
||||
}
|
||||
log.Debugf("Registered client %s from provider %s with %d models", clientID, clientProvider, len(rawModelIDs))
|
||||
misc.LogCredentialSeparator()
|
||||
return
|
||||
}
|
||||
|
||||
oldCounts := make(map[string]int, len(oldModels))
|
||||
for _, id := range oldModels {
|
||||
oldCounts[id]++
|
||||
}
|
||||
|
||||
added := make([]string, 0)
|
||||
for _, id := range uniqueModelIDs {
|
||||
if oldCounts[id] == 0 {
|
||||
added = append(added, id)
|
||||
}
|
||||
}
|
||||
|
||||
r.clientModels[clientID] = modelIDs
|
||||
removed := make([]string, 0)
|
||||
for id := range oldCounts {
|
||||
if newCounts[id] == 0 {
|
||||
removed = append(removed, id)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle provider change for overlapping models before modifications.
|
||||
if providerChanged && oldProvider != "" {
|
||||
for id, newCount := range newCounts {
|
||||
if newCount == 0 {
|
||||
continue
|
||||
}
|
||||
oldCount := oldCounts[id]
|
||||
if oldCount == 0 {
|
||||
continue
|
||||
}
|
||||
toRemove := newCount
|
||||
if oldCount < toRemove {
|
||||
toRemove = oldCount
|
||||
}
|
||||
if reg, ok := r.models[id]; ok && reg.Providers != nil {
|
||||
if count, okProv := reg.Providers[oldProvider]; okProv {
|
||||
if count <= toRemove {
|
||||
delete(reg.Providers, oldProvider)
|
||||
} else {
|
||||
reg.Providers[oldProvider] = count - toRemove
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply removals first to keep counters accurate.
|
||||
for _, id := range removed {
|
||||
oldCount := oldCounts[id]
|
||||
for i := 0; i < oldCount; i++ {
|
||||
r.removeModelRegistration(clientID, id, oldProvider, now)
|
||||
}
|
||||
}
|
||||
|
||||
for id, oldCount := range oldCounts {
|
||||
newCount := newCounts[id]
|
||||
if newCount == 0 || oldCount <= newCount {
|
||||
continue
|
||||
}
|
||||
overage := oldCount - newCount
|
||||
for i := 0; i < overage; i++ {
|
||||
r.removeModelRegistration(clientID, id, oldProvider, now)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply additions.
|
||||
for id, newCount := range newCounts {
|
||||
oldCount := oldCounts[id]
|
||||
if newCount <= oldCount {
|
||||
continue
|
||||
}
|
||||
model := newModels[id]
|
||||
diff := newCount - oldCount
|
||||
for i := 0; i < diff; i++ {
|
||||
r.addModelRegistration(id, provider, model, now)
|
||||
}
|
||||
}
|
||||
|
||||
// Update metadata for models that remain associated with the client.
|
||||
addedSet := make(map[string]struct{}, len(added))
|
||||
for _, id := range added {
|
||||
addedSet[id] = struct{}{}
|
||||
}
|
||||
for _, id := range uniqueModelIDs {
|
||||
model := newModels[id]
|
||||
if reg, ok := r.models[id]; ok {
|
||||
reg.Info = cloneModelInfo(model)
|
||||
reg.LastUpdated = now
|
||||
if reg.QuotaExceededClients != nil {
|
||||
delete(reg.QuotaExceededClients, clientID)
|
||||
}
|
||||
if reg.SuspendedClients != nil {
|
||||
delete(reg.SuspendedClients, clientID)
|
||||
}
|
||||
if providerChanged && provider != "" {
|
||||
if _, newlyAdded := addedSet[id]; newlyAdded {
|
||||
continue
|
||||
}
|
||||
overlapCount := newCounts[id]
|
||||
if oldCount := oldCounts[id]; oldCount < overlapCount {
|
||||
overlapCount = oldCount
|
||||
}
|
||||
if overlapCount <= 0 {
|
||||
continue
|
||||
}
|
||||
if reg.Providers == nil {
|
||||
reg.Providers = make(map[string]int)
|
||||
}
|
||||
reg.Providers[provider] += overlapCount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update client bookkeeping.
|
||||
if len(rawModelIDs) > 0 {
|
||||
r.clientModels[clientID] = append([]string(nil), rawModelIDs...)
|
||||
}
|
||||
if provider != "" {
|
||||
r.clientProviders[clientID] = provider
|
||||
} else {
|
||||
delete(r.clientProviders, clientID)
|
||||
}
|
||||
log.Debugf("Registered client %s from provider %s with %d models", clientID, clientProvider, len(models))
|
||||
// Separator at the end of the registration block (acts as boundary to next group)
|
||||
|
||||
if len(added) == 0 && len(removed) == 0 && !providerChanged {
|
||||
// Only metadata (e.g., display name) changed; skip separator when no log output.
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("Reconciled client %s (provider %s) models: +%d, -%d", clientID, provider, len(added), len(removed))
|
||||
misc.LogCredentialSeparator()
|
||||
}
|
||||
|
||||
func (r *ModelRegistry) addModelRegistration(modelID, provider string, model *ModelInfo, now time.Time) {
|
||||
if model == nil || modelID == "" {
|
||||
return
|
||||
}
|
||||
if existing, exists := r.models[modelID]; exists {
|
||||
existing.Count++
|
||||
existing.LastUpdated = now
|
||||
existing.Info = cloneModelInfo(model)
|
||||
if existing.SuspendedClients == nil {
|
||||
existing.SuspendedClients = make(map[string]string)
|
||||
}
|
||||
if provider != "" {
|
||||
if existing.Providers == nil {
|
||||
existing.Providers = make(map[string]int)
|
||||
}
|
||||
existing.Providers[provider]++
|
||||
}
|
||||
log.Debugf("Incremented count for model %s, now %d clients", modelID, existing.Count)
|
||||
return
|
||||
}
|
||||
|
||||
registration := &ModelRegistration{
|
||||
Info: cloneModelInfo(model),
|
||||
Count: 1,
|
||||
LastUpdated: now,
|
||||
QuotaExceededClients: make(map[string]*time.Time),
|
||||
SuspendedClients: make(map[string]string),
|
||||
}
|
||||
if provider != "" {
|
||||
registration.Providers = map[string]int{provider: 1}
|
||||
}
|
||||
r.models[modelID] = registration
|
||||
log.Debugf("Registered new model %s from provider %s", modelID, provider)
|
||||
}
|
||||
|
||||
func (r *ModelRegistry) removeModelRegistration(clientID, modelID, provider string, now time.Time) {
|
||||
registration, exists := r.models[modelID]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
registration.Count--
|
||||
registration.LastUpdated = now
|
||||
if registration.QuotaExceededClients != nil {
|
||||
delete(registration.QuotaExceededClients, clientID)
|
||||
}
|
||||
if registration.SuspendedClients != nil {
|
||||
delete(registration.SuspendedClients, clientID)
|
||||
}
|
||||
if registration.Count < 0 {
|
||||
registration.Count = 0
|
||||
}
|
||||
if provider != "" && registration.Providers != nil {
|
||||
if count, ok := registration.Providers[provider]; ok {
|
||||
if count <= 1 {
|
||||
delete(registration.Providers, provider)
|
||||
} else {
|
||||
registration.Providers[provider] = count - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Debugf("Decremented count for model %s, now %d clients", modelID, registration.Count)
|
||||
if registration.Count <= 0 {
|
||||
delete(r.models, modelID)
|
||||
log.Debugf("Removed model %s as no clients remain", modelID)
|
||||
}
|
||||
}
|
||||
|
||||
func cloneModelInfo(model *ModelInfo) *ModelInfo {
|
||||
if model == nil {
|
||||
return nil
|
||||
}
|
||||
copy := *model
|
||||
if len(model.SupportedGenerationMethods) > 0 {
|
||||
copy.SupportedGenerationMethods = append([]string(nil), model.SupportedGenerationMethods...)
|
||||
}
|
||||
if len(model.SupportedParameters) > 0 {
|
||||
copy.SupportedParameters = append([]string(nil), model.SupportedParameters...)
|
||||
}
|
||||
return ©
|
||||
}
|
||||
|
||||
// UnregisterClient removes a client and decrements counts for its models
|
||||
// Parameters:
|
||||
// - clientID: Unique identifier for the client to remove
|
||||
|
||||
@@ -52,6 +52,39 @@ type Watcher struct {
|
||||
dispatchCancel context.CancelFunc
|
||||
}
|
||||
|
||||
type stableIDGenerator struct {
|
||||
counters map[string]int
|
||||
}
|
||||
|
||||
func newStableIDGenerator() *stableIDGenerator {
|
||||
return &stableIDGenerator{counters: make(map[string]int)}
|
||||
}
|
||||
|
||||
func (g *stableIDGenerator) next(kind string, parts ...string) (string, string) {
|
||||
if g == nil {
|
||||
return kind + ":000000000000", "000000000000"
|
||||
}
|
||||
hasher := sha256.New()
|
||||
hasher.Write([]byte(kind))
|
||||
for _, part := range parts {
|
||||
trimmed := strings.TrimSpace(part)
|
||||
hasher.Write([]byte{0})
|
||||
hasher.Write([]byte(trimmed))
|
||||
}
|
||||
digest := hex.EncodeToString(hasher.Sum(nil))
|
||||
if len(digest) < 12 {
|
||||
digest = fmt.Sprintf("%012s", digest)
|
||||
}
|
||||
short := digest[:12]
|
||||
key := kind + ":" + short
|
||||
index := g.counters[key]
|
||||
g.counters[key] = index + 1
|
||||
if index > 0 {
|
||||
short = fmt.Sprintf("%s-%d", short, index)
|
||||
}
|
||||
return fmt.Sprintf("%s:%s", kind, short), short
|
||||
}
|
||||
|
||||
// AuthUpdateAction represents the type of change detected in auth sources.
|
||||
type AuthUpdateAction string
|
||||
|
||||
@@ -640,6 +673,7 @@ func (w *Watcher) removeClient(path string) {
|
||||
func (w *Watcher) SnapshotCoreAuths() []*coreauth.Auth {
|
||||
out := make([]*coreauth.Auth, 0, 32)
|
||||
now := time.Now()
|
||||
idGen := newStableIDGenerator()
|
||||
// Also synthesize auth entries for OpenAI-compatibility providers directly from config
|
||||
w.clientsMutex.RLock()
|
||||
cfg := w.config
|
||||
@@ -647,14 +681,18 @@ func (w *Watcher) SnapshotCoreAuths() []*coreauth.Auth {
|
||||
if cfg != nil {
|
||||
// Gemini official API keys -> synthesize auths
|
||||
for i := range cfg.GlAPIKey {
|
||||
k := cfg.GlAPIKey[i]
|
||||
k := strings.TrimSpace(cfg.GlAPIKey[i])
|
||||
if k == "" {
|
||||
continue
|
||||
}
|
||||
id, token := idGen.next("gemini:apikey", k)
|
||||
a := &coreauth.Auth{
|
||||
ID: fmt.Sprintf("gemini:apikey:%d", i),
|
||||
ID: id,
|
||||
Provider: "gemini",
|
||||
Label: "gemini-apikey",
|
||||
Status: coreauth.StatusActive,
|
||||
Attributes: map[string]string{
|
||||
"source": fmt.Sprintf("config:gemini#%d", i),
|
||||
"source": fmt.Sprintf("config:gemini[%s]", token),
|
||||
"api_key": k,
|
||||
},
|
||||
CreatedAt: now,
|
||||
@@ -665,15 +703,20 @@ func (w *Watcher) SnapshotCoreAuths() []*coreauth.Auth {
|
||||
// Claude API keys -> synthesize auths
|
||||
for i := range cfg.ClaudeKey {
|
||||
ck := cfg.ClaudeKey[i]
|
||||
key := strings.TrimSpace(ck.APIKey)
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
id, token := idGen.next("claude:apikey", key, ck.BaseURL)
|
||||
attrs := map[string]string{
|
||||
"source": fmt.Sprintf("config:claude#%d", i),
|
||||
"api_key": ck.APIKey,
|
||||
"source": fmt.Sprintf("config:claude[%s]", token),
|
||||
"api_key": key,
|
||||
}
|
||||
if ck.BaseURL != "" {
|
||||
attrs["base_url"] = ck.BaseURL
|
||||
}
|
||||
a := &coreauth.Auth{
|
||||
ID: fmt.Sprintf("claude:apikey:%d", i),
|
||||
ID: id,
|
||||
Provider: "claude",
|
||||
Label: "claude-apikey",
|
||||
Status: coreauth.StatusActive,
|
||||
@@ -686,15 +729,20 @@ func (w *Watcher) SnapshotCoreAuths() []*coreauth.Auth {
|
||||
// Codex API keys -> synthesize auths
|
||||
for i := range cfg.CodexKey {
|
||||
ck := cfg.CodexKey[i]
|
||||
key := strings.TrimSpace(ck.APIKey)
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
id, token := idGen.next("codex:apikey", key, ck.BaseURL)
|
||||
attrs := map[string]string{
|
||||
"source": fmt.Sprintf("config:codex#%d", i),
|
||||
"api_key": ck.APIKey,
|
||||
"source": fmt.Sprintf("config:codex[%s]", token),
|
||||
"api_key": key,
|
||||
}
|
||||
if ck.BaseURL != "" {
|
||||
attrs["base_url"] = ck.BaseURL
|
||||
}
|
||||
a := &coreauth.Auth{
|
||||
ID: fmt.Sprintf("codex:apikey:%d", i),
|
||||
ID: id,
|
||||
Provider: "codex",
|
||||
Label: "codex-apikey",
|
||||
Status: coreauth.StatusActive,
|
||||
@@ -710,11 +758,16 @@ func (w *Watcher) SnapshotCoreAuths() []*coreauth.Auth {
|
||||
if providerName == "" {
|
||||
providerName = "openai-compatibility"
|
||||
}
|
||||
base := compat.BaseURL
|
||||
base := strings.TrimSpace(compat.BaseURL)
|
||||
for j := range compat.APIKeys {
|
||||
key := compat.APIKeys[j]
|
||||
key := strings.TrimSpace(compat.APIKeys[j])
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
idKind := fmt.Sprintf("openai-compatibility:%s", providerName)
|
||||
id, token := idGen.next(idKind, key, base)
|
||||
attrs := map[string]string{
|
||||
"source": fmt.Sprintf("config:%s#%d", compat.Name, j),
|
||||
"source": fmt.Sprintf("config:%s[%s]", providerName, token),
|
||||
"base_url": base,
|
||||
"api_key": key,
|
||||
"compat_name": compat.Name,
|
||||
@@ -724,7 +777,7 @@ func (w *Watcher) SnapshotCoreAuths() []*coreauth.Auth {
|
||||
attrs["models_hash"] = hash
|
||||
}
|
||||
a := &coreauth.Auth{
|
||||
ID: fmt.Sprintf("openai-compatibility:%s:%d", compat.Name, j),
|
||||
ID: id,
|
||||
Provider: providerName,
|
||||
Label: compat.Name,
|
||||
Status: coreauth.StatusActive,
|
||||
|
||||
Reference in New Issue
Block a user