TKM03 commited on
Commit
460a629
·
verified ·
1 Parent(s): db773fb
Files changed (1) hide show
  1. app.py +246 -122
app.py CHANGED
@@ -33,6 +33,16 @@ except Exception as e:
33
  logger.error(f"Failed to initialize InferenceClient: {str(e)}")
34
  raise RuntimeError(f"Failed to initialize the model. Please check your configuration: {str(e)}")
35
 
 
 
 
 
 
 
 
 
 
 
36
  # Conversation tracking
37
  def save_conversation(user_id, conversation):
38
  filename = f"conversations/{user_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
@@ -41,70 +51,75 @@ def save_conversation(user_id, conversation):
41
  json.dump(conversation, f)
42
  logger.info(f"Saved conversation for user {user_id}")
43
 
44
- def generate_response(message, history, system_message, max_tokens, temperature, top_p, user_id):
45
- messages = [{"role": "system", "content": system_message}]
46
-
47
- # Add history to messages
48
- for h in history:
49
- messages.append({"role": "user", "content": h[0]})
50
- messages.append({"role": "assistant", "content": h[1]})
51
-
52
- # Add current message
53
- messages.append({"role": "user", "content": message})
54
-
55
- # Generate response
56
- try:
57
- response = client.text_generation(
58
- prompt=message,
59
- max_new_tokens=max_tokens,
60
- temperature=temperature,
61
- top_p=top_p,
62
- )
63
- return response
64
- except Exception as e:
65
- logger.error(f"Error generating response: {str(e)}")
66
- return f"An error occurred: {str(e)}"
67
-
68
- def chat(message, history, system_message, max_tokens, temperature, top_p, user_id):
69
  if not message.strip():
70
- return history
71
 
72
  logger.info(f"User {user_id} sent message - Length: {len(message)}")
73
 
74
  try:
75
- response = generate_response(
76
- message,
77
- history,
78
- system_message,
79
- max_tokens,
80
- temperature,
81
- top_p,
82
- user_id
83
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- # Format response
86
- new_history = list(history or [])
87
- new_history.append([message, str(response)])
88
 
89
- # Save conversation
90
  conversation_data = {
91
  "timestamp": datetime.now().isoformat(),
92
  "user_id": user_id,
93
- "message": message,
94
- "response": str(response),
95
- "history": new_history
 
 
 
 
 
96
  }
97
  save_conversation(user_id, conversation_data)
98
 
99
- return new_history
 
 
100
 
101
  except Exception as e:
102
- logger.error(f"Error in chat function: {str(e)}")
103
- new_history = list(history or [])
104
- new_history.append([message, f"An error occurred: {str(e)}"])
105
- return new_history
106
 
107
- # Authentication
 
 
 
 
 
 
 
 
 
 
 
108
  def authenticate(username, password):
109
  valid_credentials = {
110
  "admin": {"password": "admin123", "role": "admin"},
@@ -127,8 +142,8 @@ def login(username, password):
127
  )
128
 
129
  time.sleep(0.5)
130
- success, user_id, role = authenticate(username, password)
131
 
 
132
  if success:
133
  return (
134
  gr.update(visible=False),
@@ -146,9 +161,16 @@ def login(username, password):
146
  gr.update(visible=True, value="Invalid username or password")
147
  )
148
 
149
- # CSS
150
  css = """
151
- .container { max-width: 1400px !important; margin: auto; }
 
 
 
 
 
 
 
152
  .setting-panel {
153
  background-color: #f0f4f8;
154
  border-radius: 10px;
@@ -160,12 +182,64 @@ css = """
160
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
161
  background-color: white;
162
  }
163
- .setting-disabled input,
164
- .setting-disabled select,
165
- .setting-disabled textarea,
166
- .setting-disabled button {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  pointer-events: none;
168
- opacity: 0.6;
169
  }
