diff --git a/tools/ui/src/lib/components/app/models/ModelsManager/ModelsManager.svelte b/tools/ui/src/lib/components/app/models/ModelsManager/ModelsManager.svelte index 367893eee3..3dc349b57b 100644 --- a/tools/ui/src/lib/components/app/models/ModelsManager/ModelsManager.svelte +++ b/tools/ui/src/lib/components/app/models/ModelsManager/ModelsManager.svelte @@ -19,7 +19,7 @@ import type { ModelOption } from '$lib/types/models'; import { getBackend } from '$lib/utils/api-base'; import { getBackendCapabilities } from '$lib/utils/backend'; - import type { Snippet } from 'svelte'; + import { type Snippet, untrack } from 'svelte'; import { SvelteMap, SvelteSet } from 'svelte/reactivity'; import { toast } from 'svelte-sonner'; @@ -180,6 +180,24 @@ return ordered; }); let selected = $derived(allModels.find((option) => option.id === selectedId) ?? null); + // the pane keeps a width of its own and stays in the DOM, so opening it slides a + // fixed panel in rather than reflowing one into place. Each open remounts the + // content, which is what reset the tabs when the pane used to unmount. + let paneOption = $state(null); + let paneSession = $state(0); + + $effect(() => { + const id = selectedId; + + if (!id) return; + + // untracked: this effect writes the session counter, and reading it back here + // would make the effect invalidate itself + untrack(() => { + paneOption = allModels.find((option) => option.id === id) ?? null; + paneSession += 1; + }); + }); // a caller can ask for one model to be revealed, the download rows do $effect(() => { @@ -234,17 +252,18 @@ {#snippet toolbarEndRegion()} -
+
{@render toolbarEnd?.()}
{/snippet} -
-
+
+
- {#if selected} -
- {#key selected.id} - (selectedId = null)} - onSave={(override) => saveOverride(selected, override)} - onToggleLoad={() => void toggleLoad(selected)} - onUseInNewChat={() => void useInNewChat(selected)} - option={selected} - override={overrides[selected.id]} - /> - {/key} +