huijio commited on
Commit
9e855f0
·
verified ·
1 Parent(s): d668e6e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -247
app.py CHANGED
@@ -1,8 +1,6 @@
1
  import gradio as gr
2
  import requests
3
  from html import escape
4
- import time
5
- import json
6
  from typing import List, Tuple, Optional
7
 
8
  # API endpoints
@@ -38,271 +36,117 @@ css = """
38
  border-radius: 10px;
39
  margin: 5px 0;
40
  }
41
- .model-selector {
42
- padding: 10px;
43
- background-color: #f8f9fa;
44
- border-radius: 5px;
45
- }
46
- .status-message {
47
- color: #666;
48
- font-size: 0.9em;
49
- margin-top: 5px;
50
- }
51
- .error-message {
52
- color: #d32f2f;
53
- font-size: 0.9em;
54
- margin-top: 5px;
55
- }
56
- .loading-message {
57
- color: #1976d2;
58
- font-size: 0.9em;
59
- margin-top: 5px;
60
- }
61
  """
62
 
63
- def get_available_models() -> Tuple[List[str], Optional[str]]:
64
- """
65
- Fetch available models from the API with retry logic
66
- Returns tuple of (models_list, error_message)
67
- """
68
- max_retries = 3
69
- retry_delay = 2 # seconds
70
-
71
- for attempt in range(max_retries):
72
- try:
73
- response = requests.get(MODELS_URL, timeout=10)
74
- response.raise_for_status()
75
-
76
- data = response.json()
77
-
78
- # Handle both direct list response and object with data property
79
- if isinstance(data, list):
80
- models = [model['id'] for model in data if isinstance(model, dict) and 'id' in model]
81
- elif isinstance(data, dict) and 'data' in data:
82
- models = [model['id'] for model in data['data'] if isinstance(model, dict) and 'id' in model]
83
- else:
84
- models = []
85
-
86
- if models:
87
- return sorted(models), None
88
- else:
89
- error_msg = "No models found in API response"
90
-
91
- except requests.exceptions.RequestException as e:
92
- error_msg = f"Request failed: {str(e)}"
93
-
94
- except json.JSONDecodeError:
95
- error_msg = "Invalid JSON response from server"
96
-
97
- except Exception as e:
98
- error_msg = f"Unexpected error: {str(e)}"
99
-
100
- if attempt < max_retries - 1:
101
- time.sleep(retry_delay)
102
-
103
- return [], error_msg
104
 
105
- def convert_latex(text: str) -> str:
106
- """Convert LaTeX expressions to HTML for rendering"""
107
- if not text:
108
- return ""
109
-
110
- # Handle block equations
111
- text = text.replace('$$', '</p><div class="latex-block">')
112
- text = text.replace('\\[', '</p><div class="latex-block">')
113
- text = text.replace('\\]', '</div><p>')
 
 
 
114
 
115
- # Handle inline equations
116
- text = text.replace('$', '<span class="latex-inline">')
117
- text = text.replace('\\(', '<span class="latex-inline">')
118
- text = text.replace('\\)', '</span>')
119
-
120
- return text
121
 
122
- def format_message(message: str, role: str) -> str:
123
- """Format message with role-specific styling"""
124
- message = escape(message)
125
- message = convert_latex(message)
126
- return f'<div class="message {role}">{message}</div>'
127
 
128
- def chat_completion(model: str, message: str, chat_history: list) -> tuple:
129
- """Send message to API and get response"""
130
- if not message:
 
 
 
 
131
  return chat_history, ""
132
 
133
- # Add user message to history
134
- chat_history.append((format_message(message, "user"), ""))
135
 
136
- try:
137
- payload = {
138
- "model": model,
139
- "messages": [{"role": "user", "content": message}],
140
- "temperature": 0.7
141
- }
142
-
143
- response = requests.post(API_URL, json=payload, timeout=30)
144
- response.raise_for_status()
145
-
146
- data = response.json()
147
- assistant_message = data['choices'][0]['message']['content']
148
-
149
- # Update chat history
150
- chat_history[-1] = (
151
- chat_history[-1][0],
152
- format_message(assistant_message, "assistant")
153
- )
154
-
155
- return chat_history, ""
156
 
157
- except Exception as e:
158
- error_msg = f"Error: {str(e)}"
159
- if hasattr(e, 'response') and e.response:
160
- try:
161
- error_details = e.response.json()
162
- error_msg += f"\nDetails: {json.dumps(error_details, indent=2)}"
163
- except:
164
- error_msg += f"\nStatus: {e.response.status_code}"
165
-
166
- chat_history.append(("", format_message(error_msg, "assistant")))
167
- return chat_history, ""
168
-
169
- def update_model_dropdown() -> dict:
170
- """Update the model dropdown with current available models"""
171
- models, error = get_available_models()
172
 
173
- if error:
174
- status = f'<div class="error-message">⚠️ {error}</div>'
175
- if not models:
176
- return [
177
- gr.Dropdown.update(choices=[], value=None),
178
- gr.Markdown.update(value=status),
179
- gr.Button.update(interactive=False)
180
- ]
181
  else:
182
- status = f'<div class="status-message">✅ Loaded {len(models)} models</div>'
183
 
184
- return [
185
- gr.Dropdown.update(
186
- choices=models,
187
- value=models[0] if models else None
188
- ),
189
- gr.Markdown.update(value=status),
190
- gr.Button.update(interactive=bool(models))
191
- ]
192
 
193
- with gr.Blocks(css=css, theme=gr.themes.Default()) as demo:
194
- # Title and description
195
- gr.Markdown("""
196
- # Multi-Model Chat Interface
197
- Connect to various AI models through a single interface
198
- """)
199
 
200
- # Model selection
201
- with gr.Row():
 
202
  model_dropdown = gr.Dropdown(
203
- label="Select Model",
204
- choices=[],
205
- value=None,
206
- interactive=False,
207
- elem_classes="model-selector"
208
- )
209
- refresh_btn = gr.Button(
210
- "🔄 Refresh Models",
211
- variant="secondary",
212
- interactive=False
213
  )
214
-
215
- # Status message
216
- status_message = gr.Markdown(
217
- value='<div class="loading-message">Loading models...</div>',
218
- elem_id="status-message"
219
- )
220
-
221
- # Chat interface
222
- chatbot = gr.Chatbot(
223
- label="Chat History",
224
- elem_id="chatbot",
225
- height=500,
226
- visible=False
227
- )
228
-
229
- # Message input
230
- msg = gr.Textbox(
231
- label="Your Message",
232
- placeholder="Please wait while models load...",
233
- lines=3,
234
- max_lines=10,
235
- interactive=False
236
- )
237
-
238
- # Submit and clear buttons
239
- with gr.Row():
240
- submit_btn = gr.Button(
241
- "Send",
242
- variant="primary",
243
- interactive=False
244
  )
245
- clear_btn = gr.Button(
246
- "Clear Chat",
247
- variant="secondary",
248
- interactive=False
 
249
  )
250
 
251
- def enable_interface(models):
252
- """Enable UI components if models are available"""
253
- if models:
254
- return [
255
- gr.Chatbot.update(visible=True),
256
- gr.Textbox.update(
257
- placeholder="Type your message here...",
258
- interactive=True
259
- ),
260
- gr.Button.update(interactive=True),
261
- gr.Button.update(interactive=True)
262
- ]
263
- return [
264
- gr.Chatbot.update(visible=False),
265
- gr.Textbox.update(
266
- placeholder="No models available",
267
- interactive=False
268
- ),
269
- gr.Button.update(interactive=False),
270
- gr.Button.update(interactive=False)
271
- ]
272
-
273
- # Initial model load
274
- demo.load(
275
- lambda: (update_model_dropdown() + enable_interface([])),
276
- outputs=[model_dropdown, status_message, refresh_btn] +
277
- [chatbot, msg, submit_btn, clear_btn]
278
- )
279
-
280
- # Event handlers
281
- refresh_btn.click(
282
- lambda: (update_model_dropdown() + enable_interface([])),
283
- outputs=[model_dropdown, status_message, refresh_btn] +
284
- [chatbot, msg, submit_btn, clear_btn]
285
- )
286
-
287
- submit_btn.click(
288
- chat_completion,
289
- [model_dropdown, msg, chatbot],
290
- [chatbot, msg]
291
- )
292
-
293
- msg.submit(
294
- chat_completion,
295
- [model_dropdown, msg, chatbot],
296
- [chatbot, msg]
297
- )
298
-
299
- clear_btn.click(
300
- lambda: [],
301
- None,
302
- chatbot,
303
- queue=False
304
- )
305
 
306
- # Run the demo
307
  if __name__ == "__main__":
 
308
  demo.launch()
 
1
  import gradio as gr
2
  import requests
3
  from html import escape
 
 
4
  from typing import List, Tuple, Optional
5
 
6
  # API endpoints
 
36
  border-radius: 10px;
37
  margin: 5px 0;
38
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  """
40
 
41
+ def get_available_models() -> List[str]:
42
+ """Fetch available models from the API."""
43
+ try:
44
+ response = requests.get(MODELS_URL)
45
+ response.raise_for_status()
46
+ models_data = response.json()
47
+ return sorted([model['id'] for model in models_data.get('data', [])])
48
+ except Exception as e:
49
+ print(f"Error fetching models: {e}")
50
+ return [
51
+ "samura-deepseek-r1",
52
+ "samura-gpt-4o",
53
+ "samura-claude-3-5-sonnet",
54
+ "groq-llama3-70b-8192"
55
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
+ def chat_completion(
58
+ messages: List[dict],
59
+ model: str,
60
+ ) -> dict:
61
+ """Send chat completion request to the API."""
62
+ headers = {"Content-Type": "application/json"}
63
+ data = {
64
+ "model": model,
65
+ "messages": messages,
66
+ "temperature": 0.7, # Default value
67
+ "max_tokens": 2000, # Default value
68
+ }
69
 
70
+ try:
71
+ response = requests.post(API_URL, headers=headers, json=data)
72
+ response.raise_for_status()
73
+ return response.json()
74
+ except Exception as e:
75
+ return {"error": str(e)}
76
 
77
+ def format_message(text: str) -> str:
78
+ """Format message with HTML for display."""
79
+ return escape(text).replace("\n", "<br>")
 
 
80
 
81
+ def chat_interface(
82
+ message: str,
83
+ chat_history: List[Tuple[str, str]],
84
+ model: str,
85
+ ) -> Tuple[List[Tuple[str, str]], str]:
86
+ """Handle chat interface interactions."""
87
+ if not message.strip():
88
  return chat_history, ""
89
 
90
+ chat_history.append((format_message(message), ""))
 
91
 
92
+ messages = []
93
+ for user_msg, assistant_msg in chat_history[:-1]:
94
+ if user_msg:
95
+ messages.append({"role": "user", "content": user_msg.replace("<br>", "\n")})
96
+ if assistant_msg:
97
+ messages.append({"role": "assistant", "content": assistant_msg.replace("<br>", "\n")})
98
+ messages.append({"role": "user", "content": message})
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
+ response = chat_completion(messages=messages, model=model)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
+ if "error" in response:
103
+ assistant_message = f"Error: {response['error']}"
 
 
 
 
 
 
104
  else:
105
+ assistant_message = response.get("choices", [{}])[0].get("message", {}).get("content", "No response")
106
 
107
+ chat_history[-1] = (chat_history[-1][0], format_message(assistant_message))
108
+ return chat_history, ""
 
 
 
 
 
 
109
 
110
+ def create_interface():
111
+ """Create Gradio chat interface."""
112
+ available_models = get_available_models()
 
 
 
113
 
114
+ with gr.Blocks(css=css, theme=gr.themes.Default()) as demo:
115
+ gr.Markdown("# Aham2 API Chat Interface")
116
+
117
  model_dropdown = gr.Dropdown(
118
+ choices=available_models,
119
+ value=available_models[0] if available_models else "samura-deepseek-r1",
120
+ label="Select Model"
 
 
 
 
 
 
 
121
  )
122
+
123
+ chatbot = gr.Chatbot(elem_classes=["chatbot"], bubble_full_width=False)
124
+
125
+ with gr.Row():
126
+ message = gr.Textbox(
127
+ placeholder="Type your message here...",
128
+ show_label=False,
129
+ container=False,
130
+ scale=7
131
+ )
132
+ submit = gr.Button("Send", variant="primary", scale=1)
133
+
134
+ clear = gr.ClearButton([message, chatbot])
135
+
136
+ submit.click(
137
+ fn=chat_interface,
138
+ inputs=[message, chatbot, model_dropdown],
139
+ outputs=[chatbot, message]
 
 
 
 
 
 
 
 
 
 
 
 
140
  )
141
+
142
+ message.submit(
143
+ fn=chat_interface,
144
+ inputs=[message, chatbot, model_dropdown],
145
+ outputs=[chatbot, message]
146
  )
147
 
148
+ return demo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
 
150
  if __name__ == "__main__":
151
+ demo = create_interface()
152
  demo.launch()