Wfafa commited on
Commit
5242ed2
ยท
verified ยท
1 Parent(s): 00dc4b4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -137
app.py CHANGED
@@ -1,36 +1,14 @@
1
-
2
  import os
3
  import gradio as gr
4
  import requests
5
  import json
6
 
7
- # =======================
8
- # Hugging Face Token
9
- # =======================
10
  HF_TOKEN = os.getenv("HF_TOKEN")
11
- if not HF_TOKEN:
12
- print("Error: HF_TOKEN not set.")
13
- else:
14
- print("HF_TOKEN loaded successfully.")
15
-
16
- # =======================
17
- # Memory
18
- # =======================
19
  MEMORY_FILE = "memory.json"
20
 
21
- def load_memory():
22
- if os.path.exists(MEMORY_FILE):
23
- with open(MEMORY_FILE, "r") as f:
24
- return json.load(f)
25
- return []
26
-
27
- def save_memory(memory):
28
- with open(MEMORY_FILE, "w") as f:
29
- json.dump(memory, f)
30
-
31
- # =======================
32
- # Web search function
33
- # =======================
34
  def search_web(query):
35
  try:
36
  url = "https://api.duckduckgo.com/"
@@ -40,175 +18,133 @@ def search_web(query):
40
  if data.get("AbstractText"):
41
  return data["AbstractText"]
42
  elif data.get("RelatedTopics"):
43
- topics = [t.get("Text", "") for t in data.get("RelatedTopics", []) if "Text" in t]
44
  return " ".join(topics[:3])
45
  else:
46
  return "No useful information found."
47
  except Exception as e:
48
  return f"Search error: {e}"
49
 
50
- # =======================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  # Chat function
52
- # =======================
53
  def chat_with_model(message, history, context, file_input=None):
54
- if history is None:
55
  history = []
56
 
57
  if message.lower().startswith("search "):
58
  query = message[7:]
59
- search_result = search_web(query)
60
  history.append({"role": "user", "content": message})
61
- history.append({"role": "assistant", "content": f"๐Ÿ”Ž Here's what I found online:\n\n{search_result}"})
62
  save_memory(history)
63
  return history, history
64
 
65
  if file_input:
66
- message += f"\n\n๐Ÿ“Ž (User uploaded a file named '{file_input.name}')"
67
 
68
- # Add user message
69
- history.append({"role": "user", "content": message})
 
 
 
 
70
 
71
- # Build conversation for API
72
- conversation = [{"role": m["role"], "content": m["content"]} for m in history]
 
 
73
 
74
  try:
75
  response = requests.post(
76
  "https://router.huggingface.co/v1/chat/completions",
77
- headers={
78
- "Authorization": f"Bearer {HF_TOKEN}",
79
- "Content-Type": "application/json"
80
- },
81
- json={
82
- "model": "deepseek-ai/DeepSeek-V3.2-Exp:novita",
83
- "messages": conversation
84
- }
85
  )
86
- if response.status_code != 200:
87
- raise Exception(f"API Error: {response.status_code} - {response.text}")
88
-
89
- reply = response.json()["choices"][0]["message"]["content"]
90
- # Format math nicely
91
- reply = reply.replace("Step", "\n\n**Step").replace(":", ":**").replace("\\[", "\n\n\\[").replace("\\]", "\\]\n\n")
92
 
93
- # Add assistant reply
 
94
  history.append({"role": "assistant", "content": reply})
95
  save_memory(history)
96
  return history, history
97
 
98
  except Exception as e:
99
- print("Backend Error:", e)
100
- error_msg = "๐Ÿ˜… EduAI is having trouble connecting. Check HF_TOKEN or try again later!"
101
- history.append({"role": "assistant", "content": error_msg})
102
  return history, history
103
 
104
- # =======================
105
- # Sidebar context update
106
- # =======================
107
  def update_context(choice):
108
- if choice is None:
109
- return "๐Ÿ“˜ **You are in General Mode.** Ask EduAI anything about your studies!"
110
- return f"๐Ÿ“˜ **You selected {choice} mode.** Ask anything related to this topic!"
111
 
112
- # =======================
113
- # Clear memory
114
- # =======================
115
  def clear_memory():
116
  if os.path.exists(MEMORY_FILE):
117
  os.remove(MEMORY_FILE)
