Reality123b commited on
Commit
3a7c6b3
·
verified ·
1 Parent(s): ce077ce

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +206 -72
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
  import gradio as gr
3
  from huggingface_hub import InferenceClient
 
4
 
5
  class XylariaChat:
6
  def __init__(self):
@@ -8,20 +9,22 @@ class XylariaChat:
8
  self.hf_token = os.getenv("HF_TOKEN")
9
  if not self.hf_token:
10
  raise ValueError("HuggingFace token not found in environment variables")
11
-
12
  # Initialize the inference client
13
  self.client = InferenceClient(
14
- model="Qwen/QwQ-32B-Preview",
15
  api_key=self.hf_token
16
  )
17
-
18
  # Initialize conversation history and persistent memory
19
  self.conversation_history = []
20
  self.persistent_memory = {}
21
-
 
22
  # System prompt with more detailed instructions
23
- self.system_prompt = """You are a helpful and harmless AI assistant you are Xylaria 1.4 Senoa, Made by Sk Md Saad Amin you think step by step
24
  """
 
25
  def store_information(self, key, value):
26
  """Store important information in persistent memory"""
27
  self.persistent_memory[key] = value
@@ -30,25 +33,53 @@ class XylariaChat:
30
  """Retrieve information from persistent memory"""
31
  return self.persistent_memory.get(key)
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  def reset_conversation(self):
34
  """
35
- Completely reset the conversation history, persistent memory,
36
  and clear API-side memory
37
  """
38
  # Clear local memory
39
  self.conversation_history = []
40
  self.persistent_memory.clear()
41
-
42
  # Clear API-side memory by resetting the conversation
43
  try:
44
  # Attempt to clear any API-side session or context
45
  self.client = InferenceClient(
46
- model="Qwen/QwQ-32B-Preview",
47
  api_key=self.hf_token
48
  )
49
  except Exception as e:
50
  print(f"Error resetting API client: {e}")
51
-
 
52
  return None # To clear the chatbot interface
53
 
54
  def get_response(self, user_input):
@@ -58,14 +89,14 @@ class XylariaChat:
58
  *self.conversation_history,
59
  {"role": "user", "content": user_input}
60
  ]
61
-
62
  # Add persistent memory context if available
63
  if self.persistent_memory:
64
  memory_context = "Remembered Information:\n" + "\n".join(
65
  [f"{k}: {v}" for k, v in self.persistent_memory.items()]
66
  )
67
  messages.insert(1, {"role": "system", "content": memory_context})
68
-
69
  # Generate response with streaming
70
  try:
71
  stream = self.client.chat.completions.create(
@@ -75,9 +106,9 @@ class XylariaChat:
75
  top_p=0.7,
76
  stream=True
77
  )
78
-
79
  return stream
80
-
81
  except Exception as e:
82
  return f"Error generating response: {str(e)}"
83
 
@@ -85,25 +116,25 @@ class XylariaChat:
85
  def streaming_response(message, chat_history):
86
  # Clear input textbox
87
  response_stream = self.get_response(message)
88
-
89
  # If it's an error, return immediately
90
  if isinstance(response_stream, str):
91
  return "", chat_history + [[message, response_stream]]
92
-
93
  # Prepare for streaming response
94
  full_response = ""
95
  updated_history = chat_history + [[message, ""]]
96
-
97
  # Streaming output
98
  for chunk in response_stream:
99
  if chunk.choices[0].delta.content:
100
  chunk_content = chunk.choices[0].delta.content
101
  full_response += chunk_content
102
-
103
  # Update the last message in chat history with partial response
104
  updated_history[-1][1] = full_response
105
  yield "", updated_history
106
-
107
  # Update conversation history
