Parcourir la source

feat: model selector fuzzy search

Co-Authored-By: Aryan Kothari <87589047+thearyadev@users.noreply.github.com>
Timothy J. Baek il y a 9 mois
Parent
commit
6ac40552b4
3 fichiers modifiés avec 31 ajouts et 9 suppressions
  1. 9 0
      package-lock.json
  2. 1 0
      package.json
  3. 21 9
      src/lib/components/chat/ModelSelector/Selector.svelte

+ 9 - 0
package-lock.json

@@ -20,6 +20,7 @@
 				"dayjs": "^1.11.10",
 				"eventsource-parser": "^1.1.2",
 				"file-saver": "^2.0.5",
+				"fuse.js": "^7.0.0",
 				"highlight.js": "^11.9.0",
 				"i18next": "^23.10.0",
 				"i18next-browser-languagedetector": "^7.2.0",
@@ -4820,6 +4821,14 @@
 				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
+		"node_modules/fuse.js": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
+			"integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
+			"engines": {
+				"node": ">=10"
+			}
+		},
 		"node_modules/gc-hook": {
 			"version": "0.3.1",
 			"resolved": "https://registry.npmjs.org/gc-hook/-/gc-hook-0.3.1.tgz",

+ 1 - 0
package.json

@@ -60,6 +60,7 @@
 		"dayjs": "^1.11.10",
 		"eventsource-parser": "^1.1.2",
 		"file-saver": "^2.0.5",
+		"fuse.js": "^7.0.0",
 		"highlight.js": "^11.9.0",
 		"i18next": "^23.10.0",
 		"i18next-browser-languagedetector": "^7.2.0",

+ 21 - 9
src/lib/components/chat/ModelSelector/Selector.svelte

@@ -1,6 +1,7 @@
 <script lang="ts">
 	import { DropdownMenu } from 'bits-ui';
 	import { marked } from 'marked';
+	import Fuse from 'fuse.js';
 
 	import { flyAndScale } from '$lib/utils/transitions';
 	import { createEventDispatcher, onMount, getContext, tick } from 'svelte';
@@ -45,17 +46,28 @@
 
 	let selectedModelIdx = 0;
 
-	$: filteredItems = items.filter(
-		(item) =>
-			(searchValue
-				? item.value.toLowerCase().includes(searchValue.toLowerCase()) ||
-				  item.label.toLowerCase().includes(searchValue.toLowerCase()) ||
-				  (item.model?.info?.meta?.tags ?? []).some((tag) =>
-						tag.name.toLowerCase().includes(searchValue.toLowerCase())
-				  )
-				: true) && !(item.model?.info?.meta?.hidden ?? false)
+	const fuse = new Fuse(
+		items
+			.filter((item) => !item.model?.info?.meta?.hidden)
+			.map((item) => {
+				const _item = {
+					...item,
+					modelName: item.model?.name,
+					tags: item.model?.info?.meta?.tags?.map((tag) => tag.name).join(' ')
+				};
+				return _item;
+			}),
+		{
+			keys: ['value', 'label', 'tags', 'modelName']
+		}
 	);
 
+	$: filteredItems = searchValue
+		? fuse.search(searchValue).map((e) => {
+				return e.item;
+		  })
+		: items.filter((item) => !item.model?.info?.meta?.hidden);
+
 	const pullModelHandler = async () => {
 		const sanitizedModelTag = searchValue.trim().replace(/^ollama\s+(run|pull)\s+/, '');