fix: normalize model id from source preparation

This commit is contained in:
Louis 2025-08-14 10:50:50 +07:00
parent 5657b6d917
commit 526e532e2d
No known key found for this signature in database
GPG Key ID: 44FA9F4D33C37DE2
4 changed files with 19 additions and 14 deletions

View File

@ -2,6 +2,7 @@ import { create } from 'zustand'
import { localStorageKey } from '@/constants/localStorage' import { localStorageKey } from '@/constants/localStorage'
import { createJSONStorage, persist } from 'zustand/middleware' import { createJSONStorage, persist } from 'zustand/middleware'
import { fetchModelCatalog, CatalogModel } from '@/services/models' import { fetchModelCatalog, CatalogModel } from '@/services/models'
import { sanitizeModelId } from '@/lib/utils'
// Zustand store for model sources // Zustand store for model sources
type ModelSourcesState = { type ModelSourcesState = {
@ -20,7 +21,15 @@ export const useModelSources = create<ModelSourcesState>()(
fetchSources: async () => { fetchSources: async () => {
set({ loading: true, error: null }) set({ loading: true, error: null })
try { try {
const newSources = await fetchModelCatalog() const newSources = await fetchModelCatalog().then((catalogs) =>
catalogs.map((catalog) => ({
...catalog,
quants: catalog.quants.map((quant) => ({
...quant,
model_id: sanitizeModelId(quant.model_id),
})),
}))
)
set({ set({
sources: newSources.length ? newSources : get().sources, sources: newSources.length ? newSources : get().sources,

View File

@ -157,5 +157,5 @@ export function formatDuration(startTime: number, endTime?: number): string {
} }
export function sanitizeModelId(modelId: string): string { export function sanitizeModelId(modelId: string): string {
return modelId.replace(/[^a-zA-Z0-9/_\-.]/g, '') return modelId.replace(/[^a-zA-Z0-9/_\-.]/g, '').replace(".", "_")
} }

View File

@ -3,7 +3,7 @@ import { useVirtualizer } from '@tanstack/react-virtual'
import { createFileRoute, useNavigate, useSearch } from '@tanstack/react-router' import { createFileRoute, useNavigate, useSearch } from '@tanstack/react-router'
import { route } from '@/constants/routes' import { route } from '@/constants/routes'
import { useModelSources } from '@/hooks/useModelSources' import { useModelSources } from '@/hooks/useModelSources'
import { cn, sanitizeModelId } from '@/lib/utils' import { cn } from '@/lib/utils'
import { import {
useState, useState,
useMemo, useMemo,
@ -291,8 +291,8 @@ function Hub() {
const handleDownload = () => { const handleDownload = () => {
// Immediately set local downloading state // Immediately set local downloading state
addLocalDownloadingModel(sanitizeModelId(modelId)) addLocalDownloadingModel(modelId)
pullModel(sanitizeModelId(modelId), modelUrl) pullModel(modelId, modelUrl)
} }
return ( return (
@ -764,14 +764,10 @@ function Hub() {
title={t('hub:downloadModel')} title={t('hub:downloadModel')}
onClick={() => { onClick={() => {
addLocalDownloadingModel( addLocalDownloadingModel(
sanitizeModelId( variant.model_id
variant.model_id
)
) )
pullModel( pullModel(
sanitizeModelId( variant.model_id,
variant.model_id
),
variant.path variant.path
) )
}} }}

View File

@ -1,3 +1,4 @@
import { sanitizeModelId } from '@/lib/utils'
import { import {
AIEngine, AIEngine,
EngineManager, EngineManager,
@ -5,7 +6,6 @@ import {
SettingComponentProps, SettingComponentProps,
} from '@janhq/core' } from '@janhq/core'
import { Model as CoreModel } from '@janhq/core' import { Model as CoreModel } from '@janhq/core'
import { sanitizeModelId } from '@/lib/utils'
// Types for model catalog // Types for model catalog
export interface ModelQuant { export interface ModelQuant {
model_id: string model_id: string
@ -163,10 +163,10 @@ export const convertHfRepoToCatalogModel = (
} }
// Generate model_id from filename (remove .gguf extension, case-insensitive) // Generate model_id from filename (remove .gguf extension, case-insensitive)
const modelId = sanitizeModelId(file.rfilename.replace(/\.gguf$/i, '')) const modelId = file.rfilename.replace(/\.gguf$/i, '')
return { return {
model_id: modelId, model_id: sanitizeModelId(modelId),
path: `https://huggingface.co/${repo.modelId}/resolve/main/${file.rfilename}`, path: `https://huggingface.co/${repo.modelId}/resolve/main/${file.rfilename}`,
file_size: formatFileSize(file.size), file_size: formatFileSize(file.size),
} }