shinmentakezo07
Add OmniRoute codebase without binary assets
9e4583c
Raw
History Blame Contribute Delete
3.22 kB
import { CORS_ORIGIN } from "@/shared/utils/cors";
import { handleChat } from "@/sse/handlers/chat";
import { initTranslators } from "@omniroute/open-sse/translator/index.ts";
let initialized = false;
/**
* Initialize translators once
*/
async function ensureInitialized() {
if (!initialized) {
await initTranslators();
initialized = true;
console.log("[SSE] Translators initialized for /v1beta/models");
}
}
/**
* Handle CORS preflight
*/
export async function OPTIONS() {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": CORS_ORIGIN,
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "*",
},
});
}
/**
* POST /v1beta/models/{model}:generateContent - Gemini compatible endpoint
* Converts Gemini format to internal format and handles via handleChat
*/
export async function POST(request, { params }) {
await ensureInitialized();
try {
const { path } = await params;
// path = ["provider", "model:generateContent"] or ["model:generateContent"]
let model;
if (path.length >= 2) {
// Format: /v1beta/models/provider/model:generateContent
const provider = path[0];
const modelAction = path[1];
const modelName = modelAction
.replace(":generateContent", "")
.replace(":streamGenerateContent", "");
model = `${provider}/${modelName}`;
} else {
// Format: /v1beta/models/model:generateContent
const modelAction = path[0];
model = modelAction.replace(":generateContent", "").replace(":streamGenerateContent", "");
}
const body = await request.json();
// Convert Gemini format to OpenAI/internal format
const convertedBody = convertGeminiToInternal(body, model);
// Create new request with converted body
const newRequest = new Request(request.url, {
method: "POST",
headers: request.headers,
body: JSON.stringify(convertedBody),
});
return await handleChat(newRequest);
} catch (error) {
console.log("Error handling Gemini request:", error);
return Response.json({ error: { message: error.message, code: 500 } }, { status: 500 });
}
}
/**
* Convert Gemini request format to internal format
*/
function convertGeminiToInternal(geminiBody, model) {
const messages = [];
// Convert system instruction
if (geminiBody.systemInstruction) {
const systemText = geminiBody.systemInstruction.parts?.map((p) => p.text).join("\n") || "";
if (systemText) {
messages.push({ role: "system", content: systemText });
}
}
// Convert contents to messages
if (geminiBody.contents) {
for (const content of geminiBody.contents) {
const role = content.role === "model" ? "assistant" : "user";
const text = content.parts?.map((p) => p.text).join("\n") || "";
messages.push({ role, content: text });
}
}
// Determine if streaming
const stream = geminiBody.generationConfig?.stream !== false;
return {
model,
messages,
stream,
max_tokens: geminiBody.generationConfig?.maxOutputTokens,
temperature: geminiBody.generationConfig?.temperature,
top_p: geminiBody.generationConfig?.topP,
};
}