feat: новая функция

This commit is contained in:
2025-10-09 20:49:51 +03:00
parent 13fb51e447
commit 34666b44d8
11 changed files with 553 additions and 53 deletions

View File

@@ -12,6 +12,7 @@
const logger = require('../utils/logger');
const ollamaConfig = require('./ollamaConfig');
const { shouldProcessWithAI } = require('../utils/languageFilter');
/**
* AI Assistant - тонкая обёртка для работы с Ollama и RAG
@@ -70,6 +71,18 @@ class AIAssistant {
try {
logger.info(`[AIAssistant] Генерация ответа для канала ${channel}, пользователь ${userId}`);
// 0. Проверяем язык сообщения (только русский)
const languageCheck = shouldProcessWithAI(userQuestion);
if (!languageCheck.shouldProcess) {
logger.info(`[AIAssistant] ⚠️ Пропуск обработки: ${languageCheck.reason} (user: ${userId}, channel: ${channel})`);
return {
success: false,
reason: languageCheck.reason,
skipped: true,
message: 'AI обрабатывает только сообщения на русском языке'
};
}
const messageDeduplicationService = require('./messageDeduplicationService');
const aiAssistantSettingsService = require('./aiAssistantSettingsService');
const aiAssistantRulesService = require('./aiAssistantRulesService');

View File

@@ -56,12 +56,20 @@ class BotManager {
await telegramBot.initialize().catch(error => {
logger.warn('[BotManager] Telegram Bot не инициализирован:', error.message);
});
// Устанавливаем централизованный процессор сообщений для Telegram
telegramBot.setMessageProcessor(this.processMessage.bind(this));
logger.info('[BotManager] ✅ Telegram Bot подключен к unified processor');
// Инициализируем Email Bot
logger.info('[BotManager] Инициализация Email Bot...');
await emailBot.initialize().catch(error => {
logger.warn('[BotManager] Email Bot не инициализирован:', error.message);
});
// Устанавливаем централизованный процессор сообщений для Email
emailBot.setMessageProcessor(this.processMessage.bind(this));
logger.info('[BotManager] ✅ Email Bot подключен к unified processor');
this.isInitialized = true;
logger.info('[BotManager] ✅ BotManager успешно инициализирован');

View File

@@ -150,14 +150,14 @@ async function getEmbeddingModel() {
function getTimeouts() {
return {
// Ollama API - таймауты запросов
ollamaChat: 120000, // 120 сек (2 мин) - генерация ответов LLM
ollamaEmbedding: 60000, // 60 сек (1 мин) - генерация embeddings
ollamaChat: 180000, // 180 сек (3 мин) - генерация ответов LLM (увеличено для сложных запросов)
ollamaEmbedding: 90000, // 90 сек (1.5 мин) - генерация embeddings (увеличено)
ollamaHealth: 5000, // 5 сек - health check
ollamaTags: 10000, // 10 сек - список моделей
// Vector Search - таймауты запросов
vectorSearch: 30000, // 30 сек - поиск по векторам
vectorUpsert: 60000, // 60 сек - индексация данных
vectorSearch: 90000, // 90 сек - поиск по векторам (увеличено для больших баз)
vectorUpsert: 90000, // 90 сек - индексация данных (увеличено)
vectorHealth: 5000, // 5 сек - health check
// AI Cache - TTL (Time To Live) для кэширования
@@ -166,12 +166,12 @@ function getTimeouts() {
cacheMax: 1000, // Максимум записей в кэше
// AI Queue - параметры очереди
queueTimeout: 120000, // 120 сек - таймаут задачи в очереди
queueTimeout: 180000, // 180 сек - таймаут задачи в очереди (увеличено)
queueMaxSize: 100, // Максимум задач в очереди
queueInterval: 100, // 100 мс - интервал проверки очереди
// Default для совместимости
default: 120000 // 120 сек
default: 180000 // 180 сек (увеличено с 120)
};
}

View File

@@ -395,6 +395,15 @@ async function generateLLMResponse({
const ollamaUrl = ollamaConfig.getBaseUrl();
const timeouts = ollamaConfig.getTimeouts();
// Логируем размер промпта для отладки
const promptSize = JSON.stringify(messages).length;
console.log(`[RAG] Отправка запроса в Ollama. Размер промпта: ${promptSize} символов, таймаут: ${timeouts.ollamaChat/1000}с`);
// Проверяем размер промпта и предупреждаем, если он большой
if (promptSize > 10000) {
console.warn(`[RAG] ⚠️ Большой промпт (${promptSize} символов). Возможны проблемы с производительностью.`);
}
const response = await axios.post(`${ollamaUrl}/api/chat`, {
model: model || ollamaConfig.getDefaultModel(),
messages: messages,
@@ -406,7 +415,17 @@ async function generateLLMResponse({
llmResponse = response.data.message.content;
} catch (error) {
console.error(`[RAG] Error in Ollama call:`, error.message);
const isTimeout = error.message && (
error.message.includes('timeout') ||
error.message.includes('ETIMEDOUT') ||
error.message.includes('ECONNABORTED')
);
if (isTimeout) {
console.warn(`[RAG] Ollama timeout после ${timeouts.ollamaChat/1000}с. Возможно, модель перегружена или контекст слишком большой.`);
} else {
console.error(`[RAG] Error in Ollama call:`, error.message);
}
// Финальный fallback - возврат ответа из RAG
if (answer) {
@@ -414,6 +433,11 @@ async function generateLLMResponse({
return answer;
}
// Если был таймаут и нет ответа из RAG - возвращаем более информативное сообщение
if (isTimeout) {
return 'Извините, обработка запроса заняла слишком много времени. Пожалуйста, попробуйте упростить ваш вопрос или повторите попытку позже.';
}
return 'Извините, произошла ошибка при генерации ответа.';
}