From c1d990fd937533ebe62fc4d3e76e84cf7eb4b3ee Mon Sep 17 00:00:00 2001 From: dimitrievgs Date: Mon, 15 Sep 2025 00:36:48 +0300 Subject: [PATCH] Fix bug with sending all the messages from all nodes instead of current branch --- app/graph_history_manager.py | 132 ++++++++++++++------- app/llm_client.py | 12 +- app/models.py | 9 +- app/nodes.py | 220 +++++++++++++++++++++++------------ app/workflows.py | 50 +++++--- graph_history.db | Bin 286720 -> 81920 bytes 6 files changed, 286 insertions(+), 137 deletions(-) diff --git a/app/graph_history_manager.py b/app/graph_history_manager.py index d0ff3da..4b2c728 100644 --- a/app/graph_history_manager.py +++ b/app/graph_history_manager.py @@ -17,6 +17,7 @@ class GraphHistoryManager: def __init__(self, db_path="graph_history.db"): self.db_path = db_path + self._create_table(self._get_connection()) # Создаем таблицу при инициализации def _get_connection(self): """Получает соединение с базой данных.""" @@ -28,7 +29,6 @@ class GraphHistoryManager: cursor.execute(""" CREATE TABLE IF NOT EXISTS graphs ( id TEXT PRIMARY KEY, - messages TEXT, graph_nodes TEXT, graph_edges TEXT, current_node_id TEXT @@ -45,8 +45,12 @@ class GraphHistoryManager: result = cursor.fetchone()[0] return result if result is not None else 0 + # ---------------------------------------------------- public methods ---------------------------------------------------------------- def save_graph(self, graph_data: Any) -> str: - """Сохраняет или обновляет данные графа в базе данных и возвращает ID.""" + """ + Сохраняет или обновляет данные графа в базе данных и возвращает ID. + Не сохраняет полную историю сообщений, только структуру графа. + """ conn = self._get_connection() cursor = conn.cursor() try: @@ -58,7 +62,6 @@ class GraphHistoryManager: graph_data["id"] = graph_id # Преобразуем структуры данных в JSON-строки для хранения в SQLite - messages_json = json.dumps(graph_data.get("messages", [])) graph_nodes_json = json.dumps(graph_data.get("graph_nodes", [])) graph_edges_json = json.dumps(graph_data.get("graph_edges", [])) current_node_id = graph_data.get("current_node_id", "") @@ -72,20 +75,19 @@ class GraphHistoryManager: cursor.execute( """ UPDATE graphs SET - messages = ?, graph_nodes = ?, graph_edges = ?, current_node_id = ? WHERE id = ? - """, (messages_json, graph_nodes_json, graph_edges_json, + """, (graph_nodes_json, graph_edges_json, current_node_id, graph_id)) else: # Вставляем новую запись cursor.execute( """ - INSERT INTO graphs (id, messages, graph_nodes, graph_edges, current_node_id) - VALUES (?, ?, ?, ?, ?) - """, (graph_id, messages_json, graph_nodes_json, + INSERT INTO graphs (id, graph_nodes, graph_edges, current_node_id) + VALUES (?, ?, ?, ?) + """, (graph_id, graph_nodes_json, graph_edges_json, current_node_id)) conn.commit() @@ -94,29 +96,51 @@ class GraphHistoryManager: finally: conn.close() - def get_graph(self, graph_id: str) -> Optional[Any]: - """Получает данные графа по ID из базы данных.""" + def get_graph(self, graph_id: str, target_node_id: Optional[str] = None) -> Optional[Dict[str, Any]]: + """ + Получает данные графа по ID из базы данных. + Динамически вычисляет 'messages' до 'target_node_id'. + Если target_node_id не указан, используется current_node_id из БД. + """ conn = self._get_connection() cursor = conn.cursor() try: cursor.execute( - "SELECT messages, graph_nodes, graph_edges, current_node_id FROM graphs WHERE id = ?", + "SELECT graph_nodes, graph_edges, current_node_id FROM graphs WHERE id = ?", (graph_id, )) result = cursor.fetchone() if result: - messages_json, graph_nodes_json, graph_edges_json, current_node_id = result + graph_nodes_json, graph_edges_json, db_current_node_id = result + # Преобразуем JSON-строки обратно в структуры данных Python - messages = json.loads(messages_json) graph_nodes = json.loads(graph_nodes_json) graph_edges = json.loads(graph_edges_json) + resolved_current_node_id = target_node_id if target_node_id else db_current_node_id + + # Если нет узлов, значит граф пуст или некорректен + if not graph_nodes: + return { + "id": graph_id, + "messages": [], + "graph_nodes": [], + "graph_edges": [], + "current_node_id": resolved_current_node_id + } + + # Динамически собираем сообщения + messages = self.get_messages_from_root_to_node( + {"graph_nodes": graph_nodes, "graph_edges": graph_edges}, + resolved_current_node_id + ) + return { "id": graph_id, - "messages": messages, + "messages": messages, # Здесь будут вычисленные сообщения "graph_nodes": graph_nodes, "graph_edges": graph_edges, - "current_node_id": current_node_id + "current_node_id": resolved_current_node_id } else: return None @@ -124,54 +148,80 @@ class GraphHistoryManager: conn.close() def get_all_graphs_summary(self) -> List[Dict[str, str]]: - """Возвращает краткий список всех сохраненных графов.""" + """ + Возвращает краткий список всех сохраненных графов. + Первое сообщение извлекается путем построения пути к current_node_id + и взятия первого сообщения. + """ conn = self._get_connection() cursor = conn.cursor() try: - cursor.execute("SELECT id, messages FROM graphs") + cursor.execute("SELECT id, graph_nodes, graph_edges, current_node_id FROM graphs") graphs_data = cursor.fetchall() - return [{ - "id": - gid, - "first_message": - json.loads(messages)[0].get("content", "No content") - if messages else "No content" - } for gid, messages in graphs_data] + summaries = [] + for gid, nodes_json, edges_json, current_node_id in graphs_data: + graph_nodes = json.loads(nodes_json) + graph_edges = json.loads(edges_json) + + # Получаем все сообщения до current_node_id + full_messages = self.get_messages_from_root_to_node( + {"graph_nodes": graph_nodes, "graph_edges": graph_edges}, + current_node_id + ) + + first_message_content = "No content" + if full_messages: + # Ищем первое сообщение, которое является пользовательским + for msg in full_messages: + if msg.get("role") == "user": + first_message_content = msg.get("content", "No content") + break + if first_message_content == "No content": # Если не нашли пользовательского, берем первое ассистента + first_message_content = full_messages[0].get("content", "No content") + + summaries.append({ + "id": gid, + "first_message": first_message_content + }) + return summaries finally: conn.close() def get_messages_from_root_to_node( self, graph_data: Dict[str, Any], target_node_id: str) -> List[Dict[str, str]]: - """Получает список сообщений от корневого узла до указанного узла.""" - nodes = graph_data.get("graph_nodes", []) + """ + Получает список сообщений от корневого узла до указанного узла. + Сообщения извлекаются из данных узлов, а не из отдельного поля. + """ + all_nodes = graph_data.get("graph_nodes", []) edges = graph_data.get("graph_edges", []) - messages = graph_data.get("messages", []) + # Создаем словарь для быстрого поиска узлов по ID + node_map = {node['id']: node for node in all_nodes} # Создаем словарь для быстрого поиска родительских узлов parent_map = {edge['target']: edge['source'] for edge in edges} # Функция для рекурсивного подъема по дереву до корневого узла def get_path_to_root(node_id: str) -> List[str]: path = [node_id] - while node_id in parent_map: - node_id = parent_map[node_id] - path.append(node_id) + current = node_id + while current in parent_map: + current = parent_map[current] + path.append(current) return path[::-1] # Инвертируем, чтобы получить путь от корня # Получаем путь от корня до целевого узла - path_to_root = get_path_to_root(target_node_id) + path_to_target = get_path_to_root(target_node_id) - # Собираем сообщения, соответствующие узлам в пути + + # Собираем сообщения, соответствующие узлам в пути. + # Сообщения теперь хранятся в 'data' каждого узла при создании. messages_for_path = [] - node_ids_in_path = set(path_to_root) - - for message in messages: - if "node_id" in message and message["node_id"] in node_ids_in_path: - messages_for_path.append({ - "role": message["role"], - "content": message["content"] - }) + for node_id in path_to_target: + node = node_map.get(node_id) + if node and 'message' in node.get('data', {}): # Проверяем наличие поля 'message' + messages_for_path.append(node['data']['message']) return messages_for_path @@ -182,7 +232,7 @@ class GraphHistoryManager: try: cursor.execute("DELETE FROM graphs WHERE id = ?", (graph_id, )) conn.commit() - return True + return cursor.rowcount > 0 # Возвращает True, если была удалена хотя бы одна строка except Exception as e: print(f"Ошибка при удалении графа: {e}") return False diff --git a/app/llm_client.py b/app/llm_client.py index 30cdc52..c3230df 100644 --- a/app/llm_client.py +++ b/app/llm_client.py @@ -5,7 +5,7 @@ import requests from typing import Dict, Any, List -from langchain_core.messages import HumanMessage, SystemMessage +from langchain_core.messages import HumanMessage, SystemMessage, AIMessage # --- Конфигурация LLM --- # Пустой словарь для локальных моделей (Ollama) @@ -101,6 +101,11 @@ class CustomLLM: "role": "system", "content": msg.content }) + elif isinstance(msg, AIMessage): # Добавляем обработку AIMessage + openai_messages.append({ + "role": "assistant", + "content": msg.content + }) else: # Предполагаем, что это другие типы сообщений Langchain или словари openai_messages.append({ "role": @@ -155,6 +160,11 @@ class CustomLLM: "role": "system", "content": msg.content }) + elif isinstance(msg, AIMessage): # Добавляем обработку AIMessage + mistral_messages.append({ + "role": "assistant", + "content": msg.content + }) else: # Предполагаем, что это другие типы сообщений Langchain или словари mistral_messages.append({ "role": diff --git a/app/models.py b/app/models.py index 71cb887..f3e2809 100644 --- a/app/models.py +++ b/app/models.py @@ -14,11 +14,6 @@ class AgentState(BaseModel): command: Optional[str] = Field(None, description="Распознанная слеш-команда.") command_args: List[str] = Field([], description="Аргументы команды.") - chat_history: List[Dict[str, str]] = Field( - [], - description= - "Полная история сообщений в текущей ветке диалога. Формат: [{'role': 'user/assistant', 'content': 'message'}]" - ) llm_response: Optional[str] = Field(None, description="Ответ от LLM.") image_urls: List[str] = Field( [], description="URL сгенерированных изображений.") @@ -37,3 +32,7 @@ class AgentState(BaseModel): "start", description="ID текущего узла графа для фронтенда.") parent_node_id: Optional[str] = Field(None, description="ID родительского узла.") + # Временное хранилище для chat_history, которое не сохраняется в БД + # Оно используется для передачи контекста между узлами в пределах одного выполнения + temporary_chat_history: List[Dict[str, Any]] = Field( + [], description="Временная история чата, не сохраняемая в БД.") diff --git a/app/nodes.py b/app/nodes.py index 5948292..3f694e4 100644 --- a/app/nodes.py +++ b/app/nodes.py @@ -4,7 +4,7 @@ разбор команд, вызов LLM или выполнение сервисов. """ -from langchain_core.messages import HumanMessage, SystemMessage +from langchain_core.messages import HumanMessage, SystemMessage, AIMessage from llm_client import get_llm from services import ImageGenerationService, SubtitleService, ImageAnalysisService, SummarizationService @@ -66,21 +66,28 @@ class CommandManager: command_manager = CommandManager() +# Здесь мы меняем состояние графа, добавляя сообщение от пользователя def parse_command_node(state: AgentState) -> AgentState: - """Парсит вход пользователя на предмет слеш-команды.""" + """ + Парсит вход пользователя на предмет слеш-команды и инициализирует узел пользователя в графе. + """ print("Выполняется узел: parse_command_node") user_input = state.input.strip() - # Добавляем узел пользователя в граф для фронтенда + # Создаем ID для узла пользователя user_node_id = f"user_{len(state.graph_nodes) + 1}" + + # Добавляем узел пользователя в граф для фронтенда с полным текстом сообщения state.graph_nodes.append({ "id": user_node_id, "type": "user", "data": { - "label": - user_input[:30] + "..." if len(user_input) > 30 else user_input + "label": user_input[:30] + "..." if len(user_input) > 30 else user_input, + "message": {"role": "user", "content": user_input, "node_id": user_node_id} # Сохраняем сообщение здесь } }) + + # Добавляем ребро к новому узлу, если есть родительский узел if state.parent_node_id: state.graph_edges.append({ "id": f"e{state.parent_node_id}-{user_node_id}", @@ -90,10 +97,12 @@ def parse_command_node(state: AgentState) -> AgentState: state.parent_node_id = user_node_id state.current_node_id = user_node_id - state.chat_history.append({ + # Обновляем временную историю чата, которая используется для передачи между узлами + # и для вызова LLM в текущем раунде. + state.temporary_chat_history.append({ "role": "user", "content": user_input, - "node_id": user_node_id # Сохраняем ID узла + "node_id": user_node_id }) if user_input.startswith('/'): @@ -116,7 +125,10 @@ def parse_command_node(state: AgentState) -> AgentState: def execute_command_node(state: AgentState) -> AgentState: - """Выполняет соответствующий workflow для команды.""" + """ + Выполняет соответствующий workflow для команды. + Этот узел служит маршрутизатором для выбора следующего узла в зависимости от команды. + """ print( f"Выполняется узел: execute_command_node для команды: {state.command}") # Этот узел будет выступать в роли маршрутизатора @@ -131,27 +143,32 @@ main_llm = get_llm(DEFAULT_LLM_NAME) def call_llm_node(state: AgentState) -> AgentState: - """Вызывает LLM для обработки обычного диалога или генерации ответа.""" + """ + Вызывает LLM для обработки обычного диалога или генерации ответа. + Использует `temporary_chat_history` для передачи контекста LLM. + """ print("Выполняется узел: call_llm_node (для обычного чата)") try: - # Для обычного чата LLM использует всю историю + # TODO: добавить в переписку ещё SystemMessage с системным промптом, типа: messages_for_llm.append(SystemMessage(content=msg["content"])) + # Для обычного чата LLM использует текущую временную историю messages_for_llm = [] - for msg in state.chat_history: + for msg in state.temporary_chat_history: # Используем temporary_chat_history if msg["role"] == "user": messages_for_llm.append(HumanMessage(content=msg["content"])) elif msg["role"] == "assistant": - messages_for_llm.append(SystemMessage(content=msg["content"])) + messages_for_llm.append(AIMessage(content=msg["content"])) response = main_llm.invoke(messages_for_llm) - # Добавляем узел LLM в граф для фронтенда llm_node_id = f"llm_{len(state.graph_nodes) + 1}" + + # Добавляем узел LLM в граф для фронтенда с полным текстом ответа state.graph_nodes.append({ "id": llm_node_id, "type": "llm", "data": { - "label": - response[:30] + "..." if len(response) > 30 else response + "label": response[:30] + "..." if len(response) > 30 else response, + "message": {"role": "assistant", "content": response, "node_id": llm_node_id} # Сохраняем сообщение здесь } }) state.graph_edges.append({ @@ -162,10 +179,11 @@ def call_llm_node(state: AgentState) -> AgentState: state.parent_node_id = llm_node_id state.current_node_id = llm_node_id - state.chat_history.append({ + # Обновляем временную историю чата с ответом LLM + state.temporary_chat_history.append({ "role": "assistant", "content": response, - "node_id": llm_node_id # Сохраняем ID узла + "node_id": llm_node_id }) state.llm_response = response @@ -182,12 +200,16 @@ image_gen_service = ImageGenerationService( def generate_images_node(state: AgentState) -> AgentState: - """Генерирует изображения по промпту.""" + """ + Генерирует изображения по промпту, переданному в команде `/imagine`. + """ print("Выполняется узел: generate_images_node") prompt = " ".join(state.command_args) if not prompt: state.error = "Для команды /imagine требуется промпт. Пример: /imagine кошка на луне" state.llm_response = state.error + # Добавляем ошибку во временную историю для согласованности + state.temporary_chat_history.append({"role": "assistant", "content": state.error}) return state try: @@ -196,20 +218,21 @@ def generate_images_node(state: AgentState) -> AgentState: # Формируем текст ответа с использованием Markdown для отображения изображений image_markdown = "\n".join([ - f'image{i}' + f'image{i}' for i, url in enumerate(urls) ]) response_text = f"Сгенерировано {len(urls)} изображений:\n{image_markdown}" state.llm_response = response_text - # Добавляем узел генерации изображений в граф img_gen_node_id = f"img_gen_{len(state.graph_nodes) + 1}" + # Добавляем узел генерации изображений в граф state.graph_nodes.append({ "id": img_gen_node_id, "type": "tool", "data": { "label": "Генерация изображений", - "details": prompt + "details": prompt, + "message": {"role": "assistant", "content": response_text, "node_id": img_gen_node_id} } }) state.graph_edges.append({ @@ -220,8 +243,8 @@ def generate_images_node(state: AgentState) -> AgentState: state.parent_node_id = img_gen_node_id state.current_node_id = img_gen_node_id - state.llm_response = "Сгенерированы изображения." - state.chat_history.append({ + # Обновляем временную историю чата + state.temporary_chat_history.append({ "role": "assistant", "content": response_text, "node_id": img_gen_node_id # Привязываем к ID узла @@ -231,6 +254,8 @@ def generate_images_node(state: AgentState) -> AgentState: state.error = f"Ошибка генерации изображений: {e}" state.llm_response = f"Произошла ошибка при генерации изображений: {e}" print(state.error) + # Добавляем ошибку во временную историю + state.temporary_chat_history.append({"role": "assistant", "content": state.llm_response}) return state @@ -239,11 +264,15 @@ image_analysis_service = ImageAnalysisService( def analyze_image_node(state: AgentState) -> AgentState: - """Анализирует изображение по URL или данным.""" + """ + Анализирует изображение по URL и промпту, переданным в команде `/analyze`. + """ print("Выполняется узел: analyze_image_node") if len(state.command_args) < 2: state.error = "Для команды /analyze требуется URL изображения и промпт. Пример: /analyze [url] 'что на изображении?'" state.llm_response = state.error + # Добавляем ошибку во временную историю для согласованности + state.temporary_chat_history.append({"role": "assistant", "content": state.error}) return state image_url = state.command_args[0] @@ -253,20 +282,18 @@ def analyze_image_node(state: AgentState) -> AgentState: analysis_result = image_analysis_service.analyze_image( image_url, prompt) state.analysis_result = analysis_result - state.llm_response = f"Результат анализа изображения '{image_url}': {analysis_result}" - state.chat_history.append({ - "role": "assistant", - "content": state.llm_response - }) + response_text = f"Результат анализа изображения '{image_url}': {analysis_result}" + state.llm_response = response_text - # Добавляем узел анализа изображения в граф img_analysis_node_id = f"img_analysis_{len(state.graph_nodes) + 1}" + # Добавляем узел анализа изображения в граф state.graph_nodes.append({ "id": img_analysis_node_id, "type": "tool", "data": { "label": "Анализ изображения", - "details": f"URL: {image_url}, Промпт: {prompt}" + "details": f"URL: {image_url}, Промпт: {prompt}", + "message": {"role": "assistant", "content": response_text, "node_id": img_analysis_node_id} } }) state.graph_edges.append({ @@ -277,10 +304,19 @@ def analyze_image_node(state: AgentState) -> AgentState: state.parent_node_id = img_analysis_node_id state.current_node_id = img_analysis_node_id + # Обновляем временную историю чата + state.temporary_chat_history.append({ + "role": "assistant", + "content": response_text, + "node_id": img_analysis_node_id + }) + except Exception as e: state.error = f"Ошибка анализа изображения: {e}" state.llm_response = f"Произошла ошибка при анализе изображения: {e}" print(state.error) + # Добавляем ошибку во временную историю + state.temporary_chat_history.append({"role": "assistant", "content": state.llm_response}) return state @@ -288,25 +324,25 @@ subtitle_service = SubtitleService() def get_meet_subtitles_node(state: AgentState) -> AgentState: - """Получает субтитры из Google Meet.""" + """ + Получает субтитры из Google Meet через команду `/subtitles_meet`. + """ print("Выполняется узел: get_meet_subtitles_node") try: subtitles = subtitle_service.get_google_meet_subtitles() state.subtitles = subtitles - state.llm_response = f"Текущие субтитры из Google Meet: {subtitles}" - state.chat_history.append({ - "role": "assistant", - "content": state.llm_response - }) + response_text = f"Текущие субтитры из Google Meet: {subtitles}" + state.llm_response = response_text - # Добавляем узел субтитров Meet в граф meet_subtitles_node_id = f"meet_subtitles_{len(state.graph_nodes) + 1}" + # Добавляем узел субтитров Meet в граф state.graph_nodes.append({ "id": meet_subtitles_node_id, "type": "tool", "data": { "label": "Субтитры Google Meet", - "details": subtitles[:30] + "..." if subtitles else "" + "details": subtitles[:30] + "..." if subtitles else "", + "message": {"role": "assistant", "content": response_text, "node_id": meet_subtitles_node_id} } }) state.graph_edges.append({ @@ -317,33 +353,42 @@ def get_meet_subtitles_node(state: AgentState) -> AgentState: state.parent_node_id = meet_subtitles_node_id state.current_node_id = meet_subtitles_node_id + # Обновляем временную историю чата + state.temporary_chat_history.append({ + "role": "assistant", + "content": response_text, + "node_id": meet_subtitles_node_id + }) + except Exception as e: state.error = f"Ошибка получения субтитров Google Meet: {e}" state.llm_response = f"Произошла ошибка при получении субтитров Google Meet: {e}" print(state.error) + # Добавляем ошибку во временную историю + state.temporary_chat_history.append({"role": "assistant", "content": state.llm_response}) return state def get_teams_subtitles_node(state: AgentState) -> AgentState: - """Получает субтитры из MS Teams.""" + """ + Получает субтитры из MS Teams через команду `/subtitles_teams`. + """ print("Выполняется узел: get_teams_subtitles_node") try: subtitles = subtitle_service.get_ms_teams_subtitles() state.subtitles = subtitles - state.llm_response = f"Текущие субтитры из MS Teams: {subtitles}" - state.chat_history.append({ - "role": "assistant", - "content": state.llm_response - }) + response_text = f"Текущие субтитры из MS Teams: {subtitles}" + state.llm_response = response_text - # Добавляем узел субтитров Teams в граф teams_subtitles_node_id = f"teams_subtitles_{len(state.graph_nodes) + 1}" + # Добавляем узел субтитров Teams в граф state.graph_nodes.append({ "id": teams_subtitles_node_id, "type": "tool", "data": { "label": "Субтитры MS Teams", - "details": subtitles[:30] + "..." if subtitles else "" + "details": subtitles[:30] + "..." if subtitles else "", + "message": {"role": "assistant", "content": response_text, "node_id": teams_subtitles_node_id} } }) state.graph_edges.append({ @@ -354,10 +399,19 @@ def get_teams_subtitles_node(state: AgentState) -> AgentState: state.parent_node_id = teams_subtitles_node_id state.current_node_id = teams_subtitles_node_id + # Обновляем временную историю чата + state.temporary_chat_history.append({ + "role": "assistant", + "content": response_text, + "node_id": teams_subtitles_node_id + }) + except Exception as e: state.error = f"Ошибка получения субтитров MS Teams: {e}" state.llm_response = f"Произошла ошибка при получении субтитров MS Teams: {e}" print(state.error) + # Добавляем ошибку во временную историю + state.temporary_chat_history.append({"role": "assistant", "content": state.llm_response}) return state @@ -366,28 +420,27 @@ summarization_service = SummarizationService( def summarize_history_node(state: AgentState) -> AgentState: - """Суммирует историю диалога.""" + """ + Суммирует историю диалога, используя `temporary_chat_history` в качестве контекста. + """ print("Выполняется узел: summarize_history_node") try: - # Для суммаризации используем полную историю, которую ведет AgentState - summarized_text = summarization_service.summarize_history( - state.chat_history) + # Для суммаризации используем временную историю, подготовленную в предыдущих узлах + summarized_text = summarization_service.summarize_history_of_dicts( + state.temporary_chat_history) # Изменен метод для использования List[Dict] state.summarized_history_text = summarized_text - state.llm_response = f"История диалога суммирована:\n{summarized_text}" - state.chat_history.append({ - "role": "assistant", - "content": state.llm_response - }) + response_text = f"История диалога суммирована:\n{summarized_text}" + state.llm_response = response_text - # Добавляем узел суммаризации в граф summary_node_id = f"summary_{len(state.graph_nodes) + 1}" + # Добавляем узел суммаризации в граф state.graph_nodes.append({ "id": summary_node_id, "type": "tool", "data": { "label": "Суммаризация истории", - "details": - summarized_text[:30] + "..." if summarized_text else "" + "details": summarized_text[:30] + "..." if summarized_text else "", + "message": {"role": "assistant", "content": response_text, "node_id": summary_node_id} } }) state.graph_edges.append({ @@ -398,30 +451,38 @@ def summarize_history_node(state: AgentState) -> AgentState: state.parent_node_id = summary_node_id state.current_node_id = summary_node_id + # Обновляем временную историю чата + state.temporary_chat_history.append({ + "role": "assistant", + "content": response_text, + "node_id": summary_node_id + }) + except Exception as e: state.error = f"Ошибка суммаризации истории: {e}" state.llm_response = f"Произошла ошибка при суммаризации истории: {e}" print(state.error) + # Добавляем ошибку во временную историю + state.temporary_chat_history.append({"role": "assistant", "content": state.llm_response}) return state def handle_error_node(state: AgentState) -> AgentState: - """Обрабатывает ошибки команд.""" + """ + Обрабатывает ошибки команд, формируя ответ для пользователя и добавляя его в граф. + """ print(f"Выполняется узел: handle_error_node. Ошибка: {state.error}") state.llm_response = state.error - state.chat_history.append({ - "role": "assistant", - "content": state.llm_response - }) - # Добавляем узел ошибки в граф error_node_id = f"error_{len(state.graph_nodes) + 1}" + # Добавляем узел ошибки в граф state.graph_nodes.append({ "id": error_node_id, "type": "error", "data": { "label": "Ошибка", - "details": state.error + "details": state.error, + "message": {"role": "assistant", "content": state.llm_response, "node_id": error_node_id} } }) state.graph_edges.append({ @@ -432,30 +493,36 @@ def handle_error_node(state: AgentState) -> AgentState: state.parent_node_id = error_node_id state.current_node_id = error_node_id + # Обновляем временную историю чата + state.temporary_chat_history.append({ + "role": "assistant", + "content": state.llm_response, + "node_id": error_node_id + }) + return state def help_node(state: AgentState) -> AgentState: - """Предоставляет информацию о доступных командах.""" + """ + Предоставляет информацию о доступных командах, формируя ответ для пользователя и добавляя его в граф. + """ print("Выполняется узел: help_node") commands_info = command_manager.get_commands() help_text = "Доступные команды:\n" for cmd, info in commands_info.items(): help_text += f"/{cmd}: {info['description']}\n" state.llm_response = help_text - state.chat_history.append({ - "role": "assistant", - "content": state.llm_response - }) - # Добавляем узел справки в граф help_node_id = f"help_{len(state.graph_nodes) + 1}" + # Добавляем узел справки в граф state.graph_nodes.append({ "id": help_node_id, "type": "info", "data": { "label": "Справка", - "details": "Список команд" + "details": "Список команд", + "message": {"role": "assistant", "content": state.llm_response, "node_id": help_node_id} } }) state.graph_edges.append({ @@ -466,4 +533,11 @@ def help_node(state: AgentState) -> AgentState: state.parent_node_id = help_node_id state.current_node_id = help_node_id + # Обновляем временную историю чата + state.temporary_chat_history.append({ + "role": "assistant", + "content": state.llm_response, + "node_id": help_node_id + }) + return state diff --git a/app/workflows.py b/app/workflows.py index ff214ca..46e5339 100644 --- a/app/workflows.py +++ b/app/workflows.py @@ -97,41 +97,57 @@ def run_agent(user_input: str, Может продолжить существующий граф по graph_id. Возвращает обновленное состояние и ID графа. """ + + # ---------------------------------------------------- Initial State Setup ---------------------------------------------------------------- initial_state = AgentState(input=user_input, parent_node_id=parent_node_id) - # Если есть существующий ID графа, загружаем его историю + # Если есть существующий ID графа, загружаем его историю и структуру + loaded_graph_data = None if existing_graph_id: - existing_graph_data = graph_history_manager.get_graph( - existing_graph_id) - if existing_graph_data: + # Получаем данные графа, включая сгенерированные сообщения до parent_node_id (либо current_node_id из БД) + # Если parent_node_id передан, используем его для построения истории. + loaded_graph_data = graph_history_manager.get_graph( + existing_graph_id, target_node_id=parent_node_id) + + if loaded_graph_data: print(f"Продолжаю существующий граф {existing_graph_id}") - initial_state.chat_history = existing_graph_data.get( - "messages", []) - initial_state.graph_nodes = existing_graph_data.get( - "graph_nodes", []) - initial_state.graph_edges = existing_graph_data.get( - "graph_edges", []) - initial_state.parent_node_id = parent_node_id or existing_graph_data.get( - "current_node_id") + # Загружаем узлы и ребра для продолжения графа + initial_state.graph_nodes = loaded_graph_data.get("graph_nodes", []) + initial_state.graph_edges = loaded_graph_data.get("graph_edges", []) + + # Устанавливаем parent_node_id для нового входного узла + # Если parent_node_id был передан в запросе, используем его, + # иначе берем current_node_id из загруженного графа. + initial_state.parent_node_id = parent_node_id or loaded_graph_data.get("current_node_id") + + # История чата для текущего раунда работы LLM формируется из загруженных сообщений. + initial_state.temporary_chat_history = loaded_graph_data.get("messages", []) + + # ---------------------------------------------------- run_agent ---------------------------------------------------------------- # Запускаем граф result = app.invoke(initial_state) final_state = AgentState(**result) - # Сохраняем обновленное состояние графа + # ---------------------------------------------------- Save Graph ---------------------------------------------------------------- + # Сохраняем обновленное состояние графа. + # Обратите внимание: chat_history больше не сохраняется напрямую, + # она является частью данных узлов в graph_nodes. graph_data_to_save = { - "id": existing_graph_id, - "messages": final_state.chat_history, + "id": existing_graph_id, # Используем существующий ID или он будет сгенерирован + # менеджером истории при первом сохранении "graph_nodes": final_state.graph_nodes, "graph_edges": final_state.graph_edges, "current_node_id": final_state.current_node_id } new_graph_id = graph_history_manager.save_graph(graph_data_to_save) - # Формируем ответ для фронтенда + # ---------------------------------------------------- prepare response ---------------------------------------------------------------- + # Для `messages` в `response_data` используем `final_state.temporary_chat_history`, + # так как она отражает только сообщения текущей ветки, добавленные в ходе этого выполнения. response_data = { "graph_id": new_graph_id, - "messages": final_state.chat_history, + "messages": final_state.temporary_chat_history, "llm_response": final_state.llm_response, "image_urls": final_state.image_urls, "analysis_result": final_state.analysis_result, diff --git a/graph_history.db b/graph_history.db index bfc11bcab2e40e3e011affdb1068d7788f4ff28e..e2c7b1c46d4bcd5d4e01fd548d895a68078126b5 100644 GIT binary patch literal 81920 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 literal 286720 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�(x| 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 Je=+&}{{x$&