maxwellb-hf commited on
Commit
a1022f8
·
verified ·
1 Parent(s): a423c0b

Error loading models... use the correct models endpoint to load models, and the generate endpoint to generate, from the same server - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +6 -4
  2. index.html +418 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Ygwyg
3
- emoji: 💻
4
  colorFrom: yellow
5
- colorTo: indigo
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: ygwyg
3
+ emoji: 🐳
4
  colorFrom: yellow
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,418 @@
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>Ollama Chat Interface</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ /* Custom scrollbar */
11
+ .custom-scrollbar::-webkit-scrollbar {
12
+ width: 6px;
13
+ }
14
+ .custom-scrollbar::-webkit-scrollbar-track {
15
+ background: #f1f1f1;
16
+ border-radius: 10px;
17
+ }
18
+ .custom-scrollbar::-webkit-scrollbar-thumb {
19
+ background: #888;
20
+ border-radius: 10px;
21
+ }
22
+ .custom-scrollbar::-webkit-scrollbar-thumb:hover {
23
+ background: #555;
24
+ }
25
+
26
+ /* Animation for message loading */
27
+ @keyframes pulse {
28
+ 0%, 100% { opacity: 0.6; }
29
+ 50% { opacity: 1; }
30
+ }
31
+ .animate-pulse {
32
+ animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
33
+ }
34
+
35
+ /* Smooth transitions */
36
+ .transition-all {
37
+ transition-property: all;
38
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
39
+ transition-duration: 200ms;
40
+ }
41
+ </style>
42
+ </head>
43
+ <body class="bg-gray-100 h-screen flex flex-col">
44
+ <!-- Header -->
45
+ <header class="bg-indigo-600 text-white shadow-md">
46
+ <div class="container mx-auto px-4 py-3 flex justify-between items-center">
47
+ <div class="flex items-center space-x-2">
48
+ <i class="fas fa-robot text-2xl"></i>
49
+ <h1 class="text-xl font-bold">Ollama Chat</h1>
50
+ </div>
51
+ <div class="flex items-center space-x-4">
52
+ <button id="settings-btn" class="p-2 rounded-full hover:bg-indigo-700 transition-all">
53
+ <i class="fas fa-cog"></i>
54
+ </button>
55
+ <button id="clear-btn" class="px-3 py-1 bg-indigo-700 rounded-md hover:bg-indigo-800 transition-all">
56
+ <i class="fas fa-trash-alt mr-1"></i> Clear
57
+ </button>
58
+ </div>
59
+ </div>
60
+ </header>
61
+
62
+ <!-- Settings Modal -->
63
+ <div id="settings-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
64
+ <div class="bg-white rounded-lg shadow-xl w-full max-w-md">
65
+ <div class="flex justify-between items-center border-b px-4 py-3">
66
+ <h3 class="text-lg font-semibold">Settings</h3>
67
+ <button id="close-settings" class="text-gray-500 hover:text-gray-700">
68
+ <i class="fas fa-times"></i>
69
+ </button>
70
+ </div>
71
+ <div class="p-4">
72
+ <div class="mb-4">
73
+ <label class="block text-gray-700 text-sm font-bold mb-2" for="endpoint">
74
+ Ollama Endpoint
75
+ </label>
76
+ <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
77
+ id="endpoint" type="text" placeholder="http://localhost:11434/api/generate" value="http://localhost:11434/api/generate">
78
+ </div>
79
+ <div class="mb-4">
80
+ <label class="block text-gray-700 text-sm font-bold mb-2" for="model">
81
+ Model
82
+ </label>
83
+ <select class="shadow border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" id="model">
84
+ <option value="">Loading models...</option>
85
+ </select>
86
+ </div>
87
+ <div class="mb-4">
88
+ <label class="block text-gray-700 text-sm font-bold mb-2" for="temperature">
89
+ Temperature: <span id="temp-value">0.7</span>
90
+ </label>
91
+ <input type="range" id="temperature" min="0" max="1" step="0.1" value="0.7"
92
+ class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
93
+ </div>
94
+ </div>
95
+ <div class="flex justify-end border-t px-4 py-3">
96
+ <button id="save-settings" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition-all">
97
+ Save
98
+ </button>
99
+ </div>
100
+ </div>
101
+ </div>
102
+
103
+ <!-- Chat Container -->
104
+ <div class="flex-1 overflow-hidden container mx-auto px-4 py-4 flex flex-col">
105
+ <div id="chat-messages" class="flex-1 overflow-y-auto custom-scrollbar mb-4 space-y-4">
106
+ <!-- Messages will be inserted here -->
107
+ <div class="welcome-message bg-white p-4 rounded-lg shadow">
108
+ <div class="flex items-start space-x-3">
109
+ <div class="flex-shrink-0 bg-indigo-100 p-2 rounded-full">
110
+ <i class="fas fa-robot text-indigo-600"></i>
111
+ </div>
112
+ <div>
113
+ <h3 class="font-bold text-gray-800">Ollama Assistant</h3>
114
+ <p class="text-gray-600 mt-1">Hello! I'm your Ollama-powered AI assistant. How can I help you today?</p>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ </div>
119
+
120
+ <!-- Input Area -->
121
+ <div class="bg-white rounded-lg shadow-md border border-gray-200 p-4">
122
+ <div class="flex items-end space-x-2">
123
+ <div class="flex-1">
124
+ <textarea id="user-input" rows="2"
125
+ class="w-full px-3 py-2 text-gray-700 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 resize-none"
126
+ placeholder="Type your message here..."></textarea>
127
+ </div>
128
+ <button id="send-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white p-3 rounded-lg transition-all">
129
+ <i class="fas fa-paper-plane"></i>
130
+ </button>
131
+ </div>
132
+ <div class="flex justify-between items-center mt-2 text-sm text-gray-500">
133
+ <div>
134
+ <span id="char-count">0</span>/1000
135
+ </div>
136
+ <div class="flex space-x-2">
137
+ <button id="upload-btn" class="text-gray-500 hover:text-indigo-600 transition-all">
138
+ <i class="fas fa-paperclip"></i>
139
+ </button>
140
+ <button id="mic-btn" class="text-gray-500 hover:text-indigo-600 transition-all">
141
+ <i class="fas fa-microphone"></i>
142
+ </button>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </div>
147
+
148
+ <script>
149
+ document.addEventListener('DOMContentLoaded', function() {
150
+ // DOM Elements
151
+ const chatMessages = document.getElementById('chat-messages');
152
+ const userInput = document.getElementById('user-input');
153
+ const sendBtn = document.getElementById('send-btn');
154
+ const clearBtn = document.getElementById('clear-btn');
155
+ const settingsBtn = document.getElementById('settings-btn');
156
+ const settingsModal = document.getElementById('settings-modal');
157
+ const closeSettings = document.getElementById('close-settings');
158
+ const saveSettings = document.getElementById('save-settings');
159
+ const charCount = document.getElementById('char-count');
160
+ const tempValue = document.getElementById('temp-value');
161
+ const temperature = document.getElementById('temperature');
162
+
163
+ // Configuration
164
+ let config = {
165
+ endpoint: 'http://localhost:11434/api/generate',
166
+ model: '',
167
+ temperature: 0.7
168
+ };
169
+
170
+ // Load saved settings from localStorage
171
+ if (localStorage.getItem('ollamaConfig')) {
172
+ config = JSON.parse(localStorage.getItem('ollamaConfig'));
173
+ document.getElementById('endpoint').value = config.endpoint;
174
+ document.getElementById('model').value = config.model;
175
+ document.getElementById('temperature').value = config.temperature;
176
+ tempValue.textContent = config.temperature;
177
+ } else {
178
+ document.getElementById('endpoint').value = config.endpoint;
179
+ }
180
+
181
+ // Fetch available models from server
182
+ fetchAvailableModels();
183
+
184
+ // Event Listeners
185
+ userInput.addEventListener('input', updateCharCount);
186
+ userInput.addEventListener('keydown', function(e) {
187
+ if (e.key === 'Enter' && !e.shiftKey) {
188
+ e.preventDefault();
189
+ sendMessage();
190
+ }
191
+ });
192
+
193
+ sendBtn.addEventListener('click', sendMessage);
194
+ clearBtn.addEventListener('click', clearChat);
195
+ settingsBtn.addEventListener('click', () => {
196
+ settingsModal.classList.remove('hidden');
197
+ fetchAvailableModels();
198
+ });
199
+ closeSettings.addEventListener('click', () => settingsModal.classList.add('hidden'));
200
+ saveSettings.addEventListener('click', saveSettingsHandler);
201
+ temperature.addEventListener('input', function() {
202
+ tempValue.textContent = this.value;
203
+ });
204
+
205
+ // Functions
206
+ async function fetchAvailableModels() {
207
+ const modelSelect = document.getElementById('model');
208
+
209
+ try {
210
+ // Show loading state
211
+ modelSelect.innerHTML = '<option value="">Loading models...</option>';
212
+
213
+ const response = await fetch(`${config.endpoint.replace('/api/generate', '')}/api/tags`);
214
+ if (!response.ok) {
215
+ throw new Error(`HTTP error! status: ${response.status}`);
216
+ }
217
+
218
+ const data = await response.json();
219
+ modelSelect.innerHTML = '';
220
+
221
+ if (data.models && data.models.length > 0) {
222
+ data.models.forEach(model => {
223
+ const option = document.createElement('option');
224
+ option.value = model.name;
225
+ option.textContent = model.name;
226
+ if (model.details) {
227
+ option.textContent += ` (${model.details.family})`;
228
+ }
229
+ modelSelect.appendChild(option);
230
+ });
231
+
232
+ // Restore selected model if available
233
+ if (config.model) {
234
+ modelSelect.value = config.model;
235
+ } else if (data.models.length > 0) {
236
+ // Set first model as default if none is selected
237
+ config.model = data.models[0].name;
238
+ modelSelect.value = config.model;
239
+ }
240
+ } else {
241
+ throw new Error('No models available');
242
+ }
243
+ } catch (error) {
244
+ console.error('Error fetching models:', error);
245
+ modelSelect.innerHTML = '<option value="">Error loading models</option>';
246
+
247
+ // Add fallback options
248
+ const fallbackModels = ['llama2', 'mistral', 'gemma', 'phi'];
249
+ fallbackModels.forEach(model => {
250
+ const option = document.createElement('option');
251
+ option.value = model;
252
+ option.textContent = model;
253
+ modelSelect.appendChild(option);
254
+ });
255
+
256
+ if (config.model) {
257
+ modelSelect.value = config.model;
258
+ }
259
+ }
260
+ }
261
+
262
+ function updateCharCount() {
263
+ const count = userInput.value.length;
264
+ charCount.textContent = count;
265
+
266
+ if (count > 1000) {
267
+ charCount.classList.add('text-red-500');
268
+ } else {
269
+ charCount.classList.remove('text-red-500');
270
+ }
271
+ }
272
+
273
+ function sendMessage() {
274
+ const message = userInput.value.trim();
275
+ if (!message) return;
276
+
277
+ // Add user message to chat
278
+ addMessage('user', message);
279
+ userInput.value = '';
280
+ updateCharCount();
281
+
282
+ // Add loading indicator for AI response
283
+ const loadingId = addLoadingIndicator();
284
+
285
+ // Prepare request data
286
+ const requestData = {
287
+ model: config.model,
288
+ prompt: message,
289
+ stream: false,
290
+ options: {
291
+ temperature: parseFloat(config.temperature)
292
+ }
293
+ };
294
+
295
+ // Send request to Ollama endpoint
296
+ fetch(`${config.endpoint.replace('/api/tags', '/api/generate')}`, {
297
+ method: 'POST',
298
+ headers: {
299
+ 'Content-Type': 'application/json'
300
+ },
301
+ body: JSON.stringify(requestData)
302
+ })
303
+ .then(response => {
304
+ if (!response.ok) {
305
+ throw new Error(`HTTP error! status: ${response.status}`);
306
+ }
307
+ return response.json();
308
+ })
309
+ .then(data => {
310
+ // Remove loading indicator
311
+ removeLoadingIndicator(loadingId);
312
+
313
+ // Add AI response to chat
314
+ if (data.response) {
315
+ addMessage('ai', data.response);
316
+ } else {
317
+ addMessage('ai', "I'm sorry, I couldn't process your request. Please try again.");
318
+ }
319
+ })
320
+ .catch(error => {
321
+ console.error('Error:', error);
322
+ removeLoadingIndicator(loadingId);
323
+ addMessage('ai', `Error: ${error.message}`);
324
+ });
325
+ }
326
+
327
+ function addMessage(sender, text) {
328
+ const messageDiv = document.createElement('div');
329
+ messageDiv.className = `message ${sender}-message bg-white p-4 rounded-lg shadow ${sender === 'user' ? 'bg-indigo-50' : ''}`;
330
+
331
+ messageDiv.innerHTML = `
332
+ <div class="flex items-start space-x-3">
333
+ <div class="flex-shrink-0 ${sender === 'user' ? 'bg-indigo-600 text-white' : 'bg-indigo-100 text-indigo-600'} p-2 rounded-full">
334
+ <i class="fas ${sender === 'user' ? 'fa-user' : 'fa-robot'}"></i>
335
+ </div>
336
+ <div class="flex-1">
337
+ <h3 class="font-bold text-gray-800">${sender === 'user' ? 'You' : 'Ollama AI'}</h3>
338
+ <p class="text-gray-600 mt-1 whitespace-pre-wrap">${text}</p>
339
+ </div>
340
+ </div>
341
+ `;
342
+
343
+ chatMessages.appendChild(messageDiv);
344
+ chatMessages.scrollTop = chatMessages.scrollHeight;
345
+ }
346
+
347
+ function addLoadingIndicator() {
348
+ const id = 'loading-' + Date.now();
349
+ const loadingDiv = document.createElement('div');
350
+ loadingDiv.id = id;
351
+ loadingDiv.className = 'message ai-message bg-white p-4 rounded-lg shadow';
352
+
353
+ loadingDiv.innerHTML = `
354
+ <div class="flex items-start space-x-3">
355
+ <div class="flex-shrink-0 bg-indigo-100 p-2 rounded-full">
356
+ <i class="fas fa-robot text-indigo-600"></i>
357
+ </div>
358
+ <div class="flex-1">
359
+ <h3 class="font-bold text-gray-800">Ollama AI</h3>
360
+ <div class="flex space-x-2 mt-2">
361
+ <div class="w-2 h-2 bg-gray-400 rounded-full animate-pulse"></div>
362
+ <div class="w-2 h-2 bg-gray-400 rounded-full animate-pulse delay-100"></div>
363
+ <div class="w-2 h-2 bg-gray-400 rounded-full animate-pulse delay-200"></div>
364
+ </div>
365
+ </div>
366
+ </div>
367
+ `;
368
+
369
+ chatMessages.appendChild(loadingDiv);
370
+ chatMessages.scrollTop = chatMessages.scrollHeight;
371
+ return id;
372
+ }
373
+
374
+ function removeLoadingIndicator(id) {
375
+ const element = document.getElementById(id);
376
+ if (element) {
377
+ element.remove();
378
+ }
379
+ }
380
+
381
+ function clearChat() {
382
+ // Keep only the welcome message
383
+ const welcomeMessage = document.querySelector('.welcome-message');
384
+ chatMessages.innerHTML = '';
385
+ if (welcomeMessage) {
386
+ chatMessages.appendChild(welcomeMessage);
387
+ }
388
+ }
389
+
390
+ function saveSettingsHandler() {
391
+ config.endpoint = document.getElementById('endpoint').value;
392
+ config.model = document.getElementById('model').value;
393
+ config.temperature = parseFloat(document.getElementById('temperature').value);
394
+
395
+ // Save to localStorage
396
+ localStorage.setItem('ollamaConfig', JSON.stringify(config));
397
+
398
+ // Close modal
399
+ settingsModal.classList.add('hidden');
400
+
401
+ // Show confirmation
402
+ const confirmation = document.createElement('div');
403
+ confirmation.className = 'fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-md shadow-lg flex items-center space-x-2';
404
+ confirmation.innerHTML = `
405
+ <i class="fas fa-check-circle"></i>
406
+ <span>Settings saved successfully!</span>
407
+ `;
408
+ document.body.appendChild(confirmation);
409
+
410
+ setTimeout(() => {
411
+ confirmation.classList.add('opacity-0');
412
+ setTimeout(() => confirmation.remove(), 300);
413
+ }, 3000);
414
+ }
415
+ });
416
+ </script>
417
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=maxwellb-hf/ygwyg" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
418
+ </html>