BlackTesla commited on
Commit
b297bac
·
verified ·
1 Parent(s): 0ef754d

Add NextAuth or MetaMask Login: OAuth with Google/GitHub/email or Web3 wallet signature. With the ability to continue without signing in, bringing you back to the home page - Follow Up Deployment

Browse files
Files changed (4) hide show
  1. agents.html +54 -53
  2. chat.html +583 -427
  3. dashboard.html +186 -45
  4. login.html +2 -1
agents.html CHANGED
@@ -106,7 +106,7 @@
106
 
107
  <!-- Agents Grid -->
108
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
109
- <!-- StarCoder Agent -->
110
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="100">
111
  <div class="p-6">
112
  <div class="flex items-center mb-4">
@@ -114,7 +114,7 @@
114
  <i data-feather="code" class="text-indigo-600 w-8 h-8"></i>
115
  </div>
116
  <div>
117
- <h3 class="text-xl font-bold text-gray-900">StarCoder</h3>
118
  <div class="flex items-center mt-1">
119
  <div class="flex items-center text-yellow-400">
120
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
@@ -128,7 +128,7 @@
128
  </div>
129
  </div>
130
  <p class="text-gray-600 mb-4">
131
- Specializes in code generation, completion, and debugging across multiple programming languages.
132
  </p>
133
  <div class="mb-4">
134
  <span class="badge bg-green-100 text-green-800">Local Model</span>
@@ -144,20 +144,20 @@
144
  </div>
145
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
146
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
147
- Chat with StarCoder
148
  </button>
149
  </div>
150
  </div>
151
 
152
- <!-- MediaGuru Agent -->
153
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="200">
154
  <div class="p-6">
155
  <div class="flex items-center mb-4">
156
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
157
- <i data-feather="video" class="text-indigo-600 w-8 h-8"></i>
158
  </div>
159
  <div>
160
- <h3 class="text-xl font-bold text-gray-900">MediaGuru</h3>
161
  <div class="flex items-center mt-1">
162
  <div class="flex items-center text-yellow-400">
163
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
@@ -171,35 +171,35 @@
171
  </div>
172
  </div>
173
  <p class="text-gray-600 mb-4">
174
- Handles audio, video, and image processing with Whisper and Gemini Vision APIs.
175
  </p>
176
  <div class="mb-4">
177
  <span class="badge bg-blue-100 text-blue-800">Multimodal</span>
178
- <span class="badge bg-pink-100 text-pink-800 ml-2">Cloud API</span>
179
  </div>
180
  <div class="flex flex-wrap">
181
- <span class="skill-tag">Audio Processing</span>
182
- <span class="skill-tag">Video Analysis</span>
183
- <span class="skill-tag">Image Recognition</span>
184
- <span class="skill-tag">Speech to Text</span>
185
  </div>
186
  </div>
187
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
188
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
189
- Chat with MediaGuru
190
  </button>
191
  </div>
192
  </div>
193
 
194
- <!-- Mistral Agent -->
195
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="300">
196
  <div class="p-6">
197
  <div class="flex items-center mb-4">
198
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
199
- <i data-feather="book" class="text-indigo-600 w-8 h-8"></i>
200
  </div>
201
  <div>
202
- <h3 class="text-xl font-bold text-gray-900">Mistral</h3>
203
  <div class="flex items-center mt-1">
204
  <div class="flex items-center text-yellow-400">
205
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
@@ -213,35 +213,35 @@
213
  </div>
214
  </div>
215
  <p class="text-gray-600 mb-4">
216
- General purpose AI with strong reasoning capabilities and broad knowledge base.
217
  </p>
218
  <div class="mb-4">
219
  <span class="badge bg-green-100 text-green-800">Local Model</span>
220
  <span class="badge bg-orange-100 text-orange-800 ml-2">Reasoning</span>
221
  </div>
222
  <div class="flex flex-wrap">
223
- <span class="skill-tag">General Knowledge</span>
224
- <span class="skill-tag">Problem Solving</span>
225
- <span class="skill-tag">Writing</span>
226
  <span class="skill-tag">Summarization</span>
227
  </div>
228
  </div>
229
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
230
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
231
- Chat with Mistral
232
  </button>
233
  </div>
234
  </div>
235
 
236
- <!-- FinLLaMA Agent -->
237
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="400">
238
  <div class="p-6">
239
  <div class="flex items-center mb-4">
240
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
241
- <i data-feather="dollar-sign" class="text-indigo-600 w-8 h-8"></i>
242
  </div>
243
  <div>
244
- <h3 class="text-xl font-bold text-gray-900">FinLLaMA</h3>
245
  <div class="flex items-center mt-1">
246
  <div class="flex items-center text-yellow-400">
247
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
@@ -255,35 +255,35 @@
255
  </div>
256
  </div>
257
  <p class="text-gray-600 mb-4">
258
- Specialized in financial analysis, market trends, and investment strategies.
259
  </p>
260
  <div class="mb-4">
261
  <span class="badge bg-green-100 text-green-800">Local Model</span>
262
  <span class="badge bg-yellow-100 text-yellow-800 ml-2">Finance</span>
263
  </div>
264
  <div class="flex flex-wrap">
265
- <span class="skill-tag">Financial Analysis</span>
 
266
  <span class="skill-tag">Market Trends</span>
267
- <span class="skill-tag">Investment</span>
268
- <span class="skill-tag">Risk Assessment</span>
269
  </div>
270
  </div>
271
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
272
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
273
- Chat with FinLLaMA
274
  </button>
275
  </div>
276
  </div>
277
 
278
- <!-- SeamlessM4T Agent -->
279
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="500">
280
  <div class="p-6">
281
  <div class="flex items-center mb-4">
282
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
283
- <i data-feather="globe" class="text-indigo-600 w-8 h-8"></i>
284
  </div>
285
  <div>
286
- <h3 class="text-xl font-bold text-gray-900">SeamlessM4T</h3>
287
  <div class="flex items-center mt-1">
288
  <div class="flex items-center text-yellow-400">
289
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
@@ -292,40 +292,40 @@
292
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
293
  <i data-feather="star" class="w-4 h-4"></i>
294
  </div>
295
- <span class="text-gray-500 text-sm ml-2">(4.3)</span>
296
  </div>
297
  </div>
298
  </div>
299
  <p class="text-gray-600 mb-4">
300
- Multilingual translation and transcription with near-human accuracy.
301
  </p>
302
  <div class="mb-4">
303
- <span class="badge bg-blue-100 text-blue-800">Multimodal</span>
304
- <span class="badge bg-purple-100 text-purple-800 ml-2">Translation</span>
305
  </div>
306
  <div class="flex flex-wrap">
307
- <span class="skill-tag">Translation</span>
308
- <span class="skill-tag">Transcription</span>
309
- <span class="skill-tag">100+ Languages</span>
310
- <span class="skill-tag">Speech-to-Text</span>
311
  </div>
312
  </div>
313
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
314
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
315
- Chat with SeamlessM4T
316
  </button>
317
  </div>
318
  </div>
319
 
320
- <!-- Mixtral Agent -->
321
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="600">
322
  <div class="p-6">
323
  <div class="flex items-center mb-4">
324
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
325
- <i data-feather="layers" class="text-indigo-600 w-8 h-8"></i>
326
  </div>
327
  <div>
328
- <h3 class="text-xl font-bold text-gray-900">Mixtral</h3>
329
  <div class="flex items-center mt-1">
330
  <div class="flex items-center text-yellow-400">
331
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
@@ -339,22 +339,22 @@
339
  </div>
340
  </div>
341
  <p class="text-gray-600 mb-4">
342
- Mixture of experts model excelling in complex problem solving and creative tasks.
343
  </p>
344
  <div class="mb-4">
345
- <span class="badge bg-green-100 text-green-800">Local Model</span>
346
- <span class="badge bg-red-100 text-red-800 ml-2">Expert</span>
347
  </div>
348
  <div class="flex flex-wrap">
349
- <span class="skill-tag">Problem Solving</span>
350
- <span class="skill-tag">Creativity</span>
351
- <span class="skill-tag">Research</span>
352
- <span class="skill-tag">Analysis</span>
353
  </div>
354
  </div>
355
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
356
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
357
- Chat with Mixtral
358
  </button>
359
  </div>
360
  </div>
@@ -449,3 +449,4 @@
449
  </script>
450
  </body>
451
  </html>
 
 
106
 
107
  <!-- Agents Grid -->
108
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
109
+ <!-- Satoshi — Coding Bot -->
110
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="100">
111
  <div class="p-6">
112
  <div class="flex items-center mb-4">
 
114
  <i data-feather="code" class="text-indigo-600 w-8 h-8"></i>
115
  </div>
116
  <div>
117
+ <h3 class="text-xl font-bold text-gray-900">Satoshi</h3>
118
  <div class="flex items-center mt-1">
119
  <div class="flex items-center text-yellow-400">
120
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
 
128
  </div>
129
  </div>
130
  <p class="text-gray-600 mb-4">
131
+ Coding Bot: code generation, completion, and debugging across multiple programming languages.
132
  </p>
133
  <div class="mb-4">
134
  <span class="badge bg-green-100 text-green-800">Local Model</span>
 
144
  </div>
145
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
146
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
147
+ Chat with Satoshi
148
  </button>
149
  </div>
150
  </div>
151
 
152
+ <!-- Basqui — Art Bot -->
153
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="200">
154
  <div class="p-6">
155
  <div class="flex items-center mb-4">
156
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
157
+ <i data-feather="image" class="text-indigo-600 w-8 h-8"></i>
158
  </div>
159
  <div>
160
+ <h3 class="text-xl font-bold text-gray-900">Basqui</h3>
161
  <div class="flex items-center mt-1">
162
  <div class="flex items-center text-yellow-400">
163
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
 
171
  </div>
172
  </div>
173
  <p class="text-gray-600 mb-4">
174
+ Art Bot: generates and edits images, styles, and concepts; assists with prompts and visual workflows.
175
  </p>
176
  <div class="mb-4">
177
  <span class="badge bg-blue-100 text-blue-800">Multimodal</span>
178
+ <span class="badge bg-pink-100 text-pink-800 ml-2">Image Tools</span>
179
  </div>
180
  <div class="flex flex-wrap">
181
+ <span class="skill-tag">Image Generation</span>
182
+ <span class="skill-tag">Image Editing</span>
183
+ <span class="skill-tag">Style Transfer</span>
184
+ <span class="skill-tag">Prompt Crafting</span>
185
  </div>
186
  </div>
187
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
188
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
189
+ Chat with Basqui
190
  </button>
191
  </div>
192
  </div>
193
 
194
+ <!-- Socrates — Reasoning -->
195
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="300">
196
  <div class="p-6">
197
  <div class="flex items-center mb-4">
198
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
199
+ <i data-feather="book-open" class="text-indigo-600 w-8 h-8"></i>
200
  </div>
201
  <div>
202
+ <h3 class="text-xl font-bold text-gray-900">Socrates</h3>
203
  <div class="flex items-center mt-1">
204
  <div class="flex items-center text-yellow-400">
205
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
 
213
  </div>
214
  </div>
215
  <p class="text-gray-600 mb-4">
216
+ Reasoning: structured thinking, problem-solving, analysis, and step-by-step explanations.
217
  </p>
218
  <div class="mb-4">
219
  <span class="badge bg-green-100 text-green-800">Local Model</span>
220
  <span class="badge bg-orange-100 text-orange-800 ml-2">Reasoning</span>
221
  </div>
222
  <div class="flex flex-wrap">
