mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-14 19:27:09 +00:00
5cf647d71ecda4b7db94181f48b942db640a90a3
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
72d1261983 |
[bugfix] Use Desktop2 bridge for missing model downloads (#12710)
## Summary Fixes the Desktop2 missing-model download path so the frontend calls the Desktop2 download bridge directly when it is available, instead of relying on the browser `<a download>` fallback that Desktop2 currently has to intercept indirectly. This addresses Linear FE-956, where missing-model downloads on Windows could open the OS Save As dialog. The issue was reproducible when the frontend language was not English: switching the UI language back to English made the download succeed again. ## Root Cause Desktop2 currently has compatibility logic that watches/intercepts the frontend missing-model download flow from outside the FE code. That interception depends on FE-rendered DOM details, including localized accessible labels such as the missing-model download button `aria-label`. In English, Desktop2 could find the expected download controls and cache the missing-model metadata before the FE-created `<a>` download was clicked. In non-English locales, the localized label no longer matched Desktop2's selector, so the Desktop2 interception path missed the download. The FE then continued down the browser download path, which Electron surfaced as a native Save As dialog on Windows. ## Changes - Adds a narrow Desktop2 runtime bridge check in `missingModelDownload.ts`: - if `window.__comfyDesktop2.downloadModel` exists - and `window.__comfyDesktop2Remote` is not set - then FE calls `window.__comfyDesktop2.downloadModel(model.url, model.name, model.directory)` directly and returns early. - Keeps remote Desktop2 sessions on the existing browser fallback path by preserving the `__comfyDesktop2Remote` guard. - Leaves the existing OSS browser fallback and legacy desktop `isDesktop` download-store path intact. - Logs Desktop2 bridge failures so rejected promises or synchronous bridge throws do not become unhandled errors. - Adds regression coverage for: - Desktop2 bridge path taking priority over browser and legacy desktop fallbacks. - rejected Desktop2 bridge calls being logged without falling back to browser download. - synchronously thrown Desktop2 bridge failures being logged without crashing or falling back to browser download. - remote Desktop2 sessions continuing to use browser fallback. ## User Impact Desktop2 users should no longer depend on localized FE DOM text for missing-model downloads. In particular, non-English UI locales should route missing-model downloads through Desktop2's managed downloader instead of opening the OS Save As dialog. ## Validation - Manually verified the issue is fixed in Desktop2 using a locally built FE dist served through ComfyUI with `--front-end-root`. - Verified Korean locale no longer triggers the Save As dialog and the missing-model download succeeds through Desktop2. - Verified the new regression test fails when the production bridge fix is reverted. - Covered the FE-side contract with unit tests because a true end-to-end assertion of the Windows native Save As dialog is not currently practical in the FE browser-test infrastructure. The FE tests can verify that clicking missing-model download routes into `window.__comfyDesktop2.downloadModel`; they cannot directly prove Electron/Windows native dialog behavior. That full native-dialog regression belongs in Desktop2/Electron integration coverage. - Ran: - `pnpm exec oxfmt --check src/platform/missingModel/missingModelDownload.ts src/platform/missingModel/missingModelDownload.test.ts` - `pnpm lint:unstaged` - `pnpm exec vitest run src/platform/missingModel/missingModelDownload.test.ts` - `pnpm typecheck` - `pnpm build` - Pre-commit hook passed: `oxfmt`, `oxlint`, `eslint`, `typecheck`. - Pre-push hook passed: `knip --cache` completed with existing tag hints only. - Ran a 3-round local Claude review loop; final verdict was approve with no Blocker/Major findings. ## Follow-up Work - Define and document the FE/Desktop2 bridge contract explicitly, including the expected semantics of `downloadModel` resolving `false` versus rejecting. - Add a shared or canonical TypeScript declaration for `window.__comfyDesktop2` and `window.__comfyDesktop2Remote` if more FE code starts depending on these globals. - Remove Desktop2's DOM/aria/class-based missing-model download interception after a sufficient FE compatibility window, so Desktop2 no longer depends on FE DOM structure or localized labels. - Add Desktop2 integration/e2e coverage for missing-model downloads in non-English locales, ideally including Windows where the Save As dialog was observed. This is the right layer for a true native Save As regression test. - Optionally add a lighter FE browser E2E that injects a fake `window.__comfyDesktop2.downloadModel` and verifies the missing-model UI calls that bridge. This would validate the FE contract, but it would still not replace Desktop2/Electron coverage for native dialog behavior. - Decide on user-facing failure UX for Desktop2 bridge download failures once Desktop2 defines whether failures, cancellations, and already-queued downloads are represented by rejection or by `false`. ## Notes This intentionally does not fall back to browser download when the Desktop2 bridge resolves `false`. Falling back there could reintroduce the exact Save As dialog behavior this PR fixes, and the meaning of `false` should be clarified in the Desktop2 bridge contract before FE invents user-facing behavior for it. A true E2E test for this bug would need to exercise Desktop2/Electron on Windows and assert that the native Save As dialog is not opened. The current FE browser-test infrastructure cannot observe that native Desktop2 behavior directly, so this PR uses focused unit regression coverage for the FE routing contract plus manual Desktop2 verification. |
||
|
|
7caba4408d |
fix: open model library for desktop model downloads (#12478)
## Summary Open the Model Library sidebar when a missing-model download starts on desktop so users can immediately see Electron download progress. This is a temporary UX patch until the dedicated desktop missing-model download progress bar lands. ## Changes - **What**: Activates the `model-library` sidebar tab before starting desktop missing-model downloads. - **Dependencies**: None. ## Review Focus Confirm the minimal behavior is scoped to the desktop download path and covers both individual downloads and Download all through the shared `downloadModel()` helper. This should remain small and easy to remove once the progress bar flow is available. ## Screenshots (if applicable) https://github.com/user-attachments/assets/d5b01db7-46b5-4a52-bb11-45e75a422474 ## Test Plan - `pnpm format` - `pnpm lint` - `pnpm typecheck` - `pnpm test:unit` - `pnpm knip` |
||
|
|
b4d209b5f6 |
feat: refresh missing models through pipeline (#11661)
## Summary Follow-up to the closed earlier attempt in #11646. This PR keeps the same user-facing goal, but changes the implementation to reuse the existing missing model pipeline for refresh instead of maintaining a separate candidate-only recheck path. Adds a missing model refresh action in the Errors tab by reusing the existing missing model pipeline, so users can re-check models after downloading or manually placing files without reloading the workflow. ## Changes - **What**: - Adds `app.refreshMissingModels()` as a reusable refresh entry point for the current root graph. - Splits node definition reloading into `app.reloadNodeDefs()` so missing-model refresh can pull fresh `object_info` without showing the generic combo refresh success flow. - Reuses the existing missing model pipeline instead of adding a separate candidate-only checker. The refresh path serializes the current graph, reuses active workflow model metadata when available, falls back to current missing-model metadata, and then reruns the same candidate discovery/enrichment/surfacing flow used during workflow load. - Adds missing model refresh state and error handling to `missingModelStore`. - Adds a Refresh button next to Download all in the missing model card action bar. - Moves Download all from the Errors tab header into the missing model card, so the Download all and Refresh actions render or hide together. - Changes Download all visibility from “more than one downloadable model” to “at least one downloadable model.” - Keeps the action bar hidden when there are no downloadable missing models; Cloud still does not render this action area. - Normalizes active workflow `pendingWarnings` updates so resolved missing model warnings do not get revived by stale empty warning objects. - Adds test IDs and coverage for the new action bar, refresh state, refresh delegation, pending warning sync, and E2E refresh behavior. - **Breaking**: None. - **Dependencies**: None. ## Review Focus The main design choice is intentionally reusing the missing model pipeline for refresh instead of implementing a smaller candidate-only recheck. The earlier candidate-only approach was cheaper, but it created a separate source of truth for missing-model resolution and made edge cases harder to reason about. In particular, it could diverge from the behavior used when a workflow is loaded, and it did not naturally handle the case where a model becomes missing after the workflow is already open. This version pays the cost of refreshing node definitions and rerunning the missing-model scan for the current graph, but keeps the refresh behavior aligned with workflow load semantics. Expected behavior by environment: - OSS browser: - The action bar appears when at least one missing model has a downloadable URL and directory. - Download all uses the existing browser download path. - Refresh reloads `object_info`, refreshes node definitions/combo values, reruns missing-model detection for the current graph, and clears the error if the selected model is now available. - OSS desktop: - The same action bar appears under the same downloadable-model condition. - Download all uses the existing Electron DownloadManager path. - Refresh uses the same missing-model pipeline as browser, so manually placed files or desktop-downloaded files can be rechecked without reloading the workflow. - Cloud: - The action bar remains hidden because model download/import is not supported in this section for Cloud. A few boundaries are intentional: - This PR does not add automatic filesystem watching. Browser OSS cannot reliably observe local model folder changes, so the user-triggered Refresh button remains the cross-environment mechanism. - This PR does not redesign the public `refreshComboInNodes` API beyond extracting `reloadNodeDefs()` for reuse. Further cleanup of toast behavior or a more explicit object-info reload API can be follow-up work. - This PR keeps refresh scoped to missing-model validation; missing media and missing nodes continue to use their existing flows. Linear: FE-417 ## Screenshots (if applicable) https://github.com/user-attachments/assets/2e02799f-1374-4377-b7b3-172241517772 ## Validation - `pnpm format` - `pnpm lint` (passes; existing unrelated warning remains in `src/platform/workspace/composables/useWorkspaceBilling.test.ts`) - `pnpm typecheck` - `pnpm test:unit` - `pnpm test:browser:local -- --project=chromium browser_tests/tests/propertiesPanel/errorsTabMissingModels.spec.ts` - `pnpm build` - `NX_SKIP_NX_CACHE=true DISTRIBUTION=desktop USE_PROD_CONFIG=true NODE_OPTIONS='--max-old-space-size=8192' pnpm exec nx build` - Manual desktop verification through `~/Projects/desktop` after copying the desktop build into `assets/ComfyUI/web_custom_versions/desktop_app`: - confirmed the FE bundle is built with `DISTRIBUTION = "desktop"` - confirmed missing model Download uses the desktop download path instead of browser download - confirmed Refresh can clear the missing model error after the model is available - Push hook: `pnpm knip --cache` ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11661-feat-refresh-missing-models-through-pipeline-34f6d73d3650811488defee54a7a6667) by [Unito](https://www.unito.io) |
||
|
|
4c35add5bc |
feat: add civitai.red hostname support (#11349)
*PR Created by the Glary-Bot Agent* --- ## Summary Civitai split its domain — NSFW content moved to `civitai.red` while `civitai.com` stays SFW. The frontend only recognized `civitai.com` URLs, causing the import button to silently reject `.red` links. This was the root cause of 8+ support tickets in 3 days. Companion to backend PR: https://github.com/Comfy-Org/cloud/pull/3259 ## Changes ### Import source recognition - **`civitaiImportSource.ts`**: Added `'civitai.red'` to `hostnames` array — this is the primary fix for "button doesn't recognize the links" ### Missing model auto-download - **`missingModelDownload.ts`**: Added `'https://civitai.red/'` to `ALLOWED_SOURCES` ### URL detection utilities - **`formatUtil.ts`**: `isCivitaiModelUrl()` now accepts `civitai.red` URLs with proper hostname validation - **`assetMetadataUtils.ts`**: `getSourceName()` returns "Civitai" for `.red` URLs ### Tests (4 files) - `useUploadModelWizard.test.ts`: Added civitai.red hostnames and URL test case - `missingModelDownload.test.ts`: Added civitai.red cases for `toBrowsableUrl` and `isModelDownloadable` - `assetMetadataUtils.test.ts`: Added civitai.red case for `getSourceName` - `useMissingModelInteractions.test.ts`: Updated mock hostnames - `formatUtil.test.ts`: Added civitai.red cases for `isCivitaiModelUrl` ## Not changed (intentionally) - `getAssetSourceUrl()` ARN fallback (line 88) — ARNs don't carry domain info, `civitai.com` is correct default - `fetchCivitaiMetadata()` API URL (line 109) — REST API works on both domains, keeping `civitai.com` Resolves BE-353 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11349-feat-add-civitai-red-hostname-support-3456d73d3650810d9c62ef4ad95ae031) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: Christian Byrne <cbyrne@comfy.org> Co-authored-by: Terry Jia <terryjia88@gmail.com> |
||
|
|
a3cf6fcde0 |
fix: convert download URLs to browsable page URLs in Copy Url button (#10228)
## Summary - Copy Url button in MissingModelRow now copies a browsable page URL instead of a direct download URL - HuggingFace: `/resolve/` → `/blob/` (file page with model info and download button) - Civitai: strips `/api/download` or `/api/v1` prefix (model page) ## Changes - Add `toBrowsableUrl()` to `missingModelDownload.ts` — converts download URLs to browsable page URLs for HuggingFace and Civitai - Update `MissingModelRow.vue` to use `toBrowsableUrl()` when copying - Add 5 unit tests covering HuggingFace, Civitai, and non-matching URL cases ## Test plan - [x] Unit tests pass (14/14) — `toBrowsableUrl` covered by 5 dedicated tests - [x] Lint, format, typecheck pass - [x] Manual: load workflow with missing HuggingFace models, click Copy Url, verify copied URL opens the file page - [x] Manual: load workflow with missing Civitai models, click Copy Url, verify copied URL opens the model page ### Why no E2E test The Copy Url button is only visible when `!isCloud && model.representative.url && !isAssetSupported`. Writing an E2E test for the clipboard content would require: 1. A test fixture with a real HuggingFace/Civitai URL (fragile — depends on external availability) 2. Granting `clipboard-read` permission in Playwright context 3. Ensuring `isAssetSupported` evaluates to `false` against the local test server's node definitions The URL transformation logic is a pure function, fully covered by unit tests. E2E clipboard content verification has no existing patterns in the codebase and would be environment-dependent and flaky. --------- Co-authored-by: Jin Yi <jin12cc@gmail.com> |
||
|
|
e2ef041170 |
feat: surface missing models in Error Tab for OSS and remove legacy dialog (#9921)
## Summary - Surface missing models in the Error Tab for OSS environments, replacing the legacy modal dialog - Add Download button per model and Download All button in group header with file size display - Move download business logic from `components/dialog/content` to `platform/missingModel` - Remove legacy missing models dialog components and composable ## Changes - **Pipeline**: Remove `isCloud` guard from `scanAllModelCandidates` and `surfaceMissingModels` so OSS detects missing models - **Grouping**: Group non-asset-supported models by directory in OSS instead of lumping into UNSUPPORTED - **UI**: Add Download button (matching Install Node Pack design) and Download All header button - **Store**: Add `folderPaths`/`fileSizes` state with setter methods, race condition guard - **Cleanup**: Delete `MissingModelsContent`, `MissingModelsHeader`, `MissingModelsFooter`, `useMissingModelsDialog`, `missingModelsUtils` - **Tests**: Add OSS/Cloud grouping tests, migrate Playwright E2E to Error Tab, improve test isolation - **Snapshots**: Reset Playwright screenshot expectations since OSS missing model error detection now causes red highlights on affected nodes - **Accessibility**: Add `aria-label` with model name, `aria-expanded` on toggle, warning icon for unknown category ## Test plan - [x] Unit tests pass (86 tests) - [x] TypeScript typecheck passes - [x] knip passes - [x] Load workflow with missing models in OSS → Error Tab shows missing models grouped by directory - [x] Download button triggers browser download with correct URL - [x] Download All button downloads all downloadable models - [x] Cloud environment behavior unchanged - [x] Playwright E2E: `pnpm test:browser:local -- --grep "Missing models in Error Tab"` ## Screenshots https://github.com/user-attachments/assets/12f15e09-215a-4c58-87ed-39bbffd1359c ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9921-feat-surface-missing-models-in-Error-Tab-for-OSS-and-remove-legacy-dialog-3236d73d365081f0a9dfc291978f5ecf) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: github-actions <github-actions@github.com> |