mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-18 01:38:03 +00:00
4337a6076531878a650781d4fdcfccdbe31c48d4
19 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5a01c5b3b4 |
Remove redundant Enter Subgraph action from Errors tab (#13136)
## Summary Remove the redundant **Enter Subgraph** action from Errors tab node cards. This button should not be part of the updated Errors tab design; it remained from the previous implementation and its removal was missed when the new interaction model was introduced. ## Changes - **What**: Removed the Errors tab `Enter Subgraph` button from `ErrorNodeCard`, along with the `enterSubgraph` event plumbing in `TabErrors`. - Removed the now-unused `useFocusNode().enterSubgraph()` helper path, since the Errors tab no longer has a separate subgraph-only action. - Removed the `ErrorCardData.isSubgraphNode` flag and its population in `useErrorGroups`, because it only existed to decide whether to show this button. - Removed the Storybook story and unit-test expectations that were specifically tied to the removed button/flag. - Removed the now-unused English `rightSidePanel.enterSubgraph` i18n entry. Non-English locale files are intentionally left untouched per the repo's localization update policy. ## Why The Errors tab already has a **Locate node on canvas** action. For errors inside subgraphs, that action navigates into the relevant subgraph and centers the target node on the canvas. The removed **Enter Subgraph** action was therefore a weaker duplicate: it entered the subgraph and fit the view, but did not provide the same direct target-node positioning. Keeping both actions made the card UI more crowded and exposed two very similar navigation paths with overlapping intent. The updated design should only keep the more useful locate action, so this PR removes the stale duplicate surface rather than adding another hidden/negative assertion around it. ## Review Focus Please verify that this only removes the Errors tab-specific action. The normal node footer/canvas subgraph navigation behavior remains untouched. Validation run locally: - `pnpm exec vitest run src/components/rightSidePanel/errors/ErrorNodeCard.test.ts src/components/rightSidePanel/errors/TabErrors.test.ts src/components/rightSidePanel/errors/useErrorGroups.test.ts` - `pnpm typecheck` - `pnpm lint` - `pnpm format:check` - `pnpm knip` ## Screenshot Before <img width="335" height="595" alt="스크린샷 2026-06-25 오후 5 33 37" src="https://github.com/user-attachments/assets/545f80e9-68bb-45ef-a4da-0a41012269f6" /> After <img width="344" height="591" alt="스크린샷 2026-06-25 오후 5 34 24" src="https://github.com/user-attachments/assets/7c1f1bf6-c5fd-4a43-9b5c-1392246070a8" /> |
||
|
|
6068571b35 |
Refactor: Brand node execution and locator IDs (#13071)
## Summary - Brand `NodeExecutionId` and `NodeLocatorId` as distinct required string types. - Route execution/locator ID construction through existing helper functions instead of minting raw strings at call sites. - Update tests and boundary parsing to use branded IDs without conflating them with local `NodeId` values. ## Validation - `pnpm typecheck` - `pnpm test:unit src/types/nodeIdentification.test.ts src/stores/executionStore.test.ts src/renderer/extensions/vueNodes/components/NodeSlots.test.ts src/composables/graph/useErrorClearingHooks.test.ts src/platform/nodeReplacement/missingNodeScan.test.ts -- --runInBand` - `pnpm exec eslint src/types/nodeIdentification.ts src/utils/graphTraversalUtil.ts src/platform/workflow/management/stores/workflowStore.ts src/renderer/extensions/minimap/data/LayoutStoreDataSource.ts src/renderer/extensions/vueNodes/execution/useNodeExecutionState.ts src/stores/workspace/favoritedWidgetsStore.ts src/stores/nodeOutputStore.ts src/utils/__tests__/executionErrorTestUtils.ts src/platform/nodeReplacement/missingNodeScan.test.ts src/stores/executionStore.test.ts --cache` Note: full `pnpm lint` timed out after 5 minutes while still in stylelint startup, so targeted lint was run on changed files. ## Open Question - Should root-level node IDs like `1` be considered valid `NodeExecutionId` values, or should `isNodeExecutionId()` require a colon and callers use a separate type/helper for root execution IDs? |
||
|
|
ab6c44aabf |
feat: remove deprecated group nodes, auto-convert to subgraphs on load (#12931)
## Summary Removes the deprecated Group Nodes feature and replaces it with a load-time migration that auto-converts any group nodes in a loaded workflow into Subgraphs (with accepted lossiness). ## Changes - **What**: - `groupNode.ts` is now a migration-only extension. `beforeConfigureGraph` registers temporary node types from `extra.groupNodes` so instances are created during `configure`; a new `afterConfigureGraph` hook converts every group node in the root graph to a subgraph (via `LGraph.convertToSubgraph`), re-scanning until none remain, then deletes `extra.groupNodes`. A failed conversion removes the offending node so loading never hangs or breaks. - Kept the minimum needed: `GroupNodeConfig` (builds the input/output/widget maps), a slimmed `GroupNodeHandler` exposing a rewritten `convertToNodes()` that no longer depends on the execution DTOs, the `globalDefs`/`addCustomNodeDefs` path, and the `nodeDefStore` `Object.assign` shim the migration relies on to detect group nodes. - Deleted: the Manage Group Nodes dialog (`groupNodeManage.ts`/`.css`), execution DTOs (`executableGroupNodeDto.ts`, `executableGroupNodeChildDTO.ts`), the create/builder flow, recreate, commands, keybindings, menus, the `isGroupNode` branches in the right-side panel / error grouping / focus composable, the group-node branches in node templates, dead i18n keys, and the now-unused `serialise` clipboard helper. - Rewrote `browser_tests/tests/groupNode.spec.ts` to assert auto-conversion; deleted the `ManageGroupNode` page object and `manageGroupNode()` helper. - Net: ~2,700 lines removed across 23 files (7 files deleted). - **Breaking**: Group nodes can no longer be created, managed, or executed. Existing workflows still load — their group nodes are converted to subgraphs on open. ## Review Focus - The load-time migration in `afterConfigureGraph` and the rewritten `GroupNodeHandler.convertToNodes()` (no longer uses the execution `getInnerNodes()` / DTOs; derives inner node type/index from `groupData.nodeData.nodes` and relies on `deserialiseAndCreate` + selection ordering). - Kept `nodeDefStore`'s `Object.assign(this, obj)` shim: the migration depends on it to propagate the group-node marker symbol onto the registered node definition. ### Accepted lossiness - Group nodes nested inside subgraphs (or inside other group nodes) convert into the root graph rather than their original container — essentially nonexistent in real legacy workflows since group nodes predate subgraphs. - Temporary `workflow>name` node types stay registered for the session; instantiating one auto-converts it to a subgraph. ## Verification `pnpm typecheck`, `typecheck:browser`, `knip`, `oxlint`, `eslint`, and `oxfmt` are green (also enforced by pre-commit hooks). Unit tests for the touched files could not be run locally due to a pre-existing environment error (`file:///assets/images/*.svg` passed to a Node filename API at import time, which also fails on unmodified test files); the browser spec requires a live server. --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: AustinMroz <austin@comfy.org> Co-authored-by: GitHub Action <action@github.com> |
||
|
|
6850d22d99 |
Redesign error overlay count and toast behavior (#12871)
## Summary Redesign the run error overlay so its count and copy use the same grouped error semantics as the redesigned Error tab, while keeping single-error toast copy precise. This is a stacked follow-up to #12828. The parent PR redesigns the Error tab cards and centralizes their grouped/row-based presentation. This PR applies the same mental model to the compact overlay shown from the Run button path, so users no longer see one count in the Error tab and a different count in the overlay. ## Changes - **What**: Align the error overlay count with the Error tab's grouped error count. - The overlay now reads the same grouped error surface that powers the Error tab hero instead of independently summing raw store error counts. - Validation/runtime/prompt execution groups use their grouped `count`. - Missing model/media/node/swap groups keep the row/group count semantics introduced by the Error tab redesign. - This avoids cases where the overlay headline says one number while the panel summarizes another. - **What**: Preserve the existing single-error toast behavior while adding explicit multi-row handling. - A single true leaf still uses the catalog/resolver toast title and toast message. - A single grouped execution error with multiple node/input items uses that group's title/message instead of the generic aggregate copy. - A single missing model/media group with multiple model/file rows uses the generic aggregate copy because it represents multiple actionable rows. - A single missing model/media row referenced by multiple nodes uses the group title/message, since there is still only one model/file to resolve. - Multiple top-level groups continue to use the aggregate "N errors found" style copy. - **What**: Restyle the overlay toast to match the new error-surface direction. - Adds a compact dark card with a destructive left accent and a visible outline for better contrast against the workspace. - Keeps the close button in the card header area. - Keeps the primary "View details" action, but adjusts spacing, size, and typography to better match the Figma direction. - Removes the older footer-style dismiss action so the overlay behaves like a focused status toast rather than a secondary dialog. - **What**: Share error grouping/count helpers instead of duplicating local logic. - Extracts execution item-list detection for reuse between the Error tab render path and count logic. - Extracts missing-model grouping/count helpers so missing-model row count semantics have one implementation. - Removes `groupedErrorMessages`, which became unused after the overlay copy decision moved to grouped error state. - **Breaking**: None. - **Dependencies**: None. ## Review Focus - **Stack boundary**: Please review this against `jaeone/fe-816-error-card-redesign`, not against `main` directly. The parent PR is #12828 and contains the Error tab card redesign that this overlay work builds on. - **Count semantics**: The visible overlay count intentionally changes from raw store counts to grouped Error tab counts. This is not just a refactor; it is the intended product behavior so the compact overlay and the panel hero agree. - **Overlay message branches**: The overlay can now choose between three message modes. The goal is to keep precise single-error copy where it is useful, but avoid showing one node-specific toast message when the overlay actually represents multiple actionable rows. | Branch | When it applies | Overlay title source | Overlay message source | Example output | | --- | --- | --- | --- | --- | | Aggregate summary | More than one top-level error group, or one missing model/media group with multiple actionable model/file rows. | Generic aggregate title using grouped count. | Generic aggregate message. | Title: `2 errors found`<br>Message: `Resolve them before running the workflow.`<br>Example case: one Missing Models group containing `first.safetensors` and `second.safetensors`. | | Group summary | Exactly one error group that is not a true single leaf, but should still be described by the group. This includes one execution catalog group with multiple items, or one missing model/media row referenced by multiple nodes. | The group's `displayTitle`. | The group's `displayMessage`. | Title: `Missing connection`<br>Message: `Required input slots have no connection feeding them.`<br>Example case: one validation group with `KSampler - model` and `KSampler - positive` rows. | | Single leaf toast | Exactly one group, one actionable row/card, and at most one node reference. | Resolver/catalog `toastTitle`. | Resolver/catalog `toastMessage`. | Title: `Model missing`<br>Message: `CheckpointLoaderSimple is missing missing.safetensors.`<br>Example case: one missing model file referenced by one node. | - **Scope control**: This PR intentionally does not redesign the full Error Overlay flow beyond the compact toast/card. It also does not revisit the deeper Error tab card layouts already handled in #12828. - **Accessibility**: The toast keeps `role="status"` for polite announcement semantics. The duplicate `aria-live` attribute was removed during cleanup because `role="status"` already implies polite live-region behavior. ## Validation - `pnpm format` - `pnpm lint` - `pnpm typecheck` - `pnpm knip` - `pnpm test:unit src/components/error/useErrorOverlayState.test.ts src/platform/missingModel/missingModelGrouping.test.ts src/components/error/ErrorOverlay.test.ts src/components/rightSidePanel/errors/useErrorGroups.test.ts` - Pre-commit staged checks passed. - Pre-push `knip` passed. ## Screenshots (if applicable) <img width="454" height="179" alt="스크린샷 2026-06-16 오후 6 00 10" src="https://github.com/user-attachments/assets/a85376ba-2b22-4cf8-a6fa-79f83fb8b244" /> <img width="453" height="179" alt="스크린샷 2026-06-16 오후 6 00 31" src="https://github.com/user-attachments/assets/d9a1d4bd-92ab-451a-bb79-e7cfbc3af7c6" /> <img width="486" height="148" alt="스크린샷 2026-06-16 오후 6 00 55" src="https://github.com/user-attachments/assets/b66faf96-65c8-4a22-9ff9-e8ccd450986e" /> <img width="395" height="127" alt="스크린샷 2026-06-16 오후 6 01 22" src="https://github.com/user-attachments/assets/c64443f9-0eba-4b2b-8049-c1887c788b1e" /> <img width="384" height="134" alt="스크린샷 2026-06-16 오후 6 01 30" src="https://github.com/user-attachments/assets/42f4fcae-b003-4df9-8f3a-0fda85a90880" /> <img width="376" height="129" alt="스크린샷 2026-06-16 오후 6 01 53" src="https://github.com/user-attachments/assets/ce9030d0-2a98-4b38-9e7d-7a9c3103960f" /> <img width="379" height="128" alt="스크린샷 2026-06-16 오후 6 02 01" src="https://github.com/user-attachments/assets/3d4ce356-1c22-4e3b-a1d0-fece351d9fbb" /> <img width="463" height="133" alt="스크린샷 2026-06-16 오후 6 02 33" src="https://github.com/user-attachments/assets/6ae13a44-02aa-4167-8878-4906db468ad6" /> |
||
|
|
c36da042d0 |
Redesign error tab cards with summary hero and unified sections (#12828)
## Summary Redesigns the Errors tab cards to match the new Figma error-panel spec (file `Czv0JcCfcUiizeEZURevpq`): every error group is now wrapped in a single bordered card led by an error-count summary hero, with each category rendered as a collapsible section whose count lives in a circular badge rather than a parenthetical title suffix. > Rebased onto `main` after #12793 was merged. This PR now contains only the error-card redesign slice. ## Changes - **What**: - **New `ErrorCardSection.vue`** — the shared section shell used by every error type. Renders a 32px header (circular count badge + neutral title + `actions` slot + collapse chevron) and a `TransitionCollapse` body. Replaces the per-group `PropertiesAccordionItem`, dropping the old octagon-alert icon + red title + `(n)` suffix and the sticky-header behavior. - **`TabErrors.vue`** — wraps all groups in one `rounded-lg` card bordered with `secondary-background`. Adds a summary **hero** (large severity-colored total count, vertical divider, "N Errors detected / Resolve before running the workflow"). Moves the per-group action buttons (Install All / Replace All / missing-model Refresh) into the section's `actions` slot. Adds `getGroupCount()` / `totalErrorCount` and switches content background to `interface-panel-surface`. Most of the line count here is re-indentation from the template restructure, not behavior change. - **`missingErrorResolver.ts`** — drops the `formatCountTitle` helper so display titles are `"Missing Models"` instead of `"Missing Models (4)"`; the badge now carries the count. Toast titles/messages are untouched. - **`ErrorNodeCard.vue`** — restyles the runtime/validation error-log box to the Figma spec: borderless `base-foreground/5` surface, `ERROR LOG` header, 12px non-mono body at 50% opacity, inset footer divider with Get Help / Find on GitHub links. - **Row components** (`MissingModelRow`, `MissingPackGroupRow`, `SwapNodeGroupRow`, `MissingMediaCard`, `MissingNodeCard`, `MissingModelCard`) — align spacing, fonts, badges, and button sizes with Figma: 12px row labels, `size="sm"` (24px) action buttons, 16px count badges (`rounded-sm`, `secondary-background-hover`, 9px), 32px reference-row heights, `px-3` card padding. Model-name wrapping is kept independent of its count badge and link button so they never reflow into the metadata sub-label. - **i18n** — adds `errorsDetected` (pluralized), `resolveBeforeRun`, `expand`, `collapse` to `en/main.json`. - **Breaking**: None. No store, composable, action, or data-flow changes — all handlers and emitted events are preserved. The only user-visible copy change is the removal of the `(n)` count suffix from section titles. ## Review Focus - **Title copy change**: `"Missing Models (4)"` → `"Missing Models"`. Search-filter matching against the old `(n)` string no longer applies, but the count is shown by the badge and the hero total. - **Sticky header removed**: section headers no longer pin to the top on scroll (intentional per the new design). - **Collapse click target**: the old single-button header (which nested action buttons inside a `<button>` — invalid HTML) is split into a separate title button and chevron button. Behavior is unchanged and accessibility improves; the empty space beside an action button no longer toggles collapse. - All semantic colors map to existing design-system tokens (no `dark:` variants, no hardcoded hex). Verified the artifact hex values match the tokens (e.g. `#262729` = `secondary-background`, `#e04e48` = `destructive-background-hover`, `#171718` = `interface-panel-surface`). ## Follow-up This PR intentionally keeps the error-count ownership cleanup out of the current diff so the card redesign remains reviewable. A follow-up PR will centralize error counting around a single source of truth so the Errors tab summary hero, section badges, and any overlay surfaces cannot drift from one another. That follow-up will also address the current count mismatch in the ErrorOverlay and continue the ErrorOverlay redesign there, instead of expanding this PR after review. ## Screenshots (if applicable) After <img width="603" height="703" alt="스크린샷 2026-06-13 오후 1 00 02" src="https://github.com/user-attachments/assets/065d7c19-9748-4e99-9b43-675a31e92949" /> <img width="601" height="197" alt="스크린샷 2026-06-13 오후 1 01 07" src="https://github.com/user-attachments/assets/0fa1fbda-9091-4a45-9eca-e99c43089c0e" /> <img width="617" height="612" alt="스크린샷 2026-06-13 오후 1 02 43" src="https://github.com/user-attachments/assets/3d67a057-bf65-4e51-bcf5-70ecce851826" /> <img width="495" height="723" alt="스크린샷 2026-06-13 오후 1 03 28" src="https://github.com/user-attachments/assets/6dcc4021-0fc3-4955-a68b-c0533c66a3cf" /> --------- Co-authored-by: GitHub Action <action@github.com> |
||
|
|
1b90696459 |
Simplify missing media error presentation (#12705)
## Summary This is the second PR in the planned Workflow Overview error-tab modernization stack. It follows the merged execution-error slice in #12683 and focuses only on Missing Media / Missing Inputs. The intent is to simplify missing-media errors from media-type/file-resolution cards into compact node-level guidance. Missing media is now presented as a flat list of affected node inputs, matching the new catalog-driven item-row direction introduced by the first PR while intentionally avoiding the larger missing-node, swap-node, and missing-model redesigns. This PR also removes the upload/library selection workflow from the error tab. Missing media rows now help the user locate the affected node/input directly, rather than attempting to resolve the missing file inside the error card. ## Changes - **What**: Simplifies the Missing Inputs card into a flat list of affected node/widget rows. - **What**: Displays each missing media row with a catalog-resolved item label in the form `{nodeName} - {inputName}`. - **What**: Makes both the row label and right-aligned locate icon navigate to the affected node on canvas. - **What**: Adds item-specific accessible labels for locate icon buttons and an explicit focus-visible state for clickable row labels. - **What**: Uses the existing `list-scale` transition pattern so missing media rows animate consistently when they enter or leave. - **What**: Removes the old image/video/audio sub-sections from the missing-media card. - **What**: Removes missing-media upload/dropzone/library-selection/status/confirm/cancel UI, because resolution is no longer handled inside this card. - **What**: Removes stale E2E selectors and tests tied to the deleted upload/library controls. - **What**: Removes stale English missing-media locale keys for the deleted controls; translated locale files are intentionally left to the localization sync process. - **What**: Removes stale missing-media store interaction state (`expandState`, `uploadState`, `pendingSelection`) and the now-unused name-based removal API that only supported the deleted upload/library flow. - **What**: Keeps the remaining widget/node/prefix candidate-removal APIs used by the missing-media lifecycle. - **What**: Carries `nodeType` through missing-media referencing nodes so fallback labels remain correct when the same missing filename is referenced by multiple node types. - **Breaking**: None expected. This changes the missing-media error-tab UX, but does not change the workflow schema or backend APIs. - **Dependencies**: None. ## Planned stack This PR is part of the same staged redesign plan described in #12683. The goal is to keep each error category reviewable and stable before moving to the next slice. 1. Execution errors, merged in #12683: validation, runtime, and prompt error grouping/presentation. 2. Missing media, this PR: simplify image/video/audio missing-media cards into node-level catalog item rows with locate actions. 3. Missing node and swap node: align missing-pack rows, nested node references, install/replace actions, and locate behavior. 4. Missing model: unify OSS and Cloud presentation, simplify download/import actions, and improve import/download progress behavior. This PR intentionally does not change missing node packs, swap nodes, missing models, runtime errors, validation errors, or prompt errors. ## Review Focus - Missing media rows should now be node-level rows, not file-level rows and not image/video/audio sections. - If the same missing media filename is referenced by multiple nodes, each affected node/input should render as its own row. - Clicking either the row label or locate icon should focus the corresponding affected node. - Removed upload/library controls are intentional and should not be restored in this PR. - The missing-media store cleanup should not remove any state or API still used by the remaining missing-media lifecycle. - Only `rightSidePanel.missingMedia.missingMediaTitle` should remain in the English locale for the old missing-media UI namespace; new row copy lives in the error catalog. - This PR should stay scoped to Missing Media / Missing Inputs and should not include the larger missing model/node/swap redesign work. ## Screenshots (if applicable) This PR <img width="483" height="339" alt="스크린샷 2026-06-08 오후 8 26 43" src="https://github.com/user-attachments/assets/e029411e-b1db-41cd-aa6e-2bd5d86762f6" /> Before (Main) <img width="484" height="802" alt="스크린샷 2026-06-08 오후 8 32 19" src="https://github.com/user-attachments/assets/c183c18d-babe-4f4e-b4e0-706ce41298de" /> ## Validation - `pnpm format` - `pnpm test:unit src/platform/missingMedia/missingMediaStore.test.ts src/components/rightSidePanel/errors/TabErrors.test.ts src/platform/errorCatalog/errorMessageResolver.test.ts src/platform/missingMedia/missingMediaScan.test.ts src/platform/missingMedia/missingMediaAssetResolver.test.ts` - `pnpm typecheck` - `pnpm knip --cache` - `pnpm test:browser:local browser_tests/tests/propertiesPanel/errorsTabMissingMedia.spec.ts --project=chromium` - Pre-push hook: `pnpm knip --cache` ## Review notes Claude review was run after the main implementation and again after cleanup. No blocker or major issues remained. The only final minor finding was stale inline i18n fixture data in `TabErrors.test.ts`, which was removed in the final commit. |
||
|
|
74b9f16b62 |
Refine execution error presentation (#12683)
## Summary This is the first PR in a planned stack to modernize the Workflow Overview error tab. It focuses only on execution-style errors: validation errors, runtime errors, and known prompt errors. The intent is to establish the catalog-driven presentation model before touching the larger missing-resource cards. Validation and prompt errors are known product states, so this PR makes them read more like structured guidance instead of generic reportable failures. Runtime errors remain reportable, but their details are reorganized so the error log is easier to scan and copy. ## What changed - Groups validation errors by error catalog id instead of node class/type. - Adds an `unknown_validation_error` fallback catalog id so validation grouping can follow one rule without special-case missing catalog ids. - Shows validation group title and message once, then lists each affected input as a compact item row. - Adds per-item validation detail disclosure so detailed validation text is still available without repeating the group title/message for every item. - Keeps locate-node behavior available from validation rows, including keyboard/ARIA disclosure wiring. - Removes GitHub, copy, and help actions from validation/prompt errors because these are known, cataloged errors where the UI copy should guide the user directly. - Refines runtime error cards so the error log is visible by default, has its own header, and keeps copy/report actions inside the log area. - Removes the special full-panel singleton runtime layout so runtime errors keep the same fixed card rhythm as the other error groups. - Keeps runtime errors reportable via Get Help and Find on GitHub, because these can still represent unexpected execution failures. - Updates prompt error detail styling to match the darker runtime error-log treatment. - Restores display-message semantics for grouped execution messages: `displayMessage ?? message` is used for user-facing dedupe instead of raw backend-only messages. - Adds focused unit coverage for catalog grouping, fallback validation catalog ids, display-message grouping, runtime detail behavior, and the updated prompt/validation action model. ## Planned stack This PR intentionally keeps the first slice narrow. The broader redesign is planned as a sequence of follow-up PRs rather than one large change: 1. Execution errors, this PR: validation, runtime, and prompt error grouping/presentation. 2. Missing media: simplify image/video/audio missing-media cards around catalog item labels and locate actions. 3. Missing node and swap node: align missing-pack rows, nested node references, install/replace actions, and locate behavior. 4. Missing model: unify OSS and Cloud presentation, simplify download/import actions, and improve import/download progress behavior. The goal is to review and stabilize each slice before stacking the next one. This is especially important because later missing-model changes are much larger and should not obscure the catalog/error-card behavior introduced here. ## Review focus - Validation errors should now group by catalog id, not by node class. - Validation groups intentionally show one message per group, with individual affected inputs rendered as rows. - Prompt and validation errors intentionally no longer show report/copy/help actions. - Runtime errors intentionally still show report actions, but only inside the error-log panel. - Node id badges are intentionally not shown in these execution error rows; the follow-up missing-resource PRs will handle their own row treatments separately. - This PR does not change missing media, missing model, missing node pack, or swap node cards. ## Screenshots ### This PR Validation error <img width="457" height="362" alt="스크린샷 2026-06-07 오전 4 26 19" src="https://github.com/user-attachments/assets/4c35b9f3-57dd-4dae-b44a-6d2fd8547b7c" /> Runtime error <img width="454" height="545" alt="스크린샷 2026-06-07 오전 4 24 24" src="https://github.com/user-attachments/assets/b7d4482f-b35b-4ed2-90f2-0a62dafa3519" /> Prompt / Service error <img width="456" height="192" alt="스크린샷 2026-06-07 오전 4 27 58" src="https://github.com/user-attachments/assets/aeec0978-b47f-40c7-ab71-0a0d18ceb054" /> ### Old (main) Validation error <img width="457" height="853" alt="스크린샷 2026-06-07 오전 4 25 09" src="https://github.com/user-attachments/assets/185dd573-430d-4041-8b31-a8eb6346f1ff" /> Runtime error <img width="455" height="554" alt="스크린샷 2026-06-07 오전 4 24 58" src="https://github.com/user-attachments/assets/deb1c09d-ea58-4d6a-9ac6-d2a3a9832fbe" /> Prompt / Service error <img width="455" height="297" alt="스크린샷 2026-06-07 오전 4 28 14" src="https://github.com/user-attachments/assets/c68eef7c-6525-4a5b-858c-6482fe76ad27" /> ## Validation - `pnpm format:check` - `pnpm test:unit src/components/rightSidePanel/errors/TabErrors.test.ts src/components/rightSidePanel/errors/ErrorNodeCard.test.ts src/components/rightSidePanel/errors/useErrorGroups.test.ts src/platform/errorCatalog/errorMessageResolver.test.ts` - `pnpm typecheck` - `pnpm lint` - `pnpm knip` - `pnpm build` |
||
|
|
874b486640 |
fix: resolve missing resource error messages (#12646)
## Summary Resolve missing resource error groups through the error catalog so missing nodes, replaceable nodes, missing models, and missing media use consistent panel and single-error overlay copy. ## Changes - **What**: Adds missing-resource resolvers for `missing_node`, `swap_nodes`, `missing_model`, and `missing_media` that provide `displayMessage`, `toastTitle`, and `toastMessage` alongside the existing group titles. The Errors tab now renders a group-level `displayMessage` under non-execution group headers, which gives grouped missing-resource cards the same explanatory message path used by validation/runtime errors without adding per-row detail fields that these grouped cards do not need. - **What**: Moves missing node and swap node explanatory copy out of card-local hardcoded text and into `errorCatalog.missingErrors.*` keys. `MissingNodeCard` and `SwapNodesCard` now focus on rendering their grouped rows and actions, while the shared error group header owns the explanatory copy. - **What**: Adds environment-aware copy for missing node packs and missing models. Cloud messages explain unsupported resources and replacement/import paths without suggesting local execution, while OSS messages point users toward installing or downloading the missing resources. - **What**: Adds single-error overlay/toast copy for missing resources. Missing media uses a concise input-focused title/message, missing models distinguish Cloud unsupported models from OSS missing files, and missing nodes/swap nodes use node-type-aware copy. - **What**: Deduplicates missing node and swap node toast decisions by distinct node type so repeated instances of the same missing/replaceable node do not accidentally switch the single-error copy to plural copy. - **What**: Preserves representative missing media candidate metadata so missing media toast copy can use a human-readable node name such as `Load Image is missing a required media file.` - **What**: Removes unused missing-resource resolver fields such as grouped `displayDetails`, grouped `displayItemLabel`, and the unused `mediaTypes` source parameter after deciding those fields do not fit grouped missing-resource cards. - **Breaking**: None. - **Dependencies**: None. ## Review Focus - Missing resource groups are still grouped cards. This PR intentionally gives them group-level display and toast copy, but does not split missing resources into one error item per underlying candidate. - Missing resource count semantics are intentionally not normalized here. Error overlay totals, store counts, and grouped card counts still follow the existing behavior; a follow-up PR can define those count units separately. - The Cloud/OSS message variants remain explicit in the resolver instead of being abstracted into a generic variant helper. That keeps this PR focused on the messaging behavior and avoids a broader resolver refactor. - Only `src/locales/en/main.json` is updated directly. Other locales should be synced by the existing localization flow. ## Screenshots (if applicable) <img width="668" height="245" alt="스크린샷 2026-06-05 오전 3 16 49" src="https://github.com/user-attachments/assets/98b50ac3-67e1-438d-8c37-e06c7bf465ee" /> <img width="666" height="195" alt="스크린샷 2026-06-05 오전 3 16 58" src="https://github.com/user-attachments/assets/92da95b1-03d6-4739-97e6-c573982bfec9" /> <img width="505" height="358" alt="스크린샷 2026-06-05 오전 3 17 27" src="https://github.com/user-attachments/assets/4d0e1a6e-13b9-4097-9fb5-19fe0c5331dc" /> <img width="507" height="324" alt="스크린샷 2026-06-05 오전 3 17 44" src="https://github.com/user-attachments/assets/054e42f8-0d0c-44b5-8a67-e467fc04f1fc" /> ## Validation - `pnpm format` - `pnpm lint` - `pnpm test:unit src/platform/errorCatalog/errorMessageResolver.test.ts src/components/rightSidePanel/errors/useErrorGroups.test.ts src/components/rightSidePanel/errors/TabErrors.test.ts` - `pnpm typecheck` - push hook: `knip --cache` |
||
|
|
f9cbaf750f |
fix: simplify error overlay messaging (#12598)
## Summary Simplifies the error overlay so it presents one clear title, one clear message, and one stable details action instead of rendering a list of per-error messages. ## Changes - **What**: Extracts the error overlay view model into `useErrorOverlayState`, adds focused unit coverage for the overlay copy resolution rules, and updates the overlay E2E coverage to match the new behavior. - **Breaking**: None. - **Dependencies**: None. ### Behavior changes - The overlay body no longer renders a `<ul>` of individual error messages. It now always renders a single paragraph message. - Single-error overlays now prefer toast-specific copy when it exists. For execution errors, the overlay resolves the message in this order: `toastMessage`, `displayMessage`, raw `message`, group `displayMessage`, then group `displayTitle`. The title resolves from `toastTitle`, then `displayTitle`, then the group title. - Single non-execution groups use group-level toast/display copy. This lets grouped error types supply overlay-friendly copy without the overlay needing to understand each card implementation. - Multiple-error overlays now ignore individual error item copy in the overlay itself. The header becomes the pluralized count title, for example `7 errors found`, and the body becomes the fixed guidance message: `Resolve them before running the workflow.` - The overlay is hidden if the store reports an error count but no resolved overlay message exists. This avoids rendering a visible shell with an empty body. - The action button no longer varies by error type in normal app mode. Missing nodes, missing models, missing media, swap nodes, validation errors, and runtime errors all use `View details` instead of labels like `Show missing nodes`, `Show missing models`, `Show missing inputs`, or `See Errors`. - App mode keeps its existing `Show errors in graph` action label. - The overlay width now keeps the previous width as its minimum and allows a wider maximum, reducing avoidable wrapping in longer error headers. - The live region was softened from an assertive alert-style announcement to `role="status"` with `aria-live="polite"` so updates such as count changes are less disruptive. ### Tests - Adds component coverage for the rendered overlay shape and app-mode action label. - Adds composable coverage for single execution errors, runtime errors, grouped missing media errors, multiple-error aggregate copy, hidden empty-message state, and display-copy fallback behavior. - Updates `errorOverlay.spec.ts` so the E2E suite checks the new single-message overlay, the stable `View details` action, and the fixed multiple-error body guidance. - Removes the old type-specific button-label E2E expectations because that branch no longer exists in product behavior. ### Follow-up PR A follow-up PR is stacked on top of this one: `jaeone/fe-816-missing-resource-error-messaging`. That follow-up will wire missing resource error resolvers into the copy model consumed here. It covers missing node packs, missing models, missing media, and swap-node groups, including the group-level `toastTitle`, `toastMessage`, `displayMessage`, `displayDetails`, and item label copy those cards need. This PR intentionally keeps the overlay behavior separate so it can merge first without depending on the missing-resource resolver copy. ## Review Focus - Please check the single-error versus multiple-error overlay behavior, especially the fallback order for execution error copy. - Please check that the `View details` action is now intentionally error-type agnostic in normal app mode while app mode keeps `Show errors in graph`. - Please check the empty-message guard and the requirement that a single-error overlay only resolves a single group when the total error count and group list agree. - Please check the E2E reduction: the old type-specific action-label assertions were removed because the UI branch they tested was removed. ## Screenshots (if applicable) N/A |
||
|
|
79f2904937 |
Add special runtime error messaging (#12466)
## Summary
This PR extends the error catalog with targeted runtime error messaging
for common workflow execution failures.
The goal is to show clearer, user-facing copy in the error panel while
preserving the raw API `message` and `details` fields on each error
item. The resolver continues to add display-only fields (`displayTitle`,
`displayMessage`, `displayDetails`, `displayItemLabel`, `toastTitle`,
`toastMessage`) so the UI can render friendlier messages without
changing the underlying error contract.
## What This PR Targets
This PR adds catalog handling for common runtime failure categories,
including:
- General execution failure fallback for uncataloged node runtime errors
- Content blocked / safety check failures
- Credits, subscription, access, and sign-in related failures
- Rate limit and busy-server style failures
- Runtime timeout, stalled generation, and preparation failure cases
- Server stopped / unavailable cases
- Out-of-memory failures
- Image load failures
- Invalid CLIP input failures
- Invalid prompt and invalid workflow request failures
- Request/start/end failure cases
- Model access and model download failures
- Unexpected service failures
Unknown node execution errors resolve to the general runtime fallback:
- Title: `Execution failed`
- Message: `Node threw an error during execution.`
- Item label: node name
- Toast title: `{nodeName} failed`
- Toast message: `This node threw an error during execution. Check its
inputs or try a different configuration.`
## Implementation Notes
### Resolver Split
The previous resolver file was doing too much, so this PR splits
source-specific catalog logic into smaller modules:
- `catalogIds.ts` defines FE-resolved catalog IDs that normalize
multiple sources or do not map 1:1 to an API error type.
- `catalogI18n.ts` owns shared translation/fallback helpers.
- `validationErrorResolver.ts` keeps validation catalog logic.
- `promptErrorResolver.ts` keeps prompt-specific catalog logic and
handles non-node-scoped failures before falling back to prompt-specific
keys.
- `executionErrorResolver.ts` handles node-scoped runtime errors.
- `runtimeErrorMatcher.ts` owns conservative runtime error matching.
- `runtimeErrorCopy.ts` builds runtime display/toast fields from catalog
IDs and fallback copy.
- `missingErrorResolver.ts` keeps the existing missing-model/node/media
group display copy.
`errorMessageResolver.ts` is now a thin facade over these smaller
resolvers.
### Conservative Matching
Runtime errors can share generic exception labels, so this PR keeps
matching narrow: exact strings or stable prefixes only. The matcher is
ordered, and the first matching rule wins, so specific user-actionable
failures are checked before broader fallbacks.
The matching is intentionally not fuzzy. For example, arbitrary messages
that merely mention moderation terminology are not treated as
content-blocked unless they match one of the known client-visible
failure strings. This avoids false positives while covering the targeted
high-volume cases.
### Raw Detail Preservation
Some cataloged errors keep the original message as `displayDetails` when
it contains useful troubleshooting context. This is display-only; the
raw API `message` and `details` fields remain unchanged on the original
error item.
## Out Of Scope / Follow-Ups
This PR does not redesign the error overlay or right-side error panel
UI. It only provides the resolved fields those surfaces can consume.
Planned follow-up work remains:
- Regroup execution errors by message/catalog type where appropriate
- Error overlay copy/layout updates for single vs multiple errors
- Right panel visual design updates
- Rendering `displayItemLabel` in the revised panel design
- More specific UI actions for auth, retry, and similar flows
- Broader fallthrough observability if we decide it is needed
Non-English locale files are intentionally not updated here. The
repository uses `src/locales/en/main.json` as the source of truth and
the release i18n sync flow generates the other locale files.
## Validation
Ran successfully:
- `pnpm format`
- `pnpm lint:unstaged`
- `pnpm typecheck`
- `pnpm test:unit`
- `pnpm vitest run
src/platform/errorCatalog/errorMessageResolver.test.ts`
- `pnpm vitest run
src/platform/errorCatalog/errorMessageResolver.test.ts
src/components/rightSidePanel/errors/useErrorGroups.test.ts`
- `pnpm build`
- `pnpm knip`
Notes:
- `pnpm build` still prints existing asset/icon and dynamic import
warnings, but exits successfully.
- `pnpm knip` exits successfully and still reports the existing
`flac.ts` tag hint.
## Screenshots (Before / After)
[Diff.zip](https://github.com/user-attachments/files/28300639/Diff.zip)
Uploaded as a ZIP file due to the image upload limit
|
||
|
|
c0ef283a05 |
General execution error messaging (#12448)
## Summary This PR builds on the error catalog display resolver foundation from #12402 and adds the first broader catalog pass for general execution-related messaging. The goal is to keep the raw API contract intact (`message` / `details`) while adding resolved display fields that the UI can prefer when catalog copy exists. The main functional sample in this PR is validation error messaging. It expands the resolver beyond `required_input_missing` so common node validation failures can show friendlier titles, grouped messages, detail copy, item labels, and toast copy without overwriting the original backend payload. ## What changed - Added catalog copy for known node validation errors: - `required_input_missing` as `missing_connection` - `bad_linked_input` - `return_type_mismatch` - `invalid_input_type` - `value_smaller_than_min` - `value_bigger_than_max` - `value_not_in_list` - `custom_validation_failed` - `exception_during_inner_validation` - `exception_during_validation` - `dependency_cycle` - Added an `image_not_loaded` validation override for `custom_validation_failed` messages that indicate invalid image files or directory paths. - Added value-aware validation details when Core provides structured `extra_info`, including received values, expected/received types, and min/max bounds. - Added prompt-level catalog handling for known prompt errors that already have stable types/copy, including missing node type, prompt output validation, image download, and OOM prompt errors. - Preserved runtime execution errors as raw API copy for now, so service-level or actionable runtime failures are not hidden behind generic catalog text before targeted runtime handling lands. - Added/updated English `errorCatalog` i18n keys for the new validation and prompt catalog copy. - Added resolver and grouping tests for the new catalog paths, raw fallback behavior, runtime raw preservation, prompt copy, and image-not-loaded detection. ## Screenshots (diff) ### Before <img width="371" height="346" alt="Old_1" src="https://github.com/user-attachments/assets/bd474869-7428-4f68-a067-bb412aa95d3b" /> <img width="373" height="296" alt="Old_2" src="https://github.com/user-attachments/assets/fc393792-dc6d-46fb-b7df-20290b35e30e" /> <img width="370" height="292" alt="Old_3" src="https://github.com/user-attachments/assets/bcb867ea-12ba-49b7-887a-ce06afa60475" /> <img width="370" height="269" alt="Old_4" src="https://github.com/user-attachments/assets/05caeff8-2597-4c95-97cf-2736825b85f3" /> <img width="371" height="292" alt="Old_5" src="https://github.com/user-attachments/assets/dd58113e-5953-4701-b597-d59cb6e124e9" /> <img width="373" height="282" alt="Old_6" src="https://github.com/user-attachments/assets/60fb02c0-4ed6-4734-926c-f8a20f0aeb1c" /> <img width="371" height="279" alt="Old_7" src="https://github.com/user-attachments/assets/a3453b5c-c779-4f43-af27-97cc9a083480" /> <img width="370" height="292" alt="Old_8" src="https://github.com/user-attachments/assets/59d08636-c1b3-4cde-a340-befb48726ee8" /> <img width="371" height="276" alt="Old_9" src="https://github.com/user-attachments/assets/7a94465b-ed5c-4ad9-a40a-cfe3c08d3dc7" /> <img width="368" height="279" alt="Old_10" src="https://github.com/user-attachments/assets/3f791ff3-e3e3-4cb7-aab1-640ec1cee751" /> <img width="370" height="276" alt="Old_11" src="https://github.com/user-attachments/assets/9c0f28c2-4f60-4f38-b3c4-5560609e329e" /> <img width="370" height="279" alt="Old_12" src="https://github.com/user-attachments/assets/4b61545e-db7e-4512-b300-e883ab37f347" /> ### After <img width="426" height="301" alt="New_1" src="https://github.com/user-attachments/assets/9874c036-2b3d-4b7c-ac3d-cb9c396c597f" /> <img width="421" height="301" alt="New_2" src="https://github.com/user-attachments/assets/38cd0f35-53a4-490a-b47f-da21eaa44fc8" /> <img width="418" height="347" alt="New_3" src="https://github.com/user-attachments/assets/db5ab3cc-f246-407d-b80b-9ad92c95c7ad" /> <img width="425" height="327" alt="New_4" src="https://github.com/user-attachments/assets/4333c2b8-3077-4122-9719-21d56a7b2230" /> <img width="424" height="325" alt="New_5" src="https://github.com/user-attachments/assets/6616d61f-fa90-4d2f-b8fd-50ac5a3f32cb" /> <img width="423" height="326" alt="New_6" src="https://github.com/user-attachments/assets/02a4f97a-708e-4c00-b061-d8e4dcaacd8f" /> <img width="424" height="323" alt="New_7" src="https://github.com/user-attachments/assets/9d1e96c9-69de-4e26-a152-1a101675c5eb" /> <img width="425" height="327" alt="New_8" src="https://github.com/user-attachments/assets/ffa66faf-1a33-43a3-b604-25352195f28c" /> <img width="425" height="323" alt="New_9" src="https://github.com/user-attachments/assets/f7eb5f0c-4d0c-4f1b-aa3d-30358fbc9943" /> <img width="423" height="328" alt="New_10" src="https://github.com/user-attachments/assets/72665c97-ec61-4e5a-b702-379baf919822" /> <img width="423" height="351" alt="New_11" src="https://github.com/user-attachments/assets/c5376f02-7a62-42e6-9cda-e50ab6d41b04" /> <img width="425" height="326" alt="New_12" src="https://github.com/user-attachments/assets/413df105-dc7e-4289-90b0-30ecaa417c84" /> ## Intentional boundaries This PR does not add targeted runtime/cloud-specific message matching yet. Runtime execution errors still use the original exception message and traceback in the error panel. This is intentional because cloud/service runtime errors can include actionable strings such as auth, payment, rate limit, timeout, moderation, or infrastructure failures, and collapsing those too early would make the UX worse. This PR also does not change the overlay or right-side panel design. It only prepares and fills resolved display fields so the next stacked PRs can consume them with much less plumbing. ## Follow-up PR plan - Add targeted runtime/cloud-specific messaging for high-volume errors such as credits, timeouts, disallowed content, rate limit, sign-in/payment requirements, and server crash style failures. - Revisit runtime execution grouping once runtime catalog IDs are explicit enough to group by message category rather than node class or raw exception text. - Update the error overlay to use single-error toast title/message fields and multi-error aggregate copy. - Update the right-side error panel design, including item labels such as `Node name - input/widget name`. - Consider splitting `errorMessageResolver.ts` by error family (`validation`, `prompt`, `runtime`, `cloud-specific`) before adding more runtime-specific rules. ## Validation - `pnpm exec vitest run src/platform/errorCatalog/errorMessageResolver.test.ts src/components/rightSidePanel/errors/useErrorGroups.test.ts` - `pnpm typecheck` - Commit hooks ran staged formatting, lint fixes, and `pnpm typecheck`. - Push hook ran `knip --cache`; it completed with an existing tag-hint warning for `src/scripts/metadata/flac.ts`. |
||
|
|
654a7d6904 |
Add error catalog display resolver (#12402)
## Summary This PR introduces the frontend error catalog display resolver as the foundation for the DES-220 / FE-816 error messaging work. The main goal is to create a single FE boundary where raw Core/Cloud error payloads can be converted into human-friendly display fields, while preserving the original API contract fields (`message` and `details`) unchanged. UI components can now prefer resolved display copy when it exists and fall back to the raw API copy otherwise. As a small concrete sample, this PR implements the first cataloged validation error: - `required_input_missing` is resolved as the `missing_connection` catalog item. - Panel title: `Missing connection` - Panel message: `Required input slots have no connection feeding them.` - Detail/item copy can include the node and input name, e.g. `KSampler is missing a required input: model` and `KSampler - model`. - Single-error toast/overlay-oriented fields are added to the data model for follow-up UI work, but this PR does not redesign the overlay. ## What This PR Targets This PR is intentionally scoped as the skeleton PR for the error catalog UX system. It adds: - A new resolver module under `src/platform/errorCatalog`. - Shared resolved display fields: - `catalogId` - `displayTitle` - `displayMessage` - `displayDetails` - `displayItemLabel` - `toastTitle` - `toastMessage` - A resolver entry point for run-time workflow errors: - node validation errors - execution/runtime errors - prompt errors - A resolver entry point for pre-run missing-resource groups: - missing node packs - swap nodes - missing models - missing media - Error group wiring so `useErrorGroups` resolves display copy in one place instead of making UI components own message decisions. - The first real validation rule for `required_input_missing` / Missing connection. - The existing prompt error copy moved into the `errorCatalog.promptErrors` namespace in `src/locales/en/main.json`. - Tests covering the resolver, grouping behavior, panel rendering, prompt error copy, missing group copy, and fallback behavior. ## What This PR Deliberately Does Not Target This PR avoids the larger UX and product behavior changes so the foundation can land separately. It does not: - Redesign the error overlay. - Redesign the right-side error panel. - Change the shape of Core/Cloud API error payloads. - Replace raw `message` / `details`; those remain intact for API-contract alignment and technical debugging. - Re-group execution errors by final message type yet. - Add special runtime error messaging for credits, timeouts, content policy, OOM, or rate limits. - Render the new `displayItemLabel` everywhere it will eventually be useful. ## User-Facing Behavior Most behavior is preserved. The main visible change is for missing required input validation errors. Those now display as Missing connection copy instead of exposing the raw validation message directly. Prompt errors should keep the same user-facing wording as before, but the source of that wording now lives under the error catalog namespace. Missing node/model/media/swap-node groups still preserve the existing titles, counts, and friendly messages, but their display copy now flows through the same resolver boundary. Execution/runtime errors receive catalog fields for future toast/overlay usage, but the current runtime overlay path intentionally keeps the raw technical error copy until the overlay redesign PR decides how to consume the new fields. ## Screenshots Before <img width="505" height="266" alt="스크린샷 2026-05-22 오후 2 15 27" src="https://github.com/user-attachments/assets/09e8eb31-dca4-42d8-8237-9474cb71a14c" /> <img width="463" height="317" alt="스크린샷 2026-05-22 오후 2 16 09" src="https://github.com/user-attachments/assets/c0a0159e-5bd9-4b3f-9c21-c0040373fbca" /> After <img width="482" height="297" alt="스크린샷 2026-05-22 오후 2 14 25" src="https://github.com/user-attachments/assets/4ca10bf0-29d2-4b65-940e-0d78db3fd278" /> <img width="460" height="194" alt="스크린샷 2026-05-22 오후 2 16 55" src="https://github.com/user-attachments/assets/20848054-5012-4dd3-b903-ef8c920f70c8" /> ## Follow-Up PR Plan This PR is the first stacked PR in the error catalog work. Follow-up PRs are expected to build on this foundation in roughly this order: 1. Expand general execution error messaging. - Add broader validation error handling beyond `required_input_missing`, including list/range/value validation cases. - Add general runtime execution messaging. - Continue migrating prompt error display decisions into the catalog resolver. 2. Add special runtime error messaging. - Credits / insufficient credits. - Timeout. - Content not allowed / blocked content. - Server crash. - Out of memory. - Rate limiting. - Other high-volume Cloud-only runtime failures from DES-220. 3. Re-group execution errors by message/catalog type. - Move away from grouping primarily by node class when the cataloged error type is the more useful user-facing grouping key. - Keep raw technical details available inside cards/logs. 4. Update the error overlay behavior. - Use `toastTitle` and `toastMessage` for single-error cases. - Use aggregate copy such as "N errors found" for multi-error cases. - Add node navigation affordances where appropriate. 5. Update the right-side error panel design. - Render resolved item labels such as `Node name - Input name`. - Align expanded card details and logs with the new design. - Preserve copy/debug affordances for technical details. 6. Fold in related missing media/model/node messaging improvements. - FE-583 should become a child/follow-up issue in this stack for improving missing image/media messaging. ## Validation - `pnpm format` - `pnpm lint` - `pnpm typecheck` - `pnpm test:unit` - Targeted resolver/grouping tests during review iterations - `pnpm knip` `pnpm knip` passes with only the pre-existing tag hint: `Unused tag in src/scripts/metadata/flac.ts: getFromFlacBuffer → @knipIgnoreUnusedButUsedByCustomNodes` |
||
|
|
693b8383d6 |
fix: missing-asset correctness follow-ups from #10856 (#11233)
Follow-up to #10856. Four correctness issues and their regression tests. ## Bugs fixed ### 1. ErrorOverlay model count reflected node selection `useErrorGroups` exposed `filteredMissingModelGroups` under the public name `missingModelGroups`. `ErrorOverlay.vue` read that alias to compute its model count label, so selecting a node shrank the overlay total. The overlay must always show the whole workflow's errors. Exposed both shapes explicitly: `missingModelGroups` / `missingMediaGroups` (unfiltered totals) and `filteredMissingModelGroups` / `filteredMissingMediaGroups` (selection-scoped). `TabErrors.vue` destructures the filtered variant with an alias. Before https://github.com/user-attachments/assets/eb848c5f-d092-4a4f-b86f-d22bb4408003 After https://github.com/user-attachments/assets/75e67819-c9f2-45ec-9241-74023eca6120 ### 2. Bypass → un-bypass dropped url/hash metadata Realtime `scanNodeModelCandidates` only reads widget values, so un-bypass produced a fresh candidate without the url that `enrichWithEmbeddedMetadata` had previously attached from `graphData.models`. `MissingModelRow`'s download/copy-url buttons disappeared after a bypass/un-bypass cycle. Added `enrichCandidateFromNodeProperties` that copies `url`/`hash`/`directory` from the node's own `properties.models` — which persists across mode toggles — into each scanned candidate. Applied to every call site of the per-node scan. A later fix in the same branch also enforces directory agreement to prevent a same-name / different-directory collision from stamping the wrong metadata. Before https://github.com/user-attachments/assets/39039d83-4d55-41a9-9d01-dec40843741b After https://github.com/user-attachments/assets/047a603b-fb52-4320-886d-dfeed457d833 ### 3. Initial full scan surfaced interior errors of a muted/bypassed subgraph container `scanAllModelCandidates`, `scanAllMediaCandidates`, and the JSON-based missing-node scan only check each node's own mode. Interior nodes whose parent container was bypassed passed the filter. Added `isAncestorPathActive(rootGraph, executionId)` to `graphTraversalUtil` and post-filter the three pipelines in `app.ts` after the live rootGraph is configured. The filter uses the execution-ID path (`"65:63"` → check node 65's mode) so it handles both live-scan-produced and JSON-enrichment-produced candidates. Before https://github.com/user-attachments/assets/3032d46b-81cd-420e-ab8e-f58392267602 After https://github.com/user-attachments/assets/02a01931-951d-4a48-986c-06424044fbf8 ### 4. Bypassed subgraph entry re-surfaced interior errors `useGraphNodeManager` replays `graph.onNodeAdded` for each existing interior node when the Vue node manager initializes on subgraph entry. That chain reached `scanSingleNodeErrors` via `installErrorClearingHooks`' `onNodeAdded` override. Each interior node's own mode was active, so the caller guards passed and the scan re-introduced the error that the initial pipeline had correctly suppressed. Added an ancestor-activity gate at the top of `scanSingleNodeErrors`, the single entry point shared by paste, un-bypass, subgraph entry, and subgraph container activation. A later commit also hardens this guard against detached nodes (null execution ID → skip) and applies the same ancestor check to `isCandidateStillActive` in the realtime verification callback. Before https://github.com/user-attachments/assets/fe44862d-f1d6-41ed-982d-614a7e83d441 After https://github.com/user-attachments/assets/497a76ce-3caa-479f-9024-4cd0f7bd20a4 ## Tests - 6 unit tests for `isAncestorPathActive` (root, active, immediate-bypass, deep-nested mute, unresolvable ancestor, null rootGraph) - 4 unit tests for `enrichCandidateFromNodeProperties` (enrichment, no-overwrite, name mismatch, directory mismatch) - 1 unit test for `scanSingleNodeErrors` ancestor guard (subgraph entry replaying onNodeAdded) - 2 unit tests for `useErrorGroups` dual export + ErrorOverlay contract - 4 E2E tests: - ErrorOverlay model count stays constant when a node is selected (new fixture `missing_models_distinct.json`) - Bypass/un-bypass cycle preserves Copy URL button (uses `missing_models_from_node_properties`) - Loading a workflow with bypassed subgraph suppresses interior missing model error (new fixture `missing_models_in_bypassed_subgraph.json`) - Entering a bypassed subgraph does not resurface interior missing model error (shares the above fixture) `pnpm typecheck`, `pnpm lint`, 206 related unit tests passing. ## Follow-up Several items raised by code review are deferred as pre-existing tech debt or scope-avoided refactors. Tracked via comments on #11215 and #11216. --- Follows up on #10856. |
||
|
|
661e3d7949 |
test: migrate as unknown as to @total-typescript/shoehorn (#10761)
*PR Created by the Glary-Bot Agent* --- ## Summary - Replace all `as unknown as Type` assertions in 59 unit test files with type-safe `@total-typescript/shoehorn` functions - Use `fromPartial<Type>()` for partial mock objects where deep-partial type-checks (21 files) - Use `fromAny<Type>()` for fundamentally incompatible types: null, undefined, primitives, variables, class expressions, and mocks with test-specific extra properties that `PartialDeepObject` rejects (remaining files) - All explicit type parameters preserved so TypeScript return types are correct - Browser test `.spec.ts` files excluded (shoehorn unavailable in `page.evaluate` browser context) ## Verification - `pnpm typecheck` ✅ - `pnpm lint` ✅ - `pnpm format` ✅ - Pre-commit hooks passed (format + oxlint + eslint + typecheck) - Migrated test files verified passing (ran representative subset) - No test behavior changes — only type assertion syntax changed - No UI changes — screenshots not applicable ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-10761-test-migrate-as-unknown-as-to-total-typescript-shoehorn-3336d73d365081f6b8adc44db5dcc380) by [Unito](https://www.unito.io) --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: Amp <amp@ampcode.com> |
||
|
|
66daa6d645 |
refactor: error system cleanup — store separation, DDD fix, test improvements (#10302)
## Summary Refactors the error system to improve separation of concerns, fix DDD layer violations, and address code quality issues. - Extract `missingNodesErrorStore` from `executionErrorStore`, removing the delegation pattern that coupled missing-node logic into the execution error store - Extract `useNodeErrorFlagSync` composable for node error flag reconciliation (previously inlined) - Extract `useErrorClearingHooks` composable with explicit callback cleanup on node removal - Extract `useErrorActions` composable to deduplicate telemetry+command patterns across error card components - Move `getCnrIdFromNode`/`getCnrIdFromProperties` to `platform/nodeReplacement` layer (DDD fix) - Move `missingNodesErrorStore` to `platform/nodeReplacement` (DDD alignment) - Add unmount cancellation guard to `useErrorReport` async `onMounted` - Return watch stop handle from `useNodeErrorFlagSync` - Add `asyncResolvedIds` eviction on `missingNodesError` reset - Add `console.warn` to silent catch blocks and empty array guard - Hoist `useCommandStore` to setup scope, fix floating promises - Add `data-testid` to error groups, image/video error spans, copy button - Update E2E tests to use scoped locators and testids - Add unit tests for `onNodeRemoved` restoration and double-install guard Fixes #9875, Fixes #10027, Fixes #10033, Fixes #10085 ## Test plan - [x] Existing unit tests pass with updated imports and mocks - [x] New unit tests for `useErrorClearingHooks` (callback restoration, double-install guard) - [x] E2E tests updated to use scoped locators and `data-testid` - [ ] Manual: verify error tab shows runtime errors and missing nodes correctly - [ ] Manual: verify "Find on GitHub", "Copy", and "Get Help" buttons work in error cards ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-10302-refactor-error-system-cleanup-store-separation-DDD-fix-test-improvements-3286d73d365081838279d045b8dd957a) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.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> |
||
|
|
2f7f3c4e56 |
[feat] Surface missing models in Errors tab (Cloud) (#9743)
## Summary When a workflow is loaded with missing models, users currently have no way to identify or resolve them from within the UI. This PR adds a full missing-model detection and resolution pipeline that surfaces missing models in the Errors tab, allowing users to install or import them without leaving the editor. ## Changes ### Missing Model Detection - Scan all COMBO widgets across root graph and subgraphs for model-like filenames during workflow load - Enrich candidates with embedded workflow metadata (url, hash, directory) when available - Verify asset-supported candidates against the asset store asynchronously to confirm installation status - Propagate missing model state to `executionErrorStore` alongside existing node/prompt errors ### Errors Tab UI — Model Resolution - Group missing models by directory (e.g. `checkpoints`, `loras`, `vae`) with collapsible category cards - Each model row displays: - Model name with copy-to-clipboard button - Expandable list of referencing nodes with locate-on-canvas button - **Library selector**: Pick an alternative from the user's existing models to substitute the missing model with one click - **URL import**: Paste a Civitai or HuggingFace URL to import a model directly; debounced metadata fetch shows filename and file size before confirming; type-mismatch warnings (e.g. importing a LoRA into checkpoints directory) are surfaced with an "Import Anyway" option - **Upgrade prompt**: In cloud environment, free-tier subscribers are shown an upgrade modal when attempting URL import - Separate "Import Not Supported" section for custom-node models that cannot be auto-resolved - Status card with live download progress, completion, failure, and category-mismatch states ### Canvas Integration - Highlight nodes and widgets that reference missing models with error indicators - Propagate missing-model badges through subgraph containers so issues are visible at every graph level ### Code Cleanup - Simplify `surfacePendingWarnings` in workflowService, remove stale widget-detected model merging logic - Add `flattenWorkflowNodes` utility to workflowSchema for traversing nested subgraph structures - Extract `MissingModelUrlInput`, `MissingModelLibrarySelect`, `MissingModelStatusCard` as focused single-responsibility components ## Testing - Unit tests for scan pipeline (`missingModelScan.test.ts`): enrichment, skip-installed, subgraph flattening - Unit tests for store (`missingModelStore.test.ts`): state management, removal helpers - Unit tests for interactions (`useMissingModelInteractions.test.ts`): combo select, URL input, import flow, library confirm - Component tests for `MissingModelCard` and error grouping (`useErrorGroups.test.ts`) - Updated `workflowService.test.ts` and `workflowSchema.test.ts` for new logic ## Review Focus - Missing model scan + enrichment pipeline in `missingModelScan.ts` - Interaction composable `useMissingModelInteractions.ts` — URL metadata fetch, library install, upload fallback - Store integration and canvas-level error propagation ## Screenshots https://github.com/user-attachments/assets/339a6d5b-93a3-43cd-98dd-0fb00681b66f ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9743-feat-Surface-missing-models-in-Errors-tab-Cloud-3206d73d365081678326d3a16c2165d8) by [Unito](https://www.unito.io) |
||
|
|
9e2299ca65 |
feat(error-groups): sort execution error cards by node execution ID (#9334)
## Summary Sort execution error cards within each error group by their node execution ID in ascending numeric order, ensuring consistent and predictable display order. ## Changes - **What**: Added `compareExecutionId` utility to `src/types/nodeIdentification.ts` that splits node IDs on `:` and compares segments numerically left-to-right; applied it as a sort comparator when building `ErrorGroup.cards` in `useErrorGroups.ts` ## Review Focus - The comparison treats missing segments as `0`, so `"1"` sorts before `"1:20"` (subgraph nodes follow their parent); confirm this ordering matches user expectations - All comparisons are purely numeric — non-numeric segment values would sort as `NaN` (treated as `0`) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9334-feat-error-groups-sort-execution-error-cards-by-node-execution-ID-3176d73d365081e1b3e4e4fa8831fe16) by [Unito](https://www.unito.io) |
||
|
|
a0e518aa98 |
refactor(node-replacement): reorganize domain components and expand comprehensive test suite (#9301)
## Summary Resolves six open issues by reorganizing node replacement components into a domain-driven folder structure, refactoring event handling to follow the emit pattern, and adding comprehensive test coverage across all affected modules. ## Changes - **What**: - Moved `SwapNodeGroupRow.vue` and `SwapNodesCard.vue` from `src/components/rightSidePanel/errors/` to `src/platform/nodeReplacement/components/` (Issues #9255) - Moved `useMissingNodeScan.ts` from `src/composables/` to `src/platform/nodeReplacement/missingNodeScan.ts`, renamed to reflect it is a plain function not a Vue composable (Issues #9254) - Refactored `SwapNodeGroupRow.vue` to emit a `'replace'` event instead of calling `useNodeReplacement()` and `useExecutionErrorStore()` directly; replacement logic now handled in `TabErrors.vue` (Issue #9267) - Added unit tests for `removeMissingNodesByType` (`executionErrorStore.test.ts`), `scanMissingNodes` (`missingNodeScan.test.ts`), and `swapNodeGroups` computed (`swapNodeGroups.test.ts`, `useErrorGroups.test.ts`) (Issue #9270) - Added placeholder detection tests covering unregistered-type detection when `has_errors` is false, and exclusion of registered types (`useNodeReplacement.test.ts`) (Issue #9271) - Added component tests for `MissingNodeCard` and `MissingPackGroupRow` covering rendering, expand/collapse, events, install states, and edge cases (Issue #9231) - Added component tests for `SwapNodeGroupRow` and `SwapNodesCard` (Issues #9255, #9267) ## Additional Changes (Post-Review) - **Edge case guard in placeholder detection** (`useNodeReplacement.ts`): When `last_serialization.type` is absent (old serialization format), the predicate falls back to `n.type`, which the app may have already run through `sanitizeNodeName` — stripping HTML special characters (`& < > " ' \` =`). In that case, a `Set.has()` lookup against the original unsanitized type name would silently miss, causing replacement to be skipped. Fixed by including sanitized variants of each target type in the `targetTypes` Set at construction time. For the overwhelmingly common case (no special characters in type names), the Set deduplicates the entries and runtime behavior is identical to before. A regression test was added to cover the specific scenario: `last_serialization.type` absent + live `n.type` already sanitized. ## Review Focus - `TabErrors.vue`: confirm the new `@replace` event handler correctly replaces nodes and removes them from missing nodes list (mirrors the old inline logic in `SwapNodeGroupRow`) - `missingNodeScan.ts`: filename/export name change from `useMissingNodeScan` — verify all call sites updated via `app.ts` - Test mocking strategy: module-level `vi.mock()` factories use closures over `ref`/plain objects to allow per-test overrides without global mutable state - Fixes #9231 - Fixes #9254 - Fixes #9255 - Fixes #9267 - Fixes #9270 - Fixes #9271 |