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}`);
});