QAway-to commited on
Commit
5cc7e19
·
1 Parent(s): a8db2c5

Revert "Updated structure v1.2"

Browse files

This reverts commit a8db2c594e26563c5f4494acc49ca2ed9e709210.

app.py CHANGED
@@ -1,37 +1,56 @@
 
1
  import gradio as gr
2
- from core.interviewer_phi3 import generate_question, categories
3
- from core.analyzer_mbti import classify_answer
4
-
5
- state = {"i": 0, "history": []}
6
-
7
- def next_step(user_answer):
8
- # Сохраняем ответ
9
- if user_answer.strip():
10
- state["history"].append(user_answer)
11
- else:
12
- return "⚠️ Please type your answer.", ""
13
-
14
- # Анализ MBTI
15
- traits = classify_answer(user_answer)
16
- traits_text = "\n".join([f"{t['label']} → {t['score']:.3f}" for t in traits])
17
-
18
- # Следующий вопрос
19
- if state["i"] < len(categories):
20
- cat = categories[state["i"]]
21
- q = generate_question(state["history"], cat)
22
- state["i"] += 1
23
- else:
24
- q = "✅ Interview finished. Personality summary calculated."
25
-
26
- return traits_text, q
27
-
28
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
29
- gr.Markdown("## 🧠 MBTI Interviewer (Phi-3)")
30
- inp = gr.Textbox(label="Answer", lines=3)
31
- btn = gr.Button("Next Question", variant="primary")
32
- out1 = gr.Textbox(label="📊 MBTI Analysis", lines=3)
33
- out2 = gr.Textbox(label="💬 Next Question", lines=3)
34
- btn.click(fn=next_step, inputs=inp, outputs=[out1, out2])
35
- demo.load(lambda: ("", generate_question([], categories[0])), outputs=out2)
36
-
37
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
  import gradio as gr
3
+ from core.utils import generate_first_question
4
+ from core.mbti_analyzer import analyze_mbti
5
+ from core.interviewer import generate_question
6
+
7
+ def analyze_and_ask(user_text, prev_count):
8
+ """Пошаговый генератор — стриминг без async и без streaming=True."""
9
+ if not user_text.strip():
10
+ yield "⚠️ Please enter your answer.", "", prev_count
11
+ return
12
+
13
+ try:
14
+ n = int(prev_count.split("/")[0]) + 1
15
+ except Exception:
16
+ n = 1
17
+ counter = f"{n}/30"
18
+
19
+ # 1️⃣ Шаг 1 — анализ
20
+ mbti_gen = analyze_mbti(user_text)
21
+ mbti_text = ""
22
+ for chunk in mbti_gen:
23
+ mbti_text = chunk
24
+ yield mbti_text, "💭 Interviewer is thinking...", counter
25
+
26
+ # 2️⃣ Шаг 2 — вопрос
27
+ interviewer_gen = generate_question("default_user", user_text)
28
+ next_q = ""
29
+ for chunk in interviewer_gen:
30
+ next_q = chunk
31
+ yield mbti_text, next_q, counter
32
+
33
+ # --------------------------------------------------------------
34
+ # Gradio интерфейс
35
+ # --------------------------------------------------------------
36
+ with gr.Blocks(theme=gr.themes.Soft(), title="MBTI Personality Interviewer") as demo:
37
+ gr.Markdown("## 🧠 MBTI Personality Interviewer\nОпредели личностный тип и получи следующий вопрос от интервьюера.")
38
+
39
+ with gr.Row():
40
+ with gr.Column(scale=1):
41
+ inp = gr.Textbox(
42
+ label="Ваш ответ",
43
+ placeholder="Например: I enjoy working with people and organizing events.",
44
+ lines=4
45
+ )
46
+ btn = gr.Button("Анализировать и задать новый вопрос", variant="primary")
47
+ with gr.Column(scale=1):
48
+ mbti_out = gr.Textbox(label="📊 Анализ MBTI", lines=4)
49
+ interviewer_out = gr.Textbox(label="💬 Следующий вопрос от интервьюера", lines=3)
50
+ progress = gr.Textbox(label="⏳ Прогресс", value="0/30")
51
+
52
+ btn.click(analyze_and_ask, inputs=[inp, progress], outputs=[mbti_out, interviewer_out, progress])
53
+
54
+ demo.load(lambda: ("", generate_first_question(), "0/30"), inputs=None, outputs=[mbti_out, interviewer_out, progress])
55
+
56
+ demo.queue(max_size=20).launch(server_name="0.0.0.0", server_port=7860)
core/analyzer_mbti.py DELETED
@@ -1,9 +0,0 @@
1
- from transformers import pipeline
2
-
3
- MBTI_MODEL = "f3nsmart/MBTIclassifier"
4
- classifier = pipeline("text-classification", model=MBTI_MODEL, return_all_scores=True)
5
-
6
- def classify_answer(answer: str):
7
- res = classifier(answer)[0]
8
- sorted_res = sorted(res, key=lambda x: x["score"], reverse=True)
9
- return sorted_res[:3] # top 3 traits
 
 
 
 
 
 
 
 
 
 
core/interviewer_phi3.py DELETED
@@ -1,34 +0,0 @@
1
- from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
2
- import random, json, os
3
-
4
- MODEL_NAME = "microsoft/Phi-3-mini-4k-instruct"
5
- tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
6
- model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, torch_dtype="auto", device_map="auto")
7
-
8
- generator = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=70, temperature=0.7, top_p=0.9)
9
-
10
- DATA_PATH = "data"
11
- categories = sorted([f.replace(".json", "") for f in os.listdir(DATA_PATH) if f.endswith(".json")])
12
-
13
- def load_category_sample(cat_name):
14
- path = os.path.join(DATA_PATH, f"{cat_name}.json")
15
- with open(path, "r", encoding="utf-8") as f:
16
- data = json.load(f)
17
- return random.choice(data).get("instruction", "")
18
-
19
- def generate_question(history, current_cat):
20
- """
21
- Сценарий генерации вопроса по текущей категории MBTI.
22
- """
23
- sample = load_category_sample(current_cat)
24
- hist_text = "\n".join([f"Q{i//2+1 if i%2==0 else ''}: {h}" for i, h in enumerate(history)])
25
- prompt = (
26
- f"You're generating interview questions for MBTI testing.\n"
27
- f"Previous dialogue:\n{hist_text}\n"
28
- f"Generate one new open-ended question related to {current_cat.replace('_', ' ')} "
29
- f"based on this example:\n'{sample}'\n"
30
- f"Do not repeat or rephrase previous ones. Output only the question text."
31
- )
32
- output = generator(prompt)[0]["generated_text"]
33
- q = output.split("\n")[-1].strip()
34
- return q
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
core/mbti_analyzer.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # core/mbti_analyzer.py
2
+ from transformers import pipeline
3
+ import asyncio
4
+
5
+ MBTI_MODEL = "f3nsmart/MBTIclassifier"
6
+ mbti_pipe = pipeline("text-classification", model=MBTI_MODEL, return_all_scores=True)
7
+
8
+ async def analyze_mbti_async(user_text: str):
9
+ """Асинхронный MBTI-анализ."""
10
+ loop = asyncio.get_event_loop()
11
+ return await loop.run_in_executor(None, lambda: mbti_pipe(user_text)[0])
12
+
13
+ def analyze_mbti(user_text: str):
14
+ """Генератор для стриминга результата."""
15
+ yield "⏳ Analyzing personality traits..."
16
+ res = asyncio.run(analyze_mbti_async(user_text))
17
+ res_sorted = sorted(res, key=lambda x: x["score"], reverse=True)
18
+ mbti_text = "\n".join([f"{r['label']} → {r['score']:.3f}" for r in res_sorted[:3]])
19
+ yield mbti_text