acecalisto3 commited on
Commit
91df01e
·
verified ·
1 Parent(s): fd5ee65

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +352 -255
index.html CHANGED
@@ -1,277 +1,374 @@
1
- <!DOCTYPE html>
2
  <html>
3
- <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width" />
6
-
7
  <title>Smolagents and tools gallery</title>
8
  <meta name="description" content="Discover all smolagents and tools created by the community." />
9
-
10
- <meta property="og:url" content="https://smolagents-tools-gallery.hf.space/" />
11
- <meta property="og:type" content="website" />
12
- <meta property="og:title" content="smolagents and tools gallery" />
13
- <meta property="og:description" content="Discover all smolagents and tools created by the community." />
14
- <meta property="og:image" content="https://huggingface-projects-diffusers-gallery.hf.space/Fo6vR6JX0AEjbw1.jpeg" />
15
-
16
- <meta name="twitter:card" content="player" />
17
- <meta property="twitter:url" content="https://davidberenstein1957-smolagents-and-tools.static.hf.space" />
18
- <meta name="twitter:description" content="Discover all smolagents and tools created by the community." />
19
-
20
- <meta name="twitter:site" content="@huggingface" />
21
- <meta name="twitter:title" content="smolagents and tools gallery" />
22
-
23
- <meta name="twitter:image" content="https://huggingface-projects-diffusers-gallery.hf.space/Fo6vR6JX0AEjbw1.jpeg" />
24
- <meta name="twitter:player" content="https://davidberenstein1957-smolagents-and-tools.static.hf.space" />
25
- <meta name="twitter:player:width" content="100%" />
26
- <meta name="twitter:player:height" content="600" />
27
-
28
  <script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script>
29
  <script src="https://cdn.tailwindcss.com"></script>
30
-
31
  <style>
