Skip to content

Commit b64749b

Browse files
authored
fix: distinguish between hub and models search (#4989)
* fix: distinguish between hub and models search * chore: refresh models hub when going to hub screen
1 parent db43008 commit b64749b

File tree

5 files changed

+72
-7
lines changed

5 files changed

+72
-7
lines changed

core/src/browser/extensions/model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,9 @@ export abstract class ModelExtension
4040
* Delete a model source
4141
*/
4242
abstract deleteSource(source: string): Promise<void>
43+
44+
/**
45+
* Fetch models hub
46+
*/
47+
abstract fetchModelsHub(): Promise<void>
4348
}

extensions/model-extension/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export default class JanModelExtension extends ModelExtension {
6767
}
6868

6969
// Sync with cortexsohub
70-
this.fetchCortexsoModels()
70+
this.fetchModelsHub()
7171
}
7272

7373
/**
@@ -450,7 +450,7 @@ export default class JanModelExtension extends ModelExtension {
450450
/**
451451
* Fetch models from cortex.so
452452
*/
453-
private fetchCortexsoModels = async () => {
453+
fetchModelsHub = async () => {
454454
const models = await this.fetchModels()
455455

456456
return this.queue.add(() =>

web/containers/ModelSearch/index.tsx

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,23 @@ import { SearchIcon } from 'lucide-react'
55

66
import { useDebouncedCallback } from 'use-debounce'
77

8+
import {
9+
useGetModelSources,
10+
useModelSourcesMutation,
11+
} from '@/hooks/useModelSource'
12+
13+
import Spinner from '../Loader/Spinner'
14+
815
type Props = {
16+
supportModelImport?: boolean
917
onSearchLocal?: (searchText: string) => void
1018
}
1119

12-
const ModelSearch = ({ onSearchLocal }: Props) => {
20+
const ModelSearch = ({ supportModelImport, onSearchLocal }: Props) => {
1321
const [searchText, setSearchText] = useState('')
22+
const [isSearching, setSearching] = useState(false)
23+
const { mutate } = useGetModelSources()
24+
const { addModelSource } = useModelSourcesMutation()
1425
const inputRef = useRef<HTMLInputElement | null>(null)
1526
const debounced = useDebouncedCallback(async () => {
1627
if (searchText.indexOf('/') === -1) {
@@ -20,6 +31,15 @@ const ModelSearch = ({ onSearchLocal }: Props) => {
2031
}
2132
// Attempt to search local
2233
onSearchLocal?.(searchText)
34+
35+
setSearching(true)
36+
// Attempt to search model source
37+
if (supportModelImport)
38+
addModelSource(searchText)
39+
.then(() => mutate())
40+
.then(() => onSearchLocal?.(searchText))
41+
.catch(console.debug)
42+
.finally(() => setSearching(false))
2343
}, 300)
2444

2545
const onSearchChanged = useCallback(
@@ -50,8 +70,18 @@ const ModelSearch = ({ onSearchLocal }: Props) => {
5070
return (
5171
<Input
5272
ref={inputRef}
53-
prefixIcon={<SearchIcon size={16} />}
54-
placeholder="Search models..."
73+
prefixIcon={
74+
isSearching ? (
75+
<Spinner size={16} strokeWidth={2} />
76+
) : (
77+
<SearchIcon size={16} />
78+
)
79+
}
80+
placeholder={
81+
supportModelImport
82+
? 'Search or enter Hugging Face URL'
83+
: 'Search models'
84+
}
5585
onChange={onSearchChanged}
5686
onKeyDown={onKeyDown}
5787
value={searchText}

web/hooks/useEngineManagement.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ModelEvent,
1313
ModelSource,
1414
ModelSibling,
15+
ModelExtension,
1516
} from '@janhq/core'
1617
import { useAtom, useAtomValue } from 'jotai'
1718
import { atomWithStorage } from 'jotai/utils'
@@ -497,3 +498,21 @@ export const useRefreshModelList = (engine: string) => {
497498

498499
return { refreshingModels, refreshModels }
499500
}
501+
502+
export const useFetchModelsHub = () => {
503+
const extension = useMemo(
504+
() => extensionManager.get<ModelExtension>(ExtensionTypeEnum.Model) ?? null,
505+
[]
506+
)
507+
508+
const { data, error, mutate } = useSWR(
509+
extension ? 'fetchModelsHub' : null,
510+
() => extension?.fetchModelsHub(),
511+
{
512+
revalidateOnFocus: false,
513+
revalidateOnReconnect: true,
514+
}
515+
)
516+
517+
return { modelsHub: data, error, mutate }
518+
}

web/screens/Hub/index.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ import { twMerge } from 'tailwind-merge'
2525
import CenterPanelContainer from '@/containers/CenterPanelContainer'
2626
import ModelSearch from '@/containers/ModelSearch'
2727

28-
import { useGetEngineModelSources } from '@/hooks/useEngineManagement'
28+
import {
29+
useFetchModelsHub,
30+
useGetEngineModelSources,
31+
} from '@/hooks/useEngineManagement'
2932
import { setImportModelStageAtom } from '@/hooks/useImportModel'
3033

3134
import {
@@ -85,6 +88,7 @@ const hubCompatibleAtom = atom(false)
8588
const HubScreen = () => {
8689
const { sources } = useGetModelSources()
8790
const { sources: remoteModelSources } = useGetEngineModelSources()
91+
const { mutate: fetchModelsHub } = useFetchModelsHub()
8892
const { addModelSource } = useModelSourcesMutation()
8993
const [searchValue, setSearchValue] = useState('')
9094
const [sortSelected, setSortSelected] = useState('newest')
@@ -268,6 +272,10 @@ const HubScreen = () => {
268272
},
269273
})
270274

275+
useEffect(() => {
276+
fetchModelsHub()
277+
}, [])
278+
271279
return (
272280
<CenterPanelContainer>
273281
<m.div
@@ -422,7 +430,10 @@ const HubScreen = () => {
422430
<div className="absolute left-1/2 top-1/2 z-10 mx-auto w-4/5 -translate-x-1/2 -translate-y-1/2 rounded-xl sm:w-2/6">
423431
<div className="flex flex-col items-center justify-between gap-2 sm:flex-row">
424432
<div className="w-full" ref={dropdownRef}>
425-
<ModelSearch onSearchLocal={onSearchUpdate} />
433+
<ModelSearch
434+
onSearchLocal={onSearchUpdate}
435+
supportModelImport
436+
/>
426437
<div
427438
className={twMerge(
428439
'invisible absolute mt-2 max-h-[400px] w-full overflow-y-auto rounded-lg border border-[hsla(var(--app-border))] bg-[hsla(var(--app-bg))] shadow-lg',

0 commit comments

Comments
 (0)