diff --git a/internal/client/gemini-web_client.go b/internal/client/gemini-web_client.go index 3f7e0535..ebbf0c5c 100644 --- a/internal/client/gemini-web_client.go +++ b/internal/client/gemini-web_client.go @@ -172,6 +172,7 @@ func NewGeminiWebClient(cfg *config.Config, ts *gemini.GeminiWebTokenStorage, to go client.backgroundInitRetry() } else { client.cookieRotationStarted = true + client.registerModelsOnce() // Persist immediately once after successful init to capture fresh cookies _ = client.SaveTokenToFile() client.startCookiePersist() diff --git a/internal/client/qwen_client.go b/internal/client/qwen_client.go index 74e2416a..9eff9a46 100644 --- a/internal/client/qwen_client.go +++ b/internal/client/qwen_client.go @@ -70,12 +70,12 @@ func NewQwenClient(cfg *config.Config, ts *qwen.QwenTokenStorage, tokenFilePath // If created with a known token file path, record it. if len(tokenFilePath) > 0 && tokenFilePath[0] != "" { - client.tokenFilePath = tokenFilePath[0] + client.tokenFilePath = filepath.Clean(tokenFilePath[0]) } // If no explicit path provided but email exists, derive the canonical path. if client.tokenFilePath == "" && ts != nil && ts.Email != "" { - client.tokenFilePath = filepath.Join(cfg.AuthDir, fmt.Sprintf("qwen-%s.json", ts.Email)) + client.tokenFilePath = filepath.Clean(filepath.Join(cfg.AuthDir, fmt.Sprintf("qwen-%s.json", ts.Email))) } if client.tokenFilePath != "" { @@ -102,8 +102,10 @@ func NewQwenClient(cfg *config.Config, ts *qwen.QwenTokenStorage, tokenFilePath }, }, ) - if _, err := client.snapshotManager.Apply(); err != nil { + if applied, err := client.snapshotManager.Apply(); err != nil { log.Warnf("Failed to apply Qwen cookie snapshot for %s: %v", filepath.Base(client.tokenFilePath), err) + } else if applied { + log.Debugf("Loaded Qwen cookie snapshot: %s", filepath.Base(util.CookieSnapshotPath(client.tokenFilePath))) } } @@ -515,27 +517,29 @@ func (c *QwenClient) UnregisterClientWithReason(reason interfaces.UnregisterReas } func (c *QwenClient) unregisterClient(reason interfaces.UnregisterReason) { - if c.snapshotManager == nil { - return - } - switch reason { - case interfaces.UnregisterReasonAuthFileRemoved: - if c.tokenFilePath != "" { - log.Debugf("skipping Qwen snapshot flush because auth file is missing: %s", filepath.Base(c.tokenFilePath)) - util.RemoveCookieSnapshots(c.tokenFilePath) - } - case interfaces.UnregisterReasonAuthFileUpdated: - if c.tokenFilePath != "" { - log.Debugf("skipping Qwen snapshot flush because auth file was updated: %s", filepath.Base(c.tokenFilePath)) - util.RemoveCookieSnapshots(c.tokenFilePath) - } - case interfaces.UnregisterReasonShutdown, interfaces.UnregisterReasonReload: - if err := c.snapshotManager.Flush(); err != nil { - log.Errorf("Failed to flush Qwen cookie snapshot to main for %s: %v", filepath.Base(c.tokenFilePath), err) - } - default: - if err := c.snapshotManager.Flush(); err != nil { - log.Errorf("Failed to flush Qwen cookie snapshot to main for %s: %v", filepath.Base(c.tokenFilePath), err) - } + if c.snapshotManager != nil { + switch reason { + case interfaces.UnregisterReasonAuthFileRemoved: + if c.tokenFilePath != "" { + log.Debugf("skipping Qwen snapshot flush because auth file is missing: %s", filepath.Base(c.tokenFilePath)) + util.RemoveCookieSnapshots(c.tokenFilePath) + } + case interfaces.UnregisterReasonAuthFileUpdated: + if c.tokenFilePath != "" { + log.Debugf("skipping Qwen snapshot flush because auth file was updated: %s", filepath.Base(c.tokenFilePath)) + util.RemoveCookieSnapshots(c.tokenFilePath) + } + case interfaces.UnregisterReasonShutdown, interfaces.UnregisterReasonReload: + if err := c.snapshotManager.Flush(); err != nil { + log.Errorf("Failed to flush Qwen cookie snapshot to main for %s: %v", filepath.Base(c.tokenFilePath), err) + } + default: + if err := c.snapshotManager.Flush(); err != nil { + log.Errorf("Failed to flush Qwen cookie snapshot to main for %s: %v", filepath.Base(c.tokenFilePath), err) + } + } + } else if c.tokenFilePath != "" && (reason == interfaces.UnregisterReasonAuthFileRemoved || reason == interfaces.UnregisterReasonAuthFileUpdated) { + util.RemoveCookieSnapshots(c.tokenFilePath) } + c.ClientBase.UnregisterClient() } diff --git a/internal/cmd/run.go b/internal/cmd/run.go index 0c2904b2..453bec5f 100644 --- a/internal/cmd/run.go +++ b/internal/cmd/run.go @@ -139,7 +139,7 @@ func StartService(cfg *config.Config, configPath string) { if err = json.Unmarshal(data, &ts); err == nil { // For each valid Qwen token, create an authenticated client. log.Info("Initializing qwen authentication for token...") - qwenClient := client.NewQwenClient(cfg, &ts) + qwenClient := client.NewQwenClient(cfg, &ts, path) log.Info("Authentication successful.") cliClients[path] = qwenClient successfulAuthCount++ diff --git a/internal/watcher/watcher.go b/internal/watcher/watcher.go index 6cd5e54a..44f72e2f 100644 --- a/internal/watcher/watcher.go +++ b/internal/watcher/watcher.go @@ -393,7 +393,7 @@ func (w *Watcher) createClientFromFile(path string, cfg *config.Config) (interfa } else if tokenType == "qwen" { var ts qwen.QwenTokenStorage if err = json.Unmarshal(data, &ts); err == nil { - return client.NewQwenClient(cfg, &ts), nil + return client.NewQwenClient(cfg, &ts, path), nil } } else if tokenType == "gemini-web" { var ts gemini.GeminiWebTokenStorage