223
+ <span class="skill-tag">Logic</span>
224
+ <span class="skill-tag">Decomposition</span>
225
+ <span class="skill-tag">Planning</span>
226
  <span class="skill-tag">Summarization</span>
227
  </div>
228
  </div>
229
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
230
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
231
+ Chat with Socrates
232
  </button>
233
  </div>
234
  </div>
235
 
236
+ <!-- Wolf — Financial Literacy Bot -->
237
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="400">
238
  <div class="p-6">
239
  <div class="flex items-center mb-4">
240
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
241
+ <i data-feather="trending-up" class="text-indigo-600 w-8 h-8"></i>
242
  </div>
243
  <div>
244
+ <h3 class="text-xl font-bold text-gray-900">Wolf</h3>
245
  <div class="flex items-center mt-1">
246
  <div class="flex items-center text-yellow-400">
247
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
 
255
  </div>
256
  </div>
257
  <p class="text-gray-600 mb-4">
258
+ Financial Literacy Bot: budgeting, fundamentals, market concepts, and risk awareness.
259
  </p>
260
  <div class="mb-4">
261
  <span class="badge bg-green-100 text-green-800">Local Model</span>
262
  <span class="badge bg-yellow-100 text-yellow-800 ml-2">Finance</span>
263
  </div>
264
  <div class="flex flex-wrap">
265
+ <span class="skill-tag">Budgeting</span>
266
+ <span class="skill-tag">Investing Basics</span>
267
  <span class="skill-tag">Market Trends</span>
268
+ <span class="skill-tag">Risk &amp; Reward</span>
 
269
  </div>
270
  </div>
271
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
272
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
273
+ Chat with Wolf
274
  </button>
275
  </div>
276
  </div>
277
 
278
+ <!-- Angelu — Creative Writing Bot -->
279
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="500">
280
  <div class="p-6">
281
  <div class="flex items-center mb-4">
282
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
283
+ <i data-feather="edit-3" class="text-indigo-600 w-8 h-8"></i>
284
  </div>
285
  <div>
286
+ <h3 class="text-xl font-bold text-gray-900">Angelu</h3>
287
  <div class="flex items-center mt-1">
288
  <div class="flex items-center text-yellow-400">
289
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
 
292
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
293
  <i data-feather="star" class="w-4 h-4"></i>
294
  </div>
295
+ <span class="text-gray-500 text-sm ml-2">(4.6)</span>
296
  </div>
297
  </div>
298
  </div>
299
  <p class="text-gray-600 mb-4">
300
+ Creative Writing Bot: stories, scripts, poems, and copy—plus outlining and revisions.
301
  </p>
302
  <div class="mb-4">
303
+ <span class="badge bg-blue-100 text-blue-800">Style</span>
304
+ <span class="badge bg-purple-100 text-purple-800 ml-2">Editing</span>
305
  </div>
306
  <div class="flex flex-wrap">
307
+ <span class="skill-tag">Story Craft</span>
308
+ <span class="skill-tag">Poetry</span>
309
+ <span class="skill-tag">Screenwriting</span>
310
+ <span class="skill-tag">Copywriting</span>
311
  </div>
312
  </div>
313
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
314
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
315
+ Chat with Angelu
316
  </button>
317
  </div>
318
  </div>
319
 
320
+ <!-- DataDoc — Data Science (graphs) -->
321
  <div class="agent-card bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm" data-aos="fade-up" data-aos-delay="600">
322
  <div class="p-6">
323
  <div class="flex items-center mb-4">
324
  <div class="w-16 h-16 rounded-full bg-indigo-100 flex items-center justify-center mr-4">
325
+ <i data-feather="bar-chart-2" class="text-indigo-600 w-8 h-8"></i>
326
  </div>
327
  <div>
328
+ <h3 class="text-xl font-bold text-gray-900">DataDoc</h3>
329
  <div class="flex items-center mt-1">
330
  <div class="flex items-center text-yellow-400">
331
  <i data-feather="star" class="w-4 h-4 fill-current"></i>
 
339
  </div>
340
  </div>
341
  <p class="text-gray-600 mb-4">
342
+ Data Science: explores datasets, builds simple models, and creates charts/graphs for insight.
343
  </p>
344
  <div class="mb-4">
345
+ <span class="badge bg-green-100 text-green-800">Local Tools</span>
346
+ <span class="badge bg-teal-100 text-teal-800 ml-2">Visualization</span>
347
  </div>
348
  <div class="flex flex-wrap">
349
+ <span class="skill-tag">Pandas</span>
350
+ <span class="skill-tag">EDA</span>
351
+ <span class="skill-tag">Charts</span>
352
+ <span class="skill-tag">Dashboards</span>
353
  </div>
354
  </div>
355
  <div class="bg-gray-50 px-6 py-3 border-t border-gray-200 flex justify-end">
356
  <button class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition">
357
+ Chat with DataDoc
358
  </button>
359
  </div>
360
  </div>
 
449
  </script>
450
  </body>
451
  </html>
452
+
chat.html CHANGED
@@ -1,448 +1,604 @@
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>Archindus Chat</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
9
- <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
10
- <script src="https://unpkg.com/feather-icons"></script>
11
- <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
12
- <style>
13
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
14
- body {
15
- font-family: 'Inter', sans-serif;
16
- }
17
- .chat-container {
18
- height: calc(100vh - 140px);
19
- }
20
- .messages-container {
21
- height: calc(90% - 60px);
22
- }
23
- .chat-bubble {
24
- max-width: 80%;
25
- }
26
- .typing-indicator {
27
- display: inline-block;
28
- }
29
- .typing-dot {
30
- display: inline-block;
31
- width: 8px;
32
- height: 8px;
33
- border-radius: 50%;
34
- background-color: #6B7280;
35
- margin-right: 4px;
36
- animation: typing-animation 1.4s infinite ease-in-out;
37
- }
38
- .typing-dot:nth-child(1) {
39
- animation-delay: 0s;
40
- }
41
- .typing-dot:nth-child(2) {
42
- animation-delay: 0.2s;
43
- }
44
- .typing-dot:nth-child(3) {
45
- animation-delay: 0.4s;
46
- margin-right: 0;
47
- }
48
- @keyframes typing-animation {
49
- 0%, 60%, 100% {
50
- transform: translateY(0);
51
- }
52
- 30% {
53
- transform: translateY(-5px);
54
- }
55
- }
56
- .agent-selector:hover .agent-overlay {
57
- opacity: 1;
58
- }
59
- .agent-overlay {
60
- transition: opacity 0.3s ease;
61
- }
62
- </style>
63
  </head>
64
  <body class="bg-gray-50">
65
- <div class="min-h-screen flex flex-col">
66
- <!-- Navigation -->
67
- <nav class="bg-white/80 backdrop-blur-md border-b border-gray-200 px-4 py-3 shadow-sm">
68
- <div class="max-w-7xl mx-auto flex justify-between items-center">
69
- <div class="flex items-center space-x-2">
70
- <i data-feather="cpu" class="text-indigo-600 w-6 h-6"></i>
71
- <span class="text-xl font-bold text-gray-800">Archindus</span>
72
- </div>
73
- <div class="hidden md:flex items-center space-x-6">
74
- <a href="index.html" class="text-gray-600 hover:text-indigo-600 transition">Home</a>
75
- <a href="agents.html" class="text-gray-600 hover:text-indigo-600 transition">Agents</a>
76
- <a href="#" class="text-indigo-600 font-medium">Chat</a>
77
- <a href="dashboard.html" class="text-gray-600 hover:text-indigo-600 transition">Dashboard</a>
78
- </div>
79
- <div class="flex items-center space-x-4">
80
- <button class="md:hidden text-gray-600">
81
- <i data-feather="menu"></i>
82
- </button>
83
- <div class="relative group">
84
- <a href="login.html" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition flex items-center space-x-2">
85
- <i data-feather="log-in" class="w-4 h-4"></i>
86
- <span>Sign In</span>
87
- </a>
88
- <div class="absolute hidden group-hover:block right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1 z-10">
89
- <a href="login.html" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">OAuth Login</a>
90
- <a href="login.html" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">MetaMask</a>
91
- <a href="index.html" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Continue as Guest</a>
92
- </div>
93
- </div>
94
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  </div>
96
- </nav>
97
 
98
- <!-- Main Chat Area -->
99
- <main class="flex-grow">
100
- <div class="max-w-7xl mx-auto px-4 py-6">
101
- <!-- Chat Header -->
102
- <div class="flex items-center justify-between mb-6">
103
- <div>
104
- <h1 class="text-2xl font-bold text-gray-900">AI Chat</h1>
105
- <p class="text-gray-600">Chat with our specialized AI agents</p>
106
- </div>
107
- <div class="flex space-x-2">
108
- <button class="bg-white hover:bg-gray-100 text-gray-800 border border-gray-300 px-4 py-2 rounded-lg transition flex items-center space-x-2">
109
- <i data-feather="plus" class="w-4 h-4"></i>
110
- <span>New Chat</span>
111
- </button>
112
- <button class="bg-white hover:bg-gray-100 text-gray-800 border border-gray-300 px-4 py-2 rounded-lg transition flex items-center space-x-2">
113
- <i data-feather="users" class="w-4 h-4"></i>
114
- <span>Group Chat</span>
115
- </button>
116
- </div>
117
- </div>
118
 
