текст из pdf распознается, все работает, добавлены все функции из файла работы с базой данных db_cli.py. Готовность к оптимизации интерфейса.

This commit is contained in:
2026-08-11 16:19:07 +03:00
parent 286355e4c0
commit a622fd98d2
13 changed files with 641 additions and 78 deletions
+110 -18
View File
@@ -2,12 +2,12 @@ import json
import urllib.request
import urllib.error
import logging
from typing import List, Dict, Any, Tuple
from datetime import datetime
from typing import List, Dict, Any, Tuple, Optional
from datetime import datetime, timedelta
from .db_tools import (
db_get_active_system_prompt,
db_add_system_prompt,
db_add_system_prompt,
db_get_tasks,
db_update_task_status,
db_delete_task,
@@ -15,7 +15,16 @@ from .db_tools import (
db_get_rules,
db_set_session_state,
db_get_session_state,
db_get_snapshots,
db_delete_snapshots,
db_clear_session_state,
db_get_current_server_time,
db_save_chat_message,
db_get_chat_history,
db_get_stats,
db_get_anomalies,
db_get_session_states,
db_get_reference,
get_db_connection
)
@@ -27,6 +36,11 @@ logger = logging.getLogger("SCUD_AGENT")
OLLAMA_URL = "http://192.168.11.3:11434/api/chat"
MODEL_NAME = "qwen2.5:14b"
DAYS_RU = [
"понедельник", "вторник", "среда", "четверг",
"пятница", "суббота", "воскресенье"
]
def clean_output(text: str) -> str:
if not text:
return text
@@ -37,26 +51,71 @@ def clean_output(text: str) -> str:
text = text[len(art):].lstrip(",.!?:; -")
return text.strip()
def process_chat_message(user_id: int, user_message: str, chat_history: List[Dict[str, Any]] = None, session_id: str = "web_session_main") -> Tuple[str, List[Dict[str, Any]]]:
if chat_history is None:
chat_history = []
def get_dynamic_calendar_context() -> str:
now = datetime.now()
current_wd = now.weekday()
lines = [
f"СЕГОДНЯ: {DAYS_RU[current_wd].upper()}, {now.strftime('%d.%m.%Y')} (время сервера: {now.strftime('%H:%M:%S')}).",
"\nСПРАВОЧНИК ДАТ ДЛЯ ОТВЕТОВ (БЕРИ ДАТЫ СТРОГО ОТСЮДА):",
f"• Сегодня: {now.strftime('%d.%m.%Y')} ({DAYS_RU[current_wd]})",
f"• Вчера: {(now - timedelta(days=1)).strftime('%d.%m.%Y')} ({DAYS_RU[(current_wd - 1) % 7]})",
f"• Позавчера: {(now - timedelta(days=2)).strftime('%d.%m.%Y')} ({DAYS_RU[(current_wd - 2) % 7]})",
"\nПрошедшие дни недели:"
]
for days_back in range(1, 8):
dt = now - timedelta(days=days_back)
day_name = DAYS_RU[dt.weekday()]
if days_back == 7:
label = f"Прошлый {day_name}" if dt.weekday() in [0, 1, 3, 6] else f"Прошлая {day_name}"
lines.append(f"• {label} (ровно неделю назад): {dt.strftime('%d.%m.%Y')}")
else:
label = f"Ближайший прошедший {day_name}" if dt.weekday() in [0, 1, 3, 6] else f"Ближайшая прошедшая {day_name}"
lines.append(f"• {label} / {day_name}: {dt.strftime('%d.%m.%Y')}")
return "\n".join(lines)
def process_chat_message(
user_id: int,
user_message: str,
file_context: str = "",
chat_history: List[Dict[str, Any]] = None,
session_id: str = "web_session_main"
) -> Tuple[str, List[Dict[str, Any]]]:
logger.info(f"Получено сообщение от user_id={user_id}, session_id={session_id}: {user_message}")
current_now = datetime.now().strftime("%Y-%m-%d %H:%M")
# Формируем итоговое содержимое запроса
full_user_content = user_message
if file_context:
full_user_content = f"{user_message}\n\n[СОДЕРЖИМОЕ ПРИКРЕПЛЕННОГО ФАЙЛА]:\n{file_context}"
db_history = db_get_chat_history(session_id, limit=20)
db_save_chat_message(session_id, "user", full_user_content)
dynamic_prompt_text = db_get_active_system_prompt()
calendar_context = get_dynamic_calendar_context()
session_state = db_get_session_state(session_id)
preview_status_note = ""
if session_state and session_state["state_type"] == "PROMPT_PREVIEW":
if session_state and session_state.get("state_type") == "PROMPT_PREVIEW":
preview_status_note = "\n\n[АКТИВНО ПРЕВЬЮ ПРОМПТА: Ожидается подтверждение или отмена изменений пользователем]."
system_prompt_content = (
f"[СИСТЕМНЫЙ КАЛЕНДАРЬ СЕРВЕРА]\n"
f"{calendar_context}\n\n"
f"ПРАВИЛО РАБОТЫ С ДАТАМИ:\n"
f"При любых вопросах про дни недели ('прошлая среда', 'вторник', 'дата в прошлый понедельник') бери ГОТОВУЮ точную дату из справочника выше. Тебе ЗАПРЕЩЕНО вычислять даты самостоятельно!\n\n"
f"ТЕКУЩИЙ АКТИВНЫЙ СИСТЕМНЫЙ ПРОМПТ:\n{dynamic_prompt_text}{preview_status_note}"
)
system_prompt = {
"role": "system",
"content": f"Текущая дата и время сервера: {current_now}.\n\nТЕКУЩИЙ АКТИВНЫЙ СИСТЕМНЫЙ ПРОМПТ:\n{dynamic_prompt_text}{preview_status_note}"
"content": system_prompt_content
}
messages = [system_prompt] + chat_history + [{"role": "user", "content": user_message}]
messages = [system_prompt] + db_history + [{"role": "user", "content": full_user_content}]
payload = {
"model": MODEL_NAME,
@@ -87,7 +146,16 @@ def process_chat_message(user_id: int, user_message: str, chat_history: List[Dic
logger.info(f"Вызов функции (Tool): {fn_name} с аргументами: {fn_args}")
tool_result_content = ""
if fn_name == "db_get_tasks":
if fn_name == "db_get_snapshots":
date_arg = fn_args.get("date_str")
snapshots_res = db_get_snapshots(session_id=session_id, date_str=date_arg, original_user_message=user_message)
tool_result_content = json.dumps(snapshots_res, ensure_ascii=False)
elif fn_name == "db_get_current_server_time":
time_res = db_get_current_server_time()
tool_result_content = json.dumps(time_res, ensure_ascii=False)
elif fn_name == "db_get_tasks":
tasks = db_get_tasks(user_id)
tool_result_content = json.dumps(tasks, ensure_ascii=False)
@@ -95,19 +163,39 @@ def process_chat_message(user_id: int, user_message: str, chat_history: List[Dic
prompt_content = db_get_active_system_prompt()
tool_result_content = json.dumps({"system_prompt": prompt_content}, ensure_ascii=False)
elif fn_name == "db_get_stats":
tool_result_content = json.dumps(db_get_stats(), ensure_ascii=False)
elif fn_name == "db_get_anomalies":
limit_arg = fn_args.get("limit", 100)
date_arg = fn_args.get("date_str")
tool_result_content = json.dumps(db_get_anomalies(limit=limit_arg, date_str=date_arg), ensure_ascii=False)
elif fn_name == "db_get_session_states":
tool_result_content = json.dumps(db_get_session_states(), ensure_ascii=False)
elif fn_name == "db_delete_snapshots":
snap_id = fn_args.get("snapshot_id")
day_arg = fn_args.get("day_str")
tool_result_content = json.dumps(db_delete_snapshots(snapshot_id=snap_id, day_str=day_arg), ensure_ascii=False)
elif fn_name == "db_get_reference":
cat_arg = fn_args.get("category")
tool_result_content = json.dumps(db_get_reference(category=cat_arg), ensure_ascii=False)
elif fn_name == "db_preview_prompt_merge":
proposed_text = fn_args.get("proposed_prompt", "")
if proposed_text:
# Фиксируем превью в сессии и сразу возвращаем текст пользователю на экран
db_set_session_state(session_id, "PROMPT_PREVIEW", proposed_text)
preview_reply = f"Ваше изменение успешно предпросмотрено. Полный обновленный системный промпт теперь выглядит так:\n\n{proposed_text}\n\nДля применения изменений подтвердите действие («подтверждаю») или отмените («отмена»)."
return preview_reply, chat_history + [{"role": "user", "content": user_message}, {"role": "assistant", "content": preview_reply}]
db_save_chat_message(session_id, "assistant", preview_reply)
return preview_reply, db_get_chat_history(session_id)
else:
tool_result_content = json.dumps({"status": "error", "message": "Текст превью пуст."}, ensure_ascii=False)
elif fn_name == "db_confirm_prompt_preview":
if session_state and session_state["state_type"] == "PROMPT_PREVIEW":
pending_text = session_state["pending_data"]
if session_state and session_state.get("state_type") == "PROMPT_PREVIEW":
pending_text = session_state.get("pending_data", "")
res = db_add_system_prompt("main_agent", pending_text)
db_clear_session_state(session_id)
tool_result_content = json.dumps(res, ensure_ascii=False)
@@ -162,11 +250,15 @@ def process_chat_message(user_id: int, user_message: str, chat_history: List[Dic
with urllib.request.urlopen(sec_req) as sec_response:
sec_res_data = json.loads(sec_response.read().decode("utf-8"))
final_content = clean_output(sec_res_data.get("message", {}).get("content", "").strip().replace("**", ""))
return final_content, chat_history + [{"role": "user", "content": user_message}, {"role": "assistant", "content": final_content}]
db_save_chat_message(session_id, "assistant", final_content)
return final_content, db_get_chat_history(session_id)
content_str = clean_output(msg.get("content", "").strip().replace("**", ""))
return content_str or "Запрос обработан.", chat_history + [{"role": "user", "content": user_message}, {"role": "assistant", "content": content_str}]
final_reply = content_str or "Запрос обработан."
db_save_chat_message(session_id, "assistant", final_reply)
return final_reply, db_get_chat_history(session_id)
except Exception as ex:
logger.exception(f"Непредвиденная ошибка: {ex}")
return f"Внутренняя ошибка сервера: {ex}", chat_history
error_reply = f"Внутренняя ошибка сервера: {ex}"
return error_reply, db_get_chat_history(session_id)