From 807e3670b158baa34f82ae3d677b42be16ba1fc9 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Fri, 20 Mar 2026 22:45:46 +0800 Subject: [PATCH] =?UTF-8?q?refactor(grok):=20=E7=A7=BB=E9=99=A4=E6=B5=81?= =?UTF-8?q?=E5=BC=8F=E8=AF=B7=E6=B1=82=E9=87=8D=E8=AF=95=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=B9=B6=E7=AE=80=E5=8C=96=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除 generateContentStream 方法中的重试机制及相关辅助方法,将错误处理简化为仅处理认证错误。版本号更新至 2.11.7.1。 --- VERSION | 2 +- src/providers/grok/grok-core.js | 73 ++++----------------------------- 2 files changed, 9 insertions(+), 66 deletions(-) diff --git a/VERSION b/VERSION index 34728b5..309cc3f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.11.7 +2.11.7.1 diff --git a/src/providers/grok/grok-core.js b/src/providers/grok/grok-core.js index 970f20c..50c6433 100644 --- a/src/providers/grok/grok-core.js +++ b/src/providers/grok/grok-core.js @@ -3,7 +3,7 @@ import logger from '../../utils/logger.js'; import * as http from 'http'; import * as https from 'https'; import { v4 as uuidv4 } from 'uuid'; -import { MODEL_PROTOCOL_PREFIX, isRetryableNetworkError } from '../../utils/common.js'; +import { MODEL_PROTOCOL_PREFIX } from '../../utils/common.js'; import { getProviderModels } from '../provider-models.js'; import { configureAxiosProxy, configureTLSSidecar } from '../../utils/proxy-utils.js'; import { MODEL_PROVIDER } from '../../utils/common.js'; @@ -85,34 +85,6 @@ export class GrokApiService { this.lastSyncAt = null; } - getMaxRequestRetries() { - const requestMaxRetries = Number.parseInt(this.config.REQUEST_MAX_RETRIES, 10); - if (Number.isFinite(requestMaxRetries) && requestMaxRetries > 0) { - return requestMaxRetries; - } - - return 3; - } - - classifyApiError(error) { - const status = error.response?.status; - const errorCode = error.code; - const errorMessage = error.message || ''; - const isNetworkError = isRetryableNetworkError(error); - - if (status === 401 || status === 403) { - error.shouldSwitchCredential = true; - error.message = 'Grok authentication failed (SSO token invalid or expired)'; - } else if (isNetworkError) { - // Network jitter or request timeout should not immediately degrade account health. - // Let the upper retry layer switch credential without incrementing the provider error count. - error.shouldSwitchCredential = true; - error.skipErrorCount = true; - } - - return { status, errorCode, errorMessage, isNetworkError }; - } - async setupNsfw() { if (this.nsfwSetupDone) return; try { @@ -509,11 +481,7 @@ export class GrokApiService { try { return (await axios(axiosConfig)).data; } catch (error) { return null; } } - async * generateContentStream(model, requestBody, retryCount = 0) { - const maxRetries = this.getMaxRequestRetries(); - const baseDelay = this.config.REQUEST_BASE_DELAY || 1000; - let hasYieldedData = false; - + async * generateContentStream(model, requestBody) { if (this.converter) { if (this.uuid) this.converter.setUuid(this.uuid); if (requestBody._requestBaseUrl) this.converter.setRequestBaseUrl(requestBody._requestBaseUrl); @@ -630,42 +598,17 @@ export class GrokApiService { } } } - hasYieldedData = true; yield json; } catch (e) {} } yield { result: { response: { isDone: true, responseId: lastResponseId, _requestBaseUrl: reqBaseUrl, _uuid: this.uuid } } }; - } catch (error) { - const { status, errorCode, errorMessage, isNetworkError } = this.classifyApiError(error); - const canRetryInRequest = !hasYieldedData && retryCount < maxRetries; + } catch (error) { this.handleApiError(error); } + } - if (status === 429 && canRetryInRequest) { - const delay = baseDelay * Math.pow(2, retryCount); - logger.info(`[Grok API] Received 429 during stream. Retrying in ${delay}ms... (attempt ${retryCount + 1}/${maxRetries})`); - await new Promise(resolve => setTimeout(resolve, delay)); - yield* this.generateContentStream(model, requestBody, retryCount + 1); - return; - } - - if (status >= 500 && status < 600 && canRetryInRequest) { - const delay = baseDelay * Math.pow(2, retryCount); - logger.info(`[Grok API] Received ${status} server error during stream. Retrying in ${delay}ms... (attempt ${retryCount + 1}/${maxRetries})`); - await new Promise(resolve => setTimeout(resolve, delay)); - yield* this.generateContentStream(model, requestBody, retryCount + 1); - return; - } - - if (isNetworkError && canRetryInRequest) { - const delay = baseDelay * Math.pow(2, retryCount); - const errorIdentifier = errorCode || errorMessage.substring(0, 50); - logger.info(`[Grok API] Network error (${errorIdentifier}) during stream. Retrying in ${delay}ms... (attempt ${retryCount + 1}/${maxRetries})`); - await new Promise(resolve => setTimeout(resolve, delay)); - yield* this.generateContentStream(model, requestBody, retryCount + 1); - return; - } - - throw error; - } + handleApiError(error) { + const status = error.response?.status; + if (status === 401 || status === 403) { error.shouldSwitchCredential = true; error.message = 'Grok authentication failed (SSO token invalid or expired)'; } + throw error; } async listModels() {