wip: direct models

This commit is contained in:
Timothy Jaeryang Baek 2025-02-12 01:17:30 -08:00
parent 982b1fb7e2
commit 431e97b03a
20 changed files with 194 additions and 61 deletions

View File

@ -1,6 +1,11 @@
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import { getOpenAIModelsDirect } from './openai';
export const getModels = async (token: string = '', base: boolean = false) => { export const getModels = async (
token: string = '',
connections: object | null = null,
base: boolean = false
) => {
let error = null; let error = null;
const res = await fetch(`${WEBUI_BASE_URL}/api/models${base ? '/base' : ''}`, { const res = await fetch(`${WEBUI_BASE_URL}/api/models${base ? '/base' : ''}`, {
method: 'GET', method: 'GET',
@ -25,6 +30,76 @@ export const getModels = async (token: string = '', base: boolean = false) => {
} }
let models = res?.data ?? []; let models = res?.data ?? [];
if (connections && !base) {
let localModels = [];
if (connections) {
const OPENAI_API_BASE_URLS = connections.OPENAI_API_BASE_URLS;
const OPENAI_API_KEYS = connections.OPENAI_API_KEYS;
const OPENAI_API_CONFIGS = connections.OPENAI_API_CONFIGS;
const requests = [];
for (const idx in OPENAI_API_BASE_URLS) {
const url = OPENAI_API_BASE_URLS[idx];
if (idx.toString() in OPENAI_API_CONFIGS) {
const apiConfig = OPENAI_API_CONFIGS[idx.toString()] ?? {};
const enable = apiConfig?.enable ?? true;
const modelIds = apiConfig?.model_ids ?? [];
if (enable) {
if (modelIds.length > 0) {
const modelList = {
object: 'list',
data: modelIds.map((modelId) => ({
id: modelId,
name: modelId,
owned_by: 'openai',
openai: { id: modelId },
urlIdx: idx
}))
};
requests.push(() => modelList);
} else {
requests.push(getOpenAIModelsDirect(url, OPENAI_API_KEYS[idx]));
}
} else {
requests.push(() => {});
}
}
}
const responses = await Promise.all(requests);
for (const idx in responses) {
const response = responses[idx];
const apiConfig = OPENAI_API_CONFIGS[idx.toString()] ?? {};
let models = Array.isArray(response) ? response : (response?.data ?? []);
models = models.map((model) => ({ ...model, openai: { id: model.id }, urlIdx: idx }));
const prefixId = apiConfig.prefix_id;
if (prefixId) {
for (const model of models) {
model.id = `${prefixId}.${model.id}`;
}
}
localModels = localModels.concat(models);
}
}
models = models.concat(
localModels.map((model) => ({
...model,
name: model?.name ?? model?.id,
direct: true
}))
);
}
return models; return models;
}; };

View File

@ -208,6 +208,33 @@ export const updateOpenAIKeys = async (token: string = '', keys: string[]) => {
return res.OPENAI_API_KEYS; return res.OPENAI_API_KEYS;
}; };
export const getOpenAIModelsDirect = async (url: string, key: string) => {
let error = null;
const res = await fetch(`${url}/models`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(key && { authorization: `Bearer ${key}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.catch((err) => {
error = `OpenAI: ${err?.error?.message ?? 'Network Problem'}`;
return [];
});
if (error) {
throw error;
}
return res;
};
export const getOpenAIModels = async (token: string, urlIdx?: number) => { export const getOpenAIModels = async (token: string, urlIdx?: number) => {
let error = null; let error = null;

View File

@ -3,7 +3,7 @@
import fileSaver from 'file-saver'; import fileSaver from 'file-saver';
const { saveAs } = fileSaver; const { saveAs } = fileSaver;
import { WEBUI_NAME, config, functions, models } from '$lib/stores'; import { WEBUI_NAME, config, functions, models, settings } from '$lib/stores';
import { onMount, getContext, tick } from 'svelte'; import { onMount, getContext, tick } from 'svelte';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
@ -126,7 +126,7 @@
toast.success($i18n.t('Function deleted successfully')); toast.success($i18n.t('Function deleted successfully'));
functions.set(await getFunctions(localStorage.token)); functions.set(await getFunctions(localStorage.token));
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} }
}; };
@ -147,7 +147,7 @@
} }
functions.set(await getFunctions(localStorage.token)); functions.set(await getFunctions(localStorage.token));
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} }
}; };
@ -359,7 +359,9 @@
bind:state={func.is_active} bind:state={func.is_active}
on:change={async (e) => { on:change={async (e) => {
toggleFunctionById(localStorage.token, func.id); toggleFunctionById(localStorage.token, func.id);
models.set(await getModels(localStorage.token)); models.set(
await getModels(localStorage.token, $settings?.directConnections ?? null)
);
}} }}
/> />
</Tooltip> </Tooltip>
@ -496,7 +498,7 @@
id={selectedFunction?.id ?? null} id={selectedFunction?.id ?? null}
on:save={async () => { on:save={async () => {
await tick(); await tick();
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
}} }}
/> />
@ -517,7 +519,7 @@
toast.success($i18n.t('Functions imported successfully')); toast.success($i18n.t('Functions imported successfully'));
functions.set(await getFunctions(localStorage.token)); functions.set(await getFunctions(localStorage.token));
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
}; };
reader.readAsText(importFiles[0]); reader.readAsText(importFiles[0]);

View File

@ -10,7 +10,7 @@
getModels as _getModels, getModels as _getModels,
getVoices as _getVoices getVoices as _getVoices
} from '$lib/apis/audio'; } from '$lib/apis/audio';
import { config } from '$lib/stores'; import { config, settings } from '$lib/stores';
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte'; import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
@ -51,9 +51,11 @@
if (TTS_ENGINE === '') { if (TTS_ENGINE === '') {
models = []; models = [];
} else { } else {
const res = await _getModels(localStorage.token).catch((e) => { const res = await _getModels(localStorage.token, $settings?.directConnections ?? null).catch(
toast.error(`${e}`); (e) => {
}); toast.error(`${e}`);
}
);
if (res) { if (res) {
console.log(res); console.log(res);

View File

@ -9,7 +9,7 @@
import { getModels as _getModels } from '$lib/apis'; import { getModels as _getModels } from '$lib/apis';
import { getDirectConnectionsConfig, setDirectConnectionsConfig } from '$lib/apis/configs'; import { getDirectConnectionsConfig, setDirectConnectionsConfig } from '$lib/apis/configs';
import { models, user } from '$lib/stores'; import { models, settings, user } from '$lib/stores';
import Switch from '$lib/components/common/Switch.svelte'; import Switch from '$lib/components/common/Switch.svelte';
import Spinner from '$lib/components/common/Spinner.svelte'; import Spinner from '$lib/components/common/Spinner.svelte';
@ -23,7 +23,7 @@
const i18n = getContext('i18n'); const i18n = getContext('i18n');
const getModels = async () => { const getModels = async () => {
const models = await _getModels(localStorage.token); const models = await _getModels(localStorage.token, $settings?.directConnections ?? null);
return models; return models;
}; };

View File

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { models, user } from '$lib/stores'; import { models, settings, user } from '$lib/stores';
import { createEventDispatcher, onMount, getContext, tick } from 'svelte'; import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
@ -27,7 +27,7 @@
if (config) { if (config) {
toast.success('Settings saved successfully'); toast.success('Settings saved successfully');
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} }
}; };
@ -36,7 +36,7 @@
config.EVALUATION_ARENA_MODELS = [...config.EVALUATION_ARENA_MODELS]; config.EVALUATION_ARENA_MODELS = [...config.EVALUATION_ARENA_MODELS];
await submitHandler(); await submitHandler();
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
}; };
const editModelHandler = async (model, modelIdx) => { const editModelHandler = async (model, modelIdx) => {
@ -44,7 +44,7 @@
config.EVALUATION_ARENA_MODELS = [...config.EVALUATION_ARENA_MODELS]; config.EVALUATION_ARENA_MODELS = [...config.EVALUATION_ARENA_MODELS];
await submitHandler(); await submitHandler();
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
}; };
const deleteModelHandler = async (modelIdx) => { const deleteModelHandler = async (modelIdx) => {
@ -53,7 +53,7 @@
); );
await submitHandler(); await submitHandler();
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
}; };
onMount(async () => { onMount(async () => {

View File

@ -68,7 +68,7 @@
const init = async () => { const init = async () => {
workspaceModels = await getBaseModels(localStorage.token); workspaceModels = await getBaseModels(localStorage.token);
baseModels = await getModels(localStorage.token, true); baseModels = await getModels(localStorage.token, null, true);
models = baseModels.map((m) => { models = baseModels.map((m) => {
const workspaceModel = workspaceModels.find((wm) => wm.id === m.id); const workspaceModel = workspaceModels.find((wm) => wm.id === m.id);
@ -111,7 +111,7 @@
} }
} }
_models.set(await getModels(localStorage.token)); _models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
await init(); await init();
}; };
@ -133,7 +133,7 @@
} }
// await init(); // await init();
_models.set(await getModels(localStorage.token)); _models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
}; };
onMount(async () => { onMount(async () => {
@ -330,7 +330,9 @@
} }
} }
await _models.set(await getModels(localStorage.token)); await _models.set(
await getModels(localStorage.token, $settings?.directConnections ?? null)
);
init(); init();
}; };

View File

@ -3,7 +3,7 @@
import { getContext, onMount } from 'svelte'; import { getContext, onMount } from 'svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
import { WEBUI_NAME, models, MODEL_DOWNLOAD_POOL, user, config } from '$lib/stores'; import { WEBUI_NAME, models, MODEL_DOWNLOAD_POOL, user, config, settings } from '$lib/stores';
import { splitStream } from '$lib/utils'; import { splitStream } from '$lib/utils';
import { import {
@ -235,7 +235,7 @@
}) })
); );
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} else { } else {
toast.error($i18n.t('Download canceled')); toast.error($i18n.t('Download canceled'));
} }
@ -394,7 +394,7 @@
modelTransferring = false; modelTransferring = false;
uploadProgress = null; uploadProgress = null;
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
}; };
const deleteModelHandler = async () => { const deleteModelHandler = async () => {
@ -407,7 +407,7 @@
} }
deleteModelTag = ''; deleteModelTag = '';
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
}; };
const cancelModelPullHandler = async (model: string) => { const cancelModelPullHandler = async (model: string) => {
@ -506,7 +506,7 @@
} }
} }
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
createModelLoading = false; createModelLoading = false;

View File

@ -2,7 +2,7 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { models } from '$lib/stores'; import { models, settings } from '$lib/stores';
import { getContext, onMount, tick } from 'svelte'; import { getContext, onMount, tick } from 'svelte';
import type { Writable } from 'svelte/store'; import type { Writable } from 'svelte/store';
import type { i18n as i18nType } from 'i18next'; import type { i18n as i18nType } from 'i18next';
@ -63,7 +63,7 @@
if (res) { if (res) {
toast.success($i18n.t('Valves updated successfully')); toast.success($i18n.t('Valves updated successfully'));
setPipelines(); setPipelines();
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
saveHandler(); saveHandler();
} }
} else { } else {
@ -125,7 +125,7 @@
if (res) { if (res) {
toast.success($i18n.t('Pipeline downloaded successfully')); toast.success($i18n.t('Pipeline downloaded successfully'));
setPipelines(); setPipelines();
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} }
downloading = false; downloading = false;
@ -150,7 +150,7 @@
if (res) { if (res) {
toast.success($i18n.t('Pipeline downloaded successfully')); toast.success($i18n.t('Pipeline downloaded successfully'));
setPipelines(); setPipelines();
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} }
} else { } else {
toast.error($i18n.t('No file selected')); toast.error($i18n.t('No file selected'));
@ -179,7 +179,7 @@
if (res) { if (res) {
toast.success($i18n.t('Pipeline deleted successfully')); toast.success($i18n.t('Pipeline deleted successfully'));
setPipelines(); setPipelines();
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} }
}; };

View File

@ -12,7 +12,14 @@
import { deleteModel, getOllamaVersion, pullModel } from '$lib/apis/ollama'; import { deleteModel, getOllamaVersion, pullModel } from '$lib/apis/ollama';
import { user, MODEL_DOWNLOAD_POOL, models, mobile, temporaryChatEnabled } from '$lib/stores'; import {
user,
MODEL_DOWNLOAD_POOL,
models,
mobile,
temporaryChatEnabled,
settings
} from '$lib/stores';
import { toast } from 'svelte-sonner'; import { toast } from 'svelte-sonner';
import { capitalizeFirstLetter, sanitizeResponseContent, splitStream } from '$lib/utils'; import { capitalizeFirstLetter, sanitizeResponseContent, splitStream } from '$lib/utils';
import { getModels } from '$lib/apis'; import { getModels } from '$lib/apis';
@ -186,7 +193,7 @@
}) })
); );
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} else { } else {
toast.error($i18n.t('Download canceled')); toast.error($i18n.t('Download canceled'));
} }
@ -358,7 +365,24 @@
<!-- {JSON.stringify(item.info)} --> <!-- {JSON.stringify(item.info)} -->
{#if item.model.owned_by === 'openai'} {#if item.model?.direct}
<Tooltip content={`${'Direct'}`}>
<div class="translate-y-[1px]">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="size-3"
>
<path
fill-rule="evenodd"
d="M2 2.75A.75.75 0 0 1 2.75 2C8.963 2 14 7.037 14 13.25a.75.75 0 0 1-1.5 0c0-5.385-4.365-9.75-9.75-9.75A.75.75 0 0 1 2 2.75Zm0 4.5a.75.75 0 0 1 .75-.75 6.75 6.75 0 0 1 6.75 6.75.75.75 0 0 1-1.5 0C8 10.35 5.65 8 2.75 8A.75.75 0 0 1 2 7.25ZM3.5 11a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z"
clip-rule="evenodd"
/>
</svg>
</div>
</Tooltip>
{:else if item.model.owned_by === 'openai'}
<Tooltip content={`${'External'}`}> <Tooltip content={`${'External'}`}>
<div class="translate-y-[1px]"> <div class="translate-y-[1px]">
<svg <svg

View File

@ -58,14 +58,6 @@
}); });
}; };
const submitHandler = async () => {
await updateHandler();
await saveSettings({
directConnections: config
});
};
onMount(async () => { onMount(async () => {
config = $settings?.directConnections ?? { config = $settings?.directConnections ?? {
OPENAI_API_BASE_URLS: [], OPENAI_API_BASE_URLS: [],
@ -77,7 +69,12 @@
<AddConnectionModal direct bind:show={showConnectionModal} onSubmit={addConnectionHandler} /> <AddConnectionModal direct bind:show={showConnectionModal} onSubmit={addConnectionHandler} />
<form class="flex flex-col h-full justify-between text-sm" on:submit|preventDefault={submitHandler}> <form
class="flex flex-col h-full justify-between text-sm"
on:submit|preventDefault={() => {
updateHandler();
}}
>
<div class=" overflow-y-scroll scrollbar-hidden h-full"> <div class=" overflow-y-scroll scrollbar-hidden h-full">
{#if config !== null} {#if config !== null}
<div class=""> <div class="">

View File

@ -322,7 +322,7 @@
}; };
const getModels = async () => { const getModels = async () => {
return await _getModels(localStorage.token); return await _getModels(localStorage.token, $settings?.directConnections ?? null);
}; };
let selectedTab = 'general'; let selectedTab = 'general';
@ -654,8 +654,8 @@
/> />
{:else if selectedTab === 'connections'} {:else if selectedTab === 'connections'}
<Connections <Connections
{saveSettings} saveSettings={async (updated) => {
on:save={() => { await saveSettings(updated);
toast.success($i18n.t('Settings saved successfully!')); toast.success($i18n.t('Settings saved successfully!'));
}} }}
/> />

View File

@ -68,7 +68,7 @@
toast.success($i18n.t(`Deleted {{name}}`, { name: model.id })); toast.success($i18n.t(`Deleted {{name}}`, { name: model.id }));
} }
await _models.set(await getModels(localStorage.token)); await _models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
models = await getWorkspaceModels(localStorage.token); models = await getWorkspaceModels(localStorage.token);
}; };
@ -134,7 +134,7 @@
); );
} }
await _models.set(await getModels(localStorage.token)); await _models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
models = await getWorkspaceModels(localStorage.token); models = await getWorkspaceModels(localStorage.token);
}; };
@ -371,7 +371,9 @@
bind:state={model.is_active} bind:state={model.is_active}
on:change={async (e) => { on:change={async (e) => {
toggleModelById(localStorage.token, model.id); toggleModelById(localStorage.token, model.id);
_models.set(await getModels(localStorage.token)); _models.set(
await getModels(localStorage.token, $settings?.directConnections ?? null)
);
}} }}
/> />
</Tooltip> </Tooltip>
@ -417,7 +419,9 @@
} }
} }
await _models.set(await getModels(localStorage.token)); await _models.set(
await getModels(localStorage.token, $settings?.directConnections ?? null)
);
models = await getWorkspaceModels(localStorage.token); models = await getWorkspaceModels(localStorage.token);
}; };

View File

@ -93,7 +93,7 @@
settings.set(localStorageSettings); settings.set(localStorageSettings);
} }
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
banners.set(await getBanners(localStorage.token)); banners.set(await getBanners(localStorage.token));
tools.set(await getTools(localStorage.token)); tools.set(await getTools(localStorage.token));

View File

@ -3,7 +3,7 @@
import { onMount, getContext } from 'svelte'; import { onMount, getContext } from 'svelte';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { functions, models } from '$lib/stores'; import { functions, models, settings } from '$lib/stores';
import { createNewFunction, getFunctions } from '$lib/apis/functions'; import { createNewFunction, getFunctions } from '$lib/apis/functions';
import FunctionEditor from '$lib/components/admin/Functions/FunctionEditor.svelte'; import FunctionEditor from '$lib/components/admin/Functions/FunctionEditor.svelte';
import { getModels } from '$lib/apis'; import { getModels } from '$lib/apis';
@ -47,7 +47,7 @@
if (res) { if (res) {
toast.success($i18n.t('Function created successfully')); toast.success($i18n.t('Function created successfully'));
functions.set(await getFunctions(localStorage.token)); functions.set(await getFunctions(localStorage.token));
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
await goto('/admin/functions'); await goto('/admin/functions');
} }

View File

@ -4,7 +4,7 @@
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { page } from '$app/stores'; import { page } from '$app/stores';
import { functions, models } from '$lib/stores'; import { functions, models, settings } from '$lib/stores';
import { updateFunctionById, getFunctions, getFunctionById } from '$lib/apis/functions'; import { updateFunctionById, getFunctions, getFunctionById } from '$lib/apis/functions';
import FunctionEditor from '$lib/components/admin/Functions/FunctionEditor.svelte'; import FunctionEditor from '$lib/components/admin/Functions/FunctionEditor.svelte';
@ -48,7 +48,7 @@
if (res) { if (res) {
toast.success($i18n.t('Function updated successfully')); toast.success($i18n.t('Function updated successfully'));
functions.set(await getFunctions(localStorage.token)); functions.set(await getFunctions(localStorage.token));
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
} }
}; };

View File

@ -1,13 +1,13 @@
<script> <script>
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { models } from '$lib/stores'; import { models, settings } from '$lib/stores';
import { getModels } from '$lib/apis'; import { getModels } from '$lib/apis';
import Models from '$lib/components/workspace/Models.svelte'; import Models from '$lib/components/workspace/Models.svelte';
onMount(async () => { onMount(async () => {
await Promise.all([ await Promise.all([
(async () => { (async () => {
models.set(await getModels(localStorage.token)); models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
})() })()
]); ]);
}); });

View File

@ -42,7 +42,7 @@
}); });
if (res) { if (res) {
await models.set(await getModels(localStorage.token)); await models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
toast.success($i18n.t('Model created successfully!')); toast.success($i18n.t('Model created successfully!'));
await goto('/workspace/models'); await goto('/workspace/models');
} }

View File

@ -34,7 +34,7 @@
const res = await updateModelById(localStorage.token, modelInfo.id, modelInfo); const res = await updateModelById(localStorage.token, modelInfo.id, modelInfo);
if (res) { if (res) {
await models.set(await getModels(localStorage.token)); await models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
toast.success($i18n.t('Model updated successfully')); toast.success($i18n.t('Model updated successfully'));
await goto('/workspace/models'); await goto('/workspace/models');
} }

View File

@ -61,7 +61,7 @@
////////////////////////// //////////////////////////
const loadSharedChat = async () => { const loadSharedChat = async () => {
await models.set(await getModels(localStorage.token)); await models.set(await getModels(localStorage.token, $settings?.directConnections ?? null));
await chatId.set($page.params.id); await chatId.set($page.params.id);
chat = await getChatByShareId(localStorage.token, $chatId).catch(async (error) => { chat = await getChatByShareId(localStorage.token, $chatId).catch(async (error) => {
await goto('/'); await goto('/');