Abhaykoul commited on
Commit
7cbe8ed
·
verified ·
1 Parent(s): a338ea6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +632 -257
app.py CHANGED
@@ -1,7 +1,12 @@
1
  import gradio as gr
2
  import torch
3
- from transformers import AutoModelForCausalLM, AutoTokenizer
 
 
 
4
  import spaces
 
 
5
  import re
6
 
7
  # Model configuration
@@ -32,12 +37,42 @@ def load_model():
32
 
33
  print("Model loaded successfully!")
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  def format_thinking_text(text):
36
- """Format text to properly display <think> tags in Gradio with blue border styling like HelpingAI"""
37
  if not text:
38
  return text
39
 
40
- # More sophisticated formatting for thinking blocks with blue styling
41
  formatted_text = text
42
 
43
  # Handle thinking blocks with proper HTML-like styling for Gradio
@@ -57,103 +92,151 @@ def format_thinking_text(text):
57
  </div>
58
  </div>
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  '''
61
 
62
  formatted_text = re.sub(thinking_pattern, replace_thinking_block, formatted_text, flags=re.DOTALL)
 
63
 
64
  # Clean up any remaining raw tags that might not have been caught
65
  formatted_text = re.sub(r'</?think>', '', formatted_text)
 
66
 
67
  return formatted_text.strip()
68
 
69
  @spaces.GPU()
70
  def generate_response(message, history, max_tokens, temperature, top_p):
71
- """Generate streaming response without threading"""
72
  global model, tokenizer
73
-
74
  if model is None or tokenizer is None:
75
  yield "Model is still loading. Please wait..."
76
  return
77
-
78
  # Prepare conversation history
79
  messages = []
80
  for user_msg, assistant_msg in history:
81
  messages.append({"role": "user", "content": user_msg})
82
  if assistant_msg:
83
  messages.append({"role": "assistant", "content": assistant_msg})
84
-
85
  # Add current message
86
  messages.append({"role": "user", "content": message})
87
-
88
  # Apply chat template
89
  text = tokenizer.apply_chat_template(
90
  messages,
91
  tokenize=False,
92
  add_generation_prompt=True
93
  )
94
-
95
  # Tokenize input
96
  model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
97
-
98
- try:
99
- with torch.no_grad():
100
- # Use transformers streaming with custom approach
101
- generated_text = ""
102
- current_input_ids = model_inputs["input_ids"]
103
- current_attention_mask = model_inputs["attention_mask"]
104
-
105
- for _ in range(max_tokens):
106
- # Generate next token
107
- outputs = model(
108
- input_ids=current_input_ids,
109
- attention_mask=current_attention_mask,
110
- use_cache=True
111
- )
112
-
113
- # Get logits for the last token
114
- logits = outputs.logits[0, -1, :]
115
-
116
- # Apply temperature
117
- if temperature != 1.0:
118
- logits = logits / temperature
119
-
120
- # Apply top-p sampling
121
- if top_p < 1.0:
122
- sorted_logits, sorted_indices = torch.sort(logits, descending=True)
123
- cumulative_probs = torch.cumsum(torch.softmax(sorted_logits, dim=-1), dim=-1)
124
- sorted_indices_to_remove = cumulative_probs > top_p
125
- sorted_indices_to_remove[1:] = sorted_indices_to_remove[:-1].clone()
126
- sorted_indices_to_remove[0] = 0
127
- indices_to_remove = sorted_indices[sorted_indices_to_remove]
128
- logits[indices_to_remove] = float('-inf')
129
-
130
- # Sample next token
131
- probs = torch.softmax(logits, dim=-1)
132
- next_token = torch.multinomial(probs, num_samples=1)
133
-
134
- # Check for EOS token
135
- if next_token.item() == tokenizer.eos_token_id:
136
- break
137
-
138
- # Decode the new token (preserve special tokens like <think>)
139
- new_token_text = tokenizer.decode(next_token, skip_special_tokens=False)
140
- generated_text += new_token_text
141
-
142
- # Format and yield the current text
143
- formatted_text = format_thinking_text(generated_text)
144
- yield formatted_text
145
-
146
- # Update inputs for next iteration
147
- current_input_ids = torch.cat([current_input_ids, next_token.unsqueeze(0)], dim=-1)
148
- current_attention_mask = torch.cat([current_attention_mask, torch.ones((1, 1), device=model.device)], dim=-1)
149
-
150
- except Exception as e:
151
- yield f"Error generating response: {str(e)}"
152
- return
153
-
154
  # Final yield with complete formatted text
155
- final_text = format_thinking_text(generated_text) if generated_text else "No response generated."
156
- yield final_text
 
 
 
157
 
158
  def chat_interface(message, history, max_tokens, temperature, top_p):
159
  """Main chat interface with improved streaming"""
@@ -174,209 +257,508 @@ def chat_interface(message, history, max_tokens, temperature, top_p):
174
  print("Initializing model...")
175
  load_model()
176
 
177
- # Custom CSS for better styling and thinking blocks
178
  custom_css = """
179
- /* Main chatbot styling */
180
- .chatbot {
181
- font-size: 14px;
182
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 
 
 
 
183
  }
184
 
185
- /* Enhanced thinking block styling - now handled via inline HTML */
186
- .thinking-block {
187
- background: linear-gradient(135deg, #f0f8ff 0%, #e6f3ff 100%);
188
- border-left: 4px solid #4a90e2;
189
- border-radius: 8px;
190
- padding: 12px 16px;
191
- margin: 12px 0;
192
- font-family: 'Segoe UI', sans-serif;
193
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
194
- position: relative;
195
  }
196
 
197
- /* Support for HTML content in chatbot */
198
- .chatbot .message {
199
- overflow: visible;
 
 
 
 
 
 
 
 
200
  }
201
 
202
- .chatbot .message div {
203
- max-width: none;
 
 
 
204
  }
205
 
206
- /* Message styling */
207
- .message {
208
- padding: 10px 14px;
209
- margin: 6px 0;
210
- border-radius: 12px;
211
- line-height: 1.5;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  }
213
 
214
- .user-message {
215
- background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
 
 
216
  margin-left: 15%;
217
- border-bottom-right-radius: 4px;
 
218
  }
219
 
220
- .assistant-message {
221
- background: linear-gradient(135deg, #f5f5f5 0%, #eeeeee 100%);
 
 
222
  margin-right: 15%;
223
- border-bottom-left-radius: 4px;
 
224
  }
225
 
226
- /* Code block styling */
227
- pre {
228
- background-color: #f8f9fa;
229
- border: 1px solid #e9ecef;
230
- border-radius: 6px;
231
- padding: 12px;
232
- overflow-x: auto;
233
- font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
234
- font-size: 13px;
235
- line-height: 1.4;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  }
237
 
238
  /* Button styling */
239
  .gradio-button {
240
- border-radius: 8px;
241
- font-weight: 500;
242
- transition: all 0.2s ease;
 
 
 
 
 
 
 
 
243
  }
244
 
245
- .gradio-button:hover {
246
- transform: translateY(-1px);
247
- box-shadow: 0 4px 8px rgba(0,0,0,0.15);
 
248
  }
249
 
250
- /* Input styling */
251
- .gradio-textbox {
252
- border-radius: 8px;
253
- border: 2px solid #e0e0e0;
254
- transition: border-color 0.2s ease;
255
  }
256
 
257
- .gradio-textbox:focus {
258
- border-color: #4a90e2;
259
- box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
 
 
 
 
 
 
 
260
  }
261
 
262
  /* Slider styling */
263
  .gradio-slider {
264
- margin: 8px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  }
266
 
267
  /* Examples styling */
268
  .gradio-examples {
269
- margin-top: 16px;
 
 
 
 
 
270
  }
271
 
272
  .gradio-examples .gradio-button {
273
- background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
274
- border: 1px solid #dee2e6;
275
- color: #495057;
276
  font-size: 13px;
277
- padding: 8px 12px;
 
 
 
 
278
  }
279
 
280
  .gradio-examples .gradio-button:hover {
281
- background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
282
- color: #212529;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  }
284
  """
285
 
286
- # Create Gradio interface
287
  with gr.Blocks(
288
- title="🤖 Dhanishtha-2.0-preview Chat",
289
- theme=gr.themes.Soft(),
290
- css=custom_css
 
 
 
 
 
 
 
291
  ) as demo:
292
- gr.Markdown(
293
- """
294
- # 🤖 Dhanishtha-2.0-preview Chat
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
 
296
- Chat with the **HelpingAI/Dhanishtha-2.0-preview** model - The world's first LLM designed to think between responses!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
 
298
- ### Key Features:
299
- - 🧠 **Multi-step Reasoning**: Unlike other LLMs that think once, Dhanishtha can think, rethink, self-evaluate, and refine using multiple `<think>` blocks
300
- - 🔄 **Iterative Thinking**: Watch the model's thought process unfold in real-time
301
- - 💡 **Enhanced Problem Solving**: Better reasoning capabilities through structured thinking
 
 
 
 
 
302
 
303
- **Note**: The `<think>` blocks show the model's internal reasoning process and will be displayed in a formatted way below.
304
- """
305
- )
306
-
307
- with gr.Row():
308
- with gr.Column(scale=4):
309
- chatbot = gr.Chatbot(
310
- [],
311
- elem_id="chatbot",
312
- bubble_full_width=False,
313
- height=600,
314
- show_copy_button=True,
315
- show_share_button=True,
316
- avatar_images=("👤", "🤖"),
317
- render_markdown=True,
318
- sanitize_html=False, # Allow HTML for thinking blocks
319
- latex_delimiters=[
320
- {"left": "$$", "right": "$$", "display": True},
321
- {"left": "$", "right": "$", "display": False}
322
- ]
323
- )
324
-
325
- with gr.Row():
326
- msg = gr.Textbox(
327
- container=False,
328
- placeholder="Ask me anything! I'll show you my thinking process...",
329
- label="Message",
330
- autofocus=True,
331
- scale=8,
332
- lines=1,
333
- max_lines=5
334
  )
335
- send_btn = gr.Button("🚀 Send", variant="primary", scale=1, size="lg")
336
-
337
- with gr.Column(scale=1, min_width=300):
338
- gr.Markdown("### ⚙️ Generation Parameters")
339
-
340
- max_tokens = gr.Slider(
341
- minimum=50,
342
- maximum=8192,
343
- value=2048,
344
- step=50,
345
- label="🎯 Max Tokens",
346
- info="Maximum number of tokens to generate"
347
- )
348
-
349
- temperature = gr.Slider(
350
- minimum=0.1,
351
- maximum=2.0,
352
- value=0.7,
353
- step=0.1,
354
- label="🌡️ Temperature",
355
- info="Higher = more creative, Lower = more focused"
356
- )
357
-
358
- top_p = gr.Slider(
359
- minimum=0.1,
360
- maximum=1.0,
361
- value=0.9,
362
- step=0.05,
363
- label="🎲 Top-p",
364
- info="Nucleus sampling threshold"
365
- )
366
-
367
- with gr.Row():
368
- clear_btn = gr.Button("🗑️ Clear Chat", variant="secondary", scale=1)
369
- stop_btn = gr.Button("⏹️ Stop", variant="stop", scale=1)
370
-
371
- gr.Markdown("### 📊 Model Info")
372
- gr.Markdown(
373
- """
374
- **Model**: HelpingAI/Dhanishtha-2.0-preview
375
- **Type**: Reasoning LLM with thinking blocks
376
- **Features**: Multi-step reasoning, self-evaluation
377
- """
378
- )
379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  # Event handlers
381
  def clear_chat():
382
  """Clear the chat history"""
@@ -406,50 +788,43 @@ with gr.Blocks(
406
  show_progress=False
407
  )
408
 
409
- # Example prompts section
410
- with gr.Row():
411
- gr.Examples(
412
- examples=[
413
- ["Hello! Can you introduce yourself and show me how you think?"],
414
- ["Solve this step by step: What is 15% of 240?"],
415
- ["Explain quantum entanglement in simple terms"],
416
- ["Write a short Python function to find the factorial of a number"],
417
- ["What are the pros and cons of renewable energy?"],
418
- ["Help me understand the difference between AI and machine learning"],
419
- ["Create a haiku about artificial intelligence"],
420
- ["Explain why the sky is blue using physics principles"]
421
- ],
422
- inputs=msg,
423
- label="💡 Example Prompts - Try these to see the thinking process!",
424
- examples_per_page=4
425
- )
426
-
427
- # Footer with information
428
- gr.Markdown(
429
- """
430
- ---
431
- ### 🔧 Technical Details
432
- - **Model**: HelpingAI/Dhanishtha-2.0-preview
433
- - **Framework**: Transformers + Gradio
434
- - **Features**: Real-time streaming, thinking process visualization, custom sampling
435
- - **Reasoning**: Multi-step thinking with `<think>` blocks for transparent AI reasoning
436
-
437
- **Note**: This interface streams responses token by token and formats thinking blocks for better readability.
438
- The model's internal reasoning process is displayed in formatted code blocks.
439
-
440
- ---
441
- *Built with ❤️ using Gradio and Transformers*
442
- """
443
- )
444
 
445
  if __name__ == "__main__":
446
  demo.queue(
447
- max_size=20,
448
- default_concurrency_limit=1
449
  ).launch(
450
  server_name="0.0.0.0",
451
  server_port=7860,
452
  share=False,
453
  show_error=True,
454
- quiet=False
 
 
 
455
  )
 
1
  import gradio as gr
2
  import torch
3
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer
4
+ import threading
5
+ import queue
6
+ import time
7
  import spaces
8
+ import sys
9
+ from io import StringIO
10
  import re
11
 
12
  # Model configuration
 
37
 
38
  print("Model loaded successfully!")
39
 
40
+ class StreamCapture:
41
+ """Capture streaming output from TextStreamer"""
42
+ def __init__(self):
43
+ self.text_queue = queue.Queue()
44
+ self.captured_text = ""
45
+
46
+ def write(self, text):
47
+ """Capture written text"""
48
+ if text and text.strip():
49
+ self.captured_text += text
50
+ self.text_queue.put(text)
51
+ return len(text)
52
+
53
+ def flush(self):
54
+ """Flush method for compatibility"""
55
+ pass
56
+
57
+ def get_text(self):
58
+ """Get all captured text"""
59
+ return self.captured_text
60
+
61
+ def reset(self):
62
+ """Reset the capture"""
63
+ self.captured_text = ""
64
+ while not self.text_queue.empty():
65
+ try:
66
+ self.text_queue.get_nowait()
67
+ except queue.Empty:
68
+ break
69
+
70
  def format_thinking_text(text):
71
+ """Format text to properly display <think> and <ser> tags in Gradio with styled borders"""
72
  if not text:
73
  return text
74
 
75
+ # More sophisticated formatting for thinking and SER blocks
76
  formatted_text = text
77
 
78
  # Handle thinking blocks with proper HTML-like styling for Gradio
 
92
  </div>
93
  </div>
94
 
95
+ '''
96
+
97
+ # Handle SER blocks with purple/violet styling and structured formatting
98
+ ser_pattern = r'<ser>(.*?)</ser>'
99
+
100
+ def replace_ser_block(match):
101
+ ser_content = match.group(1).strip()
102
+
103
+ # Parse structured SER content if it follows the pattern
104
+ ser_lines = ser_content.split('\n')
105
+ formatted_content = []
106
+
107
+ for line in ser_lines:
108
+ line = line.strip()
109
+ if not line:
110
+ continue
111
+
112
+ # Check if line has the "Key ==> Value" pattern
113
+ if ' ==> ' in line:
114
+ parts = line.split(' ==> ', 1)
115
+ if len(parts) == 2:
116
+ key = parts[0].strip()
117
+ value = parts[1].strip()
118
+ formatted_content.append(f'<div style="margin: 8px 0;"><strong style="color: #8e44ad;">{key}:</strong> <span style="color: #2c3e50;">{value}</span></div>')
119
+ else:
120
+ formatted_content.append(f'<div style="margin: 4px 0; color: #2c3e50;">{line}</div>')
121
+ else:
122
+ formatted_content.append(f'<div style="margin: 4px 0; color: #2c3e50;">{line}</div>')
123
+
124
+ if not formatted_content:
125
+ formatted_content = [f'<div style="color: #2c3e50; line-height: 1.6;">{ser_content}</div>']
126
+
127
+ content_html = ''.join(formatted_content)
128
+
129
+ # Use HTML div with inline CSS for purple border styling for SER
130
+ return f'''
131
+
132
+ <div style="border-left: 4px solid #8e44ad; background: linear-gradient(135deg, #f8f4ff 0%, #ede7f6 100%); padding: 16px 20px; margin: 16px 0; border-radius: 12px; font-family: 'Segoe UI', sans-serif; box-shadow: 0 2px 8px rgba(142, 68, 173, 0.15); border: 1px solid rgba(142, 68, 173, 0.2);">
133
+ <div style="color: #8e44ad; font-weight: 600; margin-bottom: 10px; display: flex; align-items: center; font-size: 14px;">
134
+ <span style="margin-right: 8px;">💜</span> SER (Structured Emotional Reasoning)
135
+ </div>
136
+ <div style="line-height: 1.6; font-size: 14px;">
137
+ {content_html}
138
+ </div>
139
+ </div>
140
+
141
  '''