108
  self.conversation_history.append(
109
  {"role": "user", "content": message}
@@ -111,15 +142,22 @@ class XylariaChat:
111
  self.conversation_history.append(
112
  {"role": "assistant", "content": full_response}
113
  )
114
-
115
  # Limit conversation history to prevent token overflow
116
  if len(self.conversation_history) > 10:
117
  self.conversation_history = self.conversation_history[-10:]
118
 
119
- # Custom CSS for Inter font
 
 
 
 
 
 
 
120
  custom_css = """
121
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
122
-
123
  body, .gradio-container {
124
  font-family: 'Inter', sans-serif !important;
125
  }
@@ -133,64 +171,160 @@ class XylariaChat:
133
  .gradio-container button {
134
  font-family: 'Inter', sans-serif !important;
135
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  """
137
 
 
 
 
 
 
 
 
 
 
 
 
138
  with gr.Blocks(theme='soft', css=custom_css) as demo:
139
- # Chat interface with improved styling
140
- with gr.Column():
141
- chatbot = gr.Chatbot(
142
- label="Xylaria 1.4 Senoa",
143
- height=500,
144
- show_copy_button=True
145
- )
146
-
147
- # Input row with improved layout
148
- with gr.Row():
149
- txt = gr.Textbox(
150
- show_label=False,
151
- placeholder="Type your message...",
152
- container=False,
153
- scale=4
154
  )
155
- btn = gr.Button("Send", scale=1)
156
-
157
- # Clear history and memory buttons
158
- clear = gr.Button("Clear Conversation")
159
- clear_memory = gr.Button("Clear Memory")
160
-
161
- # Submit functionality with streaming
162
- btn.click(
163
- fn=streaming_response,
164
- inputs=[txt, chatbot],
165
- outputs=[txt, chatbot]
166
- )
167
- txt.submit(
168
- fn=streaming_response,
169
- inputs=[txt, chatbot],
170
- outputs=[txt, chatbot]
171
- )
172
-
173
- # Clear conversation history
174
- clear.click(
175
- fn=lambda: None,
176
- inputs=None,
177
- outputs=[chatbot],
178
- queue=False
179
- )
180
-
181
- # Clear persistent memory and reset conversation
182
- clear_memory.click(
183
- fn=self.reset_conversation,
184
- inputs=None,
185
- outputs=[chatbot],
186
- queue=False
187
- )
188
 
189
- # Ensure memory is cleared when the interface is closed
190
- demo.load(self.reset_conversation, None, None)
191
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  return demo
193
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  # Launch the interface
195
  def main():
196
  chat = XylariaChat()
 
1
  import os
2
  import gradio as gr
3
  from huggingface_hub import InferenceClient
4
+ import json
5
 
6
  class XylariaChat:
7
  def __init__(self):
 
9
  self.hf_token = os.getenv("HF_TOKEN")
10
  if not self.hf_token:
11
  raise ValueError("HuggingFace token not found in environment variables")
12
+
13
  # Initialize the inference client
14
  self.client = InferenceClient(
15
+ model="Qwen/Qwen-32B-Preview",
16
  api_key=self.hf_token
17
  )
18
+
19
  # Initialize conversation history and persistent memory
20
  self.conversation_history = []
21
  self.persistent_memory = {}
22
+ self.chat_file_path = "chat_history.txt" # File to save chats
23
+
24
  # System prompt with more detailed instructions
25
+ self.system_prompt = """You are a helpful and harmless AI assistant you are Xylaria 1.4 Senoa, Made by Sk Md Saad Amin you think step by step
26
  """
27
+
28
  def store_information(self, key, value):
29
  """Store important information in persistent memory"""
30
  self.persistent_memory[key] = value
 
33
  """Retrieve information from persistent memory"""
34
  return self.persistent_memory.get(key)
35
 
36
+ def save_chat(self):
37
+ """Saves the current chat history to a text file."""
38
+ try:
39
+ with open(self.chat_file_path, "w") as f:
40
+ chat_data = {
41
+ "conversation_history": self.conversation_history,
42
+ "persistent_memory": self.persistent_memory
43
+ }
44
+ json.dump(chat_data, f)
45
+ except Exception as e:
46
+ print(f"Error saving chat history: {e}")
47
+
48
+ def load_chat(self):
49
+ """Loads chat history from a text file."""
50
+ try:
51
+ with open(self.chat_file_path, "r") as f:
52
+ chat_data = json.load(f)
53
+ self.conversation_history = chat_data.get("conversation_history", [])
54
+ self.persistent_memory = chat_data.get("persistent_memory", {})
55
+ return self.conversation_history, self.persistent_memory
56
+ except FileNotFoundError:
57
+ print("Chat history file not found.")
58
+ return [], {}
59
+ except Exception as e:
60
+ print(f"Error loading chat history: {e}")
61
+ return [], {}
62
+
63
  def reset_conversation(self):
64
  """
65
+ Completely reset the conversation history, persistent memory,
66
  and clear API-side memory
67
  """
68
  # Clear local memory
69
  self.conversation_history = []
70
  self.persistent_memory.clear()
71
+
72
  # Clear API-side memory by resetting the conversation
73
  try:
74
  # Attempt to clear any API-side session or context
75
  self.client = InferenceClient(
76
+ model="Qwen/Qwen-32B-Preview",
77
  api_key=self.hf_token
78
  )
79
  except Exception as e:
80
  print(f"Error resetting API client: {e}")
81
+
82
+ self.save_chat() # Save the empty chat history
83
  return None # To clear the chatbot interface
84
 
85
  def get_response(self, user_input):
 
89
  *self.conversation_history,
90
  {"role": "user", "content": user_input}
91
  ]
