refactor(open-sse): translator DRY + schema enums, bug fixes, dead code cleanup

- Bug B1-B7: media UI m.kind||m.type, serviceKinds, gemini mediaPriority, schema kind, models/info lookup by kind
- Dead code D1-D6: safeParseJSON, drop PROVIDER_ENDPOINTS, orphan fetcher, GITHUB_CONFIG derive, getProviderConfig internal, legacy kiro file
- Translator concerns: toOpenAIUsage, toOpenAIFinish (gemini/kiro/ollama + fix kiro tool finish), thinking effort maps
- Reorg helpers/ → concerns/ (logic) + formats/ (per-format) + schema/ (pure enums: roles/blocks/finishReasons/defaults)
- Wire ~280 hardcoded role/block/finish/default literals to schema enums across 20+ files
- collapseTextParts + extractTextContent dedup
- Normalize translator fn names to openaiToXRequest / xToOpenAIResponse
- Golden tests lock behavior; 0 regression (byte-for-byte providers/alias, 26=26 known fails)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
decolua
2026-06-14 18:49:38 +07:00
parent c5c9061eac
commit d3f61aac2f
145 changed files with 1252 additions and 1160 deletions

View File

@@ -1,7 +1,9 @@
import { register } from "../index.js";
import { FORMATS } from "../formats.js";
import { adjustMaxTokens } from "../helpers/maxTokensHelper.js";
import { encodeDataUri } from "../helpers/imageHelper.js";
import { adjustMaxTokens } from "../formats/maxTokens.js";
import { encodeDataUri } from "../concerns/image.js";
import { collapseTextParts } from "../concerns/message.js";
import { ROLE, GEMINI_ROLE, OPENAI_BLOCK } from "../schema/index.js";
// Convert Gemini request to OpenAI format
export function geminiToOpenAIRequest(model, body, stream) {
@@ -31,7 +33,7 @@ export function geminiToOpenAIRequest(model, body, stream) {
const systemText = extractGeminiText(body.systemInstruction);
if (systemText) {
result.messages.push({
role: "system",
role: ROLE.SYSTEM,
content: systemText
});
}
@@ -54,7 +56,7 @@ export function geminiToOpenAIRequest(model, body, stream) {
if (tool.functionDeclarations) {
for (const func of tool.functionDeclarations) {
result.tools.push({
type: "function",
type: OPENAI_BLOCK.FUNCTION,
function: {
name: func.name,
description: func.description || "",
@@ -71,7 +73,7 @@ export function geminiToOpenAIRequest(model, body, stream) {
// Convert Gemini content to OpenAI message
function convertGeminiContent(content) {
const role = content.role === "user" ? "user" : "assistant";
const role = content.role === GEMINI_ROLE.USER ? ROLE.USER : ROLE.ASSISTANT;
if (!content.parts || !Array.isArray(content.parts)) {
return null;
@@ -82,12 +84,12 @@ function convertGeminiContent(content) {
for (const part of content.parts) {
if (part.text !== undefined) {
parts.push({ type: "text", text: part.text });
parts.push({ type: OPENAI_BLOCK.TEXT, text: part.text });
}
if (part.inlineData) {
parts.push({
type: "image_url",
type: OPENAI_BLOCK.IMAGE_URL,
image_url: {
url: encodeDataUri(part.inlineData.mimeType, part.inlineData.data)
}
@@ -97,7 +99,7 @@ function convertGeminiContent(content) {
if (part.functionCall) {
toolCalls.push({
id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
type: "function",
type: OPENAI_BLOCK.FUNCTION,
function: {
name: part.functionCall.name,
arguments: JSON.stringify(part.functionCall.args || {})
@@ -107,7 +109,7 @@ function convertGeminiContent(content) {
if (part.functionResponse) {
return {
role: "tool",
role: ROLE.TOOL,
tool_call_id: part.functionResponse.id || part.functionResponse.name,
content: JSON.stringify(part.functionResponse.response?.result || part.functionResponse.response || {})
};
@@ -115,7 +117,7 @@ function convertGeminiContent(content) {
}
if (toolCalls.length > 0) {
const result = { role: "assistant" };
const result = { role: ROLE.ASSISTANT };
if (parts.length > 0) {
result.content = parts.length === 1 ? parts[0].text : parts;
}
@@ -126,7 +128,7 @@ function convertGeminiContent(content) {
if (parts.length > 0) {
return {
role,
content: parts.length === 1 && parts[0].type === "text" ? parts[0].text : parts
content: collapseTextParts(parts)
};
}