| 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 |
|
|