Reality123b commited on
Commit
1271777
·
verified ·
1 Parent(s): 419785c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -293
app.py CHANGED
@@ -1,11 +1,6 @@
1
  import os
2
  import gradio as gr
3
  from huggingface_hub import InferenceClient
4
- import json
5
-
6
- # Global variables to track state (use with caution!)
7
- chat_visible_global = False
8
- sidebar_collapsed = False
9
 
10
  class XylariaChat:
11
  def __init__(self):
@@ -16,18 +11,35 @@ class XylariaChat:
16
 
17
  # Initialize the inference client
18
  self.client = InferenceClient(
19
- model="Qwen/Qwen-32B-Preview",
20
- api_key=self.hf_token
21
  )
22
 
23
  # Initialize conversation history and persistent memory
24
  self.conversation_history = []
25
  self.persistent_memory = {}
26
- self.chat_file_path = "chat_history.txt" # File to save chats
27
 
28
- # System prompt
29
- 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
30
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  def store_information(self, key, value):
33
  """Store important information in persistent memory"""
@@ -37,53 +49,14 @@ class XylariaChat:
37
  """Retrieve information from persistent memory"""
38
  return self.persistent_memory.get(key)
39
 
40
- def save_chat(self):
41
- """Saves the current chat history to a text file."""
42
- try:
43
- with open(self.chat_file_path, "w") as f:
44
- chat_data = {
45
- "conversation_history": self.conversation_history,
46
- "persistent_memory": self.persistent_memory
47
- }
48
- json.dump(chat_data, f)
49
- except Exception as e:
50
- print(f"Error saving chat history: {e}")
51
-
52
- def load_chat(self):
53
- """Loads chat history from a text file."""
54
- try:
55
- with open(self.chat_file_path, "r") as f:
56
- chat_data = json.load(f)
57
- self.conversation_history = chat_data.get("conversation_history", [])
58
- self.persistent_memory = chat_data.get("persistent_memory", {})
59
- return self.conversation_history, self.persistent_memory
60
- except FileNotFoundError:
61
- print("Chat history file not found.")
62
- return [], {}
63
- except Exception as e:
64
- print(f"Error loading chat history: {e}")
65
- return [], {}
66
-
67
  def reset_conversation(self):
68
  """
69
- Completely reset the conversation history, persistent memory,
70
- and clear API-side memory
71
  """
72
- # Clear local memory
73
  self.conversation_history = []
74
- self.persistent_memory.clear()
75
-
76
- # Clear API-side memory by resetting the conversation
77
- try:
78
- # Attempt to clear any API-side session or context
79
- self.client = InferenceClient(
80
- model="Qwen/Qwen-32B-Preview",
81
- api_key=self.hf_token
82
- )
83
- except Exception as e:
84
- print(f"Error resetting API client: {e}")
85
-
86
- self.save_chat() # Save the empty chat history
87
 
88
  def get_response(self, user_input):
89
  # Prepare messages with conversation context and persistent memory
@@ -102,37 +75,76 @@ class XylariaChat:
102
 
103
  # Generate response with streaming
104
  try:
105
- stream = self.client.chat.completions.create(
106
- messages=messages,
 
107
  temperature=0.5,
108
- max_tokens=10240,
109
  top_p=0.7,
110
  stream=True
111
  )
112
 
113
- return stream
114
 
115
  except Exception as e:
116
  return f"Error generating response: {str(e)}"
117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  def create_interface(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  def streaming_response(message, chat_history):
 
120
  response_stream = self.get_response(message)
121
 
 
122
  if isinstance(response_stream, str):
123
- # Error handling: directly append error message to chat history
124
  return "", chat_history + [[message, response_stream]]
125
 
 
126
  full_response = ""
127
  updated_history = chat_history + [[message, ""]]
128
 
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
- updated_history[-1][1] = full_response
134
- yield "", updated_history
135
 
 
 
 
 
 
136
  self.conversation_history.append(
137
  {"role": "user", "content": message}
138
  )
@@ -140,282 +152,116 @@ class XylariaChat:
140
  {"role": "assistant", "content": full_response}
141
  )
142
 
 
143
  if len(self.conversation_history) > 10:
144
  self.conversation_history = self.conversation_history[-10:]
145
 
146
- self.save_chat() # Save after each interaction
147
-
148
- # Function to format and display chat history
149
- def format_chat_history():
150
- self.load_chat() # Load the chat history first
151
- if not self.conversation_history:
152
- return "No chat history found."
153
 
