likithyadavv commited on
Commit
08c48b7
Β·
verified Β·
1 Parent(s): 57c4324

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -20
app.py CHANGED
@@ -59,6 +59,8 @@ def has_code(text):
59
  # ── Detect student signal ────────────────────────────────────
60
  def detect_student_signal(text):
61
  text_lower = text.lower()
 
 
62
  if any(k in text_lower for k in ["hint", "help", "don't know", "idk", "no idea", "i give up", "tell me", "just give"]):
63
  return "hint_request"
64
  if any(k in text_lower for k in ["i think", "maybe", "is it", "could it be", "how about", "like this", "would it"]):
@@ -69,24 +71,29 @@ def detect_student_signal(text):
69
  return "submitted_code"
70
  return "general"
71
 
 
 
 
 
 
 
 
 
 
 
 
72
  # ── Build adaptive prompt ────────────────────────────────────
73
  def build_prompt(user_message, history, language):
74
  signal = detect_student_signal(user_message)
75
 
76
- # history: list of gr.ChatMessage objects with .role and .content
77
  history_text = ""
78
  if history:
79
  pairs = []
80
  i = 0
81
  while i < len(history) - 1:
82
  a, b = history[i], history[i + 1]
83
- # Support both ChatMessage objects and plain dicts
84
- a_role = a.role if hasattr(a, "role") else a.get("role", "")
85
- a_content = a.content if hasattr(a, "content") else a.get("content", "")
86
- b_role = b.role if hasattr(b, "role") else b.get("role", "")
87
- b_content = b.content if hasattr(b, "content") else b.get("content", "")
88
- if a_role == "user" and b_role == "assistant":
89
- pairs.append((a_content, b_content))
90
  i += 2
91
  else:
92
  i += 1
@@ -96,6 +103,7 @@ def build_prompt(user_message, history, language):
96
  context = f"Previous conversation:\n{history_text}" if history_text else ""
97
 
98
  styles = {
 
99
  "hint_request": "The student is asking for a hint.\n- Give ONE small hint only β€” not the answer\n- Point them in the right direction with a question\n- Do NOT write complete code",
100
  "submitted_code": "The student has written code.\n- First check if the logic is correct or not\n- If CORRECT: validate genuinely then push forward with a question\n- If WRONG: identify the specific issue, give a targeted hint\n- If copy-pasted (too perfect): ask them to walk you through it\n- Never rewrite their code for them",
101
  "attempting": "The student is guessing or attempting an explanation.\n- If CORRECT: confirm clearly and move to the next concept\n- If WRONG: gently correct their thinking with a question\n- Always build on what they said",
@@ -113,13 +121,31 @@ Detected language: {language}
113
  {style}
114
 
115
  {context}### Instruction:
116
- Student question or code
117
 
118
  ### Input:
119
  {user_message}
120
 
121
  ### Response:
122
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
  # ── Generate response ────────────────────────────────────────
125
  def generate(prompt):
@@ -133,9 +159,10 @@ def generate(prompt):
133
  temperature=0.7,
134
  top_p=0.9,
135
  repetition_penalty=1.2,
 
136
  )
137
  full = tokenizer.decode(outputs[0], skip_special_tokens=True)
138
- return full.split("### Response:")[-1].strip()
139
 
140
  # ── Log conversations ────────────────────────────────────────
141
  def log_conversation(user_msg, bot_msg, language):
@@ -147,11 +174,9 @@ def log_conversation(user_msg, bot_msg, language):
147
  def chat(user_message, history):
148
  language = detect_language(user_message)
149
  if language == "General" and history:
150
- for msg in history:
151
- content = msg.content if hasattr(msg, "content") else msg.get("content", "")
152
- role = msg.role if hasattr(msg, "role") else msg.get("role", "")
153
- if role == "user":
154
- detected = detect_language(content)
155
  if detected != "General":
156
  language = detected
157
  break
@@ -165,7 +190,6 @@ with gr.Blocks(title="CodeMentor AI") as demo:
165
  gr.Markdown("# πŸŽ“ CodeMentor β€” AI Programming Tutor")
166
  gr.Markdown("*Ask any programming question. I'll guide you β€” not give you the answer!*")
167
 
168
- # No type= param β€” use gr.ChatMessage objects for compatibility
169
  chatbot = gr.Chatbot(height=450)
170
 
171
  lang_display = gr.Textbox(label="Detected Language", interactive=False, value="🌐 General")
@@ -180,9 +204,9 @@ with gr.Blocks(title="CodeMentor AI") as demo:
180
  if not message.strip():
181
  return "", chat_history, lang_display.value
182
  response, language = chat(message, chat_history)
183
- # gr.ChatMessage is the cross-version compatible way to append messages
184
- chat_history.append(gr.ChatMessage(role="user", content=message))
185
- chat_history.append(gr.ChatMessage(role="assistant", content=response))
186
  return "", chat_history, f"🌐 {language}"
187
 
188
  send.click(respond, [msg, chatbot], [msg, chatbot, lang_display])
 
59
  # ── Detect student signal ────────────────────────────────────
60
  def detect_student_signal(text):
