diff --git a/src/lib/components/admin/Settings/Models.svelte b/src/lib/components/admin/Settings/Models.svelte index 98928b1ab9..dd0f860b09 100644 --- a/src/lib/components/admin/Settings/Models.svelte +++ b/src/lib/components/admin/Settings/Models.svelte @@ -71,6 +71,8 @@ let models = null; let modelsConfig = null; let modelOrderList: string[] = []; + let defaultModelIds: string[] = []; + let defaultPinnedModelIds: string[] = []; let workspaceModels: ModelListItem[] = []; let baseModels: ModelListItem[] = []; @@ -121,6 +123,9 @@ return 'text-gray-500 dark:text-gray-400'; }; + const isDefaultModel = (model) => defaultModelIds.includes(model.id); + const isDefaultPinnedModel = (model) => defaultPinnedModelIds.includes(model.id); + $: if (models) { const modelOrder = new Map(modelOrderList.map((id, idx) => [id, idx])); @@ -230,6 +235,10 @@ modelsConfig = await getModelsConfig(localStorage.token); modelOrderList = modelsConfig?.MODEL_ORDER_LIST ?? []; + defaultModelIds = (modelsConfig?.DEFAULT_MODELS ?? '').split(',').filter((id) => id); + defaultPinnedModelIds = (modelsConfig?.DEFAULT_PINNED_MODELS ?? '') + .split(',') + .filter((id) => id); tags = await getBaseModelTags(localStorage.token); if (selectedTag && !tags.includes(selectedTag)) { @@ -282,8 +291,8 @@ savingModelOrder = true; const res = await setModelsConfig(localStorage.token, { - DEFAULT_MODELS: modelsConfig?.DEFAULT_MODELS ?? null, - DEFAULT_PINNED_MODELS: modelsConfig?.DEFAULT_PINNED_MODELS ?? null, + DEFAULT_MODELS: defaultModelIds.join(','), + DEFAULT_PINNED_MODELS: defaultPinnedModelIds.join(','), MODEL_ORDER_LIST: orderedModelIds, DEFAULT_MODEL_METADATA: modelsConfig?.DEFAULT_MODEL_METADATA ?? null, DEFAULT_MODEL_PARAMS: modelsConfig?.DEFAULT_MODEL_PARAMS ?? null @@ -307,6 +316,65 @@ savingModelOrder = false; }; + const saveModelDefaults = async ( + nextDefaultModelIds: string[], + nextDefaultPinnedModelIds: string[], + successMessage: string + ) => { + const previousDefaultModelIds = defaultModelIds; + const previousDefaultPinnedModelIds = defaultPinnedModelIds; + + defaultModelIds = nextDefaultModelIds; + defaultPinnedModelIds = nextDefaultPinnedModelIds; + + const res = await setModelsConfig(localStorage.token, { + DEFAULT_MODELS: nextDefaultModelIds.join(','), + DEFAULT_PINNED_MODELS: nextDefaultPinnedModelIds.join(','), + MODEL_ORDER_LIST: modelsConfig?.MODEL_ORDER_LIST ?? [], + DEFAULT_MODEL_METADATA: modelsConfig?.DEFAULT_MODEL_METADATA ?? null, + DEFAULT_MODEL_PARAMS: modelsConfig?.DEFAULT_MODEL_PARAMS ?? null + }).catch((error) => { + toast.error(`${error}`); + return null; + }); + + if (res) { + modelsConfig = res; + toast.success(successMessage); + } else { + defaultModelIds = previousDefaultModelIds; + defaultPinnedModelIds = previousDefaultPinnedModelIds; + } + }; + + const toggleDefaultModelHandler = async (model) => { + const nextDefaultModelIds = isDefaultModel(model) + ? defaultModelIds.filter((id) => id !== model.id) + : [...new Set([...defaultModelIds, model.id])]; + + await saveModelDefaults( + nextDefaultModelIds, + defaultPinnedModelIds, + isDefaultModel(model) + ? $i18n.t('Model removed from selected models') + : $i18n.t('Model added to selected models') + ); + }; + + const toggleDefaultPinnedModelHandler = async (model) => { + const nextDefaultPinnedModelIds = isDefaultPinnedModel(model) + ? defaultPinnedModelIds.filter((id) => id !== model.id) + : [...new Set([...defaultPinnedModelIds, model.id])]; + + await saveModelDefaults( + defaultModelIds, + nextDefaultPinnedModelIds, + isDefaultPinnedModel(model) + ? $i18n.t('Model removed from pinned models') + : $i18n.t('Model added to pinned models') + ); + }; + const positionChangeHandler = async (event) => { const { oldIndex, newIndex, item } = event; @@ -803,7 +871,7 @@ class="flex cursor-pointer transition w-full px-2 py-1 rounded-xl hover:bg-gray-50/70 dark:hover:bg-gray-850/50 {model ?.meta?.hidden ? 'opacity-50 dark:opacity-50' - : ''}" + : ''}" id="model-item-{model.id}" >
@@ -876,6 +944,22 @@ > {modelAccessLabel(model)} + + {#if isDefaultModel(model)} + + {$i18n.t('Selected')} + + {/if} + + {#if isDefaultPinnedModel(model)} + + {$i18n.t('Pinned')} + + {/if}
@@ -934,6 +1018,14 @@ privacyHandler={() => { toggleModelPrivacyHandler(model); }} + isDefaultSelected={isDefaultModel(model)} + isDefaultPinned={isDefaultPinnedModel(model)} + defaultSelectedHandler={() => { + toggleDefaultModelHandler(model); + }} + defaultPinnedHandler={() => { + toggleDefaultPinnedModelHandler(model); + }} pinModelHandler={() => { pinModelHandler(model.id); }} diff --git a/src/lib/components/admin/Settings/Models/ModelMenu.svelte b/src/lib/components/admin/Settings/Models/ModelMenu.svelte index f7bf73db44..ae4cec4421 100644 --- a/src/lib/components/admin/Settings/Models/ModelMenu.svelte +++ b/src/lib/components/admin/Settings/Models/ModelMenu.svelte @@ -14,6 +14,7 @@ import ArrowUpCircle from '$lib/components/icons/ArrowUpCircle.svelte'; import Pin from '$lib/components/icons/Pin.svelte'; import PinSlash from '$lib/components/icons/PinSlash.svelte'; + import Check from '$lib/components/icons/Check.svelte'; import GlobeAlt from '$lib/components/icons/GlobeAlt.svelte'; import LockClosed from '$lib/components/icons/LockClosed.svelte'; @@ -28,6 +29,10 @@ export let exportHandler: Function; export let hideHandler: Function; export let privacyHandler: Function; + export let isDefaultSelected = false; + export let isDefaultPinned = false; + export let defaultSelectedHandler: Function; + export let defaultPinnedHandler: Function; export let pinModelHandler: Function; export let copyLinkHandler: Function; export let cloneHandler: Function; @@ -108,6 +113,46 @@ + + + + -
+ {#if showDefaultPromptSuggestions} +
+ - !(model?.info?.meta?.hidden ?? false))} - bind:modelIds={defaultPinnedModelIds} - /> + {#if promptSuggestions.length > 0} +
+ {$i18n.t( + 'Adjusting these settings will apply changes universally to all users.' + )} +
+ {/if} +
+ {/if} + -
+
-
- +
+ - {#if showDefaultPromptSuggestions} -
- + {#if showDefaultCapabilities} +
+ - {#if promptSuggestions.length > 0} -
- {$i18n.t( - 'Adjusting these settings will apply changes universally to all users.' - )} -
- {/if} -
- {/if} -
+ {#if Object.keys(defaultCapabilities).filter((key) => defaultCapabilities[key]).length > 0} + {@const availableFeatures = Object.entries(defaultCapabilities) + .filter( + ([key, value]) => + value && + ['web_search', 'code_interpreter', 'image_generation'].includes(key) + ) + .map(([key, value]) => key)} -
- -
- - - {#if showDefaultCapabilities} -
- - - {#if Object.keys(defaultCapabilities).filter((key) => defaultCapabilities[key]).length > 0} - {@const availableFeatures = Object.entries(defaultCapabilities) - .filter( - ([key, value]) => - value && - ['web_search', 'code_interpreter', 'image_generation'].includes( - key - ) - ) - .map(([key, value]) => key)} - - {#if availableFeatures.length > 0} -
- -
- {/if} - {/if} - - {#if defaultCapabilities.builtin_tools} + {#if availableFeatures.length > 0}
- +
{/if} -
- {/if} -
+ {/if} -
+ {#if defaultCapabilities.builtin_tools} +
+ +
+ {/if} +
+ {/if} +
-
- +
- {#if showDefaultParams} -
- -
- {/if} -
+
+ + + {#if showDefaultParams} +
+ +
+ {/if} +
diff --git a/src/lib/components/workspace/Prompts/PromptEditor.svelte b/src/lib/components/workspace/Prompts/PromptEditor.svelte index 0fe060cf7a..7a27f98b26 100644 --- a/src/lib/components/workspace/Prompts/PromptEditor.svelte +++ b/src/lib/components/workspace/Prompts/PromptEditor.svelte @@ -2,6 +2,7 @@ import { onMount, tick, getContext } from 'svelte'; import type { Writable } from 'svelte/store'; import type { i18n as i18nType } from 'i18next'; + import { goto } from '$app/navigation'; import Textarea from '$lib/components/common/Textarea.svelte'; import { toast } from 'svelte-sonner'; @@ -15,6 +16,7 @@ import Spinner from '$lib/components/common/Spinner.svelte'; import Modal from '$lib/components/common/Modal.svelte'; import XMark from '$lib/components/icons/XMark.svelte'; + import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte'; import { getPromptHistory, setProductionPromptVersion, @@ -382,9 +384,19 @@ {#if edit} -
- -
+
+ + +
-
- / - +
+
+ / + +
-
-
- {#if !disabled} - +
+ {#if !disabled} + - (showAccessControlModal = true)} /> - {:else} - {$i18n.t('Read Only')} - {/if} -
- -
- - - -
+ (showAccessControlModal = true)} /> + {:else} + + {$i18n.t('Read Only')} + + {/if}
@@ -456,6 +454,18 @@ }} />
+ + + +
@@ -517,9 +527,12 @@
-
-
{selectedHistoryEntry?.snapshot
-								?.content || content}
+
+
{selectedHistoryEntry
+								?.snapshot?.content || content}