| import gradio as gr | |
| from app.services.knowledge_service import KnowledgeService | |
| from app.messenger.chat_engine import ChatEngine | |
| from app.messenger.feedback_handler import save_feedback, send_feedback_to_telegram | |
| kb = KnowledgeService() | |
| chat = ChatEngine() | |
| def kb_add(pdf_file): | |
| if pdf_file is None: | |
| return "Загрузите PDF." | |
| return kb.add_pdf(pdf_file) | |
| def kb_list(): | |
| return kb.list_docs() | |
| def kb_search(query, top_k): | |
| hits = kb.search(query, top_k=int(top_k)) | |
| if not hits: | |
| return "Ничего не найдено." | |
| out = [] | |
| for h in hits: | |
| out.append(f"### {h['title']} (score={h['score']})\n{h['snippet']}\n") | |
| return "\n\n".join(out) | |
| def messenger_ask(history, user_text, top_k): | |
| context = kb.build_context(user_text, top_k=int(top_k)) | |
| answer = chat.answer(user_text, context=context) | |
| history = history + [(user_text, answer)] | |
| return history, "" | |
| def messenger_quick(btn, history): | |
| presets = { | |
| "📌 Спросить про документ": "Что в базе знаний сказано про требования к карманам/фурнитуре/посадке?", | |
| "🧩 Предложить улучшение": "Предложи 5 улучшений процесса, опираясь на базу знаний и лучшие практики.", | |
| "🧾 Сформулировать вопрос": "Сформулируй уточняющий вопрос для дизайнера, чтобы убрать двусмысленность." | |
| } | |
| return history, presets.get(btn, "") | |
| def feedback_submit(author, channel, topic, rating, message, also_telegram): | |
| if not message or len(message.strip()) < 5: | |
| return "⚠️ Сообщение слишком короткое." | |
| saved = save_feedback(author, channel, topic, rating, message) | |
| if also_telegram: | |
| tg = send_feedback_to_telegram(author, channel, topic, rating, message) | |
| return saved + "\n" + tg | |
| return saved | |
| def build_demo(): | |
| with gr.Blocks(title="2MOOD Feedback Knowledge Base (Pilot)") as demo: | |
| gr.Markdown("# 2MOOD Feedback Knowledge Base (Pilot)\nПилот: база знаний (PDF) + сбор обратной связи + messenger.") | |
| with gr.Tabs(): | |
| with gr.Tab("📚 База знаний"): | |
| with gr.Row(): | |
| pdf = gr.File(label="Загрузить PDF", file_types=[".pdf"]) | |
| add_btn = gr.Button("➕ Добавить в базу") | |
| add_out = gr.Textbox(label="Статус загрузки", lines=2) | |
| with gr.Row(): | |
| list_btn = gr.Button("📄 Список документов") | |
| docs_out = gr.Markdown() | |
| gr.Markdown("---") | |
| query = gr.Textbox(label="Поиск по базе", placeholder="например: 'параметры кармана' / 'правки по изделию'") | |
| top_k = gr.Slider(1, 10, value=5, step=1, label="Top-K") | |
| search_btn = gr.Button("🔎 Найти") | |
| search_out = gr.Markdown() | |
| add_btn.click(fn=kb_add, inputs=[pdf], outputs=[add_out]) | |
| list_btn.click(fn=kb_list, inputs=[], outputs=[docs_out]) | |
| search_btn.click(fn=kb_search, inputs=[query, top_k], outputs=[search_out]) | |
| with gr.Tab("💬 2MOOD Messenger"): | |
| gr.Markdown("Чат-виджет: отвечает с опорой на базу знаний (RAG).") | |
| history = gr.Chatbot(label="Диалог", height=380) | |
| user_text = gr.Textbox(label="Сообщение", placeholder="Напишите вопрос…") | |
| with gr.Row(): | |
| ask_btn = gr.Button("Отправить") | |
| k = gr.Slider(1, 8, value=4, step=1, label="Top-K контекста") | |
| with gr.Row(): | |
| b1 = gr.Button("📌 Спросить про документ") | |
| b2 = gr.Button("🧩 Предложить улучшение") | |
| b3 = gr.Button("🧾 Сформулировать вопрос") | |
| ask_btn.click(fn=messenger_ask, inputs=[history, user_text, k], outputs=[history, user_text]) | |
| b1.click(fn=messenger_quick, inputs=[b1, history], outputs=[history, user_text]) | |
| b2.click(fn=messenger_quick, inputs=[b2, history], outputs=[history, user_text]) | |
| b3.click(fn=messenger_quick, inputs=[b3, history], outputs=[history, user_text]) | |
| with gr.Tab("📝 Обратная связь"): | |
| gr.Markdown("Форма обратной связи: сохраняем в SQLite + опционально отправляем в Telegram.") | |
| author = gr.Textbox(label="Автор", value="2MOOD User") | |
| channel = gr.Dropdown(["Web Form", "Interview", "Telegram", "Email"], value="Web Form", label="Канал") | |
| topic = gr.Dropdown(["KB", "Messenger", "Protocols", "UX", "Bug", "Feature"], value="KB", label="Тема") | |
| rating = gr.Slider(1, 5, value=5, step=1, label="Оценка (1–5)") | |
| message = gr.Textbox(label="Сообщение", lines=6, placeholder="Что улучшить? Что мешает? Что понравилось?") | |
| also_tg = gr.Checkbox(label="Отправить копию в Telegram", value=True) | |
| submit = gr.Button("✅ Отправить") | |
| fb_out = gr.Textbox(label="Статус", lines=3) | |
| submit.click(fn=feedback_submit, inputs=[author, channel, topic, rating, message, also_tg], outputs=[fb_out]) | |
| return demo | |