Mohit0199 commited on
Commit
4f20b87
Β·
verified Β·
1 Parent(s): a63a141

create a chatbot which is customizable and where user can enter their openrouter api key and then can select any llm available on openrouter and can use it in chatbot.

Browse files
Files changed (2) hide show
  1. README.md +8 -5
  2. index.html +305 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Chatrouter Your Llm Portal
3
- emoji: πŸƒ
4
- colorFrom: red
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: ChatRouter - Your LLM Portal πŸš€
3
+ colorFrom: green
4
+ colorTo: purple
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://deepsite.hf.co).
index.html CHANGED
@@ -1,19 +1,306 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ChatRouter - AI Chat Interface</title>
7
+ <link rel="icon" type="image/x-icon" href="https://static.photos/technology/200x200/42">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <style>
12
+ .chat-height {
13
+ height: calc(100vh - 200px);
14
+ }
15
+ .message-bubble {
16
+ max-width: 85%;
17
+ word-wrap: break-word;
18
+ }
19
+ .typing-indicator {
20
+ display: inline-block;
21
+ width: 8px;
22
+ height: 8px;
23
+ border-radius: 50%;
24
+ background-color: #9ca3af;
25
+ margin-right: 4px;
26
+ }
27
+ .typing-indicator:nth-child(1) {
28
+ animation: typing 1s infinite;
29
+ }
30
+ .typing-indicator:nth-child(2) {
31
+ animation: typing 1s infinite 0.2s;
32
+ }
33
+ .typing-indicator:nth-child(3) {
34
+ animation: typing 1s infinite 0.4s;
35
+ margin-right: 0;
36
+ }
37
+ @keyframes typing {
38
+ 0% { transform: translateY(0); }
39
+ 50% { transform: translateY(-5px); }
40
+ 100% { transform: translateY(0); }
41
+ }
42
+ </style>
43
+ </head>
44
+ <body class="bg-gradient-to-br from-indigo-900 to-purple-900 text-white">
45
+ <div class="container mx-auto px-4 py-8 max-w-5xl">
46
+ <header class="flex justify-between items-center mb-8">
47
+ <div class="flex items-center space-x-3">
48
+ <i data-feather="cpu" class="w-8 h-8 text-indigo-300"></i>
49
+ <h1 class="text-2xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-indigo-300 to-purple-300">ChatRouter</h1>
50
+ </div>
51
+ <button id="settingsBtn" class="flex items-center space-x-2 bg-indigo-800 hover:bg-indigo-700 px-4 py-2 rounded-lg transition-all">
52
+ <i data-feather="settings" class="w-5 h-5"></i>
53
+ <span>Settings</span>
54
+ </button>
55
+ </header>
56
+
57
+ <!-- Settings Modal -->
58
+ <div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
59
+ <div class="bg-gray-800 rounded-xl p-6 w-full max-w-md">
60
+ <div class="flex justify-between items-center mb-4">
61
+ <h2 class="text-xl font-bold">Chat Settings</h2>
62
+ <button id="closeSettings" class="text-gray-400 hover:text-white">
63
+ <i data-feather="x"></i>
64
+ </button>
65
+ </div>
66
+ <div class="space-y-4">
67
+ <div>
68
+ <label class="block text-sm font-medium mb-1">OpenRouter API Key</label>
69
+ <input type="password" id="apiKeyInput" placeholder="Enter your API key" class="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500">
70
+ <p class="text-xs text-gray-400 mt-1">Your key is stored locally and never sent to our servers</p>
71
+ </div>
72
+ <div>
73
+ <label class="block text-sm font-medium mb-1">Select Model</label>
74
+ <select id="modelSelect" class="w-full bg-gray-700 border border-gray-600 rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500">
75
+ <option value="openai/gpt-3.5-turbo">GPT-3.5 Turbo</option>
76
+ <option value="openai/gpt-4">GPT-4</option>
77
+ <option value="anthropic/claude-2">Claude 2</option>
78
+ <option value="google/palm-2-chat-bison">PaLM 2 Chat</option>
79
+ <option value="meta-llama/llama-2-70b-chat">Llama 2 (70B)</option>
80
+ </select>
81
+ </div>
82
+ <div>
83
+ <label class="block text-sm font-medium mb-1">Chat Theme</label>
84
+ <div class="flex space-x-2">
85
+ <button data-theme="indigo" class="theme-btn w-8 h-8 bg-indigo-600 rounded-full border-2 border-transparent focus:border-white"></button>
86
+ <button data-theme="emerald" class="theme-btn w-8 h-8 bg-emerald-600 rounded-full border-2 border-transparent focus:border-white"></button>
87
+ <button data-theme="rose" class="theme-btn w-8 h-8 bg-rose-600 rounded-full border-2 border-transparent focus:border-white"></button>
88
+ <button data-theme="amber" class="theme-btn w-8 h-8 bg-amber-600 rounded-full border-2 border-transparent focus:border-white"></button>
89
+ <button data-theme="cyan" class="theme-btn w-8 h-8 bg-cyan-600 rounded-full border-2 border-transparent focus:border-white"></button>
90
+ </div>
91
+ </div>
92
+ <button id="saveSettings" class="w-full bg-indigo-600 hover:bg-indigo-500 text-white py-2 rounded-lg transition-colors">Save Settings</button>
93
+ </div>
94
+ </div>
95
+ </div>
96
+
97
+ <!-- Chat Container -->
98
+ <div class="bg-gray-800 bg-opacity-60 backdrop-blur-lg rounded-2xl shadow-xl overflow-hidden">
99
+ <!-- Chat Messages -->
100
+ <div id="chatContainer" class="chat-height overflow-y-auto p-4 space-y-4">
101
+ <div class="flex justify-center">
102
+ <div class="bg-gray-700 bg-opacity-50 px-4 py-2 rounded-lg text-sm text-gray-300">
103
+ <i data-feather="info" class="inline mr-2 w-4 h-4"></i>
104
+ Enter your API key in settings to start chatting
105
+ </div>
106
+ </div>
107
+ </div>
108
+
109
+ <!-- Input Area -->
110
+ <div class="border-t border-gray-700 p-4 bg-gray-800">
111
+ <div class="flex items-center space-x-2">
112
+ <textarea id="messageInput" placeholder="Type your message..." rows="1" class="flex-1 bg-gray-700 border border-gray-600 rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 resize-none max-h-32"></textarea>
113
+ <button id="sendBtn" class="bg-indigo-600 hover:bg-indigo-500 text-white p-3 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed" disabled>
114
+ <i data-feather="send" class="w-5 h-5"></i>
115
+ </button>
116
+ </div>
117
+ <div class="flex justify-between items-center mt-2 text-xs text-gray-400">
118
+ <div id="typingIndicator" class="flex items-center hidden">
119
+ <span class="mr-2">AI is typing</span>
120
+ <div class="typing-indicator"></div>
121
+ <div class="typing-indicator"></div>
122
+ <div class="typing-indicator"></div>
123
+ </div>
124
+ <div>
125
+ <span id="modelIndicator">No model selected</span>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ </div>
130
+
131
+ <footer class="mt-8 text-center text-sm text-gray-400">
132
+ <p>ChatRouter connects you to the best AI models via OpenRouter</p>
133
+ <p class="mt-1">Your conversations stay private and secure</p>
134
+ </footer>
135
+ </div>
136
+
137
+ <script>
138
+ feather.replace();
139
+
140
+ // DOM Elements
141
+ const settingsBtn = document.getElementById('settingsBtn');
142
+ const settingsModal = document.getElementById('settingsModal');
143
+ const closeSettings = document.getElementById('closeSettings');
144
+ const apiKeyInput = document.getElementById('apiKeyInput');
145
+ const modelSelect = document.getElementById('modelSelect');
146
+ const saveSettings = document.getElementById('saveSettings');
147
+ const messageInput = document.getElementById('messageInput');
148
+ const sendBtn = document.getElementById('sendBtn');
149
+ const chatContainer = document.getElementById('chatContainer');
150
+ const typingIndicator = document.getElementById('typingIndicator');
151
+ const modelIndicator = document.getElementById('modelIndicator');
152
+ const themeBtns = document.querySelectorAll('.theme-btn');
153
+
154
+ // Load saved settings
155
+ function loadSettings() {
156
+ const savedApiKey = localStorage.getItem('chatRouterApiKey');
157
+ const savedModel = localStorage.getItem('chatRouterModel');
158
+ const savedTheme = localStorage.getItem('chatRouterTheme') || 'indigo';
159
+
160
+ if (savedApiKey) {
161
+ apiKeyInput.value = savedApiKey;
162
+ sendBtn.disabled = false;
163
+ }
164
+ if (savedModel) {
165
+ modelSelect.value = savedModel;
166
+ modelIndicator.textContent = `Using: ${savedModel.split('/').pop()}`;
167
+ }
168
+
169
+ // Apply theme
170
+ document.body.className = `bg-gradient-to-br from-${savedTheme}-900 to-purple-900 text-white`;
171
+ }
172
+
173
+ // Save settings
174
+ saveSettings.addEventListener('click', () => {
175
+ const apiKey = apiKeyInput.value.trim();
176
+ const model = modelSelect.value;
177
+
178
+ if (apiKey) {
179
+ localStorage.setItem('chatRouterApiKey', apiKey);
180
+ localStorage.setItem('chatRouterModel', model);
181
+ sendBtn.disabled = false;
182
+ modelIndicator.textContent = `Using: ${model.split('/').pop()}`;
183
+ settingsModal.classList.add('hidden');
184
+
185
+ // Add confirmation message to chat
186
+ addMessage('system', 'Settings saved successfully. You can now start chatting!');
187
+ } else {
188
+ alert('Please enter your OpenRouter API key');
189
+ }
190
+ });
191
+
192
+ // Theme selection
193
+ themeBtns.forEach(btn => {
194
+ btn.addEventListener('click', () => {
195
+ const theme = btn.dataset.theme;
196
+ localStorage.setItem('chatRouterTheme', theme);
197
+ document.body.className = `bg-gradient-to-br from-${theme}-900 to-purple-900 text-white`;
198
+
199
+ // Update button colors to match theme
200
+ document.querySelectorAll('.bg-indigo-600').forEach(el => {
201
+ el.classList.remove('bg-indigo-600', 'hover:bg-indigo-500');
202
+ el.classList.add(`bg-${theme}-600`, `hover:bg-${theme}-500`);
203
+ });
204
+ });
205
+ });
206
+
207
+ // Modal controls
208
+ settingsBtn.addEventListener('click', () => {
209
+ settingsModal.classList.remove('hidden');
210
+ });
211
+
212
+ closeSettings.addEventListener('click', () => {
213
+ settingsModal.classList.add('hidden');
214
+ });
215
+
216
+ // Auto-resize textarea
217
+ messageInput.addEventListener('input', () => {
218
+ messageInput.style.height = 'auto';
219
+ messageInput.style.height = (messageInput.scrollHeight) + 'px';
220
+ });
221
+
222
+ // Add message to chat
223
+ function addMessage(role, content) {
224
+ const messageDiv = document.createElement('div');
225
+ messageDiv.className = `flex ${role === 'user' ? 'justify-end' : 'justify-start'}`;
226
+
227
+ const bubble = document.createElement('div');
228
+ bubble.className = `message-bubble rounded-2xl px-4 py-3 ${role === 'user' ? 'bg-indigo-600 rounded-tr-none' : 'bg-gray-700 rounded-tl-none'}`;
229
+ bubble.textContent = content;
230
+
231
+ messageDiv.appendChild(bubble);
232
+ chatContainer.appendChild(messageDiv);
233
+ chatContainer.scrollTop = chatContainer.scrollHeight;
234
+ }
235
+
236
+ // Send message to OpenRouter
237
+ async function sendMessage() {
238
+ const message = messageInput.value.trim();
239
+ if (!message) return;
240
+
241
+ const apiKey = localStorage.getItem('chatRouterApiKey');
242
+ const model = localStorage.getItem('chatRouterModel');
243
+
244
+ if (!apiKey || !model) {
245
+ addMessage('system', 'Please configure your API key and model in settings first.');
246
+ return;
247
+ }
248
+
249
+ // Add user message to chat
250
+ addMessage('user', message);
251
+ messageInput.value = '';
252
+ messageInput.style.height = 'auto';
253
+
254
+ // Show typing indicator
255
+ typingIndicator.classList.remove('hidden');
256
+
257
+ try {
258
+ const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
259
+ method: 'POST',
260
+ headers: {
261
+ 'Content-Type': 'application/json',
262
+ 'Authorization': `Bearer ${apiKey}`,
263
+ 'HTTP-Referer': window.location.href,
264
+ 'X-Title': 'ChatRouter'
265
+ },
266
+ body: JSON.stringify({
267
+ model: model,
268
+ messages: [{ role: 'user', content: message }]
269
+ })
270
+ });
271
+
272
+ const data = await response.json();
273
+ if (data.error) {
274
+ addMessage('system', `Error: ${data.error.message}`);
275
+ } else if (data.choices && data.choices[0].message.content) {
276
+ addMessage('assistant', data.choices[0].message.content);
277
+ }
278
+ } catch (error) {
279
+ addMessage('system', `Error: ${error.message}`);
280
+ } finally {
281
+ typingIndicator.classList.add('hidden');
282
+ }
283
+ }
284
+
285
+ // Event listeners
286
+ messageInput.addEventListener('keydown', (e) => {
287
+ if (e.key === 'Enter' && !e.shiftKey) {
288
+ e.preventDefault();
289
+ sendMessage();
290
+ }
291
+ });
292
+
293
+ sendBtn.addEventListener('click', sendMessage);
294
+
295
+ // Initialize
296
+ loadSettings();
297
+
298
+ // Welcome message
299
+ setTimeout(() => {
300
+ if (!localStorage.getItem('chatRouterApiKey')) {
301
+ addMessage('system', 'Welcome to ChatRouter! Please enter your OpenRouter API key in settings to begin.');
302
+ }
303
+ }, 1000);
304
+ </script>
305
+ </body>
306
  </html>