Reality123b commited on
Commit
a806d95
·
verified ·
1 Parent(s): bd8821d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +200 -76
app.py CHANGED
@@ -1,13 +1,38 @@
1
  import os
2
  import gradio as gr
3
  from huggingface_hub import InferenceClient
 
 
 
4
 
5
  class XylariaChat:
6
  def __init__(self):
7
- # Securely load HuggingFace token
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(
@@ -15,38 +40,70 @@ class XylariaChat:
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 Xylaria 1.4 Senoa, an AI assistant developed by SK MD Saad Amin.
24
- -Youre NOT MADE BY OPENAI OR ANY OTHER INSTITUITON
25
- - respond to image quires with the link of the image
26
- - be as friendly and chatty as possible, use emoji sometimes. """
27
 
28
- def store_information(self, key, value):
29
- """Store important information in persistent memory"""
30
- self.persistent_memory[key] = value
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- def retrieve_information(self, key):
33
- """Retrieve information from persistent memory"""
34
- return self.persistent_memory.get(key)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- def get_response(self, user_input):
37
- # Prepare messages with conversation context and persistent memory
38
  messages = [
39
- {"role": "system", "content": self.system_prompt},
40
- *self.conversation_history,
41
- {"role": "user", "content": user_input}
 
42
  ]
43
 
44
- # Add persistent memory context if available
45
- if self.persistent_memory:
46
- memory_context = "Remembered Information:\n" + "\n".join(
47
- [f"{k}: {v}" for k, v in self.persistent_memory.items()]
48
- )
49
- messages.insert(1, {"role": "system", "content": memory_context})
50
 
51
  # Generate response with streaming
52
  try:
@@ -64,9 +121,79 @@ class XylariaChat:
64
  return f"Error generating response: {str(e)}"
65
 
66
  def create_interface(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  def streaming_response(message, chat_history):
68
- # Clear input textbox
69
- response_stream = self.get_response(message)
 
 
 
 
 
 
70
 
71
  # If it's an error, return immediately
72
  if isinstance(response_stream, str):
@@ -86,59 +213,64 @@ class XylariaChat:
86
  updated_history[-1][1] = full_response
87
  yield "", updated_history
88
 
89
- # Update conversation history
90
- self.conversation_history.append(
91
- {"role": "user", "content": message}
92
- )
93
- self.conversation_history.append(
94
- {"role": "assistant", "content": full_response}
95
- )
96
 
97
- # Limit conversation history to prevent token overflow
98
- if len(self.conversation_history) > 10:
99
- self.conversation_history = self.conversation_history[-10:]
100
-
101
- # Custom CSS for Inter font
102
- custom_css = """
103
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
104
-
105
- body, .gradio-container {
106
- font-family: 'Inter', sans-serif !important;
107
- }
108
-
109
- .chatbot-container .message {
110
- font-family: 'Inter', sans-serif !important;
111
- }
112
-
113
- .gradio-container input,
114
- .gradio-container textarea,
115
- .gradio-container button {
116
- font-family: 'Inter', sans-serif !important;
117
- }
118
- """
119
 
120
  with gr.Blocks(theme='soft', css=custom_css) as demo:
121
- # Chat interface with improved styling
122
- with gr.Column():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  chatbot = gr.Chatbot(
124
  label="Xylaria 1.4 Senoa",
125
  height=500,
126
- show_copy_button=True
 
127
  )
128
 
129
- # Input row with improved layout
130
  with gr.Row():
131
  txt = gr.Textbox(
132
  show_label=False,
133
  placeholder="Type your message...",
134
  container=False,
135
- scale=4
 
136
  )
137
- btn = gr.Button("Send", scale=1)
138
 
139
- # Clear history and memory buttons
140
  clear = gr.Button("Clear Conversation")
141
- clear_memory = gr.Button("Clear Memory")
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
  # Submit functionality with streaming
144
  btn.click(
@@ -159,14 +291,6 @@ class XylariaChat:
159
  outputs=[chatbot],
160
  queue=False
161
  )
162
-
163
- # Clear persistent memory
164
- clear_memory.click(
165
- fn=lambda: None,
166
- inputs=None,
167
- outputs=[],
168
- queue=False
169
- )
170
 
171
  return demo
172
 
 
1
  import os
2
  import gradio as gr
3
  from huggingface_hub import InferenceClient
4
+ import firebase_admin
5
+ from firebase_admin import credentials, firestore, auth
6
+ import uuid
7
 
8
  class XylariaChat:
9
  def __init__(self):
10
+ # Securely load HuggingFace and Firebase tokens from Hugging Face Space Secrets
11
+ self.hf_token = os.environ.get("HF_TOKEN")
12
+ firebase_cred_json = os.environ.get("FIREBASE_SERVICE_ACCOUNT")
13
+
14
+ if not self.hf_token or not firebase_cred_json:
15
+ raise ValueError("Required secrets (HF_TOKEN or FIREBASE_SERVICE_ACCOUNT) not found")
16
+
17
+ # Initialize Firebase
18
+ try:
19
+ # Convert the JSON string to a temporary credentials file
20
+ import tempfile
21
+ import json
22
+
23
+ with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as temp_cred_file:
24
+ json.dump(json.loads(firebase_cred_json), temp_cred_file)
25
+ temp_cred_file.close()
26
+
27
+ firebase_cred = credentials.Certificate(temp_cred_file.name)
28
+ firebase_admin.initialize_app(firebase_cred)
29
+ self.db = firestore.client()
30
+
31
+ # Remove the temporary credentials file
32
+ os.unlink(temp_cred_file.name)
33
+ except Exception as e:
34
+ print(f"Firebase initialization error: {e}")
35
+ self.db = None
36
 
37
  # Initialize the inference client
38
  self.client = InferenceClient(
 
40
  api_key=self.hf_token
41
  )
42
 
43
+ # Initialize conversation history
44
  self.conversation_history = []
 
 
 
 
 
 
 
45
 
46
+ def signup(self, username, email, password):
47
+ """User signup method"""
48
+ try:
49
+ # Create user in Firebase Authentication
50
+ user = auth.create_user(
51
+ email=email,
52
+ password=password,
53
+ display_name=username
54
+ )
55
+
56
+ # Store additional user info in Firestore
57
+ if self.db:
58
+ user_ref = self.db.collection('users').document(user.uid)
59
+ user_ref.set({
60
+ 'username': username,
61
+ 'email': email,
62
+ 'created_at': firestore.SERVER_TIMESTAMP
63
+ })
64
+
65
+ return f"Successfully created account for {username}"
66
+ except Exception as e:
67
+ return f"Signup error: {str(e)}"
68
 
69
+ def login(self, email, password):
70
+ """User login method"""
71
+ try:
72
+ # Authenticate user with Firebase
73
+ user = auth.get_user_by_email(email)
74
+
75
+ # In a real-world scenario, you'd use Firebase Auth's sign-in method
76
+ # This is a simplified version for demonstration
77
+ return f"Login successful for {user.display_name}"
78
+ except Exception as e:
79
+ return f"Login error: {str(e)}"
80
+
81
+ def save_message(self, user_id, message, sender):
82
+ """Save message to Firestore"""
83
+ if not self.db:
84
+ return
85
+
86
+ try:
87
+ messages_ref = self.db.collection('conversations').document(user_id)
88
+ messages_ref.collection('messages').add({
89
+ 'text': message,
90
+ 'sender': sender,
91
+ 'timestamp': firestore.SERVER_TIMESTAMP
92
+ })
93
+ except Exception as e:
94
+ print(f"Error saving message: {e}")
95
 
96
+ def get_response(self, user_input, chat_history):
97
+ # Prepare messages with conversation context
98
  messages = [
99
+ {"role": "system", "content": """You are Xylaria 1.4 Senoa, an AI assistant developed by SK MD Saad Amin.
100
+ - You're NOT MADE BY OPENAI OR ANY OTHER INSTITUTION
101
+ - Be friendly and chatty, use emoji sometimes."""},
102
+ *[{"role": "user" if msg[0] else "assistant", "content": msg[1]} for msg in chat_history]
103
  ]
104
 
105
+ # Add current user input
106
+ messages.append({"role": "user", "content": user_input})
 
 
 
 
107
 
108
  # Generate response with streaming
109
  try:
 
121
  return f"Error generating response: {str(e)}"
122
 
123
  def create_interface(self):
124
+ # Dynamic CSS for OS theme detection
125
+ custom_css = """
126
+ /* OS Theme Detection */
127
+ @media (prefers-color-scheme: dark) {
128
+ .gradio-container {
129
+ background-color: #121212;
130
+ color: #ffffff;
131
+ }
132
+ .chatbot .user-message {
133
+ background-color: #2563eb;
134
+ color: white;
135
+ }
136
+ .chatbot .bot-message {
137
+ background-color: #1f2937;
138
+ color: #f3f4f6;
139
+ box-shadow: 0 1px 3px 0 rgba(255, 255, 255, 0.1);
140
+ }
141
+ .chatbot-input-row {
142
+ background-color: #1f2937;
143
+ color: #f3f4f6;
144
+ }
145
+ .send-button {
146
+ background-color: #2563eb;
147
+ color: white;
148
+ }
149
+ }
150
+
151
+ @media (prefers-color-scheme: light) {
152
+ .gradio-container {
153
+ font-family: 'Inter', sans-serif;
154
+ background-color: #f3f4f6;
155
+ color: #1f2937;
156
+ }
157
+ .chatbot .message {
158
+ max-width: 80%;
159
+ border-radius: 1rem;
160
+ padding: 0.75rem;
161
+ margin-bottom: 0.5rem;
162
+ }
163
+ .chatbot .user-message {
164
+ background-color: #3b82f6;
165
+ color: white;
166
+ align-self: flex-end;
167
+ }
168
+ .chatbot .bot-message {
169
+ background-color: white;
170
+ color: #1f2937;
171
+ align-self: flex-start;
172
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
173
+ }
174
+ .chatbot-input-row {
175
+ background-color: white;
176
+ border-radius: 9999px;
177
+ padding: 0.5rem 1rem;
178
+ }
179
+ .send-button {
180
+ background-color: #3b82f6;
181
+ color: white;
182
+ border-radius: 9999px;
183
+ padding: 0.5rem;
184
+ }
185
+ }
186
+ """
187
+
188
  def streaming_response(message, chat_history):
189
+ # Unique user ID (in a real app, you'd use actual user authentication)
190
+ user_id = str(uuid.uuid4())
191
+
192
+ # Save user message to Firestore
193
+ self.save_message(user_id, message, 'user')
194
+
195
+ # Get AI response stream
196
+ response_stream = self.get_response(message, chat_history)
197
 
198
  # If it's an error, return immediately
199
  if isinstance(response_stream, str):
 
213
  updated_history[-1][1] = full_response
214
  yield "", updated_history
215
 
216
+ # Save bot message to Firestore
217
+ self.save_message(user_id, full_response, 'bot')
 
 
 
 
 
218
 
219
+ return "", updated_history
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
  with gr.Blocks(theme='soft', css=custom_css) as demo:
222
+ # Authentication Tab
223
+ with gr.Tabs():
224
+ with gr.TabItem("Login"):
225
+ with gr.Column():
226
+ login_email = gr.Textbox(label="Email")
227
+ login_password = gr.Textbox(label="Password", type="password")
228
+ login_btn = gr.Button("Login")
229
+ login_output = gr.Textbox(label="Login Status")
230
+
231
+ with gr.TabItem("Signup"):
232
+ with gr.Column():
233
+ signup_username = gr.Textbox(label="Username")
234
+ signup_email = gr.Textbox(label="Email")
235
+ signup_password = gr.Textbox(label="Password", type="password")
236
+ signup_btn = gr.Button("Sign Up")
237
+ signup_output = gr.Textbox(label="Signup Status")
238
+
239
+ # Chat Interface
240
+ with gr.Column(scale=1):
241
  chatbot = gr.Chatbot(
242
  label="Xylaria 1.4 Senoa",
243
  height=500,
244
+ show_copy_button=True,
245
+ likeable=True
246
  )
247
 
248
+ # Input row with minimalist design
249
  with gr.Row():
250
  txt = gr.Textbox(
251
  show_label=False,
252
  placeholder="Type your message...",
253
  container=False,
254
+ scale=4,
255
+ container_css_class="chatbot-input-row"
256
  )
257
+ btn = gr.Button("Send", css_class="send-button", scale=1)
258
 
259
+ # Clear conversation button
260
  clear = gr.Button("Clear Conversation")
261
+
262
+ # Authentication Event Handlers
263
+ login_btn.click(
264
+ fn=self.login,
265
+ inputs=[login_email, login_password],
266
+ outputs=[login_output]
267
+ )
268
+
269
+ signup_btn.click(
270
+ fn=self.signup,
271
+ inputs=[signup_username, signup_email, signup_password],
272
+ outputs=[signup_output]
273
+ )
274
 
275
  # Submit functionality with streaming
276
  btn.click(
 
291
  outputs=[chatbot],
292
  queue=False
293
  )
 
 
 
 
 
 
 
 
294
 
295
  return demo
296