From 4bfafbe3aa51b01b240325e00e0cdaf2366cea5b Mon Sep 17 00:00:00 2001 From: hkfires <10558748+hkfires@users.noreply.github.com> Date: Fri, 19 Sep 2025 11:13:03 +0800 Subject: [PATCH] refactor(watcher): Move API key client creation to watcher package --- internal/cmd/run.go | 60 ++---------------------------------- internal/misc/credentials.go | 8 +++++ internal/watcher/watcher.go | 17 +++++++--- 3 files changed, 24 insertions(+), 61 deletions(-) diff --git a/internal/cmd/run.go b/internal/cmd/run.go index 453bec5f8..600acb68d 100644 --- a/internal/cmd/run.go +++ b/internal/cmd/run.go @@ -9,7 +9,6 @@ import ( "context" "encoding/json" "io/fs" - "net/http" "os" "os/signal" "path/filepath" @@ -26,7 +25,7 @@ import ( "github.com/luispater/CLIProxyAPI/v5/internal/client" "github.com/luispater/CLIProxyAPI/v5/internal/config" "github.com/luispater/CLIProxyAPI/v5/internal/interfaces" - "github.com/luispater/CLIProxyAPI/v5/internal/util" + "github.com/luispater/CLIProxyAPI/v5/internal/misc" "github.com/luispater/CLIProxyAPI/v5/internal/watcher" log "github.com/sirupsen/logrus" "github.com/tidwall/gjson" @@ -75,6 +74,7 @@ func StartService(cfg *config.Config, configPath string) { // Process only JSON files in the auth directory to load authentication tokens. if !info.IsDir() && strings.HasSuffix(info.Name(), ".json") { + misc.LogCredentialSeparator() log.Debugf("Loading token from: %s", path) data, errReadFile := os.ReadFile(path) if errReadFile != nil { @@ -170,7 +170,7 @@ func StartService(cfg *config.Config, configPath string) { log.Fatalf("Error walking auth directory: %v", err) } - apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := buildAPIKeyClients(cfg) + apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := watcher.BuildAPIKeyClients(cfg) totalNewClients := len(cliClients) + len(apiKeyClients) log.Infof("full client load complete - %d clients (%d auth files + %d GL API keys + %d Claude API keys + %d Codex keys + %d OpenAI-compat)", @@ -377,57 +377,3 @@ func clientsToSlice(clientMap map[string]interfaces.Client) []interfaces.Client } return s } - -// buildAPIKeyClients creates clients from API keys in the config -func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, int, int, int) { - apiKeyClients := make(map[string]interfaces.Client) - glAPIKeyCount := 0 - claudeAPIKeyCount := 0 - codexAPIKeyCount := 0 - openAICompatCount := 0 - - if len(cfg.GlAPIKey) > 0 { - for _, key := range cfg.GlAPIKey { - httpClient := util.SetProxy(cfg, &http.Client{}) - log.Debug("Initializing with Generative Language API Key...") - cliClient := client.NewGeminiClient(httpClient, cfg, key) - apiKeyClients[cliClient.GetClientID()] = cliClient - glAPIKeyCount++ - } - } - - if len(cfg.ClaudeKey) > 0 { - for i := range cfg.ClaudeKey { - log.Debug("Initializing with Claude API Key...") - cliClient := client.NewClaudeClientWithKey(cfg, i) - apiKeyClients[cliClient.GetClientID()] = cliClient - claudeAPIKeyCount++ - } - } - - if len(cfg.CodexKey) > 0 { - for i := range cfg.CodexKey { - log.Debug("Initializing with Codex API Key...") - cliClient := client.NewCodexClientWithKey(cfg, i) - apiKeyClients[cliClient.GetClientID()] = cliClient - codexAPIKeyCount++ - } - } - - if len(cfg.OpenAICompatibility) > 0 { - for _, compatConfig := range cfg.OpenAICompatibility { - for i := 0; i < len(compatConfig.APIKeys); i++ { - log.Debugf("Initializing OpenAI compatibility client for provider: %s", compatConfig.Name) - compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig, i) - if errClient != nil { - log.Errorf("failed to create OpenAI compatibility client for %s: %v", compatConfig.Name, errClient) - continue - } - apiKeyClients[compatClient.GetClientID()] = compatClient - openAICompatCount++ - } - } - } - - return apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount -} diff --git a/internal/misc/credentials.go b/internal/misc/credentials.go index f7e8119c2..8d36e9136 100644 --- a/internal/misc/credentials.go +++ b/internal/misc/credentials.go @@ -2,10 +2,13 @@ package misc import ( "path/filepath" + "strings" log "github.com/sirupsen/logrus" ) +var credentialSeparator = strings.Repeat("-", 70) + // LogSavingCredentials emits a consistent log message when persisting auth material. func LogSavingCredentials(path string) { if path == "" { @@ -14,3 +17,8 @@ func LogSavingCredentials(path string) { // Use filepath.Clean so logs remain stable even if callers pass redundant separators. log.Infof("Saving credentials to %s", filepath.Clean(path)) } + +// LogCredentialSeparator adds a visual separator to group auth/key processing logs. +func LogCredentialSeparator() { + log.Info(credentialSeparator) +} diff --git a/internal/watcher/watcher.go b/internal/watcher/watcher.go index a4393bb70..a6303f319 100644 --- a/internal/watcher/watcher.go +++ b/internal/watcher/watcher.go @@ -26,6 +26,7 @@ import ( "github.com/luispater/CLIProxyAPI/v5/internal/client" "github.com/luispater/CLIProxyAPI/v5/internal/config" "github.com/luispater/CLIProxyAPI/v5/internal/interfaces" + "github.com/luispater/CLIProxyAPI/v5/internal/misc" "github.com/luispater/CLIProxyAPI/v5/internal/util" log "github.com/sirupsen/logrus" "github.com/tidwall/gjson" @@ -302,7 +303,7 @@ func (w *Watcher) reloadClients() { } // Create new API key clients based on the new config - newAPIKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := buildAPIKeyClients(cfg) + newAPIKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := BuildAPIKeyClients(cfg) log.Debugf("created %d new API key clients", len(newAPIKeyClients)) // Load file-based clients @@ -604,6 +605,7 @@ func (w *Watcher) loadFileClients(cfg *config.Config) (map[string]interfaces.Cli } if !info.IsDir() && strings.HasSuffix(info.Name(), ".json") { authFileCount++ + misc.LogCredentialSeparator() log.Debugf("processing auth file %d: %s", authFileCount, filepath.Base(path)) if cliClient, errCreate := w.createClientFromFile(path, cfg); errCreate == nil && cliClient != nil { newClients[path] = cliClient @@ -622,8 +624,7 @@ func (w *Watcher) loadFileClients(cfg *config.Config) (map[string]interfaces.Cli return newClients, successfulAuthCount } -// buildAPIKeyClients creates clients from API keys in the config. -func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, int, int, int) { +func BuildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, int, int, int) { apiKeyClients := make(map[string]interfaces.Client) glAPIKeyCount := 0 claudeAPIKeyCount := 0 @@ -633,6 +634,8 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, if len(cfg.GlAPIKey) > 0 { for _, key := range cfg.GlAPIKey { httpClient := util.SetProxy(cfg, &http.Client{}) + misc.LogCredentialSeparator() + log.Debug("Initializing with Gemini API Key...") cliClient := client.NewGeminiClient(httpClient, cfg, key) apiKeyClients[cliClient.GetClientID()] = cliClient glAPIKeyCount++ @@ -640,6 +643,8 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, } if len(cfg.ClaudeKey) > 0 { for i := range cfg.ClaudeKey { + misc.LogCredentialSeparator() + log.Debug("Initializing with Claude API Key...") cliClient := client.NewClaudeClientWithKey(cfg, i) apiKeyClients[cliClient.GetClientID()] = cliClient claudeAPIKeyCount++ @@ -647,6 +652,8 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, } if len(cfg.CodexKey) > 0 { for i := range cfg.CodexKey { + misc.LogCredentialSeparator() + log.Debug("Initializing with Codex API Key...") cliClient := client.NewCodexClientWithKey(cfg, i) apiKeyClients[cliClient.GetClientID()] = cliClient codexAPIKeyCount++ @@ -655,9 +662,11 @@ func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, if len(cfg.OpenAICompatibility) > 0 { for _, compatConfig := range cfg.OpenAICompatibility { for i := 0; i < len(compatConfig.APIKeys); i++ { + misc.LogCredentialSeparator() + log.Debugf("Initializing OpenAI compatibility client for provider: %s", compatConfig.Name) compatClient, errClient := client.NewOpenAICompatibilityClient(cfg, &compatConfig, i) if errClient != nil { - log.Errorf("failed to create OpenAI-compatibility client for %s: %v", compatConfig.Name, errClient) + log.Errorf("failed to create OpenAI compatibility client for %s: %v", compatConfig.Name, errClient) continue } apiKeyClients[compatClient.GetClientID()] = compatClient