Merge remote-tracking branch 'upstream/dev' into feat/add-i18n

This commit is contained in:
Ased Mammad 2024-03-06 01:25:29 +03:30
commit 25e0f0de42
26 changed files with 1445 additions and 668 deletions

View file

@ -34,12 +34,13 @@
import Sidebar from '$lib/components/layout/Sidebar.svelte';
import ShortcutsModal from '$lib/components/chat/ShortcutsModal.svelte';
import ChangelogModal from '$lib/components/ChangelogModal.svelte';
import Tooltip from '$lib/components/common/Tooltip.svelte';
const i18n = getContext('i18n');
let ollamaVersion = '';
let loaded = false;
let showShortcutsButtonElement: HTMLButtonElement;
let DB = null;
let localDBChats = [];
@ -186,7 +187,7 @@
if (isCtrlPressed && event.key === '/') {
event.preventDefault();
console.log('showShortcuts');
document.getElementById('show-shortcuts-button')?.click();
showShortcutsButtonElement.click();
}
});
@ -203,15 +204,18 @@
{#if loaded}
<div class=" hidden lg:flex fixed bottom-0 right-0 px-3 py-3 z-10">
<button
id="show-shortcuts-button"
class="text-gray-600 dark:text-gray-300 bg-gray-300/20 w-6 h-6 flex items-center justify-center text-xs rounded-full"
on:click={() => {
showShortcuts = !showShortcuts;
}}
>
?
</button>
<Tooltip content="help" placement="left">
<button
id="show-shortcuts-button"
bind:this={showShortcutsButtonElement}
class="text-gray-600 dark:text-gray-300 bg-gray-300/20 w-6 h-6 flex items-center justify-center text-xs rounded-full"
on:click={() => {
showShortcuts = !showShortcuts;
}}
>
?
</button>
</Tooltip>
</div>
<ShortcutsModal bind:show={showShortcuts} />

View file

@ -45,7 +45,7 @@
let stopResponseFlag = false;
let autoScroll = true;
let processing = '';
let messagesContainerElement: HTMLDivElement;
let currentRequestId = null;
let selectedModels = [''];
@ -143,8 +143,7 @@
};
const scrollToBottom = () => {
const element = document.getElementById('messages-container');
element.scrollTop = element.scrollHeight;
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
};
//////////////////////////
@ -837,8 +836,11 @@
<div
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0"
id="messages-container"
bind:this={messagesContainerElement}
on:scroll={(e) => {
autoScroll = e.target.scrollHeight - e.target.scrollTop <= e.target.clientHeight + 50;
autoScroll =
messagesContainerElement.scrollHeight - messagesContainerElement.scrollTop <=
messagesContainerElement.clientHeight + 50;
}}
>
<div
@ -846,10 +848,7 @@
? 'max-w-full'
: 'max-w-2xl md:px-0'} mx-auto w-full px-4"
>
<ModelSelector
bind:selectedModels
disabled={messages.length > 0 && !selectedModels.includes('')}
/>
<ModelSelector bind:selectedModels />
</div>
<div class=" h-full w-full flex flex-col py-8">

View file

@ -47,7 +47,7 @@
let stopResponseFlag = false;
let autoScroll = true;
let processing = '';
let messagesContainerElement: HTMLDivElement;
let currentRequestId = null;
// let chatId = $page.params.id;
@ -162,8 +162,7 @@
};
const scrollToBottom = () => {
const element = document.getElementById('messages-container');
element.scrollTop = element.scrollHeight;
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
};
//////////////////////////
@ -865,8 +864,11 @@
<div
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0"
id="messages-container"
bind:this={messagesContainerElement}
on:scroll={(e) => {
autoScroll = e.target.scrollHeight - e.target.scrollTop <= e.target.clientHeight + 50;
autoScroll =
messagesContainerElement.scrollHeight - messagesContainerElement.scrollTop <=
messagesContainerElement.clientHeight + 50;
}}
>
<div
@ -874,10 +876,7 @@
? 'max-w-full'
: 'max-w-2xl md:px-0'} mx-auto w-full px-4"
>
<ModelSelector
bind:selectedModels
disabled={messages.length > 0 && !selectedModels.includes('')}
/>
<ModelSelector bind:selectedModels />
</div>
<div class=" h-full w-full flex flex-col py-8">

View file

@ -24,7 +24,7 @@
let inputFiles = '';
let query = '';
let documentsImportInputElement: HTMLInputElement;
let tags = [];
let showSettingsModal = false;
@ -527,6 +527,7 @@
<div class="flex space-x-2">
<input
id="documents-import-input"
bind:this={documentsImportInputElement}
bind:files={importFiles}
type="file"
accept=".json"
@ -561,9 +562,7 @@
<button
class="flex text-xs 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 dark:text-gray-200 transition"
on:click={async () => {
document.getElementById('documents-import-input')?.click();
}}
on:click={documentsImportInputElement.click}
>
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Documents Mapping')}</div>

View file

