From 0654d9330b9b510d0024c3848b130b1e724b8c81 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sat, 11 Apr 2026 19:50:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(grok):=20=E4=BF=AE=E6=AD=A3=E6=B5=81?= =?UTF-8?q?=E5=BC=8F=E5=93=8D=E5=BA=94=E4=B8=ADClaude=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E9=80=BB=E8=BE=91=E5=B9=B6=E6=8F=90=E5=8F=96?= =?UTF-8?q?=E4=B8=BA=E7=8B=AC=E7=AB=8B=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构GrokConverter中的Claude流式转换逻辑,将原先内联的复杂分支提取为独立的toClaudeStreamChunk方法,提高代码可维护性。同时调整grok-core.js中usage payload的附加时机,确保在响应存在时才附加估算数据。 --- VERSION | 2 +- src/converters/strategies/GrokConverter.js | 92 ++++++++++++---------- src/providers/grok/grok-core.js | 12 +-- 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/VERSION b/VERSION index 49e570d..14239ef 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.13.5.1 +2.13.6 diff --git a/src/converters/strategies/GrokConverter.js b/src/converters/strategies/GrokConverter.js index efde2d9..3ebb621 100644 --- a/src/converters/strategies/GrokConverter.js +++ b/src/converters/strategies/GrokConverter.js @@ -467,48 +467,8 @@ export class GrokConverter extends BaseConverter { return this.toOpenAIResponsesStreamChunk(chunk, model); case MODEL_PROTOCOL_PREFIX.CODEX: return this.toCodexStreamChunk(chunk, model); - case MODEL_PROTOCOL_PREFIX.CLAUDE: { - const openaiPieces = this.toOpenAIStreamChunk(chunk, model); - if (!openaiPieces) return null; - const key = requestId || '_'; - const openaiConverter = ConverterFactory.getConverter(MODEL_PROTOCOL_PREFIX.OPENAI); - const pieces = Array.isArray(openaiPieces) ? openaiPieces : [openaiPieces]; - const out = []; - for (const p of pieces) { - const events = openaiConverter.toClaudeStreamChunk(p, model); - if (!events) continue; - const arr = Array.isArray(events) ? events : [events]; - for (const ev of arr) { - if (!this._claudeMsgStartSent.get(key)) { - this._claudeMsgStartSent.set(key, true); - const msgId = `msg_${String(p.id || uuidv4()).replace(/^chatcmpl-/, '')}`; - out.push({ - type: 'message_start', - message: { - id: msgId, - type: 'message', - role: 'assistant', - content: [], - model: model || p.model || 'unknown', - stop_reason: null, - stop_sequence: null, - usage: { - input_tokens: 0, - output_tokens: 0, - cache_creation_input_tokens: 0, - cache_read_input_tokens: 0 - } - } - }); - } - out.push(ev); - } - } - if (chunk?.result?.response?.isDone) { - this._claudeMsgStartSent.delete(key); - } - return out.length === 0 ? null : (out.length === 1 ? out[0] : out); - } + case MODEL_PROTOCOL_PREFIX.CLAUDE: + return this.toClaudeStreamChunk(chunk, model, requestId); default: return chunk; } @@ -1424,6 +1384,54 @@ export class GrokConverter extends BaseConverter { return codexChunks.length > 0 ? codexChunks : null; } + toClaudeStreamChunk(chunk, model, requestId) { + const openaiPieces = this.toOpenAIStreamChunk(chunk, model); + if (!openaiPieces) return null; + + const key = requestId || '_'; + const openaiConverter = ConverterFactory.getConverter(MODEL_PROTOCOL_PREFIX.OPENAI); + const pieces = Array.isArray(openaiPieces) ? openaiPieces : [openaiPieces]; + const out = []; + + for (const p of pieces) { + const events = openaiConverter.toClaudeStreamChunk(p, model); + if (!events) continue; + + const arr = Array.isArray(events) ? events : [events]; + for (const ev of arr) { + if (!this._claudeMsgStartSent.get(key)) { + this._claudeMsgStartSent.set(key, true); + const msgId = `msg_${String(p.id || uuidv4()).replace(/^chatcmpl-/, '')}`; + out.push({ + type: 'message_start', + message: { + id: msgId, + type: 'message', + role: 'assistant', + content: [], + model: model || p.model || 'unknown', + stop_reason: null, + stop_sequence: null, + usage: { + input_tokens: 0, + output_tokens: 0, + cache_creation_input_tokens: 0, + cache_read_input_tokens: 0 + } + } + }); + } + out.push(ev); + } + } + + if (chunk?.result?.response?.isDone) { + this._claudeMsgStartSent.delete(key); + } + + return out.length === 0 ? null : (out.length === 1 ? out[0] : out); + } + /** * Grok模型列表 -> OpenAI模型列表 */ diff --git a/src/providers/grok/grok-core.js b/src/providers/grok/grok-core.js index da919a9..4e043cf 100644 --- a/src/providers/grok/grok-core.js +++ b/src/providers/grok/grok-core.js @@ -1348,15 +1348,11 @@ export class GrokApiService { if (dataStr === '[DONE]') break; try { const json = JSON.parse(dataStr); - if (json.result && requestBody && !grokStreamUsagePayloadAttached) { - json.result._grokUsageEstimatePayload = { - promptText: requestBody.message || "", - toolsJson: requestBody.tools && Array.isArray(requestBody.tools) && requestBody.tools.length - ? JSON.stringify(requestBody.tools) : "" - }; - grokStreamUsagePayloadAttached = true; - } if (json.result?.response) { + if (requestBody && !grokStreamUsagePayloadAttached) { + attachGrokUsageEstimatePayload(json.result, requestBody); + grokStreamUsagePayloadAttached = true; + } const resp = json.result.response; resp._requestBaseUrl = reqBaseUrl; resp._uuid = this.uuid;