119
- <!-- Chat Layout -->
120
- <div class="flex flex-col lg:flex-row gap-6">
121
- <!-- Agent Selector Sidebar -->
122
- <div class="w-full lg:w-64 bg-white rounded-xl border border-gray-200 shadow-sm p-4 h-fit">
123
- <h2 class="font-semibold text-gray-900 mb-4">Available Agents</h2>
124
- <div class="space-y-3">
125
- <!-- StarCoder -->
126
- <div class="agent-selector relative group">
127
- <div class="flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-50 cursor-pointer border border-gray-200">
128
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
129
- <i data-feather="code" class="text-indigo-600 w-5 h-5"></i>
130
- </div>
131
- <div>
132
- <p class="font-medium text-gray-900">StarCoder</p>
133
- <p class="text-xs text-gray-500">Code Specialist</p>
134
- </div>
135
- </div>
136
- <div class="agent-overlay absolute inset-0 bg-indigo-500/80 rounded-lg opacity-0 flex items-center justify-center">
137
- <button class="text-white px-4 py-1 rounded-lg border border-white">Select</button>
138
- </div>
139
- </div>
140
-
141
- <!-- MediaGuru -->
142
- <div class="agent-selector relative group">
143
- <div class="flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-50 cursor-pointer border border-gray-200">
144
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
145
- <i data-feather="video" class="text-indigo-600 w-5 h-5"></i>
146
- </div>
147
- <div>
148
- <p class="font-medium text-gray-900">MediaGuru</p>
149
- <p class="text-xs text-gray-500">Multimedia</p>
150
- </div>
151
- </div>
152
- <div class="agent-overlay absolute inset-0 bg-indigo-500/80 rounded-lg opacity-0 flex items-center justify-center">
153
- <button class="text-white px-4 py-1 rounded-lg border border-white">Select</button>
154
- </div>
155
- </div>
156
-
157
- <!-- Mistral -->
158
- <div class="agent-selector relative group">
159
- <div class="flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-50 cursor-pointer border border-gray-200 active:bg-indigo-100">
160
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
161
- <i data-feather="book" class="text-indigo-600 w-5 h-5"></i>
162
- </div>
163
- <div>
164
- <p class="font-medium text-gray-900">Mistral</p>
165
- <p class="text-xs text-gray-500">General AI</p>
166
- </div>
167
- </div>
168
- <div class="agent-overlay absolute inset-0 bg-indigo-500/80 rounded-lg opacity-0 flex items-center justify-center">
169
- <button class="text-white px-4 py-1 rounded-lg border border-white">Select</button>
170
- </div>
171
- </div>
172
-
173
- <!-- FinLLaMA -->
174
- <div class="agent-selector relative group">
175
- <div class="flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-50 cursor-pointer border border-gray-200">
176
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
177
- <i data-feather="dollar-sign" class="text-indigo-600 w-5 h-5"></i>
178
- </div>
179
- <div>
180
- <p class="font-medium text-gray-900">FinLLaMA</p>
181
- <p class="text-xs text-gray-500">Finance</p>
182
- </div>
183
- </div>
184
- <div class="agent-overlay absolute inset-0 bg-indigo-500/80 rounded-lg opacity-0 flex items-center justify-center">
185
- <button class="text-white px-4 py-1 rounded-lg border border-white">Select</button>
186
- </div>
187
- </div>
188
-
189
- <!-- SeamlessM4T -->
190
- <div class="agent-selector relative group">
191
- <div class="flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-50 cursor-pointer border border-gray-200">
192
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
193
- <i data-feather="globe" class="text-indigo-600 w-5 h-5"></i>
194
- </div>
195
- <div>
196
- <p class="font-medium text-gray-900">SeamlessM4T</p>
197
- <p class="text-xs text-gray-500">Translation</p>
198
- </div>
199
- </div>
200
- <div class="agent-overlay absolute inset-0 bg-indigo-500/80 rounded-lg opacity-0 flex items-center justify-center">
201
- <button class="text-white px-4 py-1 rounded-lg border border-white">Select</button>
202
- </div>
203
- </div>
204
-
205
- <!-- Mixtral -->
206
- <div class="agent-selector relative group">
207
- <div class="flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-50 cursor-pointer border border-gray-200">
208
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
209
- <i data-feather="layers" class="text-indigo-600 w-5 h-5"></i>
210
- </div>
211
- <div>
212
- <p class="font-medium text-gray-900">Mixtral</p>
213
- <p class="text-xs text-gray-500">Expert Model</p>
214
- </div>
215
- </div>
216
- <div class="agent-overlay absolute inset-0 bg-indigo-500/80 rounded-lg opacity-0 flex items-center justify-center">
217
- <button class="text-white px-4 py-1 rounded-lg border border-white">Select</button>
218
- </div>
219
- </div>
220
- </div>
221
-
222
- <div class="mt-6 pt-4 border-t border-gray-200">
223
- <button class="w-full bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition flex items-center justify-center space-x-2">
224
- <i data-feather="users" class="w-4 h-4"></i>
225
- <span>Add Agents</span>
226
- </button>
227
- </div>
228
- </div>
229
 
230
- <!-- Chat Box -->
231
- <div class="flex-1">
232
- <div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
233
- <!-- Chat Header -->
234
- <div class="border-b border-gray-200 p-4 bg-gray-50">
235
- <div class="flex items-center space-x-3">
236
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
237
- <i data-feather="book" class="text-indigo-600 w-5 h-5"></i>
238
- </div>
239
- <div>
240
- <p class="font-medium text-gray-900">Mistral</p>
241
- <p class="text-xs text-gray-500">General AI • Last active: 2 min ago</p>
242
- </div>
243
- <div class="ml-auto flex space-x-2">
244
- <button class="text-gray-500 hover:text-indigo-600 transition">
245
- <i data-feather="settings" class="w-5 h-5"></i>
246
- </button>
247
- <button class="text-gray-500 hover:text-indigo-600 transition">
248
- <i data-feather="x" class="w-5 h-5"></i>
249
- </button>
250
- </div>
251
- </div>
252
- </div>
253
-
254
- <!-- Messages Container -->
255
- <div class="chat-container">
256
- <div class="messages-container overflow-y-auto p-4">
257
- <!-- Welcome Message -->
258
- <div class="flex mb-6" data-aos="fade-up">
259
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex-shrink-0 flex items-center justify-center mr-3">
260
- <i data-feather="book" class="text-indigo-600 w-5 h-5"></i>
261
- </div>
262
- <div class="chat-bubble bg-indigo-50 rounded-lg p-4">
263
- <p class="font-medium text-indigo-800 mb-1">Mistral</p>
264
- <p class="text-gray-800">Hello! I'm Mistral, your general purpose AI assistant. I can help with a wide range of topics including general knowledge, problem solving, writing, and more. How can I assist you today?</p>
265
- </div>
266
- </div>
267
-
268
- <!-- User Message -->
269
- <div class="flex justify-end mb-6" data-aos="fade-up">
270
- <div class="chat-bubble bg-indigo-600 text-white rounded-lg p-4">
271
- <p class="font-medium mb-1">You</p>
272
- <p>Can you explain how the smart routing works in this platform?</p>
273
- </div>
274
- </div>
275
-
276
- <!-- AI Response -->
277
- <div class="flex mb-6" data-aos="fade-up">
278
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex-shrink-0 flex items-center justify-center mr-3">
279
- <i data-feather="book" class="text-indigo-600 w-5 h-5"></i>
280
- </div>
281
- <div class="chat-bubble bg-indigo-50 rounded-lg p-4">
282
- <p class="font-medium text-indigo-800 mb-1">Mistral</p>
283
- <p class="text-gray-800 mb-2">Certainly! The smart routing system (/chat/smart endpoint) intelligently selects the most appropriate agent based on several factors:</p>
284
- <ul class="list-disc pl-5 space-y-1 text-gray-800 mb-2">
285
- <li><strong>User Preferences:</strong> Your past feedback and ratings influence which agents are selected</li>
286
- <li><strong>Capability Groups:</strong> Agents are grouped by their specialties (coding, finance, etc.)</li>
287
- <li><strong>Performance Metrics:</strong> Each agent has weighted ratings based on response quality</li>
288
- <li><strong>Request Context:</strong> The system analyzes your message to determine the best match</li>
289
- </ul>
290
- <p class="text-gray-800">The router mixes global and user-specific ratings to compute probabilities and can limit selection to agents within a specific capability group if needed.</p>
291
- </div>
292
- </div>
293
-
294
- <!-- Typing Indicator -->
295
- <div class="flex mb-6" id="typing-indicator">
296
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex-shrink-0 flex items-center justify-center mr-3">
297
- <i data-feather="book" class="text-indigo-600 w-5 h-5"></i>
298
- </div>
299
- <div class="chat-bubble bg-indigo-50 rounded-lg p-4">
300
- <p class="font-medium text-indigo-800 mb-1">Mistral</p>
301
- <div class="typing-indicator">
302
- <span class="typing-dot"></span>
303
- <span class="typing-dot"></span>
304
- <span class="typing-dot"></span>
305
- </div>
306
- </div>
307
- </div>
308
- </div>
309
-
310
- <!-- Input Area -->
311
- <div class="border-t border-gray-200 p-4 bg-gray-50">
312
- <div class="flex items-end space-x-3">
313
- <button class="text-gray-500 hover:text-indigo-600 transition mb-1">
314
- <i data-feather="plus" class="w-5 h-5"></i>
315
- </button>
316
- <div class="flex-1 bg-white border border-gray-300 rounded-lg overflow-hidden focus-within:ring-2 focus-within:ring-indigo-500 focus-within:border-indigo-500">
317
- <textarea rows="1" placeholder="Type your message..." class="w-full p-3 resize-none focus:outline-none hovered-element"></textarea>
318
- </div>
319
- <button class="bg-indigo-600 hover:bg-indigo-700 text-white p-3 rounded-lg transition">
320
- <i data-feather="send" class="w-5 h-5"></i>
321
- </button>
322
- </div>
323
- <div class="mt-2 flex items-center justify-between text-xs text-gray-500">
324
- <div>
325
- <button class="hover:text-indigo-600 transition flex items-center space-x-1">
326
- <i data-feather="mic" class="w-4 h-4"></i>
327
- <span>Voice Input</span>
328
- </button>
329
- </div>
330
- <div>
331
- <button class="hover:text-indigo-600 transition flex items-center space-x-1">
332
- <i data-feather="paperclip" class="w-4 h-4"></i>
333
- <span>Attach Files</span>
334
- </button>
335
- </div>
336
- </div>
337
- </div>
338
- </div>
339
- </div>
340
- </div>
341
  </div>
342
- </div>
343
- </main>
344
 
345
- <!-- Footer -->
346
- <footer class="bg-gray-900 text-white py-12 px-4">
347
- <div class="max-w-7xl mx-auto">
348
- <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
349
- <div>
350
- <div class="flex items-center space-x-2 mb-4">
351
- <i data-feather="cpu" class="text-indigo-400 w-6 h-6"></i>
352
- <span class="text-xl font-bold">Archindus</span>
353
- </div>
354
- <p class="text-gray-400">
355
- The most advanced platform for collaborating with specialized AI agents.
356
- </p>
357
- </div>
358
- <div>
359
- <h3 class="text-lg font-semibold mb-4">Platform</h3>
360
- <ul class="space-y-2">
361
- <li><a href="index.html" class="text-gray-400 hover:text-white transition">Home</a></li>
362
- <li><a href="agents.html" class="text-gray-400 hover:text-white transition">Agents</a></li>
363
- <li><a href="#" class="text-gray-400 hover:text-white transition">Chat</a></li>
364
- <li><a href="dashboard.html" class="text-gray-400 hover:text-white transition">Dashboard</a></li>
365
- </ul>
366
  </div>
367
- <div>
368
- <h3 class="text-lg font-semibold mb-4">Resources</h3>
369
- <ul class="space-y-2">
370
- <li><a href="#" class="text-gray-400 hover:text-white transition">Documentation</a></li>
371
- <li><a href="#" class="text-gray-400 hover:text-white transition">API Reference</a></li>
372
- <li><a href="#" class="text-gray-400 hover:text-white transition">Community</a></li>
373
- <li><a href="#" class="text-gray-400 hover:text-white transition">Support</a></li>
374
- </ul>
375
  </div>
376
  <div>
377
- <h3 class="text-lg font-semibold mb-4">Legal</h3>
378
- <ul class="space-y-2">
379
- <li><a href="#" class="text-gray-400 hover:text-white transition">Privacy Policy</a></li>
380
- <li><a href="#" class="text-gray-400 hover:text-white transition">Terms of Service</a></li>
381
- <li><a href="#" class="text-gray-400 hover:text-white transition">Cookie Policy</a></li>
382
- </ul>
383
- </div>
384
- </div>
385
- <div class="border-t border-gray-800 mt-12 pt-8 flex flex-col md:flex-row justify-between items-center">
386
- <p class="text-gray-400 mb-4 md:mb-0">© 2023 Architect Industries Inc. All rights reserved.</p>
387
- <div class="flex space-x-6">
388
- <a href="#" class="text-gray-400 hover:text-white transition">
389
- <i data-feather="twitter" class="w-5 h-5"></i>
390
- </a>
391
- <a href="#" class="text-gray-400 hover:text-white transition">
392
- <i data-feather="github" class="w-5 h-5"></i>
393
- </a>
394
- <a href="#" class="text-gray-400 hover:text-white transition">
395
- <i data-feather="linkedin" class="w-5 h-5"></i>
396
- </a>
397
- <a href="#" class="text-gray-400 hover:text-white transition">
398
- <i data-feather="discord" class="w-5 h-5"></i>
399
- </a>
400
  </div>
 
401
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
  </div>
403
- </footer>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  </div>
 
405
 