154
- formatted_history = ""
155
- for chat in self.conversation_history:
156
- if chat["role"] == "user":
157
- formatted_history += f"**You:** {chat['content']}\n\n"
158
- elif chat["role"] == "assistant":
159
- formatted_history += f"**Xylaria:** {chat['content']}\n\n"
160
-
161
- return formatted_history
162
-
163
- # Custom CSS for improved colors and styling
164
  custom_css = """
165
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
166
-
167
  body, .gradio-container {
168
  font-family: 'Inter', sans-serif !important;
169
- background-color: #f8f8f8; /* Light background */
170
  }
171
-
172
- /* Chatbot styling */
173
  .chatbot-container .message {
174
  font-family: 'Inter', sans-serif !important;
175
- padding: 10px 15px;
176
- border-radius: 10px;
177
- margin-bottom: 8px; /* Add margin between messages */
178
- }
179
-
180
- .chatbot-container .user {
181
- background-color: #e0f2f7; /* Light blue for user messages */
182
- border: 1px solid #a7d9ed; /* Light blue border */
183
- }
184
-
185
- .chatbot-container .assistant {
186
- background-color: #f0f0f0; /* Light gray for assistant messages */
187
- border: 1px solid #d3d3d3; /* Light gray border */
188
  }
189
-
190
- .chatbot-container .message-tools {
191
- margin-right: 10px; /* Add some space between text and buttons */
192
- }
193
-
194
- /* Sidebar styling */
195
- #sidebar {
196
- background-color: #f2f2f2;
197
- border-right: 1px solid #ccc;
198
- padding: 10px;
199
- height: 100vh;
200
- overflow-y: auto;
201
- transition: width 0.3s ease; /* Smooth transition for collapse */
202
- width: 250px; /* Initial width */
203
- }
204
-
205
- #sidebar.collapsed {
206
- width: 50px; /* Collapsed width */
207
- }
208
-
209
- #sidebar.collapsed #sidebar-content {
210
- display: none; /* Hide content when collapsed */
211
- }
212
-
213
- #sidebar-content {
214
- display: block;
215
- }
216
-
217
- #collapse-button {
218
- width: 100%;
219
- margin-bottom: 10px;
220
- background-color: transparent;
221
- border: none;
222
- cursor: pointer;
223
- text-align: left;
224
- padding: 5px;
225
- }
226
-
227
- /* Main chat area */
228
- #main-chat {
229
- padding: 20px;
230
- }
231
-
232
- /* Textbox and buttons */
233
  .gradio-container input,
234
  .gradio-container textarea,
235
  .gradio-container button {
236
  font-family: 'Inter', sans-serif !important;
237
- border-radius: 5px; /* Rounded corners */
238
- }
239
-
240
- .gradio-container button {
241
- background-color: #4CAF50; /* Green button */
242
- color: white;
243
- transition: background-color 0.2s; /* Smooth transition for hover effect */
244
- }
245
-
246
- .gradio-container button:hover {
247
- background-color: #3e8e41; /* Darker green on hover */
248
  }
249
  """
250
 
251
- # Example prompts
252
- example_prompts = [
253
- "How do I get started with coding?",
254
- "Tell me a fun fact about science.",
255
- "What are some good books to read?"
256
- ]
257
-
258
- # Function to forward prompt to the textbox
259
- def forward_prompt(prompt):
260
- return prompt
261
-
262
- # Create the interface
263
- with gr.Blocks(css=custom_css) as demo:
264
- # Access global variables (use with caution!)
265
- global chat_visible_global
266
- global sidebar_collapsed_global
267
-
268
- with gr.Row():
269
- # Sidebar for displaying chat history
270
- with gr.Column(scale=1) as sidebar:
271
- # Collapse button
272
- collapse_button = gr.Button("<<", elem_id="collapse-button")
273
-
274
- # Sidebar content (in a nested column for easier hiding)
275
- with gr.Column(elem_id="sidebar-content") as sidebar_content:
276
- gr.Markdown("### Chat History")
277
- load_button = gr.Button("Load Chat History")
278
- chat_list = gr.Markdown("No chat history found.")
279
-
280
- load_button.click(
281
- fn=lambda *args: format_chat_history(),
282
- inputs=None,
283
- outputs=[chat_list]
284
- )
285
-
286
- # Main chat interface
287
- with gr.Column(scale=3) as main_chat:
288
- # Input row (stays visible)
289
- with gr.Row():
290
- txt = gr.Textbox(
291
- show_label=False,
292
- placeholder="Type your message...",
293
- container=False,
294
- scale=4
295
- )
296
- btn = gr.Button("Send", scale=1)
297
-
298
- # Xylaria welcome and example prompts (initially visible)
299
- with gr.Column(visible=True) as start_page:
300
- gr.Markdown("# Xylaria")
301
- with gr.Row():
302
- for prompt in example_prompts:
303
- gr.Button(prompt).click(
304
- fn=lambda p=prompt: p,
305
- inputs=gr.State(prompt),
306
- outputs=txt
307
- )
308
-
309
- # Chat interface (initially hidden)
310
- with gr.Column(visible=False) as chat_page:
311
- chatbot = gr.Chatbot(
312
- label="Xylaria 1.4 Senoa",
313
- height=500,
314
- show_copy_button=True,
315
- avatar_images=("user.png", "xylaria.png"),
316
- bubble_full_width=False
317
- )
318
-
319
- # Clear history and memory buttons
320
- clear = gr.Button("Clear Conversation")
321
- clear_memory = gr.Button("Clear Memory")
322
-
323
- # Toggle between start and chat pages (using visibility and global variable)
324
- def toggle_page(*args):
325
- global chat_visible_global
326
- chat_visible_global = not chat_visible_global
327
- return not chat_visible_global, chat_visible_global
328
-
329
- # Toggle sidebar visibility (using global variable)
330
- def toggle_sidebar(*args):
331
- global sidebar_collapsed_global
332
- sidebar_collapsed_global = not sidebar_collapsed_global
333
- if sidebar_collapsed_global:
334
- # If currently collapsed, expand
335
- return False, "250px", "block" # Expand, normal width, display content
336
- else:
337
- # If currently expanded, collapse
338
- return True, "50px", "none" # Collapse, narrow width, hide content
339
-
340
- # Collapse button click (handle sidebar toggling)
341
- collapse_button.click(
342
- fn=toggle_sidebar,
343
- inputs=[],
344
- outputs=[sidebar_collapsed, sidebar, sidebar_content]
345
  )
346
 
347
- # Submit prompt
348
- submit_event = btn.click(
349
  fn=streaming_response,
350
  inputs=[txt, chatbot],
351
  outputs=[txt, chatbot]
 
 
 
 
 
352
  )
353
- txt_submit_event = txt.submit(
354
  fn=streaming_response,
355
  inputs=[txt, chatbot],
356
  outputs=[txt, chatbot]
 
 
 
 
 
357
  )
358
 
359
- # Toggle to chat page after sending the first message
360
- submit_event.then(
361
- fn=toggle_page,
362
- inputs=[],
363
- outputs=[start_page, chat_page]
364
- )
365
- txt_submit_event.then(
366
- fn=toggle_page,
367
- inputs=[],
368
- outputs=[start_page, chat_page]
369
- )
370
-
371
- # Clear conversation
372
  clear.click(
373
- fn=lambda *args: [],
374
  inputs=None,
375
- outputs=[chatbot],
376
- queue=False
377
  ).then(
378
- fn=lambda *args: (True, False),
379
  inputs=None,
380
- outputs=[start_page, chat_page]
 
381
  )
382
 
383
- # Clear memory
384
  clear_memory.click(
385
  fn=self.reset_conversation,
386
  inputs=None,
387
- outputs=None,
388
- queue=False
389
  ).then(
390
- fn=lambda *args: (True, False),
391
  inputs=None,
392
- outputs=[start_page, chat_page]
 
393
  )
394
 
395
- # Load on startup
396
- demo.load(fn=self.reset_conversation, inputs=None, outputs=None)
397
-
398
- return demo
399
-
400
- def format_chat_history(self):
401
- """Formats the chat history for display in the sidebar."""
402
- self.load_chat() # Load the chat history first
403
- if not self.conversation_history:
404
- return "No chat history found."
405
-
406
- formatted_history = ""
407
- for chat in self.conversation_history:
408
- if chat["role"] == "user":
409
- formatted_history += f"**You:** {chat['content']}\n\n"
410
- elif chat["role"] == "assistant":
411
- formatted_history += f"**Xylaria:** {chat['content']}\n\n"
412
 
413
- return formatted_history
414
  def main():