142
 
143
  formatted_text = re.sub(thinking_pattern, replace_thinking_block, formatted_text, flags=re.DOTALL)
144
+ formatted_text = re.sub(ser_pattern, replace_ser_block, formatted_text, flags=re.DOTALL)
145
 
146
  # Clean up any remaining raw tags that might not have been caught
147
  formatted_text = re.sub(r'</?think>', '', formatted_text)
148
+ formatted_text = re.sub(r'</?ser>', '', formatted_text)
149
 
150
  return formatted_text.strip()
151
 
152
  @spaces.GPU()
153
  def generate_response(message, history, max_tokens, temperature, top_p):
154
+ """Generate streaming response with improved TextStreamer"""
155
  global model, tokenizer
156
+
157
  if model is None or tokenizer is None:
158
  yield "Model is still loading. Please wait..."
159
  return
160
+
161
  # Prepare conversation history
162
  messages = []
163
  for user_msg, assistant_msg in history:
164
  messages.append({"role": "user", "content": user_msg})
165
  if assistant_msg:
166
  messages.append({"role": "assistant", "content": assistant_msg})
167
+
168
  # Add current message
169
  messages.append({"role": "user", "content": message})
170
+
171
  # Apply chat template
172
  text = tokenizer.apply_chat_template(
173
  messages,
174
  tokenize=False,
175
  add_generation_prompt=True
176
  )
