diff --git a/core/commands/expert.py b/core/commands/expert.py new file mode 100644 index 0000000..9596745 --- /dev/null +++ b/core/commands/expert.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +""" +Экспертные команды: !summary, !metrics. +Не зависят от комнаты (используют последний загруженный пользователем файл или общую БЗ). +""" + +import time +import logging +from core.commands.base import Command +from core.functions.summarize_document import summarize_document +from core.functions.extract_metrics import extract_metrics + +logger = logging.getLogger(__name__) + + +class SummaryCommand(Command): + name = "!summary" + aliases = ["/summary", "!суммаризация", "/суммаризация"] + + async def execute(self, msg, args: str, user_jid: str, room_jid: str = None): + # Используем текст последнего загруженного файла (личный или комнатный – он хранится в last_file_texts) + last_text = self.bot.last_file_texts.get(user_jid, "") + if not last_text: + reply = msg.reply("Нет документа для суммаризации.") + if reply: + reply.send() # исправлено + else: + logger.error("Не удалось отправить сообщение об отсутствии документа для суммаризации") + return + reply = msg.reply("📝 Создаю суммаризацию...") + if reply: + reply.send() # исправлено + else: + logger.error("Не удалось отправить сообщение о начале суммаризации") + # Исправленный вызов: используем функцию из core.functions + summary = await summarize_document( + giga=self.bot.giga, + text=last_text, + title="Ваш документ", + prompt_text=self.bot.ai_prompts.get('summary', ''), + bot_config=self.bot.config + ) + reply = msg.reply(f"📄 **Суммаризация:**\n\n{summary}") + if reply: + reply.send() # исправлено + else: + logger.error("Не удалось отправить суммаризацию") + + def get_help(self) -> str: + return "Создаёт суммаризацию последнего загруженного документа." + + +class MetricsCommand(Command): + name = "!metrics" + aliases = ["/metrics", "!метрики", "/метрики"] + cache_ttl = 300 # 5 минут + + async def execute(self, msg, args: str, user_jid: str, room_jid: str = None): + cache_key = self.get_cache_key(user_jid, args) + now = time.time() + if cache_key in self._cache: + cached_time, cached_result = self._cache[cache_key] + if now - cached_time < self.cache_ttl: + reply = msg.reply(cached_result) + if reply: + reply.send() # исправлено + else: + logger.error("Не удалось отправить кэшированный результат метрик") + return + + reply = msg.reply("🔍 Ищу числовые показатели в ваших документах...") + if reply: + reply.send() # исправлено + else: + logger.error("Не удалось отправить сообщение о поиске метрик") + query = "числовые показатели KPI метрики статистика проценты суммы количество" + # Ищем по всей доступной БЗ (личной + глобальной или комнатной + глобальной) + context = await self.bot.kb.find_relevant_info(query, user_jid, room_jid, top_k=30) + if not context: + reply = msg.reply("📭 В вашей базе знаний нет документов с числовыми показателями.") + if reply: + reply.send() # исправлено + else: + logger.error("Не удалось отправить сообщение об отсутствии метрик") + return + # Исправленный вызов: используем функцию из core.functions + metrics = await extract_metrics( + giga=self.bot.giga, + context=context, + prompt_text=self.bot.ai_prompts.get('metrics', ''), + bot_config=self.bot.config + ) + if metrics: + lines = [] + for m in metrics[:20]: + name = m.get('metric_name', 'Показатель') + value = m.get('value', '?') + unit = m.get('unit', '') + period = m.get('period', '') + line = f"- **{name}**: {value}" + if unit: + line += f" {unit}" + if period: + line += f" ({period})" + lines.append(line) + reply = "📊 **Извлечённые метрики из ваших документов:**\n" + "\n".join(lines) + self._cache[cache_key] = (time.time(), reply) + reply_obj = msg.reply(reply) + if reply_obj: + reply_obj.send() # исправлено + else: + logger.error("Не удалось отправить список метрик") + else: + reply_obj = msg.reply("⚠️ Не удалось извлечь структурированные метрики.") + if reply_obj: + reply_obj.send() # исправлено + else: + logger.error("Не удалось отправить сообщение об ошибке извлечения метрик") + + def get_help(self) -> str: + return "Извлекает KPI из базы знаний (с кэшем на 5 минут)." \ No newline at end of file