Spaces:
Sleeping
Sleeping
IliaLarchenko
commited on
Commit
β’
d6cd6c2
1
Parent(s):
55d992f
Streaming interview feedback
Browse files- api/llm.py +87 -61
- app.py +2 -5
api/llm.py
CHANGED
@@ -13,21 +13,74 @@ class LLMManager:
|
|
13 |
self.is_demo = os.getenv("IS_DEMO")
|
14 |
self.demo_word_limit = os.getenv("DEMO_WORD_LIMIT")
|
15 |
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
try:
|
18 |
response = self.client.chat.completions.create(
|
19 |
model=self.config.llm.name,
|
20 |
-
messages=
|
21 |
-
|
22 |
-
|
23 |
-
{"role": "user", "content": "Ping!"},
|
24 |
-
],
|
25 |
)
|
26 |
-
if not response.choices:
|
27 |
-
raise APIError("LLM Test Connection Error", details="No choices in response")
|
28 |
-
return response.choices[0].message.content.strip()
|
29 |
except Exception as e:
|
30 |
-
raise APIError(f"LLM
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
def init_bot(self, problem=""):
|
33 |
system_prompt = self.prompts["coding_interviewer_prompt"]
|
@@ -50,20 +103,12 @@ class LLMManager:
|
|
50 |
if self.is_demo:
|
51 |
full_prompt += f" Keep your response very short and simple, no more than {self.demo_word_limit} words."
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
],
|
60 |
-
temperature=1.0,
|
61 |
-
)
|
62 |
-
if not response.choices:
|
63 |
-
raise APIError("LLM Problem Generation Error", details="No choices in response")
|
64 |
-
question = response.choices[0].message.content.strip()
|
65 |
-
except Exception as e:
|
66 |
-
raise APIError(f"LLM Problem Generation Error: Unexpected error: {e}")
|
67 |
|
68 |
chat_history = self.init_bot(question)
|
69 |
return question, chat_history
|
@@ -73,14 +118,7 @@ class LLMManager:
|
|
73 |
chat_history.append({"role": "user", "content": f"My latest code:\n{code}"})
|
74 |
chat_history.append({"role": "user", "content": message})
|
75 |
|
76 |
-
|
77 |
-
response = self.client.chat.completions.create(model=self.config.llm.name, messages=chat_history)
|
78 |
-
if not response.choices:
|
79 |
-
raise APIError("LLM Send Request Error", details="No choices in response")
|
80 |
-
reply = response.choices[0].message.content.strip()
|
81 |
-
except Exception as e:
|
82 |
-
raise APIError(f"LLM Send Request Error: Unexpected error: {e}")
|
83 |
-
|
84 |
chat_history.append({"role": "assistant", "content": reply})
|
85 |
|
86 |
if chat_display:
|
@@ -90,11 +128,8 @@ class LLMManager:
|
|
90 |
|
91 |
return chat_history, chat_display, "", code
|
92 |
|
93 |
-
|
94 |
-
|
95 |
-
if not chat_history or len(chat_history) <= 2:
|
96 |
-
yield "No interview content available to review."
|
97 |
-
|
98 |
transcript = [f"{message['role'].capitalize()}: {message['content']}" for message in chat_history[1:]]
|
99 |
|
100 |
system_prompt = self.prompts["grading_feedback_prompt"]
|
@@ -108,27 +143,18 @@ class LLMManager:
|
|
108 |
{"role": "user", "content": "Grade the interview based on the transcript provided and give feedback."},
|
109 |
]
|
110 |
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
yield feedback
|
127 |
-
# else:
|
128 |
-
# response = self.client.chat.completions.create(
|
129 |
-
# model=self.config.llm.name,
|
130 |
-
# messages=messages,
|
131 |
-
# temperature=0.5,
|
132 |
-
# )
|
133 |
-
# feedback = response.choices[0].message.content.strip()
|
134 |
-
# return feedback
|
|
|
13 |
self.is_demo = os.getenv("IS_DEMO")
|
14 |
self.demo_word_limit = os.getenv("DEMO_WORD_LIMIT")
|
15 |
|
16 |
+
self.status = self.test_llm()
|
17 |
+
if self.status:
|
18 |
+
self.streaming = self.test_llm_stream()
|
19 |
+
else:
|
20 |
+
self.streaming = False
|
21 |
+
|
22 |
+
if self.streaming:
|
23 |
+
self.end_interview = self.end_interview_stream
|
24 |
+
else:
|
25 |
+
self.end_interview = self.end_interview_full
|
26 |
+
|
27 |
+
def text_processor(self):
|
28 |
+
def ans_full(response):
|
29 |
+
return response
|
30 |
+
|
31 |
+
def ans_stream(response):
|
32 |
+
yield from response
|
33 |
+
|
34 |
+
if self.streaming:
|
35 |
+
return ans_full
|
36 |
+
else:
|
37 |
+
return ans_stream
|
38 |
+
|
39 |
+
def get_text(self, messages):
|
40 |
+
try:
|
41 |
+
response = self.client.chat.completions.create(model=self.config.llm.name, messages=messages, temperature=1)
|
42 |
+
if not response.choices:
|
43 |
+
raise APIError("LLM Get Text Error", details="No choices in response")
|
44 |
+
return response.choices[0].message.content.strip()
|
45 |
+
except Exception as e:
|
46 |
+
raise APIError(f"LLM Get Text Error: Unexpected error: {e}")
|
47 |
+
|
48 |
+
def get_text_stream(self, messages):
|
49 |
try:
|
50 |
response = self.client.chat.completions.create(
|
51 |
model=self.config.llm.name,
|
52 |
+
messages=messages,
|
53 |
+
temperature=1,
|
54 |
+
stream=True,
|
|
|
|
|
55 |
)
|
|
|
|
|
|
|
56 |
except Exception as e:
|
57 |
+
raise APIError(f"LLM End Interview Error: Unexpected error: {e}")
|
58 |
+
text = ""
|
59 |
+
for chunk in response:
|
60 |
+
if chunk.choices[0].delta.content:
|
61 |
+
text += chunk.choices[0].delta.content
|
62 |
+
yield text
|
63 |
+
|
64 |
+
test_messages = [
|
65 |
+
{"role": "system", "content": "You just help me test the connection."},
|
66 |
+
{"role": "user", "content": "Hi!"},
|
67 |
+
{"role": "user", "content": "Ping!"},
|
68 |
+
]
|
69 |
+
|
70 |
+
def test_llm(self):
|
71 |
+
try:
|
72 |
+
self.get_text(self.test_messages)
|
73 |
+
return True
|
74 |
+
except:
|
75 |
+
return False
|
76 |
+
|
77 |
+
def test_llm_stream(self):
|
78 |
+
try:
|
79 |
+
for _ in self.get_text_stream(self.test_messages):
|
80 |
+
pass
|
81 |
+
return True
|
82 |
+
except:
|
83 |
+
return False
|
84 |
|
85 |
def init_bot(self, problem=""):
|
86 |
system_prompt = self.prompts["coding_interviewer_prompt"]
|
|
|
103 |
if self.is_demo:
|
104 |
full_prompt += f" Keep your response very short and simple, no more than {self.demo_word_limit} words."
|
105 |
|
106 |
+
question = self.get_text(
|
107 |
+
[
|
108 |
+
{"role": "system", "content": self.prompts["problem_generation_prompt"]},
|
109 |
+
{"role": "user", "content": full_prompt},
|
110 |
+
]
|
111 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
chat_history = self.init_bot(question)
|
114 |
return question, chat_history
|
|
|
118 |
chat_history.append({"role": "user", "content": f"My latest code:\n{code}"})
|
119 |
chat_history.append({"role": "user", "content": message})
|
120 |
|
121 |
+
reply = self.get_text(chat_history)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
chat_history.append({"role": "assistant", "content": reply})
|
123 |
|
124 |
if chat_display:
|
|
|
128 |
|
129 |
return chat_history, chat_display, "", code
|
130 |
|
131 |
+
# TODO: implement both streaming and non-streaming versions
|
132 |
+
def end_interview_prepare_messages(self, problem_description, chat_history):
|
|
|
|
|
|
|
133 |
transcript = [f"{message['role'].capitalize()}: {message['content']}" for message in chat_history[1:]]
|
134 |
|
135 |
system_prompt = self.prompts["grading_feedback_prompt"]
|
|
|
143 |
{"role": "user", "content": "Grade the interview based on the transcript provided and give feedback."},
|
144 |
]
|
145 |
|
146 |
+
return messages
|
147 |
+
|
148 |
+
def end_interview_full(self, problem_description, chat_history):
|
149 |
+
if len(chat_history) <= 2:
|
150 |
+
return "No interview history available"
|
151 |
+
else:
|
152 |
+
messages = self.end_interview_prepare_messages(problem_description, chat_history)
|
153 |
+
return self.get_text_stream(messages)
|
154 |
+
|
155 |
+
def end_interview_stream(self, problem_description, chat_history):
|
156 |
+
if len(chat_history) <= 2:
|
157 |
+
yield "No interview history available"
|
158 |
+
else:
|
159 |
+
messages = self.end_interview_prepare_messages(problem_description, chat_history)
|
160 |
+
yield from self.get_text_stream(messages)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
CHANGED
@@ -78,11 +78,8 @@ with gr.Blocks(title="AI Interviewer") as demo:
|
|
78 |
except:
|
79 |
gr.Markdown(f"STT status: π΄{space} {config.stt.name}")
|
80 |
|
81 |
-
|
82 |
-
|
83 |
-
gr.Markdown(f"LLM status: π’{space} {config.llm.name}")
|
84 |
-
except:
|
85 |
-
gr.Markdown(f"LLM status: π΄{space} {config.llm.name}")
|
86 |
|
87 |
gr.Markdown(instruction["quick_start"])
|
88 |
with gr.Row():
|
|
|
78 |
except:
|
79 |
gr.Markdown(f"STT status: π΄{space} {config.stt.name}")
|
80 |
|
81 |
+
llm_status = get_status_color(llm)
|
82 |
+
gr.Markdown(f"LLM status: {llm_status}{space}{config.llm.name}")
|
|
|
|
|
|
|
83 |
|
84 |
gr.Markdown(instruction["quick_start"])
|
85 |
with gr.Row():
|