@ -18,11 +18,14 @@
let localModelfiles = [];
let importFiles;
let modelfilesImportInputElement: HTMLInputElement;
const deleteModelHandler = async (tagName) => {
let success = null;
success = await deleteModel(localStorage.token, tagName);
success = await deleteModel(localStorage.token, tagName).catch((err) => {
toast.error(err);
return null;
});
if (success) {
toast.success($i18n.t(`Deleted {tagName}`, { tagName }));
@ -237,6 +240,7 @@
<div class="flex space-x-1">
<input
id="modelfiles-import-input"
bind:this={modelfilesImportInputElement}
bind:files={importFiles}
type="file"
accept=".json"
@ -264,9 +268,7 @@
<button
class="flex text-xs 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 dark:text-gray-200 transition"
on:click={async () => {
document.getElementById('modelfiles-import-input')?.click();
}}
on:click={modelfilesImportInputElement.click}
>
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Modelfiles')}</div>

View file

@ -1,4 +1,4 @@
<script>
<script lang="ts">
import { goto } from '$app/navigation';
import { onMount, tick, getContext } from 'svelte';
@ -23,15 +23,17 @@
let mode = 'chat';
let loaded = false;
let text = '';
let selectedModelId = '';
let loading = false;
let currentRequestId;
let currentRequestId = null;
let stopResponseFlag = false;
let messagesContainerElement: HTMLDivElement;
let textCompletionAreaElement: HTMLTextAreaElement;
let system = '';
let messages = [
{
@ -41,13 +43,7 @@
];
const scrollToBottom = () => {
let element;
if (mode === 'chat') {
element = document.getElementById('messages-container');
} else {
element = document.getElementById('text-completion-textarea');
}
const element = mode === 'chat' ? messagesContainerElement : textCompletionAreaElement;
if (element) {
element.scrollTop = element?.scrollHeight;
@ -98,6 +94,10 @@
while (true) {
const { value, done } = await reader.read();
if (done || stopResponseFlag) {
if (stopResponseFlag) {
await cancelChatCompletion(localStorage.token, currentRequestId);
}
currentRequestId = null;
break;
}
@ -114,7 +114,11 @@
let data = JSON.parse(line.replace(/^data: /, ''));
console.log(data);
text += data.choices[0].delta.content ?? '';
if ('request_id' in data) {
currentRequestId = data.request_id;
} else {
text += data.choices[0].delta.content ?? '';
}
}
}
}
@ -152,16 +156,6 @@
: `${OLLAMA_API_BASE_URL}/v1`
);
// const [res, controller] = await generateChatCompletion(localStorage.token, {
// model: selectedModelId,
// messages: [
// {
// role: 'assistant',
// content: text
// }
// ]
// });
let responseMessage;
if (messages.at(-1)?.role === 'assistant') {
responseMessage = messages.at(-1);
@ -186,6 +180,11 @@
while (true) {
const { value, done } = await reader.read();
if (done || stopResponseFlag) {
if (stopResponseFlag) {
await cancelChatCompletion(localStorage.token, currentRequestId);
}
currentRequestId = null;
break;
}
@ -202,17 +201,21 @@
let data = JSON.parse(line.replace(/^data: /, ''));
console.log(data);
if (responseMessage.content == '' && data.choices[0].delta.content == '\n') {
continue;
if ('request_id' in data) {
currentRequestId = data.request_id;
} else {
textareaElement.style.height = textareaElement.scrollHeight + 'px';
if (responseMessage.content == '' && data.choices[0].delta.content == '\n') {
continue;
} else {
textareaElement.style.height = textareaElement.scrollHeight + 'px';
responseMessage.content += data.choices[0].delta.content ?? '';
messages = messages;
responseMessage.content += data.choices[0].delta.content ?? '';
messages = messages;
textareaElement.style.height = textareaElement.scrollHeight + 'px';
textareaElement.style.height = textareaElement.scrollHeight + 'px';
await tick();
await tick();
}
}
}
}
@ -223,48 +226,6 @@
scrollToBottom();
}
// while (true) {
// const { value, done } = await reader.read();
// if (done || stopResponseFlag) {
// if (stopResponseFlag) {
// await cancelChatCompletion(localStorage.token, currentRequestId);
// }
// currentRequestId = null;
// break;
// }
// try {
// let lines = value.split('\n');
// for (const line of lines) {
// if (line !== '') {
// console.log(line);
// let data = JSON.parse(line);
// if ('detail' in data) {
// throw data;
// }
// if ('id' in data) {
// console.log(data);
// currentRequestId = data.id;
// } else {
// if (data.done == false) {
// text += data.message.content;
// } else {
// console.log('done');
// }
// }
// }
// }
// } catch (error) {
// console.log(error);
// }
// scrollToBottom();
// }
}
};
@ -422,12 +383,14 @@
<div
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0"
id="messages-container"
bind:this={messagesContainerElement}
>
<div class=" h-full w-full flex flex-col">
<div class="flex-1 p-1">
{#if mode === 'complete'}
<textarea
id="text-completion-textarea"
bind:this={textCompletionAreaElement}
class="w-full h-full p-3 bg-transparent outline outline-1 outline-gray-200 dark:outline-gray-800 resize-none rounded-lg text-sm"
bind:value={text}
placeholder={$i18n.t("You're a helpful assistant.")}

View file

@ -13,7 +13,7 @@
let importFiles = '';
let query = '';
let promptsImportInputElement: HTMLInputElement;
const sharePrompt = async (prompt) => {
toast.success($i18n.t('Redirecting you to OpenWebUI Community'));
@ -210,6 +210,7 @@
<div class="flex space-x-2">
<input
id="prompts-import-input"
bind:this={promptsImportInputElement}
bind:files={importFiles}
type="file"
accept=".json"
@ -243,9 +244,7 @@
<button
class="flex text-xs 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 dark:text-gray-200 transition"
on:click={async () => {
document.getElementById('prompts-import-input')?.click();
}}
on:click={promptsImportInputElement.click}
>
<div class=" self-center mr-2 font-medium">{$i18n.t('Import Prompts')}</div>
@ -268,7 +267,7 @@
<button
class="flex text-xs 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 dark:text-gray-200 transition"
on:click={async () => {
// document.getElementById('modelfiles-import-input')?.click();
// promptsImportInputElement.click();
let blob = new Blob([JSON.stringify($prompts)], {
type: 'application/json'
});