Thomas G. Lopes commited on
Commit
936176c
·
1 Parent(s): 5ac02d2

migrate all?

Browse files
src/lib/components/avatar.svelte CHANGED
@@ -1,8 +1,12 @@
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;
 
1
  <script lang="ts">
2
+ interface Props {
3
+ orgName: string | undefined;
4
+ size?: "sm" | "md";
5
+ }
6
+
7
+ let { orgName, size = "md" }: Props = $props();
8
 
9
+ let sizeClass = $derived(size === "sm" ? "size-3" : "size-4");
10
 
11
  async function getAvatarUrl(orgName?: string) {
12
  if (!orgName) return;
src/lib/components/debug-menu.svelte CHANGED
@@ -8,8 +8,8 @@
8
  import type { ToastData } from "./toaster.svelte.js";
9
  import { addToast } from "./toaster.svelte.js";
10
 
11
- let innerWidth: number;
12
- let innerHeight: number;
13
 
14
  function toggleTheme() {
15
  document.body.classList.toggle("dark");
@@ -99,7 +99,7 @@
99
  {#each actions as { label, cb }}
100
  <button
101
  class="rounded-md bg-gray-200 px-3 py-1 text-sm hover:bg-gray-300 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600"
102
- on:click={cb}
103
  >
104
  {label}
105
  </button>
 
8
  import type { ToastData } from "./toaster.svelte.js";
9
  import { addToast } from "./toaster.svelte.js";
10
 
11
+ let innerWidth = $state<number>();
12
+ let innerHeight = $state<number>();
13
 
14
  function toggleTheme() {
15
  document.body.classList.toggle("dark");
 
99
  {#each actions as { label, cb }}
100
  <button
101
  class="rounded-md bg-gray-200 px-3 py-1 text-sm hover:bg-gray-300 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600"
102
+ onclick={cb}
103
  >
104
  {label}
105
  </button>
src/lib/components/icon-provider.svelte CHANGED
@@ -1,5 +1,10 @@
1
  <script lang="ts">
2
- export let provider: string | undefined;
 
 
 
 
 
3
  </script>
4
 
5
  {#if provider === "sambanova"}
@@ -294,7 +299,7 @@
294
  ></path></svg
295
  >
296
  {:else}
297
- <slot>
298
  <div class="size-4 flex-none rounded-sm bg-gray-200"></div>
299
- </slot>
300
  {/if}
 
1
  <script lang="ts">
2
+ interface Props {
3
+ provider: string | undefined;
4
+ children?: import('svelte').Snippet;
5
+ }
6
+
7
+ let { provider, children }: Props = $props();
8
  </script>
9
 
10
  {#if provider === "sambanova"}
 
299
  ></path></svg
300
  >
301
  {:else}
302
+ {#if children}{@render children()}{:else}
303
  <div class="size-4 flex-none rounded-sm bg-gray-200"></div>
304
+ {/if}
305
  {/if}
src/lib/components/inference-playground/conversation.svelte CHANGED
@@ -1,3 +1,5 @@
 
 
1
  <script lang="ts">
2
  import { run } from "svelte/legacy";
3
 
 
1
+ <!-- @migration-task Error while migrating Svelte code: Can only bind to an Identifier or MemberExpression or a `{get, set}` pair
2
+ https://svelte.dev/e/bind_invalid_expression -->
3
  <script lang="ts">
4
  import { run } from "svelte/legacy";
5
 
src/lib/components/inference-playground/hf-token-modal.svelte CHANGED
@@ -1,13 +1,20 @@
1
  <script lang="ts">
 
 
 
2
  import { clickOutside } from "$lib/actions/click-outside.js";
3
  import { createEventDispatcher, onDestroy, onMount } from "svelte";
4
 
5
  import IconCross from "~icons/carbon/close";
6
 
7
- export let storeLocallyHfToken = false;
 
 
 
 
8
 
9
- let backdropEl: HTMLDivElement;
10
- let modalEl: HTMLDivElement;
11
 
12
  const dispatch = createEventDispatcher<{ close: void }>();
13
 
@@ -21,7 +28,7 @@
21
 
22
  onMount(() => {
23
  document.getElementById("app")?.setAttribute("inert", "true");
24
- modalEl.focus();
25
  });
26
 
27
  onDestroy(() => {
@@ -43,10 +50,10 @@
43
  tabindex="-1"
44
  class="relative max-h-full w-full max-w-xl p-4 outline-hidden"
45
  bind:this={modalEl}
46
- on:keydown={handleKeydown}
47
  use:clickOutside={() => dispatch("close")}
48
  >
49
- <form on:submit|preventDefault class="relative rounded-lg bg-white shadow-sm dark:bg-gray-900">
50
  <div class="flex items-center justify-between rounded-t border-b p-4 md:px-5 md:py-4 dark:border-gray-800">
51
  <h3 class="flex items-center gap-2.5 text-lg font-semibold text-gray-900 dark:text-white">
52
  <img
@@ -57,7 +64,7 @@
57
  </h3>
58
  <button
59
  type="button"
60
- on:click={() => dispatch("close")}
61
  class="ms-auto inline-flex h-8 w-8 items-center justify-center rounded-lg bg-transparent text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white"
62
  >
63
  <div class="text-xl">
 
1
  <script lang="ts">
2
+ import { createBubbler, preventDefault } from "svelte/legacy";
3
+
4
+ const bubble = createBubbler();
5
  import { clickOutside } from "$lib/actions/click-outside.js";
6
  import { createEventDispatcher, onDestroy, onMount } from "svelte";
7
 
8
  import IconCross from "~icons/carbon/close";
9
 
10
+ interface Props {
11
+ storeLocallyHfToken?: boolean;
12
+ }
13
+
14
+ let { storeLocallyHfToken = $bindable(false) }: Props = $props();
15
 
16
+ let backdropEl = $state<HTMLDivElement>();
17
+ let modalEl = $state<HTMLDivElement>();
18
 
19
  const dispatch = createEventDispatcher<{ close: void }>();
20
 
 
28
 
29
  onMount(() => {
30
  document.getElementById("app")?.setAttribute("inert", "true");
31
+ modalEl?.focus();
32
  });
33
 
34
  onDestroy(() => {
 
50
  tabindex="-1"
51
  class="relative max-h-full w-full max-w-xl p-4 outline-hidden"
52
  bind:this={modalEl}
53
+ onkeydown={handleKeydown}
54
  use:clickOutside={() => dispatch("close")}
55
  >
56
+ <form onsubmit={preventDefault(bubble("submit"))} class="relative rounded-lg bg-white shadow-sm dark:bg-gray-900">
57
  <div class="flex items-center justify-between rounded-t border-b p-4 md:px-5 md:py-4 dark:border-gray-800">
58
  <h3 class="flex items-center gap-2.5 text-lg font-semibold text-gray-900 dark:text-white">
59
  <img
 
64
  </h3>
65
  <button
66
  type="button"
67
+ onclick={() => dispatch("close")}
68
  class="ms-auto inline-flex h-8 w-8 items-center justify-center rounded-lg bg-transparent text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white"
69
  >
70
  <div class="text-xl">
src/lib/components/inference-playground/model-selector-modal.svelte CHANGED
@@ -9,20 +9,24 @@
9
  import IconSearch from "~icons/carbon/search";
10
  import IconStar from "~icons/carbon/star";
11
 
12
- export let conversation: Conversation;
 
 
 
 
13
 
14
- let backdropEl: HTMLDivElement;
15
- let highlightIdx = 0;
16
- let ignoreCursorHighlight = false;
17
- let containerEl: HTMLDivElement;
18
- let query = "";
19
 
20
  const dispatch = createEventDispatcher<{ modelSelected: string; close: void }>();
21
 
22
- $: trendingModels = getTrending($models);
23
 
24
- $: featuredModels = fuzzysearch({ needle: query, haystack: trendingModels, property: "id" });
25
- $: otherModels = fuzzysearch({ needle: query, haystack: $models, property: "id" });
26
 
27
  onMount(() => {
28
  if (featuredModels.findIndex(model => model.id === conversation.model.id) !== -1) {
@@ -80,6 +84,7 @@
80
  }
81
 
82
  function handleBackdropClick(event: MouseEvent) {
 
83
  if (window?.getSelection()?.toString()) {
84
  return;
85
  }
@@ -89,13 +94,14 @@
89
  }
90
  </script>
91
 
92
- <svelte:window on:keydown={handleKeydown} on:mousemove={() => (ignoreCursorHighlight = false)} />
93
 
94
- <!-- svelte-ignore a11y-no-static-element-interactions a11y-click-events-have-key-events -->
 
95
  <div
96
  class="fixed inset-0 z-10 flex h-screen items-start justify-center bg-black/85 pt-32"
97
  bind:this={backdropEl}
98
- on:click|stopPropagation={handleBackdropClick}
99
  >
100
  <div class="flex w-full max-w-[600px] items-start justify-center overflow-hidden p-10 text-left whitespace-nowrap">
101
  <div
@@ -106,7 +112,7 @@
106
  <div class="mr-2 text-sm">
107
  <IconSearch />
108
  </div>
109
- <!-- svelte-ignore a11y-autofocus -->
110
  <input
111
  autofocus
112
  class="flex h-10 w-full rounded-md bg-transparent py-3 text-sm placeholder-gray-400 outline-hidden"
@@ -125,8 +131,8 @@
125
  class="flex w-full cursor-pointer items-center px-2 py-1.5 text-sm {highlightIdx === idx
126
  ? 'highlighted bg-gray-100 dark:bg-gray-800'
127
  : ''}"
128
- on:mouseenter={() => highlightRow(idx)}
129
- on:click={() => {
130
  dispatch("modelSelected", model.id);
131
  dispatch("close");
132
  }}
@@ -155,8 +161,8 @@
155
  class="flex w-full cursor-pointer items-center px-2 py-1.5 text-sm {highlightIdx === idx
156
  ? 'highlighted bg-gray-100 dark:bg-gray-800'
157
  : ''}"
158
- on:mouseenter={() => highlightRow(idx)}
159
- on:click={() => {
160
  dispatch("modelSelected", model.id);
161
  dispatch("close");
162
  }}
 
9
  import IconSearch from "~icons/carbon/search";
10
  import IconStar from "~icons/carbon/star";
11
 
12
+ interface Props {
13
+ conversation: Conversation;
14
+ }
15
+
16
+ let { conversation }: Props = $props();
17
 
18
+ let backdropEl = $state<HTMLDivElement>();
19
+ let highlightIdx = $state(0);
20
+ let ignoreCursorHighlight = $state(false);
21
+ let containerEl = $state<HTMLDivElement>();
22
+ let query = $state("");
23
 
24
  const dispatch = createEventDispatcher<{ modelSelected: string; close: void }>();
25
 
26
+ let trendingModels = $derived(getTrending($models));
27
 
28
+ let featuredModels = $derived(fuzzysearch({ needle: query, haystack: trendingModels, property: "id" }));
29
+ let otherModels = $derived(fuzzysearch({ needle: query, haystack: $models, property: "id" }));
30
 
31
  onMount(() => {
32
  if (featuredModels.findIndex(model => model.id === conversation.model.id) !== -1) {
 
84
  }
85
 
86
  function handleBackdropClick(event: MouseEvent) {
87
+ event.stopPropagation();
88
  if (window?.getSelection()?.toString()) {
89
  return;
90
  }
 
94
  }
95
  </script>
96
 
97
+ <svelte:window onkeydown={handleKeydown} onmousemove={() => (ignoreCursorHighlight = false)} />
98
 
99
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
100
+ <!-- svelte-ignore 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
+ onclick={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
 
112
  <div class="mr-2 text-sm">
113
  <IconSearch />
114
  </div>
115
+ <!-- svelte-ignore a11y_autofocus -->
116
  <input
117
  autofocus
118
  class="flex h-10 w-full rounded-md bg-transparent py-3 text-sm placeholder-gray-400 outline-hidden"
 
131
  class="flex w-full cursor-pointer items-center px-2 py-1.5 text-sm {highlightIdx === idx
132
  ? 'highlighted bg-gray-100 dark:bg-gray-800'
133
  : ''}"
134
+ onmouseenter={() => highlightRow(idx)}
135
+ onclick={() => {
136
  dispatch("modelSelected", model.id);
137
  dispatch("close");
138
  }}
 
161
  class="flex w-full cursor-pointer items-center px-2 py-1.5 text-sm {highlightIdx === idx
162
  ? 'highlighted bg-gray-100 dark:bg-gray-800'
163
  : ''}"
164
+ onmouseenter={() => highlightRow(idx)}
165
+ onclick={() => {
166
  dispatch("modelSelected", model.id);
167
  dispatch("close");
168
  }}
src/lib/components/inference-playground/model-selector.svelte CHANGED
@@ -8,9 +8,13 @@
8
  import ProviderSelect from "./provider-select.svelte";
9
  import { defaultSystemMessage } from "./utils.js";
10
 
11
- export let conversation: Conversation;
 
 
 
 
12
 
13
- let showModelPickerModal = false;
14
 
15
  // Model
16
  function changeModel(modelId: ModelWithTokenizer["id"]) {
@@ -23,8 +27,8 @@
23
  conversation.provider = undefined;
24
  }
25
 
26
- $: nameSpace = conversation.model.id.split("/")[0] ?? "";
27
- $: modelName = conversation.model.id.split("/")[1] ?? "";
28
  const id = crypto.randomUUID();
29
  </script>
30
 
@@ -36,7 +40,7 @@
36
  <button
37
  {id}
38
  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"
39
- on:click={() => (showModelPickerModal = true)}
40
  >
41
  <div class="flex flex-col items-start">
42
  <div class="flex items-center gap-1 text-sm text-gray-500 dark:text-gray-300">
 
8
  import ProviderSelect from "./provider-select.svelte";
9
  import { defaultSystemMessage } from "./utils.js";
10
 
11
+ interface Props {
12
+ conversation: Conversation;
13
+ }
14
+
15
+ let { conversation = $bindable() }: Props = $props();
16
 
17
+ let showModelPickerModal = $state(false);
18
 
19
  // Model
20
  function changeModel(modelId: ModelWithTokenizer["id"]) {
 
27
  conversation.provider = undefined;
28
  }
29
 
30
+ let nameSpace = $derived(conversation.model.id.split("/")[0] ?? "");
31
+ let modelName = $derived(conversation.model.id.split("/")[1] ?? "");
32
  const id = crypto.randomUUID();
33
  </script>
34
 
 
40
  <button
41
  {id}
42
  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"
43
+ onclick={() => (showModelPickerModal = true)}
44
  >
45
  <div class="flex flex-col items-start">
46
  <div class="flex items-center gap-1 text-sm text-gray-500 dark:text-gray-300">
src/lib/components/inference-playground/playground.svelte CHANGED
@@ -25,23 +25,27 @@
25
 
26
  const startMessageUser: ConversationMessage = { role: "user", content: "" };
27
 
28
- let viewCode = false;
29
- let viewSettings = false;
30
- let loading = false;
31
  let abortControllers: AbortController[] = [];
32
  let waitForNonStreaming = true;
33
- let selectCompareModelOpen = false;
34
 
35
  interface GenerationStatistics {
36
  latency: number;
37
  generatedTokensCount: number;
38
  }
39
- let generationStats = $project.conversations.map(_ => ({ latency: 0, generatedTokensCount: 0 })) as
40
- | [GenerationStatistics]
41
- | [GenerationStatistics, GenerationStatistics];
 
 
42
 
43
- $: systemPromptSupported = $project.conversations.some(conversation => isSystemPromptSupported(conversation.model));
44
- $: compareActive = $project.conversations.length === 2;
 
 
45
 
46
  function reset() {
47
  $project.conversations.map(conversation => {
@@ -209,7 +213,7 @@
209
  />
210
  {/if}
211
 
212
- <!-- svelte-ignore a11y-no-static-element-interactions -->
213
  <div
214
  class="motion-safe:animate-fade-in grid h-dvh divide-gray-200 overflow-hidden bg-gray-100/50 max-md:grid-rows-[120px_1fr] max-md:divide-y dark:divide-gray-800 dark:bg-gray-900 dark:text-gray-300 dark:[color-scheme:dark] {compareActive
215
  ? 'md:grid-cols-[clamp(220px,20%,350px)_minmax(0,1fr)]'
@@ -232,7 +236,7 @@
232
  ? "Enter a custom prompt"
233
  : "System prompt is not supported with the chosen model."}
234
  value={systemPromptSupported ? $project.conversations[0].systemMessage.content : ""}
235
- on:input={e => {
236
  for (const conversation of $project.conversations) {
237
  conversation.systemMessage.content = e.currentTarget.value;
238
  }
@@ -242,22 +246,22 @@
242
  ></textarea>
243
  </div>
244
  </div>
245
- <div class="relative divide-y divide-gray-200 dark:divide-gray-800" on:keydown={onKeydown}>
246
  <div
247
  class="flex h-[calc(100dvh-5rem-120px)] divide-x divide-gray-200 overflow-x-auto overflow-y-hidden *:w-full max-sm:w-dvw md:h-[calc(100dvh-5rem)] md:pt-3 dark:divide-gray-800"
248
  >
249
- {#each $project.conversations as conversation, conversationIdx}
250
  <div class="max-sm:min-w-full">
251
  {#if compareActive}
252
  <PlaygroundConversationHeader
253
  {conversationIdx}
254
- bind:conversation
255
  on:close={() => removeCompareModal(conversationIdx)}
256
  />
257
  {/if}
258
  <PlaygroundConversation
259
  {loading}
260
- bind:conversation
261
  {viewCode}
262
  {compareActive}
263
  on:closeCode={() => (viewCode = false)}
@@ -272,7 +276,7 @@
272
  {#if !compareActive}
273
  <button
274
  type="button"
275
- on:click={() => (viewSettings = !viewSettings)}
276
  class="flex h-[39px] items-center gap-1 rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm font-medium text-gray-900 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 focus:outline-hidden md:hidden dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:ring-gray-700"
277
  >
278
  <div class="text-black dark:text-white">
@@ -281,7 +285,7 @@
281
  {!viewSettings ? "Settings" : "Hide Settings"}
282
  </button>
283
  {/if}
284
- <button type="button" on:click={reset} class="btn size-[39px]">
285
  <IconDelete />
286
  </button>
287
  </div>
@@ -291,12 +295,12 @@
291
  {/each}
292
  </div>
293
  <div class="flex flex-1 justify-end gap-x-2">
294
- <button type="button" on:click={() => (viewCode = !viewCode)} class="btn">
295
  <IconCode />
296
  {!viewCode ? "View Code" : "Hide Code"}</button
297
  >
298
  <button
299
- on:click={() => {
300
  viewCode = false;
301
  loading ? abort() : submit();
302
  }}
@@ -347,7 +351,7 @@
347
  <div class="flex items-center gap-2 self-end px-2 text-xs whitespace-nowrap">
348
  <button
349
  class="flex items-center gap-0.5 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
350
- on:click={() => (selectCompareModelOpen = true)}
351
  >
352
  <IconCompare />
353
  Compare
@@ -367,7 +371,7 @@
367
  <GenerationConfig bind:conversation={$project.conversations[0]} />
368
  {#if $token.value}
369
  <button
370
- on:click={token.reset}
371
  class="mt-auto flex items-center gap-1 self-end text-sm text-gray-500 underline decoration-gray-300 hover:text-gray-800 dark:text-gray-400 dark:decoration-gray-600 dark:hover:text-gray-200"
372
  ><svg xmlns="http://www.w3.org/2000/svg" class="text-xs" width="1em" height="1em" viewBox="0 0 32 32"
373
  ><path
 
25
 
26
  const startMessageUser: ConversationMessage = { role: "user", content: "" };
27
 
28
+ let viewCode = $state(false);
29
+ let viewSettings = $state(false);
30
+ let loading = $state(false);
31
  let abortControllers: AbortController[] = [];
32
  let waitForNonStreaming = true;
33
+ let selectCompareModelOpen = $state(false);
34
 
35
  interface GenerationStatistics {
36
  latency: number;
37
  generatedTokensCount: number;
38
  }
39
+ let generationStats = $state(
40
+ $project.conversations.map(_ => ({ latency: 0, generatedTokensCount: 0 })) as
41
+ | [GenerationStatistics]
42
+ | [GenerationStatistics, GenerationStatistics]
43
+ );
44
 
45
+ let systemPromptSupported = $derived(
46
+ $project.conversations.some(conversation => isSystemPromptSupported(conversation.model))
47
+ );
48
+ let compareActive = $derived($project.conversations.length === 2);
49
 
50
  function reset() {
51
  $project.conversations.map(conversation => {
 
213
  />
214
  {/if}
215
 
216
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
217
  <div
218
  class="motion-safe:animate-fade-in grid h-dvh divide-gray-200 overflow-hidden bg-gray-100/50 max-md:grid-rows-[120px_1fr] max-md:divide-y dark:divide-gray-800 dark:bg-gray-900 dark:text-gray-300 dark:[color-scheme:dark] {compareActive
219
  ? 'md:grid-cols-[clamp(220px,20%,350px)_minmax(0,1fr)]'
 
236
  ? "Enter a custom prompt"
237
  : "System prompt is not supported with the chosen model."}
238
  value={systemPromptSupported ? $project.conversations[0].systemMessage.content : ""}
239
+ oninput={e => {
240
  for (const conversation of $project.conversations) {
241
  conversation.systemMessage.content = e.currentTarget.value;
242
  }
 
246
  ></textarea>
247
  </div>
248
  </div>
249
+ <div class="relative divide-y divide-gray-200 dark:divide-gray-800" onkeydown={onKeydown}>
250
  <div
251
  class="flex h-[calc(100dvh-5rem-120px)] divide-x divide-gray-200 overflow-x-auto overflow-y-hidden *:w-full max-sm:w-dvw md:h-[calc(100dvh-5rem)] md:pt-3 dark:divide-gray-800"
252
  >
253
+ {#each $project.conversations as _conversation, conversationIdx}
254
  <div class="max-sm:min-w-full">
255
  {#if compareActive}
256
  <PlaygroundConversationHeader
257
  {conversationIdx}
258
+ bind:conversation={$project.conversations[conversationIdx]!}
259
  on:close={() => removeCompareModal(conversationIdx)}
260
  />
261
  {/if}
262
  <PlaygroundConversation
263
  {loading}
264
+ bind:conversation={$project.conversations[conversationIdx]!}
265
  {viewCode}
266
  {compareActive}
267
  on:closeCode={() => (viewCode = false)}
 
276
  {#if !compareActive}
277
  <button
278
  type="button"
279
+ onclick={() => (viewSettings = !viewSettings)}
280
  class="flex h-[39px] items-center gap-1 rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm font-medium text-gray-900 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 focus:outline-hidden md:hidden dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:ring-gray-700"
281
  >
282
  <div class="text-black dark:text-white">
 
285
  {!viewSettings ? "Settings" : "Hide Settings"}
286
  </button>
287
  {/if}
288
+ <button type="button" onclick={reset} class="btn size-[39px]">
289
  <IconDelete />
290
  </button>
291
  </div>
 
295
  {/each}
296
  </div>
297
  <div class="flex flex-1 justify-end gap-x-2">
298
+ <button type="button" onclick={() => (viewCode = !viewCode)} class="btn">
299
  <IconCode />
300
  {!viewCode ? "View Code" : "Hide Code"}</button
301
  >
302
  <button
303
+ onclick={() => {
304
  viewCode = false;
305
  loading ? abort() : submit();
306
  }}
 
351
  <div class="flex items-center gap-2 self-end px-2 text-xs whitespace-nowrap">
352
  <button
353
  class="flex items-center gap-0.5 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
354
+ onclick={() => (selectCompareModelOpen = true)}
355
  >
356
  <IconCompare />
357
  Compare
 
371
  <GenerationConfig bind:conversation={$project.conversations[0]} />
372
  {#if $token.value}
373
  <button
374
+ onclick={token.reset}
375
  class="mt-auto flex items-center gap-1 self-end text-sm text-gray-500 underline decoration-gray-300 hover:text-gray-800 dark:text-gray-400 dark:decoration-gray-600 dark:hover:text-gray-200"
376
  ><svg xmlns="http://www.w3.org/2000/svg" class="text-xs" width="1em" height="1em" viewBox="0 0 32 32"
377
  ><path
src/lib/components/inference-playground/provider-select.svelte CHANGED
@@ -1,4 +1,6 @@
1
  <script lang="ts">
 
 
2
  import type { Conversation } from "$lib/types.js";
3
 
4
  import { randomPick } from "$lib/utils/array.js";
@@ -7,9 +9,13 @@
7
  import IconCaret from "~icons/carbon/chevron-down";
8
  import IconProvider from "../icon-provider.svelte";
9
 
10
- export let conversation: Conversation;
11
- let classes: string | undefined = undefined;
12
- export { classes as class };
 
 
 
 
13
 
14
  function reset(providers: typeof conversation.model.inferenceProviderMapping) {
15
  const validProvider = providers.find(p => p.provider === conversation.provider);
@@ -17,18 +23,22 @@
17
  conversation.provider = randomPick(providers)?.provider;
18
  }
19
 
20
- $: providers = conversation.model.inferenceProviderMapping;
21
- $: reset(providers);
 
 
22
 
23
  const {
24
  elements: { trigger, menu, option },
25
  states: { selected },
26
  } = createSelect<string, false>();
27
  const sync = createSync({ selected });
28
- $: sync.selected(
29
- conversation.provider ? { value: conversation.provider } : undefined,
30
- p => (conversation.provider = p?.value)
31
- );
 
 
32
 
33
  const nameMap: Record<string, string> = {
34
  "sambanova": "SambaNova",
 
1
  <script lang="ts">
2
+ import { run } from 'svelte/legacy';
3
+
4
  import type { Conversation } from "$lib/types.js";
5
 
6
  import { randomPick } from "$lib/utils/array.js";
 
9
  import IconCaret from "~icons/carbon/chevron-down";
10
  import IconProvider from "../icon-provider.svelte";
11
 
12
+ interface Props {
13
+ conversation: Conversation;
14
+ class?: string | undefined;
15
+ }
16
+
17
+ let { conversation = $bindable(), class: classes = undefined }: Props = $props();
18
+
19
 
20
  function reset(providers: typeof conversation.model.inferenceProviderMapping) {
21
  const validProvider = providers.find(p => p.provider === conversation.provider);
 
23
  conversation.provider = randomPick(providers)?.provider;
24
  }
25
 
26
+ let providers = $derived(conversation.model.inferenceProviderMapping);
27
+ run(() => {
28
+ reset(providers);
29
+ });
30
 
31
  const {
32
  elements: { trigger, menu, option },
33
  states: { selected },
34
  } = createSelect<string, false>();
35
  const sync = createSync({ selected });
36
+ run(() => {
37
+ sync.selected(
38
+ conversation.provider ? { value: conversation.provider } : undefined,
39
+ p => (conversation.provider = p?.value)
40
+ );
41
+ });
42
 
43
  const nameMap: Record<string, string> = {
44
  "sambanova": "SambaNova",
src/lib/components/prompts.svelte CHANGED
@@ -1,4 +1,4 @@
1
- <script lang="ts" context="module">
2
  import { clickOutside } from "$lib/actions/click-outside.js";
3
  import { writable } from "svelte/store";
4
  import IconCross from "~icons/carbon/close";
@@ -27,15 +27,19 @@
27
  </script>
28
 
29
  <script lang="ts">
30
- $: current = $prompts?.[0];
31
 
32
- let dialog: HTMLDialogElement | undefined;
33
 
34
- $: if (current) {
35
- dialog?.showModal();
36
- } else {
37
- dialog?.close();
38
- }
 
 
 
 
39
 
40
  function onSubmit(e: Event) {
41
  e.preventDefault();
@@ -43,11 +47,11 @@
43
  }
44
  </script>
45
 
46
- <dialog bind:this={dialog} on:close={resolvePrompt}>
47
  {#if current}
48
  <div class="fixed inset-0 z-50 flex items-center justify-center overflow-hidden bg-black/85">
49
  <form
50
- on:submit={onSubmit}
51
  class="relative w-xl rounded-lg bg-white shadow-sm dark:bg-gray-900"
52
  use:clickOutside={resolvePrompt}
53
  >
@@ -58,7 +62,7 @@
58
  <button
59
  type="button"
60
  class="ms-auto inline-flex h-8 w-8 items-center justify-center rounded-lg bg-transparent text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white"
61
- on:click={resolvePrompt}
62
  >
63
  <div class="text-xl">
64
  <IconCross />
@@ -70,7 +74,7 @@
70
  <div class="p-4 md:p-5">
71
  <label class="flex flex-col gap-2 font-medium text-gray-900 dark:text-white">
72
  <!-- This is fine in dialogs -->
73
- <!-- svelte-ignore a11y-autofocus -->
74
  <input
75
  bind:value={current.value}
76
  placeholder={current.placeholder}
 
1
+ <script lang="ts" module>
2
  import { clickOutside } from "$lib/actions/click-outside.js";
3
  import { writable } from "svelte/store";
4
  import IconCross from "~icons/carbon/close";
 
27
  </script>
28
 
29
  <script lang="ts">
30
+ import { run } from 'svelte/legacy';
31
 
32
+ let current = $derived($prompts?.[0]);
33
 
34
+ let dialog: HTMLDialogElement | undefined = $state();
35
+
36
+ run(() => {
37
+ if (current) {
38
+ dialog?.showModal();
39
+ } else {
40
+ dialog?.close();
41
+ }
42
+ });
43
 
44
  function onSubmit(e: Event) {
45
  e.preventDefault();
 
47
  }
48
  </script>
49
 
50
+ <dialog bind:this={dialog} onclose={resolvePrompt}>
51
  {#if current}
52
  <div class="fixed inset-0 z-50 flex items-center justify-center overflow-hidden bg-black/85">
53
  <form
54
+ onsubmit={onSubmit}
55
  class="relative w-xl rounded-lg bg-white shadow-sm dark:bg-gray-900"
56
  use:clickOutside={resolvePrompt}
57
  >
 
62
  <button
63
  type="button"
64
  class="ms-auto inline-flex h-8 w-8 items-center justify-center rounded-lg bg-transparent text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white"
65
+ onclick={resolvePrompt}
66
  >
67
  <div class="text-xl">
68
  <IconCross />
 
74
  <div class="p-4 md:p-5">
75
  <label class="flex flex-col gap-2 font-medium text-gray-900 dark:text-white">
76
  <!-- This is fine in dialogs -->
77
+ <!-- svelte-ignore a11y_autofocus -->
78
  <input
79
  bind:value={current.value}
80
  placeholder={current.placeholder}
src/routes/+layout.svelte CHANGED
@@ -3,9 +3,14 @@
3
  import DebugMenu from "$lib/components/debug-menu.svelte";
4
  import Prompts from "$lib/components/prompts.svelte";
5
  import Toaster from "$lib/components/toaster.svelte";
 
 
 
 
 
6
  </script>
7
 
8
- <slot />
9
  <DebugMenu />
10
  <Prompts />
11
  <Toaster />
 
3
  import DebugMenu from "$lib/components/debug-menu.svelte";
4
  import Prompts from "$lib/components/prompts.svelte";
5
  import Toaster from "$lib/components/toaster.svelte";
6
+ interface Props {
7
+ children?: import('svelte').Snippet;
8
+ }
9
+
10
+ let { children }: Props = $props();
11
  </script>
12
 
13
+ {@render children?.()}
14
  <DebugMenu />
15
  <Prompts />
16
  <Toaster />