File size: 3,719 Bytes
b6185eb
e8b5e7a
 
0611243
5cc7e19
 
4c6f761
f12b1ae
 
 
 
 
7aec9f9
f12b1ae
 
 
0611243
f12b1ae
e8b5e7a
f12b1ae
 
4c6f761
 
5cc7e19
b6185eb
 
5cc7e19
 
 
 
 
206b8e2
5cc7e19
e8b5e7a
0611243
 
4c6f761
b6185eb
5cc7e19
b6185eb
 
bbd6808
b6185eb
4c6f761
bbd6808
4c6f761
 
 
 
bbd6808
4c6f761
7aec9f9
b6185eb
e8b5e7a
b6185eb
 
206b8e2
 
4c6f761
 
206b8e2
5cc7e19
 
 
b6185eb
 
 
4c6f761
b6185eb
 
5cc7e19
 
4c6f761
206b8e2
5cc7e19
206b8e2
 
 
4df42a0
4c6f761
206b8e2
5cc7e19
206b8e2
 
 
4c6f761
206b8e2
5cc7e19
f12b1ae
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
# app.py
import gradio as gr
import asyncio
from itertools import cycle
from core.utils import generate_first_question
from core.mbti_analyzer import analyze_mbti
from core.interviewer import stream_question  # ✅ теперь используем потоковую версию

# --------------------------------------------------------------
# 🌀 Асинхронная анимация "Thinking..."
# --------------------------------------------------------------
async def async_loader(update_fn, delay=0.15):
    frames = cycle(["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"])
    for frame in frames:
        update_fn(f"💭 Interviewer is thinking... {frame}")
        await asyncio.sleep(delay)

# --------------------------------------------------------------
# ⚙️ Основная логика
# --------------------------------------------------------------
def analyze_and_ask(user_text, prev_count):
    """Основная функция — анализирует ответ и генерирует следующий вопрос (потоково)."""

    if not user_text.strip():
        yield "⚠️ Please enter your answer.", "", prev_count
        return

    try:
        n = int(prev_count.split("/")[0]) + 1
    except Exception:
        n = 1
    counter = f"{n}/8"

    # мгновенный отклик
    yield "⏳ Analyzing personality...", "💭 Interviewer is thinking... ⠋", counter

    # анализ MBTI (также потоковый)
    mbti_gen = analyze_mbti(user_text)
    mbti_text = ""
    for chunk in mbti_gen:
        mbti_text = chunk
        yield mbti_text, "💭 Interviewer is thinking... ⠙", counter

    # генерация вопроса новой моделью (потоково)
    try:
        partial_question = ""
        for piece in stream_question():  # 👈 здесь идёт токен-за-токен поток
            partial_question = piece
            yield mbti_text, partial_question, counter
    except Exception as e:
        yield mbti_text, f"⚠️ Question generator error: {e}", counter

# --------------------------------------------------------------
# 🧱 Интерфейс Gradio
# --------------------------------------------------------------
with gr.Blocks(theme=gr.themes.Soft(), title="MBTI Personality Interviewer") as demo:
    gr.Markdown(
        "## 🧠 MBTI Personality Interviewer\n"
        "Определи личностный тип и получи вопросы из разных категорий MBTI.\n\n"
        "_Теперь с потоковой генерацией вопросов._"
    )

    with gr.Row():
        with gr.Column(scale=1):
            inp = gr.Textbox(
                label="Ваш ответ",
                placeholder="Например: I enjoy working with people and organizing events.",
                lines=4,
            )
            btn = gr.Button("Анализировать и задать новый вопрос", variant="primary")
        with gr.Column(scale=1):
            mbti_out = gr.Textbox(label="📊 Анализ MBTI", lines=4)
            interviewer_out = gr.Textbox(label="💬 Следующий вопрос (streaming)", lines=3)
            progress = gr.Textbox(label="⏳ Прогресс", value="0/8")

    btn.click(
        analyze_and_ask,
        inputs=[inp, progress],
        outputs=[mbti_out, interviewer_out, progress],
        show_progress=True,
    )

    demo.load(
        lambda: ("", generate_first_question(), "0/8"),
        inputs=None,
        outputs=[mbti_out, interviewer_out, progress],
    )

demo.queue(max_size=32).launch(server_name="0.0.0.0", server_port=7860)