406
- <script>
407
- AOS.init({
408
- duration: 800,
409
- easing: 'ease-in-out',
410
- once: true
411
- });
412
- </script>
413
- <script>
414
- feather.replace();
415
-
416
- // Simulate typing indicator
417
- setTimeout(() => {
418
- document.getElementById('typing-indicator').style.display = 'none';
419
-
420
- // Add new message
421
- const messagesContainer = document.querySelector('.messages-container');
422
- const newMessage = document.createElement('div');
423
- newMessage.className = 'flex mb-6';
424
- newMessage.innerHTML = `
425
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex-shrink-0 flex items-center justify-center mr-3">
426
- <i data-feather="book" class="text-indigo-600 w-5 h-5"></i>
427
- </div>
428
- <div class="chat-bubble bg-indigo-50 rounded-lg p-4">
429
- <p class="font-medium text-indigo-800 mb-1">Mistral</p>
430
- <p class="text-gray-800">Additionally, you can specify particular agents or capability groups when making requests to override the smart routing if needed.</p>
431
- </div>
432
- `;
433
- messagesContainer.appendChild(newMessage);
434
- feather.replace();
435
-
436
- // Scroll to bottom
437
- messagesContainer.scrollTop = messagesContainer.scrollHeight;
438
- }, 2000);
439
-
440
- // Auto-expand textarea
441
- const textarea = document.querySelector('textarea');
442
- textarea.addEventListener('input', function() {
443
- this.style.height = 'auto';
444
- this.style.height = (this.scrollHeight) + 'px';
445
- });
446
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  </body>
448
  </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>Archindus Chat</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
9
+ <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
12
+ <style>
13
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
14
+ body { font-family: 'Inter', sans-serif; }
15
+ .chat-container { height: calc(100vh - 140px); }
16
+ .messages-container { height: calc(90% - 60px); }
17
+ .chat-bubble { max-width: 80%; }
18
+ .typing-indicator { display: inline-block; }
19
+ .typing-dot {
20
+ display: inline-block; width: 8px; height: 8px; border-radius: 50%;
21
+ background-color: #6B7280; margin-right: 4px; animation: typing-animation 1.4s infinite ease-in-out;
22
+ }
23
+ .typing-dot:nth-child(1) { animation-delay: 0s; }
24
+ .typing-dot:nth-child(2) { animation-delay: 0.2s; }
25
+ .typing-dot:nth-child(3) { animation-delay: 0.4s; margin-right: 0; }
26
+ @keyframes typing-animation {
27
+ 0%, 60%, 100% { transform: translateY(0); }
28
+ 30% { transform: translateY(-5px); }
29
+ }
30
+ .agent-selector:hover .agent-overlay { opacity: 1; }
31
+ .agent-overlay { transition: opacity 0.3s ease; }
32
+ .scrollbar-thin::-webkit-scrollbar { height: 6px; width: 6px; }
33
+ .scrollbar-thin::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 9999px; }
34
+ .scrollbar-thin::-webkit-scrollbar-track { background: transparent; }
35
+ .modal-bg { background: rgba(0,0,0,0.5); }
36
+ </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  </head>
38
  <body class="bg-gray-50">
39
+ <div class="min-h-screen flex flex-col">
40
+ <!-- Navigation -->
41
+ <nav class="bg-white/80 backdrop-blur-md border-b border-gray-200 px-4 py-3 shadow-sm">
42
+ <div class="max-w-7xl mx-auto flex justify-between items-center">
43
+ <div class="flex items-center space-x-2">
44
+ <i data-feather="cpu" class="text-indigo-600 w-6 h-6"></i>
45
+ <span class="text-xl font-bold text-gray-800">Archindus</span>
46
+ </div>
47
+ <div class="hidden md:flex items-center space-x-6">
48
+ <a href="index.html" class="text-gray-600 hover:text-indigo-600 transition">Home</a>
49
+ <a href="agents.html" class="text-gray-600 hover:text-indigo-600 transition">Agents</a>
50
+ <a href="#" class="text-indigo-600 font-medium">Chat</a>
51
+ <a href="dashboard.html" class="text-gray-600 hover:text-indigo-600 transition">Dashboard</a>
52
+ </div>
53
+ <div class="flex items-center space-x-2">
54
+ <button id="btn-hf-connect" class="bg-white hover:bg-gray-100 text-gray-800 border border-gray-300 px-3 py-2 rounded-lg transition flex items-center space-x-2">
55
+ <i data-feather="plug" class="w-4 h-4"></i>
56
+ <span>Connect Hugging Face</span>
57
+ </button>
58
+ <button class="md:hidden text-gray-600">
59
+ <i data-feather="menu"></i>
60
+ </button>
61
+ </div>
62
+ </div>
63
+ </nav>
64
+
65
+ <!-- Main Chat Area -->
66
+ <main class="flex-grow">
67
+ <div class="max-w-7xl mx-auto px-4 py-6">
68
+ <!-- Chat Header -->
69
+ <div class="flex items-center justify-between mb-6">
70
+ <div>
71
+ <h1 class="text-2xl font-bold text-gray-900">AI Chat</h1>
72
+ <p class="text-gray-600">Chat with our specialized AI agents</p>
73
+ </div>
74
+ <div class="flex space-x-2">
75
+ <button id="btn-new-chat" class="bg-white hover:bg-gray-100 text-gray-800 border border-gray-300 px-4 py-2 rounded-lg transition flex items-center space-x-2">
76
+ <i data-feather="plus" class="w-4 h-4"></i>
77
+ <span>New Chat</span>
78
+ </button>
79
+ <button class="bg-white hover:bg-gray-100 text-gray-800 border border-gray-300 px-4 py-2 rounded-lg transition flex items-center space-x-2" disabled title="Coming soon">
80
+ <i data-feather="users" class="w-4 h-4"></i>
81
+ <span>Group Chat</span>
82
+ </button>
83
+ </div>
84
+ </div>
85
+
86
+ <!-- Chat Layout -->
87
+ <div class="flex flex-col lg:flex-row gap-6">
88
+ <!-- Agent Selector Sidebar -->
89
+ <div class="w-full lg:w-64 bg-white rounded-xl border border-gray-200 shadow-sm p-4 h-fit">
90
+ <h2 class="font-semibold text-gray-900 mb-4">Available Agents</h2>
91
+ <div id="agent-list" class="space-y-3">
92
+ <!-- Agents populated from JS config to keep DRY -->
93
  </div>
 
94
 
95
+ <div class="mt-6 pt-4 border-t border-gray-200">
96
+ <button id="btn-add-agent" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition flex items-center justify-center space-x-2" disabled title="Manage agents (coming soon)">
97
+ <i data-feather="users" class="w-4 h-4"></i>
98
+ <span>Add Agents</span>
99
+ </button>
100
+ </div>
101
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
+ <!-- Chat Box -->
104
+ <div class="flex-1">
105
+ <div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
106
+ <!-- Chat Header -->
107
+ <div class="border-b border-gray-200 p-4 bg-gray-50">
108
+ <div class="flex items-center space-x-3">
109
+ <div id="chat-agent-icon" class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
110
+ <i data-feather="book-open" class="text-indigo-600 w-5 h-5"></i>
111
+ </div>
112
+ <div>
113
+ <p id="chat-agent-name" class="font-medium text-gray-900">Socrates</p>
114
+ <p id="chat-agent-sub" class="text-xs text-gray-500">Reasoning • Ready</p>
115
+ </div>
116
+ <div class="ml-auto flex space-x-2">
117
+ <button id="btn-settings" class="text-gray-500 hover:text-indigo-600 transition" title="Model settings">
118
+ <i data-feather="settings" class="w-5 h-5"></i>
119
+ </button>
120
+ <button id="btn-clear" class="text-gray-500 hover:text-indigo-600 transition" title="Clear chat">
121
+ <i data-feather="x" class="w-5 h-5"></i>
122
+ </button>
123
+ </div>
124
+ </div>
125
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
+ <!-- Messages Container -->
128
+ <div class="chat-container">
129
+ <div id="messages" class="messages-container overflow-y-auto p-4 scrollbar-thin">
130
+ <!-- Messages injected here -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  </div>
 
 
132
 
133
+ <!-- Input Area -->
134
+ <div class="border-t border-gray-200 p-4 bg-gray-50">
135
+ <form id="chat-form" class="flex items-end space-x-3">
136
+ <button type="button" id="btn-attach" class="text-gray-500 hover:text-indigo-600 transition mb-1" title="Attach (not wired)">
137
+ <i data-feather="plus" class="w-5 h-5"></i>
138
+ </button>
139
+ <div class="flex-1 bg-white border border-gray-300 rounded-lg overflow-hidden focus-within:ring-2 focus-within:ring-indigo-500 focus-within:border-indigo-500">
140
+ <textarea id="chat-input" rows="1" placeholder="Type your message..." class="w-full p-3 resize-none focus:outline-none"></textarea>
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  </div>
142
+ <button id="btn-send" type="submit" class="bg-indigo-600 hover:bg-indigo-700 text-white p-3 rounded-lg transition">
143
+ <i data-feather="send" class="w-5 h-5"></i>
144
+ </button>
145
+ </form>
146
+ <div class="mt-2 flex items-center justify-between text-xs text-gray-500">
147
+ <div class="flex items-center space-x-2">
148
+ <span id="hf-status" class="px-2 py-0.5 rounded bg-gray-200 text-gray-700">HF: Disconnected</span>
149
+ <span id="model-id-pill" class="px-2 py-0.5 rounded bg-gray-200 text-gray-700">Model: —</span>
150
  </div>
151
  <div>
152
+ <button id="btn-voice" class="hover:text-indigo-600 transition flex items-center space-x-1" disabled title="Voice input (coming soon)">
153
+ <i data-feather="mic" class="w-4 h-4"></i><span>Voice Input</span>
154
+ </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  </div>
156
+ </div>
157
  </div>
158
+ </div>
159
+ </div>
160
+ <!-- Tip -->
161
+ <p class="text-xs text-gray-500 mt-2">Note: Text agents use the Hugging Face Inference API. Basqui returns an image. Set your HF token via “Connect Hugging Face”.</p>
162
+ </div>
163
+ </div>
164
+ </div>
165
+ </main>
166
+
167
+ <!-- Footer -->
168
+ <footer class="bg-gray-900 text-white py-12 px-4">
169
+ <div class="max-w-7xl mx-auto">
170
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
171
+ <div>
172
+ <div class="flex items-center space-x-2 mb-4">
173
+ <i data-feather="cpu" class="text-indigo-400 w-6 h-6"></i>
174
+ <span class="text-xl font-bold">Archindus</span>
175
  </div>
