""" =============================================================================== FILE: modules/ai_engine/context_builder.py PROJECT: SCUD Orion AI (Unified Architecture) MODULE: modules / ai_engine ROLE: Динамическая сборка системного промпта из БД, календаря и контекста сессий. AI-CONTEXT-ANCHORS: - ANCHOR[CONTEXT_BUILDER_MAIN]: Формирование полного системного контекста для LLM. =============================================================================== """ from typing import Dict, Any, Optional from services.prompts.service import get_active_system_prompt from modules.web_api.llm.core.calendar_utils import get_dynamic_calendar_context # ANCHOR[CONTEXT_BUILDER_MAIN] def build_agent_system_context( user_id: int, session_state: Optional[Dict[str, Any]] ) -> str: """Формирует полный динамический системный контекст агента с правилами из БД.""" # 1. Загружаем актуальный базовый системный промпт из SQLite БД base_system_prompt = get_active_system_prompt() # 2. Серверный календарь и контекст дат calendar_context = get_dynamic_calendar_context() user_info = f"Пользователь ID={user_id}" if user_id != 0 else "Гость" # 3. Контекст текущего активного стейта сессии current_state_type = session_state.get("state_type") if session_state else None state_data = session_state.get("data_json") or {} if session_state else {} if not isinstance(state_data, dict): state_data = {} active_state_context = "" if current_state_type == "PROMPT_PREVIEW": active_state_context = ( "\n[ТЕКУЩИЙ РЕЖИМ: ПРЕДПРОСМОТР СИСТЕМНОГО ПРОМПТА]\n" "- Открыт предпросмотр изменений промпта. Для любых правок вызывай db_prompt_node_edit.\n" ) elif current_state_type == "PROMPT_FOLLOWUP": active_state_context = ( "\n[ТЕКУЩИЙ РЕЖИМ: СЕССИЯ РЕДАКТИРОВАНИЯ ПРОМПТА]\n" "- Оператор просматривает или редактирует системный промпт.\n" "- На любые команды вида 'удали пункт X.Y' или 'удали X.Y' ТЫ ОБЯЗАН ВЫЗВАТЬ db_prompt_node_edit с action='DELETE', section_id=X, item_id=Y.\n" "- На любые команды 'добавь пункт X.Y ...' вызывай action='ADD'.\n" "- Запрещено путать ADD и DELETE.\n" ) elif current_state_type == "SNAPSHOTS_VIEW": active_date = state_data.get("query_date", "выбранную дату") active_state_context = ( f"\n[ТЕКУЩИЙ РЕЖИМ: ПРОСМОТР СНАПШОТОВ СКУД]\n" f"- Сейчас на экране отображаются снапшоты за {active_date}.\n" f"- Ты можешь форматировать, фильтровать или анализировать этот текущий срез.\n" f"- Если оператор запрашивает ДРУГУЮ дату или день недели (например: 'за вчера', 'а за 13.08') — " f"ТЫ ОБЯЗАН СРАЗУ ВЫЗВАТЬ db_get_snapshots(date_str=...).\n" f"- Запрещено генерировать текст за другую дату по памяти.\n" ) elif current_state_type == "SNAPSHOT_DELETE_CONFIRM": active_state_context = "\n[ВНИМАНИЕ: ОЖИДАЕТСЯ ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ СНАПШОТОВ]\n" elif current_state_type == "TASK_DELETE_CONFIRM": active_state_context = "\n[ВНИМАНИЕ: ОЖИДАЕТСЯ ПОДТВЕРЖДЕНИЕ УДАЛЕНИЯ ЗАДАЧИ]\n" # 4. Сборка полного системного сообщения return ( f"{base_system_prompt}\n\n" f"СТРОГИЕ ПРАВИЛА ВЫЗОВА ИНСТРУМЕНТОВ:\n" f"1. Для системного промпта:\n" f" - 'добавь X.Y Текст' -> СРАЗУ вызывай db_prompt_node_edit(action='ADD', section_id=X, item_id=Y, content='Текст').\n" f" - 'удали X.Y' -> СРАЗУ вызывай db_prompt_node_edit(action='DELETE', section_id=X, item_id=Y, content='').\n" f" - 'покажи системный промпт' -> СРАЗУ вызывай db_get_system_prompt().\n" f"2. Для задач:\n" f" - 'удали задачу N' -> СРАЗУ вызывай db_tasks_edit(action='DELETE', task_id='N').\n" f" - 'возьми в работу N' -> СРАЗУ вызывай db_tasks_edit(action='UPDATE', task_id='N', status='IN_PROGRESS').\n" f" - 'заверши N' / 'готово N' -> СРАЗУ вызывай db_tasks_edit(action='UPDATE', task_id='N', status='COMPLETED').\n" f"3. Запрещено задавать вопросы и писать подтверждения текстом — СРАЗУ вызывай соответствующий инструмент!\n\n" f"[СИСТЕМНЫЙ КАЛЕНДАРЬ СЕРВЕРА]\n" f"- Пользователь: {user_info}\n" f"- {calendar_context}\n" f"{active_state_context}" )