170
  """
171
 
@@ -174,116 +248,166 @@ with gr.Blocks(css=css, title=f"{COMPANY_NAME} AI Assistant") as demo:
174
  user_id = gr.State(None)
175
  user_role = gr.State(None)
176
 
177
- # Login Interface
 
 
 
178
  with gr.Group(visible=True) as login_group:
179
- username = gr.Textbox(label="Username")
180
- password = gr.Textbox(label="Password", type="password")
181
- login_button = gr.Button("Login")
182
- error_message = gr.Markdown(visible=False)
 
 
183
 
184
- # Chat Interface
185
  with gr.Group(visible=False) as chat_group:
186
  with gr.Row():
187
  # Settings Panel
188
- with gr.Column(scale=1):
189
- role_display = gr.Markdown("")
190
- system_message = gr.Textbox(
191
- label="System Message",
192
- value=DEFAULT_SYSTEM_PROMPT,
193
- lines=3
194
- )
195
 
196
- with gr.Group() as settings_group:
 
 
 
 
 
 
 
197
  max_tokens = gr.Slider(
198
  minimum=1,
199
  maximum=2048,
200
  value=512,
201
  step=1,
202
- label="Max Tokens"
 
203
  )
204
  temperature = gr.Slider(
205
  minimum=0.1,
206
  maximum=1.0,
207
  value=0.7,
208
  step=0.1,
209
- label="Temperature"
 
210
  )
211
  top_p = gr.Slider(
212
  minimum=0.1,
213
  maximum=1.0,
214
  value=0.95,
215
  step=0.05,
216
- label="Top P"
 
217
  )
 
 
 
218
 
219
- clear_button = gr.Button("Clear Chat")
220
- logout_button = gr.Button("Logout")
 
 
 
 
221
 
222
- # Chat Panel
223
- with gr.Column(scale=2):
224
- chatbot = gr.Chatbot()
225
- msg = gr.Textbox(
226
- show_label=False,
227
- placeholder="Type your message here..."
228
- )
229
- submit_button = gr.Button("Send")
 
 
230
 
231
- # Event Handlers
232
- def update_interface(role):
233
- settings_class = [] if role == "admin" else ["setting-disabled"]
234
- return (
235
- f"Current Role: {role.title()}",
236
- gr.update(elem_classes=settings_class)
237
- )
238
 
239
- def chat_wrapper(message, history, uid, role):
240
- if not message.strip():
241
- return history
242
-
243
- system_msg = system_message.value
244
- max_tok = max_tokens.value if role == "admin" else 512
245
- temp = temperature.value if role == "admin" else 0.7
246
- tp = top_p.value if role == "admin" else 0.95
247
-
248
- return chat(message, history, system_msg, max_tok, temp, tp, uid)
249
 
250
- # Login flow
251
  login_button.click(
252
  login,
253
  inputs=[username, password],
254
  outputs=[login_group, chat_group, user_id, user_role, error_message]
255
  ).then(
256
- update_interface,
 
 
 
 
257
  inputs=[user_role],
258
- outputs=[role_display, settings_group]
259
  )
260
 
261
- # Chat flow
262
- submit_button.click(
263
- chat_wrapper,
264
- inputs=[msg, chatbot, user_id, user_role],
265
- outputs=[chatbot]
266
- ).then(lambda: "", None, msg)
267
 
 
268
  msg.submit(
269
- chat_wrapper,
270
- inputs=[msg, chatbot, user_id, user_role],
271
  outputs=[chatbot]
272
- ).then(lambda: "", None, msg)
 
 
 
 
 
 
273
 
274
  # Clear chat
275
- clear_button.click(lambda: None, None, chatbot)
276
 
277
- # Logout
278
- logout_button.click(
279
- lambda: (
280
- gr.update(visible=True),
281
- gr.update(visible=False),
282
- None,
283
- None
284
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  outputs=[login_group, chat_group, user_id, user_role]
286
  )
287
 
288
  if __name__ == "__main__":
289
- demo.launch(share=True)
 
 
 
 
 
 
 
 
 
 
33
  logger.error(f"Failed to initialize InferenceClient: {str(e)}")
34
  raise RuntimeError(f"Failed to initialize the model. Please check your configuration: {str(e)}")
35
 
36
+ # Configuration state management
37
+ class ConfigState:
38
+ def __init__(self):
39
+ self.system_message = DEFAULT_SYSTEM_PROMPT
40
+ self.max_tokens = 512
41
+ self.temperature = 0.7
42
+ self.top_p = 0.95
43
+
44
+ config_state = ConfigState()
45
+
46
  # Conversation tracking
47
  def save_conversation(user_id, conversation):
48
  filename = f"conversations/{user_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
 
51
  json.dump(conversation, f)
52
  logger.info(f"Saved conversation for user {user_id}")
53
 
54
+ # Main chat function
55
+ def respond(message, chat_history, user_id):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  if not message.strip():
57
+ return chat_history + [[message, "I'm sorry, I didn't receive any input. How can I help you today?"]]
58
 
59
  logger.info(f"User {user_id} sent message - Length: {len(message)}")
60
 
61
  try:
62
+ messages = [{"role": "system", "content": config_state.system_message}]
63
+
64
+ for user_msg, assistant_msg in chat_history:
65
+ messages.append({"role": "user", "content": user_msg})
66
+ if assistant_msg: # Check if assistant message exists
67
+ messages.append({"role": "assistant", "content": assistant_msg})
68
+
69
+ messages.append({"role": "user", "content": message})
70
+
71
+ start_time = datetime.now()
72
+ full_response = ""
73
+
74
+ for message_chunk in client.chat_completion(
75
+ messages,
76
+ max_tokens=config_state.max_tokens,
77
+ temperature=config_state.temperature,
78
+ top_p=config_state.top_p,
79
+ stream=True,
80
+ ):
81
+ if message_chunk.choices[0].delta.content:
82
+ full_response += message_chunk.choices[0].delta.content
83
+ yield chat_history + [[message, full_response]]
84
 
85
+ time_taken = (datetime.now() - start_time).total_seconds()
86
+ logger.info(f"Response generated for user {user_id} in {time_taken:.2f}s - Length: {len(full_response)}")
 
87
 
 
88
  conversation_data = {
89
  "timestamp": datetime.now().isoformat(),
90
  "user_id": user_id,
91
+ "messages": messages,
92
+ "response": full_response,
93
+ "parameters": {
94
+ "max_tokens": config_state.max_tokens,
95
+ "temperature": config_state.temperature,
96
+ "top_p": config_state.top_p
97
+ },
98
+ "time_taken": time_taken
99
  }
100
  save_conversation(user_id, conversation_data)
101
 
102
+ if not full_response:
103
+ return chat_history
104
+ return chat_history + [[message, full_response]]
105
 
106
  except Exception as e:
107
+ error_msg = f"An error occurred: {str(e)}"
108
+ logger.error(f"Error generating response for user {user_id}: {str(e)}")
109
+ return chat_history + [[message, error_msg]]
 
110
 
111
+ # Configuration update functions
112
+ def update_config(system_msg, max_tok, temp, tp, role):
113
+ if role == "admin":
114
+ config_state.system_message = system_msg
115
+ config_state.max_tokens = max_tok
116
+ config_state.temperature = temp
117
+ config_state.top_p = tp
118
+ logger.info("Configuration updated by admin")
119
+ return "Configuration updated successfully"
120
+ return "Only administrators can update configuration"
121
+
122
+ # Authentication function
123
  def authenticate(username, password):
124
  valid_credentials = {
125
  "admin": {"password": "admin123", "role": "admin"},
 
142
  )
143
 
144
  time.sleep(0.5)
 
145
 
146
+ success, user_id, role = authenticate(username, password)
147
  if success:
148
  return (
149
  gr.update(visible=False),
 
161
  gr.update(visible=True, value="Invalid username or password")
162
  )
163
 
164
+ # CSS styling (same as before)
165
  css = """
