Unverified Commit 92d9b381 authored by Timothy Jaeryang Baek's avatar Timothy Jaeryang Baek Committed by GitHub
Browse files

Merge branch 'dev' into feat/openai-embeddings-batch

parents 0cb81633 36a66fcf
......@@ -3,6 +3,7 @@
import { user, settings } from '$lib/stores';
import { createEventDispatcher, onMount, getContext } from 'svelte';
import { toast } from 'svelte-sonner';
import Switch from '$lib/components/common/Switch.svelte';
const dispatch = createEventDispatcher();
const i18n = getContext('i18n');
......@@ -13,6 +14,7 @@
let OpenAIUrl = '';
let OpenAIKey = '';
let OpenAISpeaker = '';
let STTEngines = ['', 'openai'];
let STTEngine = '';
......@@ -20,6 +22,7 @@
let conversationMode = false;
let speechAutoSend = false;
let responseAutoPlayback = false;
let nonLocalVoices = false;
let TTSEngines = ['', 'openai'];
let TTSEngine = '';
......@@ -86,14 +89,14 @@
url: OpenAIUrl,
key: OpenAIKey,
model: model,
speaker: speaker
speaker: OpenAISpeaker
});
if (res) {
OpenAIUrl = res.OPENAI_API_BASE_URL;
OpenAIKey = res.OPENAI_API_KEY;
model = res.OPENAI_API_MODEL;
speaker = res.OPENAI_API_VOICE;
OpenAISpeaker = res.OPENAI_API_VOICE;
}
}
};
......@@ -105,6 +108,7 @@
STTEngine = $settings?.audio?.STTEngine ?? '';
TTSEngine = $settings?.audio?.TTSEngine ?? '';
nonLocalVoices = $settings.audio?.nonLocalVoices ?? false;
speaker = $settings?.audio?.speaker ?? '';
model = $settings?.audio?.model ?? '';
......@@ -122,7 +126,10 @@
OpenAIUrl = res.OPENAI_API_BASE_URL;
OpenAIKey = res.OPENAI_API_KEY;
model = res.OPENAI_API_MODEL;
speaker = res.OPENAI_API_VOICE;
OpenAISpeaker = res.OPENAI_API_VOICE;
if (TTSEngine === 'openai') {
speaker = OpenAISpeaker;
}
}
}
});
......@@ -138,8 +145,14 @@
audio: {
STTEngine: STTEngine !== '' ? STTEngine : undefined,
TTSEngine: TTSEngine !== '' ? TTSEngine : undefined,
speaker: speaker !== '' ? speaker : undefined,
model: model !== '' ? model : undefined
speaker:
(TTSEngine === 'openai' ? OpenAISpeaker : speaker) !== ''
? TTSEngine === 'openai'
? OpenAISpeaker
: speaker
: undefined,
model: model !== '' ? model : undefined,
nonLocalVoices: nonLocalVoices
}
});
dispatch('save');
......@@ -227,7 +240,7 @@
on:change={(e) => {
if (e.target.value === 'openai') {
getOpenAIVoices();
speaker = 'alloy';
OpenAISpeaker = 'alloy';
model = 'tts-1';
} else {
getWebAPIVoices();
......@@ -290,16 +303,27 @@
<select
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
bind:value={speaker}
placeholder="Select a voice"
>
<option value="" selected>{$i18n.t('Default')}</option>
{#each voices.filter((v) => v.localService === true) as voice}
<option value={voice.name} class="bg-gray-100 dark:bg-gray-700">{voice.name}</option
<option value="" selected={speaker !== ''}>{$i18n.t('Default')}</option>
{#each voices.filter((v) => nonLocalVoices || v.localService === true) as voice}
<option
value={voice.name}
class="bg-gray-100 dark:bg-gray-700"
selected={speaker === voice.name}>{voice.name}</option
>
{/each}
</select>
</div>
</div>
<div class="flex items-center justify-between mb-1">
<div class="text-sm">
{$i18n.t('Allow non-local voices')}
</div>
<div class="mt-1">
<Switch bind:state={nonLocalVoices} />
</div>
</div>
</div>
{:else if TTSEngine === 'openai'}
<div>
......@@ -309,7 +333,7 @@
<input
list="voice-list"
class="w-full rounded-lg py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
bind:value={speaker}
bind:value={OpenAISpeaker}
placeholder="Select a voice"
/>
......
<script lang="ts">
import { models, user } from '$lib/stores';
import { createEventDispatcher, onMount, getContext } from 'svelte';
import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
const dispatch = createEventDispatcher();
import {
......@@ -74,23 +74,48 @@
};
const updateOpenAIHandler = async () => {
// Check if API KEYS length is same than API URLS length
if (OPENAI_API_KEYS.length !== OPENAI_API_BASE_URLS.length) {
// if there are more keys than urls, remove the extra keys
if (OPENAI_API_KEYS.length > OPENAI_API_BASE_URLS.length) {
OPENAI_API_KEYS = OPENAI_API_KEYS.slice(0, OPENAI_API_BASE_URLS.length);
}
// if there are more urls than keys, add empty keys
if (OPENAI_API_KEYS.length < OPENAI_API_BASE_URLS.length) {
const diff = OPENAI_API_BASE_URLS.length - OPENAI_API_KEYS.length;
for (let i = 0; i < diff; i++) {
OPENAI_API_KEYS.push('');
}
}
}
OPENAI_API_BASE_URLS = await updateOpenAIUrls(localStorage.token, OPENAI_API_BASE_URLS);
OPENAI_API_KEYS = await updateOpenAIKeys(localStorage.token, OPENAI_API_KEYS);
await models.set(await getModels());
};
const updateOllamaUrlsHandler = async () => {
OLLAMA_BASE_URLS = await updateOllamaUrls(localStorage.token, OLLAMA_BASE_URLS);
OLLAMA_BASE_URLS = OLLAMA_BASE_URLS.filter((url) => url !== '');
console.log(OLLAMA_BASE_URLS);
const ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => {
toast.error(error);
return null;
});
if (OLLAMA_BASE_URLS.length === 0) {
ENABLE_OLLAMA_API = false;
await updateOllamaConfig(localStorage.token, ENABLE_OLLAMA_API);
if (ollamaVersion) {
toast.success($i18n.t('Server connection verified'));
await models.set(await getModels());
toast.info($i18n.t('Ollama API disabled'));
} else {
OLLAMA_BASE_URLS = await updateOllamaUrls(localStorage.token, OLLAMA_BASE_URLS);
const ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => {
toast.error(error);
return null;
});
if (ollamaVersion) {
toast.success($i18n.t('Server connection verified'));
await models.set(await getModels());
}
}
};
......@@ -286,6 +311,10 @@
bind:state={ENABLE_OLLAMA_API}
on:change={async () => {
updateOllamaConfig(localStorage.token, ENABLE_OLLAMA_API);
if (OLLAMA_BASE_URLS.length === 0) {
OLLAMA_BASE_URLS = [''];
}
}}
/>
</div>
......
<script lang="ts">
export let className = 'size-4';
export let strokeWidth = '1.5';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3"
/>
</svg>
......@@ -63,6 +63,13 @@
// Revoke the URL to release memory
window.URL.revokeObjectURL(url);
};
const downloadJSONExport = async () => {
let blob = new Blob([JSON.stringify([chat])], {
type: 'application/json'
});
saveAs(blob, `chat-export-${Date.now()}.json`);
};
</script>
<Dropdown
......@@ -164,6 +171,14 @@
transition={flyAndScale}
sideOffset={8}
>
<DropdownMenu.Item
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
on:click={() => {
downloadJSONExport();
}}
>
<div class="flex items-center line-clamp-1">{$i18n.t('Export chat (.json)')}</div>
</DropdownMenu.Item>
<DropdownMenu.Item
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
on:click={() => {
......
......@@ -205,6 +205,10 @@
await archiveChatById(localStorage.token, id);
await chats.set(await getChatList(localStorage.token));
};
const focusEdit = async (node: HTMLInputElement) => {
node.focus();
};
</script>
<ShareChatModal bind:show={showShareChatModal} chatId={shareChatId} />
......@@ -489,7 +493,11 @@
? 'bg-gray-100 dark:bg-gray-950'
: 'group-hover:bg-gray-100 dark:group-hover:bg-gray-950'} whitespace-nowrap text-ellipsis"
>
<input bind:value={chatTitle} class=" bg-transparent w-full outline-none mr-10" />
<input
use:focusEdit
bind:value={chatTitle}
class=" bg-transparent w-full outline-none mr-10"
/>
</div>
{:else}
<a
......@@ -507,6 +515,10 @@
showSidebar.set(false);
}
}}
on:dblclick={() => {
chatTitle = chat.title;
chatTitleEditId = chat.id;
}}
draggable="false"
>
<div class=" flex self-center flex-1 w-full">
......
......@@ -8,7 +8,12 @@
const dispatch = createEventDispatcher();
import Modal from '$lib/components/common/Modal.svelte';
import { archiveChatById, deleteChatById, getArchivedChatList } from '$lib/apis/chats';
import {
archiveChatById,
deleteChatById,
getAllArchivedChats,
getArchivedChatList
} from '$lib/apis/chats';
import Tooltip from '$lib/components/common/Tooltip.svelte';
const i18n = getContext('i18n');
......@@ -38,6 +43,7 @@
};
const exportChatsHandler = async () => {
const chats = await getAllArchivedChats(localStorage.token);
let blob = new Blob([JSON.stringify(chats)], {
type: 'application/json'
});
......
......@@ -126,6 +126,13 @@
saveAs(blob, `models-export-${Date.now()}.json`);
};
const exportModelHandler = async (model) => {
let blob = new Blob([JSON.stringify([model])], {
type: 'application/json'
});
saveAs(blob, `${model.id}-${Date.now()}.json`);
};
const positionChangeHanlder = async () => {
// Get the new order of the models
const modelIds = Array.from(document.getElementById('model-list').children).map((child) =>
......@@ -322,6 +329,9 @@
cloneHandler={() => {
cloneModelHandler(model);
}}
exportHandler={() => {
exportModelHandler(model);
}}
hideHandler={() => {
hideModelHandler(model);
}}
......
......@@ -11,6 +11,7 @@
import Share from '$lib/components/icons/Share.svelte';
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
const i18n = getContext('i18n');
......@@ -18,6 +19,8 @@
export let shareHandler: Function;
export let cloneHandler: Function;
export let exportHandler: Function;
export let hideHandler: Function;
export let deleteHandler: Function;
export let onClose: Function;
......@@ -66,6 +69,17 @@
<div class="flex items-center">{$i18n.t('Clone')}</div>
</DropdownMenu.Item>
<DropdownMenu.Item
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
on:click={() => {
exportHandler();
}}
>
<ArrowDownTray />
<div class="flex items-center">{$i18n.t('Export')}</div>
</DropdownMenu.Item>
<DropdownMenu.Item
class="flex gap-2 items-center px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
on:click={() => {
......
......@@ -8,7 +8,7 @@
import { OLLAMA_API_BASE_URL, OPENAI_API_BASE_URL, WEBUI_API_BASE_URL } from '$lib/constants';
import { WEBUI_NAME, config, user, models, settings } from '$lib/stores';
import { cancelOllamaRequest, generateChatCompletion } from '$lib/apis/ollama';
import { generateChatCompletion } from '$lib/apis/ollama';
import { generateOpenAIChatCompletion } from '$lib/apis/openai';
import { splitStream } from '$lib/utils';
......@@ -24,7 +24,6 @@
let selectedModelId = '';
let loading = false;
let currentRequestId = null;
let stopResponseFlag = false;
let messagesContainerElement: HTMLDivElement;
......@@ -46,14 +45,6 @@
}
};
// const cancelHandler = async () => {
// if (currentRequestId) {
// const res = await cancelOllamaRequest(localStorage.token, currentRequestId);
// currentRequestId = null;
// loading = false;
// }
// };
const stopResponse = () => {
stopResponseFlag = true;
console.log('stopResponse');
......@@ -171,8 +162,6 @@
if (stopResponseFlag) {
controller.abort('User: Stop Response');
}
currentRequestId = null;
break;
}
......@@ -229,7 +218,6 @@
loading = false;
stopResponseFlag = false;
currentRequestId = null;
}
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -37,6 +37,7 @@
"All Users": "Ang tanan nga mga tiggamit",
"Allow": "Sa pagtugot",
"Allow Chat Deletion": "Tugoti nga mapapas ang mga chat",
"Allow non-local voices": "",
"alphanumeric characters and hyphens": "alphanumeric nga mga karakter ug hyphen",
"Already have an account?": "Naa na kay account ?",
"an assistant": "usa ka katabang",
......@@ -205,7 +206,9 @@
"Enter Your Role": "",
"Error": "",
"Experimental": "Eksperimento",
"Export": "",
"Export All Chats (All Users)": "I-export ang tanan nga mga chat (Tanan nga tiggamit)",
"Export chat (.json)": "",
"Export Chats": "I-export ang mga chat",
"Export Documents Mapping": "I-export ang pagmapa sa dokumento",
"Export Models": "",
......@@ -312,12 +315,14 @@
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "",
"Notifications": "Mga pahibalo sa desktop",
"November": "",
"num_thread (Ollama)": "",
"October": "",
"Off": "Napuo",
"Okay, Let's Go!": "Okay, lakaw na!",
"OLED Dark": "",
"Ollama": "",
"Ollama API": "",
"Ollama API disabled": "",
"Ollama Version": "Ollama nga bersyon",
"On": "Gipaandar",
"Only": "Lamang",
......@@ -494,6 +499,8 @@
"Use '#' in the prompt input to load and select your documents.": "Gamita ang '#' sa dali nga pagsulod aron makarga ug mapili ang imong mga dokumento.",
"Use Gravatar": "Paggamit sa Gravatar",
"Use Initials": "",
"use_mlock (Ollama)": "",
"use_mmap (Ollama)": "",
"user": "tiggamit",
"User Permissions": "Mga permiso sa tiggamit",
"Users": "Mga tiggamit",
......
This diff is collapsed.
......@@ -37,6 +37,7 @@
"All Users": "All Users",
"Allow": "Allow",
"Allow Chat Deletion": "Allow Delete Chats",
"Allow non-local voices": "",
"alphanumeric characters and hyphens": "so alpha, many hyphen",
"Already have an account?": "Such account exists?",
"an assistant": "such assistant",
......@@ -205,7 +206,9 @@
"Enter Your Role": "",
"Error": "",
"Experimental": "Much Experiment",
"Export": "",
"Export All Chats (All Users)": "Export All Chats (All Doggos)",
"Export chat (.json)": "",
"Export Chats": "Export Barks",
"Export Documents Mapping": "Export Mappings of Dogos",
"Export Models": "",
......@@ -312,12 +315,14 @@
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "",
"Notifications": "Notifications",
"November": "",
"num_thread (Ollama)": "",
"October": "",
"Off": "Off",
"Okay, Let's Go!": "Okay, Let's Go!",
"OLED Dark": "OLED Dark",
"Ollama": "",
"Ollama API": "",
"Ollama API disabled": "",
"Ollama Version": "Ollama Version",
"On": "On",
"Only": "Only",
......@@ -494,6 +499,8 @@
"Use '#' in the prompt input to load and select your documents.": "Use '#' in the prompt input to load and select your documents. Much use.",
"Use Gravatar": "Use Gravatar much avatar",
"Use Initials": "Use Initials much initial",
"use_mlock (Ollama)": "",
"use_mmap (Ollama)": "",
"user": "user much user",
"User Permissions": "User Permissions much permissions",
"Users": "Users much users",
......
......@@ -37,6 +37,7 @@
"All Users": "",
"Allow": "",
"Allow Chat Deletion": "",
"Allow non-local voices": "",
"alphanumeric characters and hyphens": "",
"Already have an account?": "",
"an assistant": "",
......@@ -205,7 +206,9 @@
"Enter Your Role": "",
"Error": "",
"Experimental": "",
"Export": "",
"Export All Chats (All Users)": "",
"Export chat (.json)": "",
"Export Chats": "",
"Export Documents Mapping": "",
"Export Models": "",
......@@ -312,12 +315,14 @@
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "",
"Notifications": "",
"November": "",
"num_thread (Ollama)": "",
"October": "",
"Off": "",
"Okay, Let's Go!": "",
"OLED Dark": "",
"Ollama": "",
"Ollama API": "",
"Ollama API disabled": "",
"Ollama Version": "",
"On": "",
"Only": "",
......@@ -494,6 +499,8 @@
"Use '#' in the prompt input to load and select your documents.": "",
"Use Gravatar": "",
"Use Initials": "",
"use_mlock (Ollama)": "",
"use_mmap (Ollama)": "",
"user": "",
"User Permissions": "",
"Users": "",
......
......@@ -37,6 +37,7 @@
"All Users": "",
"Allow": "",
"Allow Chat Deletion": "",
"Allow non-local voices": "",
"alphanumeric characters and hyphens": "",
"Already have an account?": "",
"an assistant": "",
......@@ -205,7 +206,9 @@
"Enter Your Role": "",
"Error": "",
"Experimental": "",
"Export": "",
"Export All Chats (All Users)": "",
"Export chat (.json)": "",
"Export Chats": "",
"Export Documents Mapping": "",
"Export Models": "",
......@@ -312,12 +315,14 @@
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "",
"Notifications": "",
"November": "",
"num_thread (Ollama)": "",
"October": "",
"Off": "",
"Okay, Let's Go!": "",
"OLED Dark": "",
"Ollama": "",
"Ollama API": "",
"Ollama API disabled": "",
"Ollama Version": "",
"On": "",
"Only": "",
......@@ -494,6 +499,8 @@
"Use '#' in the prompt input to load and select your documents.": "",
"Use Gravatar": "",
"Use Initials": "",
"use_mlock (Ollama)": "",
"use_mmap (Ollama)": "",
"user": "",
"User Permissions": "",
"Users": "",
......
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