118
- return [], "๐Ÿงน Chat memory cleared! Start fresh."
119
-
120
- # =======================
121
- # Custom CSS
122
- # =======================
123
- custom_css = """
124
- @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
125
- body { font-family:'Roboto', sans-serif; background:#1e1e1e; color:#e0e0e0; min-height:100vh; }
126
- .header-title { font-size:36px; text-align:center; margin-bottom:20px; color:#007BFF; font-weight:700; text-shadow:0 0 10px rgba(0,123,255,0.5); }
127
- .sidebar { background:#2a2a2a; padding:20px; border-radius:12px; box-shadow:0 4px 12px rgba(0,0,0,0.5); border:1px solid #333; }
128
- .menu-title { font-size:20px; font-weight:500; margin-bottom:15px; color:#007BFF; }
129
- .accordion { background:#2a2a2a; border-radius:12px; padding:10px; margin-bottom:10px; box-shadow:0 3px 8px rgba(0,0,0,0.5); }
130
- .accordion-header { background:#333; color:#e0e0e0; border-radius:10px; padding:12px; font-weight:500; cursor:pointer; transition:0.3s; }
131
- .accordion-header:hover { background:#007BFF; color:#1e1e1e; }
132
- .main-chat { padding:20px; background:#1e1e1e; }
133
- .context-box { background:#2a2a2a; padding:15px; border-radius:10px; box-shadow:0 2px 6px rgba(0,0,0,0.3); margin-bottom:15px; border:1px solid #333; color:#e0e0e0; }
134
- .chatbox .message.user { background:#007BFF; color:#fff; border-radius:20px; padding:12px 18px; margin:8px 0; }
135
- .chatbox .message.bot { background:#333; color:#e0e0e0; border-radius:20px; padding:12px 18px; margin:8px 0; }
136
- .input-row { display:flex; gap:10px; margin-top:10px; }
137
- .chat-input { flex:1; border-radius:12px; padding:12px; border:1px solid #555; background:#2a2a2a; color:#e0e0e0; }
138
- .chat-input:focus { border-color:#007BFF; outline:none; }
139
- .btn-send { background:#7c3aed; color:#fff; border-radius:12px; padding:12px 18px; border:none; cursor:pointer; transition:0.3s; }
140
- .btn-send:hover { background:#5b21b6; }
141
- .file-upload { width:50px; height:50px; border:1px solid #555; border-radius:12px; background:#2a2a2a; display:flex; align-items:center; justify-content:center; cursor:pointer; font-size:20px; color:#e0e0e0; transition:0.3s; }
142
- .file-upload:hover { background:#007BFF; color:#1e1e1e; }
143
- .btn-clear { background:#f44336; color:white; border-radius:12px; padding:10px 15px; border:none; cursor:pointer; transition:0.3s; }
144
- .btn-clear:hover { background:#d32f2f; }
145
- .about-text { font-size:14px; color:#aaa; line-height:1.5; }
146
- .radio label { color:#e0e0e0; margin:8px 0; }
147
- """
148
-
149
- # =======================
150
  # Gradio UI
151
- # =======================
152
- with gr.Blocks(theme=gr.themes.Base(), css=custom_css) as iface:
153
- gr.Markdown("# ๐ŸŽ“ **EduAI โ€” Professional Study Companion**", elem_classes="header-title")
154
 
155
  with gr.Row():
156
  # Sidebar
157
- with gr.Column(scale=1, min_width=250, elem_classes="sidebar"):
158
- gr.Markdown("### ๐Ÿงญ **Main Menu**", elem_classes="menu-title")
159
 
160
  with gr.Accordion("๐Ÿ“š Subject Tutor", open=False):
161
- subj = gr.Radio(
162
- ["Science ๐Ÿงช", "ICT ๐Ÿ’ป", "English ๐Ÿ“˜", "Mathematics โž—"],
163
- label="Choose a subject", type="index"
164
- )
165
 
166
  with gr.Accordion("๐Ÿ—“ Study Planner", open=False):
167
- planner = gr.Radio(
168
- ["View Plan ๐Ÿ“…", "Add Task โœ๏ธ", "Study Tips ๐Ÿ’ก"],
169
- label="Planner Options", type="index"
170
- )
171
 
172
  with gr.Accordion("๐ŸŒ Languages", open=False):
173
- lang = gr.Radio(
174
- ["Learn Sinhala ๐Ÿ‡ฑ๐Ÿ‡ฐ","Learn Tamil ๐Ÿ‡ฎ๐Ÿ‡ณ","Learn English ๐Ÿ‡ฌ๐Ÿ‡ง","Learn Spanish ๐Ÿ‡ช๐Ÿ‡ธ"],
175
- label="Language Options", type="index"
176
- )
177
 
178
  with gr.Accordion("โš™๏ธ Settings", open=False):
