char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
521a64cd0
char/aliceai-t5-moe
1import { filterModelOptions , groupModelOptions } from '$lib/components/app/models/utils' ; 2import { CHAT_INPUT_FOCUS_SELECTOR } from '$lib/constants' ; 3import { modelsStore , serverStore } from '$lib/stores' ; 4import type { ModelOption } from '$lib/types/models' ; 5import { onMount } from 'svelte' ; 6 7export interface UseModelsSelectorOptions { 8currentModel :() => string | null ; 9useGlobalSelection ?:() => boolean ; 10onModelChange ?:() => 11| (( modelId :string , modelName :string ) => Promise < boolean > | boolean | void ) 12| undefined ; 13onOpenChange ?:( open :boolean ) => void ; 14} 15 16export interface UseModelsSelectorReturn { 17readonly options :ModelOption []; 18readonly loading :boolean ; 19readonly updating :boolean ; 20readonly activeId :string | null ; 21readonly isRouter :boolean ; 22readonly serverModel :string | null ; 23readonly isHighlightedCurrentModelActive :boolean ; 24readonly isCurrentModelInCache :boolean ; 25readonly filteredOptions :ModelOption []; 26readonly groupedFilteredOptions :ReturnType < typeof groupModelOptions >; 27readonly isLoadingModel :boolean ; 28readonly searchTerm :string ; 29readonly showModelDialog :boolean ; 30readonly infoModelId :string | null ; 31setSearchTerm ( value :string ) :void ; 32setShowModelDialog ( value :boolean ) :void ; 33handleInfoClick ( modelName :string ) :void ; 34handleSelect ( modelId :string ) :Promise < void >; 35handleOpenChange ( open :boolean ) :void ; 36isFavorite ( model :string ) :boolean ; 37getDisplayOption () :ModelOption | undefined ; 38} 39 40/** 41* Shared reactive state and logic for model selection. 42* 43* Used by both the desktop dropdown (`ModelsSelectorDropdown`) 44* and the mobile sheet (`ModelsSelectorSheet`) to avoid 45* duplicating store derivations, selection handling, and model loading. 46*/ 47export function useModelsSelector ( opts :UseModelsSelectorOptions ) :UseModelsSelectorReturn { 48const options = $derived ( 49modelsStore . models . filter (( option ) => { 50const modelProps = modelsStore . props . getModelProps ( option . model ); 51 52return modelProps ?. ui !== false ; 53}) 54); 55const loading = $derived ( modelsStore . loading ); 56const updating = $derived ( modelsStore . updating ); 57const activeId = $derived ( modelsStore . selectedModelId ); 58const isRouter = $derived ( serverStore . isRouterMode ); 59const serverModel = $derived ( modelsStore . singleModelName ); 60const currentModel = $derived ( opts . currentModel ()); 61const onModelChange = $derived ( opts . onModelChange ?.()); 62const isHighlightedCurrentModelActive = $derived . by (() => { 63if ( ! isRouter || ! currentModel ) return false ; 64 65const currentOption = options . find (( option ) => option . model === currentModel ); 66 67return currentOption ?currentOption . id === activeId :false ; 68}); 69const isCurrentModelInCache = $derived . by (() => { 70if ( ! isRouter || ! currentModel ) return true ; 71 72return options . some (( option ) => option . model === currentModel ); 73}); 74 75let isLoadingModel = $state ( false ); 76let searchTerm = $state ( '' ); 77let showModelDialog = $state ( false ); 78let infoModelId = $state < string | null >( null ); 79 80const filteredOptions = $derived ( filterModelOptions ( options , searchTerm )); 81const groupedFilteredOptions = $derived ( 82groupModelOptions ( filteredOptions , modelsStore . favoriteModelIds , ( m ) => 83modelsStore . isModelLoaded ( m ) 84) 85); 86 87function handleInfoClick ( modelName :string ) { 88infoModelId = modelName ; 89showModelDialog = true ; 90} 91 92onMount (() => { 93modelsStore . fetch (). catch (( error ) => { 94console . error ( 'Unable to load models:' , error ); 95}); 96}); 97 98function handleOpenChange ( open :boolean ) { 99if ( loading || updating ) return ; 100 101if ( isRouter ) { 102searchTerm = '' ; 103 104if ( open ) { 105modelsStore . fetchRouterModels (). then (() => { 106modelsStore . props . fetchModalitiesForLoadedModels (); 107}); 108} 109 110opts . onOpenChange ?.( open ); 111} else { 112showModelDialog = open ; 113} 114} 115 116async function handleSelect ( modelId :string ) { 117const option = options . find (( opt ) => opt . id === modelId ); 118 119if ( ! option ) return ; 120 121let shouldCloseMenu = true ; 122 123if ( onModelChange ) { 124const result = await onModelChange ( option . id , option . model ); 125 126if ( result === false ) { 127shouldCloseMenu = false ; 128} 129} else { 130await modelsStore . selectModelById ( option . id ); 131} 132 133if ( shouldCloseMenu ) { 134handleOpenChange ( false ); 135 136requestAnimationFrame (() => { 137const input = document . querySelector < HTMLElement >( CHAT_INPUT_FOCUS_SELECTOR ); 138 139input ?. focus ({ preventScroll :true }); 140}); 141} 142 143if ( ! onModelChange && isRouter && ! modelsStore . isModelLoaded ( option . model )) { 144isLoadingModel = true ; 145 146modelsStore . status 147. load ( option . model ) 148. catch (( error ) => console . error ( 'Failed to load model:' , error )) 149. finally (() => ( isLoadingModel = false )); 150} 151} 152 153function getDisplayOption () :ModelOption | undefined { 154if ( ! isRouter ) { 155const displayModel = serverModel || currentModel ; 156 157if ( displayModel ) { 158return { 159capabilities :[], 160id :serverModel ?'current' :'offline-current' , 161model :displayModel , 162name :displayModel . split ( '/' ). pop () || displayModel 163}; 164} 165 166return undefined ; 167} 168 169if ( currentModel ) { 170if ( ! isCurrentModelInCache ) { 171return { 172capabilities :[], 173id :'not-in-cache' , 174model :currentModel , 175name :currentModel . split ( '/' ). pop () || currentModel 176}; 177} 178 179return options . find (( option ) => option . model === currentModel ); 180} 181 182if ( activeId ) { 183return options . find (( option ) => option . id === activeId ); 184} 185 186return undefined ; 187} 188 189return { 190get activeId () { 191return activeId ; 192}, 193 194get filteredOptions () { 195return filteredOptions ; 196}, 197 198 getDisplayOption, 199 200get groupedFilteredOptions () { 201return groupedFilteredOptions ; 202}, 203 204 handleInfoClick, 205 206 handleOpenChange, 207 208 handleSelect, 209 210get infoModelId () { 211return infoModelId ; 212}, 213 214get isCurrentModelInCache () { 215return isCurrentModelInCache ; 216}, 217 218isFavorite ( model :string ) { 219return modelsStore . favoriteModelIds . has ( model ); 220}, 221 222get isHighlightedCurrentModelActive () { 223return isHighlightedCurrentModelActive ; 224}, 225 226get isLoadingModel () { 227return isLoadingModel ; 228}, 229 230get isRouter () { 231return isRouter ; 232}, 233 234get loading () { 235return loading ; 236}, 237 238get options () { 239return options ; 240}, 241 242get searchTerm () { 243return searchTerm ; 244}, 245 246get serverModel () { 247return serverModel ; 248}, 249 250setSearchTerm ( value :string ) { 251searchTerm = value ; 252}, 253 254setShowModelDialog ( value :boolean ) { 255showModelDialog = value ; 256}, 257 258get showModelDialog () { 259return showModelDialog ; 260}, 261 262get updating () { 263return updating ; 264} 265}; 266}