177
+
178
  # Tokenize input
179
  model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
180
+
181
+ # Create stream capture
182
+ stream_capture = StreamCapture()
183
+
184
+ # Create TextStreamer with our capture - don't skip special tokens to preserve <think> and <ser>
185
+ streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=False)
186
+
187
+ # Temporarily redirect the streamer's output
188
+ original_stdout = sys.stdout
189
+
190
+ # Generation parameters
191
+ generation_kwargs = {
192
+ **model_inputs,
193
+ "max_new_tokens": max_tokens,
194
+ "temperature": temperature,
195
+ "top_p": top_p,
196
+ "do_sample": True,
197
+ "pad_token_id": tokenizer.eos_token_id,
198
+ "streamer": streamer,
199
+ }
200
+
201
+ # Start generation in a separate thread
202
+ def generate():
203
+ try:
204
+ # Redirect stdout to capture streamer output
205
+ sys.stdout = stream_capture
206
+ with torch.no_grad():
207
+ model.generate(**generation_kwargs)
208
+ except Exception as e:
209
+ stream_capture.text_queue.put(f"Error: {str(e)}")
210
+ finally:
211
+ # Restore stdout
212
+ sys.stdout = original_stdout
213
+ stream_capture.text_queue.put(None) # Signal end
214
+
215
+ thread = threading.Thread(target=generate)
216
+ thread.start()
217
+
218
+ # Stream the results with formatting
219
+ generated_text = ""
220
+ while True:
221
+ try:
222
+ new_text = stream_capture.text_queue.get(timeout=30)
223
+ if new_text is None:
224
+ break
225
+ generated_text += new_text
226
+ # Format and yield the current text with <think> and <ser> blocks
227
+ formatted_text = format_thinking_text(generated_text)
228
+ yield formatted_text
229
+ except queue.Empty:
230
+ break
231
+
232
+ thread.join(timeout=1)
233
+
 
 
 
