feat(recipes): reconnect suggestions, undo, and base-model family tolerance

Enhance the deleted-LoRA reconnect flow in the recipe modal:

- Suggest local reconnect candidates when the panel opens, ranked by
  identity (same hash / same CivitAI version) then filename/name
  similarity, with a hard filter on confident base-model mismatches;
  the input gets a Combobox backed by the same endpoint as you type.
- Snapshot the pre-reconnect entry and offer a permanent restore:
  reconnected entries show an undo icon at the right end of the info
  row, with the original filename in the tooltip.
- Relax the manual reconnect base-model guard to a three-tier check:
  exact/unknown labels pass silently, same-architecture families
  (e.g. Pony <-> Illustrious) pass with a warning toast, and only
  cross-architecture mismatches stay hard-rejected.
This commit is contained in:
Will Miao
2026-08-30 08:17:35 +08:00
parent 6e31da7a70
commit 838a374a56
23 changed files with 1893 additions and 45 deletions
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "Geben Sie die LoRA-Syntax oder den Namen zum Neuverknüpfen ein:",
"reconnectExample": "Beispiel: <lora:name:1> oder nur der Name",
"reconnectPlaceholder": "LoRA-Namen oder -Syntax eingeben",
"reconnectSuggestionsLoading": "Lokale Bibliothek wird durchsucht...",
"reconnectSuggestionsEmpty": "Keine passenden LoRAs in Ihrer lokalen Bibliothek",
"reconnectMatchSameHash": "Gleicher Hash",
"reconnectMatchSameVersion": "Gleiche Modellversion",
"reconnectMatchSimilarFilename": "Ähnlicher Dateiname",
"reconnectMatchSimilarName": "Ähnlicher Name",
"undoReconnect": "Rückgängig",
"undoReconnectTooltip": "Stellt die Verknüpfung wieder her, die dieser Eintrag vor dem Neuverknüpfen hatte",
"undoReconnectTooltipNamed": "Stellt {name} wieder her (die Verknüpfung vor dem Neuverknüpfen)",
"viewOnCivitai": "Auf CivitAI anzeigen",
"openLoraDetails": "{name} in der LoRA-Bibliothek anzeigen",
"openCheckpointDetails": "{name} in der Modellbibliothek anzeigen"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "Fehler beim Vorbereiten der LoRAs für den Download",
"enterLoraName": "Bitte geben Sie einen LoRA-Namen oder Syntax ein",
"reconnectedSuccessfully": "LoRA erfolgreich neu verbunden",
"reconnectBaseModelMismatch": "Neuverbindung erfolgreich, aber die Basismodelle unterscheiden sich (Rezept: {recipe}, LoRA: {lora}) — sie sind architekturkompatibel",
"reconnectFailed": "Fehler beim Neuverbinden des LoRA: {message}",
"loraRestored": "LoRA auf die vorherige Verknüpfung zurückgesetzt",
"loraRestoreFailed": "Fehler beim Wiederherstellen des LoRA: {message}",
"noPromptToSend": "Kein zu sendender Prompt",
"cannotSend": "Kann Rezept nicht senden: Fehlende Rezept-ID",
"sendFailed": "Fehler beim Senden des Rezepts an Workflow",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "Enter LoRA syntax or name to reconnect:",
"reconnectExample": "Example: <lora:name:1> or just the name",
"reconnectPlaceholder": "Enter LoRA name or syntax",
"reconnectSuggestionsLoading": "Searching local library...",
"reconnectSuggestionsEmpty": "No matching LoRAs in your local library",
"reconnectMatchSameHash": "Same hash",
"reconnectMatchSameVersion": "Same model version",
"reconnectMatchSimilarFilename": "Similar filename",
"reconnectMatchSimilarName": "Similar name",
"undoReconnect": "Undo",
"undoReconnectTooltip": "Restore the association this entry had before reconnecting",
"undoReconnectTooltipNamed": "Restore to {name} (the association before reconnecting)",
"viewOnCivitai": "View on CivitAI",
"openLoraDetails": "View {name} in the LoRA library",
"openCheckpointDetails": "View {name} in the model library"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "Error preparing LoRAs for download",
"enterLoraName": "Please enter a LoRA name or syntax",
"reconnectedSuccessfully": "LoRA reconnected successfully",
"reconnectBaseModelMismatch": "Reconnected, but base models differ (recipe: {recipe}, LoRA: {lora}) — they are architecture-compatible",
"reconnectFailed": "Error reconnecting LoRA: {message}",
"loraRestored": "LoRA restored to its previous association",
"loraRestoreFailed": "Error restoring LoRA: {message}",
"noPromptToSend": "No prompt to send",
"cannotSend": "Cannot send recipe: Missing recipe ID",
"sendFailed": "Failed to send recipe to workflow",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "Introduce la sintaxis o el nombre del LoRA para reconectar:",
"reconnectExample": "Ejemplo: <lora:name:1> o solo el nombre",
"reconnectPlaceholder": "Introduce el nombre o la sintaxis del LoRA",
"reconnectSuggestionsLoading": "Buscando en la biblioteca local...",
"reconnectSuggestionsEmpty": "No hay LoRAs coincidentes en tu biblioteca local",
"reconnectMatchSameHash": "Mismo hash",
"reconnectMatchSameVersion": "Misma versión del modelo",
"reconnectMatchSimilarFilename": "Nombre de archivo similar",
"reconnectMatchSimilarName": "Nombre similar",
"undoReconnect": "Deshacer",
"undoReconnectTooltip": "Restaura la asociación que esta entrada tenía antes de reconectar",
"undoReconnectTooltipNamed": "Restaurar a {name} (la asociación antes de reconectar)",
"viewOnCivitai": "Ver en CivitAI",
"openLoraDetails": "Ver {name} en la biblioteca de LoRAs",
"openCheckpointDetails": "Ver {name} en la biblioteca de modelos"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "Error preparando LoRAs para descarga",
"enterLoraName": "Por favor introduce un nombre de LoRA o sintaxis",
"reconnectedSuccessfully": "LoRA reconectado exitosamente",
"reconnectBaseModelMismatch": "Reconectado, pero los modelos base difieren (receta: {recipe}, LoRA: {lora}) — son compatibles a nivel de arquitectura",
"reconnectFailed": "Error reconectando LoRA: {message}",
"loraRestored": "LoRA restaurado a su asociación anterior",
"loraRestoreFailed": "Error restaurando LoRA: {message}",
"noPromptToSend": "No hay prompt para enviar",
"cannotSend": "No se puede enviar receta: Falta ID de receta",
"sendFailed": "Error al enviar receta al workflow",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "Entrez la syntaxe ou le nom du LoRA à reconnecter:",
"reconnectExample": "Exemple: <lora:name:1> ou simplement le nom",
"reconnectPlaceholder": "Entrez le nom ou la syntaxe du LoRA",
"reconnectSuggestionsLoading": "Recherche dans la bibliothèque locale...",
"reconnectSuggestionsEmpty": "Aucun LoRA correspondant dans votre bibliothèque locale",
"reconnectMatchSameHash": "Hash identique",
"reconnectMatchSameVersion": "Même version du modèle",
"reconnectMatchSimilarFilename": "Nom de fichier similaire",
"reconnectMatchSimilarName": "Nom similaire",
"undoReconnect": "Annuler",
"undoReconnectTooltip": "Restaurer l'association que cette entrée avait avant la reconnexion",
"undoReconnectTooltipNamed": "Restaurer vers {name} (l'association avant la reconnexion)",
"viewOnCivitai": "Voir sur CivitAI",
"openLoraDetails": "Voir {name} dans la bibliothèque LoRA",
"openCheckpointDetails": "Voir {name} dans la bibliothèque de modèles"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "Erreur lors de la préparation des LoRAs pour le téléchargement",
"enterLoraName": "Veuillez entrer un nom ou une syntaxe LoRA",
"reconnectedSuccessfully": "LoRA reconnecté avec succès",
"reconnectBaseModelMismatch": "Reconnexion effectuée, mais les modèles de base diffèrent (Recipe : {recipe}, LoRA : {lora}) — ils sont compatibles au niveau architectural",
"reconnectFailed": "Erreur lors de la reconnexion du LoRA : {message}",
"loraRestored": "LoRA restauré à son association précédente",
"loraRestoreFailed": "Erreur lors de la restauration du LoRA : {message}",
"noPromptToSend": "Aucun prompt à envoyer",
"cannotSend": "Impossible d'envoyer la recipe : ID de recipe manquant",
"sendFailed": "Échec de l'envoi de la recipe vers le workflow",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "הזן תחביר או שם של LoRA לחיבור מחדש:",
"reconnectExample": "דוגמה: <lora:name:1> או רק את השם",
"reconnectPlaceholder": "הזן שם או תחביר של LoRA",
"reconnectSuggestionsLoading": "מחפש בספרייה המקומית...",
"reconnectSuggestionsEmpty": "לא נמצאו LoRAs תואמים בספרייה המקומית שלך",
"reconnectMatchSameHash": "אותו hash",
"reconnectMatchSameVersion": "אותה גרסת מודל",
"reconnectMatchSimilarFilename": "שם קובץ דומה",
"reconnectMatchSimilarName": "שם דומה",
"undoReconnect": "בטל",
"undoReconnectTooltip": "שחזר את השיוך שהיה לרשומה זו לפני החיבור מחדש",
"undoReconnectTooltipNamed": "שחזר ל-{name} (השיוך לפני החיבור מחדש)",
"viewOnCivitai": "הצג ב-CivitAI",
"openLoraDetails": "הצג את {name} בספריית ה-LoRA",
"openCheckpointDetails": "הצג את {name} בספריית המודלים"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "שגיאה בהכנת LoRAs להורדה",
"enterLoraName": "אנא הזן שם LoRA או תחביר",
"reconnectedSuccessfully": "LoRA קושר מחדש בהצלחה",
"reconnectBaseModelMismatch": "הקישור מחדש הצליח, אך מודלי הבסיס שונים (מתכון: {recipe}, LoRA: {lora}) — הם תואמים מבחינת הארכיטקטורה",
"reconnectFailed": "שגיאה בקישור מחדש של LoRA: {message}",
"loraRestored": "LoRA שוחזר לשיוך הקודם",
"loraRestoreFailed": "שגיאה בשחזור LoRA: {message}",
"noPromptToSend": "אין פרומפט לשליחה",
"cannotSend": "לא ניתן לשלוח מתכון: חסר מזהה מתכון",
"sendFailed": "שליחת המתכון ל-workflow נכשלה",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "再接続する LoRA の構文または名前を入力してください:",
"reconnectExample": "例:<lora:name:1> または名前のみ",
"reconnectPlaceholder": "LoRA 名または構文を入力",
"reconnectSuggestionsLoading": "ローカルライブラリを検索中...",
"reconnectSuggestionsEmpty": "ローカルライブラリに一致するLoRAがありません",
"reconnectMatchSameHash": "同じハッシュ",
"reconnectMatchSameVersion": "同じモデルバージョン",
"reconnectMatchSimilarFilename": "類似のファイル名",
"reconnectMatchSimilarName": "類似の名前",
"undoReconnect": "元に戻す",
"undoReconnectTooltip": "このエントリーを再接続前の関連付けに戻します",
"undoReconnectTooltipNamed": "{name} に戻す(再接続前の関連付け)",
"viewOnCivitai": "CivitAI で表示",
"openLoraDetails": "LoRA ライブラリで {name} を表示",
"openCheckpointDetails": "モデルライブラリで {name} を表示"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "ダウンロード用LoRAの準備中にエラーが発生しました",
"enterLoraName": "LoRA名または構文を入力してください",
"reconnectedSuccessfully": "LoRAが正常に再接続されました",
"reconnectBaseModelMismatch": "再接続しましたが、ベースモデルが異なります(レシピ:{recipe}、LoRA:{lora})— アーキテクチャ互換です",
"reconnectFailed": "LoRA再接続エラー:{message}",
"loraRestored": "LoRAが以前の関連付けに復元されました",
"loraRestoreFailed": "LoRA復元エラー:{message}",
"noPromptToSend": "送信するプロンプトがありません",
"cannotSend": "レシピを送信できません:レシピIDがありません",
"sendFailed": "レシピのワークフローへの送信に失敗しました",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "다시 연결할 LoRA 구문 또는 이름을 입력하세요:",
"reconnectExample": "예:<lora:name:1> 또는 이름만 입력",
"reconnectPlaceholder": "LoRA 이름 또는 구문 입력",
"reconnectSuggestionsLoading": "로컬 라이브러리 검색 중...",
"reconnectSuggestionsEmpty": "로컬 라이브러리에 일치하는 LoRA가 없습니다",
"reconnectMatchSameHash": "동일한 해시",
"reconnectMatchSameVersion": "동일한 모델 버전",
"reconnectMatchSimilarFilename": "유사한 파일 이름",
"reconnectMatchSimilarName": "유사한 이름",
"undoReconnect": "실행 취소",
"undoReconnectTooltip": "이 항목을 다시 연결 전의 연결 상태로 복원",
"undoReconnectTooltipNamed": "이전 연결 상태로 복원: {name}",
"viewOnCivitai": "CivitAI에서 보기",
"openLoraDetails": "LoRA 라이브러리에서 {name} 보기",
"openCheckpointDetails": "모델 라이브러리에서 {name} 보기"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "LoRA 다운로드 준비 오류",
"enterLoraName": "LoRA 이름 또는 문법을 입력해주세요",
"reconnectedSuccessfully": "LoRA가 성공적으로 다시 연결되었습니다",
"reconnectBaseModelMismatch": "다시 연결했지만 베이스 모델이 다릅니다(레시피: {recipe}, LoRA: {lora}) — 아키텍처 호환입니다",
"reconnectFailed": "LoRA 다시 연결 오류: {message}",
"loraRestored": "LoRA가 이전 연결 상태로 복원되었습니다",
"loraRestoreFailed": "LoRA 복원 오류: {message}",
"noPromptToSend": "보낼 프롬프트가 없습니다",
"cannotSend": "레시피를 전송할 수 없습니다: 레시피 ID 누락",
"sendFailed": "레시피를 워크플로로 전송하는데 실패했습니다",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "Введите синтаксис или имя LoRA для переподключения:",
"reconnectExample": "Пример: <lora:name:1> или просто имя",
"reconnectPlaceholder": "Введите имя или синтаксис LoRA",
"reconnectSuggestionsLoading": "Поиск в локальной библиотеке...",
"reconnectSuggestionsEmpty": "В локальной библиотеке нет подходящих LoRA",
"reconnectMatchSameHash": "Тот же хеш",
"reconnectMatchSameVersion": "Та же версия модели",
"reconnectMatchSimilarFilename": "Похожее имя файла",
"reconnectMatchSimilarName": "Похожее имя",
"undoReconnect": "Отменить",
"undoReconnectTooltip": "Восстановить привязку, которая была у записи до переподключения",
"undoReconnectTooltipNamed": "Восстановить {name} (привязка до переподключения)",
"viewOnCivitai": "Открыть на CivitAI",
"openLoraDetails": "Открыть {name} в библиотеке LoRA",
"openCheckpointDetails": "Открыть {name} в библиотеке моделей"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "Ошибка подготовки LoRAs для загрузки",
"enterLoraName": "Пожалуйста, введите название LoRA или синтаксис",
"reconnectedSuccessfully": "LoRA успешно переподключена",
"reconnectBaseModelMismatch": "Переподключение выполнено, но базовые модели различаются (рецепт: {recipe}, LoRA: {lora}) — они совместимы по архитектуре",
"reconnectFailed": "Ошибка переподключения LoRA: {message}",
"loraRestored": "LoRA восстановлена к прежней привязке",
"loraRestoreFailed": "Ошибка восстановления LoRA: {message}",
"noPromptToSend": "Нет промпта для отправки",
"cannotSend": "Невозможно отправить рецепт: отсутствует ID рецепта",
"sendFailed": "Не удалось отправить рецепт в workflow",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "输入 LoRA 语法或名称以重新关联:",
"reconnectExample": "示例:<lora:name:1> 或只填名称",
"reconnectPlaceholder": "输入 LoRA 名称或语法",
"reconnectSuggestionsLoading": "正在搜索本地库...",
"reconnectSuggestionsEmpty": "本地库中没有匹配的 LoRA",
"reconnectMatchSameHash": "相同哈希",
"reconnectMatchSameVersion": "相同模型版本",
"reconnectMatchSimilarFilename": "相似文件名",
"reconnectMatchSimilarName": "相似名称",
"undoReconnect": "撤销",
"undoReconnectTooltip": "恢复此条目在重新关联前的关联",
"undoReconnectTooltipNamed": "恢复为 {name}(重新关联前的关联)",
"viewOnCivitai": "在 CivitAI 上查看",
"openLoraDetails": "在 LoRA 库中查看 {name}",
"openCheckpointDetails": "在模型库中查看 {name}"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "准备下载 LoRA 时出错",
"enterLoraName": "请输入 LoRA 名称或语法",
"reconnectedSuccessfully": "LoRA 重新连接成功",
"reconnectBaseModelMismatch": "已重新关联,但基础模型不同(配方:{recipe},LoRA{lora})——两者架构兼容",
"reconnectFailed": "LoRA 重新连接出错:{message}",
"loraRestored": "LoRA 已恢复为重新关联前的关联",
"loraRestoreFailed": "LoRA 恢复出错:{message}",
"noPromptToSend": "没有可发送的提示词",
"cannotSend": "无法发送配方:缺少配方 ID",
"sendFailed": "发送配方到工作流失败",
+12
View File
@@ -906,6 +906,15 @@
"reconnectInstructions": "輸入 LoRA 語法或名稱以重新關聯:",
"reconnectExample": "範例:<lora:name:1> 或只填名稱",
"reconnectPlaceholder": "輸入 LoRA 名稱或語法",
"reconnectSuggestionsLoading": "正在搜尋本地庫...",
"reconnectSuggestionsEmpty": "本地庫中沒有符合的 LoRA",
"reconnectMatchSameHash": "相同雜湊",
"reconnectMatchSameVersion": "相同模型版本",
"reconnectMatchSimilarFilename": "相似檔案名稱",
"reconnectMatchSimilarName": "相似名稱",
"undoReconnect": "撤銷",
"undoReconnectTooltip": "恢復此條目在重新關聯前的關聯",
"undoReconnectTooltipNamed": "恢復為 {name}(重新關聯前的關聯)",
"viewOnCivitai": "在 CivitAI 上檢視",
"openLoraDetails": "在 LoRA 庫中檢視 {name}",
"openCheckpointDetails": "在模型庫中檢視 {name}"
@@ -2046,7 +2055,10 @@
"preparingForDownloadFailed": "準備下載 LoRA 時發生錯誤",
"enterLoraName": "請輸入 LoRA 名稱或語法",
"reconnectedSuccessfully": "LoRA 重新連結成功",
"reconnectBaseModelMismatch": "已重新關聯,但基礎模型不同(配方:{recipe},LoRA{lora})——兩者架構相容",
"reconnectFailed": "LoRA 重新連結錯誤:{message}",
"loraRestored": "LoRA 已恢復為重新關聯前的關聯",
"loraRestoreFailed": "LoRA 恢復錯誤:{message}",
"noPromptToSend": "沒有可發送的提示詞",
"cannotSend": "無法傳送配方:缺少配方 ID",
"sendFailed": "傳送配方到工作流失敗",