Commit 4ff17acc authored by Jun Siang Cheah's avatar Jun Siang Cheah
Browse files

Merge remote-tracking branch 'upstream/dev' into feat/oauth

parents f49d814d 9928114c
......@@ -2,7 +2,7 @@
import { v4 as uuidv4 } from 'uuid';
import { toast } from 'svelte-sonner';
import { goto } from '$app/navigation';
import { settings, user, config, models } from '$lib/stores';
import { settings, user, config, models, tools } from '$lib/stores';
import { onMount, tick, getContext } from 'svelte';
import { addNewModel, getModelById, getModelInfos } from '$lib/apis/models';
......@@ -11,6 +11,9 @@
import AdvancedParams from '$lib/components/chat/Settings/Advanced/AdvancedParams.svelte';
import Checkbox from '$lib/components/common/Checkbox.svelte';
import Tags from '$lib/components/common/Tags.svelte';
import Knowledge from '$lib/components/workspace/Models/Knowledge.svelte';
import ToolsSelector from '$lib/components/workspace/Models/ToolsSelector.svelte';
import { stringify } from 'postcss';
const i18n = getContext('i18n');
......@@ -30,11 +33,6 @@
let id = '';
let name = '';
let params = {};
let capabilities = {
vision: true
};
let info = {
id: '',
base_model_id: null,
......@@ -53,14 +51,21 @@
}
};
let params = {};
let capabilities = {
vision: true
};
let toolIds = [];
let knowledge = [];
$: if (name) {
id = name.replace(/\s+/g, '-').toLowerCase();
}
let baseModel = null;
$: {
baseModel = $models.find((m) => m.id === info.base_model_id);
console.log(baseModel);
const addUsage = (base_model_id) => {
const baseModel = $models.find((m) => m.id === base_model_id);
if (baseModel) {
if (baseModel.owned_by === 'openai') {
capabilities.usage = baseModel.info?.meta?.capabilities?.usage ?? false;
......@@ -69,7 +74,7 @@
}
capabilities = capabilities;
}
}
};
const submitHandler = async () => {
loading = true;
......@@ -77,8 +82,24 @@
info.id = id;
info.name = name;
info.meta.capabilities = capabilities;
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
if (knowledge.length > 0) {
info.meta.knowledge = knowledge;
} else {
if (info.meta.knowledge) {
delete info.meta.knowledge;
}
}
if (toolIds.length > 0) {
info.meta.toolIds = toolIds;
} else {
if (info.meta.toolIds) {
delete info.meta.toolIds;
}
}
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
Object.keys(info.params).forEach((key) => {
if (info.params[key] === '' || info.params[key] === null) {
delete info.params[key];
......@@ -124,15 +145,34 @@
id = model.id;
if (model.info.base_model_id) {
const base_model = $models
.filter((m) => !m?.preset)
.find((m) =>
[model.info.base_model_id, `${model.info.base_model_id}:latest`].includes(m.id)
);
console.log('base_model', base_model);
if (!base_model) {
model.info.base_model_id = null;
} else if ($models.find((m) => m.id === `${model.info.base_model_id}:latest`)) {
model.info.base_model_id = `${model.info.base_model_id}:latest`;
}
}
params = { ...params, ...model?.info?.params };
params.stop = params?.stop ? (params?.stop ?? []).join(',') : null;
capabilities = { ...capabilities, ...(model?.info?.meta?.capabilities ?? {}) };
toolIds = model?.info?.meta?.toolIds ?? [];
info = {
...info,
...model.info
};
console.log(info);
};
onMount(async () => {
......@@ -233,7 +273,7 @@
<button
class="flex space-x-1"
on:click={() => {
history.back();
goto('/workspace/models');
}}
>
<div class=" self-center">
......@@ -252,7 +292,7 @@
</div>
<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
</button>
<!-- <hr class="my-3 dark:border-gray-700" /> -->
<!-- <hr class="my-3 dark:border-gray-850" /> -->
<form
class="flex flex-col max-w-2xl mx-auto mt-4 mb-10"
......@@ -331,6 +371,9 @@
class="px-3 py-1.5 text-sm w-full bg-transparent border dark:border-gray-600 outline-none rounded-lg"
placeholder="Select a base model (e.g. llama3, gpt-4o)"
bind:value={info.base_model_id}
on:change={(e) => {
addUsage(e.target.value);
}}
required
>
<option value={null} class=" text-gray-900">{$i18n.t('Select a base model')}</option>
......@@ -416,6 +459,7 @@
{#if showAdvanced}
<div class="my-2">
<AdvancedParams
admin={true}
bind:params
on:change={(e) => {
info.params = { ...info.params, ...params };
......@@ -518,6 +562,14 @@
{/if}
</div>
<div class="my-2">
<Knowledge bind:knowledge />
</div>
<div class="my-2">
<ToolsSelector bind:selectedToolIds={toolIds} tools={$tools} />
</div>
<div class="my-1">
<div class="flex w-full justify-between mb-1">
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
......
......@@ -5,7 +5,7 @@
import { onMount, getContext } from 'svelte';
import { page } from '$app/stores';
import { settings, user, config, models } from '$lib/stores';
import { settings, user, config, models, tools } from '$lib/stores';
import { splitStream } from '$lib/utils';
import { getModelInfos, updateModelById } from '$lib/apis/models';
......@@ -14,6 +14,8 @@
import { getModels } from '$lib/apis';
import Checkbox from '$lib/components/common/Checkbox.svelte';
import Tags from '$lib/components/common/Tags.svelte';
import Knowledge from '$lib/components/workspace/Models/Knowledge.svelte';
import ToolsSelector from '$lib/components/workspace/Models/ToolsSelector.svelte';
const i18n = getContext('i18n');
......@@ -54,19 +56,37 @@
};
let params = {};
let capabilities = {
vision: true
};
let knowledge = [];
let toolIds = [];
const updateHandler = async () => {
loading = true;
info.id = id;
info.name = name;
info.meta.capabilities = capabilities;
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
if (knowledge.length > 0) {
info.meta.knowledge = knowledge;
} else {
if (info.meta.knowledge) {
delete info.meta.knowledge;
}
}
if (toolIds.length > 0) {
info.meta.toolIds = toolIds;
} else {
if (info.meta.toolIds) {
delete info.meta.toolIds;
}
}
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
Object.keys(info.params).forEach((key) => {
if (info.params[key] === '' || info.params[key] === null) {
delete info.params[key];
......@@ -119,6 +139,14 @@
)
: null;
if (model?.info?.meta?.knowledge) {
knowledge = [...model?.info?.meta?.knowledge];
}
if (model?.info?.meta?.toolIds) {
toolIds = [...model?.info?.meta?.toolIds];
}
if (model?.owned_by === 'openai') {
capabilities.usage = false;
}
......@@ -126,6 +154,7 @@
if (model?.info?.meta?.capabilities) {
capabilities = { ...capabilities, ...model?.info?.meta?.capabilities };
}
console.log(model);
} else {
goto('/workspace/models');
......@@ -205,7 +234,7 @@
<button
class="flex space-x-1"
on:click={() => {
history.back();
goto('/workspace/models');
}}
>
<div class=" self-center">
......@@ -393,6 +422,7 @@
{#if showAdvanced}
<div class="my-2">
<AdvancedParams
admin={true}
bind:params
on:change={(e) => {
info.params = { ...info.params, ...params };
......@@ -405,7 +435,7 @@
<hr class=" dark:border-gray-850 my-1" />
<div class="my-1">
<div class="my-2">
<div class="flex w-full justify-between items-center">
<div class="flex w-full justify-between items-center">
<div class=" self-center text-sm font-semibold">{$i18n.t('Prompt suggestions')}</div>
......@@ -495,7 +525,15 @@
{/if}
</div>
<div class="my-1">
<div class="my-2">
<Knowledge bind:knowledge />
</div>
<div class="my-2">
<ToolsSelector bind:selectedToolIds={toolIds} tools={$tools} />
</div>
<div class="my-2">
<div class="flex w-full justify-between mb-1">
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
</div>
......
<script>
import Tools from '$lib/components/workspace/Tools.svelte';
</script>
<Tools />
<script>
import { goto } from '$app/navigation';
import { createNewTool, getTools } from '$lib/apis/tools';
import ToolkitEditor from '$lib/components/workspace/Tools/ToolkitEditor.svelte';
import { tools } from '$lib/stores';
import { onMount } from 'svelte';
import { toast } from 'svelte-sonner';
let mounted = false;
let clone = false;
let tool = null;
const saveHandler = async (data) => {
console.log(data);
const res = await createNewTool(localStorage.token, {
id: data.id,
name: data.name,
meta: data.meta,
content: data.content
}).catch((error) => {
toast.error(error);
return null;
});
if (res) {
toast.success('Tool created successfully');
tools.set(await getTools(localStorage.token));
await goto('/workspace/tools');
}
};
onMount(() => {
if (sessionStorage.tool) {
tool = JSON.parse(sessionStorage.tool);
sessionStorage.removeItem('tool');
console.log(tool);
clone = true;
}
mounted = true;
});
</script>
{#if mounted}
<ToolkitEditor
id={tool?.id ?? ''}
name={tool?.name ?? ''}
meta={tool?.meta ?? { description: '' }}
content={tool?.content ?? ''}
{clone}
on:save={(e) => {
saveHandler(e.detail);
}}
/>
{/if}
<script>
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { getToolById, getTools, updateToolById } from '$lib/apis/tools';
import Spinner from '$lib/components/common/Spinner.svelte';
import ToolkitEditor from '$lib/components/workspace/Tools/ToolkitEditor.svelte';
import { tools } from '$lib/stores';
import { onMount } from 'svelte';
import { toast } from 'svelte-sonner';
let tool = null;
const saveHandler = async (data) => {
console.log(data);
const res = await updateToolById(localStorage.token, tool.id, {
id: data.id,
name: data.name,
meta: data.meta,
content: data.content
}).catch((error) => {
toast.error(error);
return null;
});
if (res) {
toast.success('Tool updated successfully');
tools.set(await getTools(localStorage.token));
// await goto('/workspace/tools');
}
};
onMount(async () => {
console.log('mounted');
const id = $page.url.searchParams.get('id');
if (id) {
tool = await getToolById(localStorage.token, id).catch((error) => {
toast.error(error);
goto('/workspace/tools');
return null;
});
console.log(tool);
}
});
</script>
{#if tool}
<ToolkitEditor
edit={true}
id={tool.id}
name={tool.name}
meta={tool.meta}
content={tool.content}
on:save={(e) => {
saveHandler(e.detail);
}}
/>
{:else}
<div class="flex items-center justify-center h-full">
<div class=" pb-16">
<Spinner />
</div>
</div>
{/if}
<script>
import { io } from 'socket.io-client';
import { spring } from 'svelte/motion';
let loadingProgress = spring(0, {
stiffness: 0.05
});
import { onMount, tick, setContext } from 'svelte';
import {
......@@ -121,8 +126,35 @@
await tick();
document.getElementById('splash-screen')?.remove();
loaded = true;
if (
document.documentElement.classList.contains('her') &&
document.getElementById('progress-bar')
) {
loadingProgress.subscribe((value) => {
const progressBar = document.getElementById('progress-bar');
if (progressBar) {
progressBar.style.width = `${value}%`;
}
});
await loadingProgress.set(100);
document.getElementById('splash-screen')?.remove();
const audio = new Audio(`/audio/greeting.mp3`);
const playAudio = () => {
audio.play();
document.removeEventListener('click', playAudio);
};
document.addEventListener('click', playAudio);
loaded = true;
} else {
document.getElementById('splash-screen')?.remove();
loaded = true;
}
return () => {
window.removeEventListener('resize', onResize);
......
......@@ -135,7 +135,7 @@
{#if ($config?.features.auth_trusted_header ?? false) || $config?.features.auth === false}
<div class=" my-auto pb-10 w-full">
<div
class="flex items-center justify-center gap-3 text-xl sm:text-2xl text-center font-bold dark:text-gray-200"
class="flex items-center justify-center gap-3 text-xl sm:text-2xl text-center font-medium dark:text-gray-200"
>
<div>
{$i18n.t('Signing in')}
......@@ -157,7 +157,7 @@
}}
>
<div class="mb-1">
<div class=" text-2xl font-bold">
<div class=" text-2xl font-medium">
{mode === 'signin' ? $i18n.t('Sign in') : $i18n.t('Sign up')}
{$i18n.t('to')}
{$WEBUI_NAME}
......@@ -176,7 +176,7 @@
<div class="flex flex-col mt-4">
{#if mode === 'signup'}
<div>
<div class=" text-sm font-semibold text-left mb-1">{$i18n.t('Name')}</div>
<div class=" text-sm font-medium text-left mb-1">{$i18n.t('Name')}</div>
<input
bind:value={name}
type="text"
......@@ -191,7 +191,7 @@
{/if}
<div class="mb-2">
<div class=" text-sm font-semibold text-left mb-1">{$i18n.t('Email')}</div>
<div class=" text-sm font-medium text-left mb-1">{$i18n.t('Email')}</div>
<input
bind:value={email}
type="email"
......@@ -203,7 +203,7 @@
</div>
<div>
<div class=" text-sm font-semibold text-left mb-1">{$i18n.t('Password')}</div>
<div class=" text-sm font-medium text-left mb-1">{$i18n.t('Password')}</div>
<input
bind:value={password}
......@@ -218,7 +218,7 @@
<div class="mt-5">
<button
class=" bg-gray-900 hover:bg-gray-800 w-full rounded-2xl text-white font-semibold text-sm py-3 transition"
class=" bg-gray-900 hover:bg-gray-800 w-full rounded-2xl text-white font-medium text-sm py-3 transition"
type="submit"
>
{mode === 'signin' ? $i18n.t('Sign in') : $i18n.t('Create Account')}
......
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