Spaces:
Runtime error
Runtime error
Thomas G. Lopes
commited on
Commit
·
5851d63
1
Parent(s):
e48cc8b
conversation to runes
Browse files
eslint.config.mjs
CHANGED
|
@@ -67,7 +67,7 @@ export default [
|
|
| 67 |
rules: {
|
| 68 |
"require-yield": "off",
|
| 69 |
"@typescript-eslint/no-explicit-any": "error",
|
| 70 |
-
"@typescript-eslint/no-non-null-assertion": "error",
|
| 71 |
|
| 72 |
"@typescript-eslint/no-unused-vars": [
|
| 73 |
"error",
|
|
|
|
| 67 |
rules: {
|
| 68 |
"require-yield": "off",
|
| 69 |
"@typescript-eslint/no-explicit-any": "error",
|
| 70 |
+
// "@typescript-eslint/no-non-null-assertion": "error",
|
| 71 |
|
| 72 |
"@typescript-eslint/no-unused-vars": [
|
| 73 |
"error",
|
src/lib/components/InferencePlayground/InferencePlaygroundConversation.svelte
CHANGED
|
@@ -1,36 +1,25 @@
|
|
| 1 |
<script lang="ts">
|
| 2 |
-
import
|
| 3 |
|
| 4 |
-
import {
|
| 5 |
|
| 6 |
import IconPlus from "~icons/carbon/add";
|
| 7 |
import CodeSnippets from "./InferencePlaygroundCodeSnippets.svelte";
|
| 8 |
-
import Message from "./InferencePlaygroundMessage.svelte";
|
| 9 |
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
| 14 |
|
| 15 |
-
let
|
| 16 |
-
let isProgrammaticScroll = true;
|
| 17 |
-
let conversationLength = conversation.messages.length;
|
| 18 |
|
| 19 |
-
let
|
|
|
|
|
|
|
| 20 |
|
| 21 |
-
|
| 22 |
-
// ideally we would use CSS "field-sizing:content". However, it is currently only supported on Chrome.
|
| 23 |
-
await tick();
|
| 24 |
-
if (messageContainer) {
|
| 25 |
-
const containerScrollTop = messageContainer.scrollTop;
|
| 26 |
-
const textareaEls = messageContainer.querySelectorAll("textarea");
|
| 27 |
-
for (const textarea of textareaEls) {
|
| 28 |
-
textarea.style.height = "0px";
|
| 29 |
-
textarea.style.height = textarea.scrollHeight + "px";
|
| 30 |
-
}
|
| 31 |
-
messageContainer.scrollTop = containerScrollTop;
|
| 32 |
-
}
|
| 33 |
-
}
|
| 34 |
|
| 35 |
function scrollToBottom() {
|
| 36 |
if (messageContainer) {
|
|
@@ -39,22 +28,21 @@
|
|
| 39 |
}
|
| 40 |
}
|
| 41 |
|
| 42 |
-
|
| 43 |
if (conversation.messages.at(-1)) {
|
| 44 |
-
resizeMessageTextAreas();
|
| 45 |
if (shouldScrollToBottom) {
|
| 46 |
scrollToBottom();
|
| 47 |
}
|
| 48 |
}
|
| 49 |
-
}
|
| 50 |
-
|
| 51 |
-
$: if (conversation.messages.length !== conversationLength) {
|
| 52 |
-
// enable automatic scrolling when new message was added
|
| 53 |
-
conversationLength = conversation.messages.length;
|
| 54 |
-
shouldScrollToBottom = true;
|
| 55 |
-
}
|
| 56 |
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
function addMessage() {
|
| 60 |
const msgs = conversation.messages.slice();
|
|
@@ -74,15 +62,13 @@
|
|
| 74 |
}
|
| 75 |
</script>
|
| 76 |
|
| 77 |
-
<svelte:window on:resize={resizeMessageTextAreas} />
|
| 78 |
-
|
| 79 |
<div
|
| 80 |
class="@container flex flex-col overflow-x-hidden overflow-y-auto {compareActive
|
| 81 |
? 'max-h-[calc(100dvh-5.8rem-2.5rem-75px)] md:max-h-[calc(100dvh-5.8rem-2.5rem)]'
|
| 82 |
: 'max-h-[calc(100dvh-5.8rem-2.5rem-75px)] md:max-h-[calc(100dvh-5.8rem)]'}"
|
| 83 |
class:animate-pulse={loading && !conversation.streaming}
|
| 84 |
bind:this={messageContainer}
|
| 85 |
-
|
| 86 |
// disable automatic scrolling is user initiates scroll
|
| 87 |
if (!isProgrammaticScroll) {
|
| 88 |
shouldScrollToBottom = false;
|
|
@@ -91,20 +77,37 @@
|
|
| 91 |
}}
|
| 92 |
>
|
| 93 |
{#if !viewCode}
|
| 94 |
-
{#each conversation.messages as
|
| 95 |
-
<
|
| 96 |
-
class="border-b"
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
{/each}
|
| 104 |
|
| 105 |
<button
|
| 106 |
class="flex px-3.5 py-6 hover:bg-gray-50 md:px-6 dark:hover:bg-gray-800/50"
|
| 107 |
-
|
| 108 |
disabled={loading}
|
| 109 |
>
|
| 110 |
<div class="flex items-center gap-2 p-0! text-sm font-semibold">
|
|
|
|
| 1 |
<script lang="ts">
|
| 2 |
+
import { run } from "svelte/legacy";
|
| 3 |
|
| 4 |
+
import type { Conversation } from "$lib/types.js";
|
| 5 |
|
| 6 |
import IconPlus from "~icons/carbon/add";
|
| 7 |
import CodeSnippets from "./InferencePlaygroundCodeSnippets.svelte";
|
|
|
|
| 8 |
|
| 9 |
+
interface Props {
|
| 10 |
+
conversation: Conversation;
|
| 11 |
+
loading: boolean;
|
| 12 |
+
viewCode: boolean;
|
| 13 |
+
compareActive: boolean;
|
| 14 |
+
}
|
| 15 |
|
| 16 |
+
let { conversation = $bindable(), loading, viewCode, compareActive }: Props = $props();
|
|
|
|
|
|
|
| 17 |
|
| 18 |
+
let shouldScrollToBottom = $state(true);
|
| 19 |
+
let isProgrammaticScroll = $state(true);
|
| 20 |
+
let conversationLength = $state(conversation.messages.length);
|
| 21 |
|
| 22 |
+
let messageContainer: HTMLDivElement | null = $state(null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
function scrollToBottom() {
|
| 25 |
if (messageContainer) {
|
|
|
|
| 28 |
}
|
| 29 |
}
|
| 30 |
|
| 31 |
+
run(() => {
|
| 32 |
if (conversation.messages.at(-1)) {
|
|
|
|
| 33 |
if (shouldScrollToBottom) {
|
| 34 |
scrollToBottom();
|
| 35 |
}
|
| 36 |
}
|
| 37 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
+
run(() => {
|
| 40 |
+
if (conversation.messages.length !== conversationLength) {
|
| 41 |
+
// enable automatic scrolling when new message was added
|
| 42 |
+
conversationLength = conversation.messages.length;
|
| 43 |
+
shouldScrollToBottom = true;
|
| 44 |
+
}
|
| 45 |
+
});
|
| 46 |
|
| 47 |
function addMessage() {
|
| 48 |
const msgs = conversation.messages.slice();
|
|
|
|
| 62 |
}
|
| 63 |
</script>
|
| 64 |
|
|
|
|
|
|
|
| 65 |
<div
|
| 66 |
class="@container flex flex-col overflow-x-hidden overflow-y-auto {compareActive
|
| 67 |
? 'max-h-[calc(100dvh-5.8rem-2.5rem-75px)] md:max-h-[calc(100dvh-5.8rem-2.5rem)]'
|
| 68 |
: 'max-h-[calc(100dvh-5.8rem-2.5rem-75px)] md:max-h-[calc(100dvh-5.8rem)]'}"
|
| 69 |
class:animate-pulse={loading && !conversation.streaming}
|
| 70 |
bind:this={messageContainer}
|
| 71 |
+
onscroll={() => {
|
| 72 |
// disable automatic scrolling is user initiates scroll
|
| 73 |
if (!isProgrammaticScroll) {
|
| 74 |
shouldScrollToBottom = false;
|
|
|
|
| 77 |
}}
|
| 78 |
>
|
| 79 |
{#if !viewCode}
|
| 80 |
+
{#each conversation.messages as msg, idx}
|
| 81 |
+
<div
|
| 82 |
+
class=" group/message group grid grid-cols-[1fr_2.5rem] items-start gap-2 border-b px-3.5 pt-4 pb-6 hover:bg-gray-100/70 @-2xl:grid-cols-[130px_1fr_2.5rem] @2xl:grid-rows-1 @2xl:gap-4 @2xl:px-6 dark:border-gray-800 dark:hover:bg-gray-800/30"
|
| 83 |
+
class:pointer-events-none={loading}
|
| 84 |
+
>
|
| 85 |
+
<div class="col-span-2 pt-3 pb-1 text-sm font-semibold uppercase @2xl:col-span-1 @2xl:pb-2">
|
| 86 |
+
{msg.role}
|
| 87 |
+
</div>
|
| 88 |
+
<!-- svelte-ignore a11y_autofocus -->
|
| 89 |
+
<!-- svelte-ignore a11y_positive_tabindex -->
|
| 90 |
+
<textarea
|
| 91 |
+
autofocus={idx === conversation.messages.length - 1}
|
| 92 |
+
bind:value={conversation.messages[idx]!.content}
|
| 93 |
+
placeholder="Enter {msg.role} message"
|
| 94 |
+
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"
|
| 95 |
+
rows="1"
|
| 96 |
+
tabindex="2"
|
| 97 |
+
></textarea>
|
| 98 |
+
<button
|
| 99 |
+
tabindex="0"
|
| 100 |
+
onclick={() => deleteMessage(idx)}
|
| 101 |
+
type="button"
|
| 102 |
+
class="mt-1.5 size-8 rounded-lg border border-gray-200 bg-white text-xs font-medium text-gray-900 group-hover/message:block hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 focus:outline-hidden sm: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"
|
| 103 |
+
>✕</button
|
| 104 |
+
>
|
| 105 |
+
</div>
|
| 106 |
{/each}
|
| 107 |
|
| 108 |
<button
|
| 109 |
class="flex px-3.5 py-6 hover:bg-gray-50 md:px-6 dark:hover:bg-gray-800/50"
|
| 110 |
+
onclick={addMessage}
|
| 111 |
disabled={loading}
|
| 112 |
>
|
| 113 |
<div class="flex items-center gap-2 p-0! text-sm font-semibold">
|
src/lib/components/InferencePlayground/InferencePlaygroundMessage.svelte
DELETED
|
@@ -1,41 +0,0 @@
|
|
| 1 |
-
<script lang="ts">
|
| 2 |
-
import { createEventDispatcher } from "svelte";
|
| 3 |
-
import type { ConversationMessage } from "$lib/types.js";
|
| 4 |
-
|
| 5 |
-
export let message: ConversationMessage;
|
| 6 |
-
export let loading: boolean = false;
|
| 7 |
-
export let autofocus: boolean = false;
|
| 8 |
-
|
| 9 |
-
const dispatch = createEventDispatcher<{ delete: void; input: void }>();
|
| 10 |
-
</script>
|
| 11 |
-
|
| 12 |
-
<div
|
| 13 |
-
class="group/message group grid grid-cols-[1fr_2.5rem] items-start gap-2 px-3.5 pt-4 pb-6 hover:bg-gray-100/70 @-2xl:grid-cols-[130px_1fr_2.5rem] @2xl:grid-rows-1 @2xl:gap-4 @2xl:px-6 dark:border-gray-800 dark:hover:bg-gray-800/30 {$$props.class}"
|
| 14 |
-
class:pointer-events-none={loading}
|
| 15 |
-
>
|
| 16 |
-
<div class="col-span-2 pt-3 pb-1 text-sm font-semibold uppercase @2xl:col-span-1 @2xl:pb-2">
|
| 17 |
-
{message.role}
|
| 18 |
-
</div>
|
| 19 |
-
<!-- svelte-ignore a11y-autofocus -->
|
| 20 |
-
<!-- svelte-ignore a11y-positive-tabindex -->
|
| 21 |
-
<textarea
|
| 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={() => {
|
| 29 |
-
dispatch("input");
|
| 30 |
-
}}
|
| 31 |
-
></textarea>
|
| 32 |
-
<button
|
| 33 |
-
tabindex="0"
|
| 34 |
-
on:click={() => {
|
| 35 |
-
dispatch("delete");
|
| 36 |
-
}}
|
| 37 |
-
type="button"
|
| 38 |
-
class="mt-1.5 size-8 rounded-lg border border-gray-200 bg-white text-xs font-medium text-gray-900 group-hover/message:block hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 focus:outline-hidden sm: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"
|
| 39 |
-
>✕</button
|
| 40 |
-
>
|
| 41 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|