From f6ca8552f6ee7fcc89882dbaadf1e4a37835880f Mon Sep 17 00:00:00 2001 From: manoraga Date: Fri, 7 Aug 2026 07:57:20 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B2=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D0=B8=20main.py=20=D0=B8=D0=B7-=D0=B7=D0=B0?= =?UTF-8?q?=20=D0=BD=D0=B5=D1=83=D0=B4=D0=B0=D1=87=D0=BD=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D1=81=D0=BB=D0=B8=D1=8F=D0=BD=D0=B8=D1=8F=20=D0=BE=D1=81?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B5=D0=BA=D1=82=D0=B0=20=D0=B8=20=D0=B2=D0=B5=D0=B1=20=D0=BC?= =?UTF-8?q?=D0=BE=D1=80=D0=B4=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/__init__.py | 1 + app/core/__init__.py | 1 + app/core/ollama_client.py | 32 ++ app/db/__init__.py | 1 + app/db/database.py | 152 ++++++++++ app/orchestrator.py | 101 +++++++ app/tools/__init__.py | 1 + app/tools/definitions.py | 111 +++++++ app/tools/handlers.py | 101 +++++++ context_memory.db | Bin 0 -> 12288 bytes data/scud_orion_ai.db | Bin 2560000 -> 2560000 bytes data/static_reason_workers.csv | 4 +- frontend/index.html | 342 +++++++++++++++++++++ init_db.py | 78 +++++ llm_agent.py | 474 +++++++++++++++++++++++++++++ ref.py | 525 +++++++++++++++++++++++++++++++++ 16 files changed, 1923 insertions(+), 1 deletion(-) create mode 100644 app/__init__.py create mode 100644 app/core/__init__.py create mode 100644 app/core/ollama_client.py create mode 100644 app/db/__init__.py create mode 100644 app/db/database.py create mode 100644 app/orchestrator.py create mode 100644 app/tools/__init__.py create mode 100644 app/tools/definitions.py create mode 100644 app/tools/handlers.py create mode 100644 context_memory.db create mode 100644 frontend/index.html create mode 100644 init_db.py create mode 100644 llm_agent.py create mode 100644 ref.py diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/app/__init__.py @@ -0,0 +1 @@ + diff --git a/app/core/__init__.py b/app/core/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/app/core/__init__.py @@ -0,0 +1 @@ + diff --git a/app/core/ollama_client.py b/app/core/ollama_client.py new file mode 100644 index 0000000..24465e0 --- /dev/null +++ b/app/core/ollama_client.py @@ -0,0 +1,32 @@ +import json +import urllib.request +import urllib.error + +OLLAMA_URL = "http://192.168.11.3:11434/api/chat" +MODEL_NAME = "qwen2.5:14b" + +def send_ollama_request(messages: list, tools: list) -> dict: + """Отправляет HTTP-запрос к локальной модели Ollama.""" + payload = { + "model": MODEL_NAME, + "messages": messages, + "tools": tools, + "stream": False, + "options": { + "num_predict": 2048, + "num_ctx": 8192, + "temperature": 0.1 + } + } + + req = urllib.request.Request( + OLLAMA_URL, + data=json.dumps(payload).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + try: + with urllib.request.urlopen(req) as response: + return json.loads(response.read().decode("utf-8")) + except urllib.error.URLError as e: + raise ConnectionError(f"Ошибка связи с Ollama ({OLLAMA_URL}): {e}") diff --git a/app/db/__init__.py b/app/db/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/app/db/__init__.py @@ -0,0 +1 @@ + diff --git a/app/db/database.py b/app/db/database.py new file mode 100644 index 0000000..0b349de --- /dev/null +++ b/app/db/database.py @@ -0,0 +1,152 @@ +import sqlite3 + +DB_NAME = "/home/puh/scud_orion_ai_v2/data/scud_orion_ai.db" + +def get_connection(): + return sqlite3.connect(DB_NAME) + +def db_get_active_system_prompt() -> str: + """Извлекает активный системный промпт из базы данных SQLite.""" + try: + conn = get_connection() + cursor = conn.cursor() + cursor.execute("SELECT prompt_text FROM system_prompts WHERE name = 'main_agent' AND is_active = 1 LIMIT 1") + row = cursor.fetchone() + conn.close() + if row and row[0]: + return row[0].replace("**", "") + except Exception as e: + print(f"Ошибка чтения системного промпта из БД: {e}") + + return "Ты — интеллектуальный ИИ-ассистент и архитектурный координатор проекта SCUD Orion AI." + +def db_add_system_prompt(name: str = "main_agent", prompt_text: str = "") -> dict: + """Обновляет или добавляет активный системный промпт в БД.""" + clean_text = prompt_text.replace("**", "") + conn = get_connection() + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO system_prompts (name, prompt_text, is_active) + VALUES (?, ?, 1) + ON CONFLICT(name) DO UPDATE SET prompt_text=excluded.prompt_text, updated_at=CURRENT_TIMESTAMP + """, (name, clean_text)) + conn.commit() + conn.close() + return {"status": "success", "message": f"Системный промпт '{name}' успешно обновлен в базе!"} + +def db_get_rules() -> list: + """Извлекает правила из таблицы ai_knowledge_base.""" + conn = get_connection() + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + cursor.execute("SELECT id, rule_text, added_by FROM ai_knowledge_base ORDER BY id") + rows = [dict(r) for r in cursor.fetchall()] + conn.close() + return rows + +def db_add_rule(rule_text: str, added_by: str = "Operator") -> dict: + """Добавляет новое правило или инструкцию в таблицу ai_knowledge_base.""" + clean_text = rule_text.replace("**", "") + conn = get_connection() + cursor = conn.cursor() + cursor.execute( + "INSERT INTO ai_knowledge_base (rule_text, added_by) VALUES (?, ?)", + (clean_text, added_by) + ) + rule_id = cursor.lastrowid + conn.commit() + conn.close() + return {"status": "success", "message": f"Правило #{rule_id} успешно добавлено в базу знаний!", "rule_id": rule_id} + +def db_get_tasks(status: str = None) -> list: + """Извлекает список задач из реестра БД.""" + conn = get_connection() + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + if status: + cursor.execute("SELECT * FROM tasks WHERE status = ? ORDER BY task_id", (status.upper(),)) + else: + cursor.execute("SELECT * FROM tasks ORDER BY task_id") + rows = [dict(r) for r in cursor.fetchall()] + conn.close() + return rows + +def db_update_task_status(task_id: str, status: str = None, due_date: str = None) -> dict: + """Обновляет статус и/или срок выполнения задачи.""" + conn = get_connection() + cursor = conn.cursor() + updates = [] + params = [] + + if status: + status_upper = status.upper() + updates.append("status = ?") + params.append(status_upper) + if status_upper == "COMPLETED": + updates.append("completed_at = CURRENT_TIMESTAMP") + else: + updates.append("completed_at = NULL") + + if due_date: + updates.append("due_date = ?") + params.append(due_date) + + if not updates: + conn.close() + return {"error": "Не указаны параметры для обновления"} + + params.append(task_id.upper()) + query = f"UPDATE tasks SET {', '.join(updates)} WHERE task_id = ?" + cursor.execute(query, tuple(params)) + + if cursor.rowcount == 0: + conn.close() + return {"error": f"Задача {task_id} не найдена"} + + conn.commit() + conn.close() + return {"status": "success", "message": f"Задача {task_id} обновлена"} + +def db_delete_task(task_id: str) -> dict: + """Удаляет задачу из базы данных по её task_id.""" + conn = get_connection() + cursor = conn.cursor() + cursor.execute("DELETE FROM tasks WHERE task_id = ?", (task_id.upper(),)) + deleted_count = cursor.rowcount + conn.commit() + conn.close() + + if deleted_count == 0: + return {"error": f"Задача {task_id} не найдена"} + return {"status": "success", "message": f"Задача {task_id} удалена"} + +def db_add_task(module: str = "general", title: str = "", priority: str = "MEDIUM", due_date: str = None, task_id: str = None) -> dict: + """Добавляет новую задачу в реестр с авто-генерацией TASK-ID.""" + conn = get_connection() + cursor = conn.cursor() + + if not task_id: + cursor.execute("SELECT task_id FROM tasks WHERE task_id LIKE 'TASK-%'") + rows = cursor.fetchall() + max_num = 0 + for r in rows: + try: + num = int(r[0].replace("TASK-", "")) + if num > max_num: + max_num = num + except ValueError: + pass + task_id = f"TASK-{max_num + 1:02d}" + + try: + cursor.execute( + "INSERT INTO tasks (task_id, module, title, status, priority, due_date) VALUES (?, ?, ?, 'BACKLOG', ?, ?)", + (task_id.upper(), module, title, priority.upper(), due_date) + ) + conn.commit() + res = {"status": "success", "message": f"Задача {task_id} создана", "task_id": task_id} + except sqlite3.IntegrityError: + res = {"error": f"Задача с ID {task_id} уже существует"} + finally: + conn.close() + return res diff --git a/app/orchestrator.py b/app/orchestrator.py new file mode 100644 index 0000000..dcf4396 --- /dev/null +++ b/app/orchestrator.py @@ -0,0 +1,101 @@ +import json +from typing import List, Dict, Any, Tuple +from datetime import datetime + +from app.db import database +from app.tools.definitions import TOOLS_SCHEMA +from app.tools.handlers import handle_tool_call, get_system_capabilities_text +from app.core.ollama_client import send_ollama_request + +def process_chat_message(user_message: str, chat_history: List[Dict[str, Any]] = None) -> Tuple[str, List[Dict[str, Any]]]: + if chat_history is None: + chat_history = [] + + current_now = datetime.now().strftime("%Y-%m-%d %H:%M") + user_clean = user_message.replace("\xa0", " ").strip() + user_lower = user_clean.lower() + + # 1. Жесткий перехват: Помощь и варианты команд (чистый Plain Text без Markdown) + if any(phrase in user_lower for phrase in ["помощь", "возможности", "что ты умеешь", "помощь в общении", "варианты команд"]): + formatted_text = get_system_capabilities_text() + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # 2. Жесткий перехват: Системный промпт из БД + if any(phrase in user_lower for phrase in ["системный промпт", "покажи промпт", "промпт системы", "промпт из базы"]): + prompt_text = database.db_get_active_system_prompt() + formatted_text = f"⚙️ Актуальный системный промпт ИИ (из базы SQLite):\n\n{prompt_text}" + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # 3. Жесткий перехват: База знаний из БД + if any(phrase in user_lower for phrase in ["базу знаний", "база знаний", "покажи правила", "инструкции ии"]): + rules = database.db_get_rules() + if not rules: + formatted_text = "База знаний пуста." + else: + formatted_text = "🧠 База знаний ИИ (ai_knowledge_base):\n\n" + for r in rules: + formatted_text += f"{r.get('id')}. {r.get('rule_text')}\n\n" + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # Динамическая подгрузка системного промпта из БД SQLite + dynamic_prompt_text = database.db_get_active_system_prompt() + system_prompt = { + "role": "system", + "content": f"Текущая дата и время сервера: {current_now}.\n\n{dynamic_prompt_text}" + } + + messages = [system_prompt] + chat_history + [{"role": "user", "content": user_message}] + + try: + res_data = send_ollama_request(messages=messages, tools=TOOLS_SCHEMA) + msg = res_data.get("message", {}) + + tool_calls = msg.get("tool_calls", []) + content_str = msg.get("content", "").strip().replace("**", "").replace("```", "").replace("###", "") + + # Перехват текстового JSON с именем функции + if not tool_calls and "name" in content_str and "db_" in content_str: + try: + start_idx = content_str.find("{") + end_idx = content_str.rfind("}") + 1 + if start_idx != -1 and end_idx != -1: + parsed = json.loads(content_str[start_idx:end_idx]) + if "name" in parsed: + tool_calls = [{"function": parsed}] + except Exception: + pass + + if tool_calls: + for tool in tool_calls: + fn_name = tool["function"]["name"] + fn_args = tool["function"].get("arguments", {}) + + formatted_text = handle_tool_call(fn_name, fn_args) + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": content_str} + ] + return content_str, updated_history + + except Exception as e: + return f"Ошибка обработки запроса: {e}", chat_history \ No newline at end of file diff --git a/app/tools/__init__.py b/app/tools/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/app/tools/__init__.py @@ -0,0 +1 @@ + diff --git a/app/tools/definitions.py b/app/tools/definitions.py new file mode 100644 index 0000000..34f4a8d --- /dev/null +++ b/app/tools/definitions.py @@ -0,0 +1,111 @@ +TOOLS_SCHEMA = [ + { + "type": "function", + "function": { + "name": "db_get_tasks", + "description": "ПОЛУЧИТЬ СПИСОК ЗАДАЧ ПРОЕКТА. Вызывай ТОЛЬКО когда пользователь просит показать задачи, бэклог или список дел.", + "parameters": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "Фильтр статуса: BACKLOG, IN_PROGRESS или COMPLETED." + } + } + } + } + }, + { + "type": "function", + "function": { + "name": "db_get_rules", + "description": "ПОЛУЧИТЬ БАЗУ ЗНАНИЙ ИИ И ПРАВИЛА АРБИТРАЖА (ai_knowledge_base). Вызывай когда пользователь просит показать базу знаний, правила, инструкции или промпты.", + "parameters": {"type": "object", "properties": {}} + } + }, + { + "type": "function", + "function": { + "name": "db_add_rule", + "description": "Добавить новое правило, инструкцию или факт в базу знаний (ai_knowledge_base). Вызывай при командах 'добавь в базу знаний', 'запомни правило', 'запиши инструкцию'.", + "parameters": { + "type": "object", + "properties": { + "rule_text": {"type": "string", "description": "Текст правила, инструкции или факта для сохранения"}, + "added_by": {"type": "string", "description": "Автор или источник правила, по умолчанию Operator"} + }, + "required": ["rule_text"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_get_system_prompt", + "description": "ПОЛУЧИТЬ ТЕКУЩИЙ СИСТЕМНЫЙ ПРОМПТ ИИ (system_prompts). Вызывай когда пользователь просит показать системный промпт, инструкции ассистента или промпт из базы.", + "parameters": {"type": "object", "properties": {}} + } + }, + { + "type": "function", + "function": { + "name": "db_add_system_prompt", + "description": "Обновить или добавить системный промпт ИИ в базу данных. Вызывай при командах 'задай системный промпт', 'измени промпт', 'обнови системный промпт'.", + "parameters": { + "type": "object", + "properties": { + "prompt_text": {"type": "string", "description": "Полный новый текст системного промпта"}, + "name": {"type": "string", "description": "Имя промпта, по умолчанию main_agent"} + }, + "required": ["prompt_text"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_update_task_status", + "description": "Изменить статус и/или срок выполнения задачи в реестре.", + "parameters": { + "type": "object", + "properties": { + "task_id": {"type": "string", "description": "Идентификатор задачи, например TASK-17"}, + "status": {"type": "string", "description": "Новый статус: COMPLETED, IN_PROGRESS или BACKLOG"}, + "due_date": {"type": "string", "description": "Срок выполнения задачи"} + }, + "required": ["task_id"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_delete_task", + "description": "Удалить задачу из реестра по её task_id (например, TASK-18).", + "parameters": { + "type": "object", + "properties": { + "task_id": {"type": "string", "description": "Идентификатор задачи для удаления, например TASK-18"} + }, + "required": ["task_id"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_add_task", + "description": "Добавить новую задачу в бэклог проекта.", + "parameters": { + "type": "object", + "properties": { + "title": {"type": "string", "description": "Краткое описание задачи"}, + "priority": {"type": "string", "description": "Приоритет: HIGH, MEDIUM, LOW"}, + "module": {"type": "string", "description": "Модуль проекта, например general или services/scud_export"}, + "due_date": {"type": "string", "description": "Срок выполнения задачи, например '2026-08-07 12:00'"} + }, + "required": ["title"] + } + } + } +] diff --git a/app/tools/handlers.py b/app/tools/handlers.py new file mode 100644 index 0000000..259043a --- /dev/null +++ b/app/tools/handlers.py @@ -0,0 +1,101 @@ +from app.db import database + +def get_system_capabilities_text() -> str: + """Формирует список возможностей и примеров команд для текущей стадии проекта.""" + return ( + "🛠 Доступные команды и возможности системы SCUD Orion AI:\n\n" + "1. Управление задачами (Бэклог):\n" + " • «Покажи последние задачи» — вывод списка задач проекта.\n" + " • «Добавь задачу: Настроить интеграцию 1С с REST API» — создание новой задачи.\n" + " • «Измени статус задачи TASK-01 на COMPLETED» — обновление состояния.\n" + " • «Удали задачу TASK-02» — удаление задачи из реестра.\n\n" + "2. База знаний и правила (ai_knowledge_base):\n" + " • «Покажи базу знаний» (или «покажи правила») — вывод текущих правил проекта.\n" + " • «Добавь в базу знаний: Офисные сотрудники отдела разработки работают по гибкому графику с 09:00 до 11:00» — запись нового правила.\n\n" + "3. Системные промпты (system_prompts):\n" + " • «Покажи системный промпт» — просмотр активных инструкций ИИ.\n" + " • «Обнови системный промпт: Ты — ассистент SCUD Orion AI. Отвечай кратко и строго в формате Plain Text.» — смена роли ИИ на лету.\n\n" + "Вы можете написать любой из этих запросов в чат в свободной форме." + ) + +def handle_tool_call(fn_name: str, fn_args: dict) -> str: + """Диспетчеризация вызова функций и форматирование текстового ответа.""" + + if fn_name == "db_get_tasks": + tasks = database.db_get_tasks(status=fn_args.get("status")) + if not tasks: + return "Список задач пуст." + tasks_sorted = sorted(tasks, key=lambda x: x.get('task_id', ''), reverse=True) + formatted_text = "📋 Последние задачи проекта:\n\n" + for t in tasks_sorted: + due = f" (до {t['due_date']})" if t.get('due_date') else "" + priority = t.get('priority') or 'MEDIUM' + status_str = t.get('status') or 'BACKLOG' + module_str = t.get('module') or 'general' + formatted_text += f"{t.get('task_id')} — {t.get('title')} [{status_str}]\n" + formatted_text += f" • Приоритет: {priority} | Модуль: {module_str}{due}\n\n" + return formatted_text + + elif fn_name == "db_get_rules": + rules = database.db_get_rules() + if not rules: + return "База знаний пуста." + formatted_text = "🧠 База знаний ИИ (ai_knowledge_base):\n\n" + for r in rules: + formatted_text += f"{r.get('id')}. {r.get('rule_text')}\n\n" + return formatted_text + + elif fn_name == "db_add_rule": + res = database.db_add_rule( + rule_text=fn_args.get("rule_text", ""), + added_by=fn_args.get("added_by", "Operator") + ) + return res.get("message", "Правило добавлено в базу знаний.") + + elif fn_name == "db_get_system_prompt": + prompt_text = database.db_get_active_system_prompt() + return f"⚙️ Актуальный системный промпт ИИ (из базы SQLite):\n\n{prompt_text}" + + elif fn_name == "db_add_system_prompt": + res = database.db_add_system_prompt( + name=fn_args.get("name", "main_agent"), + prompt_text=fn_args.get("prompt_text", "") + ) + return res.get("message", "Промпт обновлен.") + + elif fn_name == "db_add_task": + res = database.db_add_task( + module=fn_args.get("module", "general"), + title=fn_args.get("title"), + priority=fn_args.get("priority", "MEDIUM"), + due_date=fn_args.get("due_date") + ) + if "error" in res: + return f"Ошибка добавления задачи: {res['error']}" + assigned_id = res.get("task_id", "TASK") + due_str = fn_args.get('due_date') or 'Без срока' + return ( + f"Задача {assigned_id} успешно создана!\n\n" + f"• Название: {fn_args.get('title')}\n" + f"• Приоритет: {fn_args.get('priority', 'MEDIUM')}\n" + f"• Срок: {due_str}\n" + f"• Модуль: {fn_args.get('module', 'general')}" + ) + + elif fn_name == "db_update_task_status": + res = database.db_update_task_status( + task_id=fn_args.get("task_id"), + status=fn_args.get("status"), + due_date=fn_args.get("due_date") + ) + if "error" in res: + return f"Ошибка обновления задачи: {res['error']}" + return f"Статус задачи {fn_args.get('task_id')} успешно обновлен!" + + elif fn_name == "db_delete_task": + res = database.db_delete_task(task_id=fn_args.get("task_id")) + if "error" in res: + return f"Ошибка удаления задачи: {res['error']}" + return f"Задача {fn_args.get('task_id')} успешно удалена из базы!" + + return f"Функция {fn_name} выполнена." \ No newline at end of file diff --git a/context_memory.db b/context_memory.db new file mode 100644 index 0000000000000000000000000000000000000000..0f2bc8f20295f1e0431c62d4a3ce1901d46964d8 GIT binary patch literal 12288 zcmeI#&r8EF6bJC6ippR=Zo9tQ6hshD-mF`cVLNA+fjfn2E33>_mrV4iH~%RAt>Mw8 zZc0zPcpBdaNqFQXG@qW{;L1x(On2GzAvAQv8jN#xLc|#3`Pj(EGHkxNO!C#{tAewG z=Z|Xri#fG9tIg}5s}5iv0uX=z1Rwwb2tWV=5P$##An<^1<45aJ#i(B`Oovo(d;w(v{ z_(eZW@=jibGm{m$Dt)awETy)u-?5%mJ2mWtfB*y_009U<00Izz00bZa0SG`~T?H!k gVd($Y_4ndk5P$##AOHafKmY;|fB*y_0D(f_8(E%PwEzGB literal 0 HcmV?d00001 diff --git a/data/scud_orion_ai.db b/data/scud_orion_ai.db index 17618259588257f7bb4ffa26e65079c442acda05..90f2085d5b215e5ecd18aee763e116f126e1900c 100644 GIT binary patch delta 226349 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%0A!{?T%B@pq||lrIYN5jpzl9g|W^MID)$)5p4p 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 diff --git a/data/static_reason_workers.csv b/data/static_reason_workers.csv index 57e5807..49f9ef7 100644 --- a/data/static_reason_workers.csv +++ b/data/static_reason_workers.csv @@ -9,4 +9,6 @@ fio,reason,note Пшеничный Виктор Петрович,Удаленная работа,Постоянная удаленка Незнанова Валерия Игоревна,Удаленная работа,Постоянная удаленка Ковалев Владимир Владимирович,Удаленная работа,Постоянная удаленка -Кожокарь Татьяна Юрьевна,Удаленная работа,Постоянная удаленка \ No newline at end of file +Кожокарь Татьяна Юрьевна,Удаленная работа,Постоянная удаленка +Субетто Юлия Викторовна,Удаленная работа,Постоянная удаленка +Ароян Станислав Месропович,Удаленная работа,Временная удаленка \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..c7508ba --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,342 @@ +cat << 'EOF' > /home/puh/scud_orion_ai_v2/frontend/index.html + + + + + + SCUD Orion AI — Context Manager + + + + + + + +
+
+
+ +
+
+

SCUD Orion AI

+ Context & Task Manager +
+
+ +
+ + API Online + + +
+
+ + +
+
+ +
+

+ ИИ-Ассистент +

+

+ Для вывода возможных команд управления локальными системами, спросите об этом в произвольном формате или нажмите на кнопку ниже. +

+ +
+
+ + +
+
+
+ +
+ +
+ + +
+ +
+
+
+ + + + + + + + + +EOF + +# Копируем файл в корень для совместимости с веб-сервером +cp /home/puh/scud_orion_ai_v2/frontend/index.html /home/puh/scud_orion_ai_v2/index.html \ No newline at end of file diff --git a/init_db.py b/init_db.py new file mode 100644 index 0000000..e279610 --- /dev/null +++ b/init_db.py @@ -0,0 +1,78 @@ +import sqlite3 +import os +from datetime import datetime + +DB_NAME = "context_memory.db" + +def init_db(): + conn = sqlite3.connect(DB_NAME) + cursor = conn.cursor() + + # 1. Таблица трекинга задач + cursor.execute(""" + CREATE TABLE IF NOT EXISTS tasks ( + task_id TEXT PRIMARY KEY, + module TEXT NOT NULL, + title TEXT NOT NULL, + status TEXT NOT NULL, + priority TEXT NOT NULL, + completed_at TEXT + ) + """) + + # 2. Таблица архитектурных правил и контекста + cursor.execute(""" + CREATE TABLE IF NOT EXISTS architecture_memory ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + category TEXT NOT NULL, + rule_text TEXT NOT NULL, + is_active INTEGER DEFAULT 1, + created_at TEXT DEFAULT CURRENT_TIMESTAMP + ) + """) + + # Первичное заполнение реестра задач [TASK-01] .. [TASK-17] + tasks_data = [ + ("TASK-01", "services/data_loader", "Исправление KeyError по ФИО в Excel экспорте 1С (переход на .iloc)", "COMPLETED", "HIGH", "2026-08-03"), + ("TASK-02", "services/zup_extractor", "Перевод подключения 1С:ЗУП на продакшн MS SQL сервер ACCOUNT-01 + гибридный фоллбэк", "COMPLETED", "HIGH", "2026-08-04"), + ("TASK-03", "services/scud_export", "Инцидент Равина В.Э.: Фиксация 100% приоритета сырых логов pLogData СКУД над расчетом УРВ Ориона", "COMPLETED", "HIGH", "2026-08-04"), + ("TASK-04", "core/database", "Реализация схемы SQLite WAL, сохранение снапшотов и маппинг колонок (department/position)", "COMPLETED", "HIGH", "2026-08-05"), + ("TASK-05", "core/database", "Исправление бага дублирования номеров снапшотов (переход на вычисление MAX() по суффиксу)", "COMPLETED", "HIGH", "2026-08-05"), + ("TASK-06", "scripts/fix_snapshots", "Создание и выполнение скрипта сквозной переиндексации снапшотов с префиксом Y", "COMPLETED", "HIGH", "2026-08-05"), + ("TASK-07", "scripts/db_cli", "Реализация CLI-инспектора БД и выравнивание номеров срезов для идеальной верстки в терминале", "COMPLETED", "HIGH", "2026-08-05"), + ("TASK-08", "main.py / logic", "Двойная проверка исключений по department_scud и 1С, удержание 100% приоритета кадровых документов", "COMPLETED", "HIGH", "2026-08-05"), + ("TASK-09", "services/text_reporter", "Лаконичный вывод неразмеченных сотрудников с короткими аббревиатурами отделов СКУД (РУК, ОИЗ, ПУ и др.)", "COMPLETED", "HIGH", "2026-08-05"), + ("TASK-10", "services/scud_export", "Внутридневной контроль: Извлечение полных цепочек проходов pLogData (входы/выходы за смену)", "BACKLOG", "HIGH", None), + ("TASK-11", "services/data_loader", "Внутридневной контроль: Расчет количества и суммарной длительности отлучек/перекуров сверх обеда", "BACKLOG", "HIGH", None), + ("TASK-12", "services/text_reporter", "Внутридневной контроль: Вывод списка системных нарушителей внутреннего распорядка в Markdown-отчет", "BACKLOG", "MEDIUM", None), + ("TASK-13", "automation", "Автоматизация сбора срезов по расписанию (Cron / Systemd Timers на 12:00, 17:00, 19:00)", "BACKLOG", "HIGH", None), + ("TASK-14", "services/notifications", "Интеграция Telegram-бота для алертов Администратору при массовых сбоях турникетов (>5%)", "BACKLOG", "MEDIUM", None), + ("TASK-15", "api / fastapi", "Создание REST API на FastAPI (/api/v1/snapshots, /api/v1/scud/logs, /api/v1/anomalies)", "BACKLOG", "HIGH", None), + ("TASK-16", "frontend / chat", "Веб-интерфейс с ИИ-чатом на базе Ollama (Qwen 2.5 14B) с поддержкой Function Calling к REST API", "BACKLOG", "HIGH", None), + ("TASK-17", "core/memory", "Создание модуля персистентной памяти проекта в SQLite и CLI-инструмента для фиксации архитектурных решений", "IN_PROGRESS", "HIGH", None), + ] + + cursor.executemany(""" + INSERT OR REPLACE INTO tasks (task_id, module, title, status, priority, completed_at) + VALUES (?, ?, ?, ?, ?, ?) + """, tasks_data) + + # Базовые правила архитектуры + rules_data = [ + ("logic_rule", "Сырые логи pLogData СКУД имееют 100% приоритет над расчетом УРВ Ориона."), + ("logic_rule", "Официальные кадровые документы 1С (отпуска, командировки, больничные) имеют абсолютный приоритет над отсутствием в СКУД."), + ("scud_override", "Запрещено переименовывать ФИО сотрудников при 100% совпадении строк между 1С и СКУД в AI-верификаторе."), + ("formatting", "Температура указывается исключительно в градусах Цельсия, скорости в км/ч.") + ] + + cursor.executemany(""" + INSERT INTO architecture_memory (category, rule_text) + VALUES (?, ?) + """, rules_data) + + conn.commit() + conn.close() + print("[✓] База данных контекста и трекинга задач успешно создана и заполнена!") + +if __name__ == "__main__": + init_db() \ No newline at end of file diff --git a/llm_agent.py b/llm_agent.py new file mode 100644 index 0000000..867274b --- /dev/null +++ b/llm_agent.py @@ -0,0 +1,474 @@ +import sqlite3 +import json +import urllib.request +import urllib.error +from typing import List, Dict, Any, Tuple +from datetime import datetime + +# Абсолютный путь к базе данных проекта scud_orion_ai_v2 +DB_NAME = "/home/puh/scud_orion_ai_v2/data/scud_orion_ai.db" +OLLAMA_URL = "http://192.168.11.3:11434/api/chat" +MODEL_NAME = "qwen2.5:14b" + + +# === БЛОК РАБОТЫ С БАЗОЙ ДАННЫХ === + +def db_get_active_system_prompt() -> str: + """Извлекает активный системный промпт из базы данных SQLite.""" + try: + conn = sqlite3.connect(DB_NAME) + cursor = conn.cursor() + cursor.execute("SELECT prompt_text FROM system_prompts WHERE name = 'main_agent' AND is_active = 1 LIMIT 1") + row = cursor.fetchone() + conn.close() + if row and row[0]: + # Чистим от случайных звездочек + return row[0].replace("**", "") + except Exception as e: + print(f"Ошибка чтения системного промпта из БД: {e}") + + return "Ты — интеллектуальный ИИ-ассистент и архитектурный координатор проекта SCUD Orion AI." + + +def db_add_system_prompt(name: str = "main_agent", prompt_text: str = "") -> dict: + """Обновляет или добавляет активный системный промпт в БД.""" + clean_text = prompt_text.replace("**", "") + conn = sqlite3.connect(DB_NAME) + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO system_prompts (name, prompt_text, is_active) + VALUES (?, ?, 1) + ON CONFLICT(name) DO UPDATE SET prompt_text=excluded.prompt_text, updated_at=CURRENT_TIMESTAMP + """, (name, clean_text)) + conn.commit() + conn.close() + return {"status": "success", "message": f"Системный промпт '{name}' успешно обновлен в базе!"} + + +def db_get_tasks(status: str = None) -> list: + """Извлекает список задач из реестра БД.""" + conn = sqlite3.connect(DB_NAME) + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + if status: + cursor.execute("SELECT * FROM tasks WHERE status = ? ORDER BY task_id", (status.upper(),)) + else: + cursor.execute("SELECT * FROM tasks ORDER BY task_id") + rows = [dict(r) for r in cursor.fetchall()] + conn.close() + return rows + + +def db_update_task_status(task_id: str, status: str = None, due_date: str = None) -> dict: + """Обновляет статус и/или срок выполнения задачи.""" + conn = sqlite3.connect(DB_NAME) + cursor = conn.cursor() + updates = [] + params = [] + + if status: + status_upper = status.upper() + updates.append("status = ?") + params.append(status_upper) + if status_upper == "COMPLETED": + updates.append("completed_at = CURRENT_TIMESTAMP") + else: + updates.append("completed_at = NULL") + + if due_date: + updates.append("due_date = ?") + params.append(due_date) + + if not updates: + conn.close() + return {"error": "Не указаны параметры для обновления"} + + params.append(task_id.upper()) + query = f"UPDATE tasks SET {', '.join(updates)} WHERE task_id = ?" + cursor.execute(query, tuple(params)) + + if cursor.rowcount == 0: + conn.close() + return {"error": f"Задача {task_id} не найдена"} + + conn.commit() + conn.close() + return {"status": "success", "message": f"Задача {task_id} обновлена"} + + +def db_delete_task(task_id: str) -> dict: + """Удаляет задачу из базы данных по её task_id.""" + conn = sqlite3.connect(DB_NAME) + cursor = conn.cursor() + cursor.execute("DELETE FROM tasks WHERE task_id = ?", (task_id.upper(),)) + deleted_count = cursor.rowcount + conn.commit() + conn.close() + + if deleted_count == 0: + return {"error": f"Задача {task_id} не найдена"} + return {"status": "success", "message": f"Задача {task_id} удалена"} + + +def db_add_task(module: str = "general", title: str = "", priority: str = "MEDIUM", due_date: str = None, task_id: str = None) -> dict: + """Добавляет новую задачу в реестр с авто-генерацией TASK-ID.""" + conn = sqlite3.connect(DB_NAME) + cursor = conn.cursor() + + if not task_id: + cursor.execute("SELECT task_id FROM tasks WHERE task_id LIKE 'TASK-%'") + rows = cursor.fetchall() + max_num = 0 + for r in rows: + try: + num = int(r[0].replace("TASK-", "")) + if num > max_num: + max_num = num + except ValueError: + pass + task_id = f"TASK-{max_num + 1:02d}" + + try: + cursor.execute( + "INSERT INTO tasks (task_id, module, title, status, priority, due_date) VALUES (?, ?, ?, 'BACKLOG', ?, ?)", + (task_id.upper(), module, title, priority.upper(), due_date) + ) + conn.commit() + res = {"status": "success", "message": f"Задача {task_id} создана", "task_id": task_id} + except sqlite3.IntegrityError: + res = {"error": f"Задача с ID {task_id} уже существует"} + finally: + conn.close() + return res + + +def db_get_rules() -> list: + """Извлекает правила из таблицы ai_knowledge_base.""" + conn = sqlite3.connect(DB_NAME) + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + cursor.execute("SELECT id, rule_text, added_by FROM ai_knowledge_base ORDER BY id") + rows = [dict(r) for r in cursor.fetchall()] + conn.close() + return rows + + +# === СХЕМА ИНСТРУМЕНТОВ ДЛЯ OLLAMA === + +TOOLS_SCHEMA = [ + { + "type": "function", + "function": { + "name": "db_get_tasks", + "description": "ПОЛУЧИТЬ СПИСОК ЗАДАЧ ПРОЕКТА. Вызывай ТОЛЬКО когда пользователь просит показать задачи, бэклог или список дел.", + "parameters": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "Фильтр статуса: BACKLOG, IN_PROGRESS или COMPLETED." + } + } + } + } + }, + { + "type": "function", + "function": { + "name": "db_get_rules", + "description": "ПОЛУЧИТЬ БАЗУ ЗНАНИЙ ИИ И ПРАВИЛА АРБИТРАЖА (ai_knowledge_base). Вызывай когда пользователь просит показать базу знаний, правила, инструкции или промпты.", + "parameters": {"type": "object", "properties": {}} + } + }, + { + "type": "function", + "function": { + "name": "db_get_system_prompt", + "description": "ПОЛУЧИТЬ ТЕКУЩИЙ СИСТЕМНЫЙ ПРОМПТ ИИ (system_prompts). Вызывай когда пользователь просит показать системный промпт, инструкции ассистента или промпт из базы.", + "parameters": {"type": "object", "properties": {}} + } + }, + { + "type": "function", + "function": { + "name": "db_add_system_prompt", + "description": "Обновить или добавить системный промпт ИИ в базу данных. Вызывай при командах 'задай системный промпт', 'измени промпт', 'обнови системный промпт'.", + "parameters": { + "type": "object", + "properties": { + "prompt_text": {"type": "string", "description": "Полный новый текст системного промпта"}, + "name": {"type": "string", "description": "Имя промпта, по умолчанию main_agent"} + }, + "required": ["prompt_text"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_update_task_status", + "description": "Изменить статус и/или срок выполнения задачи в реестре.", + "parameters": { + "type": "object", + "properties": { + "task_id": {"type": "string", "description": "Идентификатор задачи, например TASK-17"}, + "status": {"type": "string", "description": "Новый статус: COMPLETED, IN_PROGRESS или BACKLOG"}, + "due_date": {"type": "string", "description": "Срок выполнения задачи"} + }, + "required": ["task_id"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_delete_task", + "description": "Удалить задачу из реестра по её task_id (например, TASK-18).", + "parameters": { + "type": "object", + "properties": { + "task_id": {"type": "string", "description": "Идентификатор задачи для удаления, например TASK-18"} + }, + "required": ["task_id"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_add_task", + "description": "Добавить новую задачу в бэклог проекта.", + "parameters": { + "type": "object", + "properties": { + "title": {"type": "string", "description": "Краткое описание задачи"}, + "priority": {"type": "string", "description": "Приоритет: HIGH, MEDIUM, LOW"}, + "module": {"type": "string", "description": "Модуль проекта, например general или services/scud_export"}, + "due_date": {"type": "string", "description": "Срок выполнения задачи, например '2026-08-07 12:00'"} + }, + "required": ["title"] + } + } + } +] + + +# === ОСНОВНАЯ ФУНКЦИЯ ОБРАБОТКИ СООБЩЕНИЙ === + +def process_chat_message(user_message: str, chat_history: List[Dict[str, Any]] = None) -> Tuple[str, List[Dict[str, Any]]]: + if chat_history is None: + chat_history = [] + + current_now = datetime.now().strftime("%Y-%m-%d %H:%M") + user_lower = user_message.lower().strip() + + # Жесткие перехваты для 100% чистого вывода без участия генератора Ollama (без звездочек!) + if any(phrase in user_lower for phrase in ["системный промпт", "покажи промпт", "промпт системы", "промпт из базы"]): + prompt_text = db_get_active_system_prompt() + formatted_text = f"⚙️ Актуальный системный промпт ИИ (из базы SQLite):\n\n{prompt_text}" + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + if any(phrase in user_lower for phrase in ["базу знаний", "база знаний", "покажи правила", "инструкции ии"]): + rules = db_get_rules() + if not rules: + formatted_text = "База знаний пуста." + else: + formatted_text = "🧠 База знаний ИИ (ai_knowledge_base):\n\n" + for r in rules: + formatted_text += f"{r.get('id')}. {r.get('rule_text')}\n\n" + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # Динамическая подгрузка системного промпта из БД SQLite + dynamic_prompt_text = db_get_active_system_prompt() + + system_prompt = { + "role": "system", + "content": f"Текущая дата и время сервера: {current_now}.\n\n{dynamic_prompt_text}" + } + + messages = [system_prompt] + chat_history + [{"role": "user", "content": user_message}] + + payload = { + "model": MODEL_NAME, + "messages": messages, + "tools": TOOLS_SCHEMA, + "stream": False, + "options": { + "num_predict": 2048, + "num_ctx": 8192, + "temperature": 0.1 + } + } + + req = urllib.request.Request( + OLLAMA_URL, + data=json.dumps(payload).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + try: + with urllib.request.urlopen(req) as response: + res_data = json.loads(response.read().decode("utf-8")) + msg = res_data.get("message", {}) + + tool_calls = msg.get("tool_calls", []) + content_str = msg.get("content", "").strip().replace("**", "") + + # Перехват вызова функции из текста + if not tool_calls and "name" in content_str and "db_" in content_str: + try: + start_idx = content_str.find("{") + end_idx = content_str.rfind("}") + 1 + if start_idx != -1 and end_idx != -1: + parsed = json.loads(content_str[start_idx:end_idx]) + if "name" in parsed: + tool_calls = [{"function": parsed}] + except Exception: + pass + + if tool_calls: + for tool in tool_calls: + fn_name = tool["function"]["name"] + fn_args = tool["function"].get("arguments", {}) + + # 1. Вывод задач + if fn_name == "db_get_tasks": + tasks = db_get_tasks(status=fn_args.get("status")) + if not tasks: + formatted_text = "Список задач пуст." + else: + tasks_sorted = sorted(tasks, key=lambda x: x.get('task_id', ''), reverse=True) + formatted_text = "📋 Последние задачи проекта:\n\n" + for t in tasks_sorted: + due = f" (до {t['due_date']})" if t.get('due_date') else "" + priority = t.get('priority') or 'MEDIUM' + status_str = t.get('status') or 'BACKLOG' + module_str = t.get('module') or 'general' + + formatted_text += f"{t.get('task_id')} — {t.get('title')} [{status_str}]\n" + formatted_text += f" • Приоритет: {priority} | Модуль: {module_str}{due}\n\n" + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # 2. Вывод базы знаний + elif fn_name == "db_get_rules": + rules = db_get_rules() + if not rules: + formatted_text = "База знаний пуста." + else: + formatted_text = "🧠 База знаний ИИ (ai_knowledge_base):\n\n" + for r in rules: + formatted_text += f"{r.get('id')}. {r.get('rule_text')}\n\n" + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # 3. Вывод системного промпта + elif fn_name == "db_get_system_prompt": + prompt_text = db_get_active_system_prompt() + formatted_text = f"⚙️ Актуальный системный промпт ИИ (из базы SQLite):\n\n{prompt_text}" + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # 4. Добавление/обновление системного промпта + elif fn_name == "db_add_system_prompt": + res = db_add_system_prompt( + name=fn_args.get("name", "main_agent"), + prompt_text=fn_args.get("prompt_text", "") + ) + formatted_text = res.get("message", "Промпт обновлен.") + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # 5. Добавление новой задачи + elif fn_name == "db_add_task": + res = db_add_task( + module=fn_args.get("module", "general"), + title=fn_args.get("title"), + priority=fn_args.get("priority", "MEDIUM"), + due_date=fn_args.get("due_date") + ) + + if "error" in res: + formatted_text = f"Ошибка добавления задачи: {res['error']}" + else: + assigned_id = res.get("task_id", "TASK") + due_str = fn_args.get('due_date') or 'Без срока' + formatted_text = ( + f"Задача {assigned_id} успешно создана!\n\n" + f"• Название: {fn_args.get('title')}\n" + f"• Приоритет: {fn_args.get('priority', 'MEDIUM')}\n" + f"• Срок: {due_str}\n" + f"• Модуль: {fn_args.get('module', 'general')}" + ) + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # 6. Обновление статуса задачи + elif fn_name == "db_update_task_status": + res = db_update_task_status( + task_id=fn_args.get("task_id"), + status=fn_args.get("status"), + due_date=fn_args.get("due_date") + ) + + if "error" in res: + formatted_text = f"Ошибка обновления задачи: {res['error']}" + else: + formatted_text = f"Статус задачи {fn_args.get('task_id')} успешно обновлен!" + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # 7. Удаление задачи + elif fn_name == "db_delete_task": + res = db_delete_task(task_id=fn_args.get("task_id")) + if "error" in res: + formatted_text = f"Ошибка удаления задачи: {res['error']}" + else: + formatted_text = f"Задача {fn_args.get('task_id')} успешно удалена из базы!" + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": content_str} + ] + return content_str, updated_history + + except urllib.error.URLError as e: + return f"Ошибка связи с Ollama ({OLLAMA_URL}): {e}", chat_history \ No newline at end of file diff --git a/ref.py b/ref.py new file mode 100644 index 0000000..7359194 --- /dev/null +++ b/ref.py @@ -0,0 +1,525 @@ +#!/usr/bin/env python3 +import os + +# Базовый путь к проекту +BASE_DIR = "/home/puh/scud_orion_ai_v2" + +# 1. Данные для файла app/db/database.py +DB_PY = '''import sqlite3 + +DB_NAME = "/home/puh/scud_orion_ai_v2/data/scud_orion_ai.db" + +def get_connection(): + return sqlite3.connect(DB_NAME) + +def db_get_active_system_prompt() -> str: + """Извлекает активный системный промпт из базы данных SQLite.""" + try: + conn = get_connection() + cursor = conn.cursor() + cursor.execute("SELECT prompt_text FROM system_prompts WHERE name = 'main_agent' AND is_active = 1 LIMIT 1") + row = cursor.fetchone() + conn.close() + if row and row[0]: + return row[0].replace("**", "") + except Exception as e: + print(f"Ошибка чтения системного промпта из БД: {e}") + + return "Ты — интеллектуальный ИИ-ассистент и архитектурный координатор проекта SCUD Orion AI." + +def db_add_system_prompt(name: str = "main_agent", prompt_text: str = "") -> dict: + """Обновляет или добавляет активный системный промпт в БД.""" + clean_text = prompt_text.replace("**", "") + conn = get_connection() + cursor = conn.cursor() + cursor.execute(""" + INSERT INTO system_prompts (name, prompt_text, is_active) + VALUES (?, ?, 1) + ON CONFLICT(name) DO UPDATE SET prompt_text=excluded.prompt_text, updated_at=CURRENT_TIMESTAMP + """, (name, clean_text)) + conn.commit() + conn.close() + return {"status": "success", "message": f"Системный промпт '{name}' успешно обновлен в базе!"} + +def db_get_rules() -> list: + """Извлекает правила из таблицы ai_knowledge_base.""" + conn = get_connection() + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + cursor.execute("SELECT id, rule_text, added_by FROM ai_knowledge_base ORDER BY id") + rows = [dict(r) for r in cursor.fetchall()] + conn.close() + return rows + +def db_add_rule(rule_text: str, added_by: str = "Operator") -> dict: + """Добавляет новое правило или инструкцию в таблицу ai_knowledge_base.""" + clean_text = rule_text.replace("**", "") + conn = get_connection() + cursor = conn.cursor() + cursor.execute( + "INSERT INTO ai_knowledge_base (rule_text, added_by) VALUES (?, ?)", + (clean_text, added_by) + ) + rule_id = cursor.lastrowid + conn.commit() + conn.close() + return {"status": "success", "message": f"Правило #{rule_id} успешно добавлено в базу знаний!", "rule_id": rule_id} + +def db_get_tasks(status: str = None) -> list: + """Извлекает список задач из реестра БД.""" + conn = get_connection() + conn.row_factory = sqlite3.Row + cursor = conn.cursor() + if status: + cursor.execute("SELECT * FROM tasks WHERE status = ? ORDER BY task_id", (status.upper(),)) + else: + cursor.execute("SELECT * FROM tasks ORDER BY task_id") + rows = [dict(r) for r in cursor.fetchall()] + conn.close() + return rows + +def db_update_task_status(task_id: str, status: str = None, due_date: str = None) -> dict: + """Обновляет статус и/или срок выполнения задачи.""" + conn = get_connection() + cursor = conn.cursor() + updates = [] + params = [] + + if status: + status_upper = status.upper() + updates.append("status = ?") + params.append(status_upper) + if status_upper == "COMPLETED": + updates.append("completed_at = CURRENT_TIMESTAMP") + else: + updates.append("completed_at = NULL") + + if due_date: + updates.append("due_date = ?") + params.append(due_date) + + if not updates: + conn.close() + return {"error": "Не указаны параметры для обновления"} + + params.append(task_id.upper()) + query = f"UPDATE tasks SET {', '.join(updates)} WHERE task_id = ?" + cursor.execute(query, tuple(params)) + + if cursor.rowcount == 0: + conn.close() + return {"error": f"Задача {task_id} не найдена"} + + conn.commit() + conn.close() + return {"status": "success", "message": f"Задача {task_id} обновлена"} + +def db_delete_task(task_id: str) -> dict: + """Удаляет задачу из базы данных по её task_id.""" + conn = get_connection() + cursor = conn.cursor() + cursor.execute("DELETE FROM tasks WHERE task_id = ?", (task_id.upper(),)) + deleted_count = cursor.rowcount + conn.commit() + conn.close() + + if deleted_count == 0: + return {"error": f"Задача {task_id} не найдена"} + return {"status": "success", "message": f"Задача {task_id} удалена"} + +def db_add_task(module: str = "general", title: str = "", priority: str = "MEDIUM", due_date: str = None, task_id: str = None) -> dict: + """Добавляет новую задачу в реестр с авто-генерацией TASK-ID.""" + conn = get_connection() + cursor = conn.cursor() + + if not task_id: + cursor.execute("SELECT task_id FROM tasks WHERE task_id LIKE 'TASK-%'") + rows = cursor.fetchall() + max_num = 0 + for r in rows: + try: + num = int(r[0].replace("TASK-", "")) + if num > max_num: + max_num = num + except ValueError: + pass + task_id = f"TASK-{max_num + 1:02d}" + + try: + cursor.execute( + "INSERT INTO tasks (task_id, module, title, status, priority, due_date) VALUES (?, ?, ?, 'BACKLOG', ?, ?)", + (task_id.upper(), module, title, priority.upper(), due_date) + ) + conn.commit() + res = {"status": "success", "message": f"Задача {task_id} создана", "task_id": task_id} + except sqlite3.IntegrityError: + res = {"error": f"Задача с ID {task_id} уже существует"} + finally: + conn.close() + return res +''' + +# 2. Данные для файла app/tools/definitions.py +TOOLS_DEFINITIONS_PY = '''TOOLS_SCHEMA = [ + { + "type": "function", + "function": { + "name": "db_get_tasks", + "description": "ПОЛУЧИТЬ СПИСОК ЗАДАЧ ПРОЕКТА. Вызывай ТОЛЬКО когда пользователь просит показать задачи, бэклог или список дел.", + "parameters": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "Фильтр статуса: BACKLOG, IN_PROGRESS или COMPLETED." + } + } + } + } + }, + { + "type": "function", + "function": { + "name": "db_get_rules", + "description": "ПОЛУЧИТЬ БАЗУ ЗНАНИЙ ИИ И ПРАВИЛА АРБИТРАЖА (ai_knowledge_base). Вызывай когда пользователь просит показать базу знаний, правила, инструкции или промпты.", + "parameters": {"type": "object", "properties": {}} + } + }, + { + "type": "function", + "function": { + "name": "db_add_rule", + "description": "Добавить новое правило, инструкцию или факт в базу знаний (ai_knowledge_base). Вызывай при командах 'добавь в базу знаний', 'запомни правило', 'запиши инструкцию'.", + "parameters": { + "type": "object", + "properties": { + "rule_text": {"type": "string", "description": "Текст правила, инструкции или факта для сохранения"}, + "added_by": {"type": "string", "description": "Автор или источник правила, по умолчанию Operator"} + }, + "required": ["rule_text"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_get_system_prompt", + "description": "ПОЛУЧИТЬ ТЕКУЩИЙ СИСТЕМНЫЙ ПРОМПТ ИИ (system_prompts). Вызывай когда пользователь просит показать системный промпт, инструкции ассистента или промпт из базы.", + "parameters": {"type": "object", "properties": {}} + } + }, + { + "type": "function", + "function": { + "name": "db_add_system_prompt", + "description": "Обновить или добавить системный промпт ИИ в базу данных. Вызывай при командах 'задай системный промпт', 'измени промпт', 'обнови системный промпт'.", + "parameters": { + "type": "object", + "properties": { + "prompt_text": {"type": "string", "description": "Полный новый текст системного промпта"}, + "name": {"type": "string", "description": "Имя промпта, по умолчанию main_agent"} + }, + "required": ["prompt_text"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_update_task_status", + "description": "Изменить статус и/или срок выполнения задачи в реестре.", + "parameters": { + "type": "object", + "properties": { + "task_id": {"type": "string", "description": "Идентификатор задачи, например TASK-17"}, + "status": {"type": "string", "description": "Новый статус: COMPLETED, IN_PROGRESS или BACKLOG"}, + "due_date": {"type": "string", "description": "Срок выполнения задачи"} + }, + "required": ["task_id"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_delete_task", + "description": "Удалить задачу из реестра по её task_id (например, TASK-18).", + "parameters": { + "type": "object", + "properties": { + "task_id": {"type": "string", "description": "Идентификатор задачи для удаления, например TASK-18"} + }, + "required": ["task_id"] + } + } + }, + { + "type": "function", + "function": { + "name": "db_add_task", + "description": "Добавить новую задачу в бэклог проекта.", + "parameters": { + "type": "object", + "properties": { + "title": {"type": "string", "description": "Краткое описание задачи"}, + "priority": {"type": "string", "description": "Приоритет: HIGH, MEDIUM, LOW"}, + "module": {"type": "string", "description": "Модуль проекта, например general или services/scud_export"}, + "due_date": {"type": "string", "description": "Срок выполнения задачи, например '2026-08-07 12:00'"} + }, + "required": ["title"] + } + } + } +] +''' + +# 3. Данные для файла app/tools/handlers.py +TOOLS_HANDLERS_PY = '''from app.db import database + +def handle_tool_call(fn_name: str, fn_args: dict) -> str: + """Диспетчеризация вызова функций и форматирование текстового ответа.""" + + if fn_name == "db_get_tasks": + tasks = database.db_get_tasks(status=fn_args.get("status")) + if not tasks: + return "Список задач пуст." + tasks_sorted = sorted(tasks, key=lambda x: x.get('task_id', ''), reverse=True) + formatted_text = "📋 Последние задачи проекта:\n\n" + for t in tasks_sorted: + due = f" (до {t['due_date']})" if t.get('due_date') else "" + priority = t.get('priority') or 'MEDIUM' + status_str = t.get('status') or 'BACKLOG' + module_str = t.get('module') or 'general' + formatted_text += f"{t.get('task_id')} — {t.get('title')} [{status_str}]\n" + formatted_text += f" • Приоритет: {priority} | Модуль: {module_str}{due}\n\n" + return formatted_text + + elif fn_name == "db_get_rules": + rules = database.db_get_rules() + if not rules: + return "База знаний пуста." + formatted_text = "🧠 База знаний ИИ (ai_knowledge_base):\n\n" + for r in rules: + formatted_text += f"{r.get('id')}. {r.get('rule_text')}\n\n" + return formatted_text + + elif fn_name == "db_add_rule": + res = database.db_add_rule( + rule_text=fn_args.get("rule_text", ""), + added_by=fn_args.get("added_by", "Operator") + ) + return res.get("message", "Правило добавлено в базу знаний.") + + elif fn_name == "db_get_system_prompt": + prompt_text = database.db_get_active_system_prompt() + return f"⚙️ Актуальный системный промпт ИИ (из базы SQLite):\n\n{prompt_text}" + + elif fn_name == "db_add_system_prompt": + res = database.db_add_system_prompt( + name=fn_args.get("name", "main_agent"), + prompt_text=fn_args.get("prompt_text", "") + ) + return res.get("message", "Промпт обновлен.") + + elif fn_name == "db_add_task": + res = database.db_add_task( + module=fn_args.get("module", "general"), + title=fn_args.get("title"), + priority=fn_args.get("priority", "MEDIUM"), + due_date=fn_args.get("due_date") + ) + if "error" in res: + return f"Ошибка добавления задачи: {res['error']}" + assigned_id = res.get("task_id", "TASK") + due_str = fn_args.get('due_date') or 'Без срока' + return ( + f"Задача {assigned_id} успешно создана!\n\n" + f"• Название: {fn_args.get('title')}\n" + f"• Приоритет: {fn_args.get('priority', 'MEDIUM')}\n" + f"• Срок: {due_str}\n" + f"• Модуль: {fn_args.get('module', 'general')}" + ) + + elif fn_name == "db_update_task_status": + res = database.db_update_task_status( + task_id=fn_args.get("task_id"), + status=fn_args.get("status"), + due_date=fn_args.get("due_date") + ) + if "error" in res: + return f"Ошибка обновления задачи: {res['error']}" + return f"Статус задачи {fn_args.get('task_id')} успешно обновлен!" + + elif fn_name == "db_delete_task": + res = database.db_delete_task(task_id=fn_args.get("task_id")) + if "error" in res: + return f"Ошибка удаления задачи: {res['error']}" + return f"Задача {fn_args.get('task_id')} успешно удалена из базы!" + + return f"Функция {fn_name} выполнена." +''' + +# 4. Данные для файла app/core/ollama_client.py +OLLAMA_CLIENT_PY = '''import json +import urllib.request +import urllib.error + +OLLAMA_URL = "http://192.168.11.3:11434/api/chat" +MODEL_NAME = "qwen2.5:14b" + +def send_ollama_request(messages: list, tools: list) -> dict: + """Отправляет HTTP-запрос к локальной модели Ollama.""" + payload = { + "model": MODEL_NAME, + "messages": messages, + "tools": tools, + "stream": False, + "options": { + "num_predict": 2048, + "num_ctx": 8192, + "temperature": 0.1 + } + } + + req = urllib.request.Request( + OLLAMA_URL, + data=json.dumps(payload).encode("utf-8"), + headers={"Content-Type": "application/json"} + ) + + try: + with urllib.request.urlopen(req) as response: + return json.loads(response.read().decode("utf-8")) + except urllib.error.URLError as e: + raise ConnectionError(f"Ошибка связи с Ollama ({OLLAMA_URL}): {e}") +''' + +# 5. Данные для файла app/orchestrator.py +ORCHESTRATOR_PY = '''import json +from typing import List, Dict, Any, Tuple +from datetime import datetime + +from app.db import database +from app.tools.definitions import TOOLS_SCHEMA +from app.tools.handlers import handle_tool_call +from app.core.ollama_client import send_ollama_request + +def process_chat_message(user_message: str, chat_history: List[Dict[str, Any]] = None) -> Tuple[str, List[Dict[str, Any]]]: + if chat_history is None: + chat_history = [] + + current_now = datetime.now().strftime("%Y-%m-%d %H:%M") + user_lower = user_message.lower().strip() + + # Быстрые жесткие перехваты + if any(phrase in user_lower for phrase in ["системный промпт", "покажи промпт", "промпт системы", "промпт из базы"]): + prompt_text = database.db_get_active_system_prompt() + formatted_text = f"⚙️ Актуальный системный промпт ИИ (из базы SQLite):\n\n{prompt_text}" + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + if any(phrase in user_lower for phrase in ["базу знаний", "база знаний", "покажи правила", "инструкции ии"]): + rules = database.db_get_rules() + if not rules: + formatted_text = "База знаний пуста." + else: + formatted_text = "🧠 База знаний ИИ (ai_knowledge_base):\n\n" + for r in rules: + formatted_text += f"{r.get('id')}. {r.get('rule_text')}\n\n" + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + # Загрузка актуального промпта + dynamic_prompt_text = database.db_get_active_system_prompt() + system_prompt = { + "role": "system", + "content": f"Текущая дата и время сервера: {current_now}.\n\n{dynamic_prompt_text}" + } + + messages = [system_prompt] + chat_history + [{"role": "user", "content": user_message}] + + try: + res_data = send_ollama_request(messages=messages, tools=TOOLS_SCHEMA) + msg = res_data.get("message", {}) + + tool_calls = msg.get("tool_calls", []) + content_str = msg.get("content", "").strip().replace("**", "") + + # Перехват текстового JSON с именем функции + if not tool_calls and "name" in content_str and "db_" in content_str: + try: + start_idx = content_str.find("{") + end_idx = content_str.rfind("}") + 1 + if start_idx != -1 and end_idx != -1: + parsed = json.loads(content_str[start_idx:end_idx]) + if "name" in parsed: + tool_calls = [{"function": parsed}] + except Exception: + pass + + if tool_calls: + for tool in tool_calls: + fn_name = tool["function"]["name"] + fn_args = tool["function"].get("arguments", {}) + + formatted_text = handle_tool_call(fn_name, fn_args) + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": formatted_text} + ] + return formatted_text, updated_history + + updated_history = chat_history + [ + {"role": "user", "content": user_message}, + {"role": "assistant", "content": content_str} + ] + return content_str, updated_history + + except Exception as e: + return f"Ошибка обработки запроса: {e}", chat_history +''' + +# 6. Обновленный главный модуль llm_agent.py +LLM_AGENT_PY = '''""" +SCUD Orion AI — Главная точка входа для общения с LLM-ассистентом. +Перенаправляет вызовы в центральный оркестратор app.orchestrator. +""" + +from app.orchestrator import process_chat_message + +__all__ = ["process_chat_message"] +''' + +def build_structure(): + files = { + os.path.join(BASE_DIR, "app", "__init__.py"): "", + os.path.join(BASE_DIR, "app", "db", "__init__.py"): "", + os.path.join(BASE_DIR, "app", "db", "database.py"): DB_PY, + os.path.join(BASE_DIR, "app", "tools", "__init__.py"): "", + os.path.join(BASE_DIR, "app", "tools", "definitions.py"): TOOLS_DEFINITIONS_PY, + os.path.join(BASE_DIR, "app", "tools", "handlers.py"): TOOLS_HANDLERS_PY, + os.path.join(BASE_DIR, "app", "core", "__init__.py"): "", + os.path.join(BASE_DIR, "app", "core", "ollama_client.py"): OLLAMA_CLIENT_PY, + os.path.join(BASE_DIR, "app", "orchestrator.py"): ORCHESTRATOR_PY, + os.path.join(BASE_DIR, "llm_agent.py"): LLM_AGENT_PY, + } + + print("🚀 Начинаем рефакторинг проекта...") + for filepath, content in files.items(): + os.makedirs(os.path.dirname(filepath), exist_ok=True) + with open(filepath, "w", encoding="utf-8") as f: + f.write(content.strip() + "\n") + print(f" [✓] Создан/обновлен: {filepath}") + + print("\n✅ Рефакторинг завершен успешно!") + +if __name__ == "__main__": + build_structure() \ No newline at end of file