234
  # Final yield with complete formatted text
235
+ if generated_text:
236
+ final_text = format_thinking_text(generated_text)
237
+ yield final_text
238
+ else:
239
+ yield "No response generated."
240
 
241
  def chat_interface(message, history, max_tokens, temperature, top_p):
242
  """Main chat interface with improved streaming"""
 
257
  print("Initializing model...")
258
  load_model()
259
 
260
+ # Custom CSS for modern, professional styling
261
  custom_css = """
262
+ /* Import Google Fonts */
263
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');
264
+
265
+ /* Global styling */
266
+ .gradio-container {
267
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
268
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
269
+ min-height: 100vh;
270
  }
271
 
272
+ /* Main container styling */
273
+ .main {
274
+ background: rgba(255, 255, 255, 0.95);
275
+ backdrop-filter: blur(20px);
276
+ border-radius: 24px;
277
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
278
+ margin: 20px;
279
+ padding: 32px;
280
+ border: 1px solid rgba(255, 255, 255, 0.2);
 
281
  }
282
 
283
+ /* Header styling */
284
+ .gradio-markdown h1 {
285
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
286
+ -webkit-background-clip: text;
287
+ -webkit-text-fill-color: transparent;
288
+ background-clip: text;
289
+ font-weight: 700;
290
+ font-size: 3rem;
291
+ text-align: center;
292
+ margin-bottom: 1rem;
293
+ text-shadow: 0 2px 4px rgba(0,0,0,0.1);
294
  }
295
 
296
+ .gradio-markdown h3 {
297
+ color: #4a5568;
298
+ font-weight: 600;
299
+ margin-top: 1.5rem;
300
+ margin-bottom: 0.5rem;
301
  }
302
 
303
+ /* Chatbot styling */
304
+ .chatbot {
305
+ font-size: 15px;
306
+ font-family: 'Inter', sans-serif;
307
+ background: #ffffff;
308
+ border-radius: 20px;
309
+ border: 1px solid #e2e8f0;
310
+ box-shadow: 0 8px 32px rgba(0,0,0,0.08);
311
+ overflow: hidden;
312
+ }
313
+
314
+ .chatbot .message {
315
+ padding: 16px 20px;
316
+ margin: 8px 12px;
317
+ border-radius: 16px;
318
+ line-height: 1.6;
319
+ box-shadow: 0 2px 8px rgba(0,0,0,0.06);
320
+ transition: all 0.2s ease;
321
+ }
322
+
323
+ .chatbot .message:hover {
324
+ transform: translateY(-1px);
325
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
326
  }
327
 
328
+ /* User message styling */
329
+ .chatbot .message.user {
330
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
331
+ color: white;
332
  margin-left: 15%;
333
+ border-bottom-right-radius: 6px;
334
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3);
335
  }
336
 
337
+ /* Assistant message styling */
338
+ .chatbot .message.bot {
339
+ background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
340
+ color: #2d3748;
341
  margin-right: 15%;
342
+ border-bottom-left-radius: 6px;
343
+ border: 1px solid #e2e8f0;
344
  }
345
 
346
+ /* Enhanced thinking and SER block styling */
347
+ .thinking-block, .ser-block {
348
+ border-radius: 12px;
349
+ padding: 16px 20px;
350
+ margin: 16px 0;
351
+ font-family: 'Inter', sans-serif;
352
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08);
353
+ position: relative;
354
+ overflow: hidden;
355
+ }
356
+
357
+ .thinking-block::before, .ser-block::before {
358
+ content: '';
359
+ position: absolute;
360
+ top: 0;
361
+ left: 0;
362
+ right: 0;
363
+ height: 3px;
364
+ background: linear-gradient(90deg, #4a90e2, #357abd);
365
+ }
366
+
367
+ /* Input styling */
368
+ .gradio-textbox {
369
+ border-radius: 16px;
370
+ border: 2px solid #e2e8f0;
371
+ transition: all 0.3s ease;
372
+ font-family: 'Inter', sans-serif;
373
+ padding: 16px 20px;
374
+ font-size: 15px;
375
+ background: #ffffff;
376
+ box-shadow: 0 2px 8px rgba(0,0,0,0.04);
377
+ }
378
+
379
+ .gradio-textbox:focus {
380
+ border-color: #667eea;
381
+ box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
382
+ outline: none;
383
  }
384
 
385
  /* Button styling */
386
  .gradio-button {
387
+ border-radius: 14px;
388
+ font-weight: 600;
389
+ font-family: 'Inter', sans-serif;
390
+ transition: all 0.3s ease;
391
+ padding: 12px 24px;
392
+ font-size: 14px;
393
+ letter-spacing: 0.5px;
394
+ border: none;
395
+ cursor: pointer;
396
+ position: relative;
397
+ overflow: hidden;
398
  }
399
 
400
+ .gradio-button.primary {
401
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
402
+ color: white;
403
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3);
404
  }
405
 
406
+ .gradio-button.primary:hover {
407
+ transform: translateY(-2px);
408
+ box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
 
 
409
  }
410
 
411
+ .gradio-button.secondary {
412
+ background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
413
+ color: #4a5568;
414
+ border: 1px solid #e2e8f0;
415
+ }
416
+
417
+ .gradio-button.secondary:hover {
418
+ background: linear-gradient(135deg, #edf2f7 0%, #e2e8f0 100%);
419
+ transform: translateY(-1px);
420
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
421
  }
422
 
423
  /* Slider styling */
424
  .gradio-slider {
425
+ margin: 12px 0;
426
+ }
427
+
428
+ .gradio-slider input[type="range"] {
429
+ -webkit-appearance: none;
430
+ height: 6px;
431
+ border-radius: 3px;
432
+ background: linear-gradient(135deg, #e2e8f0 0%, #cbd5e0 100%);
433
+ outline: none;
434
+ }
435
+
436
+ .gradio-slider input[type="range"]::-webkit-slider-thumb {
437
+ -webkit-appearance: none;
438
+ appearance: none;
439
+ width: 20px;
440
+ height: 20px;
441
+ border-radius: 50%;
442
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
443
+ cursor: pointer;
444
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
445
+ transition: all 0.2s ease;
446
+ }
447
+
448
+ .gradio-slider input[type="range"]::-webkit-slider-thumb:hover {
449
+ transform: scale(1.1);
450
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
451
  }
452
 
453
  /* Examples styling */
454
  .gradio-examples {
455
+ margin-top: 24px;
456
+ background: rgba(255, 255, 255, 0.7);
457
+ backdrop-filter: blur(10px);
458
+ border-radius: 16px;
459
+ padding: 20px;
460
+ border: 1px solid rgba(255, 255, 255, 0.2);
461
  }
462
 
463
  .gradio-examples .gradio-button {
464
+ background: rgba(255, 255, 255, 0.9);
465
+ border: 1px solid #e2e8f0;
466
+ color: #4a5568;
467
  font-size: 13px;
468
+ padding: 12px 16px;
469
+ margin: 4px;
470
+ border-radius: 12px;
471
+ transition: all 0.2s ease;
472
+ backdrop-filter: blur(10px);
473
  }
474
 
475
  .gradio-examples .gradio-button:hover {
476
+ background: rgba(255, 255, 255, 1);
477
+ color: #2d3748;
478
+ transform: translateY(-1px);
479
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
480
+ }
481
+
482
+ /* Code block styling */
483
+ pre {
484
+ background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%);
485
+ color: #e2e8f0;
486
+ border-radius: 12px;
487
+ padding: 20px;
488
+ overflow-x: auto;
489
+ font-family: 'JetBrains Mono', 'Consolas', 'Monaco', monospace;
490
+ font-size: 14px;
491
+ line-height: 1.5;
492
+ box-shadow: 0 4px 16px rgba(0,0,0,0.1);
493
+ border: 1px solid #4a5568;
494
+ }
495
+
496
+ /* Sidebar styling */
497
+ .gradio-column {
498
+ background: rgba(255, 255, 255, 0.8);
499
+ backdrop-filter: blur(10px);
500
+ border-radius: 16px;
501
+ padding: 20px;
502
+ margin: 8px;
503
+ border: 1px solid rgba(255, 255, 255, 0.2);
504
+ box-shadow: 0 4px 16px rgba(0,0,0,0.05);
505
+ }
506
+
507
+ /* Footer styling */
508
+ .gradio-markdown hr {
509
+ border: none;
510
+ height: 1px;
511
+ background: linear-gradient(90deg, transparent, #e2e8f0, transparent);
512
+ margin: 2rem 0;
513
+ }
514
+
515
+ /* Responsive design */
516
+ @media (max-width: 768px) {
517
+ .main {
518
+ margin: 10px;
519
+ padding: 20px;
520
+ border-radius: 16px;
521
+ }
522
+
523
+ .gradio-markdown h1 {
524
+ font-size: 2rem;
525
+ }
526
+
527
+ .chatbot .message.user,
528
+ .chatbot .message.bot {
529
+ margin-left: 5%;
530
+ margin-right: 5%;
531
+ }
532
+ }
533
+
534
+ /* Loading animation */
535
+ .loading {
536
+ display: inline-block;
537
+ width: 20px;
538
+ height: 20px;
539
+ border: 3px solid rgba(102, 126, 234, 0.3);
540
+ border-radius: 50%;
541
+ border-top-color: #667eea;
542
+ animation: spin 1s ease-in-out infinite;
543
+ }
544
+
545
+ @keyframes spin {
546
+ to { transform: rotate(360deg); }
547
+ }
548
+
549
+ /* Scroll styling */
550
+ ::-webkit-scrollbar {
551
+ width: 8px;
552
+ }
553
+
554
+ ::-webkit-scrollbar-track {
555
+ background: #f1f1f1;
556
+ border-radius: 4px;
557
+ }
558
+
559
+ ::-webkit-scrollbar-thumb {
560
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
561
+ border-radius: 4px;
562
+ }
563
+
564
+ ::-webkit-scrollbar-thumb:hover {
565
+ background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
566
  }
567
  """
