diff --git a/src/lib/components/playground/Chat.svelte b/src/lib/components/playground/Chat.svelte index 1ac0678892..b42771c6f7 100644 --- a/src/lib/components/playground/Chat.svelte +++ b/src/lib/components/playground/Chat.svelte @@ -5,7 +5,7 @@ import { toast } from 'svelte-sonner'; import { goto } from '$app/navigation'; - import { onMount, tick, getContext } from 'svelte'; + import { onDestroy, onMount, tick, getContext } from 'svelte'; import { OLLAMA_API_BASE_URL, @@ -13,16 +13,19 @@ WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; - import { WEBUI_NAME, config, user, models, settings } from '$lib/stores'; + import { WEBUI_NAME, config, user, models, settings, showControls } from '$lib/stores'; import { chatCompletion } from '$lib/apis/openai'; import { splitStream } from '$lib/utils'; import Collapsible from '../common/Collapsible.svelte'; + import Tooltip from '../common/Tooltip.svelte'; import Dropdown from '../common/Dropdown.svelte'; import DropdownSub from '../common/DropdownSub.svelte'; + import Drawer from '../common/Drawer.svelte'; import Messages from '$lib/components/playground/Chat/Messages.svelte'; + import PlaygroundControls from '$lib/components/playground/Chat/Controls.svelte'; import ChevronUp from '../icons/ChevronUp.svelte'; import ChevronDown from '../icons/ChevronDown.svelte'; import Pencil from '../icons/Pencil.svelte'; @@ -31,8 +34,10 @@ import ArrowRight from '../icons/ArrowRight.svelte'; import Download from '../icons/Download.svelte'; import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte'; + import Knobs from '../icons/Knobs.svelte'; + import XMark from '../icons/XMark.svelte'; - const i18n = getContext('i18n'); + const i18n = getContext('i18n') as any; let loaded = false; @@ -47,11 +52,18 @@ let showSettings = false; let system = ''; + let params: Record = {}; let role = 'user'; let message = ''; let messages = []; + let largeScreen = false; + let mediaQuery: MediaQueryList | null = null; + + const handleMediaQuery = (event: MediaQueryList | MediaQueryListEvent) => { + largeScreen = event.matches; + }; const scrollToBottom = () => { const element = messagesContainerElement; @@ -78,6 +90,27 @@ resizeSystemTextarea(); } + const getStopTokens = () => { + const stop = params?.stop as string | string[] | null | undefined; + if (!stop) return undefined; + + const tokens = Array.isArray(stop) ? stop : stop.split(',').map((s: string) => s.trim()); + + return tokens + .filter(Boolean) + .map((token: string) => decodeURIComponent(JSON.parse(`"${token.replace(/"/g, '\\"')}"`))); + }; + + const getRequestParams = () => { + const requestParams = { ...params }; + + if (params?.stop) { + requestParams.stop = getStopTokens(); + } + + return requestParams; + }; + const chatCompletionHandler = async () => { if (selectedModelId === '') { toast.error($i18n.t('Please select a model.')); @@ -90,11 +123,14 @@ return; } + const requestParams = getRequestParams(); + const [res, controller] = await chatCompletion( localStorage.token, { model: model.id, stream: true, + ...(Object.keys(requestParams).length > 0 ? { params: requestParams } : {}), messages: [ system ? { @@ -249,7 +285,10 @@ chat: { title: 'Playground Chat', models: [selectedModelId], - params: system ? { system } : {}, + params: { + ...params, + ...(system ? { system } : {}) + }, history: { messages: messagesMap, currentId @@ -288,7 +327,17 @@ toast.success($i18n.t('Chat exported successfully')); }; + onDestroy(() => { + mediaQuery?.removeEventListener('change', handleMediaQuery); + showControls.set(false); + }); + onMount(async () => { + showControls.set(false); + mediaQuery = window.matchMedia('(min-width: 1024px)'); + mediaQuery.addEventListener('change', handleMediaQuery); + handleMediaQuery(mediaQuery); + if ($user?.role !== 'admin') { await goto('/'); } @@ -304,7 +353,7 @@ }); -
+
@@ -390,12 +439,30 @@ downloadTxt(); }} > -
{$i18n.t('Plain text (.txt)')}
+
+ {$i18n.t('Plain text (.txt)')} +
+ + {#if $user?.role === 'admin' || ($user?.permissions.chat?.controls ?? true)} + + + + {/if}
+ {#if largeScreen && $showControls} +
+
+
+
+ {$i18n.t('Controls')} +
+ + +
+ +
+ +
+
+
+ {/if}
+ +{#if !largeScreen && $showControls} + showControls.set(false)} + className="min-h-[100dvh] !bg-white dark:!bg-gray-850" + > +
+
+
+ {$i18n.t('Controls')} +
+ + +
+ +
+ +
+
+
+{/if} diff --git a/src/lib/components/playground/Chat/Controls.svelte b/src/lib/components/playground/Chat/Controls.svelte new file mode 100644 index 0000000000..db35c6a81d --- /dev/null +++ b/src/lib/components/playground/Chat/Controls.svelte @@ -0,0 +1,63 @@ + + +
+ {#if $user?.role === 'admin' || ($user?.permissions.chat?.controls ?? true)} +
+ {#if $user?.role === 'admin' || ($user?.permissions.chat?.valves ?? true)} + +
+ +
+
+ +
+ {/if} + + {#if $user?.role === 'admin' || ($user?.permissions.chat?.params ?? true)} + +
+ +
+
+ {/if} +
+ {/if} +