IliaLarchenko commited on
Commit
d6cd6c2
β€’
1 Parent(s): 55d992f

Streaming interview feedback

Browse files
Files changed (2) hide show
  1. api/llm.py +87 -61
  2. 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
- def test_connection(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  try:
18
  response = self.client.chat.completions.create(
19
  model=self.config.llm.name,
20
- messages=[
21
- {"role": "system", "content": "You just help me test the connection."},
22
- {"role": "user", "content": "Hi!"},
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 Test Connection Error: Unexpected error: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- try:
54
- response = self.client.chat.completions.create(
55
- model=self.config.llm.name,
56
- messages=[
57
- {"role": "system", "content": self.prompts["problem_generation_prompt"]},
58
- {"role": "user", "content": full_prompt},
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
- try:
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
- def end_interview(self, problem_description, chat_history):
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
- if os.getenv("STREAMING", False):
112
- try:
113
- response = self.client.chat.completions.create(
114
- model=self.config.llm.name,
115
- messages=messages,
116
- temperature=0.5,
117
- stream=True,
118
- )
119
- except Exception as e:
120
- raise APIError(f"LLM End Interview Error: Unexpected error: {e}")
121
-
122
- feedback = ""
123
- for chunk in response:
124
- if chunk.choices[0].delta.content:
125
- feedback += chunk.choices[0].delta.content
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
- try:
82
- llm.test_connection()
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():