Unverified Commit 38ff3209 authored by Timothy Jaeryang Baek's avatar Timothy Jaeryang Baek Committed by GitHub
Browse files

Merge pull request #1881 from open-webui/dev

0.1.123
parents c9589e21 2789102d
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -34,6 +34,8 @@ export const documents = writable([ ...@@ -34,6 +34,8 @@ export const documents = writable([
]); ]);
export const settings: Writable<Settings> = writable({}); export const settings: Writable<Settings> = writable({});
export const showSidebar = writable(false);
export const showSettings = writable(false); export const showSettings = writable(false);
export const showChangelog = writable(false); export const showChangelog = writable(false);
...@@ -78,6 +80,7 @@ type Settings = { ...@@ -78,6 +80,7 @@ type Settings = {
saveChatHistory?: boolean; saveChatHistory?: boolean;
notificationEnabled?: boolean; notificationEnabled?: boolean;
title?: TitleSettings; title?: TitleSettings;
splitLargeDeltas?: boolean;
system?: string; system?: string;
requestFormat?: string; requestFormat?: string;
......
...@@ -154,7 +154,7 @@ ...@@ -154,7 +154,7 @@
if (isCtrlPressed && event.key === '.') { if (isCtrlPressed && event.key === '.') {
event.preventDefault(); event.preventDefault();
console.log('openSettings'); console.log('openSettings');
document.getElementById('open-settings-button')?.click(); showSettings.set(!$showSettings);
} }
// Check if Ctrl + / is pressed // Check if Ctrl + / is pressed
...@@ -192,6 +192,8 @@ ...@@ -192,6 +192,8 @@
</div> </div>
<ShortcutsModal bind:show={showShortcuts} /> <ShortcutsModal bind:show={showShortcuts} />
<SettingsModal bind:show={$showSettings} />
<ChangelogModal bind:show={$showChangelog} />
<div class="app relative"> <div class="app relative">
<div <div
...@@ -292,8 +294,6 @@ ...@@ -292,8 +294,6 @@
{/if} {/if}
<Sidebar /> <Sidebar />
<SettingsModal bind:show={$showSettings} />
<ChangelogModal bind:show={$showChangelog} />
<slot /> <slot />
{/if} {/if}
</div> </div>
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
chatId, chatId,
config, config,
WEBUI_NAME, WEBUI_NAME,
tags as _tags tags as _tags,
showSidebar
} from '$lib/stores'; } from '$lib/stores';
import { copyToClipboard, splitStream } from '$lib/utils'; import { copyToClipboard, splitStream } from '$lib/utils';
...@@ -50,7 +51,9 @@ ...@@ -50,7 +51,9 @@
let currentRequestId = null; let currentRequestId = null;
let showModelSelector = true; let showModelSelector = true;
let selectedModels = ['']; let selectedModels = [''];
let atSelectedModel = '';
let selectedModelfile = null; let selectedModelfile = null;
$: selectedModelfile = $: selectedModelfile =
...@@ -144,7 +147,8 @@ ...@@ -144,7 +147,8 @@
setTimeout(() => chatInput?.focus(), 0); setTimeout(() => chatInput?.focus(), 0);
}; };
const scrollToBottom = () => { const scrollToBottom = async () => {
await tick();
if (messagesContainerElement) { if (messagesContainerElement) {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight; messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
} }
...@@ -242,7 +246,8 @@ ...@@ -242,7 +246,8 @@
const _chatId = JSON.parse(JSON.stringify($chatId)); const _chatId = JSON.parse(JSON.stringify($chatId));
await Promise.all( await Promise.all(
selectedModels.map(async (modelId) => { (atSelectedModel !== '' ? [atSelectedModel.id] : selectedModels).map(async (modelId) => {
console.log('modelId', modelId);
const model = $models.filter((m) => m.id === modelId).at(0); const model = $models.filter((m) => m.id === modelId).at(0);
if (model) { if (model) {
...@@ -536,7 +541,7 @@ ...@@ -536,7 +541,7 @@
console.log(docs); console.log(docs);
console.log(model); scrollToBottom();
const [res, controller] = await generateOpenAIChatCompletion( const [res, controller] = await generateOpenAIChatCompletion(
localStorage.token, localStorage.token,
...@@ -605,14 +610,8 @@ ...@@ -605,14 +610,8 @@
scrollToBottom(); scrollToBottom();
if (res && res.ok) { if (res && res.ok && res.body) {
const reader = res.body const textStream = await createOpenAITextStream(res.body, $settings.splitLargeChunks);
.pipeThrough(new TextDecoderStream())
.pipeThrough(splitStream('\n'))
.getReader();
const textStream = await createOpenAITextStream(reader, $settings.splitLargeChunks);
console.log(textStream);
for await (const update of textStream) { for await (const update of textStream) {
const { value, done } = update; const { value, done } = update;
...@@ -844,7 +843,11 @@ ...@@ -844,7 +843,11 @@
</title> </title>
</svelte:head> </svelte:head>
<div class="h-screen max-h-[100dvh] w-full flex flex-col"> <div
class="min-h-screen max-h-screen {$showSidebar
? 'lg:max-w-[calc(100%-260px)]'
: ''} w-full max-w-full flex flex-col"
>
<Navbar <Navbar
{title} {title}
bind:selectedModels bind:selectedModels
...@@ -855,7 +858,7 @@ ...@@ -855,7 +858,7 @@
/> />
<div class="flex flex-col flex-auto"> <div class="flex flex-col flex-auto">
<div <div
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0" class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0 max-w-full"
id="messages-container" id="messages-container"
bind:this={messagesContainerElement} bind:this={messagesContainerElement}
on:scroll={(e) => { on:scroll={(e) => {
...@@ -873,22 +876,25 @@ ...@@ -873,22 +876,25 @@
bind:history bind:history
bind:messages bind:messages
bind:autoScroll bind:autoScroll
bind:prompt
bottomPadding={files.length > 0} bottomPadding={files.length > 0}
suggestionPrompts={selectedModelfile?.suggestionPrompts ??
$config.default_prompt_suggestions}
{sendPrompt} {sendPrompt}
{continueGeneration} {continueGeneration}
{regenerateResponse} {regenerateResponse}
/> />
</div> </div>
</div> </div>
</div>
</div>
<MessageInput <MessageInput
bind:files bind:files
bind:prompt bind:prompt
bind:autoScroll bind:autoScroll
suggestionPrompts={selectedModelfile?.suggestionPrompts ?? $config.default_prompt_suggestions} bind:selectedModel={atSelectedModel}
{messages} {messages}
{submitPrompt} {submitPrompt}
{stopResponse} {stopResponse}
/> />
</div>
</div>
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
import ChatBubbles from '$lib/components/icons/ChatBubbles.svelte'; import ChatBubbles from '$lib/components/icons/ChatBubbles.svelte';
import Tooltip from '$lib/components/common/Tooltip.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte';
import UserChatsModal from '$lib/components/admin/UserChatsModal.svelte'; import UserChatsModal from '$lib/components/admin/UserChatsModal.svelte';
import AddUserModal from '$lib/components/admin/AddUserModal.svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
let page = 1; let page = 1;
let showSettingsModal = false; let showSettingsModal = false;
let showAddUserModal = false;
let showUserChatsModal = false; let showUserChatsModal = false;
let showEditUserModal = false; let showEditUserModal = false;
...@@ -91,6 +93,12 @@ ...@@ -91,6 +93,12 @@
/> />
{/key} {/key}
<AddUserModal
bind:show={showAddUserModal}
on:save={async () => {
users = await getUsers(localStorage.token);
}}
/>
<UserChatsModal bind:show={showUserChatsModal} user={selectedUser} /> <UserChatsModal bind:show={showUserChatsModal} user={selectedUser} />
<SettingsModal bind:show={showSettingsModal} /> <SettingsModal bind:show={showSettingsModal} />
...@@ -100,12 +108,13 @@ ...@@ -100,12 +108,13 @@
<div class=" mx-auto w-full"> <div class=" mx-auto w-full">
<div class="w-full"> <div class="w-full">
<div class=" flex flex-col justify-center"> <div class=" flex flex-col justify-center">
<div class=" px-5 pt-3"> <div class=" px-6 pt-4">
<div class=" flex justify-between items-center"> <div class=" flex justify-between items-center">
<div class="flex items-center text-2xl font-semibold">Dashboard</div> <div class="flex items-center text-2xl font-semibold">Dashboard</div>
<div> <div>
<Tooltip content={$i18n.t('Admin Settings')}>
<button <button
class="flex items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 transition" class="flex items-center space-x-1 p-2 md:px-3 md:py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 transition"
type="button" type="button"
on:click={() => { on:click={() => {
showSettingsModal = !showSettingsModal; showSettingsModal = !showSettingsModal;
...@@ -124,21 +133,22 @@ ...@@ -124,21 +133,22 @@
/> />
</svg> </svg>
<div class=" text-xs">{$i18n.t('Admin Settings')}</div> <div class="hidden md:inline text-xs">{$i18n.t('Admin Settings')}</div>
</button> </button>
</Tooltip>
</div> </div>
</div> </div>
</div> </div>
<div class="px-5 flex text-sm gap-2.5"> <div class="px-6 flex text-sm gap-2.5">
<div class="py-3 border-b font-medium text-gray-100 cursor-pointer">Overview</div> <div class="py-3 border-b font-medium text-gray-100 cursor-pointer">Overview</div>
<!-- <div class="py-3 text-gray-300 cursor-pointer">Users</div> --> <!-- <div class="py-3 text-gray-300 cursor-pointer">Users</div> -->
</div> </div>
<hr class=" mb-3 dark:border-gray-800" /> <hr class=" mb-3 dark:border-gray-800" />
<div class="px-5"> <div class="px-6">
<div class="mt-0.5 mb-3 flex justify-between"> <div class="mt-0.5 mb-3 gap-1 flex flex-col md:flex-row justify-between">
<div class="flex text-lg font-medium px-0.5"> <div class="flex text-lg font-medium px-0.5">
{$i18n.t('All Users')} {$i18n.t('All Users')}
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" /> <div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" />
...@@ -147,12 +157,34 @@ ...@@ -147,12 +157,34 @@
> >
</div> </div>
<div class=""> <div class="flex gap-1">
<input <input
class=" w-60 rounded-lg py-1.5 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none" class="w-full md:w-60 rounded-xl py-1.5 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
placeholder={$i18n.t('Search')} placeholder={$i18n.t('Search')}
bind:value={search} bind:value={search}
/> />
<div>
<Tooltip content="Add User">
<button
class=" px-2 py-2 rounded-xl border border-gray-200 dark:border-gray-600 dark:border-0 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 transition font-medium text-sm flex items-center space-x-1"
on:click={() => {
showAddUserModal = !showAddUserModal;
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
d="M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z"
/>
</svg>
</button>
</Tooltip>
</div>
</div> </div>
</div> </div>
...@@ -235,6 +267,7 @@ ...@@ -235,6 +267,7 @@
<td class="px-3 py-2 text-right"> <td class="px-3 py-2 text-right">
<div class="flex justify-end w-full"> <div class="flex justify-end w-full">
{#if user.role !== 'admin'}
<Tooltip content="Chats"> <Tooltip content="Chats">
<button <button
class="self-center w-fit text-sm px-2 py-2 hover:bg-black/5 dark:hover:bg-white/5 rounded-xl" class="self-center w-fit text-sm px-2 py-2 hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
...@@ -247,7 +280,7 @@ ...@@ -247,7 +280,7 @@
</button> </button>
</Tooltip> </Tooltip>
<Tooltip content="Edit User"> <Tooltip content={$i18n.t('Edit User')}>
<button <button
class="self-center w-fit text-sm px-2 py-2 hover:bg-black/5 dark:hover:bg-white/5 rounded-xl" class="self-center w-fit text-sm px-2 py-2 hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
on:click={async () => { on:click={async () => {
...@@ -272,7 +305,7 @@ ...@@ -272,7 +305,7 @@
</button> </button>
</Tooltip> </Tooltip>
<Tooltip content="Delete User"> <Tooltip content={$i18n.t('Delete User')}>
<button <button
class="self-center w-fit text-sm px-2 py-2 hover:bg-black/5 dark:hover:bg-white/5 rounded-xl" class="self-center w-fit text-sm px-2 py-2 hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
on:click={async () => { on:click={async () => {
...@@ -295,6 +328,7 @@ ...@@ -295,6 +328,7 @@
</svg> </svg>
</button> </button>
</Tooltip> </Tooltip>
{/if}
</div> </div>
</td> </td>
</tr> </tr>
......
This diff is collapsed.
...@@ -345,7 +345,7 @@ ...@@ -345,7 +345,7 @@
// await chats.set(await getChatListByTagName(localStorage.token, tag.name)); // await chats.set(await getChatListByTagName(localStorage.token, tag.name));
}} }}
> >
<div class=" text-xs font-medium self-center line-clamp-1">{$i18n.t('add tags')}</div> <div class=" text-xs font-medium self-center line-clamp-1">add tags</div>
</button> --> </button> -->
<button <button
......
...@@ -316,7 +316,7 @@ ...@@ -316,7 +316,7 @@
</div> </div>
</div> </div>
<div class="flex flex-col gap-1 px-1 w-full"> <div class="flex flex-col gap-1 w-full">
<div class="flex w-full"> <div class="flex w-full">
<div class="overflow-hidden w-full"> <div class="overflow-hidden w-full">
<div class="max-w-full"> <div class="max-w-full">
...@@ -330,6 +330,7 @@ ...@@ -330,6 +330,7 @@
info: model info: model
}))} }))}
bind:value={selectedModelId} bind:value={selectedModelId}
className="max-w-2xl"
/> />
</div> </div>
</div> </div>
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment