refactor: unify download source metadata context

This commit is contained in:
Dariusz L
2026-08-05 13:32:40 +02:00
parent bb01732b89
commit 22f294bc22
2 changed files with 101 additions and 31 deletions
@@ -3950,7 +3950,56 @@ test('search suggestion metadata prefers exact matching base model over weaker a
assert.equal(merged.filename, 'snofs_krea_v1.safetensors');
});
test('download path metadata preserves source precedence and workflow fallbacks', () => {
const getDownloadSourceContext = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadSourceContext')})`);
const getDownloadPathMetadata = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadPathMetadata')})`);
const dialog = {
getDownloadSourceContext,
getCachedSearchSuggestionData() {
return {
model_name: 'Cached model',
tags: ['style'],
repo_id: 'cached/repo',
category: 'loras'
};
},
getCompatibleCivitaiSearchResult() {
return {
base_model: 'SDXL',
creator_username: 'workflow-author'
};
},
getFilenameFromPath(value = '') {
return String(value).split(/[\\/]/).at(-1) || '';
}
};
const metadata = getDownloadPathMetadata.call(dialog, {
original_path: 'workflow/model.safetensors',
category: 'checkpoints',
civitai_info: { model_name: 'Workflow model' },
download_source: { model_name: 'Selected model' }
}, {
filename: 'explicit.safetensors',
model_name: 'Explicit model',
tags: ['explicit'],
repo_id: 'owner/repo',
author: 'explicit-author',
category: 'text_encoders'
});
assert.equal(metadata.filename, 'explicit.safetensors');
assert.equal(metadata.name, 'Explicit model');
assert.equal(metadata.base_model, 'SDXL');
assert.deepEqual(metadata.tags, ['explicit']);
assert.equal(metadata.creator.username, 'workflow-author');
assert.equal(metadata.author, 'explicit-author');
assert.equal(metadata.repo_id, 'owner/repo');
assert.equal(metadata.category, 'text_encoders');
});
test('manual URL download metadata never inherits provider identity or hash from search results', () => {
const getDownloadSourceContext = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadSourceContext')})`);
const getDownloadMetadata = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadMetadata')})`);
const staleHash = 'a'.repeat(64);
const exactHash = 'b'.repeat(64);
@@ -3987,6 +4036,7 @@ test('manual URL download metadata never inherits provider identity or hash from
hashes: { SHA256: exactHash }
};
const dialog = {
getDownloadSourceContext,
getCachedSearchSuggestionData() {
throw new Error('manual URL must not read cached search metadata');
},
@@ -4021,6 +4071,7 @@ test('manual URL download metadata never inherits provider identity or hash from
});
test('selected provider file hash overrides stale workflow hash', () => {
const getDownloadSourceContext = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadSourceContext')})`);
const getDownloadMetadata = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadMetadata')})`);
const staleHash = '1'.repeat(64);
const selectedHash = 'f'.repeat(64);
@@ -4044,6 +4095,7 @@ test('selected provider file hash overrides stale workflow hash', () => {
}
};
const dialog = {
getDownloadSourceContext,
getCachedSearchSuggestionData() {
throw new Error('selected provider metadata must not read cached search metadata');
},
@@ -4068,6 +4120,7 @@ test('selected provider file hash overrides stale workflow hash', () => {
});
test('selected provider without a file hash does not inherit workflow hash', () => {
const getDownloadSourceContext = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadSourceContext')})`);
const getDownloadMetadata = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadMetadata')})`);
const staleHash = '1'.repeat(64);
const missing = {
@@ -4085,6 +4138,7 @@ test('selected provider without a file hash does not inherit workflow hash', ()
selected_file: { name: 'another-variant.safetensors' }
};
const dialog = {
getDownloadSourceContext,
getCachedSearchSuggestionData() {
throw new Error('selected provider metadata must not read cached search metadata');
},
@@ -4107,6 +4161,7 @@ test('selected provider without a file hash does not inherit workflow hash', ()
});
test('CivArchive metadata keeps its page URL when the download mirror is HuggingFace', () => {
const getDownloadSourceContext = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadSourceContext')})`);
const getDownloadMetadata = eval(`(${extractMethod(downloadTargetMethodsSource, 'getDownloadMetadata')})`);
const civarchivePage = 'https://civarchive.com/models/123?modelVersionId=456';
const huggingFaceMirror = 'https://huggingface.co/author/repo/resolve/main/model.safetensors';
@@ -4121,6 +4176,7 @@ test('CivArchive metadata keeps its page URL when the download mirror is Hugging
download_url: huggingFaceMirror
};
const dialog = {
getDownloadSourceContext,
getCachedSearchSuggestionData() {
return {
source: 'huggingface',
+45 -31
View File
@@ -1224,17 +1224,50 @@ export const downloadTargetMethods = {
return list[0];
},
getDownloadPathMetadata(missing = {}, source = {}) {
getDownloadSourceContext(missing = {}, source = {}, { respectProvenanceBoundary = true } = {}) {
const sourceData = source && typeof source === 'object' ? source : {};
const searchSuggestion = this.getCachedSearchSuggestionData(missing);
const compatibleCivitaiSearch = this.getCompatibleCivitaiSearchResult?.(missing) || {};
const isProvidedUrl = Boolean(
sourceData.custom_url
|| sourceData.url_source === 'custom'
|| sourceData.match_type === 'custom_url'
|| sourceData.provided_url
);
const sourceIdentity = String(
sourceData.details_source || sourceData.source || sourceData.sourceKey || ''
).trim().toLowerCase().replace(/[-\s]+/g, '_');
const isProviderSelection = sourceData.match_type === 'selected'
|| ['civitai', 'civarchive', 'huggingface', 'lora_manager_archive'].includes(sourceIdentity);
const useSourceProvenanceBoundary = Boolean(
respectProvenanceBoundary && (isProvidedUrl || isProviderSelection)
);
const searchSuggestion = useSourceProvenanceBoundary
? null
: this.getCachedSearchSuggestionData(missing);
const compatibleCivitaiSearch = useSourceProvenanceBoundary
? {}
: (this.getCompatibleCivitaiSearchResult?.(missing) || {});
const inheritedDownloadSource = useSourceProvenanceBoundary ? {} : (missing?.download_source || {});
const inheritedCivitaiInfo = useSourceProvenanceBoundary ? {} : (missing?.civitai_info || {});
const merged = {
...(missing?.civitai_info || {}),
...inheritedCivitaiInfo,
...compatibleCivitaiSearch,
...(missing?.download_source || {}),
...inheritedDownloadSource,
...(searchSuggestion || {}),
...sourceData
};
return {
sourceData,
merged,
inheritedDownloadSource,
isProvidedUrl,
useSourceProvenanceBoundary
};
},
getDownloadPathMetadata(missing = {}, source = {}) {
const { merged } = this.getDownloadSourceContext(missing, source, {
respectProvenanceBoundary: false
});
const repoId = merged.repo_id || merged.repo || '';
const filename = merged.downloadFilename
|| merged.filename
@@ -1264,36 +1297,17 @@ export const downloadTargetMethods = {
},
getDownloadMetadata(missing = {}, source = {}, options = {}) {
const sourceData = source && typeof source === 'object' ? source : {};
const isProvidedUrl = Boolean(
sourceData.custom_url
|| sourceData.url_source === 'custom'
|| sourceData.match_type === 'custom_url'
|| sourceData.provided_url
);
const sourceIdentity = String(
sourceData.details_source || sourceData.source || sourceData.sourceKey || ''
).trim().toLowerCase().replace(/[-\s]+/g, '_');
const isProviderSelection = sourceData.match_type === 'selected'
|| ['civitai', 'civarchive', 'huggingface', 'lora_manager_archive'].includes(sourceIdentity);
const useSourceProvenanceBoundary = isProvidedUrl || isProviderSelection;
// A URL explicitly selected by the user is an authoritative provenance
// boundary. Never fill its hash, provider IDs, or file details from an
// earlier fuzzy search result belonging to another provider. The same
// rule applies to a selected/provider result, including LoRA Archive.
const searchSuggestion = useSourceProvenanceBoundary ? null : this.getCachedSearchSuggestionData(missing);
const compatibleCivitaiSearch = useSourceProvenanceBoundary
? {}
: (this.getCompatibleCivitaiSearchResult?.(missing) || {});
const inheritedDownloadSource = useSourceProvenanceBoundary ? {} : (missing?.download_source || {});
const inheritedCivitaiInfo = useSourceProvenanceBoundary ? {} : (missing?.civitai_info || {});
const merged = {
...inheritedCivitaiInfo,
...compatibleCivitaiSearch,
...inheritedDownloadSource,
...(searchSuggestion || {}),
...sourceData
};
const {
sourceData,
merged,
inheritedDownloadSource,
isProvidedUrl,
useSourceProvenanceBoundary
} = this.getDownloadSourceContext(missing, source);
const sourceHasIdentity = Boolean(
sourceData.model_id
|| sourceData.modelId