568
 
569
+ # Create Gradio interface with modern design
570
  with gr.Blocks(
571
+ title="🤖 Dhanishtha-2.0-preview | Advanced Reasoning AI",
572
+ theme=gr.themes.Soft(
573
+ primary_hue="blue",
574
+ secondary_hue="purple",
575
+ neutral_hue="slate",
576
+ font=gr.themes.GoogleFont("Inter"),
577
+ font_mono=gr.themes.GoogleFont("JetBrains Mono")
578
+ ),
579
+ css=custom_css,
580
+ head="<link rel='icon' href='🤖' type='image/svg+xml'>"
581
  ) as demo:
582
+ # Header Section
583
+ gr.HTML("""
584
+ <div style="text-align: center; padding: 2rem 0; background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); border-radius: 20px; margin-bottom: 2rem; border: 1px solid rgba(102, 126, 234, 0.2);">
585
+ <h1 style="margin: 0; font-size: 3.5rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 800;">
586
+ 🤖 Dhanishtha-2.0-preview
587
+ </h1>
588
+ <p style="font-size: 1.2rem; color: #64748b; margin: 1rem 0; font-weight: 500;">
589
+ Advanced Reasoning AI with Transparent Thinking Process
590
+ </p>
591
+ <div style="display: flex; justify-content: center; gap: 2rem; flex-wrap: wrap; margin-top: 1.5rem;">
592
+ <div style="background: rgba(74, 144, 226, 0.1); padding: 0.8rem 1.5rem; border-radius: 12px; border: 1px solid rgba(74, 144, 226, 0.2);">
593
+ <span style="color: #4a90e2; font-weight: 600;">🧠 Multi-step Reasoning</span>
594
+ </div>
595
+ <div style="background: rgba(142, 68, 173, 0.1); padding: 0.8rem 1.5rem; border-radius: 12px; border: 1px solid rgba(142, 68, 173, 0.2);">
596
+ <span style="color: #8e44ad; font-weight: 600;">💜 Emotional Intelligence</span>
597
+ </div>
598
+ <div style="background: rgba(34, 197, 94, 0.1); padding: 0.8rem 1.5rem; border-radius: 12px; border: 1px solid rgba(34, 197, 94, 0.2);">
599
+ <span style="color: #22c55e; font-weight: 600;">🔄 Real-time Streaming</span>
600
+ </div>
601
+ </div>
602
+ </div>
603
+ """)
604
+
605
+ # Main Chat Interface
606
+ with gr.Row(equal_height=True):
607
+ with gr.Column(scale=4, min_width=600):
608
+ # Chat Area
609
+ with gr.Group():
610
+ chatbot = gr.Chatbot(
611
+ [],
612
+ elem_id="chatbot",
613
+ bubble_full_width=False,
614
+ height=650,
615
+ show_copy_button=True,
616
+ show_share_button=True,
617
+ avatar_images=(
618
+ "https://raw.githubusercontent.com/gradio-app/gradio/main/gradio/themes/utils/profile_avatar.png",
619
+ "🤖"
620
+ ),
621
+ render_markdown=True,
622
+ sanitize_html=False, # Allow HTML for thinking blocks
623
+ latex_delimiters=[
624
+ {"left": "$$", "right": "$$", "display": True},
625
+ {"left": "$", "right": "$", "display": False}
626
+ ],
627
+ elem_classes=["modern-chatbot"]
628
+ )
629
 
630
+ # Input Section
631
+ with gr.Group():
632
+ with gr.Row():
633
+ msg = gr.Textbox(
634
+ container=False,
635
+ placeholder="💭 Ask me anything! I'll show you my thinking and emotional reasoning process...",
636
+ label="",
637
+ autofocus=True,
638
+ scale=8,
639
+ lines=1,
640
+ max_lines=5,
641
+ elem_classes=["modern-input"]
642
+ )
643
+ with gr.Column(scale=1, min_width=120):
644
+ send_btn = gr.Button(
645
+ "🚀 Send",
646
+ variant="primary",
647
+ size="lg",
648
+ elem_classes=["send-button"]
649
+ )
650
+ clear_btn = gr.Button(
651
+ "🗑️ Clear",
652
+ variant="secondary",
653
+ size="sm",
654
+ elem_classes=["clear-button"]
655
+ )
656
+
657
+ # Settings Sidebar
658
+ with gr.Column(scale=1, min_width=350):
659
+ with gr.Group():
660
+ gr.HTML("""
661
+ <div style="text-align: center; padding: 1rem; background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%); border-radius: 12px; margin-bottom: 1rem;">
662
+ <h3 style="margin: 0; color: #667eea; font-weight: 600;">⚙️ Generation Settings</h3>
663
+ </div>
664
+ """)
665
+
666
+ max_tokens = gr.Slider(
667
+ minimum=1,
668
+ maximum=40960,
669
+ value=2048,
670
+ step=1,
671
+ label="🎯 Max Tokens",
672
+ info="Maximum number of tokens to generate",
673
+ elem_classes=["modern-slider"]
674
+ )
675
 
