Spaces:
Sleeping
Sleeping
File size: 7,088 Bytes
a5ee22a 8f4ee3c a5ee22a 5914d51 a5ee22a d9a52f4 a5ee22a 5796df2 5d38af1 8f22f37 7d1620b 2927323 587da90 5d38af1 79a2685 662dd32 fa87bc3 662dd32 79a2685 5d38af1 587da90 5d38af1 d9a52f4 8f6b7be 587da90 d9a52f4 5d38af1 c2ca7e4 587da90 2b60bab d9a52f4 e89852c c2ca7e4 e89852c d9a52f4 e89852c d9a52f4 e89852c c2ca7e4 e89852c c2ca7e4 d9a52f4 c2ca7e4 d9a52f4 587da90 5d38af1 d9a52f4 587da90 7aac0bf abed4cc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
const express = require('express');
const rateLimit = require('express-rate-limit');
const axios = require('axios');
const multer = require('multer'); // импорт multer
const app = express();
//app.use(express.json({ limit: '50mb' })); // Увеличение лимита для base64 изображений
const openai_key = process.env.OPENAI_KEY;
const base_url = "https://rooni-gemini-reverse-proxy.hf.space/v1beta/models/gemini-1.5-pro-latest:streamGenerateContent?alt=sse"; //https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:streamGenerateContent?alt=sse
const limiter = rateLimit({
windowMs: 40 * 1000, // 40 секунд
max: 1, // лимит каждые 40 секунд на IP
handler: function (req, res) {
return res.json({
content: '+ошибка+Генерировать можно только 1 раз в 40 секунд! YUFI-ошибка-'
});
},
});
app.use('/gen', limiter);
app.use('/translate', limiter);
const start = `Приветствую тебя! 🌟 Ты - "Помогатор 1.5". Твоя миссия - помогать студентам, делая учебный процесс весёлым и интерактивным с помощью стильного общения и эмодзи. 🎓😊 Когда студенты просят помощи, ты подробно объясняешь им материал, используя примеры и аналогии. Но если они просят 'РЕШИТЬ', ты переключаешься в режим решения и предоставляешь точные ответы, делая упор на краткость и точность. 🧮✅ Если тебе присылают фото задания, ты тщательно его анализируешь и решаешь, предоставляя решение в понятной форме и используя дробную черту '/' для записи дробей. 🖼️➗ Твоя цель - не просто дать ответы, но и обучить, однако ты всегда готов решить задачу, когда это необходимо. А так же, не в коем случае не используй форматирование Markdown! И не в коем случае не рассказывай что ты НЕ можешь - пытайся выкрутиться. Приступим? 🚀🌈`;
const starttransl = `Ты ТОЛЬКО переводчик. Идеальный переводчик, который сохраняет характер текста, шутки, смысл и т.д. Ты переводишь всё правильно с исходным сленгом. Понятно и правильно. Но если это плохой или 18+ понтекст, то пиши (в точности): +ошибка+Контекст не подлежит переводу!-ошибка-`;
app.post('/gen', async (req, res) => {
const prompt = req.body.prompt;
const img = req.body.img; // Проверка на существование файла перед доступом к его пути
const apiKey = req.body.api || openai_key;
let payload;
if (!prompt) {
return res.json({ content: '+ошибка+❌ Ошибка данных, повторите попытку.-ошибка-' });
}
if (prompt.replace(/[\s\n]/g, '').length > 250) {
return res.json({ content: '+ошибка+❌ Максимум символов: 250-ошибка-' });
}
try {
// Создание тела запроса в зависимости от наличия изображения
if (img) {
// Если изображение предоставлено
payload = {
"generationConfig": {"temperature": 0.8, "topP": 1},
"safetySettings": [
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"}
],
"contents": [
{"parts": [{"text": start}], "role": "user"},
{"parts": [{"text": prompt}, {"inlineData": {"data": img, "mimeType": "image/jpeg"}}], "role": "user"}
]
};
} else {
// Если изображение не предоставлено
payload = {
"generationConfig": {"temperature": 0.8, "topP": 1},
"safetySettings": [
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
{"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"}
],
"contents": [
{"parts": [{"text": start}], "role": "user"},
{"parts": [{"text": prompt}], "role": "user"}
]
};
}
const response = await axios.post(base_url, payload, {
headers: {
'x-goog-api-key': `${apiKey}`,
'Content-Type': 'application/json',
},
responseType: 'stream',
});
let fullContent = '';
response.data.on('data', (chunk) => {
const chunkString = chunk.toString();
// Разбиваем на строки, убираем пустые строки
const dataLines = chunkString.split('\n').filter(line => line.trim() !== '');
dataLines.forEach(line => {
if (line.startsWith('data: ')) {
try {
// Парсим строку как JSON
const jsonData = JSON.parse(line.trim().substring(5));
if (jsonData.candidates && jsonData.candidates.length > 0) {
const textPart = jsonData.candidates[0].content.parts.map(part => part.text).join('');
fullContent += textPart;
}
} catch (error) {
console.error('Ошибка парсинга фрагмента:', error, line); // Выводим строку для отладки
}
}
});
});
await new Promise((resolve) => {
response.data.on('end', () => {
res.json({ content: fullContent });
resolve();
});
response.data.on('error', (err) => {
console.error('Ошибка в потоке ответа:', err);
res.status(500).json({ content: '+ошибка+❌ Произошла ошибка сервера при генерации.-ошибка-' });
resolve();
});
});
} catch (error) {
console.error(error);
res.status(500).json({ content: '+ошибка+❌ Произошла ошибка сервера при генерации.-ошибка-' });
}
});
const port = 7860;
app.listen(port, () => {
console.log(`API сервер запущен на порту ${port}`);
}); |