92
+
93
  # Add persistent memory context if available
94
  if self.persistent_memory:
95
  memory_context = "Remembered Information:\n" + "\n".join(
96
  [f"{k}: {v}" for k, v in self.persistent_memory.items()]
97
  )
98
  messages.insert(1, {"role": "system", "content": memory_context})
99
+
100
  # Generate response with streaming
101
  try:
102
  stream = self.client.chat.completions.create(
 
106
  top_p=0.7,
107
  stream=True
108
  )
109
+
110
  return stream
111
+
112
  except Exception as e:
113
  return f"Error generating response: {str(e)}"
114
 
 
116
  def streaming_response(message, chat_history):
117
  # Clear input textbox
118
  response_stream = self.get_response(message)
119
+
120
  # If it's an error, return immediately
121
  if isinstance(response_stream, str):
122
  return "", chat_history + [[message, response_stream]]
123
+
124
  # Prepare for streaming response
125
  full_response = ""
126
  updated_history = chat_history + [[message, ""]]
127
+
128
  # Streaming output
129
  for chunk in response_stream:
130
  if chunk.choices[0].delta.content:
131
  chunk_content = chunk.choices[0].delta.content
132
  full_response += chunk_content
133
+
134
  # Update the last message in chat history with partial response
135
  updated_history[-1][1] = full_response
136
  yield "", updated_history
137
+
138
  # Update conversation history
