feat(recipes): add reconnect remediation paths for missing recipe LoRAs

- Snapshot pre-rematch entry state (reconnectSnapshot) so rematched
  entries can be undone via the existing restore flow
- Bulk missing-LoRA downloads mark unresolvable failures hash-invalid,
  flipping those entries from download to reconnect candidacy
- Recipe modal always offers a reconnect action next to download for
  missing LoRA entries
- Rematch runs collect an opt-in relaxed-matching choice (also reconnect
  missing models by file name) via a pre-run options dialog on the
  global, bulk and single-recipe entries
- L4 (filename-level) matches are listed in a results dialog with
  per-entry undo
This commit is contained in:
Will Miao
2026-09-09 06:59:54 +08:00
parent e747946f7a
commit 1b5cbbbaa0
33 changed files with 2103 additions and 76 deletions
+9 -4
View File
@@ -677,7 +677,7 @@ export class RecipeSidebarApiClient {
};
}
async rematchBulkModels(filePaths) {
async rematchBulkModels(filePaths, options = {}) {
if (!filePaths || filePaths.length === 0) {
throw new Error('No file paths provided');
}
@@ -690,14 +690,19 @@ export class RecipeSidebarApiClient {
throw new Error('No recipe IDs could be derived from file paths');
}
const body = { recipe_ids: recipeIds };
// Only sent when opted in — the strict body stays exactly
// {recipe_ids} for backward compatibility.
if (options.relaxed === true) {
body.relaxed = true;
}
const response = await fetch(this.apiConfig.endpoints.rematchBulk, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
recipe_ids: recipeIds,
}),
body: JSON.stringify(body),
});
const result = await response.json();