Spaces:
Running
Running
Download ai_engine.js from everydaycats/everything: direct link, hf CLI and curl.
- Browser
- Download file 6.94 kB
-
https://huggingface.co/spaces/everydaycats/everything/resolve/main/ai_engine.js
- Command line
-
hf download hf://spaces/everydaycats/everything/ai_engine.js
-
curl -L -o ai_engine.js https://huggingface.co/spaces/everydaycats/everything/resolve/main/ai_engine.js
6.94 kB
| import OpenAI from "openai"; | |
| const openRouterAI = new OpenAI({ | |
| apiKey: process.env.OPENROUTER_API_KEY, | |
| baseURL: "https://openrouter.ai/api/v1", | |
| defaultHeaders: { | |
| "HTTP-Referer": process.env.YOUR_SITE_URL || "https://everydaycats.web.app", | |
| "X-Title": process.env.YOUR_SITE_NAME || "Aura Scanner", | |
| } | |
| }); | |
| // --- MODEL ROUTER --- | |
| const getModelId = (modelName) => { | |
| switch (modelName?.toLowerCase()) { | |
| case "llama": case "maverick": return "meta-llama/llama-4-maverick:floor"; | |
| case "llama-3.2-11b": return "meta-llama/llama-3.2-11b-vision-instruct:free"; | |
| case "qwen-2-vl-7b": return "qwen/qwen-2-vl-7b-instruct:free"; | |
| case "nemotron-12b": return "nvidia/nemotron-nano-12b-v2-vl:free"; | |
| case "gpt": case "gpt-5.4-nano": return "openai/gpt-5.4-nano"; | |
| case "qwen-non": return "qwen/qwen3-vl-30b-a3b-instruct"; | |
| case "bytedance-1.6": return "bytedance-seed/seed-1.6-flash:floor"; | |
| case "mistral-small": return "mistralai/mistral-small-2603:floor"; | |
| case "grok-4.3": return "x-ai/grok-4.3:floor"; | |
| case "qwen": default: return "qwen/qwen3-vl-30b-a3b-thinking:floor"; | |
| } | |
| }; | |
| // --- IMAGE MODEL ROUTER --- | |
| const getImageModelId = (tier) => { | |
| switch (tier) { | |
| case "premium": return "bytedance-seed/seedream-4.5"; | |
| case "quick": return "sourceful/riverflow-v2-fast"; | |
| default: return "sourceful/riverflow-v2-fast"; | |
| } | |
| }; | |
| // --- ERROR LOGGER --- | |
| const logOpenRouterError = (error, context) => { | |
| const status = error.status || error.response?.status; | |
| if (status === 402) console.error(`💸 [402] ${context}: Insufficient credits.`); | |
| else if (status === 429) console.error(`🚨 [429] ${context}: Rate limit exceeded.`); | |
| else if (status === 401) console.error(`🛑 [401] ${context}: Invalid API Key.`); | |
| else if (status === 400) console.error(`⚠️ [400] ${context}: Bad request / invalid payload.`); | |
| else if (status >= 500) console.error(`🔥 [${status}] ${context}: Provider backend down.`); | |
| else if (error.code === 'ECONNRESET' || error.code === 'ETIMEDOUT') | |
| console.error(`⏳ [TIMEOUT] ${context}: Connection dropped.`); | |
| else console.error(`❌ [ERROR] ${context}:`, error.message || error); | |
| }; | |
| // --- TEXT COMPLETION --- | |
| // forceJson: true → response_format json_object (structured calls, e.g. aura scan) | |
| // forceJson: false → plain text (e.g. ReplyGenius chat replies) | |
| export const generateCompletion = async ({ model, prompt, system_prompt, images, forceJson = true }) => { | |
| try { | |
| const targetModel = getModelId(model); | |
| let messagesPayload = [ | |
| { role: "system", content: system_prompt || "You are an elite AI assistant." } | |
| ]; | |
| if (images?.length > 0) { | |
| let userContent = [{ type: "text", text: prompt }]; | |
| images.forEach((imgStr) => { | |
| if (imgStr.length > 7000000) throw new Error("Image too large. Max ~4MB."); | |
| const formattedImg = imgStr.startsWith('data:image') | |
| ? imgStr : `data:image/jpeg;base64,${imgStr}`; | |
| userContent.push({ type: "image_url", image_url: { url: formattedImg } }); | |
| }); | |
| messagesPayload.push({ role: "user", content: userContent }); | |
| } else { | |
| messagesPayload.push({ role: "user", content: prompt }); | |
| } | |
| const requestParams = { | |
| model: targetModel, | |
| messages: messagesPayload, | |
| max_tokens: 1200, | |
| }; | |
| // ✅ Only enforce JSON schema when explicitly requested. | |
| // Sending response_format with a plain-text prompt causes 400 on most providers. | |
| if (forceJson) { | |
| requestParams.response_format = { type: "json_object" }; | |
| } | |
| const response = await openRouterAI.chat.completions.create(requestParams); | |
| return { | |
| success: true, | |
| data: response.choices[0].message.content, | |
| usage: response.usage, | |
| model_used: targetModel | |
| }; | |
| } catch (error) { | |
| logOpenRouterError(error, "generateCompletion"); | |
| return { success: false, error: error.message, status: error.status || 500 }; | |
| } | |
| }; | |
| // --- STREAMING TEXT COMPLETION --- | |
| export const streamCompletion = async ({ model, prompt, system_prompt, images, res }) => { | |
| try { | |
| const targetModel = getModelId(model); | |
| let messagesPayload = [ | |
| { role: "system", content: system_prompt || "You are an elite AI assistant." } | |
| ]; | |
| if (images?.length > 0) { | |
| let userContent = [{ type: "text", text: prompt }]; | |
| images.forEach((imgStr) => { | |
| if (imgStr.length > 7000000) throw new Error("Image too large. Max ~4MB."); | |
| const formattedImg = imgStr.startsWith('data:image') | |
| ? imgStr : `data:image/jpeg;base64,${imgStr}`; | |
| userContent.push({ type: "image_url", image_url: { url: formattedImg } }); | |
| }); | |
| messagesPayload.push({ role: "user", content: userContent }); | |
| } else { | |
| messagesPayload.push({ role: "user", content: prompt }); | |
| } | |
| const stream = await openRouterAI.chat.completions.create({ | |
| model: targetModel, | |
| messages: messagesPayload, | |
| stream: true, | |
| stream_options: { include_usage: true }, | |
| max_tokens: 2000, | |
| }); | |
| let totalTokenCount = 0; | |
| for await (const chunk of stream) { | |
| const delta = chunk.choices[0]?.delta; | |
| if (delta?.reasoning_content) res.write(`__THINK__${delta.reasoning_content}`); | |
| else if (delta?.content) res.write(delta.content); | |
| if (chunk.usage) totalTokenCount = chunk.usage.total_tokens; | |
| } | |
| res.write(`__USAGE__${JSON.stringify({ totalTokenCount })}`); | |
| res.end(); | |
| } catch (error) { | |
| logOpenRouterError(error, "streamCompletion"); | |
| res.write(`\n\n[ERROR]: ${error.message}`); | |
| res.end(); | |
| } | |
| }; | |
| // --- IMAGE GENERATION --- | |
| export const generateImage = async ({ prompt, tier = "quick" }) => { | |
| try { | |
| const model = getImageModelId(tier); | |
| const response = await fetch("https://openrouter.ai/api/v1/images/generations", { | |
| method: "POST", | |
| headers: { | |
| "Authorization": `Bearer ${process.env.OPENROUTER_API_KEY}`, | |
| "Content-Type": "application/json", | |
| "HTTP-Referer": process.env.YOUR_SITE_URL || "https://everydaycats.web.app", | |
| "X-Title": process.env.YOUR_SITE_NAME || "lightnovel.ai", | |
| }, | |
| body: JSON.stringify({ model, prompt, n: 1, size: "1024x1024" }) | |
| }); | |
| if (!response.ok) { | |
| const err = await response.json(); | |
| throw Object.assign(new Error(err?.error?.message || "Image gen failed"), { status: response.status }); | |
| } | |
| const data = await response.json(); | |
| const imageUrl = data?.data?.[0]?.url; | |
| if (!imageUrl) throw new Error("No image URL returned."); | |
| return { success: true, url: imageUrl, model_used: model }; | |
| } catch (error) { | |
| logOpenRouterError(error, "generateImage"); | |
| return { success: false, error: error.message, status: error.status || 500 }; | |
| } | |
| }; |