179
- clear_btn = gr.Button("๐Ÿงน Clear Memory", elem_classes="btn-clear")
180
-
181
- with gr.Accordion("๐Ÿ‘ฉ๏ฟฝ๏ฟฝ๏ฟฝ๐ŸŽ“ About", open=False):
182
- gr.Markdown(
183
- "EduAI โ€“ developed by **Wafa Fazly** using a pre-trained AI model. Helps learners understand **Science, ICT, English, and more**.",
184
- elem_classes="about-text"
185
- )
186
-
187
- # Main Chat Area
188
- with gr.Column(scale=4, elem_classes="main-chat"):
189
- context_display = gr.Markdown(
190
- "๐Ÿ“˜ **You are in General Mode.** Ask EduAI anything about your studies!",
191
- elem_classes="context-box"
192
- )
193
 
194
  chatbot = gr.Chatbot(
195
  label="EduAI Chat",
196
- height=500,
197
- render_markdown=True,
198
  type="messages",
 
199
  latex_delimiters=[{"left": "$$", "right": "$$", "display": True},
200
  {"left": "\\[", "right": "\\]", "display": True}]
201
  )
202
 
203
- # Input row
204
- with gr.Row(elem_classes="input-row"):
205
- msg = gr.Textbox(label="Ask EduAI:", placeholder="Type your question here...", elem_classes="chat-input", show_label=False)
206
- file_input = gr.File(label="๐Ÿ“Ž", file_types=[".pdf", ".docx", ".png", ".jpg"], elem_classes="file-upload", show_label=False)
207
- send_btn = gr.Button("โœˆ๏ธ", elem_classes="btn-send")
208
 
209
- # =======================
210
- # Event handlers
211
- # =======================
212
  subj.change(update_context, inputs=subj, outputs=context_display)
213
  planner.change(update_context, inputs=planner, outputs=context_display)
214
  lang.change(update_context, inputs=lang, outputs=context_display)
@@ -216,5 +152,4 @@ with gr.Blocks(theme=gr.themes.Base(), css=custom_css) as iface:
216
  msg.submit(chat_with_model, inputs=[msg, chatbot, context_display, file_input], outputs=[chatbot, chatbot])
217
  clear_btn.click(clear_memory, outputs=[chatbot, context_display])
218
 
219
- # Launch the app
220
  iface.launch()
 
 
1
  import os
2
  import gradio as gr
3
  import requests
4
  import json
5
 
 
 
 
6
  HF_TOKEN = os.getenv("HF_TOKEN")
 
 
 
 
 
 
 
 
7
  MEMORY_FILE = "memory.json"
8
 
9
+ # ----------------
10
+ # Web search
11
+ # ----------------
 
 
 
 
 
 
 
 
 
 
12
  def search_web(query):
13
  try:
14
  url = "https://api.duckduckgo.com/"
 
18
  if data.get("AbstractText"):
19
  return data["AbstractText"]
20
  elif data.get("RelatedTopics"):
21
+ topics = [t.get("Text", "") for t in data["RelatedTopics"] if "Text" in t]
22
  return " ".join(topics[:3])
23
  else:
24
  return "No useful information found."
25
  except Exception as e:
26
  return f"Search error: {e}"
27
 
28
+ # ----------------
29
+ # Memory
30
+ # ----------------
31
+ def load_memory():
32
+ if os.path.exists(MEMORY_FILE):
33
+ with open(MEMORY_FILE, "r") as f:
34
+ return json.load(f)
35
+ return []
36
+
37
+ def save_memory(memory):
38
+ with open(MEMORY_FILE, "w") as f:
39
+ json.dump(memory, f)
40
+
41
+ memory = load_memory()
42
+
43
+ # ----------------
44
  # Chat function
45
+ # ----------------
46
  def chat_with_model(message, history, context, file_input=None):
47
+ if not isinstance(history, list):
48
  history = []
49
 
50
  if message.lower().startswith("search "):
51
  query = message[7:]
52
+ result = search_web(query)
53
  history.append({"role": "user", "content": message})
54
+ history.append({"role": "assistant", "content": f"๐Ÿ”Ž {result}"})
55
  save_memory(history)
56
  return history, history
57
 
58
  if file_input:
59
+ message += f"\n\n๐Ÿ“Ž Uploaded file: {file_input.name}"
60
 
61
+ conversation = [
62
+ {"role": "system", "content": (
63
+ "You are EduAI, a multilingual educational AI assistant created by a Sri Lankan student named Wafa Fazly. "
64
+ "Explain clearly, step-by-step, with Markdown and LaTeX for math."
65
+ )}
66
+ ]
67
 
