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:
@@ -1,6 +1,8 @@
|
||||
import { register } from "../index.js";
|
||||
import { FORMATS } from "../formats.js";
|
||||
import { parseDataUri } from "../helpers/imageHelper.js";
|
||||
import { parseDataUri } from "../concerns/image.js";
|
||||
import { safeParseJSON } from "../concerns/json.js";
|
||||
import { ROLE, OPENAI_BLOCK } from "../schema/index.js";
|
||||
|
||||
/**
|
||||
* Convert OpenAI request to Ollama format
|
||||
@@ -68,7 +70,7 @@ function normalizeMessages(messages) {
|
||||
|
||||
// First pass: build tool_call_id -> tool_name map from assistant messages
|
||||
for (const msg of messages) {
|
||||
if (msg.role === "assistant" && msg.tool_calls) {
|
||||
if (msg.role === ROLE.ASSISTANT && msg.tool_calls) {
|
||||
for (const tc of msg.tool_calls) {
|
||||
if (tc.id && tc.function?.name) {
|
||||
toolCallMap.set(tc.id, tc.function.name);
|
||||
@@ -80,7 +82,7 @@ function normalizeMessages(messages) {
|
||||
// Second pass: convert messages
|
||||
for (const msg of messages) {
|
||||
// Handle tool result messages (OpenAI format -> Ollama format)
|
||||
if (msg.role === "tool") {
|
||||
if (msg.role === ROLE.TOOL) {
|
||||
const toolResult = normalizeContent(msg.content);
|
||||
if (!toolResult) continue;
|
||||
|
||||
@@ -88,7 +90,7 @@ function normalizeMessages(messages) {
|
||||
const toolName = toolCallMap.get(msg.tool_call_id) || msg.name || "unknown_tool";
|
||||
|
||||
result.push({
|
||||
role: "tool",
|
||||
role: ROLE.TOOL,
|
||||
tool_name: toolName,
|
||||
content: toolResult
|
||||
});
|
||||
@@ -96,23 +98,23 @@ function normalizeMessages(messages) {
|
||||
}
|
||||
|
||||
// Handle assistant messages with tool_calls
|
||||
if (msg.role === "assistant" && msg.tool_calls) {
|
||||
if (msg.role === ROLE.ASSISTANT && msg.tool_calls) {
|
||||
const content = normalizeContent(msg.content) || "";
|
||||
|
||||
// Convert OpenAI tool_calls format to Ollama format
|
||||
const ollamaToolCalls = msg.tool_calls.map(tc => ({
|
||||
type: "function",
|
||||
type: OPENAI_BLOCK.FUNCTION,
|
||||
function: {
|
||||
index: tc.index || 0,
|
||||
name: tc.function?.name || "",
|
||||
arguments: typeof tc.function?.arguments === "string"
|
||||
? JSON.parse(tc.function.arguments || "{}")
|
||||
? safeParseJSON(tc.function.arguments || "{}", {})
|
||||
: tc.function?.arguments || {}
|
||||
}
|
||||
}));
|
||||
|
||||
result.push({
|
||||
role: "assistant",
|
||||
role: ROLE.ASSISTANT,
|
||||
content: content,
|
||||
tool_calls: ollamaToolCalls
|
||||
});
|
||||
@@ -125,7 +127,7 @@ function normalizeMessages(messages) {
|
||||
const images = extractImagesFromContent(msg.content);
|
||||
|
||||
// Skip empty messages (except assistant)
|
||||
if (!content && role !== "assistant") continue;
|
||||
if (!content && role !== ROLE.ASSISTANT) continue;
|
||||
|
||||
const out = {
|
||||
role: role,
|
||||
@@ -154,7 +156,7 @@ function normalizeContent(content) {
|
||||
if (Array.isArray(content)) {
|
||||
// Extract text from content array
|
||||
const textParts = content
|
||||
.filter(block => block && block.type === "text" && block.text)
|
||||
.filter(block => block && block.type === OPENAI_BLOCK.TEXT && block.text)
|
||||
.map(block => block.text);
|
||||
|
||||
return textParts.join("\n") || "";
|
||||
@@ -175,7 +177,7 @@ function extractImagesFromContent(content) {
|
||||
const images = [];
|
||||
|
||||
for (const block of content) {
|
||||
if (!block || block.type !== "image_url") continue;
|
||||
if (!block || block.type !== OPENAI_BLOCK.IMAGE_URL) continue;
|
||||
|
||||
const url = typeof block.image_url === "string" ? block.image_url : block.image_url?.url;
|
||||
if (typeof url !== "string" || !url) continue;
|
||||
|
||||
Reference in New Issue
Block a user