feat(converter): 为Grok协议添加完整的转换支持
- 在GeminiConverter、ClaudeConverter和OpenAIResponsesConverter中增加toGrokRequest方法 - 扩展GrokConverter以支持向Gemini、OpenAI Responses、Codex等协议的响应转换 - 移除IFLOW_API适配器的注册以清理未使用的代码 - 修复Grok媒体URL处理中不必要的SSO令牌追加逻辑
This commit is contained in:
parent
3f8fdc0b8e
commit
0b071f261d
6 changed files with 709 additions and 548 deletions
|
|
@ -53,6 +53,8 @@ export class ClaudeConverter extends BaseConverter {
|
||||||
return this.toOpenAIResponsesRequest(data);
|
return this.toOpenAIResponsesRequest(data);
|
||||||
case MODEL_PROTOCOL_PREFIX.CODEX:
|
case MODEL_PROTOCOL_PREFIX.CODEX:
|
||||||
return this.toCodexRequest(data);
|
return this.toCodexRequest(data);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.GROK:
|
||||||
|
return this.toGrokRequest(data);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported target protocol: ${targetProtocol}`);
|
throw new Error(`Unsupported target protocol: ${targetProtocol}`);
|
||||||
}
|
}
|
||||||
|
|
@ -2094,6 +2096,18 @@ export class ClaudeConverter extends BaseConverter {
|
||||||
return codexRequest;
|
return codexRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Claude请求 -> Grok请求
|
||||||
|
*/
|
||||||
|
toGrokRequest(claudeRequest) {
|
||||||
|
// 先转换为 OpenAI 格式,因为 Grok 兼容 OpenAI 格式
|
||||||
|
const openaiRequest = this.toOpenAIRequest(claudeRequest);
|
||||||
|
return {
|
||||||
|
...openaiRequest,
|
||||||
|
_isConverted: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Claude响应 -> Codex响应 (实际上是 Codex 转 Claude)
|
* Claude响应 -> Codex响应 (实际上是 Codex 转 Claude)
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,8 @@ export class GeminiConverter extends BaseConverter {
|
||||||
return this.toOpenAIResponsesRequest(data);
|
return this.toOpenAIResponsesRequest(data);
|
||||||
case MODEL_PROTOCOL_PREFIX.CODEX:
|
case MODEL_PROTOCOL_PREFIX.CODEX:
|
||||||
return this.toCodexRequest(data);
|
return this.toCodexRequest(data);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.GROK:
|
||||||
|
return this.toGrokRequest(data);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported target protocol: ${targetProtocol}`);
|
throw new Error(`Unsupported target protocol: ${targetProtocol}`);
|
||||||
}
|
}
|
||||||
|
|
@ -1416,6 +1418,18 @@ export class GeminiConverter extends BaseConverter {
|
||||||
return codexRequest;
|
return codexRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gemini请求 -> Grok请求
|
||||||
|
*/
|
||||||
|
toGrokRequest(geminiRequest) {
|
||||||
|
// 先转换为 OpenAI 格式
|
||||||
|
const openaiRequest = this.toOpenAIRequest(geminiRequest);
|
||||||
|
return {
|
||||||
|
...openaiRequest,
|
||||||
|
_isConverted: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gemini响应 -> Codex响应 (实际上是 Codex 转 Gemini)
|
* Gemini响应 -> Codex响应 (实际上是 Codex 转 Gemini)
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,10 @@ export class GrokConverter extends BaseConverter {
|
||||||
* 转换请求
|
* 转换请求
|
||||||
*/
|
*/
|
||||||
convertRequest(data, targetProtocol) {
|
convertRequest(data, targetProtocol) {
|
||||||
return data;
|
switch (targetProtocol) {
|
||||||
|
default:
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -254,6 +257,12 @@ export class GrokConverter extends BaseConverter {
|
||||||
switch (targetProtocol) {
|
switch (targetProtocol) {
|
||||||
case MODEL_PROTOCOL_PREFIX.OPENAI:
|
case MODEL_PROTOCOL_PREFIX.OPENAI:
|
||||||
return this.toOpenAIResponse(data, model);
|
return this.toOpenAIResponse(data, model);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.GEMINI:
|
||||||
|
return this.toGeminiResponse(data, model);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.OPENAI_RESPONSES:
|
||||||
|
return this.toOpenAIResponsesResponse(data, model);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.CODEX:
|
||||||
|
return this.toCodexResponse(data, model);
|
||||||
default:
|
default:
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
@ -266,6 +275,12 @@ export class GrokConverter extends BaseConverter {
|
||||||
switch (targetProtocol) {
|
switch (targetProtocol) {
|
||||||
case MODEL_PROTOCOL_PREFIX.OPENAI:
|
case MODEL_PROTOCOL_PREFIX.OPENAI:
|
||||||
return this.toOpenAIStreamChunk(chunk, model);
|
return this.toOpenAIStreamChunk(chunk, model);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.GEMINI:
|
||||||
|
return this.toGeminiStreamChunk(chunk, model);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.OPENAI_RESPONSES:
|
||||||
|
return this.toOpenAIResponsesStreamChunk(chunk, model);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.CODEX:
|
||||||
|
return this.toCodexStreamChunk(chunk, model);
|
||||||
default:
|
default:
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +290,14 @@ export class GrokConverter extends BaseConverter {
|
||||||
* 转换模型列表
|
* 转换模型列表
|
||||||
*/
|
*/
|
||||||
convertModelList(data, targetProtocol) {
|
convertModelList(data, targetProtocol) {
|
||||||
return data;
|
switch (targetProtocol) {
|
||||||
|
case MODEL_PROTOCOL_PREFIX.OPENAI:
|
||||||
|
return this.toOpenAIModelList(data);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.GEMINI:
|
||||||
|
return this.toGeminiModelList(data);
|
||||||
|
default:
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -360,15 +382,13 @@ export class GrokConverter extends BaseConverter {
|
||||||
if (!videoUrl.startsWith('http')) {
|
if (!videoUrl.startsWith('http')) {
|
||||||
finalVideoUrl = `https://assets.grok.com${videoUrl.startsWith('/') ? '' : '/'}${videoUrl}`;
|
finalVideoUrl = `https://assets.grok.com${videoUrl.startsWith('/') ? '' : '/'}${videoUrl}`;
|
||||||
}
|
}
|
||||||
finalVideoUrl = this._appendSsoToken(finalVideoUrl, state);
|
|
||||||
|
|
||||||
let finalThumbUrl = thumbnailImageUrl;
|
let finalThumbUrl = thumbnailImageUrl;
|
||||||
if (thumbnailImageUrl && !thumbnailImageUrl.startsWith('http')) {
|
if (thumbnailImageUrl && !thumbnailImageUrl.startsWith('http')) {
|
||||||
finalThumbUrl = `https://assets.grok.com${thumbnailImageUrl.startsWith('/') ? '' : '/'}${thumbnailImageUrl}`;
|
finalThumbUrl = `https://assets.grok.com${thumbnailImageUrl.startsWith('/') ? '' : '/'}${thumbnailImageUrl}`;
|
||||||
}
|
}
|
||||||
finalThumbUrl = this._appendSsoToken(finalThumbUrl, state);
|
|
||||||
|
|
||||||
const defaultThumb = this._appendSsoToken('https://assets.grok.com/favicon.ico', state);
|
const defaultThumb = 'https://assets.grok.com/favicon.ico';
|
||||||
return `\n[](${finalVideoUrl})\n[Play Video](${finalVideoUrl})\n`;
|
return `\n[](${finalVideoUrl})\n[Play Video](${finalVideoUrl})\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -783,4 +803,351 @@ export class GrokConverter extends BaseConverter {
|
||||||
|
|
||||||
return chunks.length > 0 ? chunks : null;
|
return chunks.length > 0 ? chunks : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grok响应 -> Gemini响应
|
||||||
|
*/
|
||||||
|
toGeminiResponse(grokResponse, model) {
|
||||||
|
const openaiRes = this.toOpenAIResponse(grokResponse, model);
|
||||||
|
if (!openaiRes) return null;
|
||||||
|
|
||||||
|
const choice = openaiRes.choices[0];
|
||||||
|
const message = choice.message;
|
||||||
|
const parts = [];
|
||||||
|
|
||||||
|
if (message.reasoning_content) {
|
||||||
|
parts.push({ text: message.reasoning_content, thought: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.content) {
|
||||||
|
parts.push({ text: message.content });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.tool_calls) {
|
||||||
|
for (const tc of message.tool_calls) {
|
||||||
|
parts.push({
|
||||||
|
functionCall: {
|
||||||
|
name: tc.function.name,
|
||||||
|
args: typeof tc.function.arguments === 'string' ? JSON.parse(tc.function.arguments) : tc.function.arguments
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
candidates: [{
|
||||||
|
content: {
|
||||||
|
role: 'model',
|
||||||
|
parts: parts
|
||||||
|
},
|
||||||
|
finishReason: choice.finish_reason === 'tool_calls' ? 'STOP' : (choice.finish_reason === 'length' ? 'MAX_TOKENS' : 'STOP')
|
||||||
|
}],
|
||||||
|
usageMetadata: {
|
||||||
|
promptTokenCount: openaiRes.usage.prompt_tokens,
|
||||||
|
candidatesTokenCount: openaiRes.usage.completion_tokens,
|
||||||
|
totalTokenCount: openaiRes.usage.total_tokens
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grok流式响应块 -> Gemini流式响应块
|
||||||
|
*/
|
||||||
|
toGeminiStreamChunk(grokChunk, model) {
|
||||||
|
const openaiChunks = this.toOpenAIStreamChunk(grokChunk, model);
|
||||||
|
if (!openaiChunks) return null;
|
||||||
|
|
||||||
|
const geminiChunks = [];
|
||||||
|
for (const oachunk of openaiChunks) {
|
||||||
|
const choice = oachunk.choices[0];
|
||||||
|
const delta = choice.delta;
|
||||||
|
const parts = [];
|
||||||
|
|
||||||
|
if (delta.reasoning_content) {
|
||||||
|
parts.push({ text: delta.reasoning_content, thought: true });
|
||||||
|
}
|
||||||
|
if (delta.content) {
|
||||||
|
parts.push({ text: delta.content });
|
||||||
|
}
|
||||||
|
if (delta.tool_calls) {
|
||||||
|
for (const tc of delta.tool_calls) {
|
||||||
|
parts.push({
|
||||||
|
functionCall: {
|
||||||
|
name: tc.function.name,
|
||||||
|
args: typeof tc.function.arguments === 'string' ? JSON.parse(tc.function.arguments) : tc.function.arguments
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts.length > 0 || choice.finish_reason) {
|
||||||
|
const gchunk = {
|
||||||
|
candidates: [{
|
||||||
|
content: {
|
||||||
|
role: 'model',
|
||||||
|
parts: parts
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
if (choice.finish_reason) {
|
||||||
|
gchunk.candidates[0].finishReason = choice.finish_reason === 'length' ? 'MAX_TOKENS' : 'STOP';
|
||||||
|
}
|
||||||
|
geminiChunks.push(gchunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return geminiChunks.length > 0 ? geminiChunks : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grok响应 -> OpenAI Responses响应
|
||||||
|
*/
|
||||||
|
toOpenAIResponsesResponse(grokResponse, model) {
|
||||||
|
const openaiRes = this.toOpenAIResponse(grokResponse, model);
|
||||||
|
if (!openaiRes) return null;
|
||||||
|
|
||||||
|
const choice = openaiRes.choices[0];
|
||||||
|
const message = choice.message;
|
||||||
|
const output = [];
|
||||||
|
|
||||||
|
const content = [];
|
||||||
|
if (message.content) {
|
||||||
|
content.push({
|
||||||
|
type: "output_text",
|
||||||
|
text: message.content
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push({
|
||||||
|
id: `msg_${uuidv4().replace(/-/g, '')}`,
|
||||||
|
type: "message",
|
||||||
|
role: "assistant",
|
||||||
|
status: "completed",
|
||||||
|
content: content
|
||||||
|
});
|
||||||
|
|
||||||
|
if (message.tool_calls) {
|
||||||
|
for (const tc of message.tool_calls) {
|
||||||
|
output.push({
|
||||||
|
id: tc.id,
|
||||||
|
type: "function_call",
|
||||||
|
name: tc.function.name,
|
||||||
|
arguments: tc.function.arguments,
|
||||||
|
status: "completed"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: `resp_${uuidv4().replace(/-/g, '')}`,
|
||||||
|
object: "response",
|
||||||
|
created_at: Math.floor(Date.now() / 1000),
|
||||||
|
status: "completed",
|
||||||
|
model: model,
|
||||||
|
output: output,
|
||||||
|
usage: {
|
||||||
|
input_tokens: openaiRes.usage.prompt_tokens,
|
||||||
|
output_tokens: openaiRes.usage.completion_tokens,
|
||||||
|
total_tokens: openaiRes.usage.total_tokens
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grok流式响应块 -> OpenAI Responses流式响应块
|
||||||
|
*/
|
||||||
|
toOpenAIResponsesStreamChunk(grokChunk, model) {
|
||||||
|
const openaiChunks = this.toOpenAIStreamChunk(grokChunk, model);
|
||||||
|
if (!openaiChunks) return null;
|
||||||
|
|
||||||
|
const events = [];
|
||||||
|
for (const oachunk of openaiChunks) {
|
||||||
|
const choice = oachunk.choices[0];
|
||||||
|
const delta = choice.delta;
|
||||||
|
|
||||||
|
if (delta.role === 'assistant') {
|
||||||
|
events.push({ type: "response.created", response: { id: oachunk.id, model: model } });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta.reasoning_content) {
|
||||||
|
events.push({
|
||||||
|
type: "response.reasoning_summary_text.delta",
|
||||||
|
delta: delta.reasoning_content,
|
||||||
|
response_id: oachunk.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta.content) {
|
||||||
|
events.push({
|
||||||
|
type: "response.output_text.delta",
|
||||||
|
delta: delta.content,
|
||||||
|
response_id: oachunk.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta.tool_calls) {
|
||||||
|
for (const tc of delta.tool_calls) {
|
||||||
|
if (tc.function?.name) {
|
||||||
|
events.push({
|
||||||
|
type: "response.output_item.added",
|
||||||
|
item: { id: tc.id, type: "function_call", name: tc.function.name, arguments: "" },
|
||||||
|
response_id: oachunk.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (tc.function?.arguments) {
|
||||||
|
events.push({
|
||||||
|
type: "response.custom_tool_call_input.delta",
|
||||||
|
delta: tc.function.arguments,
|
||||||
|
item_id: tc.id,
|
||||||
|
response_id: oachunk.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (choice.finish_reason) {
|
||||||
|
events.push({ type: "response.completed", response: { id: oachunk.id, status: "completed" } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grok响应 -> Codex响应
|
||||||
|
*/
|
||||||
|
toCodexResponse(grokResponse, model) {
|
||||||
|
const openaiRes = this.toOpenAIResponse(grokResponse, model);
|
||||||
|
if (!openaiRes) return null;
|
||||||
|
|
||||||
|
const choice = openaiRes.choices[0];
|
||||||
|
const message = choice.message;
|
||||||
|
const output = [];
|
||||||
|
|
||||||
|
if (message.content) {
|
||||||
|
output.push({
|
||||||
|
type: "message",
|
||||||
|
role: "assistant",
|
||||||
|
content: [{ type: "output_text", text: message.content }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.reasoning_content) {
|
||||||
|
output.push({
|
||||||
|
type: "reasoning",
|
||||||
|
summary: [{ type: "summary_text", text: message.reasoning_content }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.tool_calls) {
|
||||||
|
for (const tc of message.tool_calls) {
|
||||||
|
output.push({
|
||||||
|
type: "function_call",
|
||||||
|
call_id: tc.id,
|
||||||
|
name: tc.function.name,
|
||||||
|
arguments: tc.function.arguments
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
response: {
|
||||||
|
id: openaiRes.id,
|
||||||
|
output: output,
|
||||||
|
usage: {
|
||||||
|
input_tokens: openaiRes.usage.prompt_tokens,
|
||||||
|
output_tokens: openaiRes.usage.completion_tokens,
|
||||||
|
total_tokens: openaiRes.usage.total_tokens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grok流式响应块 -> Codex流式响应块
|
||||||
|
*/
|
||||||
|
toCodexStreamChunk(grokChunk, model) {
|
||||||
|
const openaiChunks = this.toOpenAIStreamChunk(grokChunk, model);
|
||||||
|
if (!openaiChunks) return null;
|
||||||
|
|
||||||
|
const codexChunks = [];
|
||||||
|
for (const oachunk of openaiChunks) {
|
||||||
|
const choice = oachunk.choices[0];
|
||||||
|
const delta = choice.delta;
|
||||||
|
|
||||||
|
if (delta.role === 'assistant') {
|
||||||
|
codexChunks.push({ type: "response.created", response: { id: oachunk.id } });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta.reasoning_content) {
|
||||||
|
codexChunks.push({
|
||||||
|
type: "response.reasoning_summary_text.delta",
|
||||||
|
delta: delta.reasoning_content,
|
||||||
|
response: { id: oachunk.id }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta.content) {
|
||||||
|
codexChunks.push({
|
||||||
|
type: "response.output_text.delta",
|
||||||
|
delta: delta.content,
|
||||||
|
response: { id: oachunk.id }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta.tool_calls) {
|
||||||
|
for (const tc of delta.tool_calls) {
|
||||||
|
if (tc.function?.arguments) {
|
||||||
|
codexChunks.push({
|
||||||
|
type: "response.custom_tool_call_input.delta",
|
||||||
|
delta: tc.function.arguments,
|
||||||
|
item_id: tc.id,
|
||||||
|
response: { id: oachunk.id }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (choice.finish_reason) {
|
||||||
|
codexChunks.push({ type: "response.completed", response: { id: oachunk.id, usage: oachunk.usage } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return codexChunks.length > 0 ? codexChunks : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grok模型列表 -> OpenAI模型列表
|
||||||
|
*/
|
||||||
|
toOpenAIModelList(grokModels) {
|
||||||
|
const models = Array.isArray(grokModels) ? grokModels : (grokModels?.models || []);
|
||||||
|
return {
|
||||||
|
object: "list",
|
||||||
|
data: models.map(m => ({
|
||||||
|
id: m.id || m.name,
|
||||||
|
object: "model",
|
||||||
|
created: Math.floor(Date.now() / 1000),
|
||||||
|
owned_by: "xai",
|
||||||
|
display_name: m.name || m.id,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grok模型列表 -> Gemini模型列表
|
||||||
|
*/
|
||||||
|
toGeminiModelList(grokModels) {
|
||||||
|
const models = Array.isArray(grokModels) ? grokModels : (grokModels?.models || []);
|
||||||
|
return {
|
||||||
|
models: models.map(m => ({
|
||||||
|
name: `models/${m.id || m.name}`,
|
||||||
|
version: "1.0",
|
||||||
|
displayName: m.name || m.id,
|
||||||
|
description: m.description || `Grok model: ${m.name || m.id}`,
|
||||||
|
inputTokenLimit: 131072,
|
||||||
|
outputTokenLimit: 8192,
|
||||||
|
supportedGenerationMethods: ["generateContent", "streamGenerateContent"]
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ export class OpenAIResponsesConverter extends BaseConverter {
|
||||||
return this.toGeminiRequest(data);
|
return this.toGeminiRequest(data);
|
||||||
case MODEL_PROTOCOL_PREFIX.CODEX:
|
case MODEL_PROTOCOL_PREFIX.CODEX:
|
||||||
return this.toCodexRequest(data);
|
return this.toCodexRequest(data);
|
||||||
|
case MODEL_PROTOCOL_PREFIX.GROK:
|
||||||
|
return this.toGrokRequest(data);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported target protocol: ${toProtocol}`);
|
throw new Error(`Unsupported target protocol: ${toProtocol}`);
|
||||||
}
|
}
|
||||||
|
|
@ -808,6 +810,18 @@ export class OpenAIResponsesConverter extends BaseConverter {
|
||||||
return this.codexConverter.toOpenAIResponsesToCodexRequest(responsesRequest);
|
return this.codexConverter.toOpenAIResponsesToCodexRequest(responsesRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenAI Responses → Grok 请求转换
|
||||||
|
*/
|
||||||
|
toGrokRequest(responsesRequest) {
|
||||||
|
// 先转换为 OpenAI 格式
|
||||||
|
const openaiRequest = this.toOpenAIRequest(responsesRequest);
|
||||||
|
return {
|
||||||
|
...openaiRequest,
|
||||||
|
_isConverted: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// 辅助方法
|
// 辅助方法
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
|
||||||
|
|
@ -696,7 +696,7 @@ registerAdapter(MODEL_PROVIDER.ANTIGRAVITY, AntigravityApiServiceAdapter);
|
||||||
registerAdapter(MODEL_PROVIDER.CLAUDE_CUSTOM, ClaudeApiServiceAdapter);
|
registerAdapter(MODEL_PROVIDER.CLAUDE_CUSTOM, ClaudeApiServiceAdapter);
|
||||||
registerAdapter(MODEL_PROVIDER.KIRO_API, KiroApiServiceAdapter);
|
registerAdapter(MODEL_PROVIDER.KIRO_API, KiroApiServiceAdapter);
|
||||||
registerAdapter(MODEL_PROVIDER.QWEN_API, QwenApiServiceAdapter);
|
registerAdapter(MODEL_PROVIDER.QWEN_API, QwenApiServiceAdapter);
|
||||||
registerAdapter(MODEL_PROVIDER.IFLOW_API, IFlowApiServiceAdapter);
|
// registerAdapter(MODEL_PROVIDER.IFLOW_API, IFlowApiServiceAdapter);
|
||||||
registerAdapter(MODEL_PROVIDER.CODEX_API, CodexApiServiceAdapter);
|
registerAdapter(MODEL_PROVIDER.CODEX_API, CodexApiServiceAdapter);
|
||||||
registerAdapter(MODEL_PROVIDER.GROK_CUSTOM, GrokApiServiceAdapter);
|
registerAdapter(MODEL_PROVIDER.GROK_CUSTOM, GrokApiServiceAdapter);
|
||||||
// registerAdapter(MODEL_PROVIDER.FORWARD_API, ForwardApiServiceAdapter);
|
// registerAdapter(MODEL_PROVIDER.FORWARD_API, ForwardApiServiceAdapter);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue