raidhon commited on
Commit
3c9eaad
1 Parent(s): 1d49209

feat: init

Browse files
Files changed (3) hide show
  1. .gitignore +2 -0
  2. app.py +254 -0
  3. requirements.txt +2 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ venv
2
+ .idea
app.py ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import aiohttp
3
+ import asyncio
4
+ import json
5
+
6
+ # Define the types and their associated models with labels and values
7
+ types_and_models = {
8
+ 'deepinfra': [
9
+ ('Llama 8B', 'meta-llama/Meta-Llama-3.1-8B-Instruct'),
10
+ ('Llama 70B', 'meta-llama/Meta-Llama-3.1-70B-Instruct'),
11
+ ('Llama 405B', 'meta-llama/Meta-Llama-3.1-405B-Instruct'),
12
+ ('Qwen 72B', 'Qwen/Qwen2.5-72B-Instruct'),
13
+ ],
14
+ 'groq': [
15
+ ('Llama 3.1 8B Instant', 'llama-3.1-8b-instant'),
16
+ ('Llama 3.1 70B Versatile', 'llama-3.1-70b-versatile'),
17
+ ('Gemma 9B IT', 'gemma2-9b-it'),
18
+ ('Llama3 Groq 70B Preview', 'llama3-groq-70b-8192-tool-use-preview'),
19
+ ('Llama3 Groq 8B Preview', 'llama3-groq-8b-8192-tool-use-preview'),
20
+ ],
21
+ 'openai': [
22
+ ('GPT-4o Mini', 'gpt-4o-mini'),
23
+ ('GPT-4o', 'gpt-4o'),
24
+ ],
25
+ }
26
+
27
+
28
+ def update_models(selected_type):
29
+ # Update the models dropdown based on the selected type
30
+ choices = types_and_models[selected_type]
31
+ default_value = choices[0][1] # The value of the first model
32
+ return gr.update(choices=choices, value=default_value)
33
+
34
+
35
+ async def chat_with_server(chat_history, api_key, base_url, selected_type, selected_model, temperature, max_tokens):
36
+ headers = {
37
+ 'Content-Type': 'application/json',
38
+ 'Authorization': f'Bearer {api_key}',
39
+ }
40
+
41
+ if base_url:
42
+ base_url = base_url
43
+ else:
44
+ base_url = 'http://localhost:3000' # Default base URL
45
+
46
+ # Prepare the messages for the API
47
+ api_messages = []
48
+ for user_msg, assistant_msg in chat_history:
49
+ if user_msg is not None:
50
+ api_messages.append({'role': 'user', 'content': user_msg})
51
+ if assistant_msg is not None and not assistant_msg.startswith("Assistant is typing"):
52
+ api_messages.append({'role': 'assistant', 'content': assistant_msg})
53
+
54
+ payload = {
55
+ 'type': selected_type, # Include the selected type
56
+ 'model': selected_model,
57
+ 'messages': api_messages,
58
+ 'temperature': temperature,
59
+ 'max_tokens': int(max_tokens),
60
+ 'stream': True, # Enable streaming
61
+ }
62
+
63
+ # Initialize typing animation
64
+ if chat_history:
65
+ chat_history[-1][1] = "Assistant is typing"
66
+ yield chat_history
67
+
68
+ async with aiohttp.ClientSession() as session:
69
+ try:
70
+ # Start the server request asynchronously
71
+ response_task = asyncio.create_task(session.post(
72
+ f'{base_url}/v1/chat/completions',
73
+ headers=headers,
74
+ json=payload,
75
+ timeout=300
76
+ ))
77
+
78
+ # Typing animation variables
79
+ dots_count = 0
80
+ assistant_message = ''
81
+
82
+ while not response_task.done():
83
+ # Update typing animation
84
+ dots = '.' * ((dots_count % 3) + 1)
85
+ dots_count += 1
86
+ if chat_history:
87
+ chat_history[-1][1] = f"Assistant is typing{dots}"
88
+ yield chat_history
89
+ await asyncio.sleep(0.5) # Wait before updating again
90
+
91
+ # Now get the response
92
+ response = await response_task
93
+ if response.status != 200:
94
+ error_message = f"Error {response.status}: {await response.text()}"
95
+ chat_history[-1][1] = error_message
96
+ yield chat_history
97
+ return
98
+
99
+ assistant_message = ''
100
+ # Read the streaming response
101
+ async for line in response.content:
102
+ line = line.decode('utf-8').strip()
103
+ if line == '':
104
+ continue
105
+ if line == 'data: [DONE]':
106
+ break
107
+ if line.startswith('data: '):
108
+ data_str = line[6:].strip()
109
+ if data_str:
110
+ data = json.loads(data_str)
111
+ if 'choices' in data and len(data['choices']) > 0:
112
+ delta = data['choices'][0]['delta']
113
+ if 'content' in delta:
114
+ content = delta['content']
115
+ assistant_message += content
116
+ # Update the assistant's message in the chat
117
+ chat_history[-1][1] = assistant_message
118
+ yield chat_history
119
+ # Final update to the conversation
120
+ yield chat_history
121
+
122
+ except Exception as e:
123
+ error_message = f"Error: {str(e)}"
124
+ chat_history[-1][1] = error_message
125
+ yield chat_history
126
+
127
+
128
+ def reset_chat():
129
+ return []
130
+
131
+
132
+ with gr.Blocks() as demo:
133
+ gr.Markdown("# Chat Application")
134
+
135
+ with gr.Row():
136
+ api_key = gr.Textbox(label="API Key", placeholder="Enter your API Key",
137
+ value="ggkjgf", type="password", lines=1)
138
+ base_url = gr.Textbox(label="Base URL", placeholder="https://api.groq.com/openai/v1", lines=1)
139
+ selected_type = gr.Dropdown(
140
+ label="Type",
141
+ choices=list(types_and_models.keys()),
142
+ value=list(types_and_models.keys())[0]
143
+ )
144
+ # Initialize the selected_model with choices and value
145
+ initial_type = list(types_and_models.keys())[0]
146
+ initial_choices = types_and_models[initial_type]
147
+ selected_model = gr.Dropdown(
148
+ label="Model",
149
+ choices=initial_choices,
150
+ value=initial_choices[0][1] # First model's value
151
+ )
152
+ temperature = gr.Slider(label="Temperature", minimum=0, maximum=1, value=0.3, step=0.1)
153
+ max_tokens = gr.Number(label="Max Tokens", value=4096)
154
+
155
+ # Initialize the chatbot component
156
+ chatbot = gr.Chatbot(elem_id="chatbot", height=400)
157
+
158
+ with gr.Row():
159
+ with gr.Column(scale=10):
160
+ user_input = gr.Textbox(
161
+ show_label=False,
162
+ placeholder="Type your message here...",
163
+ lines=5,
164
+ container=False
165
+ )
166
+ with gr.Column(min_width=50, scale=1):
167
+ send_button = gr.Button("Send", variant="primary")
168
+ reset_button = gr.Button("Reset Chat")
169
+
170
+ # Update the models dropdown when the type changes
171
+ selected_type.change(
172
+ update_models,
173
+ inputs=selected_type,
174
+ outputs=selected_model
175
+ )
176
+
177
+
178
+ def user(user_message, chat_history):
179
+ # Append the user's message to the chat history
180
+ if not chat_history:
181
+ chat_history = []
182
+ chat_history = chat_history + [[user_message, None]]
183
+ return user_message, chat_history
184
+
185
+ # Set up the event handlers
186
+
187
+
188
+ send_button.click(
189
+ user,
190
+ inputs=[user_input, chatbot],
191
+ outputs=[user_input, chatbot]
192
+ ).then(
193
+ chat_with_server,
194
+ inputs=[chatbot, api_key, base_url, selected_type, selected_model, temperature, max_tokens],
195
+ outputs=chatbot,
196
+ )
197
+
198
+ reset_button.click(reset_chat, outputs=chatbot)
199
+
200
+ # Include CSS to format code blocks and other markdown elements
201
+ gr.HTML("""
202
+ <style>
203
+ .message pre {
204
+ background-color: #f0f0f0;
205
+ padding: 10px;
206
+ border-radius: 5px;
207
+ overflow-x: auto;
208
+ }
209
+ .message code {
210
+ background-color: #f0f0f0;
211
+ padding: 2px 4px;
212
+ border-radius: 3px;
213
+ }
214
+ </style>
215
+ """)
216
+
217
+ # Add JavaScript for rendering Markdown and LaTeX
218
+ gr.HTML("""
219
+ <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
220
+ <script src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" crossorigin="anonymous"></script>
221
+ <script src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" crossorigin="anonymous"></script>
222
+ <script>
223
+ function renderContent() {
224
+ const messages = document.querySelectorAll('.message');
225
+ messages.forEach((message) => {
226
+ // Render Markdown
227
+ message.innerHTML = marked.parse(message.innerHTML);
228
+ // Render LaTeX
229
+ renderMathInElement(message, {
230
+ delimiters: [
231
+ {left: "$$", right: "$$", display: true},
232
+ {left: "$", right: "$", display: false},
233
+ {left: "\\(", right: "\\)", display: false},
234
+ {left: "\\[", right: "\\]", display: true}
235
+ ],
236
+ throwOnError: false
237
+ });
238
+ });
239
+ }
240
+ // Observe changes in the chatbox to render content
241
+ const chatbox = document.querySelector('#chatbot');
242
+ const observer = new MutationObserver((mutations) => {
243
+ for (let mutation of mutations) {
244
+ if (mutation.addedNodes.length > 0) {
245
+ renderContent();
246
+ }
247
+ }
248
+ });
249
+ observer.observe(chatbox, {childList: true, subtree: true});
250
+ </script>
251
+ """)
252
+
253
+ demo.queue()
254
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ aiohttp