- Добавлен парсер запроса из текста команды с разбором имени персонажа и временного периода/количества сообщений - Внедрена кэшированная генерация и поиск промптов по персонажу для более живых и контекстных суммаризаций - Интегрирован внешний вызов API OpenRouter для разбора команд и генерации суммаризаций с учетом стиля персонажа - Обновлен основной класс TelegramHistoryBot для поддержки новой команды и вызова AI через requestAI.js - Добавлены хранилища кэша для команд и промптов с логированием загрузки, сохранения и ошибок - Созданы инструкции для генератора промптов с детальной структурой и правилами для разнообразных персонажей BREAKING CHANGE: Для корректной работы требуется добавить в .env ключи OPENROUTER_API_KEY, OPENROUTER_MODEL и OPENROUTER_CHEAP_MODEL
106 lines
3.7 KiB
JavaScript
106 lines
3.7 KiB
JavaScript
const fs = require('fs');
|
||
const logger = require('./logger');
|
||
const cacheFile = 'prompts.json';
|
||
|
||
let prompts = {};
|
||
|
||
// Загружаем кэш из файла при старте
|
||
function loadPrompts() {
|
||
logger.info('Загрузка промптов...');
|
||
try {
|
||
if (fs.existsSync(cacheFile)) {
|
||
const data = fs.readFileSync(cacheFile);
|
||
prompts = JSON.parse(data);
|
||
logger.info('✅ Промпты загружены.');
|
||
} else {
|
||
fs.writeFileSync(cacheFile, JSON.stringify({}, null, 2));
|
||
logger.info('✅ Файл промптов создан.');
|
||
}
|
||
} catch (error) {
|
||
logger.error('❌ Ошибка загрузки промптов:', error);
|
||
}
|
||
}
|
||
|
||
// Сохраняем кэш в файл
|
||
function savePrompt() {
|
||
try {
|
||
fs.writeFileSync(cacheFile, JSON.stringify(prompts, null, 2));
|
||
} catch (error) {
|
||
logger.error('❌ Ошибка сохранения промптов:', error);
|
||
}
|
||
}
|
||
loadPrompts();
|
||
|
||
// Поиск запроса в кэше
|
||
|
||
/**
|
||
* Выполняет поиск промпта в кэше по ключу запроса
|
||
*
|
||
* @description Функция ищет сохранённый промпт в глобальном кэше prompts.
|
||
* Логирует процесс поиска и результат. Используется для избежания повторных
|
||
* обращений к AI при одинаковых запросах.
|
||
*
|
||
* @param {string} request - Ключ запроса для поиска в кэше промптов
|
||
* @returns {string|null} Найденный промпт или null, если не найден
|
||
*
|
||
* @example
|
||
* // Поиск существующего промпта
|
||
* const prompt = searchInPrompts("Карл Маркс");
|
||
* if (prompt) {
|
||
* console.log("Промпт найден:", prompt);
|
||
* }
|
||
*
|
||
* @example
|
||
* // Обработка отсутствующего промпта
|
||
* const result = searchInPrompts("Журавль летающий");
|
||
* // result будет null
|
||
*
|
||
* @since 1.0.0
|
||
* @author Vufer
|
||
*
|
||
* @see {@link saveInPrompts} для сохранения в кэш
|
||
*
|
||
* @throws {Error} Не выбрасывает исключений, возвращает null при ошибках
|
||
*
|
||
* @todo Добавить поиск по частичному совпадению ключей
|
||
*/
|
||
function searchInPrompts(request) {
|
||
logger.info(`🔎 Поиск в промптах: ${request}`);
|
||
if (!request || typeof request !== 'string') return null;
|
||
const result = prompts[request] || null;
|
||
if (result) {
|
||
logger.info(`🔁 Найдено в промптах: ${request}`);
|
||
return result;
|
||
}
|
||
return null;
|
||
}
|
||
// Сохранение запроса и ответа в кэш
|
||
// async function saveInCache(request, result) {
|
||
// if (!request || !result) return;
|
||
// aiCache[request] = result;
|
||
// saveAiCache();
|
||
// logger.info(`💾 Запрос сохранён в кэш: ${request}`);
|
||
// }
|
||
async function saveInPrompts(request, result) {
|
||
if (!request || !result) return;
|
||
|
||
let finalResult = result;
|
||
|
||
if (typeof result === 'string' && result.includes('persona') && result.includes('messages')) {
|
||
try {
|
||
finalResult = JSON.parse(result);
|
||
} catch (error) {
|
||
logger.warn(`⚠️ Не удалось распарсить JSON команды: ${error.message}`);
|
||
}
|
||
}
|
||
|
||
prompts[request] = finalResult;
|
||
savePrompt();
|
||
logger.info(`💾 Промпт сохранён в кэш: ${request}`);
|
||
}
|
||
//
|
||
// // Загрузим кэш при старте
|
||
// loadAiCache();
|
||
|
||
module.exports = { searchInPrompts, saveInPrompts };
|