diff --git a/internal/deepseek/client_auth.go b/internal/deepseek/client_auth.go index 00c72a1..a510a27 100644 --- a/internal/deepseek/client_auth.go +++ b/internal/deepseek/client_auth.go @@ -165,8 +165,40 @@ func shouldAttemptRefresh(status int, code int, bizCode int, msg string, bizMsg return true } // Some DeepSeek failures come back as HTTP 200/code=0 but with non-zero biz_code. - // In managed-account mode this is commonly stale login state, so try one refresh. - return status == http.StatusOK && code == 0 && bizCode != 0 + // Only attempt refresh when these biz failures still look auth-related. + return status == http.StatusOK && + code == 0 && + bizCode != 0 && + isAuthIndicativeBizFailure(msg, bizMsg) +} + +func isAuthIndicativeBizFailure(msg string, bizMsg string) bool { + combined := strings.ToLower(strings.TrimSpace(msg) + " " + strings.TrimSpace(bizMsg)) + authKeywords := []string{ + "auth", + "authorization", + "credential", + "expired", + "invalid jwt", + "jwt", + "login", + "not login", + "session expired", + "token", + "unauthorized", + "登录", + "未登录", + "认证", + "凭证", + "会话过期", + "令牌", + } + for _, keyword := range authKeywords { + if strings.Contains(combined, keyword) { + return true + } + } + return false } func extractResponseStatus(resp map[string]any) (code int, bizCode int, msg string, bizMsg string) { diff --git a/internal/deepseek/client_auth_refresh_test.go b/internal/deepseek/client_auth_refresh_test.go index b411bb7..2506a00 100644 --- a/internal/deepseek/client_auth_refresh_test.go +++ b/internal/deepseek/client_auth_refresh_test.go @@ -8,9 +8,15 @@ func TestShouldAttemptRefreshOnTokenInvalidSignal(t *testing.T) { } } -func TestShouldAttemptRefreshOnBizCodeOnlyFailure(t *testing.T) { - if !shouldAttemptRefresh(200, 0, 400123, "", "session create failed") { - t.Fatal("expected refresh on non-zero biz_code with HTTP 200/code=0") +func TestShouldAttemptRefreshOnAuthIndicativeBizCodeFailure(t *testing.T) { + if !shouldAttemptRefresh(200, 0, 400123, "", "login expired, token invalid") { + t.Fatal("expected refresh on auth-indicative biz_code failure") + } +} + +func TestShouldAttemptRefreshFalseOnNonAuthBizCodeFailure(t *testing.T) { + if shouldAttemptRefresh(200, 0, 400123, "", "session create failed: quota reached") { + t.Fatal("did not expect refresh on non-auth biz_code failure") } }