676
+ temperature = gr.Slider(
677
+ minimum=0.1,
678
+ maximum=2.0,
679
+ value=0.7,
680
+ step=0.1,
681
+ label="🌡️ Temperature",
682
+ info="Controls randomness in generation",
683
+ elem_classes=["modern-slider"]
684
+ )
685
 
686
+ top_p = gr.Slider(
687
+ minimum=0.1,
688
+ maximum=1.0,
689
+ value=0.9,
690
+ step=0.05,
691
+ label="🎲 Top-p (Nucleus Sampling)",
692
+ info="Controls diversity of generation",
693
+ elem_classes=["modern-slider"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
694
  )
695
+
696
+ with gr.Row():
697
+ stop_btn = gr.Button(
698
+ "⏹️ Stop Generation",
699
+ variant="stop",
700
+ size="sm",
701
+ elem_classes=["stop-button"]
702
+ )
703
+
704
+ # Model Information Panel
705
+ with gr.Group():
706
+ gr.HTML("""
707
+ <div style="background: linear-gradient(135deg, rgba(34, 197, 94, 0.1) 0%, rgba(59, 130, 246, 0.1) 100%); border-radius: 12px; padding: 1.5rem; border: 1px solid rgba(34, 197, 94, 0.2);">
708
+ <h3 style="margin: 0 0 1rem 0; color: #22c55e; font-weight: 600;">📊 Model Information</h3>
709
+ <div style="color: #64748b; line-height: 1.6;">
710
+ <strong style="color: #1e293b;">Model:</strong> HelpingAI/Dhanishtha-2.0-preview<br>
711
+ <strong style="color: #1e293b;">Type:</strong> Advanced Reasoning LLM<br>
712
+ <strong style="color: #1e293b;">Features:</strong> Multi-step reasoning, emotional intelligence<br>
713
+ <strong style="color: #1e293b;">Special:</strong> Transparent thinking process with &lt;think&gt; and &lt;ser&gt; blocks
714
+ </div>
715
+ </div>
716
+ """)
717
+
718
+ # Performance Stats (placeholder)
719
+ with gr.Group():
720
+ gr.HTML("""
721
+ <div style="background: linear-gradient(135deg, rgba(168, 85, 247, 0.1) 0%, rgba(236, 72, 153, 0.1) 100%); border-radius: 12px; padding: 1.5rem; border: 1px solid rgba(168, 85, 247, 0.2);">
722
+ <h3 style="margin: 0 0 1rem 0; color: #a855f7; font-weight: 600;">⚡ Performance</h3>
723
+ <div style="color: #64748b; line-height: 1.6;">
724
+ <strong style="color: #1e293b;">Status:</strong> <span style="color: #22c55e;">Active ✅</span><br>
725
+ <strong style="color: #1e293b;">Response Mode:</strong> Streaming<br>
726
+ <strong style="color: #1e293b;">Reasoning:</strong> Enhanced<br>
727
+ <strong style="color: #1e293b;">Context:</strong> 8192 tokens
728
+ </div>
729
+ </div>
730
+ """)
 
 
 
 
 
 
 
 
731
 
732
+ # Example Prompts Section
733
+ with gr.Group():
734
+ gr.HTML("""
735
+ <div style="text-align: center; padding: 1.5rem; background: linear-gradient(135deg, rgba(245, 158, 11, 0.1) 0%, rgba(251, 146, 60, 0.1) 100%); border-radius: 16px; margin: 2rem 0; border: 1px solid rgba(245, 158, 11, 0.2);">
736
+ <h3 style="margin: 0 0 1rem 0; color: #f59e0b; font-weight: 600;">💡 Example Prompts</h3>
737
+ <p style="color: #64748b; margin: 0;">Try these prompts to see the thinking and emotional reasoning process in action!</p>
738
+ </div>
739
+ """)
740
+
741
+ gr.Examples(
742
+ examples=[
743
+ ["Hello! Can you introduce yourself and show me your thinking and emotional reasoning process?"],
744
+ ["Solve this step by step: What is 15% of 240? Show your complete reasoning."],
745
+ ["Explain quantum entanglement in simple terms with your thought process"],
746
+ ["Write a short Python function to find the factorial of a number and explain your approach"],
747
+ ["What are the pros and cons of renewable energy? Include your emotional perspective using SER."],
748
+ ["Help me understand the difference between AI and machine learning with examples"],
749
+ ["Create a haiku about artificial intelligence and explain your creative process"],
750
+ ["Explain why the sky is blue using physics principles with step-by-step thinking"],
751
+ ["What's your favorite type of conversation and why? Show your emotional reasoning using SER format."],
752
+ ["How do you handle complex ethical dilemmas? Walk me through your thinking and emotional process."],
753
+ ["Tell me about a time when you had to change your mind about something. Use both thinking and SER blocks."],
754
+ ["What makes you feel most fulfilled in conversations? Use structured emotional reasoning."]
755
+ ],
756
+ inputs=msg,
757
+ label="",
758
+ examples_per_page=6,
759
+ elem_classes=["modern-examples"]
760
+ )
761
+
762
  # Event handlers
763
  def clear_chat():
764
  """Clear the chat history"""
 
788
  show_progress=False
789
  )