166
+ body {
167
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
168
+ background-color: #f9f9f9;
169
+ }
170
+ .container {
171
+ max-width: 1400px !important;
172
+ margin: auto;
173
+ }
174
  .setting-panel {
175
  background-color: #f0f4f8;
176
  border-radius: 10px;
 
182
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
183
  background-color: white;
184
  }
185
+ .company-header {
186
+ background-color: #2c3e50;
187
+ color: white;
188
+ padding: 15px;
189
+ border-radius: 10px 10px 0 0;
190
+ margin-bottom: 15px;
191
+ }
192
+ .footer {
193
+ text-align: center;
194
+ margin-top: 20px;
195
+ color: #666;
196
+ font-size: 0.8em;
197
+ }
198
+ .message-user {
199
+ background-color: #e6f7ff !important;
200
+ border-radius: 15px 15px 0 15px !important;
201
+ }
202
+ .message-bot {
203
+ background-color: #f0f0f0 !important;
204
+ border-radius: 15px 15px 15px 0 !important;
205
+ }
206
+ .login-container {
207
+ max-width: 500px;
208
+ margin: 50px auto;
209
+ padding: 30px;
210
+ background-color: white;
211
+ border-radius: 10px;
212
+ box-shadow: 0 4px 10px rgba(0,0,0,0.1);
213
+ }
214
+ .login-header {
215
+ text-align: center;
216
+ margin-bottom: 30px;
217
+ }
218
+ .error-message {
219
+ color: #e74c3c;
220
+ background-color: #fdedeb;
221
+ padding: 10px;
222
+ border-radius: 5px;
223
+ margin-bottom: 15px;
224
+ font-size: 14px;
225
+ }
226
+ .role-badge {
227
+ font-size: 12px;
228
+ padding: 3px 8px;
229
+ border-radius: 10px;
230
+ margin-left: 10px;
231
+ }
232
+ .admin-badge {
233
+ background-color: #e74c3c;
234
+ color: white;
235
+ }
236
+ .user-badge {
237
+ background-color: #3498db;
238
+ color: white;
239
+ }
240
+ .setting-disabled {
241
+ opacity: 0.5;
242
  pointer-events: none;
 
243
  }