32
- /* Existing styles remain unchanged */
33
- iframe {
34
- display: block;
35
- border: none;
36
- width: 100%;
37
- height: 600px;
38
- pointer-events: none;
39
- margin-top: 48px; /* Match header height */
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  .grid-container {
42
- display: grid;
43
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
44
- grid-gap: 10px;
45
- margin-top: 3.5rem;
46
- }
47
  .grid-item {
48
- position: relative;
49
- overflow-y: hidden;
50
- border-radius: 10px;
51
- border: 1px solid rgb(55 65 81);
52
- }
53
  .grid-item:hover {
54
- filter: brightness(75%);
55
- }
56
  .grid-item a {
57
- position: absolute;
58
- top: 0;
59
- left: 0;
60
- width: 100%;
61
- height: 100%;
62
- display: block;
63
- z-index: 1;
64
- }
65
  .grid-item-header {
66
- position: absolute;
67
- top: 0;
68
- left: 0;
69
- right: 0;
70
- height: 48px;
71
- background: rgba(0,0,0,0.75);
72
- padding: 8px 16px;
73
- z-index: 10;
74
- display: flex;
75
- align-items: center;
76
- width: 100%;
77
- }
78
  .grid-item-header h2 {
79
- width: 100%;
80
- overflow-wrap: break-word;
81
- word-wrap: break-word;
82
- hyphens: auto;
83
- max-height: 32px;
84
- overflow: hidden;
85
- display: -webkit-box;
86
- -webkit-line-clamp: 2;
87
- -webkit-box-orient: vertical;
88
- line-height: 1.2;
89
- }
90
  </style>
91
-
92
  <script type="module">
93
- import Alpine from "https://cdn.skypack.dev/[email protected]";
94
- import Intersect from "https://cdn.skypack.dev/@alpinejs/intersect";
95
- Alpine.plugin(Intersect);
96
- Alpine.data("themesData", () => ({
97
- async init() {
98
- const data = await this.getThemes(this.page, this.sort, this.useTestData);
99
- this.themes = data.themes;
100
- this.totalPages = data.totalPages;
101
- },
102
- themes: [],
103
- filter: "tool",
104
- sort: "likes",
105
- page: 1,
106
- totalPages: -1,
107
- useTestData: false,
108
- searchQuery: "",
109
- searchType: "keyword",
110
- hfToken: "", // New property for Hugging Face token
111
- userSpaces: [], // New property to store user spaces
112
- buttonClass(attr, filter) {
113
- if (this[attr] === filter) {
114
- return "text-orange-600 bg-gradient-to-br from-orange-300 to-orange-100 px-2 md:px-3 py-1 rounded-full";
115
- }
116
- return "text-gray-800 hover:to-orange-300/100 hover:text-orange-600 dark:hover:bg-white";
117
- },
118
- async switchData() {
119
- this.page = 1;
120
- this.useTestData = !this.useTestData;
121
- const data = await this.getThemes(this.page, this.sort, this.useTestData);
122
- this.themes = data.themes;
123
- this.totalPages = data.totalPages;
124
- },
125
- async sortThemes(sort) {
126
- this.sort = sort;
127
- this.page = 1;
128
- const data = await this.getThemes(this.page, this.sort, this.useTestData);
129
- this.themes = data.themes;
130
- this.totalPages = data.totalPages;
131
- },
132
- async filterType(filter) {
133
- this.filter = filter;
134
- this.page = 1;
135
- if (this.searchQuery) {
136
- await this.searchThemes();
137
- } else {
138
- const data = await this.getThemes(this.page, this.sort, this.useTestData);
139
- this.themes = data.themes;
140
- this.totalPages = data.totalPages;
141
- }
142
- },
143
- async searchThemes() {
144
- this.page = 1;
145
- const data = await this.getThemes(this.page, this.sort, this.useTestData);
146
- this.themes = data.themes;
147
- this.totalPages = data.totalPages;
148
- },
149
- async switchSearchType(type) {
150
- this.searchType = type;
151
- if (this.searchQuery) {
152
- await this.searchThemes();
153
- }
154
- },
155
- async getUser Spaces() {
156
- if (!this.hfToken) return;
157
- const res = await fetch(`https://huggingface.co/api/spaces?token=${this.hfToken}`);
158
- const data = await res.json();
159
- this.userSpaces = data; // Store user spaces
160
- },
161
- async getThemes(page, sort, useTestData) {
162
- let data;
163
- if (useTestData) {
164
- const res = await fetch(
165
- `https://huggingface.co/datasets/freddyaboulton/gradio-theme-subdomains/resolve/main/test_data.json`
166
- );
167
- data = await res.json();
168
- } else {
169
- const searchFilters = this.filter === 'tool' ? 'tool' : 'smolagents';
170
- let searchUrl;
171
- if (this.searchQuery) {
172
- if (this.searchType === 'semantic') {
173
- searchUrl = `https://huggingface.co/api/spaces/semantic-search?limit=100&filter=${searchFilters}&q=${encodeURIComponent(this.searchQuery)}&expand[]=subdomain&expand[]=lastModified&expand[]=likes&expand[]=runtime`;
174
- } else {
175
- searchUrl = `https://huggingface.co/api/spaces?limit=100&filter=${searchFilters}&search=${encodeURIComponent(this.searchQuery)}&expand[]=subdomain&expand[]=lastModified&expand[]=likes&expand[]=runtime`;
176
- }
177
- } else {
178
- searchUrl = `https://huggingface.co/api/spaces?limit=100&filter=${encodeURIComponent(searchFilters)}&expand[]=subdomain&expand[]=lastModified&expand[]=likes&expand[]=runtime`;
179
- }
180
- const res = await fetch(searchUrl);
181
- data = await res.json();
182
- console.log(data);
183
- data = data.filter(item => item.runtime?.stage === "RUNNING").map(item => ({
184
- id: item.id,
185
- subdomain: `https://${item.subdomain}.hf.space`,
186
- likes: item.likes,
187
- lastModified: item.lastModified
188
- }));
189
- }
190
- if (sort === 'likes') {
191
- data.sort((a, b) => (b.likes - a.likes));
192
- } else {
193
- data.sort((a, b) => (new Date(b.lastModified) - new Date(a.lastModified)));
194
- }
195
- const pageThemes = data.slice((page - 1) * 15, page * 15);
196
- console.log(pageThemes);
197
- return {
198
- themes: pageThemes,
199
- totalPages: Math.ceil(data.length / 15)
200
- };
201
- },
202
- async nextPage() {
203
- if (this.page < this.totalPages) {
204
- this.page += 1;
205
- const data = await this.getThemes(this.page, this.sort, this.useTestData);
206
- this.themes = this.themes.concat(data.themes);
207
- this.totalPages = data.totalPages;
208
- }
209
- },
210
- publishSelected() {
211
- // Logic to publish selected spaces
212
- const selectedSpaces = this.userSpaces.filter(space => space.selected);
213
- // Implement the publish functionality here
214
- },
215
- }));
216
- Alpine.start();
217
  </script>
218
- </head>
219
-
220
- <body class="pb-10 pt-5 bg-white relative">
221
  <section x-data="themesData">
222
- <section class="container px-6 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-14 mx-auto relative">
223
- <div class="col-span-2 lg:col-span-1 flex flex-col gap-14 row-start">
224
- <div class="flex items-center gap-2">
225
- <img src="https://camo.githubusercontent.com/a8c1f1d12aa3114010c6e74b29d47fee91d8da10a915f065c38e6d0ea7f16568/68747470733a2f2f68756767696e67666163652e636f2f64617461736574732f68756767696e67666163652f646f63756d656e746174696f6e2d696d616765732f7265736f6c76652f6d61696e2f736d6f6c6167656e74732f6d6173636f742e706e67" alt="Smolagents mascot" class="w-14 h-14 flex-shrink-0">
226
- <h1 class="text-xl font-semibold text-gray-800 break-words">smolagents and tools gallery</h1>
227
- </div>
228
- <div class="flex items-center gap-2">
229
- <input
230
- type="text"
231
- x-model="hfToken"
232
- placeholder="Enter your Hugging Face Token"
233
- class="px-3 py-1 border rounded-lg"
234
- >
235
- <button @click="getUser Spaces()" class="px-3 py-1 bg-blue-500 text-white rounded-lg">Import Spaces</button>
236
- </div>
237
- </div>
238
- <div class="col-span-2 md:col-span-3 flex items-center gap-14 flex flex-wrap lg-auto lg:ml-auto text-sm">
239
- <div class="flex flex-col gap-2">
240
- <div class="flex items-center">
241
- <input
242
- type="text"
243
- x-model="searchQuery"
244
- @input="searchThemes()"
245
- placeholder="Search..."
246
- class="px-3 py-1 border rounded-lg"
247
- >
248
  </div>
249
- </div>
250
- <div class="flex gap-2">
251
- <span class="md:px-3 py-1 text-gray-800">type</span>
252
- <button :class="buttonClass('filter', 'tool')" @click="filterType('tool')">Tools</button>
253
- <button :class="buttonClass('filter', 'agent')" @click="filterType('agent')">Agents</button>
254
- </div>
255
- <div class="flex gap-2">
256
- <span class="md:px-3 py-1 text-gray-800">sort by</span>
257
- <button :class="buttonClass('sort', 'likes')" @click="sortThemes('likes')">Most Likes</button>
258
- <button :class="buttonClass('sort', 'recent')" @click="sortThemes('recent')">Recent</button>
259
- </div>
260
- </div>
261
- </section>
262
- <div class="container px-6 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2 mx-auto my-8 relative">
263
- <template x-for="theme in themes" :key="theme.id">
264
- <div class="grid-item">
265
- <div class="grid-item-header">
266
- <h2 class="text-sm font-medium text-white" x-text="theme.id"></h2>
 
 
 
 
267
  </div>
268
- <iframe :src="`${theme.subdomain}?_=${new Date().getTime()}`" :alt="theme.id" scrolling="no" frameborder="0" loading="lazy"></iframe>
269
- <a :href="`https://huggingface.co/spaces/${theme.id}`" target="_blank"></a>
270
- </div>
271
- </template>
272
- </div>
273
- <div class="h-12 relative" x-intersect="nextPage" data-iframe-height></div>
274
- <button @click="publishSelected()" class="px-4 py -2 bg-green-500 text-white rounded-lg">Publish Selected Spaces</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  </section>
276
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  </html>
 
1
+ <!DOCTYPE html>
2
  <html>
3
+ <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width" />
 
6
  <title>Smolagents and tools gallery</title>
7
  <meta name="description" content="Discover all smolagents and tools created by the community." />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script>
9
  <script src="https://cdn.tailwindcss.com"></script>
 
10
  <style>
11
+ body {
12
+ font-family: sans-serif;
13
+ padding: 20px;
14
+ background-color: #f4f4f4;
15
+ }
16
+ #playground-container {
17
+ max-width: 800px;
18
+ margin: 0 auto;
19
+ background-color: white;
20
+ padding: 20px;
21
+ border-radius: 8px;
22
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
23
+ }
24
+ #input-container, #output-container, #tool-select {
25
+ margin-bottom: 20px;
26
+ }
27
+ textarea {
28
+ width: 100%;
29
+ padding: 10px;
30
+ border: 1px solid #ccc;
31
+ border-radius: 4px;
32
+ resize: vertical;
33
+ }
34
+ button {
35
+ padding: 10px 20px;
36
+ background-color: #007bff;
37
+ color: white;
38
+ border: none;
39
+ border-radius: 4px;
40
+ cursor: pointer;
41
+ }
42
+ button:hover {
43
+ background-color: #0056b3;
44
+ }
45
+ #output-container {
46
+ border: 1px solid #ddd;
47
+ padding: 15px;
48
+ min-height: 150px;
49
+ white-space: pre-wrap;
50
+ background-color: #f9f9f9;
51
+ border-radius: 4px;
52
+ }
53
+ #loading-indicator {
54
+ display: none;
55
+ text-align: center;
56
+ margin-top: 10px;
57
+ }
58
+ #error-message {
59
+ color: red;
60
+ margin-top: 10px;
61
+ }
62
+ select {
63
+ padding: 8px;
64
+ border-radius: 4px;
65
+ border: 1px solid #ccc;
66
+ }
67
+ iframe {
68
+ display: block;
69
+ border: none;
70
+ width: 100%;
71
+ height: 600px;
72
+ pointer-events: none;
73
+ margin-top: 48px; /* Match header height */
74
+ }
75
  .grid-container {
76
+ display: grid;
77
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
78
+ grid-gap: 10px;
79
+ margin-top: 3.5rem;
80
+ }
81
  .grid-item {
82
+ position: relative;
83
+ overflow-y: hidden;
84
+ border-radius: 10px;
85
+ border: 1px solid rgb(55 65 81);
86
+ }
87
  .grid-item:hover {
88
+ filter: brightness(75%);
89
+ }
90
  .grid-item a {
91
+ position: absolute;
92
+ top: 0;
93
+ left: 0;
94
+ width: 100%;
95
+ height: 100%;
96
+ display: block;
97
+ z-index: 1;
98
+ }
99
  .grid-item-header {
100
+ position: absolute;
101
+ top: 0;
102
+ left: 0;
103
+ right: 0;
104
+ height: 48px;
105
+ background: rgba(0,0,0,0.75);
106
+ padding: 8px 16px;
107
+ z-index: 10;
108
+ display: flex;
109
+ align-items: center;
110
+ width: 100%;
111
+ }
112
  .grid-item-header h2 {
113
+ width: 100%;
114
+ overflow-wrap: break-word;
115
+ word-wrap: break-word;
116
+ hyphens: auto;
117
+ max-height: 32px;
118
+ overflow: hidden;
119
+ display: -webkit-box;
120
+ -webkit-line-clamp: 2;
121
+ -webkit-box-orient: vertical;
122
+ line-height: 1.2;
123
+ }
124
  </style>
 