139
  self.conversation_history.append(
140
  {"role": "user", "content": message}
 
142
  self.conversation_history.append(
143
  {"role": "assistant", "content": full_response}
144
  )
145
+
146
  # Limit conversation history to prevent token overflow
147
  if len(self.conversation_history) > 10:
148
  self.conversation_history = self.conversation_history[-10:]
149
 
150
+ self.save_chat()
151
+
152
+ def load_chat_interface():
153
+ """Loads the chat history into the chatbot interface."""
154
+ self.load_chat()
155
+ return self.conversation_history
156
+
157
+ # Custom CSS for Inter font and sidebar
158
  custom_css = """
159
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
160
+
161
  body, .gradio-container {
162
  font-family: 'Inter', sans-serif !important;
163
  }
 
171
  .gradio-container button {
172
  font-family: 'Inter', sans-serif !important;
173
  }
174
+
175
+ /* Sidebar styling */
176
+ #sidebar {
177
+ background-color: #f2f2f2;
178
+ border-right: 1px solid #ccc;
179
+ padding: 10px;
180
+ height: 100vh;
181
+ overflow-y: auto;
182
+ }
183
+
184
+ #sidebar ul {
185
+ list-style-type: none;
186
+ padding: 0;
187
+ }
188
+
189
+ #sidebar li {
190
+ margin-bottom: 5px;
191
+ }
192
+ /* Main chat area */
193
+ #main-chat {
194
+ padding: 20px;
195
+ }
196
  """
197
 
198
+ # Example prompts
199
+ example_prompts = [
200
+ "How do I get started with coding?",
201
+ "Tell me a fun fact about science.",
202
+ "What are some good books to read?"
203
+ ]
204
+
205
+ # Function to forward prompt to the textbox
206
+ def forward_prompt(prompt):
207
+ return prompt
208
+
209
  with gr.Blocks(theme='soft', css=custom_css) as demo:
210
+ with gr.Row():
211
+ # Sidebar for displaying chat history
212
+ with gr.Column(elem_id="sidebar", scale=1): # Added elem_id for CSS
213
+ gr.Markdown("### Chat History")
214
+ load_button = gr.Button("Load Chat History")
215
+ chat_list = gr.Markdown("No chat history found.")
216
+
217
+ load_button.click(
218
+ fn=lambda: gr.Markdown.update(value=self.format_chat_history()),
219
+ inputs=None,
220
+ outputs=[chat_list]
 
 
 
 
221
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
 
223
+ # Main chat interface
224
+ with gr.Column(elem_id="main-chat", scale=3):
225
+ # Show Xylaria and example prompts only on the first page/new chat
226
+ with gr.Column(visible=True) as start_page:
227
+ gr.Markdown("# Xylaria")
228
+ with gr.Row():
229
+ for prompt in example_prompts:
230
+ gr.Button(prompt).click(
231
+ fn=forward_prompt,
232
+ inputs=gr.State(prompt),
233
+ outputs=txt
234
+ )
235
+
236
+ with gr.Column(visible=False) as chat_page:
237
+ chatbot = gr.Chatbot(
238
+ label="Xylaria 1.4 Senoa",
239
+ height=500,
240
+ show_copy_button=True
241
+ )
242
+
243
+ # Input row with improved layout
244
+ with gr.Row():
245
+ txt = gr.Textbox(
246
+ show_label=False,
247
+ placeholder="Type your message...",
248
+ container=False,
249
+ scale=4
250
+ )
251
+ btn = gr.Button("Send", scale=1)
252
+
253
+ # Clear history and memory buttons
254
+ clear = gr.Button("Clear Conversation")
255
+ clear_memory = gr.Button("Clear Memory")
256
+
257
+ # Toggle between start page and chat page
258
+ def toggle_page(choice):
259
+ return gr.Column.update(visible=choice == "chat"), gr.Column.update(visible=choice == "start")
260
+
261
+ start_page.visible = True
262
+ chat_page.visible = False
263
+
264
+ # Submit functionality with streaming
265
+ btn.click(
266
+ fn=streaming_response,
267
+ inputs=[txt, chatbot],
268
+ outputs=[txt, chatbot]
269
+ ).then(
270
+ fn=lambda: toggle_page("chat"),
271
+ inputs=gr.State("chat"),
272
+ outputs=[chat_page, start_page]
273
+ )
274
+ txt.submit(
275
+ fn=streaming_response,
276
+ inputs=[txt, chatbot],
277
+ outputs=[txt, chatbot]
278
+ ).then(
279
+ fn=lambda: toggle_page("chat"),
280
+ inputs=gr.State("chat"),
281
+ outputs=[chat_page, start_page]
282
+ )
283
+
284
+ # Clear conversation history
285
+ clear.click(
286
+ fn=lambda: None,
287
+ inputs=None,
288
+ outputs=[chatbot],
289
+ queue=False
290
+ ).then(
291
+ fn=lambda: toggle_page("start"),
292
+ inputs=gr.State("start"),
293
+ outputs=[chat_page, start_page]
294
+ )
295
+
296
+ # Clear persistent memory and reset conversation
297
+ clear_memory.click(
298
+ fn=self.reset_conversation,
299
+ inputs=None,
300
+ outputs=[chatbot],
301
+ queue=False
302
+ ).then(
303
+ fn=lambda: toggle_page("start"),
304
+ inputs=gr.State("start"),
305
+ outputs=[chat_page, start_page]
306
+ )
307
+
308
+ # Ensure memory is cleared when the interface is closed
309
+ demo.load(self.reset_conversation, None, None)
310
+
311
  return demo
312
 
313
+ def format_chat_history(self):
314
+ """Formats the chat history for display in the sidebar."""
315
+ self.load_chat() # Load the chat history first
316
+ if not self.conversation_history:
317
+ return "No chat history found."
318
+
319
+ formatted_history = ""
320
+ for chat in self.conversation_history:
321
+ if chat["role"] == "user":
322
+ formatted_history += f"**You:** {chat['content']}\n\n"
323
+ elif chat["role"] == "assistant":
324
+ formatted_history += f"**Xylaria:** {chat['content']}\n\n"
325
+
326
+ return formatted_history
327
+
328
  # Launch the interface
329
  def main():
330
  chat = XylariaChat()