File size: 3,920 Bytes
c6c602e 9700948 c6c602e 9700948 c6c602e 9700948 f34d9e8 9700948 f34d9e8 c6c602e f34d9e8 9700948 c6c602e 9700948 c6c602e 9700948 c6c602e 9700948 c6c602e 9700948 c6c602e 9700948 c6c602e 9700948 c6c602e 9700948 1080c74 c23e8fc 1080c74 c23e8fc 7e12323 c23e8fc 1080c74 c23e8fc 7e12323 1080c74 c23e8fc 1080c74 c23e8fc 1080c74 c23e8fc 1080c74 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | import json
import os
import re
import pypdf
from duckduckgo_search import DDGS
def get_clean_text(content):
"""Извлекает чистый текст из любого формата (str, dict, list)."""
if content is None:
return ""
if isinstance(content, str):
return content
if isinstance(content, dict):
return content.get("text", "")
if isinstance(content, list):
return "".join(
[
item if isinstance(item, str) else item.get("text", "")
for item in content
]
)
return str(content)
def extract_text_from_file(file_path):
"""Читает текст из загруженного файла."""
if not file_path or not os.path.exists(file_path):
return ""
ext = os.path.splitext(file_path)[1].lower()
try:
if ext == ".pdf":
text = ""
with open(file_path, "rb") as f:
reader = pypdf.PdfReader(f)
for page in reader.pages:
text += (page.extract_text() or "") + "\n"
return text
else:
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
return f.read()
except Exception as e:
return f"[Ошибка чтения файла: {e}]"
def web_search(query: str, max_results: int = 3) -> list:
"""Выполняет поиск в интернете через DuckDuckGo и возвращает список словарей."""
try:
with DDGS() as ddgs:
results = list(ddgs.text(query, max_results=max_results))
if not results:
return []
formatted_results = []
for r in results:
formatted_results.append(
{
"title": r.get("title", ""),
"url": r.get("href", ""),
"snippet": r.get("body", ""),
}
)
return formatted_results
except Exception as e:
print(f"Ошибка DDGS: {e}")
return []
def extract_search_query(text: str):
"""Супер-надежный парсер запроса (с поддержкой XML, JSON и логов)."""
if not text:
return None
# ВЫВОДИМ В КОНСОЛЬ ТО, ЧТО РЕАЛЬНО ПОДУМАЛ РОУТЕР
print(f"\n--- [DEBUG] RAW ROUTER OUTPUT ---\n{text}\n---------------------------\n")
# 1. Очищаем от размышлений
clean = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL).strip()
if not clean:
clean = text
# 2. Ищем XML-тег (наш новый основной метод)
xml_match = re.search(r"<search>(.*?)</search>", clean, re.IGNORECASE)
if xml_match:
return xml_match.group(1).strip()
# 3. Резерв на случай JSON
json_match = re.search(r"\{.*?\}", clean, re.DOTALL)
if json_match:
try:
data = json.loads(json_match.group(0))
if data.get("search") is True or str(data.get("search")).lower() == "true":
return data.get("query")
except:
pass
# 4. Резерв на случай "старых галлюцинаций" с массивами
if "search" in text.lower():
match = re.search(
r"(?:запрос|query|text)['\"]\s*:\s*['\"]([^'\"]+)['\"]", text, re.IGNORECASE
)
if match:
val = match.group(1)
val = re.sub(
r"^(?:🔍\s*)?(?:Поиск(?:\s*по\s*запросу)?|Search):\s*",
"",
val,
flags=re.IGNORECASE,
).strip()
if val and val.lower() not in ["no", "false", "none", "no_search"]:
return val
return None
|