diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index e45a8316..259f0c5f 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -29,11 +29,11 @@ jobs: - name: Extract latest CHANGELOG entry id: changelog run: | - CHANGELOG_CONTENT=$(awk '/^## \[/{n++} n==1' CHANGELOG.md) - echo "CHANGELOG_CONTENT< { +export const getImageGenerationConfig = async (token: string = '') => { let error = null; - const res = await fetch(`${IMAGES_API_BASE_URL}/enabled`, { + const res = await fetch(`${IMAGES_API_BASE_URL}/config`, { method: 'GET', headers: { Accept: 'application/json', @@ -32,10 +32,50 @@ export const getImageGenerationEnabledStatus = async (token: string = '') => { return res; }; -export const toggleImageGenerationEnabledStatus = async (token: string = '') => { +export const updateImageGenerationConfig = async ( + token: string = '', + engine: string, + enabled: boolean +) => { let error = null; - const res = await fetch(`${IMAGES_API_BASE_URL}/enabled/toggle`, { + const res = await fetch(`${IMAGES_API_BASE_URL}/config/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + engine, + enabled + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getOpenAIKey = async (token: string = '') => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/key`, { method: 'GET', headers: { Accept: 'application/json', @@ -61,7 +101,42 @@ export const toggleImageGenerationEnabledStatus = async (token: string = '') => throw error; } - return res; + return res.OPENAI_API_KEY; +}; + +export const updateOpenAIKey = async (token: string = '', key: string) => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/key/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + key: key + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.OPENAI_API_KEY; }; export const getAUTOMATIC1111Url = async (token: string = '') => { @@ -263,7 +338,7 @@ export const updateImageSteps = async (token: string = '', steps: number) => { return res.IMAGE_STEPS; }; -export const getDiffusionModels = async (token: string = '') => { +export const getImageGenerationModels = async (token: string = '') => { let error = null; const res = await fetch(`${IMAGES_API_BASE_URL}/models`, { @@ -295,7 +370,7 @@ export const getDiffusionModels = async (token: string = '') => { return res; }; -export const getDefaultDiffusionModel = async (token: string = '') => { +export const getDefaultImageGenerationModel = async (token: string = '') => { let error = null; const res = await fetch(`${IMAGES_API_BASE_URL}/models/default`, { @@ -327,7 +402,7 @@ export const getDefaultDiffusionModel = async (token: string = '') => { return res.model; }; -export const updateDefaultDiffusionModel = async (token: string = '', model: string) => { +export const updateDefaultImageGenerationModel = async (token: string = '', model: string) => { let error = null; const res = await fetch(`${IMAGES_API_BASE_URL}/models/default/update`, { diff --git a/src/lib/apis/index.ts b/src/lib/apis/index.ts index b7b346c0..b33fb571 100644 --- a/src/lib/apis/index.ts +++ b/src/lib/apis/index.ts @@ -77,3 +77,65 @@ export const getVersionUpdates = async () => { return res; }; + +export const getModelFilterConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/config/model/filter`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateModelFilterConfig = async ( + token: string, + enabled: boolean, + models: string[] +) => { + let error = null; + + const res = await fetch(`${WEBUI_BASE_URL}/api/config/model/filter`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + enabled: enabled, + models: models + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/litellm/index.ts b/src/lib/apis/litellm/index.ts index 6466ee35..302e9c4a 100644 --- a/src/lib/apis/litellm/index.ts +++ b/src/lib/apis/litellm/index.ts @@ -77,6 +77,7 @@ type AddLiteLLMModelForm = { api_base: string; api_key: string; rpm: string; + max_tokens: string; }; export const addLiteLLMModel = async (token: string = '', payload: AddLiteLLMModelForm) => { @@ -95,7 +96,8 @@ export const addLiteLLMModel = async (token: string = '', payload: AddLiteLLMMod model: payload.model, ...(payload.api_base === '' ? {} : { api_base: payload.api_base }), ...(payload.api_key === '' ? {} : { api_key: payload.api_key }), - ...(isNaN(parseInt(payload.rpm)) ? {} : { rpm: parseInt(payload.rpm) }) + ...(isNaN(parseInt(payload.rpm)) ? {} : { rpm: parseInt(payload.rpm) }), + ...(payload.max_tokens === '' ? {} : { max_tokens: payload.max_tokens }) } }) }) diff --git a/src/lib/apis/rag/index.ts b/src/lib/apis/rag/index.ts index 4e8e9b14..668fe227 100644 --- a/src/lib/apis/rag/index.ts +++ b/src/lib/apis/rag/index.ts @@ -1,9 +1,9 @@ import { RAG_API_BASE_URL } from '$lib/constants'; -export const getChunkParams = async (token: string) => { +export const getRAGConfig = async (token: string) => { let error = null; - const res = await fetch(`${RAG_API_BASE_URL}/chunk`, { + const res = await fetch(`${RAG_API_BASE_URL}/config`, { method: 'GET', headers: { 'Content-Type': 'application/json', @@ -27,18 +27,27 @@ export const getChunkParams = async (token: string) => { return res; }; -export const updateChunkParams = async (token: string, size: number, overlap: number) => { +type ChunkConfigForm = { + chunk_size: number; + chunk_overlap: number; +}; + +type RAGConfigForm = { + pdf_extract_images: boolean; + chunk: ChunkConfigForm; +}; + +export const updateRAGConfig = async (token: string, payload: RAGConfigForm) => { let error = null; - const res = await fetch(`${RAG_API_BASE_URL}/chunk/update`, { + const res = await fetch(`${RAG_API_BASE_URL}/config/update`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, body: JSON.stringify({ - chunk_size: size, - chunk_overlap: overlap + ...payload }) }) .then(async (res) => { @@ -252,7 +261,7 @@ export const queryCollection = async ( token: string, collection_names: string, query: string, - k: number + k: number | null = null ) => { let error = null; diff --git a/src/lib/components/admin/Settings/Users.svelte b/src/lib/components/admin/Settings/Users.svelte index 8a442c51..9f2b5c40 100644 --- a/src/lib/components/admin/Settings/Users.svelte +++ b/src/lib/components/admin/Settings/Users.svelte @@ -1,10 +1,14 @@ @@ -21,6 +32,8 @@ on:submit|preventDefault={async () => { // console.log('submit'); await updateUserPermissions(localStorage.token, permissions); + + await updateModelFilterConfig(localStorage.token, whitelistEnabled, whitelistModels); saveHandler(); }} > @@ -69,6 +82,106 @@ + +
+ +
+
+
+
+
Manage Models
+
+
+ +
+
+
+
Model Whitelisting
+ + +
+
+ + {#if whitelistEnabled} +
+
+ {#each whitelistModels as modelId, modelIdx} +
+
+ +
+ + {#if modelIdx === 0} + + {:else} + + {/if} +
+ {/each} +
+ +
+
+ {whitelistModels.length} Model(s) Whitelisted +
+
+
+ {/if} +
+
+
diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 5a7e8a05..036e089f 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -19,7 +19,7 @@ export let suggestionPrompts = []; export let autoScroll = true; - let chatTextAreaElement:HTMLTextAreaElement + let chatTextAreaElement: HTMLTextAreaElement; let filesInputElement; let promptsElement; @@ -359,12 +359,12 @@ {#if dragged}
-
+
diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 6e29a4ca..3f6c7739 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -6,6 +6,7 @@ import auto_render from 'katex/dist/contrib/auto-render.mjs'; import 'katex/dist/katex.min.css'; + import { fade } from 'svelte/transition'; import { createEventDispatcher } from 'svelte'; import { onMount, tick } from 'svelte'; @@ -276,13 +277,15 @@ const generateImage = async (message) => { generatingImage = true; - const res = await imageGenerations(localStorage.token, message.content); + const res = await imageGenerations(localStorage.token, message.content).catch((error) => { + toast.error(error); + }); console.log(res); if (res) { - message.files = res.images.map((image) => ({ + message.files = res.map((image) => ({ type: 'image', - url: `data:image/png;base64,${image}` + url: `${image.url}` })); dispatch('save', message); @@ -477,7 +480,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -503,7 +506,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -622,7 +625,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -637,7 +640,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -703,7 +706,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -733,7 +736,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -762,7 +765,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -792,7 +795,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > diff --git a/src/lib/components/chat/Messages/UserMessage.svelte b/src/lib/components/chat/Messages/UserMessage.svelte index 45ae52b4..118dbfb6 100644 --- a/src/lib/components/chat/Messages/UserMessage.svelte +++ b/src/lib/components/chat/Messages/UserMessage.svelte @@ -258,7 +258,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -282,7 +282,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > @@ -307,7 +307,7 @@ xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" - stroke-width="1.5" + stroke-width="2" stroke="currentColor" class="w-4 h-4" > diff --git a/src/lib/components/chat/Settings/Account.svelte b/src/lib/components/chat/Settings/Account.svelte index 8aceae18..cc41bde6 100644 --- a/src/lib/components/chat/Settings/Account.svelte +++ b/src/lib/components/chat/Settings/Account.svelte @@ -271,7 +271,7 @@