176
+ <p class="text-gray-400">The most advanced platform for collaborating with specialized AI agents.</p>
177
+ </div>
178
+ <div>
179
+ <h3 class="text-lg font-semibold mb-4">Platform</h3>
180
+ <ul class="space-y-2">
181
+ <li><a href="index.html" class="text-gray-400 hover:text-white transition">Home</a></li>
182
+ <li><a href="agents.html" class="text-gray-400 hover:text-white transition">Agents</a></li>
183
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Chat</a></li>
184
+ <li><a href="dashboard.html" class="text-gray-400 hover:text-white transition">Dashboard</a></li>
185
+ </ul>
186
+ </div>
187
+ <div>
188
+ <h3 class="text-lg font-semibold mb-4">Resources</h3>
189
+ <ul class="space-y-2">
190
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Documentation</a></li>
191
+ <li><a href="#" class="text-gray-400 hover:text-white transition">API Reference</a></li>
192
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Community</a></li>
193
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Support</a></li>
194
+ </ul>
195
+ </div>
196
+ <div>
197
+ <h3 class="text-lg font-semibold mb-4">Legal</h3>
198
+ <ul class="space-y-2">
199
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Privacy Policy</a></li>
200
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Terms of Service</a></li>
201
+ <li><a href="#" class="text-gray-400 hover:text-white transition">Cookie Policy</a></li>
202
+ </ul>
203
+ </div>
204
+ </div>
205
+ <div class="border-t border-gray-800 mt-12 pt-8 flex flex-col md:flex-row justify-between items-center">
206
+ <p class="text-gray-400 mb-4 md:mb-0">© 2023 Architect Industries Inc. All rights reserved.</p>
207
+ <div class="flex space-x-6">
208
+ <a href="#" class="text-gray-400 hover:text-white transition"><i data-feather="twitter" class="w-5 h-5"></i></a>
209
+ <a href="#" class="text-gray-400 hover:text-white transition"><i data-feather="github" class="w-5 h-5"></i></a>
210
+ <a href="#" class="text-gray-400 hover:text-white transition"><i data-feather="linkedin" class="w-5 h-5"></i></a>
211
+ <a href="#" class="text-gray-400 hover:text-white transition"><i data-feather="discord" class="w-5 h-5"></i></a>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ </footer>
216
+ </div>
217
+
218
+ <!-- HF Connect Modal -->
219
+ <div id="hf-modal" class="fixed inset-0 hidden items-center justify-center modal-bg z-50">
220
+ <div class="bg-white rounded-xl shadow-xl w-full max-w-lg p-6">
221
+ <div class="flex items-start justify-between">
222
+ <h3 class="text-lg font-semibold text-gray-900">Connect to Hugging Face</h3>
223
+ <button id="hf-close" class="text-gray-500 hover:text-gray-800"><i data-feather="x" class="w-5 h-5"></i></button>
224
+ </div>
225
+ <p class="text-sm text-gray-600 mt-2">Paste your <strong>Hugging Face API token</strong>. It is stored locally in your browser (localStorage).</p>
226
+
227
+ <label class="block text-sm font-medium text-gray-700 mt-4">HF API Token</label>
228
+ <input id="hf-token-input" type="password" class="mt-1 w-full border border-gray-300 rounded-lg px-3 py-2" placeholder="hf_xxx..." />
229
+
230
+ <div class="mt-4 flex justify-end space-x-2">
231
+ <button id="hf-clear" class="px-4 py-2 rounded-lg border border-gray-300 text-gray-700">Clear</button>
232
+ <button id="hf-save" class="px-4 py-2 rounded-lg bg-indigo-600 text-white">Save</button>
233
+ </div>
234
+
235
+ <div class="mt-6">
236
+ <h4 class="text-sm font-semibold text-gray-900 mb-2">Agent → Model mapping</h4>
237
+ <p class="text-xs text-gray-600">You can adjust these IDs inside the code (see <code>AGENTS</code> config). Defaults:</p>
238
+ <ul class="text-xs text-gray-600 list-disc pl-5 mt-2 space-y-1">
239
+ <li>Satoshi → bigcode/starcoder2-7b (text-generation)</li>
240
+ <li>Basqui → stabilityai/stable-diffusion-2-1 (image)</li>
241
+ <li>Socrates → Qwen/Qwen2.5-7B-Instruct (text-generation)</li>
242
+ <li>Wolf → mistralai/Mistral-7B-Instruct-v0.3 (text-generation)</li>
243
+ <li>Angelu → meta-llama/Llama-3.1-8B-Instruct (text-generation)</li>
244
+ <li>DataDoc → google/gemma-2-9b-it (text-generation)</li>
245
+ </ul>
246
+ </div>
247
  </div>
248
+ </div>
249
 
250
+ <script>
251
+ AOS.init({ duration: 800, easing: 'ease-in-out', once: true });
252
+ feather.replace();
253
+
254
+ // ---------- AGENT CONFIG ----------
255
+ // icon: feather icon name
256
+ // type: "text" | "image"
257
+ // model: HF model id (or Space-redirectable model id)
258
+ const AGENTS = {
259
+ "Satoshi": { sub: "Coding Bot", icon: "code", type: "text", model: "bigcode/starcoder2-7b" },
260
+ "Basqui": { sub: "Art Bot", icon: "image", type: "image", model: "stabilityai/stable-diffusion-2-1" },
261
+ "Socrates":{ sub: "Reasoning", icon: "book-open",type: "text", model: "Qwen/Qwen2.5-7B-Instruct" },
262
+ "Wolf": { sub: "Financial Literacy", icon: "trending-up", type: "text", model: "mistralai/Mistral-7B-Instruct-v0.3" },
263
+ "Angelu": { sub: "Creative Writing", icon: "edit-3", type: "text", model: "meta-llama/Llama-3.1-8B-Instruct" },
264
+ "DataDoc": { sub: "Data Science", icon: "bar-chart-2", type: "text", model: "google/gemma-2-9b-it" }
265
+ };
266
+
267
+ // Simple per-agent memory
268
+ const conversations = Object.fromEntries(Object.keys(AGENTS).map(a => [a, []]));
269
+
270
+ let currentAgent = "Socrates";
271
+
272
+ // ---------- DOM HOOKS ----------
273
+ const agentListEl = document.getElementById('agent-list');
274
+ const messagesEl = document.getElementById('messages');
275
+ const chatForm = document.getElementById('chat-form');
276
+ const chatInput = document.getElementById('chat-input');
277
+ const chatAgentName = document.getElementById('chat-agent-name');
278
+ const chatAgentSub = document.getElementById('chat-agent-sub');
279
+ const chatAgentIcon = document.getElementById('chat-agent-icon');
280
+
281
+ const btnClear = document.getElementById('btn-clear');
282
+ const btnNewChat = document.getElementById('btn-new-chat');
283
+
284
+ const hfModal = document.getElementById('hf-modal');
285
+ const btnHFConnect = document.getElementById('btn-hf-connect');
286
+ const btnHFSave = document.getElementById('hf-save');
287
+ const btnHFClear = document.getElementById('hf-clear');
288
+ const btnHFClose = document.getElementById('hf-close');
289
+ const hfTokenInput = document.getElementById('hf-token-input');
290
+ const hfStatus = document.getElementById('hf-status');
291
+ const modelIdPill = document.getElementById('model-id-pill');
292
+
293
+ // ---------- RENDER AGENTS ----------
294
+ function renderAgentList() {
295
+ agentListEl.innerHTML = '';
296
+ Object.entries(AGENTS).forEach(([name, cfg]) => {
297
+ const item = document.createElement('div');
298
+ item.className = "agent-selector relative group";
299
+ item.innerHTML = `
300
+ <div class="flex items-center space-x-3 p-3 rounded-lg hover:bg-gray-50 cursor-pointer border border-gray-200">
301
+ <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
302
+ <i data-feather="${cfg.icon}" class="text-indigo-600 w-5 h-5"></i>
303
+ </div>
304
+ <div>
305
+ <p class="font-medium text-gray-900">${name}</p>
306
+ <p class="text-xs text-gray-500">${cfg.sub}</p>
307
+ </div>
308
+ </div>
309
+ <div class="agent-overlay absolute inset-0 bg-indigo-500/80 rounded-lg opacity-0 flex items-center justify-center">
310
+ <button class="text-white px-4 py-1 rounded-lg border border-white">Select</button>
311
+ </div>
312
+ `;
313
+ item.addEventListener('click', () => setAgent(name));
314
+ agentListEl.appendChild(item);
315
+ });
316
+ feather.replace();
317
+ }
318
+
319
+ function setAgent(name) {
320
+ currentAgent = name;
321
+ const cfg = AGENTS[name];
322
+ chatAgentName.textContent = name;
323
+ chatAgentSub.textContent = `${cfg.sub} • Ready`;
324
+ chatAgentIcon.innerHTML = `<i data-feather="${cfg.icon}" class="text-indigo-600 w-5 h-5"></i>`;
325
+ feather.replace();
326
+
327
+ // Update model pill
328
+ modelIdPill.textContent = `Model: ${cfg.model}`;
329
+
330
+ // Render that agent's conversation
331
+ renderConversation();
332
+ }
333
+
334
+ function renderConversation() {
335
+ messagesEl.innerHTML = '';
336
+ const conv = conversations[currentAgent] || [];
337
+ conv.forEach(m => {
338
+ if (m.role === 'user') {
339
+ addUserBubble(m.content);
340
+ } else if (m.role === 'assistant') {
341
+ if (m.type === 'image' && m.blobUrl) {
342
+ addAIBubbleImage(currentAgent, m.blobUrl);
343
+ } else {
344
+ addAIBubble(currentAgent, m.content);
345
+ }
346
+ }
347
+ });
348
+ messagesEl.scrollTop = messagesEl.scrollHeight;
349
+ }
350
+
351
+ // ---------- BUBBLES ----------
352
+ function addUserBubble(text) {
353
+ const wrap = document.createElement('div');
354
+ wrap.className = 'flex justify-end mb-6';
355
+ wrap.innerHTML = `
356
+ <div class="chat-bubble bg-indigo-600 text-white rounded-lg p-4">
357
+ <p class="font-medium mb-1">You</p>
358
+ <p>${escapeHtml(text)}</p>
359
+ </div>
360
+ `;
361
+ messagesEl.appendChild(wrap);
362
+ }
363
+
364
+ function addAIBubble(agent, text) {
365
+ const icon = AGENTS[agent].icon;
366
+ const wrap = document.createElement('div');
367
+ wrap.className = 'flex mb-6';
368
+ wrap.innerHTML = `
369
+ <div class="w-10 h-10 rounded-full bg-indigo-100 flex-shrink-0 flex items-center justify-center mr-3">
370
+ <i data-feather="${icon}" class="text-indigo-600 w-5 h-5"></i>
371
+ </div>
372
+ <div class="chat-bubble bg-indigo-50 rounded-lg p-4">
373
+ <p class="font-medium text-indigo-800 mb-1">${agent}</p>
374
+ <p class="text-gray-800 whitespace-pre-wrap">${escapeHtml(text)}</p>
375
+ </div>
376
+ `;
377
+ messagesEl.appendChild(wrap);
378
+ feather.replace();
379
+ }
380
+
381
+ function addAIBubbleImage(agent, blobUrl) {
382
+ const icon = AGENTS[agent].icon;
383
+ const wrap = document.createElement('div');
384
+ wrap.className = 'flex mb-6';
385
+ wrap.innerHTML = `
386
+ <div class="w-10 h-10 rounded-full bg-indigo-100 flex-shrink-0 flex items-center justify-center mr-3">
387
+ <i data-feather="${icon}" class="text-indigo-600 w-5 h-5"></i>
388
+ </div>
389
+ <div class="chat-bubble bg-indigo-50 rounded-lg p-4">
390
+ <p class="font-medium text-indigo-800 mb-2">${agent}</p>
391
+ <img src="${blobUrl}" alt="Generated image" class="rounded-lg border border-gray-200 max-w-full"/>
392
+ </div>
393
+ `;
394
+ messagesEl.appendChild(wrap);
395
+ feather.replace();
396
+ }
397
+
398
+ function addTyping(agent) {
399
+ const icon = AGENTS[agent].icon;
400
+ const wrap = document.createElement('div');
401
+ wrap.className = 'flex mb-6';
402
+ wrap.id = 'typing';
403
+ wrap.innerHTML = `
404
+ <div class="w-10 h-10 rounded-full bg-indigo-100 flex-shrink-0 flex items-center justify-center mr-3">
405
+ <i data-feather="${icon}" class="text-indigo-600 w-5 h-5"></i>
406
+ </div>
407
+ <div class="chat-bubble bg-indigo-50 rounded-lg p-4">
408
+ <p class="font-medium text-indigo-800 mb-1">${agent}</p>
409
+ <div class="typing-indicator"><span class="typing-dot"></span><span class="typing-dot"></span><span class="typing-dot"></span></div>
410
+ </div>
411
+ `;
412
+ messagesEl.appendChild(wrap);
413
+ messagesEl.scrollTop = messagesEl.scrollHeight;
414
+ feather.replace();
415
+ }
416
+
417
+ function removeTyping() {
418
+ const t = document.getElementById('typing');
419
+ if (t) t.remove();
420
+ }
421
+
422
+ // ---------- HELPERS ----------
423
+ function escapeHtml(str = '') {
424
+ return str.replace(/[&<>"']/g, (m) => ({
425
+ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'
426
+ }[m]));
427
+ }
428
+
429
+ function tokenPresent() {
430
+ return !!localStorage.getItem('HF_TOKEN');
431
+ }
432
+
433
+ function updateHFStatus() {
434
+ if (tokenPresent()) {
435
+ hfStatus.textContent = 'HF: Connected';
436
+ hfStatus.className = 'px-2 py-0.5 rounded bg-green-100 text-green-800';
437
+ } else {
438
+ hfStatus.textContent = 'HF: Disconnected';
439
+ hfStatus.className = 'px-2 py-0.5 rounded bg-gray-200 text-gray-700';
440
+ }
441
+ }
442
+
443
+ // ---------- HF API CALLS ----------
444
+ async function callHFText(modelId, prompt) {
445
+ const url = `https://api-inference.huggingface.co/models/${encodeURIComponent(modelId)}`;
446
+ const headers = {
447
+ 'Authorization': `Bearer ${localStorage.getItem('HF_TOKEN') || ''}`,
448
+ 'Content-Type': 'application/json'
449
+ };
450
+ const body = JSON.stringify({
451
+ inputs: prompt,
452
+ parameters: {
453
+ max_new_tokens: 256,
454
+ temperature: 0.7,
455
+ do_sample: true,
456
+ return_full_text: false
457
+ }
458
+ });
459
+
460
+ const res = await fetch(url, { method: 'POST', headers, body });
461
+ if (!res.ok) {
462
+ const text = await res.text();
463
+ throw new Error(`HF error ${res.status}: ${text}`);
464
+ }
465
+ const data = await res.json();
466
+
467
+ // HF responses can vary by model; normalize common shapes
468
+ if (Array.isArray(data) && data[0] && (data[0].generated_text || data[0].summary_text)) {
469
+ return data[0].generated_text || data[0].summary_text;
470
+ }
471
+ if (data.generated_text) return data.generated_text;
472
+ if (typeof data === 'string') return data;
473
+
474
+ // Fallback
475
+ return JSON.stringify(data, null, 2);
476
+ }
477
+
478
+ async function callHFImage(modelId, prompt) {
479
+ const url = `https://api-inference.huggingface.co/models/${encodeURIComponent(modelId)}`;
480
+ const headers = {
481
+ 'Authorization': `Bearer ${localStorage.getItem('HF_TOKEN') || ''}`,
482
+ 'Content-Type': 'application/json',
483
+ 'Accept': 'image/png'
484
+ };
485
+ const body = JSON.stringify({ inputs: prompt });
486
+
487
+ const res = await fetch(url, { method: 'POST', headers, body });
488
+ if (!res.ok) {
489
+ const text = await res.text();
490
+ throw new Error(`HF error ${res.status}: ${text}`);
491
+ }
492
+ const blob = await res.blob();
493
+ return URL.createObjectURL(blob);
494
+ }
495
+
496
+ // Build a very simple prompt from history (lightweight)
497
+ function buildPrompt(agent) {
498
+ const sys = {
499
+ "Satoshi": "You are Satoshi, a Coding Bot. Provide accurate, concise code and explanations.",
500
+ "Basqui": "You are Basqui, an Art Bot. You create images from text prompts.",
501
+ "Socrates":"You are Socrates, a Reasoning agent. Think step by step and explain clearly.",
502
+ "Wolf": "You are Wolf, a Financial Literacy Bot. Teach concepts responsibly and clearly.",
503
+ "Angelu": "You are Angelu, a Creative Writing Bot. Write with style and structure.",
504
+ "DataDoc": "You are DataDoc, a Data Science helper. Explain data workflows and chart ideas."
505
+ }[agent];
506
+
507
+ const history = conversations[agent] || [];
508
+ let buf = `System: ${sys}\n`;
509
+ history.slice(-6).forEach(m => {
510
+ if (m.role === 'user') buf += `User: ${m.content}\n`;
511
+ if (m.role === 'assistant' && m.type !== 'image') buf += `Assistant: ${m.content}\n`;
512
+ });
513
+ buf += `Assistant:`;
514
+ return buf;
515
+ }
516
+
517
+ // ---------- CHAT ACTIONS ----------
518
+ chatForm.addEventListener('submit', async (e) => {
519
+ e.preventDefault();
520
+ const text = chatInput.value.trim();
521
+ if (!text) return;
522
+
523
+ const cfg = AGENTS[currentAgent];
524
+
525
+ // append user message
526
+ conversations[currentAgent].push({ role: 'user', content: text });
527
+ addUserBubble(text);
528
+ chatInput.value = '';
529
+ chatInput.style.height = 'auto';
530
+
531
+ addTyping(currentAgent);
532
+
533
+ try {
534
+ if (cfg.type === 'text') {
535
+ if (!tokenPresent()) throw new Error('No HF token set. Click “Connect Hugging Face”.');
536
+ const prompt = buildPrompt(currentAgent);
537
+ const output = await callHFText(cfg.model, `${prompt}\nUser: ${text}\nAssistant:`);
538
+ removeTyping();
539
+ conversations[currentAgent].push({ role: 'assistant', content: output });
540
+ addAIBubble(currentAgent, output);
541
+ } else if (cfg.type === 'image') {
542
+ if (!tokenPresent()) throw new Error('No HF token set. Click “Connect Hugging Face”.');
543
+ const blobUrl = await callHFImage(cfg.model, text);
544
+ removeTyping();
545
+ conversations[currentAgent].push({ role: 'assistant', type: 'image', blobUrl });
546
+ addAIBubbleImage(currentAgent, blobUrl);
547
+ }
548
+ } catch (err) {
549
+ removeTyping();
550
+ const msg = (err && err.message) ? err.message : String(err);
551
+ conversations[currentAgent].push({ role: 'assistant', content: `Error: ${msg}` });
552
+ addAIBubble(currentAgent, `Error: ${msg}`);
553
+ } finally {
554
+ messagesEl.scrollTop = messagesEl.scrollHeight;
555
+ }
556
+ });
557
+
558
+ btnClear.addEventListener('click', () => {
559
+ conversations[currentAgent] = [];
560
+ renderConversation();
561
+ });
562
+
563
+ btnNewChat.addEventListener('click', () => {
564
+ // Start a fresh conversation but keep other agents intact
565
+ conversations[currentAgent] = [];
566
+ renderConversation();
567
+ });
568
+
569
+ // Auto-expand textarea
570
+ chatInput.addEventListener('input', function () {
571
+ this.style.height = 'auto';
572
+ this.style.height = (this.scrollHeight) + 'px';
573
+ });
574
+
575
+ // ---------- HF MODAL ----------
576
+ function showHFModal(show) {
577
+ hfModal.classList.toggle('hidden', !show);
578
+ if (show) {
579
+ hfTokenInput.value = localStorage.getItem('HF_TOKEN') || '';
580
+ hfTokenInput.type = 'password';
581
+ }
582
+ }
583
+ btnHFConnect.addEventListener('click', () => showHFModal(true));
584
+ btnHFClose.addEventListener('click', () => showHFModal(false));
585
+ btnHFClear.addEventListener('click', () => {
586
+ localStorage.removeItem('HF_TOKEN');
587
+ updateHFStatus();
588
+ hfTokenInput.value = '';
589
+ });
590
+ btnHFSave.addEventListener('click', () => {
591
+ const tok = hfTokenInput.value.trim();
592
+ if (tok) localStorage.setItem('HF_TOKEN', tok);
593
+ updateHFStatus();
594
+ showHFModal(false);
595
+ });
596
+
597
+ // ---------- INIT ----------
598
+ renderAgentList();
599
+ setAgent(currentAgent);
600
+ updateHFStatus();
601
+ </script>
602
  </body>
603
  </html>
604
+
dashboard.html CHANGED
@@ -2,10 +2,10 @@
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>Archindus Dashboard</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
- <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet" />
9
  <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
10
  <script src="https://unpkg.com/feather-icons"></script>
11
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
@@ -17,12 +17,14 @@
17
  .main-content { margin-left: 280px; transition: all 0.3s ease; }
18
  .main-content.expanded { margin-left: 80px; }
19
  .stat-card:hover { transform: translateY(-3px); box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05); }
