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