Thomas G. Lopes commited on
Commit
2488073
·
1 Parent(s): 9662103

simple provider select

Browse files
package.json CHANGED
@@ -40,6 +40,7 @@
40
  "@huggingface/hub": "^1.0.1",
41
  "@huggingface/inference": "^3.5.1",
42
  "@huggingface/tasks": "^0.17.1",
 
43
  "@tailwindcss/container-queries": "^0.1.1"
44
  }
45
  }
 
40
  "@huggingface/hub": "^1.0.1",
41
  "@huggingface/inference": "^3.5.1",
42
  "@huggingface/tasks": "^0.17.1",
43
+ "@melt-ui/svelte": "^0.86.3",
44
  "@tailwindcss/container-queries": "^0.1.1"
45
  }
46
  }
pnpm-lock.yaml CHANGED
@@ -17,6 +17,9 @@ importers:
17
  '@huggingface/tasks':
18
  specifier: ^0.17.1
19
  version: 0.17.1
 
 
 
20
  '@tailwindcss/container-queries':
21
  specifier: ^0.1.1
22
  version: 0.1.1([email protected])
@@ -251,6 +254,15 @@ packages:
251
  resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
252
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
253
 
 
 
 
 
 
 
 
 
 
254
  '@huggingface/[email protected]':
255
  resolution: {integrity: sha512-wogGVETaNUV/wYBkny0uQD48L0rK9cttVtbaA1Rw/pGCuSYoZ8YlvTV6zymsGJfXaxQU8zup0aOR2XLIf6HVfg==}
256
  engines: {node: '>=18'}
@@ -278,6 +290,9 @@ packages:
278
  resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
279
  deprecated: Use @eslint/object-schema instead
280
 
 
 
 
281
  '@jridgewell/[email protected]':
282
  resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
283
  engines: {node: '>=6.0.0'}
@@ -296,6 +311,11 @@ packages:
296
  '@jridgewell/[email protected]':
297
  resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
298
 
 
 
 
 
 
299
  '@nodelib/[email protected]':
300
  resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
301
  engines: {node: '>= 8'}
@@ -476,6 +496,9 @@ packages:
476
  svelte: ^4.0.0 || ^5.0.0-next.0
477
  vite: ^5.0.0
478
 
 
 
 
479
  '@tailwindcss/[email protected]':
480
  resolution: {integrity: sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==}
481
  peerDependencies:
@@ -758,6 +781,10 @@ packages:
758
  resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
759
  engines: {node: '>=0.10.0'}
760
 
 
 
 
 
761
762
  resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
763
  engines: {node: '>=8'}
@@ -902,6 +929,9 @@ packages:
902
903
  resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
904
 
 
 
 
905
906
  resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
907
 
@@ -1170,6 +1200,11 @@ packages:
1170
  engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1171
  hasBin: true
1172
 
 
 
 
 
 
1173
1174
  resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1175
 
@@ -1506,6 +1541,9 @@ packages:
1506
  resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==}
1507
  engines: {node: '>=16'}
1508
 
 
 
 
1509
1510
  resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==}
1511
 
@@ -1717,6 +1755,17 @@ snapshots:
1717
 
1718
  '@eslint/[email protected]': {}
1719
 
 
 
 
 
 
 
 
 
 
 
 
1720
  '@huggingface/[email protected]':
1721
  dependencies:
1722
  '@huggingface/tasks': 0.15.9
@@ -1741,6 +1790,10 @@ snapshots:
1741
 
1742
  '@humanwhocodes/[email protected]': {}
1743
 
 
 
 
 
1744
  '@jridgewell/[email protected]':
1745
  dependencies:
1746
  '@jridgewell/set-array': 1.2.1
@@ -1758,6 +1811,16 @@ snapshots:
1758
  '@jridgewell/resolve-uri': 3.1.2
1759
  '@jridgewell/sourcemap-codec': 1.5.0
1760
 
 
 
 
 
 
 
 
 
 
 
1761
  '@nodelib/[email protected]':
1762
  dependencies:
1763
  '@nodelib/fs.stat': 2.0.5
@@ -1918,6 +1981,10 @@ snapshots:
1918
  transitivePeerDependencies:
1919
  - supports-color
1920
 
 
 
 
 
1921
1922
  dependencies:
1923
  tailwindcss: 4.0.9
@@ -2195,6 +2262,8 @@ snapshots:
2195
 
2196
2197
 
 
 
2198
2199
 
2200
@@ -2391,6 +2460,10 @@ snapshots:
2391
 
2392
2393
 
 
 
 
 
2394
2395
 
2396
@@ -2608,6 +2681,8 @@ snapshots:
2608
 
2609
2610
 
 
 
2611
2612
 
2613
@@ -2881,6 +2956,8 @@ snapshots:
2881
  magic-string: 0.30.17
2882
  periscopic: 3.1.0
2883
 
 
 
2884
2885
 
2886
 
17
  '@huggingface/tasks':
18
  specifier: ^0.17.1
19
  version: 0.17.1
20
+ '@melt-ui/svelte':
21
+ specifier: ^0.86.3
22
+ version: 0.86.3([email protected])
23
  '@tailwindcss/container-queries':
24
  specifier: ^0.1.1
25
  version: 0.1.1([email protected])
 
254
  resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
255
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
256
 
257
+ '@floating-ui/[email protected]':
258
+ resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==}
259
+
260
+ '@floating-ui/[email protected]':
261
+ resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==}
262
+
263
+ '@floating-ui/[email protected]':
264
+ resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
265
+
266
  '@huggingface/[email protected]':
267
  resolution: {integrity: sha512-wogGVETaNUV/wYBkny0uQD48L0rK9cttVtbaA1Rw/pGCuSYoZ8YlvTV6zymsGJfXaxQU8zup0aOR2XLIf6HVfg==}
268
  engines: {node: '>=18'}
 
290
  resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
291
  deprecated: Use @eslint/object-schema instead
292
 
293
+ '@internationalized/[email protected]':
294
+ resolution: {integrity: sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==}
295
+
296
  '@jridgewell/[email protected]':
297
  resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
298
  engines: {node: '>=6.0.0'}
 
311
  '@jridgewell/[email protected]':
312
  resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
313
 
314
+ '@melt-ui/[email protected]':
315
+ resolution: {integrity: sha512-ZsWmHGd6P636mws1CgatlX7JtLkWoUBPXeNzPzvHYgZdagp8io8MPFotDIfRyKwTEQFUqF9fhBks6CWr0Nupuw==}
316
+ peerDependencies:
317
+ svelte: ^3.0.0 || ^4.0.0 || ^5.0.0-next.118
318
+
319
  '@nodelib/[email protected]':
320
  resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
321
  engines: {node: '>= 8'}
 
496
  svelte: ^4.0.0 || ^5.0.0-next.0
497
  vite: ^5.0.0
498
 
499
+ '@swc/[email protected]':
500
+ resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
501
+
502
  '@tailwindcss/[email protected]':
503
  resolution: {integrity: sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==}
504
  peerDependencies:
 
781
  resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
782
  engines: {node: '>=0.10.0'}
783
 
784
785
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
786
+ engines: {node: '>=6'}
787
+
788
789
  resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
790
  engines: {node: '>=8'}
 
929
930
  resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
931
 
932
933
+ resolution: {integrity: sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==}
934
+
935
936
  resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
937
 
 
1200
  engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1201
  hasBin: true
1202
 
1203
1204
+ resolution: {integrity: sha512-b+CiXQCNMUGe0Ri64S9SXFcP9hogjAJ2Rd6GdVxhPLRm7mhGaM7VgOvCAJ1ZshfHbqVDI3uqTI5C8/GaKuLI7g==}
1205
+ engines: {node: ^18 || >=20}
1206
+ hasBin: true
1207
+
1208
1209
  resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1210
 
 
1541
  resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==}
1542
  engines: {node: '>=16'}
1543
 
1544
1545
+ resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
1546
+
1547
1548
  resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==}
1549
 
 
1755
 
1756
  '@eslint/[email protected]': {}
1757
 
1758
+ '@floating-ui/[email protected]':
1759
+ dependencies:
1760
+ '@floating-ui/utils': 0.2.9
1761
+
1762
+ '@floating-ui/[email protected]':
1763
+ dependencies:
1764
+ '@floating-ui/core': 1.6.9
1765
+ '@floating-ui/utils': 0.2.9
1766
+
1767
+ '@floating-ui/[email protected]': {}
1768
+
1769
  '@huggingface/[email protected]':
1770
  dependencies:
1771
  '@huggingface/tasks': 0.15.9
 
1790
 
1791
  '@humanwhocodes/[email protected]': {}
1792
 
1793
+ '@internationalized/[email protected]':
1794
+ dependencies:
1795
+ '@swc/helpers': 0.5.15
1796
+
1797
  '@jridgewell/[email protected]':
1798
  dependencies:
1799
  '@jridgewell/set-array': 1.2.1
 
1811
  '@jridgewell/resolve-uri': 3.1.2
1812
  '@jridgewell/sourcemap-codec': 1.5.0
1813
 
1814
1815
+ dependencies:
1816
+ '@floating-ui/core': 1.6.9
1817
+ '@floating-ui/dom': 1.6.13
1818
+ '@internationalized/date': 3.7.0
1819
+ dequal: 2.0.3
1820
+ focus-trap: 7.6.4
1821
+ nanoid: 5.1.2
1822
+ svelte: 4.2.19
1823
+
1824
  '@nodelib/[email protected]':
1825
  dependencies:
1826
  '@nodelib/fs.stat': 2.0.5
 
1981
  transitivePeerDependencies:
1982
  - supports-color
1983
 
1984
+ '@swc/[email protected]':
1985
+ dependencies:
1986
+ tslib: 2.8.1
1987
+
1988
1989
  dependencies:
1990
  tailwindcss: 4.0.9
 
2262
 
2263
2264
 
2265
2266
+
2267
2268
 
2269
 
2460
 
2461
2462
 
2463
2464
+ dependencies:
2465
+ tabbable: 6.2.0
2466
+
2467
2468
 
2469
 
2681
 
2682
2683
 
2684
2685
+
2686
2687
 
2688
 
2956
  magic-string: 0.30.17
2957
  periscopic: 3.1.0
2958
 
2959
2960
+
2961
2962
 
2963
src/app.css CHANGED
@@ -26,7 +26,3 @@
26
  html {
27
  font-size: 15px;
28
  }
29
-
30
- :focus-visible:not(:is(.outline-hidden, .!outline-hidden)) {
31
- outline: 4px solid white;
32
- }
 
26
  html {
27
  font-size: 15px;
28
  }
 
 
 
 
src/lib/components/Avatar.svelte CHANGED
@@ -1,10 +1,11 @@
1
  <script lang="ts">
2
- export let orgName: string;
3
  export let size: "sm" | "md" = "md";
4
 
5
- const sizeClass = size === "sm" ? "size-3" : "size-4";
6
 
7
- async function getAvatarUrl(orgName: string) {
 
8
  const url = `https://huggingface.co/api/organizations/${orgName}/avatar`;
9
  const res = await fetch(url);
10
  if (!res.ok) {
@@ -20,7 +21,11 @@
20
  {#await getAvatarUrl(orgName)}
21
  <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
22
  {:then avatarUrl}
23
- <img class="{sizeClass} flex-none rounded-sm bg-gray-200 object-cover" src={avatarUrl} alt="{orgName} avatar" />
 
 
 
 
24
  {:catch}
25
  <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
26
  {/await}
 
1
  <script lang="ts">
2
+ export let orgName: string | undefined;
3
  export let size: "sm" | "md" = "md";
4
 
5
+ $: sizeClass = size === "sm" ? "size-3" : "size-4";
6
 
7
+ async function getAvatarUrl(orgName?: string) {
8
+ if (!orgName) return;
9
  const url = `https://huggingface.co/api/organizations/${orgName}/avatar`;
10
  const res = await fetch(url);
11
  if (!res.ok) {
 
21
  {#await getAvatarUrl(orgName)}
22
  <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
23
  {:then avatarUrl}
24
+ {#if avatarUrl}
25
+ <img class="{sizeClass} flex-none rounded-sm bg-gray-200 object-cover" src={avatarUrl} alt="{orgName} avatar" />
26
+ {:else}
27
+ <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
28
+ {/if}
29
  {:catch}
30
  <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
31
  {/await}
src/lib/components/Icons/IconProvider.svelte ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ export let provider: string | undefined;
3
+ const icons = {
4
+ "sambanova":
5
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><path d="M23.9395 23H22.8288V9.38464C22.8288 6.5566 20.4901 4.11242 17.6039 4.11242H10.3219C7.43574 4.11242 5.10488 6.44692 5.10488 9.2828C5.10488 12.1108 7.43574 14.4454 10.3219 14.4454H11.0493C12.2695 14.4454 13.2707 15.4481 13.2707 16.6702C13.2707 17.8923 12.2695 18.8872 11.0493 18.8872H3.93945V17.7826H10.9946C11.6047 17.7826 12.1053 17.2812 12.1053 16.725C12.1053 16.114 11.6047 15.6674 10.9946 15.6674H10.2672C6.82565 15.6126 3.93945 12.7767 3.93945 9.2828C3.93945 5.78104 6.82565 3 10.3219 3H17.6587C21.1002 3 23.9395 5.94555 23.9395 9.38464V23Z" fill="#EE7624"></path><path d="M11.1041 13.6069C12.6606 13.6617 14.1624 15.0562 14.1624 16.717C14.1624 18.3856 12.7701 19.827 11.0493 19.827H3.93945V20.9394H10.9946C13.3255 20.9394 15.2652 19.0515 15.2652 16.717C15.2652 16.1137 15.1557 15.5575 14.882 15.0013C14.6551 14.5 14.2719 13.9986 13.8808 13.6069C13.435 13.223 12.9344 12.941 12.379 12.7217C11.7142 12.5023 11.0493 12.5571 10.3219 12.5023C9.93085 12.5023 9.047 12.2751 8.54641 11.9461C8.04583 11.6092 7.65474 11.1627 7.43574 10.6692C7.26366 10.2226 7.15416 9.7761 7.15416 9.27473C7.15416 7.55127 8.54641 6.16466 10.2672 6.16466H17.5961C19.3168 6.16466 20.7091 7.66878 20.7091 9.32957V22.9919H21.8198V9.3844C21.8198 7.05773 19.9348 5.05225 17.5961 5.05225H10.3219C7.99108 5.05225 6.0513 6.94022 6.0513 9.27473C6.0513 9.88577 6.16081 10.442 6.43456 10.9982C6.66139 11.4996 6.9899 12.0009 7.43574 12.3848C7.82682 12.7765 8.38216 13.0507 8.88275 13.2779C9.1565 13.3875 9.43808 13.4424 9.76659 13.4972C10.5488 13.552 11.0493 13.6069 11.1041 13.6069Z" fill="#EE7624"></path><path d="M10.9946 23H3.93945V21.8876H10.9946C13.8808 21.8876 16.2116 19.5531 16.2116 16.7172C16.2116 13.8892 13.8808 11.5546 10.9946 11.5546H10.2672C9.047 11.5546 8.04583 10.5519 8.04583 9.32981C8.04583 8.10772 9.047 7.10498 10.2672 7.10498H17.6039C18.8241 7.10498 19.8253 8.16256 19.8253 9.38465V22.9922H18.7146V9.38465C18.7146 8.78144 18.214 8.22523 17.6587 8.22523H10.3219C9.71184 8.22523 9.27383 8.7266 9.27383 9.27498C9.27383 9.83118 9.77442 10.3326 10.3845 10.3326H11.1041C14.6004 10.3326 17.4396 13.1606 17.4396 16.6075C17.3849 20.1641 14.4909 22.9922 10.9946 22.9922V23Z" fill="#EE7624"></path></svg>',
6
+ "fal":
7
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><path fill-rule="evenodd" clip-rule="evenodd" d="M16.5899 2.37891C16.9579 2.37891 17.2529 2.67812 17.2881 3.04443C17.6019 6.31174 20.2023 8.91191 23.4698 9.22569C23.8361 9.26089 24.1353 9.55582 24.1353 9.92378V16.0761C24.1353 16.4441 23.8361 16.739 23.4698 16.7742C20.2023 17.088 17.6019 19.6881 17.2881 22.9555C17.2529 23.3218 16.9579 23.621 16.5899 23.621H10.4373C10.0692 23.621 9.77432 23.3218 9.73912 22.9555C9.42534 19.6881 6.82494 17.088 3.5574 16.7742C3.19109 16.739 2.89185 16.4441 2.89185 16.0761V9.92378C2.89185 9.55582 3.19109 9.26089 3.55741 9.22569C6.82494 8.91191 9.42534 6.31174 9.73912 3.04443C9.77432 2.67812 10.0692 2.37891 10.4373 2.37891H16.5899ZM7.15714 12.982C7.15714 16.5163 10.0192 19.3814 13.5498 19.3814C17.0804 19.3814 19.9426 16.5163 19.9426 12.982C19.9426 9.44762 17.0804 6.58248 13.5498 6.58248C10.0192 6.58248 7.15714 9.44762 7.15714 12.982Z" fill="currentColor"></path></svg>',
8
+ "cerebras":
9
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26" fill="none"><path d="M15 22C10.0294 22 6 17.9706 6 13C6 8.02939 10.0294 4 15 4M10.3635 18.5622C7.2966 15.989 6.89677 11.417 9.46998 8.35026C12.0432 5.28338 16.6151 4.88355 19.6819 7.45675M12.4088 17.8643C9.72407 16.447 8.69627 13.1212 10.1136 10.4368C11.5308 7.75157 14.8559 6.72427 17.5411 8.14156M15 16.746C12.9314 16.746 11.2543 15.0689 11.2543 13.0003C11.2543 10.9316 12.9314 9.25454 15 9.25454" stroke="#F15A29" stroke-width="1.5" stroke-miterlimit="10"></path></svg>',
10
+ "replicate":
11
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><rect x="3.14136" y="2.43652" width="21.1274" height="21.1274" rx="3.54011" fill="url(#paint0_linear_171_78)"></rect><path fill-rule="evenodd" clip-rule="evenodd" d="M19.9161 7.72173V6.18848H7.49072V19.8116H9.21034V7.72173H19.9161ZM19.919 9.09575V10.629H12.4584V19.8109H10.7388V9.09575H19.919ZM19.9161 11.9922V13.5342H15.7008V19.8082H13.9811V11.9922H19.9161Z" fill="white"></path><defs><linearGradient id="paint0_linear_171_78" x1="22.9091" y1="3.17345" x2="4.19652" y2="22.4427" gradientUnits="userSpaceOnUse"><stop stop-color="#EBFF18"></stop><stop offset="0.5" stop-color="#EB40F0"></stop><stop offset="1" stop-color="#BE0000"></stop></linearGradient></defs></svg>',
12
+ "black-forest-labs":
13
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.1146 5L22.5938 18.9541L20.7344 18.9687L13.1146 7.54511L6.55208 17.528H14.6458L16.1042 18.9687C16.1042 19.0468 4 18.9541 4 18.9541L13.1146 5ZM21.3906 9.46122C21.3979 9.47585 21.6969 9.95853 22.0615 10.5436C22.4188 11.1287 22.7615 11.6918 22.9583 12.0063H19.8229L20.2458 11.3262C20.2458 11.3262 20.8365 10.3827 21.026 10.0463C21.2229 9.70988 21.3833 9.44659 21.3906 9.46122Z" fill="currentColor"></path><path d="M19.6305 18.9541H17.917L13.4326 12.0794H15.2555L19.6305 18.9541Z" fill="currentColor"></path><path d="M13.224 15.9556H10.1979L11.6563 13.5787L13.224 15.9556Z" fill="currentColor"></path></svg>',
14
+ "fireworks-ai":
15
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><path d="M19.7941 2.5H6.20588C4.15918 2.5 2.5 4.15918 2.5 6.20588V19.7941C2.5 21.8408 4.15918 23.5 6.20588 23.5H19.7941C21.8408 23.5 23.5 21.8408 23.5 19.7941V6.20588C23.5 4.15918 21.8408 2.5 19.7941 2.5Z" fill="#5019C5"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M12.9917 14.8005C12.4958 14.8005 12.0508 14.5061 11.861 14.0503L9.57335 8.58789H10.9123L12.9995 13.5848L15.0847 8.58789H16.4237L14.1223 14.0523C13.9316 14.5061 13.4875 14.8005 12.9917 14.8005ZM15.9767 17.4106C15.4828 17.4106 15.0398 17.1181 14.8481 16.6663C14.6554 16.2105 14.7551 15.6902 15.1034 15.3371L19.2699 11.1168L19.7902 12.3442L15.9758 16.2007L21.4128 16.1704L21.9331 17.3979L15.9777 17.4125L15.9758 17.4106H15.9767ZM4.58722 16.1684L4.06689 17.3959L4.06885 17.394L10.0242 17.4076C10.5162 17.4076 10.9612 17.1162 11.1529 16.6633C11.3466 16.2085 11.2458 15.6863 10.8977 15.3342L6.73113 11.1138L6.2108 12.3413L10.0242 16.1988L4.58722 16.1684Z" fill="white"></path></svg>',
16
+ "together":
17
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><g clip-path="url(#clip0_55_1726)"><path d="M19.925 2.5H6.33674C4.29004 2.5 2.63086 4.15918 2.63086 6.20588V19.7941C2.63086 21.8408 4.29004 23.5 6.33674 23.5H19.925C21.9717 23.5 23.6309 21.8408 23.6309 19.7941V6.20588C23.6309 4.15918 21.9717 2.5 19.925 2.5Z" fill="#F1EFED"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M17.6087 12.5368C19.6554 12.5368 21.3146 10.8776 21.3146 8.83088C21.3146 6.78418 19.6554 5.125 17.6087 5.125C15.562 5.125 13.9028 6.78418 13.9028 8.83088C13.9028 10.8776 15.562 12.5368 17.6087 12.5368ZM17.6087 21.1842C19.6554 21.1842 21.3146 19.525 21.3146 17.4783C21.3146 15.4316 19.6554 13.7725 17.6087 13.7725C15.562 13.7725 13.9028 15.4316 13.9028 17.4783C13.9028 19.525 15.562 21.1842 17.6087 21.1842ZM12.6676 17.4783C12.6676 19.525 11.0084 21.1842 8.96174 21.1842C6.91504 21.1842 5.25586 19.525 5.25586 17.4783C5.25586 15.4316 6.91504 13.7725 8.96174 13.7725C11.0084 13.7725 12.6676 15.4316 12.6676 17.4783Z" fill="#D3D1D1"></path><path d="M8.96174 12.5368C11.0084 12.5368 12.6676 10.8776 12.6676 8.83088C12.6676 6.78418 11.0084 5.125 8.96174 5.125C6.91504 5.125 5.25586 6.78418 5.25586 8.83088C5.25586 10.8776 6.91504 12.5368 8.96174 12.5368Z" fill="#0F6FFF"></path></g><defs><clipPath id="clip0_55_1726"><rect width="21" height="21" fill="white" transform="translate(2.63086 2.5)"></rect></clipPath></defs></svg>',
18
+ "nebius":
19
+ '<svg width="1em" height="1em" viewBox="0 0 26 26" class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" preserveAspectRatio="xMidYMid meet"><rect x="3.14136" y="2.43652" width="21.1274" height="21.1274" rx="3.54011" fill="#D9FE00"></rect><path fill-rule="evenodd" clip-rule="evenodd" d="M22 5.2226H19V18.4781C19 18.4781 22 18.2885 22 14.6817V5.2226ZM4 11.3183V20.7701H7V7.5146C7 7.5146 8.80257 7.25164 9.75584 9.56444L13.5339 18.6933C14.1519 20.1708 15.1636 21 16.5923 21C18.021 21 19 19.7855 19 18.4842C19 18.4842 17.1974 18.7471 16.2383 16.4356L12.4661 7.30668C11.8481 5.82923 10.8364 5 9.40771 5C7.97897 5 7 6.21327 7 7.5146C6.99416 7.5146 4 7.71029 4 11.3183Z" fill="#002C44"></path></svg>',
20
+ "hyperbolic":
21
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><path d="M3.4211 4.72C3.66077 4.42 4.22 3.9 4.65939 3.58C5.09879 3.26 5.71793 3 6.03749 3C6.397 3 6.69659 3.16 6.87634 3.46C7.03612 3.7 7.67524 5.14 8.27442 6.64C8.89356 8.16 9.39287 9.58 9.39287 9.8C9.39287 10.18 9.35293 10.2 8.15458 9.9C7.45554 9.72 6.35705 9.34 5.69796 9.02C5.03887 8.7 4.16008 8.06 3.76063 7.62C3.16145 6.98 3.00167 6.64 3.00167 6.06C2.9817 5.58 3.14148 5.1 3.4211 4.72Z" fill="#594CE9"></path><path d="M17.7813 6.4C18.3406 5.02 18.9397 3.7 19.0995 3.46C19.2793 3.16 19.5988 3 19.9384 3C20.2379 3 20.8371 3.24 21.2765 3.56C21.7159 3.88 22.2552 4.34 22.4749 4.6C22.7545 4.92 22.8743 5.32 22.8743 6C22.8743 6.84 22.7745 7.08 22.1753 7.7C21.7958 8.1 20.937 8.68 20.2779 9C19.6188 9.32 18.5003 9.72 16.4831 10.2L16.6029 9.54C16.6828 9.2 17.2021 7.78 17.7813 6.4Z" fill="#594CE9"></path><path d="M4.71931 10.8C4.5795 10.3 4.39975 9.72 4.31986 9.52C4.23997 9.24 4.27991 9.16 4.45967 9.24C4.5795 9.32 5.23859 9.6 5.89769 9.86C6.55678 10.14 7.81505 10.52 8.69384 10.7C9.75238 10.92 11.2104 11.04 12.9879 11.04C14.7455 11.04 16.2434 10.92 17.282 10.7C18.1608 10.52 19.5189 10.1 20.2779 9.78C21.0568 9.48 21.6959 9.24 21.7359 9.26C21.7559 9.28 21.616 9.66 21.4363 10.1C21.1966 10.66 21.0968 11.48 21.0768 12.9C21.0768 14.36 21.1767 15.14 21.4363 15.8C21.636 16.3 21.7559 16.72 21.7359 16.74C21.6959 16.76 21.0568 16.52 20.2779 16.22C19.5189 15.9 18.1608 15.48 17.282 15.3C16.2235 15.06 14.7655 14.96 12.9879 14.96C11.2104 14.96 9.75238 15.06 8.69384 15.3C7.81505 15.48 6.47689 15.9 5.69796 16.22C4.93901 16.52 4.27991 16.76 4.25994 16.74C4.23997 16.72 4.39975 16.2 4.59947 15.6C4.83914 14.94 4.99892 13.94 4.99892 13.1C4.99892 12.34 4.87909 11.3 4.71931 10.8Z" fill="#594CE9"></path><path d="M5.69796 17C6.35705 16.68 7.43557 16.3 8.07469 16.14C9.13323 15.88 9.27304 15.9 9.33296 16.18C9.39287 16.36 9.05334 17.44 8.59397 18.6C8.13461 19.76 7.53543 21.2 7.23584 21.8C6.79645 22.7 6.59672 22.9 6.15733 22.96C5.83777 22.98 5.29851 22.82 4.95898 22.62C4.59947 22.42 4.0003 21.92 3.66077 21.52C3.14148 20.96 3.00167 20.62 3.00167 20C3.00167 19.36 3.14148 19.04 3.76063 18.38C4.16008 17.94 5.03887 17.3 5.69796 17Z" fill="#594CE9"></path><path d="M17.7813 19.6C17.2021 18.22 16.7028 16.84 16.6629 16.52L16.583 15.94L17.4817 16.06C17.981 16.14 18.9797 16.44 19.7386 16.74C20.6174 17.1 21.4163 17.62 22.0754 18.24C23.074 19.2 23.074 19.22 22.9342 20.16C22.8543 20.68 22.6346 21.28 22.4349 21.48C22.2352 21.68 21.7159 22.12 21.2765 22.44C20.8371 22.76 20.2379 23 19.9384 23C19.5788 23 19.2793 22.84 19.0995 22.56C18.9397 22.3 18.3406 20.98 17.7813 19.6Z" fill="#594CE9"></path></svg>',
22
+ "novita":
23
+ '<svg width="1em" height="1em" viewBox="0 0 26 26" class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" preserveAspectRatio="xMidYMid meet" version="1.2"><rect x="2.43628" y="2.43652" width="21.1274" height="21.1274" rx="3.54011" fill="black"></rect><path d="M10.7187 5.79061C10.6923 5.80858 10.6791 6.78313 10.6835 8.13942L10.6923 10.4568C4.90331 16.3759 3.23298 18.105 3.24617 18.1274C3.25496 18.1454 4.93408 18.1589 6.97804 18.1589H10.6923C10.6923 14.5391 10.7055 13.4792 10.7275 13.4703C10.7451 13.4568 11.7956 14.5077 13.066 15.8056L15.3736 18.1589C21.1143 18.1589 22.789 18.1454 22.7978 18.123C22.811 18.105 20.1077 15.3161 16.789 11.9253C13.4703 8.53463 10.7407 5.77265 10.7187 5.79061Z" fill="#26D57A"></path></svg>',
24
+ "cohere":
25
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.48 14.92C10.0133 14.92 11.08 14.8933 12.5733 14.28C14.3067 13.56 17.72 12.28 20.2 10.9467C21.9333 10.0133 22.68 8.78667 22.68 7.13333C22.68 4.86667 20.84 3 18.5467 3H8.94667C5.66667 3 3 5.66667 3 8.94667C3 12.2267 5.50667 14.92 9.48 14.92Z" fill="#39594D"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M11.1066 19C11.1066 17.4 12.0666 15.9333 13.5599 15.32L16.5732 14.0666C19.6399 12.8133 22.9999 15.0533 22.9999 18.36C22.9999 20.92 20.9199 23 18.3599 23H15.0799C12.8932 23 11.1066 21.2133 11.1066 19Z" fill="#D18EE2"></path><path d="M6.44 15.6934C4.54667 15.6934 3 17.24 3 19.1334V19.5867C3 21.4534 4.54667 23 6.44 23C8.33333 23 9.88 21.4534 9.88 19.56V19.1067C9.85333 17.24 8.33333 15.6934 6.44 15.6934Z" fill="#FF7759"></path></svg>',
26
+ "hf-inference":
27
+ '<svg class="text-lg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 26 26"><rect x="3.34856" y="3.02654" width="19.9474" height="19.9474" rx="2.95009" fill="#FFD21E" stroke="#FFB41E" stroke-width="1.18004"></rect><path fill-rule="evenodd" clip-rule="evenodd" d="M7.69336 9.74609V16.9754H9.32329V13.9595H11.8181V16.9754H13.4591V9.74609H11.8181V12.5292H9.32329V9.74609H7.69336ZM15.1646 9.74609V16.9754H16.7945V14.1702H19.3004V12.7953H16.7945V11.121H19.7217V9.74609H15.1646Z" fill="#814D00"></path></svg>',
28
+ };
29
+
30
+ $: icon = provider && provider in icons ? icons[provider as keyof typeof icons] : null;
31
+ </script>
32
+
33
+ {#if icon}
34
+ <span class="inline-block">{@html icon}</span>
35
+ {:else}
36
+ <!-- Allow passing custom fallback -->
37
+ <slot>
38
+ <div class="size-4 flex-none rounded-sm bg-gray-200"></div>
39
+ </slot>
40
+ {/if}
src/lib/components/InferencePlayground/InferencePlaygroundMessage.svelte CHANGED
@@ -22,7 +22,7 @@
22
  {autofocus}
23
  bind:value={message.content}
24
  placeholder="Enter {message.role} message"
25
- class="resize-none overflow-hidden rounded-sm bg-transparent px-2 py-2.5 ring-gray-100 group-hover/message:ring-3 hover:resize-y hover:bg-white focus:resize-y focus:bg-white focus:ring-3 @2xl:px-3 dark:ring-gray-600 dark:hover:bg-gray-900 dark:focus:bg-gray-900"
26
  rows="1"
27
  tabindex="2"
28
  on:input={() => {
 
22
  {autofocus}
23
  bind:value={message.content}
24
  placeholder="Enter {message.role} message"
25
+ class="resize-none overflow-hidden rounded-sm bg-transparent px-2 py-2.5 ring-gray-100 outline-none group-hover/message:ring-3 hover:resize-y hover:bg-white focus:resize-y focus:bg-white focus:ring-3 @2xl:px-3 dark:ring-gray-600 dark:hover:bg-gray-900 dark:focus:bg-gray-900"
26
  rows="1"
27
  tabindex="2"
28
  on:input={() => {
src/lib/components/InferencePlayground/InferencePlaygroundModelSelector.svelte CHANGED
@@ -4,18 +4,23 @@
4
  import { goto } from "$app/navigation";
5
  import { page } from "$app/stores";
6
 
 
7
  import { fetchHuggingFaceModel, type InferenceProviderMapping } from "$lib/fetchers/providers";
8
  import { models } from "$lib/stores/models";
9
  import { token } from "$lib/stores/token";
 
10
  import Avatar from "../Avatar.svelte";
11
  import IconCaret from "../Icons/IconCaret.svelte";
 
12
  import ModelSelectorModal from "./InferencePlaygroundModelSelectorModal.svelte";
13
  import { defaultSystemMessage } from "./inferencePlaygroundUtils";
 
14
 
15
  export let conversation: Conversation;
16
 
17
  let showModelPickerModal = false;
18
 
 
19
  function changeModel(modelId: ModelEntryWithTokenizer["id"]) {
20
  const model = $models.find(m => m.id === modelId);
21
  if (!model) {
@@ -35,26 +40,34 @@
35
 
36
  $: nameSpace = conversation.model.id.split("/")[0] ?? "";
37
  $: modelName = conversation.model.id.split("/")[1] ?? "";
 
38
 
 
39
  async function loadProviders(modelId: string) {
 
40
  providerMap = {};
41
  const res = await fetchHuggingFaceModel(modelId, $token.value);
42
  providerMap = res.inferenceProviderMapping;
 
 
43
  }
44
- let providerMap: InferenceProviderMapping = {};
45
- // $: loadProviders(conversation.model.id);
46
 
47
- const id = crypto.randomUUID();
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  </script>
49
 
50
- {#if showModelPickerModal}
51
- <ModelSelectorModal
52
- {conversation}
53
- on:modelSelected={e => changeModel(e.detail)}
54
- on:close={() => (showModelPickerModal = false)}
55
- />
56
- {/if}
57
-
58
  <div class="flex flex-col gap-2">
59
  <label for={id} class="flex items-baseline gap-2 text-sm font-medium text-gray-900 dark:text-white">
60
  Models<span class="text-xs font-normal text-gray-400">{$models.length}</span>
@@ -76,23 +89,43 @@
76
  </button>
77
  </div>
78
 
 
 
 
 
 
 
 
 
79
  <div class="flex flex-col gap-2">
80
- <label for={id} class="flex items-baseline gap-2 text-sm font-medium text-gray-900 dark:text-white">
 
81
  Providers<span class="text-xs font-normal text-gray-400"></span>
82
  </label>
 
83
 
84
  <button
85
- {id}
 
86
  class="relative flex items-center justify-between gap-6 overflow-hidden rounded-lg border bg-gray-100/80 px-3 py-1.5 leading-tight whitespace-nowrap shadow-sm hover:brightness-95 dark:border-gray-700 dark:bg-gray-800 dark:hover:brightness-110"
87
- on:click={() => (showModelPickerModal = true)}
88
  >
89
- <div class="flex flex-col items-start">
90
- <div class="flex items-center gap-1 text-sm text-gray-500 dark:text-gray-300">
91
- <Avatar orgName={nameSpace} size="sm" />
92
- {nameSpace}
93
- </div>
94
- <div>{modelName}</div>
95
  </div>
96
  <IconCaret classNames="text-xl bg-gray-100 dark:bg-gray-600 rounded-sm size-4 flex-none absolute right-2" />
97
  </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  </div>
 
4
  import { goto } from "$app/navigation";
5
  import { page } from "$app/stores";
6
 
7
+ import { browser } from "$app/environment";
8
  import { fetchHuggingFaceModel, type InferenceProviderMapping } from "$lib/fetchers/providers";
9
  import { models } from "$lib/stores/models";
10
  import { token } from "$lib/stores/token";
11
+ import { randomPick } from "$lib/utils/array";
12
  import Avatar from "../Avatar.svelte";
13
  import IconCaret from "../Icons/IconCaret.svelte";
14
+ import IconProvider from "../Icons/IconProvider.svelte";
15
  import ModelSelectorModal from "./InferencePlaygroundModelSelectorModal.svelte";
16
  import { defaultSystemMessage } from "./inferencePlaygroundUtils";
17
+ import { createSelect, createSync } from "@melt-ui/svelte";
18
 
19
  export let conversation: Conversation;
20
 
21
  let showModelPickerModal = false;
22
 
23
+ // Model
24
  function changeModel(modelId: ModelEntryWithTokenizer["id"]) {
25
  const model = $models.find(m => m.id === modelId);
26
  if (!model) {
 
40
 
41
  $: nameSpace = conversation.model.id.split("/")[0] ?? "";
42
  $: modelName = conversation.model.id.split("/")[1] ?? "";
43
+ const id = crypto.randomUUID();
44
 
45
+ // Provider
46
  async function loadProviders(modelId: string) {
47
+ if (!browser) return;
48
  providerMap = {};
49
  const res = await fetchHuggingFaceModel(modelId, $token.value);
50
  providerMap = res.inferenceProviderMapping;
51
+ if (conversation.provider ?? "" in providerMap) return;
52
+ conversation.provider = randomPick(Object.keys(providerMap));
53
  }
 
 
54
 
55
+ let providerMap: InferenceProviderMapping = {};
56
+ $: modelId = conversation.model.id;
57
+ $: loadProviders(modelId);
58
+ $: provider = conversation.provider;
59
+
60
+ const {
61
+ elements: { trigger, menu, option },
62
+ states: { selected },
63
+ } = createSelect<string, false>();
64
+ const sync = createSync({ selected });
65
+ $: sync.selected(
66
+ conversation.provider ? { value: conversation.provider } : undefined,
67
+ p => (conversation.provider = p?.value)
68
+ );
69
  </script>
70
 
 
 
 
 
 
 
 
 
71
  <div class="flex flex-col gap-2">
72
  <label for={id} class="flex items-baseline gap-2 text-sm font-medium text-gray-900 dark:text-white">
73
  Models<span class="text-xs font-normal text-gray-400">{$models.length}</span>
 
89
  </button>
90
  </div>
91
 
92
+ {#if showModelPickerModal}
93
+ <ModelSelectorModal
94
+ {conversation}
95
+ on:modelSelected={e => changeModel(e.detail)}
96
+ on:close={() => (showModelPickerModal = false)}
97
+ />
98
+ {/if}
99
+
100
  <div class="flex flex-col gap-2">
101
+ <!--
102
+ <label class="flex items-baseline gap-2 text-sm font-medium text-gray-900 dark:text-white">
103
  Providers<span class="text-xs font-normal text-gray-400"></span>
104
  </label>
105
+ -->
106
 
107
  <button
108
+ {...$trigger}
109
+ use:trigger
110
  class="relative flex items-center justify-between gap-6 overflow-hidden rounded-lg border bg-gray-100/80 px-3 py-1.5 leading-tight whitespace-nowrap shadow-sm hover:brightness-95 dark:border-gray-700 dark:bg-gray-800 dark:hover:brightness-110"
 
111
  >
112
+ <div class="flex items-center gap-1 text-sm text-gray-500 dark:text-gray-300">
113
+ <IconProvider provider={conversation.provider} />
114
+ {conversation.provider ?? "loading"}
 
 
 
115
  </div>
116
  <IconCaret classNames="text-xl bg-gray-100 dark:bg-gray-600 rounded-sm size-4 flex-none absolute right-2" />
117
  </button>
118
+
119
+ <div {...$menu} use:menu class="rounded-lg border bg-gray-100/80 dark:border-gray-700 dark:bg-gray-800">
120
+ {#each Object.keys(providerMap) as provider (provider)}
121
+ <div {...$option({ value: provider })} use:option class="group p-1 text-sm dark:text-white">
122
+ <div
123
+ class="flex items-center gap-2 rounded-md px-2 py-1 group-data-[highlighted]:bg-gray-200 dark:group-data-[highlighted]:bg-gray-700"
124
+ >
125
+ <IconProvider {provider} />
126
+ {provider}
127
+ </div>
128
+ </div>
129
+ {/each}
130
+ </div>
131
  </div>
src/lib/components/InferencePlayground/InferencePlaygroundProviderSelectorModal.svelte DELETED
@@ -1,179 +0,0 @@
1
- <script lang="ts">
2
- import type { Conversation, ModelEntryWithTokenizer } from "./types";
3
-
4
- import { createEventDispatcher, tick } from "svelte";
5
-
6
- import { FEATURED_MODELS_IDS } from "./inferencePlaygroundUtils";
7
- import IconSearch from "../Icons/IconSearch.svelte";
8
- import IconStar from "../Icons/IconStar.svelte";
9
- import { models } from "$lib/stores/models";
10
-
11
- export let conversation: Conversation;
12
-
13
- let backdropEl: HTMLDivElement;
14
- let highlightIdx = 0;
15
- let ignoreCursorHighlight = false;
16
- let containerEl: HTMLDivElement;
17
-
18
- const dispatch = createEventDispatcher<{ modelSelected: string; close: void }>();
19
-
20
- let featuredModels = $models.filter(m => FEATURED_MODELS_IDS.includes(m.id));
21
- let otherModels = $models.filter(m => !FEATURED_MODELS_IDS.includes(m.id));
22
-
23
- if (featuredModels.findIndex(model => model.id === conversation.model.id) !== -1) {
24
- highlightIdx = featuredModels.findIndex(model => model.id === conversation.model.id);
25
- } else {
26
- highlightIdx = featuredModels.length + otherModels.findIndex(model => model.id === conversation.model.id);
27
- }
28
-
29
- function handleKeydown(event: KeyboardEvent) {
30
- const { key } = event;
31
- let scrollLogicalPosition: ScrollLogicalPosition = "end";
32
- if (key === "Escape") {
33
- event.preventDefault();
34
- dispatch("close");
35
- } else if (key === "Enter") {
36
- event.preventDefault();
37
- const highlightedEl = document.querySelector(".highlighted");
38
- if (highlightedEl) {
39
- (highlightedEl as HTMLButtonElement).click();
40
- }
41
- } else if (key === "ArrowUp") {
42
- event.preventDefault();
43
- highlightIdx--;
44
- scrollLogicalPosition = "start";
45
- ignoreCursorHighlight = true;
46
- } else if (key === "ArrowDown") {
47
- event.preventDefault();
48
- highlightIdx++;
49
- ignoreCursorHighlight = true;
50
- }
51
- const n = featuredModels.length + otherModels.length;
52
- highlightIdx = ((highlightIdx % n) + n) % n;
53
- scrollToResult(scrollLogicalPosition);
54
- }
55
-
56
- async function scrollToResult(block: ScrollLogicalPosition) {
57
- await tick();
58
- const highlightedEl = document.querySelector(".highlighted");
59
- if (containerEl && highlightedEl) {
60
- const { bottom: containerBottom, top: containerTop } = containerEl.getBoundingClientRect();
61
- const { bottom: highlightedBottom, top: highlightedTop } = highlightedEl.getBoundingClientRect();
62
- if (highlightedBottom > containerBottom || containerTop > highlightedTop) {
63
- highlightedEl.scrollIntoView({ block });
64
- }
65
- }
66
- }
67
-
68
- function highlightRow(idx: number) {
69
- if (!ignoreCursorHighlight) {
70
- highlightIdx = idx;
71
- }
72
- }
73
-
74
- function handleBackdropClick(event: MouseEvent) {
75
- if (window?.getSelection()?.toString()) {
76
- return;
77
- }
78
- if (event.target === backdropEl) {
79
- dispatch("close");
80
- }
81
- }
82
-
83
- function filterModels(query: string) {
84
- featuredModels = $models.filter(m =>
85
- query
86
- ? FEATURED_MODELS_IDS.includes(m.id) && m.id.toLocaleLowerCase().includes(query.toLocaleLowerCase().trim())
87
- : FEATURED_MODELS_IDS.includes(m.id)
88
- );
89
-
90
- otherModels = $models.filter(m =>
91
- query
92
- ? !FEATURED_MODELS_IDS.includes(m.id) && m.id.toLocaleLowerCase().includes(query.toLocaleLowerCase().trim())
93
- : !FEATURED_MODELS_IDS.includes(m.id)
94
- );
95
- }
96
- </script>
97
-
98
- <svelte:window on:keydown={handleKeydown} on:mousemove={() => (ignoreCursorHighlight = false)} />
99
-
100
- <!-- svelte-ignore a11y-no-static-element-interactions a11y-click-events-have-key-events -->
101
- <div
102
- class="fixed inset-0 z-10 flex h-screen items-start justify-center bg-black/85 pt-32"
103
- bind:this={backdropEl}
104
- on:click|stopPropagation={handleBackdropClick}
105
- >
106
- <div class="flex w-full max-w-[600px] items-start justify-center overflow-hidden p-10 text-left whitespace-nowrap">
107
- <div
108
- class="flex h-full w-full flex-col overflow-hidden rounded-lg border bg-white text-gray-900 shadow-md dark:border-gray-800 dark:bg-gray-900 dark:text-gray-300"
109
- bind:this={containerEl}
110
- >
111
- <div class="flex items-center border-b px-3 dark:border-gray-800">
112
- <IconSearch classNames="mr-2 text-sm" />
113
- <!-- svelte-ignore a11y-autofocus -->
114
- <input
115
- autofocus
116
- class="flex h-10 w-full rounded-md bg-transparent py-3 text-sm placeholder-gray-400 outline-hidden"
117
- placeholder="Search models ..."
118
- on:input={e => filterModels(e.currentTarget.value)}
119
- />
120
- </div>
121
- <div class="max-h-[300px] overflow-x-hidden overflow-y-auto">
122
- {#if featuredModels.length}
123
- <div>
124
- <div class="px-2 py-1.5 text-xs font-medium text-gray-500">Trending</div>
125
- <div>
126
- {#each featuredModels as model, idx}
127
- {@const [nameSpace, modelName] = model.id.split("/")}
128
- <button
129
- class="flex w-full cursor-pointer items-center px-2 py-1.5 text-sm {highlightIdx === idx
130
- ? 'highlighted bg-gray-100 dark:bg-gray-800'
131
- : ''}"
132
- on:mouseenter={() => highlightRow(idx)}
133
- on:click={() => {
134
- dispatch("modelSelected", model.id);
135
- dispatch("close");
136
- }}
137
- >
138
- <IconStar classNames="lucide lucide-star mr-1.5 size-4 text-yellow-400" />
139
- <span class="inline-flex items-center"
140
- ><span class="text-gray-500 dark:text-gray-400">{nameSpace}</span><span
141
- class="mx-1 text-gray-300 dark:text-gray-700">/</span
142
- ><span class="text-black dark:text-white">{modelName}</span></span
143
- >
144
- </button>
145
- {/each}
146
- </div>
147
- </div>
148
- {/if}
149
- {#if otherModels.length}
150
- <div>
151
- <div class="px-2 py-1.5 text-xs font-medium text-gray-500">Other Models</div>
152
- <div>
153
- {#each otherModels as model, _idx}
154
- {@const [nameSpace, modelName] = model.id.split("/")}
155
- {@const idx = featuredModels.length + _idx}
156
- <button
157
- class="flex w-full cursor-pointer items-center px-2 py-1.5 text-sm {highlightIdx === idx
158
- ? 'highlighted bg-gray-100 dark:bg-gray-800'
159
- : ''}"
160
- on:mouseenter={() => highlightRow(idx)}
161
- on:click={() => {
162
- dispatch("modelSelected", model.id);
163
- dispatch("close");
164
- }}
165
- >
166
- <span class="inline-flex items-center"
167
- ><span class="text-gray-500 dark:text-gray-400">{nameSpace}</span><span
168
- class="mx-1 text-gray-300 dark:text-gray-700">/</span
169
- ><span class="text-black dark:text-white">{modelName}</span></span
170
- >
171
- </button>
172
- {/each}
173
- </div>
174
- </div>
175
- {/if}
176
- </div>
177
- </div>
178
- </div>
179
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/components/InferencePlayground/types.ts CHANGED
@@ -1,4 +1,5 @@
1
  import type { GenerationConfig } from "$lib/components/InferencePlayground/generationConfigSettings";
 
2
  import type { ModelEntry } from "@huggingface/hub";
3
  import type { ChatCompletionInputMessage } from "@huggingface/tasks";
4
 
@@ -10,6 +11,7 @@ export type Conversation = {
10
  messages: ConversationMessage[];
11
  systemMessage: ConversationMessage;
12
  streaming: boolean;
 
13
  };
14
 
15
  export type Session = {
 
1
  import type { GenerationConfig } from "$lib/components/InferencePlayground/generationConfigSettings";
2
+ import type { Provider } from "$lib/fetchers/providers";
3
  import type { ModelEntry } from "@huggingface/hub";
4
  import type { ChatCompletionInputMessage } from "@huggingface/tasks";
5
 
 
11
  messages: ConversationMessage[];
12
  systemMessage: ConversationMessage;
13
  streaming: boolean;
14
+ provider?: string;
15
  };
16
 
17
  export type Session = {
src/lib/fetchers/providers.ts CHANGED
@@ -13,6 +13,7 @@ export interface Provider {
13
  providerId: string;
14
  task: string;
15
  }
 
16
  /**
17
  * Error thrown when the Hugging Face API request fails
18
  */
 
13
  providerId: string;
14
  task: string;
15
  }
16
+
17
  /**
18
  * Error thrown when the Hugging Face API request fails
19
  */
src/lib/stores/session.ts CHANGED
@@ -14,6 +14,7 @@ export function createSessionStore() {
14
  let hasStarted = false;
15
  const store = writable<Session>();
16
 
 
17
  function init() {
18
  const startMessageUser: ChatCompletionInputMessage = { role: "user", content: "" };
19
  const modelIdsFromQueryParam = get(safePage)?.url?.searchParams?.get("modelId")?.split(",");
 
14
  let hasStarted = false;
15
  const store = writable<Session>();
16
 
17
+ // Init is needed, otherwise there are stale values coming from page.
18
  function init() {
19
  const startMessageUser: ChatCompletionInputMessage = { role: "user", content: "" };
20
  const modelIdsFromQueryParam = get(safePage)?.url?.searchParams?.get("modelId")?.split(",");
src/lib/utils/array.ts ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ export function last<T>(arr: T[]): T | undefined {
2
+ return arr[arr.length - 1];
3
+ }
4
+
5
+ export function randomPick<T>(arr: T[]): T | undefined {
6
+ return arr[Math.floor(Math.random() * arr.length)];
7
+ }