ваше сообщение коммита

This commit is contained in:
2025-08-08 16:30:47 +03:00
parent 0a72902c37
commit badb8b9557
15 changed files with 921 additions and 218 deletions

View File

@@ -1,5 +1,13 @@
/**
* Очередь для AI запросов с приоритизацией
* Copyright (c) 2024-2025 Тарабанов Александр Викторович
* All rights reserved.
*
* This software is proprietary and confidential.
* Unauthorized copying, modification, or distribution is prohibited.
*
* For licensing inquiries: info@hb3-accelerator.com
* Website: https://hb3-accelerator.com
* GitHub: https://github.com/HB3-ACCELERATOR
*/
const EventEmitter = require('events');
@@ -10,50 +18,51 @@ class AIQueue extends EventEmitter {
super();
this.queue = [];
this.processing = false;
this.maxConcurrent = 1; // Максимум 1 запрос одновременно (последовательная обработка)
this.activeRequests = 0;
this.maxConcurrent = 1; // Ограничиваем до 1 для стабильности
this.isPaused = false;
this.stats = {
total: 0,
completed: 0,
failed: 0,
avgResponseTime: 0
avgResponseTime: 0,
lastProcessedAt: null,
initializedAt: Date.now()
};
}
// Добавление запроса в очередь
async addRequest(request, priority = 0) {
const requestId = Date.now() + Math.random();
const queueItem = {
id: Date.now() + Math.random(),
id: requestId,
request,
priority,
timestamp: Date.now(),
status: 'pending'
status: 'queued',
timestamp: Date.now()
};
// Добавляем в очередь с учетом приоритета
this.queue.push(queueItem);
this.queue.sort((a, b) => b.priority - a.priority); // Сортировка по приоритету
this.queue.sort((a, b) => b.priority - a.priority);
this.stats.total++;
logger.info(`[AIQueue] Added request ${queueItem.id} with priority ${priority}`);
logger.info(`[AIQueue] Добавлен запрос ${requestId} с приоритетом ${priority}. Очередь: ${this.queue.length}`);
// Запускаем обработку если не запущена
// Запускаем обработку очереди
if (!this.processing) {
this.processQueue();
}
return queueItem.id;
return requestId;
}
// Обработка очереди
async processQueue() {
if (this.processing || this.activeRequests >= this.maxConcurrent) {
return;
}
if (this.processing) return;
this.processing = true;
logger.info(`[AIQueue] Начинаем обработку очереди. Запросов в очереди: ${this.queue.length}`);
while (this.queue.length > 0 && this.activeRequests < this.maxConcurrent) {
while (!this.isPaused && this.queue.length > 0 && this.activeRequests < this.maxConcurrent) {
const item = this.queue.shift();
if (!item) continue;
@@ -72,6 +81,7 @@ class AIQueue extends EventEmitter {
this.stats.completed++;
this.updateAvgResponseTime(responseTime);
this.stats.lastProcessedAt = Date.now();
logger.info(`[AIQueue] Запрос ${item.id} завершен за ${responseTime}ms`);
@@ -83,6 +93,7 @@ class AIQueue extends EventEmitter {
item.error = error.message;
this.stats.failed++;
this.stats.lastProcessedAt = Date.now();
logger.error(`[AIQueue] Запрос ${item.id} завершился с ошибкой:`, error.message);
// Эмитим событие об ошибке
@@ -96,21 +107,24 @@ class AIQueue extends EventEmitter {
logger.info(`[AIQueue] Обработка очереди завершена. Осталось запросов: ${this.queue.length}`);
// Если в очереди еще есть запросы, продолжаем обработку
if (this.queue.length > 0) {
if (!this.isPaused && this.queue.length > 0) {
setTimeout(() => this.processQueue(), 100);
}
}
// Обработка одного запроса
async processRequest(request) {
// Прямой вызов AI без очереди
const aiAssistant = require('./ai-assistant');
// Используем прямой метод без очереди
// Формируем сообщения для API
const messages = [];
// Добавляем системный промпт
if (request.systemPrompt) {
messages.push({ role: 'system', content: request.systemPrompt });
}
// Добавляем историю сообщений
if (request.history && Array.isArray(request.history)) {
for (const msg of request.history) {
if (msg.role && msg.content) {
@@ -118,10 +132,12 @@ class AIQueue extends EventEmitter {
}
}
}
// Добавляем текущее сообщение пользователя
messages.push({ role: 'user', content: request.message });
// Прямой вызов API без очереди
return await aiAssistant.fallbackRequestOpenAI(messages, request.systemPrompt);
// Используем прямой метод для избежания рекурсии
return await aiAssistant.directRequest(messages, request.systemPrompt);
}
// Обновление средней скорости ответа
@@ -133,8 +149,17 @@ class AIQueue extends EventEmitter {
// Получение статистики
getStats() {
const totalProcessed = this.stats.completed + this.stats.failed;
return {
...this.stats,
// совместимость с AIQueueMonitor.vue и маршрутами
totalProcessed,
totalFailed: this.stats.failed,
averageProcessingTime: this.stats.avgResponseTime,
currentQueueSize: this.queue.length,
runningTasks: this.activeRequests,
lastProcessedAt: this.stats.lastProcessedAt,
isInitialized: true,
// старые поля на всякий случай
queueLength: this.queue.length,
activeRequests: this.activeRequests,
processing: this.processing
@@ -146,6 +171,39 @@ class AIQueue extends EventEmitter {
this.queue = [];
logger.info('[AIQueue] Queue cleared');
}
// Совместимость с роутами AI Queue
pause() {
this.isPaused = true;
logger.info('[AIQueue] Queue paused');
}
resume() {
const wasPaused = this.isPaused;
this.isPaused = false;
logger.info('[AIQueue] Queue resumed');
if (wasPaused) {
this.processQueue();
}
}
async addTask(taskData) {
// Маппинг к addRequest
const priority = this._calcTaskPriority(taskData);
const taskId = await this.addRequest(taskData, priority);
return { taskId };
}
_calcTaskPriority({ message = '', type, userRole, history }) {
let priority = 0;
if (userRole === 'admin') priority += 10;
if (type === 'chat') priority += 5;
if (type === 'analysis') priority += 3;
if (type === 'generation') priority += 1;
if (message && message.length < 100) priority += 2;
if (history && Array.isArray(history) && history.length > 0) priority += 1;
return priority;
}
}
module.exports = new AIQueue();