saneowl commited on
Commit
280275c
·
verified ·
1 Parent(s): 7f94b06

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +36 -26
app.py CHANGED
@@ -3,25 +3,28 @@ import requests
3
  import re
4
  import os
5
 
 
6
  API_ENDPOINT = os.getenv("API_ENDPOINT")
7
  API_TOKEN = os.getenv("API_TOKEN")
8
- MODEL_ID = os.getenv("MODEL_ID", "none") # Default value if not set
9
 
10
  def get_ai_response(message, history):
11
  """Fetch AI response from the API using the modern messages format."""
12
  messages = [{"role": "system", "content": "You are a helpful assistant."}]
13
- # Build the API history using all prior complete pairs
14
  for user_msg, ai_msg in history:
15
  if ai_msg != "⏳ Thinking...":
 
16
  clean_ai_msg = re.sub(r'<details>.*?</details>', '', ai_msg, flags=re.DOTALL)
17
  clean_ai_msg = re.sub(r'<[^>]*>', '', clean_ai_msg)
18
  messages.append({"role": "user", "content": user_msg})
19
  messages.append({"role": "assistant", "content": clean_ai_msg})
20
- # Append the new user message for which we want a response
 
21
  messages.append({"role": "user", "content": message})
22
 
23
  payload = {
24
- "model": MODEL_ID, # Use the environment variable here
25
  "messages": messages,
26
  "stream": False,
27
  "max_tokens": 10000,
@@ -31,6 +34,7 @@ def get_ai_response(message, history):
31
  "Authorization": f"Bearer {API_TOKEN}",
32
  "Content-Type": "application/json"
33
  }
 
34
  try:
35
  response = requests.post(API_ENDPOINT, headers=headers, json=payload)
36
  response.raise_for_status()
@@ -41,45 +45,51 @@ def get_ai_response(message, history):
41
  return f"Error: {str(e)}"
42
 
43
  def convert_reasoning_to_collapsible(text):
44
- """Convert reasoning tags to collapsible HTML sections."""
45
  reasoning_pattern = re.compile(r'<reasoning>(.*?)</reasoning>', re.DOTALL)
 
46
  def replace_with_collapsible(match):
47
  reasoning_content = match.group(1).strip()
48
- return f'<details><summary><strong>See reasoning</strong></summary><div class="reasoning-content">{reasoning_content}</div></details>'
 
 
 
 
 
 
49
  html_response = reasoning_pattern.sub(replace_with_collapsible, text)
50
  html_response = re.sub(r'<sep>.*?</sep>', '', html_response, flags=re.DOTALL)
51
  html_response = html_response.replace('<sep>', '').replace('</sep>', '')
52
  return html_response
53
 
54
  def add_user_message(message, history):
55
- """Immediately add the user's message with a '⏳ Thinking...' assistant reply."""
56
  if history is None:
57
  history = []
58
  history.append((message, "⏳ Thinking..."))
59
- # Return both updated state and chatbot messages
60
  return history, history
61
 
62
  def generate_response_from_history(history):
63
- """Generate the assistant's reply and update the last pending message."""
64
  if not history:
65
  return history, history
66
- # Get the last user message (which is paired with "⏳ Thinking...")
67
  last_user_message = history[-1][0]
68
- # Build API history excluding pending messages
69
  api_history = []
 
70
  for user_msg, ai_msg in history:
71
  if ai_msg != "⏳ Thinking...":
72
  clean_ai_msg = re.sub(r'<details>.*?</details>', '', ai_msg, flags=re.DOTALL)
73
  clean_ai_msg = re.sub(r'<[^>]*>', '', clean_ai_msg)
74
  api_history.append({"role": "user", "content": user_msg})
75
  api_history.append({"role": "assistant", "content": clean_ai_msg})
76
- # Append the last user message to fetch the assistant's reply
77
  api_history.append({"role": "user", "content": last_user_message})
78
  ai_response = get_ai_response(last_user_message, api_history)
79
  history[-1] = (last_user_message, ai_response)
80
  return history, history
81
 
82
- # Modern CSS for a clean UI
83
  custom_css = """
84
  body { background-color: #1a1a1a; color: #ffffff; font-family: 'Arial', sans-serif; }
85
  #chatbot { height: 80vh; background-color: #2d2d2d; border: 1px solid #404040; border-radius: 8px; }
@@ -90,23 +100,25 @@ summary { cursor: pointer; color: #70a9e6; }
90
  .reasoning-content { padding: 10px; margin-top: 5px; background-color: #404040; border-radius: 5px; }
91
  """
92
 
93
- # Get model name for display (use the full model ID from environment variable)
94
  model_display_name = MODEL_ID
95
 
 
96
  with gr.Blocks(css=custom_css, title=model_display_name) as demo:
97
  with gr.Column():
98
  gr.Markdown("## nvidia-Llama-3_1-Nemotron-Ultra-253B-v1 Demo")
99
  gr.Markdown("This is a demo of nvidia-Llama-3_1-Nemotron-Ultra-253B-v1")
100
  chatbot = gr.Chatbot(elem_id="chatbot", render_markdown=False, bubble_full_width=True)
 
101
  with gr.Row():
102
  message = gr.Textbox(placeholder="Type your message...", show_label=False, container=False)
103
- # Make the button larger by using size "lg"
104
  submit_btn = gr.Button("Send", size="lg")
 
105
  clear_chat_btn = gr.Button("Clear Chat")
106
-
107
- # State management for chat history
108
  chat_state = gr.State([])
109
 
 
110
  js = """
111
  function() {
112
  const observer = new MutationObserver(function(mutations) {
@@ -130,7 +142,7 @@ with gr.Blocks(css=custom_css, title=model_display_name) as demo:
130
  }
131
  """
132
 
133
- # First, add the user message with a pending reply, then update it with the actual response.
134
  submit_btn.click(
135
  add_user_message,
136
  [message, chat_state],
@@ -140,12 +152,10 @@ with gr.Blocks(css=custom_css, title=model_display_name) as demo:
140
  chat_state,
141
  [chat_state, chatbot]
142
  ).then(
143
- lambda: "", # Clear the input box after processing
144
- None,
145
- message
146
  )
147
 
148
- # Enable pressing Enter to submit
149
  message.submit(
150
  add_user_message,
151
  [message, chat_state],
@@ -155,18 +165,17 @@ with gr.Blocks(css=custom_css, title=model_display_name) as demo:
155
  chat_state,
156
  [chat_state, chatbot]
157
  ).then(
158
- lambda: "",
159
- None,
160
- message
161
  )
162
 
 
163
  clear_chat_btn.click(
164
  lambda: ([], []),
165
  None,
166
  [chat_state, chatbot]
167
  )
168
 
169
- # Load JavaScript to enable HTML rendering in chatbot messages
170
  demo.load(
171
  fn=lambda: None,
172
  inputs=None,
@@ -174,5 +183,6 @@ with gr.Blocks(css=custom_css, title=model_display_name) as demo:
174
  js=js
175
  )
176
 
 
177
  demo.queue()
178
  demo.launch()
 
3
  import re
4
  import os
5
 
6
+ # Load from environment or fallback to default
7
  API_ENDPOINT = os.getenv("API_ENDPOINT")
8
  API_TOKEN = os.getenv("API_TOKEN")
9
+ MODEL_ID = os.getenv("MODEL_ID", "none")
10
 
11
  def get_ai_response(message, history):
12
  """Fetch AI response from the API using the modern messages format."""
13
  messages = [{"role": "system", "content": "You are a helpful assistant."}]
14
+
15
  for user_msg, ai_msg in history:
16
  if ai_msg != "⏳ Thinking...":
17
+ # Clean HTML from AI messages to avoid nesting artifacts
18
  clean_ai_msg = re.sub(r'<details>.*?</details>', '', ai_msg, flags=re.DOTALL)
19
  clean_ai_msg = re.sub(r'<[^>]*>', '', clean_ai_msg)
20
  messages.append({"role": "user", "content": user_msg})
21
  messages.append({"role": "assistant", "content": clean_ai_msg})
22
+
23
+ # Add latest user message
24
  messages.append({"role": "user", "content": message})
25
 
26
  payload = {
27
+ "model": MODEL_ID,
28
  "messages": messages,
29
  "stream": False,
30
  "max_tokens": 10000,
 
34
  "Authorization": f"Bearer {API_TOKEN}",
35
  "Content-Type": "application/json"
36
  }
37
+
38
  try:
39
  response = requests.post(API_ENDPOINT, headers=headers, json=payload)
40
  response.raise_for_status()
 
45
  return f"Error: {str(e)}"
46
 
47
  def convert_reasoning_to_collapsible(text):
48
+ """Convert <reasoning> tags into collapsible HTML elements."""
49
  reasoning_pattern = re.compile(r'<reasoning>(.*?)</reasoning>', re.DOTALL)
50
+
51
  def replace_with_collapsible(match):
52
  reasoning_content = match.group(1).strip()
53
+ return (
54
+ f'<details>'
55
+ f'<summary><strong>See reasoning</strong></summary>'
56
+ f'<div class="reasoning-content">{reasoning_content}</div>'
57
+ f'</details>'
58
+ )
59
+
60
  html_response = reasoning_pattern.sub(replace_with_collapsible, text)
61
  html_response = re.sub(r'<sep>.*?</sep>', '', html_response, flags=re.DOTALL)
62
  html_response = html_response.replace('<sep>', '').replace('</sep>', '')
63
  return html_response
64
 
65
  def add_user_message(message, history):
66
+ """Add user message with a placeholder AI response ('⏳ Thinking...')."""
67
  if history is None:
68
  history = []
69
  history.append((message, "⏳ Thinking..."))
 
70
  return history, history
71
 
72
  def generate_response_from_history(history):
73
+ """Replace last ' Thinking...' with real assistant response."""
74
  if not history:
75
  return history, history
76
+
77
  last_user_message = history[-1][0]
 
78
  api_history = []
79
+
80
  for user_msg, ai_msg in history:
81
  if ai_msg != "⏳ Thinking...":
82
  clean_ai_msg = re.sub(r'<details>.*?</details>', '', ai_msg, flags=re.DOTALL)
83
  clean_ai_msg = re.sub(r'<[^>]*>', '', clean_ai_msg)
84
  api_history.append({"role": "user", "content": user_msg})
85
  api_history.append({"role": "assistant", "content": clean_ai_msg})
86
+
87
  api_history.append({"role": "user", "content": last_user_message})
88
  ai_response = get_ai_response(last_user_message, api_history)
89
  history[-1] = (last_user_message, ai_response)
90
  return history, history
91
 
92
+ # CSS for dark mode + collapsible sections
93
  custom_css = """
94
  body { background-color: #1a1a1a; color: #ffffff; font-family: 'Arial', sans-serif; }
95
  #chatbot { height: 80vh; background-color: #2d2d2d; border: 1px solid #404040; border-radius: 8px; }
 
100
  .reasoning-content { padding: 10px; margin-top: 5px; background-color: #404040; border-radius: 5px; }
101
  """
102
 
103
+ # Set model name for UI title
104
  model_display_name = MODEL_ID
105
 
106
+ # Gradio UI definition
107
  with gr.Blocks(css=custom_css, title=model_display_name) as demo:
108
  with gr.Column():
109
  gr.Markdown("## nvidia-Llama-3_1-Nemotron-Ultra-253B-v1 Demo")
110
  gr.Markdown("This is a demo of nvidia-Llama-3_1-Nemotron-Ultra-253B-v1")
111
  chatbot = gr.Chatbot(elem_id="chatbot", render_markdown=False, bubble_full_width=True)
112
+
113
  with gr.Row():
114
  message = gr.Textbox(placeholder="Type your message...", show_label=False, container=False)
 
115
  submit_btn = gr.Button("Send", size="lg")
116
+
117
  clear_chat_btn = gr.Button("Clear Chat")
118
+
 
119
  chat_state = gr.State([])
120
 
121
+ # JS to allow rendering HTML in the chat
122
  js = """
123
  function() {
124
  const observer = new MutationObserver(function(mutations) {
 
142
  }
143
  """
144
 
145
+ # Event: Send button clicked
146
  submit_btn.click(
147
  add_user_message,
148
  [message, chat_state],
 
152
  chat_state,
153
  [chat_state, chatbot]
154
  ).then(
155
+ lambda: "", None, message # clear textbox
 
 
156
  )
157
 
158
+ # Event: Pressing Enter key in Textbox
159
  message.submit(
160
  add_user_message,
161
  [message, chat_state],
 
165
  chat_state,
166
  [chat_state, chatbot]
167
  ).then(
168
+ lambda: "", None, message
 
 
169
  )
170
 
171
+ # Clear chat
172
  clear_chat_btn.click(
173
  lambda: ([], []),
174
  None,
175
  [chat_state, chatbot]
176
  )
177
 
178
+ # Load JS on UI load
179
  demo.load(
180
  fn=lambda: None,
181
  inputs=None,
 
183
  js=js
184
  )
185
 
186
+ # Launch Gradio interface
187
  demo.queue()
188
  demo.launch()