open-webui/src/lib/components/chat/MessageInput/Commands/Models.svelte

95 lines
2.2 KiB
Svelte
Raw Normal View History

2024-08-23 20:31:39 +08:00
<script lang="ts">
2024-10-06 12:25:04 +08:00
import Fuse from 'fuse.js';
2025-07-01 19:57:01 +08:00
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
2024-08-23 20:31:39 +08:00
import { tick, getContext } from 'svelte';
import { models } from '$lib/stores';
import { WEBUI_BASE_URL } from '$lib/constants';
2024-08-23 20:31:39 +08:00
const i18n = getContext('i18n');
2025-09-13 00:31:57 +08:00
export let query = '';
export let onSelect = (e) => {};
2024-08-23 20:31:39 +08:00
let selectedIdx = 0;
2025-09-13 00:31:57 +08:00
export let filteredItems = [];
2024-10-06 12:25:04 +08:00
let fuse = new Fuse(
$models
.filter((model) => !model?.info?.meta?.hidden)
.map((model) => {
const _item = {
...model,
modelName: model?.name,
tags: model?.info?.meta?.tags?.map((tag) => tag.name).join(' '),
desc: model?.info?.meta?.description
};
return _item;
}),
{
keys: ['value', 'tags', 'modelName'],
2025-09-09 23:01:39 +08:00
threshold: 0.5
2024-10-06 12:25:04 +08:00
}
);
2024-08-23 20:31:39 +08:00
2025-09-13 00:31:57 +08:00
$: filteredItems = query
? fuse.search(query).map((e) => {
2024-10-06 12:25:04 +08:00
return e.item;
})
: $models.filter((model) => !model?.info?.meta?.hidden);
2024-08-23 20:31:39 +08:00
2025-09-13 00:31:57 +08:00
$: if (query) {
2024-08-23 20:31:39 +08:00
selectedIdx = 0;
}
export const selectUp = () => {
selectedIdx = Math.max(0, selectedIdx - 1);
};
export const selectDown = () => {
2024-10-06 12:25:04 +08:00
selectedIdx = Math.min(selectedIdx + 1, filteredItems.length - 1);
2024-08-23 20:31:39 +08:00
};
2025-09-13 00:31:57 +08:00
export const select = async () => {
const model = filteredItems[selectedIdx];
if (model) {
onSelect({ type: 'model', data: model });
2025-07-01 19:57:01 +08:00
}
};
2024-08-23 20:31:39 +08:00
</script>
2025-09-13 00:31:57 +08:00
<div class="px-2 text-xs text-gray-500 py-1">
{$i18n.t('Models')}
</div>
2024-10-06 12:25:04 +08:00
{#if filteredItems.length > 0}
2025-09-13 00:31:57 +08:00
{#each filteredItems as model, modelIdx}
<button
class="px-2.5 py-1.5 rounded-xl w-full text-left {modelIdx === selectedIdx
? 'bg-gray-50 dark:bg-gray-800 selected-command-option-button'
: ''}"
type="button"
on:click={() => {
onSelect({ type: 'model', data: model });
}}
on:mousemove={() => {
selectedIdx = modelIdx;
}}
on:focus={() => {}}
data-selected={modelIdx === selectedIdx}
>
<div class="flex text-black dark:text-gray-100 line-clamp-1">
<img
src={model?.info?.meta?.profile_image_url ?? `${WEBUI_BASE_URL}/static/favicon.png`}
alt={model?.name ?? model.id}
class="rounded-full size-5 items-center mr-2"
/>
<div class="truncate">
{model.name}
2024-08-23 20:31:39 +08:00
</div>
</div>
2025-09-13 00:31:57 +08:00
</button>
{/each}
2024-08-23 20:31:39 +08:00
{/if}