68
+ for msg_obj in history[-5:]:
69
+ conversation.append(msg_obj)
70
+
71
+ conversation.append({"role": "user", "content": message})
72
 
73
  try:
74
  response = requests.post(
75
  "https://router.huggingface.co/v1/chat/completions",
76
+ headers={"Authorization": f"Bearer {HF_TOKEN}", "Content-Type": "application/json"},
77
+ json={"model": "deepseek-ai/DeepSeek-V3.2-Exp:novita", "messages": conversation}
 
 
 
 
 
 
78
  )
79
+ data = response.json()
80
+ reply = data["choices"][0]["message"]["content"]
 
 
 
 
81
 
82
+ reply = reply.replace("Step", "\n\n**Step").replace(":", ":**")
83
+ history.append({"role": "user", "content": message})
84
  history.append({"role": "assistant", "content": reply})
85
  save_memory(history)
86
  return history, history
87
 
88
  except Exception as e:
89
+ history.append({"role": "user", "content": message})
90
+ history.append({"role": "assistant", "content": "๐Ÿ˜… EduAI is having trouble connecting."})
 
91
  return history, history
92
 
93
+ # ----------------
94
+ # Sidebar helpers
95
+ # ----------------
96
  def update_context(choice):
97
+ if not choice:
98
+ return "๐Ÿ“˜ **General Mode.** Ask EduAI anything!"
99
+ return f"๐Ÿ“˜ **{choice} mode selected.**"
100
 
 
 
 
101
  def clear_memory():
102
  if os.path.exists(MEMORY_FILE):
103
  os.remove(MEMORY_FILE)
104
+ return [], "๐Ÿงน Chat memory cleared."
105
+
106
+ # ----------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  # Gradio UI
108
+ # ----------------
109
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="violet")) as iface:
110
+ gr.Markdown("# ๐ŸŽ“ EduAI โ€” Professional Study Companion")
111
 
112
  with gr.Row():
113
  # Sidebar
114
+ with gr.Column(scale=1, min_width=250):
115
+ gr.Markdown("### ๐Ÿงญ Main Menu")
116
 
117
  with gr.Accordion("๐Ÿ“š Subject Tutor", open=False):
118
+ subj = gr.Radio(["Science ๐Ÿงช", "ICT ๐Ÿ’ป", "English ๐Ÿ“˜", "Math โž—"], label="Subject")
 
 
 
119
 
120
  with gr.Accordion("๐Ÿ—“ Study Planner", open=False):
121
+ planner = gr.Radio(["View Plan ๐Ÿ“…", "Add Task โœ๏ธ", "Study Tips ๐Ÿ’ก"], label="Planner")
 
 
 
122
 
123
  with gr.Accordion("๐ŸŒ Languages", open=False):
124
+ lang = gr.Radio(["Sinhala ๐Ÿ‡ฑ๐Ÿ‡ฐ", "Tamil ๐Ÿ‡ฎ๐Ÿ‡ณ", "English ๐Ÿ‡ฌ๐Ÿ‡ง", "Spanish ๐Ÿ‡ช๐Ÿ‡ธ"], label="Language")
 
 
 
125
 
126
  with gr.Accordion("โš™๏ธ Settings", open=False):
127
+ clear_btn = gr.Button("๐Ÿงน Clear Memory")
128
+
129
+ # Chat area
130
+ with gr.Column(scale=4):
131
+ context_display = gr.Markdown("๐Ÿ“˜ **General Mode.** Ask EduAI anything!")
 
 
 
 
 
 
 
 
 
132
 
133
  chatbot = gr.Chatbot(
134
  label="EduAI Chat",
135
+ height=450,
 
136
  type="messages",
137
+ render_markdown=True,
138
  latex_delimiters=[{"left": "$$", "right": "$$", "display": True},
139
  {"left": "\\[", "right": "\\]", "display": True}]
140
  )
141
 
142
+ with gr.Row():
143
+ msg = gr.Textbox(placeholder="Type your question here...", show_label=False)
144
+ file_input = gr.File(file_types=[".pdf", ".docx", ".png", ".jpg"], show_label=False)
145
+ send_btn = gr.Button("โœˆ๏ธ")
 
146
 
147
+ # Events
 
 
148
  subj.change(update_context, inputs=subj, outputs=context_display)
149
  planner.change(update_context, inputs=planner, outputs=context_display)
150
  lang.change(update_context, inputs=lang, outputs=context_display)
 
152
  msg.submit(chat_with_model, inputs=[msg, chatbot, context_display, file_input], outputs=[chatbot, chatbot])
153
  clear_btn.click(clear_memory, outputs=[chatbot, context_display])
154
 
 
155
  iface.launch()