fix(grok): 修正流式响应中Claude协议转换逻辑并提取为独立方法
重构GrokConverter中的Claude流式转换逻辑,将原先内联的复杂分支提取为独立的toClaudeStreamChunk方法,提高代码可维护性。同时调整grok-core.js中usage payload的附加时机,确保在响应存在时才附加估算数据。
This commit is contained in:
parent
0818e608cf
commit
0654d9330b
3 changed files with 55 additions and 51 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
2.13.5.1
|
||||
2.13.6
|
||||
|
|
|
|||
|
|
@ -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模型列表
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue