File size: 4,127 Bytes
502cb81 5213b80 1189124 a979074 0ffe6c3 502cb81 0ffe6c3 502cb81 f2e5687 502cb81 eb79b3d 502cb81 5213b80 f2e5687 502cb81 5213b80 502cb81 5213b80 d5e14b5 5213b80 502cb81 f2e5687 5213b80 502cb81 5213b80 f2e5687 5213b80 3d94876 5213b80 3d94876 0ffe6c3 3d94876 5213b80 f2e5687 5213b80 f2e5687 5213b80 502cb81 5213b80 502cb81 5213b80 a979074 5213b80 502cb81 5213b80 79d3242 5213b80 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import CodeSnippets from './InferencePlaygroundCodeSnippets.svelte';
import Message from './InferencePlaygroundMessage.svelte';
import PlaygroundOptions from './InferencePlaygroundGenerationConfig.svelte';
import IconPlus from '../Icons/IconPlus.svelte';
import type { Conversation } from '$lib/types';
export let loading;
export let conversation: Conversation;
export let index;
export let viewCode;
export let sideBySide = false;
const dispatch = createEventDispatcher<{
addMessage: void;
deleteMessage: number;
deleteConversation: number;
}>();
let messageContainer: HTMLDivElement | null = null;
function scrollToBottom() {
if (messageContainer) {
messageContainer.scrollTop = messageContainer.scrollHeight;
}
}
$: {
if (conversation.messages.at(-1)) {
scrollToBottom();
}
}
</script>
<div
class="flex max-h-[calc(100dvh-5.8rem)] flex-col overflow-y-auto overflow-x-hidden @container"
class:pointer-events-none={loading}
class:animate-pulse={loading && !conversation.streaming}
bind:this={messageContainer}
>
{#if sideBySide}
<div
class="sticky top-0 flex h-11 flex-none items-center gap-2 whitespace-nowrap rounded-lg border border-gray-200/80 bg-white pl-3 pr-2 text-sm leading-none shadow-sm *:flex-none dark:border-gray-800 dark:bg-gray-800/70 dark:hover:bg-gray-800"
class:mr-3={index === 0}
class:mx-3={index === 1}
>
<div class="size-3.5 rounded bg-black dark:bg-gray-400"></div>
<div>{conversation.model}</div>
<button
class="ml-auto flex size-6 items-center justify-center rounded bg-gray-50 text-xs hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700"
on:click={() => dispatch('deleteConversation', index)}
>
✕
</button>
<button
class="group relative flex size-6 items-center justify-center rounded bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700"
>
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"
><path
fill="currentColor"
d="M27 16.76v-1.53l1.92-1.68A2 2 0 0 0 29.3 11l-2.36-4a2 2 0 0 0-1.73-1a2 2 0 0 0-.64.1l-2.43.82a11.35 11.35 0 0 0-1.31-.75l-.51-2.52a2 2 0 0 0-2-1.61h-4.68a2 2 0 0 0-2 1.61l-.51 2.52a11.48 11.48 0 0 0-1.32.75l-2.38-.86A2 2 0 0 0 6.79 6a2 2 0 0 0-1.73 1L2.7 11a2 2 0 0 0 .41 2.51L5 15.24v1.53l-1.89 1.68A2 2 0 0 0 2.7 21l2.36 4a2 2 0 0 0 1.73 1a2 2 0 0 0 .64-.1l2.43-.82a11.35 11.35 0 0 0 1.31.75l.51 2.52a2 2 0 0 0 2 1.61h4.72a2 2 0 0 0 2-1.61l.51-2.52a11.48 11.48 0 0 0 1.32-.75l2.42.82a2 2 0 0 0 .64.1a2 2 0 0 0 1.73-1l2.28-4a2 2 0 0 0-.41-2.51ZM25.21 24l-3.43-1.16a8.86 8.86 0 0 1-2.71 1.57L18.36 28h-4.72l-.71-3.55a9.36 9.36 0 0 1-2.7-1.57L6.79 24l-2.36-4l2.72-2.4a8.9 8.9 0 0 1 0-3.13L4.43 12l2.36-4l3.43 1.16a8.86 8.86 0 0 1 2.71-1.57L13.64 4h4.72l.71 3.55a9.36 9.36 0 0 1 2.7 1.57L25.21 8l2.36 4l-2.72 2.4a8.9 8.9 0 0 1 0 3.13L27.57 20Z"
/><path
fill="currentColor"
d="M16 22a6 6 0 1 1 6-6a5.94 5.94 0 0 1-6 6Zm0-10a3.91 3.91 0 0 0-4 4a3.91 3.91 0 0 0 4 4a3.91 3.91 0 0 0 4-4a3.91 3.91 0 0 0-4-4Z"
/></svg
>
<PlaygroundOptions
bind:conversation
classNames="absolute top-8 right-0 w-56 invisible group-focus:visible hover:visible border border-gray-200/80 bg-white z-10 px-4 py-6 text-sm shadow-sm dark:border-gray-800 dark:bg-gray-800 rounded-xl"
/>
</button>
</div>
{/if}
{#if !viewCode}
{#each conversation.messages as message, messageIdx}
<Message
class="border-b"
{message}
conversationIdx={index}
{messageIdx}
on:messageValueChanged
on:delete={() => dispatch('deleteMessage', messageIdx)}
autofocus={!sideBySide && !loading && messageIdx === conversation.messages.length - 1}
/>
{/each}
<button
class="flex px-6 py-6 hover:bg-gray-50 dark:hover:bg-gray-800/50"
on:click={() => dispatch('addMessage')}
disabled={loading}
>
<div class="flex items-center gap-2 !p-0 text-sm font-semibold">
<IconPlus classNames="text-lg" /> Add message
</div>
</button>
{:else}
<CodeSnippets {conversation} />
{/if}
</div>
|