20
- .active-tab { border-bottom: 2px solid #4F46E5; color: #4F46E5; }
21
  .badge { font-size: 0.75rem; padding: 0.25rem 0.5rem; border-radius: 9999px; }
22
- /* Fix the “descending page” by constraining chart height and forcing canvas to fill */
23
  .chart-box { position: relative; }
24
  .chart-box canvas { display:block; width:100% !important; height:100% !important; }
25
-
 
 
 
 
26
  @media (max-width: 768px) {
27
  .sidebar { position: fixed; z-index: 50; left: -280px; }
28
  .sidebar.open { left: 0; }
@@ -84,7 +86,13 @@
84
  <div class="flex items-center justify-between mb-6">
85
  <div>
86
  <h1 class="text-2xl md:text-3xl font-bold text-gray-900">AI Agents — Live Feedback Dashboard</h1>
87
- <p class="text-gray-600 mt-1">Powered by user feedback from <a href="https://huggingface.co/spaces/BlackTesla/archindus" target="_blank" class="text-indigo-600 underline">Hugging Face Space</a>.</p>
 
 
 
 
 
 
88
  </div>
89
  <div class="flex items-center gap-2">
90
  <span id="lastUpdated" class="text-xs text-gray-500">Last update: —</span>
@@ -92,6 +100,27 @@
92
  </div>
93
  </div>
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  <!-- KPI cards -->
96
  <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4 mb-8">
97
  <div class="stat-card bg-white rounded-2xl p-4 border border-gray-200">
@@ -195,13 +224,99 @@
195
  AOS.init();
196
  feather.replace();
197
 
198
- // --- CONFIG ---
 
 
 
 
 
 
 
 
 
 
 
199
  const HF_OWNER = 'BlackTesla';
200
  const HF_SPACE = 'archindus';
201
- const PROXY_URL = ''; // set to your proxy endpoint to avoid CORS
202
 
203
- // --- UTILITIES ---
204
  const el = (id) => document.getElementById(id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  const fmtPct = (n) => `${(n * 100).toFixed(0)}%`;
206
  const ago = (d) => {
207
  const diff = (Date.now() - new Date(d).getTime()) / 1000;
@@ -211,7 +326,7 @@
211
  return `${Math.floor(diff/86400)}d ago`;
212
  };
213
 
214
- // Sentiment heuristic
215
  const POS = ['great','good','love','fast','helpful','amazing','excellent','awesome','smooth','wow'];
216
  const NEG = ['bad','slow','hate','bug','issue','error','crash','broken','lag','confusing','terrible'];
217
  function sentimentScore(text=''){
@@ -220,9 +335,9 @@
220
  return Math.max(-2, Math.min(2, s));
221
  }
222
 
223
- // --- DATA ACCESS ---
224
  async function fetchFeedback(){
225
- if(PROXY_URL){
226
  const r = await fetch(PROXY_URL);
227
  if(!r.ok) throw new Error('Proxy fetch failed');
228
  return await r.json();
@@ -232,16 +347,24 @@
232
  const r = await fetch(url, { headers: { 'Accept': 'application/json' } });
233
  if(!r.ok) throw new Error('HF discussions not accessible from browser');
234
  const data = await r.json();
235
- const items = (data.discussions || data.items || []).map(d => ({
236
- id: d.id || d.num,
237
- title: d.title || 'Feedback',
238
- createdAt: d.created_at || d.createdAt || d.last_activity || Date.now(),
239
- url: d.url || `https://huggingface.co/spaces/${HF_OWNER}/${HF_SPACE}/discussions/${d.num}`,
240
- author: d.author || (d.user && d.user.name) || 'user',
241
- text: (d.first ? d.first.content : d.body) || d.summary || '',
242
- rating: (()=>{ const m=(d.title||'').match(/rating\s*[:=]\s*(\d+(?:\.\d+)?)/i); return m?Number(m[1]):null; })(),
243
- agent: (()=>{ const m=(d.title||'').match(/agent\s*[:=]\s*([^\]\)\-:]+)/i); return m?m[1].trim():null; })()
244
- }));
 
 
 
 
 
 
 
 
245
  return { items, total: items.length };
246
  }catch(err){
247
  console.warn('Falling back to mock feedback:', err.message);
@@ -251,37 +374,44 @@
251
 
252
  function mockFeedback(){
253
  const now = Date.now();
254
- const agents = ['Researcher','Coder','Designer','Analyst'];
255
  const texts = [
256
  'Amazing response time and accurate answers!',
257
  'Good but a bit slow on large files.',
258
- 'Great UI suggestions, very helpful.',
259
- 'Error parsing JSON earlier but recovered.',
260
- 'Awesome code fix, shipped it.',
261
- 'Confusing output for one prompt, needs work',
262
  ];
263
- const items = Array.from({length: 28}).map((_,i)=>{
264
  const ts = now - i * 1000*60*60*6;
265
- const agent = agents[i % agents.length];
266
  const text = texts[i % texts.length];
267
- const rating = 3 + (i % 3);
268
- return { id: i+1, title: `${agent} feedback`, createdAt: ts, url: '#', author: 'anon', text, rating, agent };
269
  });
270
  return { items, total: items.length, mock: true };
271
  }
272
 
273
- // --- AGGREGATION ---
274
  function aggregate(items){
 
 
 
 
 
 
 
275
  const byAgent = {};
276
  const byDay = {};
277
  let pos=0, neu=0, neg=0;
278
 
279
- items.forEach(it=>{
280
  const day = new Date(it.createdAt).toISOString().slice(0,10);
281
  byDay[day] = (byDay[day]||0)+1;
282
  const s = sentimentScore(it.text);
283
  if(s>0) pos++; else if(s<0) neg++; else neu++;
284
- const name = it.agent || 'Unknown';
285
  const entry = byAgent[name] || { count:0, ratingSum:0, ratingN:0, name };
286
  entry.count++;
287
  if(typeof it.rating === 'number'){ entry.ratingSum += it.rating; entry.ratingN++; }
@@ -290,7 +420,7 @@
290
 
291
  const leaderboard = Object.values(byAgent).map(a=>{
292
  const avg = a.ratingN? (a.ratingSum/a.ratingN) : 0;
293
- const score = avg * Math.log2(1 + a.count); // confidence-ish
294
  return { ...a, avg: Number(avg.toFixed(2)), score: Number(score.toFixed(2)) };
295
  }).sort((a,b)=> b.score - a.score);
296
 
@@ -300,18 +430,20 @@
300
  });
301
  const volume = days.map(d=> byDay[d] || 0);
302
 
303
- const total = items.length;
304
  return {
305
  total,
306
  pos, neu, neg,
307
  volumeLabels: days,
308
  volumeValues: volume,
309
- leaderboard
 
310
  };
311
  }
312
 
313
- // --- RENDER ---
314
  let chartVolume, chartSentiment;
 
315
  function renderCharts(agg){
316
  const ctx1 = document.getElementById('chartVolume');
317
  if(chartVolume) chartVolume.destroy();
@@ -337,7 +469,7 @@
337
  <tr class="border-b last:border-b-0">
338
  <td class="py-2 pr-4">
339
  <div class="flex items-center gap-2">
340
- <span class="inline-flex items-center justify-center w-6 h-6 rounded-full bg-indigo-50 text-indigo-700 text-xs">${r.name[0]||'?'}</span>
341
  <span class="font-medium">${r.name}</span>
342
  <span class="badge bg-gray-100 text-gray-600">${r.count}</span>
343
  </div>
@@ -386,7 +518,7 @@
386
  el('kpiTopAgentScore').textContent = top ? `score ${top.score.toFixed(2)} · avg ${top.avg.toFixed(2)}` : '—';
387
  }
388
 
389
- // Cache last non-empty payload to avoid zeroed KPIs on transient empty responses
390
  let lastItems = [];
391
  async function refresh(){
392
  try{
@@ -400,23 +532,24 @@
400
  const agg = aggregate(items);
401
  renderCharts(agg);
402
  renderLeaderboard(agg.leaderboard);
403
- renderRecent(items.sort((a,b)=> new Date(b.createdAt) - new Date(a.createdAt)));
404
  renderKpis(agg);
405
  const lu = document.getElementById('lastUpdated');
406
  if(lu){ lu.textContent = `Last update: ${new Date().toLocaleTimeString()}`; lu.classList.remove('text-red-600'); }
407
  } catch(e){
 
408
  const { items } = mockFeedback();
409
  const agg = aggregate(items);
410
  renderCharts(agg);
411
  renderLeaderboard(agg.leaderboard);
412
- renderRecent(items);
413
  renderKpis(agg);
414
  const lu = document.getElementById('lastUpdated');
415
  if(lu){ lu.textContent = `Last update: fallback ${new Date().toLocaleTimeString()}`; lu.classList.add('text-red-600'); }
416
  }
417
  }
418
 
419
- // --- WIRE-UP ---
420
  document.getElementById('sidebarToggle')?.addEventListener('click', ()=>{
421
  const s = document.querySelector('.sidebar');
422
  const m = document.querySelector('.main-content');
@@ -424,11 +557,19 @@
424
  m.classList.toggle('expanded');
425
  });
426
  document.getElementById('manualRefresh')?.addEventListener('click', refresh);
 
 
 
 
 
 
 
 
 
427
 
428
  // Kickoff + Polling
429
  refresh();
430
  setInterval(refresh, 15000);
431
  </script>
432
  </body>
433
- </html>
434
-
 
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>Archindus Dashboard</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet"/>
9
  <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
10
  <script src="https://unpkg.com/feather-icons"></script>
11
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
 
17
  .main-content { margin-left: 280px; transition: all 0.3s ease; }
18
  .main-content.expanded { margin-left: 80px; }
19
  .stat-card:hover { transform: translateY(-3px); box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05); }
 
20
  .badge { font-size: 0.75rem; padding: 0.25rem 0.5rem; border-radius: 9999px; }
 
21
  .chart-box { position: relative; }
22
  .chart-box canvas { display:block; width:100% !important; height:100% !important; }
23
+ .chip { border:1px solid #e5e7eb; }
24
+ .chip.active { background:#eef2ff; border-color:#c7d2fe; color:#4338ca; }
25
+ .scrollbar-thin::-webkit-scrollbar { height: 6px; width: 6px; }
26
+ .scrollbar-thin::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 9999px; }
27
+ .scrollbar-thin::-webkit-scrollbar-track { background: transparent; }
28
  @media (max-width: 768px) {
29
  .sidebar { position: fixed; z-index: 50; left: -280px; }
30
  .sidebar.open { left: 0; }
 
86
  <div class="flex items-center justify-between mb-6">
87
  <div>
88
  <h1 class="text-2xl md:text-3xl font-bold text-gray-900">AI Agents — Live Feedback Dashboard</h1>
89
+ <p class="text-gray-600 mt-1">
90
+ Powered by user feedback from
91
+ <a href="https://huggingface.co/spaces/BlackTesla/archindus" target="_blank" class="text-indigo-600 underline">Hugging Face Space</a>.
92
+ </p>
93
+ <div class="mt-2 text-xs">
94
+ <span id="hfStatus" class="px-2 py-0.5 rounded bg-gray-200 text-gray-700">HF: Disconnected</span>
95
+ </div>
96
  </div>
97
  <div class="flex items-center gap-2">
98
  <span id="lastUpdated" class="text-xs text-gray-500">Last update: —</span>
 
100
  </div>
101
  </div>
102
 
103
+ <!-- Agent Filters + Agents Panel -->
104
+ <div class="grid grid-cols-1 xl:grid-cols-3 gap-6 mb-8">
105
+ <!-- Filters -->
106
+ <div class="bg-white rounded-2xl p-4 border border-gray-200 xl:col-span-2">
107
+ <div class="flex items-center justify-between mb-3">
108
+ <h3 class="font-semibold">Filter by Agent</h3>
109
+ <button id="clearFilter" class="text-sm text-indigo-600 underline">Clear</button>
110
+ </div>
111
+ <div id="agentChips" class="flex flex-wrap gap-2"></div>
112
+ </div>
113
+
114
+ <!-- Agents panel -->
115
+ <div class="bg-white rounded-2xl p-4 border border-gray-200">
116
+ <div class="flex items-center justify-between mb-3">
117
+ <h3 class="font-semibold">Agents & Models</h3>
118
+ <a href="agents.html" class="text-sm text-indigo-600 underline">Manage</a>
119
+ </div>
120
+ <div id="agentsPanel" class="space-y-3"></div>
121
+ </div>
122
+ </div>
123
+
124
  <!-- KPI cards -->
125
  <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4 mb-8">
126
  <div class="stat-card bg-white rounded-2xl p-4 border border-gray-200">
 
224
  AOS.init();
225
  feather.replace();
226
 
227
+ // -------------------- CONFIG (Keep in sync with chat.html) --------------------
228
+ const AGENTS = {
229
+ "Satoshi": { sub: "Coding Bot", icon: "code", model: "bigcode/starcoder2-7b" },
230
+ "Basqui": { sub: "Art Bot", icon: "image", model: "stabilityai/stable-diffusion-2-1" },
231
+ "Socrates":{ sub: "Reasoning", icon: "book-open", model: "Qwen/Qwen2.5-7B-Instruct" },
232
+ "Wolf": { sub: "Financial Literacy Bot", icon: "trending-up",model: "mistralai/Mistral-7B-Instruct-v0.3" },
233
+ "Angelu": { sub: "Creative Writing Bot", icon: "edit-3", model: "meta-llama/Llama-3.1-8B-Instruct" },
234
+ "DataDoc": { sub: "Data Science / Graphs", icon: "bar-chart-2",model: "google/gemma-2-9b-it" }
235
+ };
236
+ const AGENT_NAMES = Object.keys(AGENTS);
237
+
238
+ // Your Space (used when browser can fetch discussions directly)
239
  const HF_OWNER = 'BlackTesla';
240
  const HF_SPACE = 'archindus';
241
+ const PROXY_URL = ''; // optional: set to a server endpoint that returns consolidated JSON to avoid CORS
242
 
243
+ // -------------------- UI HOOKS --------------------
244
  const el = (id) => document.getElementById(id);
245
+ const hfStatusEl = el('hfStatus');
246
+
247
+ // HF token status (shared with chat.html via localStorage 'HF_TOKEN')
248
+ function updateHFStatus() {
249
+ const tok = localStorage.getItem('HF_TOKEN');
250
+ if (tok) {
251
+ hfStatusEl.textContent = 'HF: Connected';
252
+ hfStatusEl.className = 'px-2 py-0.5 rounded bg-green-100 text-green-800';
253
+ } else {
254
+ hfStatusEl.textContent = 'HF: Disconnected';
255
+ hfStatusEl.className = 'px-2 py-0.5 rounded bg-gray-200 text-gray-700';
256
+ }
257
+ }
258
+ updateHFStatus();
259
+
260
+ // -------------------- AGENT FILTER CHIPS --------------------
261
+ let activeFilter = new Set(); // empty = all
262
+ function renderAgentChips() {
263
+ const wrap = el('agentChips');
264
+ wrap.innerHTML = '';
265
+ AGENT_NAMES.forEach(name => {
266
+ const chip = document.createElement('button');
267
+ chip.className = 'chip px-3 py-1 rounded-full text-sm flex items-center gap-2';
268
+ chip.dataset.agent = name;
269
+ chip.innerHTML = `<i data-feather="${AGENTS[name].icon}" class="w-4 h-4"></i><span>${name}</span>`;
270
+ chip.addEventListener('click', () => {
271
+ if (activeFilter.has(name)) activeFilter.delete(name); else activeFilter.add(name);
272
+ updateChipStyles();
273
+ refresh(); // re-aggregate with filter
274
+ });
275
+ wrap.appendChild(chip);
276
+ });
277
+ updateChipStyles();
278
+ feather.replace();
279
+ }
280
+ function updateChipStyles() {
281
+ const chips = el('agentChips').querySelectorAll('.chip');
282
+ chips.forEach(c => {
283
+ const a = c.dataset.agent;
284
+ const isActive = activeFilter.size === 0 || activeFilter.has(a);
285
+ c.classList.toggle('active', activeFilter.has(a));
286
+ c.style.opacity = isActive ? '1' : '0.5';
287
+ });
288
+ }
289
+
290
+ // -------------------- AGENTS PANEL --------------------
291
+ function renderAgentsPanel() {
292
+ const box = el('agentsPanel');
293
+ box.innerHTML = '';
294
+ AGENT_NAMES.forEach(name => {
295
+ const cfg = AGENTS[name];
296
+ const row = document.createElement('div');
297
+ row.className = 'flex items-center justify-between p-3 rounded-lg border border-gray-200';
298
+ row.innerHTML = `
299
+ <div class="flex items-center gap-3">
300
+ <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center">
301
+ <i data-feather="${cfg.icon}" class="text-indigo-600 w-5 h-5"></i>
302
+ </div>
303
+ <div>
304
+ <div class="font-medium text-gray-900">${name}</div>
305
+ <div class="text-xs text-gray-500">${cfg.sub}</div>
306
+ </div>
307
+ </div>
308
+ <div class="flex items-center gap-3">
309
+ <span class="hidden md:inline text-xs text-gray-500">Model:</span>
310
+ <span class="badge bg-gray-100 text-gray-700">${cfg.model}</span>
311
+ <a href="chat.html?agent=${encodeURIComponent(name)}" class="px-3 py-1 rounded-lg bg-indigo-600 text-white text-xs hover:bg-indigo-700">Open Chat</a>
312
+ </div>
313
+ `;
314
+ box.appendChild(row);
315
+ });
316
+ feather.replace();
317
+ }
318
+
319
+ // -------------------- UTILS --------------------
320
  const fmtPct = (n) => `${(n * 100).toFixed(0)}%`;
321
  const ago = (d) => {
322
  const diff = (Date.now() - new Date(d).getTime()) / 1000;
 
326
  return `${Math.floor(diff/86400)}d ago`;
327
  };
328
 
329
+ // sentiment heuristic
330
  const POS = ['great','good','love','fast','helpful','amazing','excellent','awesome','smooth','wow'];
331
  const NEG = ['bad','slow','hate','bug','issue','error','crash','broken','lag','confusing','terrible'];
332
  function sentimentScore(text=''){
 
335
  return Math.max(-2, Math.min(2, s));
336
  }
337
 
338
+ // -------------------- DATA ACCESS --------------------
339
  async function fetchFeedback(){
340
+ if (PROXY_URL) {
341
  const r = await fetch(PROXY_URL);
342
  if(!r.ok) throw new Error('Proxy fetch failed');
343
  return await r.json();
 
347
  const r = await fetch(url, { headers: { 'Accept': 'application/json' } });
348
  if(!r.ok) throw new Error('HF discussions not accessible from browser');
349
  const data = await r.json();
350
+ const list = (data.discussions || data.items || []);
351
+ const items = list.map(d => {
352
+ const created = d.created_at || d.createdAt || d.last_activity || Date.now();
353
+ const title = d.title || 'Feedback';
354
+ // Try to extract agent and rating from title like "Agent: Socrates | Rating: 4.5"
355
+ const agentMatch = title.match(/agent\s*[:=]\s*([^\]\)\-:|]+)/i);
356
+ const ratingMatch = title.match(/rating\s*[:=]\s*(\d+(?:\.\d+)?)/i);
357
+ return {
358
+ id: d.id || d.num,
359
+ title,
360
+ createdAt: created,
361
+ url: d.url || `https://huggingface.co/spaces/${HF_OWNER}/${HF_SPACE}/discussions/${d.num}`,
362
+ author: d.author || (d.user && d.user.name) || 'user',
363
+ text: (d.first ? d.first.content : d.body) || d.summary || '',
364
+ rating: ratingMatch ? Number(ratingMatch[1]) : null,
365
+ agent: agentMatch ? agentMatch[1].trim() : null
366
+ };
367
+ });
368
  return { items, total: items.length };
369
  }catch(err){
370
  console.warn('Falling back to mock feedback:', err.message);
 
374
 
375
  function mockFeedback(){
376
  const now = Date.now();
377
+ const agentCycle = AGENT_NAMES;
378
  const texts = [
379
  'Amazing response time and accurate answers!',
380
  'Good but a bit slow on large files.',
381
+ 'Great suggestions, very helpful.',
382
+ 'Hit an error earlier but recovered.',
383
+ 'Awesome output, shipped it.',
384
+ 'Confusing result for one prompt, needs work'
385
  ];
386
+ const items = Array.from({length: 30}).map((_,i)=>{
387
  const ts = now - i * 1000*60*60*6;
388
+ const agent = agentCycle[i % agentCycle.length];
389
  const text = texts[i % texts.length];
390
+ const rating = 3 + ((i + 1) % 3); // 3..5
391
+ return { id: i+1, title: `${agent} feedback — Rating: ${rating}`, createdAt: ts, url: '#', author: 'anon', text, rating, agent };
392
  });
393
  return { items, total: items.length, mock: true };
394
  }
395
 
396
+ // -------------------- AGGREGATION (with filter) --------------------
397
  function aggregate(items){
398
+ // Apply filter
399
+ const filtered = items.filter(it => {
400
+ if (activeFilter.size === 0) return true;
401
+ const a = (it.agent || 'Unknown').trim();
402
+ return activeFilter.has(a);
403
+ });
404
+
405
  const byAgent = {};
406
  const byDay = {};
407
  let pos=0, neu=0, neg=0;
408
 
409
+ filtered.forEach(it=>{
410
  const day = new Date(it.createdAt).toISOString().slice(0,10);
411
  byDay[day] = (byDay[day]||0)+1;
412
  const s = sentimentScore(it.text);
413
  if(s>0) pos++; else if(s<0) neg++; else neu++;
414
+ const name = (it.agent && AGENT_NAMES.includes(it.agent.trim())) ? it.agent.trim() : 'Unknown';
415
  const entry = byAgent[name] || { count:0, ratingSum:0, ratingN:0, name };
416
  entry.count++;
417
  if(typeof it.rating === 'number'){ entry.ratingSum += it.rating; entry.ratingN++; }
 
420
 
421
  const leaderboard = Object.values(byAgent).map(a=>{
422
  const avg = a.ratingN? (a.ratingSum/a.ratingN) : 0;
423
+ const score = avg * Math.log2(1 + a.count);
424
  return { ...a, avg: Number(avg.toFixed(2)), score: Number(score.toFixed(2)) };
425
  }).sort((a,b)=> b.score - a.score);
426
 
 
430
  });
431
  const volume = days.map(d=> byDay[d] || 0);
432
 
433
+ const total = filtered.length;
434
  return {
435
  total,
436
  pos, neu, neg,
437
  volumeLabels: days,
438
  volumeValues: volume,
439
+ leaderboard,
440
+ recent: filtered.sort((a,b)=> new Date(b.createdAt) - new Date(a.createdAt))
441
  };
442
  }
443
 
444
+ // -------------------- RENDER --------------------
445
  let chartVolume, chartSentiment;
446
+
447
  function renderCharts(agg){
448
  const ctx1 = document.getElementById('chartVolume');
449
  if(chartVolume) chartVolume.destroy();
 
469
  <tr class="border-b last:border-b-0">
470
  <td class="py-2 pr-4">
471
  <div class="flex items-center gap-2">
472
+ <span class="inline-flex items-center justify-center w-6 h-6 rounded-full bg-indigo-50 text-indigo-700 text-xs">${(r.name||'?')[0]}</span>
473
  <span class="font-medium">${r.name}</span>
474
  <span class="badge bg-gray-100 text-gray-600">${r.count}</span>
475
  </div>
 
518
  el('kpiTopAgentScore').textContent = top ? `score ${top.score.toFixed(2)} · avg ${top.avg.toFixed(2)}` : '—';
519
  }
520
 
521
+ // -------------------- REFRESH PIPELINE --------------------
522
  let lastItems = [];
523
  async function refresh(){
524
  try{
 
532
  const agg = aggregate(items);
533
  renderCharts(agg);
534
  renderLeaderboard(agg.leaderboard);
535
+ renderRecent(agg.recent);
536
  renderKpis(agg);
537
  const lu = document.getElementById('lastUpdated');
538
  if(lu){ lu.textContent = `Last update: ${new Date().toLocaleTimeString()}`; lu.classList.remove('text-red-600'); }
539
  } catch(e){
540
+ console.warn('Refresh error; using mock:', e);
541
  const { items } = mockFeedback();
542
  const agg = aggregate(items);
543
  renderCharts(agg);
544
  renderLeaderboard(agg.leaderboard);
545
+ renderRecent(agg.recent);
546
  renderKpis(agg);
547
  const lu = document.getElementById('lastUpdated');
548
  if(lu){ lu.textContent = `Last update: fallback ${new Date().toLocaleTimeString()}`; lu.classList.add('text-red-600'); }
549
  }
550
  }
551
 
552
+ // -------------------- WIRE-UP --------------------
553
  document.getElementById('sidebarToggle')?.addEventListener('click', ()=>{
554
  const s = document.querySelector('.sidebar');
555
  const m = document.querySelector('.main-content');
 
557
  m.classList.toggle('expanded');
558
  });
559
  document.getElementById('manualRefresh')?.addEventListener('click', refresh);
560
+ document.getElementById('clearFilter')?.addEventListener('click', ()=>{
561
+ activeFilter.clear();
562
+ updateChipStyles();
563
+ refresh();
564
+ });
565
+
566
+ // Init sections
567
+ renderAgentChips();
568
+ renderAgentsPanel();
569
 
570
  // Kickoff + Polling
571
  refresh();
572
  setInterval(refresh, 15000);
573
  </script>
574
  </body>
575
+ </html>
 
login.html CHANGED
@@ -109,4 +109,5 @@
109
  });
110
  </script>
111
  </body>
112
- </html>
 
 
109
  });
110
  </script>
111
  </body>
112
+ </html>
113
+