125
  <script type="module">
126
+ import Alpine from "https://cdn.skypack.dev/[email protected]";
127
+ import Intersect from "https://cdn.skypack.dev/@alpinejs/intersect";
128
+ Alpine.plugin(Intersect);
129
+ Alpine.data("themesData", () => ({
130
+ async init() {
131
+ const data = await this.getThemes(this.page, this.sort, this.useTestData);
132
+ this.themes = data.themes;
133
+ this.totalPages = data.totalPages;
134
+ },
135
+ themes:,
136
+ filter: "tool",
137
+ sort: "likes",
138
+ page: 1,
139
+ totalPages: -1,
140
+ useTestData: false,
141
+ searchQuery: "",
142
+ searchType: "keyword",
143
+ hfToken: "",
144
+ userSpaces:,
145
+ buttonClass(attr, filter) {
146
+ if (this[attr] === filter) {
147
+ return "text-orange-600 bg-gradient-to-br from-orange-300 to-orange-100 px-2 md:px-3 py-1 rounded-full";
148
+ }
149
+ return "text-gray-800 hover:to-orange-300/100 hover:text-orange-600 dark:hover:bg-white";
150
+ },
151
+ async switchData() {
152
+ this.page = 1;
153
+ this.useTestData =!this.useTestData;
154
+ const data = await this.getThemes(this.page, this.sort, this.useTestData);
155
+ this.themes = data.themes;
156
+ this.totalPages = data.totalPages;
157
+ },
158
+ async sortThemes(sort) {
159
+ this.sort = sort;
160
+ this.page = 1;
161
+ const data = await this.getThemes(this.page, this.sort, this.useTestData);
162
+ this.themes = data.themes;
163
+ this.totalPages = data.totalPages;
164
+ },
165
+ async filterType(filter) {
166
+ this.filter = filter;
167
+ this.page = 1;
168
+ if (this.searchQuery) {
169
+ await this.searchThemes();
170
+ } else {
171
+ const data = await this.getThemes(this.page, this.sort, this.useTestData);
172
+ this.themes = data.themes;
173
+ this.totalPages = data.totalPages;
174
+ }
175
+ },
176
+ async searchThemes() {
177
+ this.page = 1;
178
+ const data = await this.getThemes(this.page, this.sort, this.useTestData);
179
+ this.themes = data.themes;
180
+ this.totalPages = data.totalPages;
181
+ },
182
+ async switchSearchType(type) {
183
+ this.searchType = type;
184
+ if (this.searchQuery) {
185
+ await this.searchThemes();
186
+ }
187
+ },
188
+ async getUserSpaces() {
189
+ if (!this.hfToken) return;
190
+ const res = await fetch(`https://huggingface.co/api/spaces?token=${this.hfToken}`);
191
+ const data = await res.json();
192
+ this.userSpaces = data;
193
+ },
194
+ async getThemes(page, sort, useTestData) {
195
+ let data;
196
+ if (useTestData) {
197
+ const res = await fetch(
198
+ `https://huggingface.co/datasets/freddyaboulton/gradio-theme-subdomains/resolve/main/test_data.json`
199
+ );
200
+ data = await res.json();
201
+ } else {
202
+ const searchFilters = this.filter === 'tool'? 'tool': 'smolagents';
203
+ let searchUrl;
204
+ if (this.searchQuery) {
205
+ if (this.searchType === 'semantic') {
206
+ searchUrl = `https://huggingface.co/api/spaces/semantic-search?limit=100&filter=<span class="math-inline">\{searchFilters\}&q\=</span>{encodeURIComponent(this.searchQuery)}&expand=subdomain&expand=lastModified&expand=likes&expand=runtime`;
207
+ } else {
208
+ searchUrl = `https://huggingface.co/api/spaces?limit=100&filter=<span class="math-inline">\{searchFilters\}&search\=</span>{encodeURIComponent(this.searchQuery)}&expand=subdomain&expand=lastModified&expand=likes&expand=runtime`;
209
+ }
210
+ } else {
211
+ searchUrl = `https://huggingface.co/api/spaces?limit=100&filter=${encodeURIComponent(searchFilters)}&expand=subdomain&expand=lastModified&expand=likes&expand=runtime`;
212
+ }
213
+ const res = await fetch(searchUrl);
214
+ data = await res.json();
215
+ data = data.filter(item => item.runtime?.stage === "RUNNING").map(item => ({
216
+ id: item.id,
217
+ subdomain: `https://${item.subdomain}.hf.space`,
218
+ likes: item.likes,
219
+ lastModified: item.lastModified
220
+ }));
221
+ }
222
+ if (sort === 'likes') {
223
+ data.sort((a, b) => (b.likes - a.likes));
224
+ } else {
225
+ data.sort((a, b) => (new Date(b.lastModified) - new Date(a.lastModified)));
226
+ }
227
+ const pageThemes = data.slice((page - 1) * 15, page * 15);
228
+ return {
229
+ themes: pageThemes,
230
+ totalPages: Math.ceil(data.length / 15)
231
+ };
232
+ },
233
+ async nextPage() {
234
+ if (this.page < this.totalPages) {
235
+ this.page += 1;
236
+ const data = await this.getThemes(this.page, this.sort, this.useTestData);
237
+ this.themes = this.themes.concat(data.themes);
238
+ this.totalPages = data.totalPages;
239
+ }
240
+ },
241
+ publishSelected() {
242
+ const selectedSpaces = this.userSpaces.filter(space => space.selected);
243
+ },
244
+ }));
245
+ Alpine.start();
 
 
 
 
246
  </script>
247
+ </head>
248
+ <body class="pb-10 pt-5 bg-white relative">
 
249
  <section x-data="themesData">
250
+ <section class="container px-6 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-14 mx-auto relative">
251
+ <div class="col-span-2 lg:col-span-1 flex flex-col gap-14 row-start">
252
+ <div class="flex items-center gap-2">
253
+ <img src="https://camo.githubusercontent.com/a8c1f1d12aa3114010c6e74b29d47fee91d8da10a915f065c38e6d0ea7f16568/68747470733a2f2f68756767696e67666163652e636f2f64617461736574732f68756767696e67666163652f646f63756d656e746174696f6e2d696d616765732f7265736f6c76652f6d61696e2f736d6f6c6167656e74732f6d6173636f742e706e67" alt="Smolagents mascot" class="w-14 h-14 flex-shrink-0">
254
+ <h1 class="text-xl font-semibold text-gray-800 break-words">smolagents and tools gallery</h1>
255
+ </div>
256
+ <div class="flex items-center gap-2">
257
+ <input
258
+ type="text"
259
+ x-model="hfToken"
260
+ placeholder="Enter your Hugging Face Token"
261
+ class="px-3 py-1 border rounded-lg"
262
+ >
263
+ <button @click="getUserSpaces()" class="px-3 py-1 bg-blue-500 text-white rounded-lg">Import Spaces</button>
264
+ </div>
 
 
 
 
 
 
 
 
 
 
 
265
  </div>
266
+ <div class="col-span-2 md:col-span-3 flex items-center gap-14 flex flex-wrap lg-auto lg:ml-auto text-sm">
267
+ <div class="flex flex-col gap-2">
268
+ <div class="flex items-center">
269
+ <input
270
+ type="text"
271
+ x-model="searchQuery"
272
+ @input="searchThemes()"
273
+ placeholder="Search..."
274
+ class="px-3 py-1 border rounded-lg"
275
+ >
276
+ </div>
277
+ </div>
278
+ <div class="flex gap-2">
279
+ <span class="md:px-3 py-1 text-gray-800">type</span>
280
+ <button:class="buttonClass('filter', 'tool')" @click="filterType('tool')">Tools</button>
281
+ <button:class="buttonClass('filter', 'agent')" @click="filterType('agent')">Agents</button>
282
+ </div>
283
+ <div class="flex gap-2">
284
+ <span class="md:px-3 py-1 text-gray-800">sort by</span>
285
+ <button:class="buttonClass('sort', 'likes')" @click="sortThemes('likes')">Most Likes</button>
286
+ <button:class="buttonClass('sort', 'recent')" @click="sortThemes('recent')">Recent</button>
287
+ </div>
288
  </div>
289
+ </section>
290
+ <div class="container px-6 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2 mx-auto my-8 relative">
291
+ <template x-for="theme in themes":key="theme.id">
292
+ <div class="grid-item">
293
+ <div class="grid-item-header">
294
+ <h2 class="text-sm font-medium text-white" x-text="theme.id"></h2>
295
+ </div>
296
+ <iframe:src="`<span class="math-inline">\{theme\.subdomain\}?\_\=</span>{new Date().getTime()}`":alt="theme.id" scrolling="no" frameborder="0" loading="lazy"></iframe>
297
+ <a:href="`https://huggingface.co/spaces/${theme.id}`" target="_blank"></a>
298
+ </div>
299
+ </template>
300
+ <div class="grid-item">
301
+ <div class="grid-item-header">
302
+ <h2 class="text-sm font-medium text-white">smolagents Playground</h2>
303
+ </div>
304
+
305
+ <div id="playground-container">
306
+ <div id="tool-select">
307
+ <label for="tools">Select Tools:</label><br>
308
+ <select id="tools" multiple>
309
+ <option value="DuckDuckGoSearchTool">DuckDuckGoSearchTool</option>
310
+ </select>
311
+ </div>
312
+
313
+ <div id="input-container">
314
+ <label for="user-input">Enter your query:</label><br>
315
+ <textarea id="user-input" rows="5"></textarea><br>
316
+ <button id="run-button">Run Agent</button>
317
+ <div id="loading-indicator">Running...</div>
318
+ <div id="error-message"></div>
319
+ </div>
320
+
321
+ <div id="output-container">
322
+ <p>Agent output:</p>
323
+ <div id="output"></div>
324
+ </div>
325
+ </div>
326
+
327
+ <a href="https://huggingface.co/spaces/your-username/your-space-name" target="_blank"></a>
328
+ </div>
329
+ </div>
330
+
331
+ <div class="h-12 relative" x-intersect="nextPage" data-iframe-height></div>
332
+ <button @click="publishSelected()" class="px-4 py-2 bg-green-500 text-white rounded-lg">Publish Selected Spaces</button>
333
  </section>
334
+
335
+ <script>
336
+ document.getElementById('run-button').addEventListener('click', async () => {
337
+ const userInput = document.getElementById('user-input').value;
338
+ const outputDiv = document.getElementById('output');
339
+ const loadingIndicator = document.getElementById('loading-indicator');
340
+ const errorMessage = document.getElementById('error-message');
341
+
342
+ outputDiv.textContent = "";
343
+ errorMessage.textContent = "";
344
+ loadingIndicator.style.display = 'block';
345
+
346
+ const selectedTools = Array.from(document.getElementById('tools').selectedOptions).map(option => option.value);
347
+
348
+ try {const response = await fetch('/run_agent', {
349
+ method: 'POST',
350
+ headers: {
351
+ 'Content-Type': 'application/json'
352
+ },
353
+ body: JSON.stringify({
354
+ query: userInput,
355
+ tools: selectedTools
356
+ })
357
+ });
358
+
359
+ loadingIndicator.style.display = 'none';
360
+
361
+ if (response.ok) {
362
+ const data = await response.json();
363
+ outputDiv.textContent = data.result;
364
+ } else {
365
+ errorMessage.textContent = `Error: ${response.statusText}`;
366
+ }
367
+ } catch (error) {
368
+ loadingIndicator.style.display = 'none';
369
+ errorMessage.textContent = `Error: ${error.message}`;
370
+ }
371
+ });
372
+ </script>
373
+ </body>
374
  </html>