fix: enable verified ModelScope speech downloads
Selecting ModelScope could leave supported speech models unavailable because their fixed targets were incomplete and the official LFS redirect host was not allowed. Speech models now resolve complete per-source artifact fingerprints while preserving integrity checks, ZIP compatibility, and source isolation. Release note: 修复选择 ModelScope 后部分语音模型仍无法下载的问题;六个语音模型现均可从已验证的固定 ModelScope 来源下载。
This commit is contained in:
@@ -501,6 +501,13 @@ export function DocumentParsingSettingsSection({
|
||||
)
|
||||
const modelSourceAvailable =
|
||||
modelDownloadAvailability?.available === true
|
||||
const modelSize = installedModel
|
||||
? installedModel.files.reduce(
|
||||
(total, file) => total + file.size,
|
||||
0
|
||||
)
|
||||
: modelDownloadAvailability?.totalBytes ??
|
||||
(model ? catalogSize(model) : undefined)
|
||||
const pendingModelSelection =
|
||||
draft.localOcrModelId !== snapshot.settings.localOcrModelId
|
||||
const selectedModelReady = installedModel !== undefined
|
||||
@@ -845,7 +852,9 @@ export function DocumentParsingSettingsSection({
|
||||
})}
|
||||
</span>
|
||||
<span className="speech-model-tag">
|
||||
{formatBytes(catalogSize(model))}
|
||||
{formatBytes(
|
||||
modelSize ?? catalogSize(model)
|
||||
)}
|
||||
</span>
|
||||
<span className="speech-model-tag">
|
||||
{model.license.name}
|
||||
|
||||
@@ -117,6 +117,50 @@ describe('SpeechModelSettingsSection', () => {
|
||||
expect(openRepository).toHaveBeenCalledWith('sensevoice-small-int8')
|
||||
})
|
||||
|
||||
it('shows the selected download source artifact size', async () => {
|
||||
await changeUiLocale('en-US')
|
||||
const sourceSpecificSnapshot: SpeechModelSnapshot = {
|
||||
...snapshot,
|
||||
catalog: [
|
||||
{
|
||||
...entry,
|
||||
downloadAvailability: [
|
||||
{
|
||||
source: 'modelscope',
|
||||
available: true,
|
||||
totalBytes: 2 * 1024 * 1024
|
||||
},
|
||||
{
|
||||
source: 'hugging-face',
|
||||
available: true,
|
||||
totalBytes: 1_100
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Object.defineProperty(window, 'goodbuddy', {
|
||||
configurable: true,
|
||||
value: {
|
||||
speechModels: {
|
||||
getSnapshot: vi.fn(async () => sourceSpecificSnapshot),
|
||||
install: vi.fn(),
|
||||
cancel: vi.fn(async () => true),
|
||||
remove: vi.fn(),
|
||||
select: vi.fn(),
|
||||
importArchive: vi.fn(),
|
||||
exportArchive: vi.fn(),
|
||||
openRepository: vi.fn(),
|
||||
openModelsDirectory: vi.fn()
|
||||
}
|
||||
} as unknown as DesktopApi
|
||||
})
|
||||
|
||||
render(<SpeechModelSettingsSection />)
|
||||
|
||||
expect(await screen.findByText('2.0 MB')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('lists downloadable models and starts a verified download', async () => {
|
||||
const installedSnapshot: SpeechModelSnapshot = {
|
||||
...snapshot,
|
||||
|
||||
@@ -309,11 +309,17 @@ export function SpeechModelSettingsSection({
|
||||
const percent = operation
|
||||
? progressPercent(operation)
|
||||
: undefined
|
||||
const size = model ? catalogSize(model) : undefined
|
||||
const downloadAvailability = model?.downloadAvailability.find(
|
||||
(availability) =>
|
||||
availability.source === snapshot.selectedDownloadSource
|
||||
)
|
||||
const size = installed
|
||||
? installed.files.reduce(
|
||||
(total, file) => total + file.size,
|
||||
0
|
||||
)
|
||||
: downloadAvailability?.totalBytes ??
|
||||
(model ? catalogSize(model) : undefined)
|
||||
const sourceAvailable = downloadAvailability?.available === true
|
||||
const selected = model?.id === effectiveSelectedModelId
|
||||
const inUse = model?.id === effectivePersistedModelId
|
||||
|
||||
Reference in New Issue
Block a user