feat: add dialogue compaction with summary integration
- Add /compact command for manual compaction - Integrate summary loading from ChromaDB - Add summary to AI prompt context - Automatic compaction at 70% threshold - Keep last 20 messages uncompressed Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
417a858468
commit
bff74741a6
88
bot.py
88
bot.py
|
|
@ -213,8 +213,17 @@ async def handle_ai_task(update: Update, text: str):
|
|||
def on_oauth_url(url: str):
|
||||
pass # OAuth обрабатывается автоматически
|
||||
|
||||
# Формируем контекст с историей + памятью
|
||||
history_context = "\n".join(state.ai_chat_history)
|
||||
# Формируем контекст с историей + памятью + summary
|
||||
# Получаем summary и последние сообщения из ChromaDB
|
||||
summary = None
|
||||
try:
|
||||
summary, recent_messages = compactor.get_context_with_summary(limit=20)
|
||||
# Формируем историю из последних сообщений
|
||||
history_context = "\n".join([f"{msg['role']}: {msg['content']}" for msg in recent_messages])
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка загрузки summary: {e}")
|
||||
# Fallback на старую логику
|
||||
history_context = "\n".join(state.ai_chat_history)
|
||||
|
||||
# Получаем контекст из системы памяти (профиль + релевантные факты)
|
||||
memory_context = get_context(user_id, query=text)
|
||||
|
|
@ -231,15 +240,29 @@ async def handle_ai_task(update: Update, text: str):
|
|||
# Собираем полный промпт с системным промптом
|
||||
system_prompt = qwen_manager.load_system_prompt()
|
||||
|
||||
full_task = (
|
||||
f"{system_prompt}\n\n"
|
||||
f"=== КОНТЕКСТ ПАМЯТИ ===\n"
|
||||
f"{memory_context}\n\n"
|
||||
f"=== ИСТОРИЯ ДИАЛОГА ===\n"
|
||||
f"{history_context}\n\n"
|
||||
f"=== ЗАПРОС ПОЛЬЗОВАТЕЛЯ ===\n"
|
||||
f"{text}"
|
||||
)
|
||||
# Формируем полный промпт с summary (если есть)
|
||||
if summary:
|
||||
full_task = (
|
||||
f"{system_prompt}\n\n"
|
||||
f"=== SUMMARY ДИАЛОГА (контекст) ===\n"
|
||||
f"{summary}\n\n"
|
||||
f"=== КОНТЕКСТ ПАМЯТИ ===\n"
|
||||
f"{memory_context}\n\n"
|
||||
f"=== ИСТОРИЯ ДИАЛОГА (последние 20 сообщений) ===\n"
|
||||
f"{history_context}\n\n"
|
||||
f"=== ЗАПРОС ПОЛЬЗОВАТЕЛЯ ===\n"
|
||||
f"{text}"
|
||||
)
|
||||
else:
|
||||
full_task = (
|
||||
f"{system_prompt}\n\n"
|
||||
f"=== КОНТЕКСТ ПАМЯТИ ===\n"
|
||||
f"{memory_context}\n\n"
|
||||
f"=== ИСТОРИЯ ДИАЛОГА ===\n"
|
||||
f"{history_context}\n\n"
|
||||
f"=== ЗАПРОС ПОЛЬЗОВАТЕЛЯ ===\n"
|
||||
f"{text}"
|
||||
)
|
||||
|
||||
# Выполняем задачу (системный промпт уже добавлен в full_task)
|
||||
result = await qwen_manager.run_task(user_id, full_task, on_output, on_oauth_url, use_system_prompt=False)
|
||||
|
|
@ -1371,6 +1394,48 @@ async def ai_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||
)
|
||||
|
||||
|
||||
@check_access
|
||||
async def compact_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Обработка команды /compact — ручная компактификация истории диалога."""
|
||||
user_id = update.effective_user.id
|
||||
|
||||
logger.info(f"Пользователь {user_id} запросил ручную компактификацию")
|
||||
|
||||
status_msg = await update.message.reply_text(
|
||||
"🔄 **Запуск компактификации истории...**\n\n"
|
||||
"_Сжатие старой истории в структурированный summary._\n"
|
||||
"_Это может занять несколько секунд._",
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
|
||||
result = await compactor.compact()
|
||||
|
||||
await status_msg.delete()
|
||||
|
||||
if result.success:
|
||||
if result.messages_compressed > 0:
|
||||
await update.message.reply_text(
|
||||
f"✅ **Компактификация завершена!**\n\n"
|
||||
f"📊 Сжато сообщений: `{result.messages_compressed}`\n"
|
||||
f"📝 Длина summary: `{result.summary_length}` символов\n"
|
||||
f"💾 Экономия токенов: ~`{result.tokens_saved}`\n\n"
|
||||
f"_Summary автоматически используется в контексте диалога._",
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
else:
|
||||
await update.message.reply_text(
|
||||
"ℹ️ **Компактификация не требуется**\n\n"
|
||||
"_Недостаточно сообщений для сжатия или summary уже актуален._",
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
else:
|
||||
logger.error(f"Компактификация не удалась: {result.error}")
|
||||
await update.message.reply_text(
|
||||
f"⚠️ **Ошибка компактификации:**\n`{result.error}`",
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
|
||||
|
||||
@check_access
|
||||
async def memory_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Обработка команды /memory — статистика памяти ИИ."""
|
||||
|
|
@ -1567,6 +1632,7 @@ def main():
|
|||
application.add_handler(CommandHandler("menu", menu_command))
|
||||
application.add_handler(CommandHandler("stop", stop_command))
|
||||
application.add_handler(CommandHandler("memory", memory_command))
|
||||
application.add_handler(CommandHandler("compact", compact_command))
|
||||
application.add_handler(CommandHandler("facts", facts_command))
|
||||
application.add_handler(CommandHandler("forget", forget_command))
|
||||
application.add_handler(CallbackQueryHandler(menu_callback))
|
||||
|
|
|
|||
Loading…
Reference in New Issue