Spaces:
Running
Running
import os | |
import gradio as gr | |
from db import db | |
from rag import process_query | |
from llm import LLM | |
from prompts import default_system_promot | |
import re | |
def init_db(): | |
with open("sources.txt", encoding="utf-8") as f: | |
urls = f.read().splitlines() | |
db.add(urls) | |
def get_llm(model): | |
return LLM(model) | |
def extract_json_and_clean_text(text): | |
# print(text) | |
# Регулярное выражение для поиска содержимого между <json> и </json> | |
pattern = r"(```json.*?```)" | |
# Ищем совпадения (re.DOTALL позволяет захватывать многострочные данные) | |
match = re.search(pattern, text, re.DOTALL) | |
if match: | |
# Извлекаем найденный JSON как строку | |
json_string = match.group(1).strip() | |
# Удаляем JSON блок из исходного текста | |
cleaned_text = re.sub(pattern, "", text, flags=re.DOTALL).strip() | |
return cleaned_text, json_string | |
else: | |
print("JSON блок не найден в тексте.") | |
return text.strip(), "" | |
# Высота столбцов (в пикселях) | |
COLUMN_HEIGHT = 280 | |
NUM_LINES = 12 | |
def tab1(): | |
with gr.Tab("Анализ пресейлов"): | |
# Создаем два столбца: левый для загрузки файлов, правый для системного промпта | |
with gr.Row(): | |
with gr.Column(scale=1): # Левый столбец | |
file_input = gr.File( | |
label="Прикрепите рассматриваемый запрос", | |
) | |
with gr.Column(scale=2): # Правый столбец | |
system_prompt_input = gr.Textbox( | |
label="Системный промпт", | |
placeholder="Введите системный промпт...", | |
lines=NUM_LINES, # Количество строк зависит от доступной высоты | |
max_lines=NUM_LINES, | |
interactive=True, | |
value=default_system_promot | |
) | |
with gr.Row(): | |
model = gr.Dropdown( | |
choices=["mistral", "qwen2.5-vl-72b-instruct", "deepseek_v3", "llama-3.3-70b"], # Список строк для выбора | |
label="Выберите модель", # Подпись к выпадающему списку | |
multiselect=False # Если True, можно выбрать несколько значений | |
) | |
temperature = gr.Slider( | |
minimum=0, | |
maximum=1, | |
step=0.01, | |
label="Температура", | |
value=0, | |
info="Увеличение гибридного поиска повышает креативность модели" | |
) | |
alpha = gr.Slider( | |
minimum=0, | |
maximum=1, | |
step=0.01, | |
label="Альфа", | |
value=0.5, | |
info="Регулировка гибридного поиска" | |
) | |
# Кнопка "Отправить" | |
send_button = gr.Button("Отправить") | |
# Текстовое поле для отображения результата | |
# result_output = gr.Textbox(label="Результат", lines=5, interactive=False) | |
# with gr.Accordion('Результат:', open=True): | |
# result_output = gr.Markdown(value="Здесь будет представлен результат") | |
# Группа с лейблом и рамкой | |
with gr.Row(): | |
with gr.Column(elem_classes="markdown-group", scale=2): | |
gr.HTML("<div class='markdown-label'>Результат:</div>") # Лейбл внутри рамки | |
with gr.Column(elem_classes="markdown-content"): | |
result_output = gr.Markdown(value="Здесь будет представлен результат", min_height=200, show_copy_button=True) | |
with gr.Column(elem_classes="markdown-group", scale=1): | |
gr.HTML("<div class='markdown-label'>Json результат:</div>") # Лейбл внутри рамки | |
with gr.Column(elem_classes="markdown-content"): | |
json_output = gr.Markdown(value="Здесь будет представлен json", min_height=200, show_copy_button=True) | |
def respond(file, system_prompt, model, temperature, alpha): | |
llm = get_llm(model) | |
llm_response = process_query(file, system_prompt, llm, temperature, alpha) | |
return extract_json_and_clean_text(llm_response) | |
# Привязываем кнопку к функции обработки | |
send_button.click( | |
respond, | |
inputs=[file_input, system_prompt_input, model, temperature, alpha], | |
outputs=[result_output, json_output] | |
) | |
def add_new_source(): | |
new_url = gr.Textbox( | |
label="url нового источника", | |
placeholder="Введите url нового источника...", | |
lines=1, | |
max_lines=1, | |
interactive=True, | |
info="Поддерживается парсинг только с сайта https://www.reksoft.ru" | |
) | |
add_button = gr.Button("Добавить") | |
def add_source(url): | |
if url.startswith("https://www.reksoft.ru"): | |
db.add([url]) | |
gr.Success(f"{url} успешно добавлен") | |
else: | |
gr.Error("Ошибка: представленная ссылка не принадлежит https://www.reksoft.ru") | |
return url | |
add_button.click( | |
add_source, | |
inputs=new_url, | |
outputs=new_url | |
) | |
def get_sources(): | |
ids = db.get_ids() | |
str_ids = "" | |
for source in ids: | |
str_ids += f'* {source}\n' | |
return f"""\ | |
# Источники | |
{str_ids}""" | |
def tab2(): | |
with gr.Tab("Источники") as dynamic_tab: | |
add_new_source() | |
markdown_output = gr.Markdown("Изначальное содержимое Markdown") | |
dynamic_tab.select(get_sources, outputs=markdown_output) | |
# Функция для чтения содержимого файла и возврата его как строки | |
def read_file_content(file_path): | |
try: | |
with open(file_path, 'r', encoding='utf-8') as file: | |
content = file.read() | |
return content | |
except FileNotFoundError: | |
return "Файл не найден." | |
except Exception as e: | |
return f"Произошла ошибка: {str(e)}" | |
def tab3(): | |
with gr.Tab("Инфо"): | |
gr.Markdown(read_file_content('info.md')) | |
gr.Image("architecture.png") | |
gr.Markdown(read_file_content('team.md')) | |
css = """ | |
.markdown-group { | |
border: 1px solid #e0e0e0 !important; | |
border-radius: 4px !important; | |
margin: 16px 0 !important; | |
position: relative !important; | |
padding-top: 14px !important; # Место для лейбла | |
} | |
.markdown-label { | |
position: absolute !important; | |
top: 0px !important; | |
left: 8px !important; | |
background: white !important; | |
padding: 0 4px !important; | |
font-size: 14px !important; | |
color: #6b6b6b !important; | |
font-weight: 500 !important; | |
} | |
.markdown-content { | |
padding: 12px !important; | |
background: #f9f9f9 !important; | |
}""" | |
# Интерфейс Gradio | |
with gr.Blocks(css=css) as demo: | |
gr.Markdown("# Анализ тендерных заявок") | |
with gr.Tabs(): | |
tab1() | |
tab2() | |
tab3() | |
init_db() | |
# Запуск приложения | |
demo.launch() |