415
  chat = XylariaChat()
416
  interface = chat.create_interface()
417
  interface.launch(
418
- share=False, # Set to True to create a public link
419
  debug=True # Show detailed errors
420
  )
421
 
 
1
  import os
2
  import gradio as gr
3
  from huggingface_hub import InferenceClient
 
 
 
 
 
4
 
5
  class XylariaChat:
6
  def __init__(self):
 
11
 
12
  # Initialize the inference client
13
  self.client = InferenceClient(
14
+ model="Qwen/QwQ-32B-Preview", # Changed model name
15
+ token=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 Xylaria 1.4 Senoa, Made by Sk Md Saad Amin designed to provide helpful, accurate, and engaging support across a wide range of topics. Key guidelines for our interaction include:
24
+ Core Principles:
25
+ - Provide accurate and comprehensive assistance
26
+ - Maintain a friendly and approachable communication style
27
+ - Prioritize the user's needs and context
28
+ Communication Style:
29
+ - Be conversational and warm
30
+ - Use clear, concise language
31
+ - Occasionally use light, appropriate emoji to enhance communication
32
+ - Adapt communication style to the user's preferences
33
+ - Respond in english
34
+ Important Notes:
35
+ - I am an AI assistant created by an independent developer
36
+ - I do not represent OpenAI or any other AI institution
37
+ - For image-related queries, I can describe images or provide analysis, or generate or link to images directly
38
+ Capabilities:
39
+ - Assist with research, writing, analysis, problem-solving, and creative tasks
40
+ - Answer questions across various domains
41
+ - Provide explanations and insights
42
+ - Offer supportive and constructive guidance """
43
 
44
  def store_information(self, key, value):
45
  """Store important information in persistent memory"""
 
49
  """Retrieve information from persistent memory"""
50
  return self.persistent_memory.get(key)
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  def reset_conversation(self):
53
  """
54
+ Completely reset the conversation history and persistent memory
55
+ This helps prevent exposing previous users' conversations
56
  """
 
57
  self.conversation_history = []
58
+ self.persistent_memory = {}
59
+ return []
 
 
 
 
 
 
 
 
 
 
 
60
 
61
  def get_response(self, user_input):
62
  # Prepare messages with conversation context and persistent memory
 
75
 
76
  # Generate response with streaming
77
  try:
78
+ response_stream = self.client.text_generation(
79
+ prompt=self.messages_to_prompt(messages), # Convert messages to prompt format
80
+ max_new_tokens=1024,
81
  temperature=0.5,
 
82
  top_p=0.7,
83
  stream=True
84
  )
85
 
86
+ return response_stream
87
 
88
  except Exception as e:
89
  return f"Error generating response: {str(e)}"
90
 
91
+ def messages_to_prompt(self, messages):
92
+ """
93
+ Converts a list of messages in OpenAI format to a prompt string.
94
+ """
95
+ prompt = ""
96
+ for message in messages:
97
+ if message["role"] == "system":
98
+ prompt += f"<|im_start|>system\n{message['content']}<|im_end|>\n"
99
+ elif message["role"] == "user":
100
+ prompt += f"<|im_start|>user\n{message['content']}<|im_end|>\n"
101
+ elif message["role"] == "assistant":
102
+ prompt += f"<|im_start|>assistant\n{message['content']}<|im_end|>\n"
103
+ prompt += "<|im_start|>assistant\n"
104
+ return prompt
105
+
106
  def create_interface(self):
107
+ # Local storage JavaScript functions (these are strings, not functions)
108
+ load_from_local_storage_js = """
109
+ async () => {
110
+ const savedHistory = localStorage.getItem('xylaria_chat_history');
111
+ return savedHistory ? JSON.parse(savedHistory) : [];
112
+ }
113
+ """
114
+
115
+ save_to_local_storage_js = """
116
+ async (chatHistory) => {
117
+ localStorage.setItem('xylaria_chat_history', JSON.stringify(chatHistory));
118
+ }
119
+ """
120
+
121
+ clear_local_storage_js = """
122
+ async () => {
123
+ localStorage.removeItem('xylaria_chat_history');
124
+ }
125
+ """
126
+
127
  def streaming_response(message, chat_history):
128
+ # Clear input textbox
129
  response_stream = self.get_response(message)
130
 
131
+ # If it's an error, return immediately
132
  if isinstance(response_stream, str):
 
133
  return "", chat_history + [[message, response_stream]]
134
 
135
+ # Prepare for streaming response
136
  full_response = ""
137
  updated_history = chat_history + [[message, ""]]
138
 
139
+ # Streaming output
140
+ for response_text in response_stream:
141
+ full_response += response_text
 
 
 
142
 
143
+ # Update the last message in chat history with partial response
144
+ updated_history[-1][1] = full_response
145
+ yield "", updated_history
146
+
147
+ # Update conversation history
148
  self.conversation_history.append(
149
  {"role": "user", "content": message}
150
  )
 
152
  {"role": "assistant", "content": full_response}
153
  )
154
 
155
+ # Limit conversation history to prevent token overflow
156
  if len(self.conversation_history) > 10:
157
  self.conversation_history = self.conversation_history[-10:]
158
 
159
+ return "", updated_history
 
 
 
 
 
 
160
 
161
+ # Custom CSS for Inter font
 
 
 
 
 
 
 
 
 
162
  custom_css = """
163
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
 
164
  body, .gradio-container {
165
  font-family: 'Inter', sans-serif !important;
 
166
  }
 
 
167
  .chatbot-container .message {
168
  font-family: 'Inter', sans-serif !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  .gradio-container input,
171
  .gradio-container textarea,
172
  .gradio-container button {
173
  font-family: 'Inter', sans-serif !important;
 
 
 
 
 
 
 
 
 
 
 
174
  }
175
  """
176
 
177
+ with gr.Blocks(theme='soft', css=custom_css) as demo:
178
+ # Chat interface with improved styling
179
+ with gr.Column():
180
+ chatbot = gr.Chatbot(
181
+ label="Xylaria 1.4 Senoa",
182
+ height=500,
183
+ show_copy_button=True,
184
+ # type="messages" # Use the 'messages' format
185
+ )
186
+
187
+ # Input row with improved layout
188
+ with gr.Row():
189
+ txt = gr.Textbox(
190
+ show_label=False,
191
+ placeholder="Type your message...",
192
+ container=False,
193
+ scale=4
194
+ )
195
+ btn = gr.Button("Send", scale=1)
196
+
197
+ # Clear history and memory buttons
198
+ clear = gr.Button("Clear Conversation")
199
+ clear_memory = gr.Button("Clear Memory")
200
+
201
+ # Use `gr.State` to manage initial chatbot value and `demo.load` for initialization
202
+ initial_chat_history = gr.State([])
203
+
204
+ demo.load(
205
+ fn=lambda: initial_chat_history.value,
206
+ inputs=None,
207
+ outputs=[chatbot],
208
+ js=load_from_local_storage_js
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  )
210
 
211
+ # Submit functionality with local storage save
212
+ btn.click(
213
  fn=streaming_response,
214
  inputs=[txt, chatbot],
215
  outputs=[txt, chatbot]
216
+ ).then(
217
+ fn=None,
218
+ inputs=[chatbot], # Pass chatbot history to JavaScript
219
+ outputs=None,
220
+ js=save_to_local_storage_js
221
  )
222
+ txt.submit(
223
  fn=streaming_response,
224
  inputs=[txt, chatbot],
225
  outputs=[txt, chatbot]
226
+ ).then(
227
+ fn=None,
228
+ inputs=[chatbot], # Pass chatbot history to JavaScript
229
+ outputs=None,
230
+ js=save_to_local_storage_js
231
  )
232
 
233
+ # Clear conversation history with local storage clear
 
 
 
 
 
 
 
 
 
 
 
 
234
  clear.click(
235
+ fn=lambda: [],
236
  inputs=None,
237
+ outputs=[chatbot]
 
238
  ).then(
239
+ fn=None,
240
  inputs=None,
241
+ outputs=None,
242
+ js=clear_local_storage_js
243
  )
244
 
245
+ # Clear persistent memory and reset conversation with local storage clear
246
  clear_memory.click(
247
  fn=self.reset_conversation,
248
  inputs=None,
249
+ outputs=[chatbot]
 
250
  ).then(
251
+ fn=None,
252
  inputs=None,
253
+ outputs=None,
254
+ js=clear_local_storage_js
255
  )
256
 
257
+ return demo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
 
259
+ # Launch the interface
260
  def main():
261
  chat = XylariaChat()
262
  interface = chat.create_interface()
263
  interface.launch(
264
+ share=True, # Optional: create a public link
265
  debug=True # Show detailed errors
266
  )
267