244
  """
245
 
 
248
  user_id = gr.State(None)
249
  user_role = gr.State(None)
250
 
251
+ with gr.Row():
252
+ gr.Markdown(f"<div class='company-header'><h1>{COMPANY_NAME} AI Assistant</h1></div>")
253
+
254
+ # Login Group
255
  with gr.Group(visible=True) as login_group:
256
+ with gr.Column(elem_classes=["login-container"]):
257
+ gr.Markdown(f"<div class='login-header'><h2>Welcome to {COMPANY_NAME}</h2><p>Please log in to continue</p></div>")
258
+ error_message = gr.Markdown(visible=False, value="", elem_classes=["error-message"])
259
+ username = gr.Textbox(label="Username", placeholder="Enter your username")
260
+ password = gr.Textbox(label="Password", type="password", placeholder="Enter your password")
261
+ login_button = gr.Button("Login", variant="primary", size="lg")
262
 
263
+ # Chat Group
264
  with gr.Group(visible=False) as chat_group:
265
  with gr.Row():
266
  # Settings Panel
267
+ with gr.Column(scale=1, elem_classes=["setting-panel"]):
268
+ role_indicator = gr.Markdown("", elem_id="role-indicator")
 
 
 
 
 
269
 
270
+ gr.Markdown("### Configuration")
271
+ with gr.Group() as config_group:
272
+ system_message = gr.Textbox(
273
+ value=DEFAULT_SYSTEM_PROMPT,
274
+ label="System Instructions",
275
+ lines=4,
276
+ interactive=False # Initially disabled
277
+ )
278
  max_tokens = gr.Slider(
279
  minimum=1,
280
  maximum=2048,
281
  value=512,
282
  step=1,
283
+ label="Max Response Length",
284
+ interactive=False
285
  )
286
  temperature = gr.Slider(
287
  minimum=0.1,
288
  maximum=1.0,
289
  value=0.7,
290
  step=0.1,
291
+ label="Temperature",
292
+ interactive=False
293
  )
294
  top_p = gr.Slider(
295
  minimum=0.1,
296
  maximum=1.0,
297
  value=0.95,
298
  step=0.05,
299
+ label="Top-p",
300
+ interactive=False
301
  )
302
+
303
+ update_config_btn = gr.Button("Update Configuration", visible=False)
304
+ config_status = gr.Markdown("")
305
 
306
+ gr.Markdown("### Chat Actions")
307
+ with gr.Row():
308
+ clear_btn = gr.Button("Clear Chat", variant="secondary")
309
+ export_btn = gr.Button("Export Conversation", variant="secondary")
310
+
311
+ logout_btn = gr.Button("Logout", variant="stop")
312
 
313
+ # Chat Interface
314
+ with gr.Column(scale=2, elem_classes=["chat-container"]):
315
+ chatbot = gr.Chatbot(elem_classes=["chatbox"])
316
+ with gr.Row():
317
+ msg = gr.Textbox(
318
+ show_label=False,
319
+ placeholder="Type your message here...",
320
+ container=False
321
+ )
322
+ submit_btn = gr.Button("Send", variant="primary")
323
 
324
+ # Event handlers
325
+ def update_role_display(role):
326
+ badge_class = "admin-badge" if role == "admin" else "user-badge"
327
+ role_display = "Administrator" if role == "admin" else "Standard User"
328
+ return f"<h3>Role: <span class='role-badge {badge_class}'>{role_display}</span></h3>"
 
 
329
 
330
+ def handle_role_permissions(role):
331
+ is_admin = role == "admin"
332
+ return [
333
+ gr.update(interactive=is_admin), # system_message
334
+ gr.update(interactive=is_admin), # max_tokens
335
+ gr.update(interactive=is_admin), # temperature
336
+ gr.update(interactive=is_admin), # top_p
337
+ gr.update(visible=is_admin), # update_config_btn
338
+ ]
 
339
 
340
+ # Login handler
341
  login_button.click(
342
  login,
343
  inputs=[username, password],
344
  outputs=[login_group, chat_group, user_id, user_role, error_message]
345
  ).then(
346
+ update_role_display,
347
+ inputs=[user_role],
348
+ outputs=[role_indicator]
349
+ ).then(
350
+ handle_role_permissions,
351
  inputs=[user_role],
352
+ outputs=[system_message, max_tokens, temperature, top_p, update_config_btn]
353
  )
354
 
355
+ # Configuration update handler
356
+ update_config_btn.click(
357
+ update_config,
358
+ inputs=[system_message, max_tokens, temperature, top_p, user_role],
359
+ outputs=[config_status]
360
+ )
361
 
362
+ # Chat handlers
363
  msg.submit(
364
+ respond,
365
+ inputs=[msg, chatbot, user_id],
366
  outputs=[chatbot]
367
+ ).then(lambda: "", None, [msg])
368
+
369
+ submit_btn.click(
370
+ respond,
371
+ inputs=[msg, chatbot, user_id],
372
+ outputs=[chatbot]
373
+ ).then(lambda: "", None, [msg])
374
 
375
  # Clear chat
376
+ clear_btn.click(lambda: [], None, chatbot, queue=False)
377
 
378
+ # Export conversation
379
+ def export_conversation(chat_history, uid):
380
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
381
+ filename = f"conversations/export_{uid}_{timestamp}.json"
382
+ os.makedirs(os.path.dirname(filename), exist_ok=True)
383
+ with open(filename, 'w') as f:
384
+ json.dump(chat_history, f)
385
+ logger.info(f"Exported conversation for user {uid}")
386
+ return gr.update(value=f"Conversation exported to {filename}", visible=True)
387
+
388
+ export_btn.click(
389
+ export_conversation,
390
+ inputs=[chatbot, user_id],
391
+ outputs=[error_message]
392
+ )
393
+
394
+ # Logout handler
395
+ def logout():
396
+ return gr.update(visible=True), gr.update(visible=False), None, None
397
+
398
+ logout_btn.click(
399
+ logout,
400
  outputs=[login_group, chat_group, user_id, user_role]
401
  )
402
 
403
  if __name__ == "__main__":
404
+ if os.environ.get("PRODUCTION", "false").lower() == "true":
405
+ demo.launch(
406
+ server_name="0.0.0.0",
407
+ server_port=int(os.environ.get("PORT", 7860)),
408
+ share=False,
409
+ show_error=False,
410
+ auth=None,
411
+ )
412
+ else:
413
+ demo.launch(show_error=True)