crsmithdev commited on
Commit
a9bc71e
·
verified ·
1 Parent(s): 8002d5b

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +766 -19
index.html CHANGED
@@ -1,19 +1,766 @@
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>AI Agent Code Arena</title>
7
+ <!-- Import Phosphor Icons -->
8
+ <script src="https://unpkg.com/@phosphor-icons/web"></script>
9
+ <!-- Import Highlight.js for syntax highlighting -->
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css">
11
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
12
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js"></script>
13
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/python.min.js"></script>
14
+
15
+ <style>
16
+ :root {
17
+ /* Color Palette */
18
+ --bg-body: #0f1115;
19
+ --bg-panel: #161b22;
20
+ --bg-input: #0d1117;
21
+ --border-color: #30363d;
22
+ --primary: #58a6ff;
23
+ --primary-hover: #79c0ff;
24
+ --accent-green: #238636;
25
+ --accent-purple: #8957e5;
26
+ --accent-orange: #d29922;
27
+ --text-main: #c9d1d9;
28
+ --text-muted: #8b949e;
29
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
30
+
31
+ /* Typography */
32
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
33
+ --font-mono: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
34
+ }
35
+
36
+ * {
37
+ box-sizing: border-box;
38
+ margin: 0;
39
+ padding: 0;
40
+ }
41
+
42
+ body {
43
+ background-color: var(--bg-body);
44
+ color: var(--text-main);
45
+ font-family: var(--font-sans);
46
+ height: 100vh;
47
+ display: flex;
48
+ flex-direction: column;
49
+ overflow: hidden;
50
+ }
51
+
52
+ /* --- Header --- */
53
+ header {
54
+ background-color: var(--bg-panel);
55
+ border-bottom: 1px solid var(--border-color);
56
+ padding: 1rem 2rem;
57
+ display: flex;
58
+ justify-content: space-between;
59
+ align-items: center;
60
+ height: 64px;
61
+ }
62
+
63
+ .logo-area {
64
+ display: flex;
65
+ align-items: center;
66
+ gap: 0.75rem;
67
+ font-weight: 700;
68
+ font-size: 1.25rem;
69
+ color: #fff;
70
+ }
71
+
72
+ .logo-icon {
73
+ color: var(--primary);
74
+ font-size: 1.5rem;
75
+ }
76
+
77
+ .anycoder-link {
78
+ font-size: 0.875rem;
79
+ color: var(--text-muted);
80
+ text-decoration: none;
81
+ transition: color 0.2s;
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 0.5rem;
85
+ }
86
+
87
+ .anycoder-link:hover {
88
+ color: var(--primary);
89
+ }
90
+
91
+ /* --- Main Layout --- */
92
+ main {
93
+ flex: 1;
94
+ display: flex;
95
+ flex-direction: column;
96
+ overflow: hidden;
97
+ position: relative;
98
+ }
99
+
100
+ /* --- Input Section --- */
101
+ .prompt-container {
102
+ padding: 1.5rem 2rem;
103
+ background: linear-gradient(180deg, var(--bg-body) 0%, rgba(15, 17, 21, 0.9) 100%);
104
+ z-index: 10;
105
+ border-bottom: 1px solid var(--border-color);
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: 1rem;
109
+ max-width: 1200px;
110
+ width: 100%;
111
+ margin: 0 auto;
112
+ }
113
+
114
+ .prompt-wrapper {
115
+ position: relative;
116
+ width: 100%;
117
+ }
118
+
119
+ textarea {
120
+ width: 100%;
121
+ background-color: var(--bg-input);
122
+ border: 1px solid var(--border-color);
123
+ border-radius: 8px;
124
+ padding: 1rem;
125
+ padding-right: 4rem;
126
+ color: var(--text-main);
127
+ font-family: var(--font-sans);
128
+ font-size: 1rem;
129
+ resize: none;
130
+ height: 100px;
131
+ outline: none;
132
+ transition: border-color 0.2s, box-shadow 0.2s;
133
+ }
134
+
135
+ textarea:focus {
136
+ border-color: var(--primary);
137
+ box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.1);
138
+ }
139
+
140
+ .generate-btn {
141
+ position: absolute;
142
+ bottom: 12px;
143
+ right: 12px;
144
+ background-color: var(--accent-green);
145
+ color: white;
146
+ border: none;
147
+ border-radius: 6px;
148
+ padding: 0.5rem 1rem;
149
+ font-weight: 600;
150
+ cursor: pointer;
151
+ display: flex;
152
+ align-items: center;
153
+ gap: 0.5rem;
154
+ transition: background-color 0.2s, transform 0.1s;
155
+ }
156
+
157
+ .generate-btn:hover {
158
+ background-color: #2ea043;
159
+ }
160
+
161
+ .generate-btn:active {
162
+ transform: scale(0.98);
163
+ }
164
+
165
+ .generate-btn:disabled {
166
+ background-color: var(--border-color);
167
+ cursor: not-allowed;
168
+ color: var(--text-muted);
169
+ }
170
+
171
+ .settings-bar {
172
+ display: flex;
173
+ gap: 1.5rem;
174
+ align-items: center;
175
+ font-size: 0.875rem;
176
+ color: var(--text-muted);
177
+ }
178
+
179
+ .agent-toggle {
180
+ display: flex;
181
+ align-items: center;
182
+ gap: 0.5rem;
183
+ cursor: pointer;
184
+ user-select: none;
185
+ }
186
+
187
+ .toggle-checkbox {
188
+ appearance: none;
189
+ width: 16px;
190
+ height: 16px;
191
+ border: 1px solid var(--border-color);
192
+ border-radius: 4px;
193
+ background-color: var(--bg-input);
194
+ position: relative;
195
+ cursor: pointer;
196
+ }
197
+
198
+ .toggle-checkbox:checked {
199
+ background-color: var(--primary);
200
+ border-color: var(--primary);
201
+ }
202
+
203
+ .toggle-checkbox:checked::after {
204
+ content: '✔';
205
+ position: absolute;
206
+ font-size: 10px;
207
+ color: white;
208
+ top: 50%;
209
+ left: 50%;
210
+ transform: translate(-50%, -50%);
211
+ }
212
+
213
+ /* --- Results Grid --- */
214
+ .results-area {
215
+ flex: 1;
216
+ padding: 1.5rem 2rem;
217
+ overflow-y: auto;
218
+ display: grid;
219
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
220
+ gap: 1.5rem;
221
+ }
222
+
223
+ .agent-card {
224
+ background-color: var(--bg-panel);
225
+ border: 1px solid var(--border-color);
226
+ border-radius: 12px;
227
+ display: flex;
228
+ flex-direction: column;
229
+ overflow: hidden;
230
+ transition: box-shadow 0.3s;
231
+ height: 100%;
232
+ min-height: 400px;
233
+ position: relative;
234
+ }
235
+
236
+ .agent-card:hover {
237
+ box-shadow: var(--shadow-lg);
238
+ border-color: #444c56;
239
+ }
240
+
241
+ .card-header {
242
+ padding: 1rem;
243
+ border-bottom: 1px solid var(--border-color);
244
+ display: flex;
245
+ justify-content: space-between;
246
+ align-items: center;
247
+ background-color: rgba(255, 255, 255, 0.02);
248
+ }
249
+
250
+ .agent-info {
251
+ display: flex;
252
+ align-items: center;
253
+ gap: 0.75rem;
254
+ }
255
+
256
+ .agent-avatar {
257
+ width: 32px;
258
+ height: 32px;
259
+ border-radius: 8px;
260
+ display: flex;
261
+ align-items: center;
262
+ justify-content: center;
263
+ font-size: 1.2rem;
264
+ color: white;
265
+ }
266
+
267
+ /* Agent specific colors */
268
+ .agent-gpt .agent-avatar { background: linear-gradient(135deg, #10a37f, #0d8a6a); }
269
+ .agent-claude .agent-avatar { background: linear-gradient(135deg, #d97757, #c25e3e); }
270
+ .agent-llama .agent-avatar { background: linear-gradient(135deg, #0066ff, #0044aa); }
271
+
272
+ .agent-name {
273
+ font-weight: 600;
274
+ font-size: 0.95rem;
275
+ }
276
+
277
+ .agent-model {
278
+ font-size: 0.75rem;
279
+ color: var(--text-muted);
280
+ }
281
+
282
+ .status-badge {
283
+ font-size: 0.75rem;
284
+ padding: 0.25rem 0.6rem;
285
+ border-radius: 99px;
286
+ background-color: rgba(139, 148, 158, 0.2);
287
+ color: var(--text-muted);
288
+ display: flex;
289
+ align-items: center;
290
+ gap: 0.35rem;
291
+ }
292
+
293
+ .status-badge.generating {
294
+ background-color: rgba(210, 153, 34, 0.2);
295
+ color: var(--accent-orange);
296
+ }
297
+
298
+ .status-badge.completed {
299
+ background-color: rgba(35, 134, 54, 0.2);
300
+ color: var(--accent-green);
301
+ }
302
+
303
+ .status-dot {
304
+ width: 6px;
305
+ height: 6px;
306
+ border-radius: 50%;
307
+ background-color: currentColor;
308
+ }
309
+
310
+ .status-badge.generating .status-dot {
311
+ animation: pulse 1.5s infinite;
312
+ }
313
+
314
+ @keyframes pulse {
315
+ 0% { opacity: 1; transform: scale(1); }
316
+ 50% { opacity: 0.5; transform: scale(1.2); }
317
+ 100% { opacity: 1; transform: scale(1); }
318
+ }
319
+
320
+ .card-body {
321
+ flex: 1;
322
+ padding: 0;
323
+ overflow-y: auto;
324
+ background-color: #0d1117;
325
+ position: relative;
326
+ }
327
+
328
+ /* Code Block Styling */
329
+ pre {
330
+ margin: 0;
331
+ padding: 1.5rem;
332
+ font-family: var(--font-mono);
333
+ font-size: 0.9rem;
334
+ line-height: 1.6;
335
+ }
336
+
337
+ code {
338
+ font-family: inherit;
339
+ }
340
+
341
+ .copy-btn {
342
+ position: absolute;
343
+ top: 10px;
344
+ right: 10px;
345
+ background: rgba(255, 255, 255, 0.1);
346
+ border: 1px solid rgba(255, 255, 255, 0.1);
347
+ color: var(--text-main);
348
+ padding: 0.25rem 0.5rem;
349
+ border-radius: 4px;
350
+ font-size: 0.75rem;
351
+ cursor: pointer;
352
+ opacity: 0;
353
+ transition: opacity 0.2s;
354
+ display: flex;
355
+ align-items: center;
356
+ gap: 4px;
357
+ }
358
+
359
+ .card-body:hover .copy-btn {
360
+ opacity: 1;
361
+ }
362
+
363
+ .copy-btn:hover {
364
+ background: rgba(255, 255, 255, 0.2);
365
+ }
366
+
367
+ /* Metrics Footer */
368
+ .card-footer {
369
+ padding: 0.75rem 1rem;
370
+ border-top: 1px solid var(--border-color);
371
+ background-color: var(--bg-panel);
372
+ display: flex;
373
+ justify-content: space-between;
374
+ font-size: 0.75rem;
375
+ color: var(--text-muted);
376
+ }
377
+
378
+ .metric {
379
+ display: flex;
380
+ align-items: center;
381
+ gap: 0.35rem;
382
+ }
383
+
384
+ .metric i {
385
+ font-size: 1rem;
386
+ }
387
+
388
+ /* Empty State */
389
+ .empty-state {
390
+ grid-column: 1 / -1;
391
+ display: flex;
392
+ flex-direction: column;
393
+ align-items: center;
394
+ justify-content: center;
395
+ height: 100%;
396
+ color: var(--text-muted);
397
+ text-align: center;
398
+ padding: 4rem;
399
+ }
400
+
401
+ .empty-icon {
402
+ font-size: 4rem;
403
+ margin-bottom: 1rem;
404
+ opacity: 0.5;
405
+ }
406
+
407
+ /* Scrollbar */
408
+ ::-webkit-scrollbar {
409
+ width: 8px;
410
+ height: 8px;
411
+ }
412
+ ::-webkit-scrollbar-track {
413
+ background: var(--bg-body);
414
+ }
415
+ ::-webkit-scrollbar-thumb {
416
+ background: #30363d;
417
+ border-radius: 4px;
418
+ }
419
+ ::-webkit-scrollbar-thumb:hover {
420
+ background: #484f58;
421
+ }
422
+
423
+ /* Mobile Responsive */
424
+ @media (max-width: 768px) {
425
+ .results-area {
426
+ grid-template-columns: 1fr;
427
+ }
428
+ .header {
429
+ padding: 1rem;
430
+ }
431
+ .prompt-container {
432
+ padding: 1rem;
433
+ }
434
+ .settings-bar {
435
+ flex-wrap: wrap;
436
+ gap: 1rem;
437
+ }
438
+ }
439
+ </style>
440
+ </head>
441
+ <body>
442
+
443
+ <header>
444
+ <div class="logo-area">
445
+ <i class="ph ph-code-block logo-icon"></i>
446
+ <span>AgentArena</span>
447
+ </div>
448
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
449
+ Built with anycoder <i class="ph ph-arrow-square-out"></i>
450
+ </a>
451
+ </header>
452
+
453
+ <main>
454
+ <div class="prompt-container">
455
+ <div class="prompt-wrapper">
456
+ <textarea id="promptInput" placeholder="Describe the code you want to generate (e.g., 'Create a Python script to scrape product prices from Amazon')..."></textarea>
457
+ <button id="generateBtn" class="generate-btn" onclick="startGeneration()">
458
+ <i class="ph ph-lightning"></i> Generate
459
+ </button>
460
+ </div>
461
+
462
+ <div class="settings-bar">
463
+ <span>Active Agents:</span>
464
+ <label class="agent-toggle">
465
+ <input type="checkbox" class="toggle-checkbox" checked disabled>
466
+ <span>GPT-4o</span>
467
+ </label>
468
+ <label class="agent-toggle">
469
+ <input type="checkbox" class="toggle-checkbox" checked>
470
+ <span>Claude 3.5 Sonnet</span>
471
+ </label>
472
+ <label class="agent-toggle">
473
+ <input type="checkbox" class="toggle-checkbox" checked>
474
+ <span>Llama 3 70B</span>
475
+ </label>
476
+ </div>
477
+ </div>
478
+
479
+ <div class="results-area" id="resultsArea">
480
+ <div class="empty-state">
481
+ <i class="ph ph-robot empty-icon"></i>
482
+ <h2>Ready to Code</h2>
483
+ <p>Enter a prompt above to see how different AI agents tackle the same problem.</p>
484
+ </div>
485
+ </div>
486
+ </main>
487
+
488
+ <script>
489
+ // Mock Data for "Streaming" Simulation
490
+ const mockResponses = {
491
+ gpt: `import requests
492
+ from bs4 import BeautifulSoup
493
+ import pandas as pd
494
+ import time
495
+
496
+ def scrape_amazon_prices(product_list):
497
+ headers = {
498
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
499
+ "Accept-Language": "en-US,en;q=0.9"
500
+ }
501
+
502
+ data = []
503
+
504
+ for url in product_list:
505
+ try:
506
+ response = requests.get(url, headers=headers)
507
+ soup = BeautifulSoup(response.content, "html.parser")
508
+
509
+ # Extract Title
510
+ title = soup.find("span", attrs={"id": 'productTitle'})
511
+ title = title.string.strip() if title else "NA"
512
+
513
+ # Extract Price
514
+ price = soup.find("span", attrs={'class': 'a-price-whole'})
515
+ price = price.string.strip() if price else "NA"
516
+
517
+ data.append({"Title": title, "Price": price, "URL": url})
518
+
519
+ # Be polite to the server
520
+ time.sleep(2)
521
+
522
+ except Exception as e:
523
+ print(f"Error scraping {url}: {e}")
524
+
525
+ return pd.DataFrame(data)
526
+
527
+ # Example Usage
528
+ if __name__ == "__main__":
529
+ urls = ["https://amazon.com/dp/B08N5WRWNW"] # Example URL
530
+ df = scrape_amazon_prices(urls)
531
+ print(df)`,
532
+
533
+ claude: `import asyncio
534
+ import aiohttp
535
+ from bs4 import BeautifulSoup
536
+ from typing import List, Dict
537
+
538
+ class AmazonScraper:
539
+ def __init__(self):
540
+ self.headers = {
541
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
542
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
543
+ }
544
+
545
+ async def fetch_page(self, session: aiohttp.ClientSession, url: str) -> str:
546
+ async with session.get(url, headers=self.headers) as response:
547
+ return await response.text()
548
+
549
+ def parse_price(self, html: str) -> Dict:
550
+ soup = BeautifulSoup(html, 'lxml')
551
+
552
+ # Selectors logic
553
+ title_el = soup.select_one('#productTitle')
554
+ price_whole = soup.select_one('.a-price-whole')
555
+ price_fraction = soup.select_one('.a-price-fraction')
556
+
557
+ title = title_el.get_text().strip() if title_el else None
558
+
559
+ price = "N/A"
560
+ if price_whole and price_fraction:
561
+ price = f"{price_whole.get_text().strip()}.{price_fraction.get_text().strip()}"
562
+
563
+ return {
564
+ 'title': title,
565
+ 'price': price,
566
+ 'timestamp': datetime.now().isoformat()
567
+ }
568
+
569
+ async def scrape_products(self, urls: List[str]):
570
+ async with aiohttp.ClientSession() as session:
571
+ tasks = [self.fetch_page(session, url) for url in urls]
572
+ pages = await asyncio.gather(*tasks)
573
+ return [self.parse_price(page) for page in pages]
574
+
575
+ # This is a more robust async approach
576
+ # Requires: pip install aiohttp beautifulsoup4 lxml`,
577
+
578
+ llama: `import requests
579
+ from bs4 import BeautifulSoup
580
+ import csv
581
+
582
+ def get_product_details(url):
583
+ """
584
+ Simple function to get product details.
585
+ Note: Amazon has strict anti-scraping.
586
+ You might need proxies in production.
587
+ """
588
+
589
+ # Headers are crucial to avoid 503 errors
590
+ headers = ({'User-Agent':
591
+ 'Mozilla/5.0 (X11; Linux x86_64) \
592
+ AppleWebKit/537.36 (KHTML, like Gecko) \
593
+ Chrome/44.0.2403.157 Safari/537.36',
594
+ 'Accept-Language': 'en-US, en;q=0.5'})
595
+
596
+ page = requests.get(url, headers=headers)
597
+ soup = BeautifulSoup(page.content, "html.parser")
598
+
599
+ try:
600
+ title = soup.find("span", attrs={"id": 'productTitle'}).text.strip()
601
+ except AttributeError:
602
+ title = ""
603
+
604
+ try:
605
+ price_parent = soup.find("span", attrs={'class': 'a-price'})
606
+ price = price_parent.find("span", attrs={'class': 'a-offscreen'}).text
607
+ except AttributeError:
608
+ price = ""
609
+
610
+ return title, price
611
+
612
+ def save_to_csv(products):
613
+ fields = ['Title', 'Price', 'Link']
614
+ with open('amazon_products.csv', 'w', newline='') as f:
615
+ write = csv.writer(f)
616
+ write.writerow(fields)
617
+ write.writerows(products)
618
+
619
+ # Main execution flow
620
+ print("Starting scraper...")
621
+ `
622
+ };
623
+
624
+ const agents = [
625
+ { id: 'gpt', name: 'GPT-4o', model: 'OpenAI', class: 'agent-gpt', icon: 'ph-openai-logo' },
626
+ { id: 'claude', name: 'Claude 3.5', model: 'Anthropic', class: 'agent-claude', icon: 'ph-brain' },
627
+ { id: 'llama', name: 'Llama 3', model: 'Meta AI', class: 'agent-llama', icon: 'ph-meta-logo' }
628
+ ];
629
+
630
+ function createAgentCard(agent) {
631
+ return `
632
+ <div class="agent-card ${agent.class}" id="card-${agent.id}">
633
+ <div class="card-header">
634
+ <div class="agent-info">
635
+ <div class="agent-avatar">
636
+ <i class="ph ${agent.icon}"></i>
637
+ </div>
638
+ <div>
639
+ <div class="agent-name">${agent.name}</div>
640
+ <div class="agent-model">${agent.model}</div>
641
+ </div>
642
+ </div>
643
+ <div class="status-badge generating" id="status-${agent.id}">
644
+ <div class="status-dot"></div>
645
+ <span>Thinking...</span>
646
+ </div>
647
+ </div>
648
+ <div class="card-body">
649
+ <button class="copy-btn" onclick="copyCode('code-${agent.id}')">
650
+ <i class="ph ph-copy"></i> Copy
651
+ </button>
652
+ <pre><code class="language-python" id="code-${agent.id}"></code></pre>
653
+ </div>
654
+ <div class="card-footer">
655
+ <div class="metric" id="time-${agent.id}">
656
+ <i class="ph ph-clock"></i> --s
657
+ </div>
658
+ <div class="metric" id="tokens-${agent.id}">
659
+ <i class="ph ph-text-aa"></i> -- tokens
660
+ </div>
661
+ </div>
662
+ </div>
663
+ `;
664
+ }
665
+
666
+ function sleep(ms) {
667
+ return new Promise(resolve => setTimeout(resolve, ms));
668
+ }
669
+
670
+ async function typeWriter(elementId, text, speed = 10) {
671
+ const element = document.getElementById(elementId);
672
+ let i = 0;
673
+ // Clear previous content
674
+ element.textContent = '';
675
+
676
+ // Random chunk size to simulate network packets
677
+ while (i < text.length) {
678
+ const chunkSize = Math.floor(Math.random() * 5) + 2;
679
+ const chunk = text.slice(i, i + chunkSize);
680
+ element.textContent += chunk;
681
+
682
+ // Highlight syntax periodically (simulating real-time render)
683
+ if (i % 50 === 0) {
684
+ hljs.highlightElement(element);
685
+ // Auto scroll to bottom
686
+ element.parentElement.parentElement.scrollTop = element.parentElement.parentElement.scrollHeight;
687
+ }
688
+
689
+ i += chunkSize;
690
+ await sleep(speed);
691
+ }
692
+
693
+ // Final highlight
694
+ hljs.highlightElement(element);
695
+ }
696
+
697
+ async function simulateAgent(agent) {
698
+ const startTime = Date.now();
699
+ const codeElementId = `code-${agent.id}`;
700
+ const statusElementId = `status-${agent.id}`;
701
+ const timeElementId = `time-${agent.id}`;
702
+ const tokenElementId = `tokens-${agent.id}`;
703
+
704
+ // Initial Delay to simulate processing start
705
+ await sleep(Math.random() * 1000 + 500);
706
+
707
+ const statusEl = document.getElementById(statusElementId);
708
+ statusEl.innerHTML = `<div class="status-dot"></div><span>Generating...</span>`;
709
+
710
+ // Typewriter effect
711
+ await typeWriter(codeElementId, mockResponses[agent.id], 15); // 15ms per char approx
712
+
713
+ const endTime = Date.now();
714
+ const duration = ((endTime - startTime) / 1000).toFixed(2);
715
+ const tokens = mockResponses[agent.id].length / 4; // Rough estimate
716
+
717
+ // Update UI to completed
718
+ statusEl.className = 'status-badge completed';
719
+ statusEl.innerHTML = `<i class="ph ph-check-circle"></i><span>Done</span>`;
720
+
721
+ document.getElementById(timeElementId).innerHTML = `<i class="ph ph-clock"></i> ${duration}s`;
722
+ document.getElementById(tokenElementId).innerHTML = `<i class="ph ph-text-aa"></i> ~${Math.floor(tokens)} tokens`;
723
+ }
724
+
725
+ async function startGeneration() {
726
+ const promptInput = document.getElementById('promptInput');
727
+ const generateBtn = document.getElementById('generateBtn');
728
+ const resultsArea = document.getElementById('resultsArea');
729
+
730
+ if (!promptInput.value.trim()) {
731
+ alert("Please enter a prompt first.");
732
+ return;
733
+ }
734
+
735
+ // Lock UI
736
+ generateBtn.disabled = true;
737
+ generateBtn.innerHTML = `<i class="ph ph-spinner-gap ph-spin"></i> Processing...`;
738
+
739
+ // Clear previous results and setup grid
740
+ resultsArea.innerHTML = '';
741
+
742
+ // Create cards
743
+ agents.forEach(agent => {
744
+ resultsArea.innerHTML += createAgentCard(agent);
745
+ });
746
+
747
+ // Start simulations concurrently
748
+ const promises = agents.map(agent => simulateAgent(agent));
749
+
750
+ await Promise.all(promises);
751
+
752
+ // Unlock UI
753
+ generateBtn.disabled = false;
754
+ generateBtn.innerHTML = `<i class="ph ph-lightning"></i> Generate`;
755
+ }
756
+
757
+ function copyCode(elementId) {
758
+ const code = document.getElementById(elementId).innerText;
759
+ navigator.clipboard.writeText(code).then(() => {
760
+ // Simple feedback
761
+ alert('Code copied to clipboard!');
762
+ });
763
+ }
764
+ </script>
765
+ </body>
766
+ </html>