61
  text_lower = text.lower()
62
+ if any(k in text_lower for k in ["hello", "hi", "hey", "good morning", "good evening", "howdy"]):
63
+ return "greeting"
64
  if any(k in text_lower for k in ["hint", "help", "don't know", "idk", "no idea", "i give up", "tell me", "just give"]):
65
  return "hint_request"
66
  if any(k in text_lower for k in ["i think", "maybe", "is it", "could it be", "how about", "like this", "would it"]):
 
71
  return "submitted_code"
72
  return "general"
73
 
74
+ # ── Extract content from a history message (dict or ChatMessage) ──
75
+ def msg_role(m):
76
+ return m["role"] if isinstance(m, dict) else m.role
77
+
78
+ def msg_content(m):
79
+ c = m["content"] if isinstance(m, dict) else m.content
80
+ # If content is itself a dict (ChatMessage serialization artifact), unwrap it
81
+ if isinstance(c, dict):
82
+ return c.get("text", c.get("content", str(c)))
83
+ return str(c)
84
+
85
  # ── Build adaptive prompt ────────────────────────────────────
86
  def build_prompt(user_message, history, language):
87
  signal = detect_student_signal(user_message)
88
 
 
89
  history_text = ""
90
  if history:
91
  pairs = []
92
  i = 0
93
  while i < len(history) - 1:
94
  a, b = history[i], history[i + 1]
95
+ if msg_role(a) == "user" and msg_role(b) == "assistant":
96
+ pairs.append((msg_content(a), msg_content(b)))
 
 
 
 
 
97
  i += 2
98
  else:
99
  i += 1
 
103
  context = f"Previous conversation:\n{history_text}" if history_text else ""
104
 
105
  styles = {
106
+ "greeting": "The student just said hello.\n- Greet them briefly and warmly (1 sentence max)\n- Ask what programming topic or problem they want to work on today\n- Do NOT give any code or explanations yet",
107
  "hint_request": "The student is asking for a hint.\n- Give ONE small hint only β€” not the answer\n- Point them in the right direction with a question\n- Do NOT write complete code",
108
  "submitted_code": "The student has written code.\n- First check if the logic is correct or not\n- If CORRECT: validate genuinely then push forward with a question\n- If WRONG: identify the specific issue, give a targeted hint\n- If copy-pasted (too perfect): ask them to walk you through it\n- Never rewrite their code for them",
109
  "attempting": "The student is guessing or attempting an explanation.\n- If CORRECT: confirm clearly and move to the next concept\n- If WRONG: gently correct their thinking with a question\n- Always build on what they said",
 
121
  {style}
122
 
123
  {context}### Instruction:
124
+ Respond to the student's message below.
125
 
126
  ### Input:
127
  {user_message}
128
 
129
  ### Response:
130
+ CodeMentor:"""
131
+
132
+ # ── Extract clean response ───────────────────────────────────
133
+ def extract_response(full_text):
134
+ if "### Response:" in full_text:
135
+ after = full_text.split("### Response:")[-1]
136
+ else:
137
+ after = full_text
138
+
139
+ if after.lstrip().startswith("CodeMentor:"):
140
+ after = after.lstrip()[len("CodeMentor:"):].strip()
141
+ else:
142
+ after = after.strip()
143
+
144
+ for stop in ["### Input:", "### Instruction:", "Student:", "\n###"]:
145
+ if stop in after:
146
+ after = after.split(stop)[0]
147
+
148
+ return after.strip()
149
 
150
  # ── Generate response ────────────────────────────────────────
151
  def generate(prompt):
 
159
  temperature=0.7,
160
  top_p=0.9,
161
  repetition_penalty=1.2,
162
+ pad_token_id=tokenizer.eos_token_id,
163
  )
164
  full = tokenizer.decode(outputs[0], skip_special_tokens=True)
165
+ return extract_response(full)
166
 
167
  # ── Log conversations ────────────────────────────────────────
168
  def log_conversation(user_msg, bot_msg, language):
 
174
  def chat(user_message, history):
175
  language = detect_language(user_message)
176
  if language == "General" and history:
177
+ for m in history:
178
+ if msg_role(m) == "user":
179
+ detected = detect_language(msg_content(m))
 
 
180
  if detected != "General":
181
  language = detected
182
  break
 
190
  gr.Markdown("# πŸŽ“ CodeMentor β€” AI Programming Tutor")
191
  gr.Markdown("*Ask any programming question. I'll guide you β€” not give you the answer!*")
192
 
 
193
  chatbot = gr.Chatbot(height=450)
194
 
195
  lang_display = gr.Textbox(label="Detected Language", interactive=False, value="🌐 General")
 
204
  if not message.strip():
205
  return "", chat_history, lang_display.value
206
  response, language = chat(message, chat_history)
207
+ # Plain dicts β€” the correct format for this Gradio version
208
+ chat_history.append({"role": "user", "content": message})
209
+ chat_history.append({"role": "assistant", "content": response})
210
  return "", chat_history, f"🌐 {language}"
211
 
212
  send.click(respond, [msg, chatbot], [msg, chatbot, lang_display])