790
 
791
+ # Footer Section
792
+ gr.HTML("""
793
+ <div style="text-align: center; padding: 2rem; background: linear-gradient(135deg, rgba(71, 85, 105, 0.1) 0%, rgba(100, 116, 139, 0.1) 100%); border-radius: 16px; margin-top: 2rem; border: 1px solid rgba(71, 85, 105, 0.2);">
794
+ <h3 style="color: #475569; font-weight: 600; margin-bottom: 1rem;">🔧 Technical Specifications</h3>
795
+ <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; color: #64748b; line-height: 1.6;">
796
+ <div>
797
+ <strong style="color: #1e293b;">Model:</strong> HelpingAI/Dhanishtha-2.0-preview<br>
798
+ <strong style="color: #1e293b;">Framework:</strong> Transformers + Gradio
799
+ </div>
800
+ <div>
801
+ <strong style="color: #1e293b;">Features:</strong> Real-time streaming<br>
802
+ <strong style="color: #1e293b;">Reasoning:</strong> Multi-step with transparency
803
+ </div>
804
+ <div>
805
+ <strong style="color: #1e293b;">Special Tags:</strong> &lt;think&gt; and &lt;ser&gt; blocks<br>
806
+ <strong style="color: #1e293b;">Sampling:</strong> Custom temperature & top-p
807
+ </div>
808
+ </div>
809
+ <hr style="border: none; height: 1px; background: linear-gradient(90deg, transparent, #e2e8f0, transparent); margin: 1.5rem 0;">
810
+ <p style="color: #64748b; margin: 0; font-size: 14px;">
811
+ 🚀 <strong>Built with ❤️ using Gradio and Transformers</strong> |
812
+ 💡 The first LLM to show transparent thinking and emotional reasoning processes
813
+ </p>
814
+ </div>
815
+ """)
 
 
 
 
 
 
 
 
 
 
816
 
817
  if __name__ == "__main__":
818
  demo.queue(
819
+ max_size=30,
820
+ default_concurrency_limit=2
821
  ).launch(
822
  server_name="0.0.0.0",
823
  server_port=7860,
824
  share=False,
825
  show_error=True,
826
+ quiet=False,
827
+ favicon_path="🤖",
828
+ show_tips=True,
829
+ enable_queue=True
830
  )