Spaces:
Running
Running
Update ai-routes.js
Browse files- ai-routes.js +52 -5
ai-routes.js
CHANGED
|
@@ -94,6 +94,49 @@ function convertGeminiToOpenAI(baseParams) {
|
|
| 94 |
return messages;
|
| 95 |
}
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
// --- Dynamic Provider Management ---
|
| 98 |
|
| 99 |
const PROVIDERS = {
|
|
@@ -179,13 +222,14 @@ async function callOpenRouterProvider(baseParams) {
|
|
| 179 |
|
| 180 |
async function callGemmaProvider(baseParams) {
|
| 181 |
const client = await getGeminiClient(); // AWAIT client
|
| 182 |
-
// Gemma
|
| 183 |
-
const fallbackModels = ['gemma-3-27b', 'gemma-3-9b', 'gemma-3-4b'];
|
| 184 |
let lastError = null;
|
| 185 |
for (const modelName of fallbackModels) {
|
| 186 |
try {
|
| 187 |
console.log(`🛡️ [AI Debug] Switching to Backup (Gemma): ${modelName}`);
|
| 188 |
-
|
|
|
|
| 189 |
return await callAIWithRetry(() => client.models.generateContent(currentParams), 1);
|
| 190 |
} catch (e) {
|
| 191 |
lastError = e;
|
|
@@ -298,12 +342,14 @@ async function streamOpenRouter(baseParams, res) {
|
|
| 298 |
|
| 299 |
async function streamGemma(baseParams, res) {
|
| 300 |
const client = await getGeminiClient(); // AWAIT client
|
| 301 |
-
|
|
|
|
| 302 |
let lastError = null;
|
| 303 |
for (const modelName of models) {
|
| 304 |
try {
|
| 305 |
console.log(`🛡️ [AI Debug] STREAMING Gemma: ${modelName}`);
|
| 306 |
-
|
|
|
|
| 307 |
const result = await client.models.generateContentStream(currentParams);
|
| 308 |
let fullText = "";
|
| 309 |
// FIX: Iterate result directly
|
|
@@ -318,6 +364,7 @@ async function streamGemma(baseParams, res) {
|
|
| 318 |
return fullText;
|
| 319 |
} catch (e) {
|
| 320 |
lastError = e;
|
|
|
|
| 321 |
}
|
| 322 |
}
|
| 323 |
throw lastError || new Error("Gemma streaming failed");
|
|
|
|
| 94 |
return messages;
|
| 95 |
}
|
| 96 |
|
| 97 |
+
// Helper to adapt params for Gemma (Remove systemInstruction and prepend to prompt)
|
| 98 |
+
function prepareGemmaParams(baseParams, modelName) {
|
| 99 |
+
// Deep copy to avoid mutating original for other providers
|
| 100 |
+
const newParams = JSON.parse(JSON.stringify(baseParams));
|
| 101 |
+
newParams.model = modelName;
|
| 102 |
+
|
| 103 |
+
// Gemma models do not support systemInstruction in config, move it to text
|
| 104 |
+
if (newParams.config && newParams.config.systemInstruction) {
|
| 105 |
+
const sysInst = newParams.config.systemInstruction;
|
| 106 |
+
delete newParams.config.systemInstruction;
|
| 107 |
+
|
| 108 |
+
const systemPrefix = `[System Instruction: ${sysInst}]\n\n`;
|
| 109 |
+
|
| 110 |
+
if (Array.isArray(newParams.contents) && newParams.contents.length > 0) {
|
| 111 |
+
// Chat mode: Prepend to first user message
|
| 112 |
+
const firstMsg = newParams.contents[0];
|
| 113 |
+
if (firstMsg.role === 'user' && firstMsg.parts && firstMsg.parts.length > 0) {
|
| 114 |
+
const textPart = firstMsg.parts.find(p => p.text);
|
| 115 |
+
if (textPart) {
|
| 116 |
+
textPart.text = systemPrefix + textPart.text;
|
| 117 |
+
} else {
|
| 118 |
+
// Only has image/audio, add text part
|
| 119 |
+
firstMsg.parts.unshift({ text: systemPrefix });
|
| 120 |
+
}
|
| 121 |
+
} else {
|
| 122 |
+
// If history starts with model (rare), prepend a new user message
|
| 123 |
+
newParams.contents.unshift({ role: 'user', parts: [{ text: systemPrefix }] });
|
| 124 |
+
}
|
| 125 |
+
} else if (newParams.contents && newParams.contents.parts) {
|
| 126 |
+
// Generate content mode (single object)
|
| 127 |
+
if (Array.isArray(newParams.contents.parts)) {
|
| 128 |
+
const textPart = newParams.contents.parts.find(p => p.text);
|
| 129 |
+
if (textPart) {
|
| 130 |
+
textPart.text = systemPrefix + textPart.text;
|
| 131 |
+
} else {
|
| 132 |
+
newParams.contents.parts.unshift({ text: systemPrefix });
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
return newParams;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
// --- Dynamic Provider Management ---
|
| 141 |
|
| 142 |
const PROVIDERS = {
|
|
|
|
| 222 |
|
| 223 |
async function callGemmaProvider(baseParams) {
|
| 224 |
const client = await getGeminiClient(); // AWAIT client
|
| 225 |
+
// Updated to Gemma 3 series as per user quota (including smaller ones)
|
| 226 |
+
const fallbackModels = ['gemma-3-27b-it', 'gemma-3-9b-it', 'gemma-3-4b-it'];
|
| 227 |
let lastError = null;
|
| 228 |
for (const modelName of fallbackModels) {
|
| 229 |
try {
|
| 230 |
console.log(`🛡️ [AI Debug] Switching to Backup (Gemma): ${modelName}`);
|
| 231 |
+
// Use adapter to remove systemInstruction
|
| 232 |
+
const currentParams = prepareGemmaParams(baseParams, modelName);
|
| 233 |
return await callAIWithRetry(() => client.models.generateContent(currentParams), 1);
|
| 234 |
} catch (e) {
|
| 235 |
lastError = e;
|
|
|
|
| 342 |
|
| 343 |
async function streamGemma(baseParams, res) {
|
| 344 |
const client = await getGeminiClient(); // AWAIT client
|
| 345 |
+
// Updated to Gemma 3 series as per user quota
|
| 346 |
+
const models = ['gemma-3-27b-it', 'gemma-3-9b-it', 'gemma-3-4b-it'];
|
| 347 |
let lastError = null;
|
| 348 |
for (const modelName of models) {
|
| 349 |
try {
|
| 350 |
console.log(`🛡️ [AI Debug] STREAMING Gemma: ${modelName}`);
|
| 351 |
+
// Use adapter to remove systemInstruction
|
| 352 |
+
const currentParams = prepareGemmaParams(baseParams, modelName);
|
| 353 |
const result = await client.models.generateContentStream(currentParams);
|
| 354 |
let fullText = "";
|
| 355 |
// FIX: Iterate result directly
|
|
|
|
| 364 |
return fullText;
|
| 365 |
} catch (e) {
|
| 366 |
lastError = e;
|
| 367 |
+
console.warn(`Streaming GEMMA ${modelName} failed:`, e.message);
|
| 368 |
}
|
| 369 |
}
|
| 370 |
throw lastError || new Error("Gemma streaming failed");
|