Skip to content

Conversation

@luke-mino-altherr
Copy link
Contributor

@luke-mino-altherr luke-mino-altherr commented Dec 16, 2025

Summary

Adds HuggingFace as a model import source alongside CivitAI, with improved UX for model type selection and UTF-8 filename support.

Changes

  • Import Sources: Implemented extensible import source handler pattern supporting both CivitAI and HuggingFace
  • UTF-8 Support: Decode URL-encoded filenames to properly display international characters (e.g., Chinese)
  • UX: Sort model types alphabetically for easier selection
  • Feature Flag: Added huggingfaceModelImportEnabled flag for gradual rollout
  • i18n: Use proper template parameters for localized error messages

Technical Details

  • Created ImportSourceHandler interface for extensibility
  • Refactored existing CivitAI logic into handler pattern
  • Added URL validation per source
  • Filename decoding handles malformed URLs gracefully

┆Issue is synchronized with this Notion page by Unito

- Add HuggingFace as a model import source alongside CivitAI
- Support URL-encoded filenames (UTF-8 characters like Chinese)
- Sort model types alphabetically for easier selection
- Add feature flag for HuggingFace import enablement
- Implement import source handler pattern for extensibility
- Use proper i18n template parameters for error messages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@luke-mino-altherr luke-mino-altherr added enhancement New feature or request area:models labels Dec 16, 2025
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Dec 16, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 16, 2025

📝 Walkthrough

Walkthrough

Adds Hugging Face as an optional import source behind a new server feature flag; introduces import-source types and implementations; updates upload dialog, inputs, and wizard to detect source, fetch/decode metadata, prefill fields, pre-upload previews, and expose detectedSource; adds i18n keys and remoteConfig flag.

Changes

Cohort / File(s) Summary
Feature flag & remote config
src/composables/useFeatureFlags.ts, src/platform/remoteConfig/types.ts
Added HUGGINGFACE_MODEL_IMPORT_ENABLED to ServerFeatureFlag, exposed huggingfaceModelImportEnabled computed flag; added huggingface_model_import_enabled?: boolean to RemoteConfig.
Import-source types & implementations
src/platform/assets/types/importSource.ts, src/platform/assets/importSources/civitaiImportSource.ts, src/platform/assets/importSources/huggingfaceImportSource.ts
New ImportSourceType and ImportSource interface plus validateSourceUrl function; added civitaiImportSource and huggingfaceImportSource constants describing supported hostnames and types.
Upload wizard & model types
src/platform/assets/composables/useUploadModelWizard.ts, src/platform/assets/composables/useModelTypes.ts
Wizard now uses feature flags to build importSources, detects detectedSource via URL validation, fetches/decodes metadata, pre-fills name/tags/preview, pre-uploads preview image, sets user_metadata.source on upload; model type options now sorted by display name.
Upload dialog components
src/platform/assets/components/UploadModelDialog.vue, src/platform/assets/components/UploadModelDialogHeader.vue, src/platform/assets/components/UploadModelFooter.vue
Conditional rendering gated by feature flag (HF vs Civitai flows); header text/image chosen by flag; footer click handlers switched to :on-click arrow wrappers emitting same events.
URL input variants
src/platform/assets/components/UploadModelUrlInput.vue, src/platform/assets/components/UploadModelUrlInputCivitai.vue
Unified generic URL input layout with attribution and help footer; added new Civitai-specific input component exposing modelValue/error props and update:modelValue emit.
Locales
src/locales/en/main.json
Added and refactored localization keys for generic/Civitai/Hugging Face upload flows, examples, placeholders, help text, and supported-source messaging.
Minor reflow
src/components/graph/GraphCanvas.vue
Reflowed a dynamic import statement across lines with no behavioral change.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Dialog as UploadModelDialog
    participant Wizard as useUploadModelWizard
    participant Source as ImportSource (validator)
    participant Server as Backend API

    User->>Dialog: Enter model URL (Step 1)
    Dialog->>Wizard: set url

    Wizard->>Wizard: read huggingfaceModelImportEnabled flag
    Wizard->>Wizard: build importSources (civitai ± huggingface)
    Wizard->>Source: validateSourceUrl(url) for each source
    Source-->>Wizard: match/no-match
    Wizard->>Wizard: set detectedSource (first match)

    alt source detected
        User->>Dialog: request metadata fetch
        Dialog->>Wizard: fetchMetadata()
        Wizard->>Server: GET metadata (source-specific)
        Server-->>Wizard: metadata (filename, name, tags, preview URL)
        Wizard->>Wizard: decode fields, prefill name/tags/preview, advance step
        Wizard->>Server: upload preview image (if present)
        Server-->>Wizard: preview upload result (continue on failure)
        User->>Dialog: confirm upload
        Dialog->>Wizard: upload()
        Wizard->>Server: POST model with user_metadata.source = detectedSource.type
        Server-->>Wizard: upload complete
    else no source detected
        Wizard->>Dialog: set uploadError (supported sources list)
        Dialog->>User: show error
    end
Loading

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/huggingface-model-import

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 108cfaa and 7eef849.

⛔ Files ignored due to path filters (1)
  • public/assets/images/hf-logo.svg is excluded by !**/*.svg
📒 Files selected for processing (14)
  • src/components/graph/GraphCanvas.vue (1 hunks)
  • src/composables/useFeatureFlags.ts (2 hunks)
  • src/locales/en/main.json (4 hunks)
  • src/platform/assets/components/UploadModelDialog.vue (3 hunks)
  • src/platform/assets/components/UploadModelDialogHeader.vue (1 hunks)
  • src/platform/assets/components/UploadModelFooter.vue (2 hunks)
  • src/platform/assets/components/UploadModelUrlInput.vue (1 hunks)
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue (1 hunks)
  • src/platform/assets/composables/useModelTypes.ts (1 hunks)
  • src/platform/assets/composables/useUploadModelWizard.ts (6 hunks)
  • src/platform/assets/importSources/civitaiImportSource.ts (1 hunks)
  • src/platform/assets/importSources/huggingfaceImportSource.ts (1 hunks)
  • src/platform/assets/types/importSource.ts (1 hunks)
  • src/platform/remoteConfig/types.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/locales/en/main.json
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/composables/useModelTypes.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/components/UploadModelUrlInput.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/components/UploadModelUrlInput.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Vue component file names must use PascalCase; for example, MenuHamburger.vue

Files:

  • src/components/graph/GraphCanvas.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/graph/GraphCanvas.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/graph/GraphCanvas.vue
src/composables/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Composable files must follow the naming pattern useXyz.ts

Files:

  • src/composables/useFeatureFlags.ts
🧠 Learnings (34)
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/remoteConfig/types.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/composables/useFeatureFlags.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Implement proper TypeScript types throughout the codebase

Applied to files:

  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useModelTypes.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Imports must be sorted and grouped by plugin; run `pnpm format` before committing

Applied to files:

  • src/platform/assets/composables/useModelTypes.ts
  • src/components/graph/GraphCanvas.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/components/UploadModelUrlInput.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/assets/components/UploadModelDialogHeader.vue
  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/components/graph/GraphCanvas.vue
  • src/platform/assets/components/UploadModelUrlInput.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Implement lifecycle hooks using `onMounted`, `onUpdated`, and other Vue lifecycle functions

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Prefer `useModel` to separately defining a prop and emit

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement lifecycle hooks with onMounted, onUpdated, etc.

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/platform/assets/components/UploadModelFooter.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Vue components must use `<script setup lang="ts">` for component logic

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use setup() function for component logic

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/locales/en/main.json
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Applied to files:

  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components

Applied to files:

  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Do not import Vue macros unnecessarily; only use when needed

Applied to files:

  • src/components/graph/GraphCanvas.vue
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use vue-i18n for ALL UI strings

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use vue-i18n in composition API for any string literals; place new translation entries in `src/locales/en/main.json`

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use `ref` for reactive state in Vue Composition API components

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Implement computed properties with `computed()` from Vue; avoid using a `ref` with a `watch` if a `computed` would work instead

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
🧬 Code graph analysis (4)
src/platform/assets/importSources/huggingfaceImportSource.ts (1)
src/platform/assets/types/importSource.ts (2)
  • ImportSourceHandler (11-41)
  • ImportSourceType (4-4)
src/platform/assets/importSources/civitaiImportSource.ts (1)
src/platform/assets/types/importSource.ts (2)
  • ImportSourceHandler (11-41)
  • ImportSourceType (4-4)
src/composables/useFeatureFlags.ts (2)
src/platform/remoteConfig/remoteConfig.ts (1)
  • remoteConfig (22-22)
src/scripts/api.ts (1)
  • api (1306-1306)
src/platform/assets/composables/useUploadModelWizard.ts (5)
src/composables/useFeatureFlags.ts (1)
  • useFeatureFlags (23-90)
src/platform/assets/types/importSource.ts (1)
  • ImportSourceHandler (11-41)
src/platform/assets/importSources/civitaiImportSource.ts (1)
  • civitaiImportSource (35-35)
src/platform/assets/importSources/huggingfaceImportSource.ts (1)
  • huggingfaceImportSource (37-37)
src/platform/assets/services/assetService.ts (1)
  • assetService (463-463)
🔇 Additional comments (20)
src/platform/assets/composables/useModelTypes.ts (1)

53-58: LGTM! Alphabetical sorting improves UX.

The alphabetical sorting by display name makes the model type list more user-friendly. Using localeCompare ensures proper locale-aware string comparison.

src/components/graph/GraphCanvas.vue (1)

465-467: Formatting-only change.

This is a formatting adjustment with no functional impact. The CI formatter will handle these automatically.

src/platform/remoteConfig/types.ts (1)

43-43: LGTM! Feature flag addition follows existing patterns.

The new huggingface_model_import_enabled field is properly typed as an optional boolean and follows the established pattern for remote config feature flags.

src/platform/assets/components/UploadModelDialogHeader.vue (1)

1-29: LGTM! Feature flag integration is well-implemented.

The conditional rendering based on huggingfaceModelImportEnabled flag is correctly implemented:

  • Civitai logo shown only when the flag is disabled
  • Title dynamically switches between generic and Civitai-specific text
  • Follows Vue 3 Composition API patterns properly
src/platform/assets/components/UploadModelDialog.vue (1)

6-16: LGTM! Feature flag gating is properly implemented.

The conditional rendering correctly switches between the generic UploadModelUrlInput and UploadModelUrlInputCivitai components based on the feature flag, with both properly bound to wizardData.url.

src/platform/assets/importSources/huggingfaceImportSource.ts (1)

1-37: LGTM! Implementation correctly follows the ImportSourceHandler interface.

The HuggingFaceImportSource class is well-structured:

  • Properly implements the ImportSourceHandler interface
  • URL validation correctly checks for huggingface.co domain including subdomains
  • Uses try-catch for safe URL parsing
  • Exports a singleton instance following the established pattern
src/platform/assets/components/UploadModelFooter.vue (1)

43-43: > Likely an incorrect or invalid review comment.

src/composables/useFeatureFlags.ts (2)

16-17: LGTM! Enum addition follows convention.

The new HUGGINGFACE_MODEL_IMPORT_ENABLED flag is properly added to the ServerFeatureFlag enum with the correct naming convention.


71-80: LGTM! Feature flag implementation is consistent.

The huggingfaceModelImportEnabled getter correctly follows the established pattern: remoteConfig check first, then fallback to WebSocket feature flag with a sensible default of false.

src/platform/assets/importSources/civitaiImportSource.ts (2)

9-33: LGTM! Clean implementation of the ImportSourceHandler interface.

The CivitaiImportSource class properly implements URL validation with graceful error handling and provides appropriate i18n keys for localization.


13-20: LGTM! Robust URL validation with subdomain support.

The validateUrl method correctly handles malformed URLs with try-catch and validates both the main domain and subdomains using endsWith('.civitai.com').

src/platform/assets/components/UploadModelUrlInput.vue (2)

18-44: LGTM! External links are properly secured.

The Civitai and Hugging Face links correctly use target="_blank" with rel="noopener noreferrer" for security.


8-8: Add DOMPurify sanitization for v-html on line 65.

Line 65 renders i18n content directly with v-html without sanitization. Import DOMPurify and wrap the translation: v-html="DOMPurify.sanitize($t('assetBrowser.maxFileSize'))" to prevent XSS attacks. This pattern is already established in ReleaseNotificationToast.vue and WhatsNewPopup.vue.

⛔ Skipped due to learnings
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Sanitize HTML with DOMPurify to prevent XSS attacks
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use vue-i18n for ALL UI strings
src/platform/assets/components/UploadModelUrlInputCivitai.vue (2)

8-9: Verify XSS safety for v-html usage.

Multiple uses of v-html with i18n content should be sanitized with DOMPurify to prevent XSS attacks, consistent with the project's security guidelines. Even though these are static i18n keys, sanitization ensures defense-in-depth.

Also applies to: 14-14, 25-25


34-46: LGTM! Props and emits are properly typed.

The component correctly uses TypeScript for props and emits definitions, and implements a proper computed property for two-way binding with v-model.

src/platform/assets/types/importSource.ts (1)

1-41: LGTM! Well-designed type definitions.

The ImportSourceType and ImportSourceHandler interface provide a clean, extensible abstraction for handling multiple import sources. Good documentation and proper TypeScript usage throughout.

src/platform/assets/composables/useUploadModelWizard.ts (4)

89-97: LGTM! Proper source validation with localized error message.

The URL validation correctly uses the detectedSource and provides a helpful error message with template parameters for i18n.


103-117: LGTM! Robust URL decoding with graceful fallback.

The filename and name decoding properly handles malformed URL-encoded strings by catching errors and preserving the original value.


173-196: LGTM! Robust preview image upload with proper error handling.

The preview upload correctly extracts the file extension from the data URL MIME type and continues with the main upload even if the preview fails.


198-209: LGTM! Proper null safety with fallback value.

The source metadata correctly uses optional chaining and nullish coalescing to provide 'unknown' as a fallback when no source is detected.

Comment on lines 24 to 34
getLabelKey(): string {
return 'assetBrowser.huggingfaceLinkLabel'
}

getPlaceholderKey(): string {
return 'assetBrowser.huggingfaceLinkPlaceholder'
}

getExampleKey(): string {
return 'assetBrowser.huggingfaceLinkExample'
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check if the locale file exists and look for the referenced keys
cat src/locales/en/main.json | grep -i "huggingface\|genericLink"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 539


🏁 Script executed:

# Also check the structure to understand the exact format
head -50 src/locales/en/main.json

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2151


🏁 Script executed:

# Read the specific file to verify the implementation
cat src/platform/assets/importSources/huggingfaceImportSource.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 944


🏁 Script executed:

# Search for assetBrowser namespace in the locale file
grep -n "assetBrowser" src/locales/en/main.json | head -20

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 94


🏁 Script executed:

# Get context around assetBrowser section to see the full structure
grep -A 30 '"assetBrowser"' src/locales/en/main.json

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2232


🏁 Script executed:

# Check if there are other import sources for comparison
find src/platform/assets/importSources -name "*.ts" -type f

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 187


🏁 Script executed:

cat src/platform/assets/importSources/civitaiImportSource.ts

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 882


Add missing Hugging Face i18n keys to src/locales/en/main.json.

The implementation references three i18n keys that don't exist in the locale file:

  • assetBrowser.huggingfaceLinkLabel
  • assetBrowser.huggingfaceLinkPlaceholder
  • assetBrowser.huggingfaceLinkExample

This will cause missing translation errors at runtime. The pattern in the codebase shows each import source has branded keys (Civitai has civitaiLinkLabel, civitaiLinkPlaceholder, civitaiLinkExample). Add the corresponding Hugging Face keys to the assetBrowser namespace in src/locales/en/main.json:

"huggingfaceLinkLabel": "Hugging Face model <span class=\"font-bold italic\">download</span> link",
"huggingfaceLinkPlaceholder": "Paste Hugging Face link here",
"huggingfaceLinkExample": "<strong>Example:</strong> <a href=\"https://huggingface.co/example\" target=\"_blank\" class=\"text-muted-foreground\">https://huggingface.co/example</a>"
🤖 Prompt for AI Agents
In src/locales/en/main.json around the assetBrowser section (add after existing
import-source keys), add the three missing Hugging Face keys referenced in
src/platform/assets/importSources/huggingfaceImportSource.ts (lines 24–34):
assetBrowser.huggingfaceLinkLabel, assetBrowser.huggingfaceLinkPlaceholder, and
assetBrowser.huggingfaceLinkExample; set their values to the provided strings
for label ("Hugging Face model <span class=\"font-bold italic\">download</span>
link"), placeholder ("Paste Hugging Face link here"), and example
("<strong>Example:</strong> <a href=\"https://huggingface.co/example\"
target=\"_blank\"
class=\"text-muted-foreground\">https://huggingface.co/example</a>") so the keys
exist and match the code’s expectations.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/locales/en/main.json (1)

2257-2257: HTML in translation string was previously flagged but not addressed.

This line still contains embedded HTML (<span class="font-bold italic">1 GB</span>), which was flagged in a previous review. The HTML markup and styling should be moved to the component, with the translation using a parameter like {size} instead.

As per the previous review suggestion, refactor to:

-    "maxFileSize": "Max file size: <span class=\"font-bold italic\">1 GB</span>",
+    "maxFileSize": "Max file size: {size}",

Then apply styling in the consuming component.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7eef849 and 7c7c7ea.

📒 Files selected for processing (2)
  • src/locales/en/main.json (4 hunks)
  • src/platform/assets/components/UploadModelDialog.vue (2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/locales/en/main.json
  • src/platform/assets/components/UploadModelDialog.vue
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelDialog.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelDialog.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/assets/components/UploadModelDialog.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/components/UploadModelDialog.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/components/UploadModelDialog.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelDialog.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/assets/components/UploadModelDialog.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/assets/components/UploadModelDialog.vue
🧠 Learnings (16)
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Vue components must use `<script setup lang="ts">` for component logic

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement lifecycle hooks with onMounted, onUpdated, etc.

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use setup() function for component logic

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Prefer `useModel` to separately defining a prop and emit

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Implement lifecycle hooks using `onMounted`, `onUpdated`, and other Vue lifecycle functions

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/assets/components/UploadModelDialog.vue
🔇 Additional comments (2)
src/locales/en/main.json (2)

2267-2267: Good use of template parameters for i18n.

This key correctly uses the {sources} placeholder instead of embedding HTML or hardcoding provider names, which makes it properly translatable and maintainable.


2294-2295: Well-structured i18n additions for generic import flow.

These new keys follow i18n best practices by keeping content as plain text without embedded HTML. They properly support the feature-flagged generic model import flow with clear, translatable messaging.

Also applies to: 2298-2298, 2300-2300

Comment on lines 6 to 16
<UploadModelUrlInput
v-if="currentStep === 1"
v-if="currentStep === 1 && flags.huggingfaceModelImportEnabled"
v-model="wizardData.url"
:error="uploadError"
class="flex-1"
/>
<UploadModelUrlInputCivitai
v-else-if="currentStep === 1"
v-model="wizardData.url"
:error="uploadError"
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add consistent styling to both conditional rendering paths.

The feature-flagged UploadModelUrlInput includes class="flex-1" (line 10), but the fallback UploadModelUrlInputCivitai (line 12-16) does not. This creates layout inconsistency depending on the feature flag state.

Apply this diff to maintain consistent layout:

     <UploadModelUrlInputCivitai
       v-else-if="currentStep === 1"
       v-model="wizardData.url"
       :error="uploadError"
+      class="flex-1"
     />
🤖 Prompt for AI Agents
In src/platform/assets/components/UploadModelDialog.vue around lines 6 to 16,
the feature-flagged UploadModelUrlInput has class="flex-1" but the fallback
UploadModelUrlInputCivitai does not, causing layout shifts; add the same
class="flex-1" prop to the UploadModelUrlInputCivitai element so both
conditional branches have identical styling and preserve consistent layout.

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Dec 16, 2025
- Extract HTML tags from translation values into template placeholders
- Use i18n-t component for proper template rendering in Vue
- Add modelDownloadLinkText key for 'download' text
- Separate URLs into dedicated keys (civitaiLinkExampleUrl, uploadModelDescription2Url)
- Keep styling and markup in components, not translations
- Preserve original text order for translator intent
Remove getLabelKey(), getPlaceholderKey(), and getExampleKey() methods
as they were never called
Replace class-based ImportSourceHandler with simple configuration objects
- Change ImportSourceHandler interface to ImportSource
- Extract validation logic to validateSourceUrl function
- Remove unnecessary class boilerplate
- Hostnames are now declarative arrays instead of hardcoded logic
- Use ternary operator instead of spread for clearer intent
- Make ImportSourceType internal (not exported) since it's only used within the module
@luke-mino-altherr luke-mino-altherr force-pushed the feat/huggingface-model-import branch from fb4195d to 6e8f864 Compare December 16, 2025 03:46
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Dec 16, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/platform/assets/importSources/huggingfaceImportSource.ts (1)

1-10: LGTM! Configuration follows established pattern.

The HuggingFace import source configuration correctly implements the ImportSource interface and matches the structure of civitaiImportSource.

Note: The past review comment about missing i18n keys (huggingfaceLinkLabel, etc.) no longer applies. The current implementation uses a generic URL input component (UploadModelUrlInput.vue) with generic i18n keys rather than source-specific components for HuggingFace.

src/platform/assets/components/UploadModelUrlInputCivitai.vue (1)

22-28: Hardcoded file size - same issue as UploadModelUrlInput.

The "1 GB" file size is hardcoded here as well, creating the same maintainability issue noted in UploadModelUrlInput.vue.

Consider making the file size limit configurable or moving it to a shared constant to ensure consistency across both input components.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c7c7ea and 6e8f864.

📒 Files selected for processing (7)
  • src/locales/en/main.json (4 hunks)
  • src/platform/assets/components/UploadModelUrlInput.vue (1 hunks)
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue (1 hunks)
  • src/platform/assets/composables/useUploadModelWizard.ts (6 hunks)
  • src/platform/assets/importSources/civitaiImportSource.ts (1 hunks)
  • src/platform/assets/importSources/huggingfaceImportSource.ts (1 hunks)
  • src/platform/assets/types/importSource.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Minimize the surface area (exported values) of each module and composable

Files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
**/*.{ts,tsx,js,jsx,vue,json}

📄 CodeRabbit inference engine (AGENTS.md)

Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see .prettierrc)

Files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/locales/en/main.json
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; run pnpm format before committing
Use TypeScript for type safety; never use any type - use proper TypeScript types
Never use as any type assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nested if or for statements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones

Files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3 SFCs (Single File Components) with Composition API only; do not use Options API
Vue components must use <script setup lang="ts"> for component logic
Use Vue 3.5 TypeScript style for default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer useModel to separately defining a prop and emit
Use Tailwind 4 utility classes for styling; avoid using <style> blocks in Vue components
Use semantic Tailwind values from style.css theme instead of the dark: variant; for example, use bg-node-component-surface instead of dark: prefixes
Always use cn() utility from @/utils/tailwindUtil to merge Tailwind class names; do not use :class="[]" syntax
Use ref for reactive state in Vue Composition API components
Implement computed properties with computed() from Vue; avoid using a ref with a watch if a computed would work instead
Use watch and watchEffect for side effects in Vue components
Implement lifecycle hooks using onMounted, onUpdated, and other Vue lifecycle functions
Use provide/inject for dependency injection; do not use dependency injection if a Store or shared composable would be simpler
Do not import Vue macros unnecessarily; only use when needed
Be judicious with addition of new refs or other state: prefer props, avoid redundant computed, and prefer computed over watch
Use VueUse functions for performance-enhancing styles
In Vue Components, implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Implement proper error handling in Vue components
Follow Vue 3 style guide and naming conventions
Use vue-i18n in composition API for any string literals; place new translation entries in src/locales/en/main.json
Avoid new usage of PrimeVue components; prefer shadcn/vue or Reka UI instead

Files:

  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
src/**/{services,composables}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/{services,composables}/**/*.{ts,tsx}: Use api.apiURL() for backend endpoints instead of constructing URLs directly
Use api.fileURL() for static file access instead of constructing URLs directly

Files:

  • src/platform/assets/composables/useUploadModelWizard.ts
🧠 Learnings (21)
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/locales/en/main.json
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/platform/assets/importSources/huggingfaceImportSource.ts
  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/importSources/civitaiImportSource.ts
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/types/importSource.ts
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/platform/assets/components/UploadModelUrlInput.vue
  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Applied to files:

  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components

Applied to files:

  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use vue-i18n in composition API for any string literals; place new translation entries in `src/locales/en/main.json`

Applied to files:

  • src/platform/assets/components/UploadModelUrlInputCivitai.vue
  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Implement proper TypeScript types throughout the codebase

Applied to files:

  • src/platform/assets/types/importSource.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Avoid mutable state; prefer immutability and assignment at point of declaration

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.{ts,tsx,vue} : Imports must be sorted and grouped by plugin; run `pnpm format` before committing

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Avoid using ts-expect-error; use proper TypeScript types instead

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use vue-i18n for ALL UI strings

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Use `ref` for reactive state in Vue Composition API components

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
📚 Learning: 2025-12-09T20:22:23.620Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.620Z
Learning: Applies to **/*.vue : Implement computed properties with `computed()` from Vue; avoid using a `ref` with a `watch` if a `computed` would work instead

Applied to files:

  • src/platform/assets/composables/useUploadModelWizard.ts
🧬 Code graph analysis (3)
src/platform/assets/importSources/huggingfaceImportSource.ts (1)
src/platform/assets/types/importSource.ts (1)
  • ImportSource (9-24)
src/platform/assets/importSources/civitaiImportSource.ts (1)
src/platform/assets/types/importSource.ts (1)
  • ImportSource (9-24)
src/platform/assets/composables/useUploadModelWizard.ts (4)
src/composables/useFeatureFlags.ts (1)
  • useFeatureFlags (23-90)
src/platform/assets/types/importSource.ts (2)
  • ImportSource (9-24)
  • validateSourceUrl (29-38)
src/platform/assets/importSources/civitaiImportSource.ts (1)
  • civitaiImportSource (6-10)
src/platform/assets/importSources/huggingfaceImportSource.ts (1)
  • huggingfaceImportSource (6-10)
🔇 Additional comments (16)
src/platform/assets/types/importSource.ts (2)

26-38: LGTM! Validation logic is correct and robust.

The function properly validates URLs against import source hostnames with:

  • Exact hostname matching
  • Subdomain support (e.g., www.huggingface.co matches huggingface.co)
  • Graceful error handling for malformed URLs

1-24: Consider exporting ImportSourceType for type safety.

The ImportSourceType type is only used internally within this module. While this works, exporting it would allow consumers to type-check source types more strictly (e.g., when working with source.type values).

Example usage if exported:

import type { ImportSourceType } from './importSource'

function handleSource(sourceType: ImportSourceType) {
  // Type-safe handling of source types
}
⛔ Skipped due to learnings
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{ts,tsx,vue} : Implement proper TypeScript types throughout the codebase
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.ts : Use TypeScript for type safety
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, linting rules enforce keeping `import type` statements separate from regular `import` statements, even when importing from the same module. Do not suggest consolidating them into a single import statement.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/stores/**/*.{ts,tsx} : Use TypeScript for type safety in state management stores
src/platform/assets/importSources/civitaiImportSource.ts (1)

1-10: LGTM! Configuration is correct and consistent.

The Civitai import source configuration properly implements the ImportSource interface and follows the same pattern as the HuggingFace source.

src/platform/assets/components/UploadModelUrlInput.vue (2)

14-48: Verify feature-flag behavior for HuggingFace display.

The component unconditionally displays both Civitai and HuggingFace logos/links in the provider attribution section. However, the HuggingFace import source is feature-flagged (huggingfaceModelImportEnabled) elsewhere in the codebase.

Ensure this aligns with the intended UX: should the HuggingFace attribution be visible even when the feature is disabled, or should it be conditionally rendered based on the feature flag?

If conditional rendering is needed, you can use the feature flag:

<script setup lang="ts">
import { useFeatureFlags } from '@/composables/useFeatureFlags'
const { flags } = useFeatureFlags()
// ... existing code
</script>

<template>
  <!-- In template -->
  <span v-if="flags.huggingfaceModelImportEnabled" class="inline-flex items-center gap-1">
    <img src="/assets/images/hf-logo.svg" ... />
    <a href="https://huggingface.co" ...>Hugging Face</a>
  </span>
</template>

79-96: LGTM! Script setup follows Vue 3 composition API best practices.

The component correctly implements:

  • Type-safe props and emits
  • Computed two-way binding for v-model
  • Proper imports from PrimeVue
src/platform/assets/components/UploadModelUrlInputCivitai.vue (1)

69-86: LGTM! Script setup is correctly implemented.

The component properly implements the composition API pattern with type-safe props, emits, and computed bindings.

src/locales/en/main.json (4)

2233-2238: LGTM! i18n keys properly use placeholders.

The civitai link keys correctly use template parameters ({exampleUrl}, {download}) instead of embedded HTML, addressing the past review concern about HTML in translation strings.


2257-2257: LGTM! maxFileSize correctly uses template parameter.

The key properly uses {size} placeholder, addressing the past review concern.

Note: The Vue components still hardcode "1 GB" instead of passing it dynamically, which was flagged in the component reviews.


2268-2268: LGTM! unsupportedUrlSource uses template parameter correctly.

The key uses {sources} placeholder to dynamically list supported import sources, providing a flexible error message.


2294-2303: LGTM! Upload model description keys follow i18n best practices.

All keys properly use template parameters for dynamic content:

  • URLs separated into distinct keys
  • Size and other dynamic values use placeholders
  • Clean separation of concerns
src/platform/assets/composables/useUploadModelWizard.ts (6)

1-14: LGTM! Imports are clean and properly organized.

The new imports for i18n, feature flags, and import sources are all utilized in the code. Type imports are correctly separated as per project lint rules.


48-60: LGTM! Immutable array construction correctly addresses past review.

The importSources array is now constructed immutably using a ternary expression instead of mutation with push(), properly following the coding guidelines.

The detectedSource computed correctly validates URLs against available sources using the new validation utility.


91-99: LGTM! URL validation properly refactored for extensibility.

The validation logic now uses the detected source instead of hardcoded Civitai checks, making it extensible for future import sources. The error message is properly localized with dynamic source names.


105-120: LGTM! Filename decoding enables UTF-8 support with graceful error handling.

The decoding logic properly handles URL-encoded filenames (e.g., Chinese characters) while safely falling back to the original value if decoding fails. This addresses the PR objective of "UTF-8 filename support."


200-211: LGTM! Source metadata properly tracked in uploads.

The upload includes the detected source type in user_metadata.source, enabling proper tracking of import sources. The fallback to 'unknown' is appropriate for edge cases.


247-266: LGTM! Public API correctly extended with detectedSource.

The composable now exposes detectedSource to consumers, allowing UI components to react to the detected import source.

Comment on lines +62 to +69
<p v-else class="text-white">
<i18n-t keypath="assetBrowser.maxFileSize" tag="span">
<template #size>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text -->
<span class="font-bold italic">1 GB</span>
</template>
</i18n-t>
</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Hardcoded file size breaks i18n pattern.

The max file size is hardcoded as "1 GB" in the template, which undermines the i18n template parameter pattern. If the size limit changes or needs to vary, this requires template modifications.

Consider one of these approaches:

Option 1: Define size as a constant

const MAX_FILE_SIZE = '1 GB'

Option 2: Update the i18n string to include the size

"maxFileSize": "Max file size: 1 GB"

Option 3: Make it configurable via prop

const props = defineProps<{
  modelValue: string
  error?: string
  maxFileSizeMB?: number
}>()

const maxFileSizeDisplay = computed(() => 
  props.maxFileSizeMB ? `${props.maxFileSizeMB / 1024} GB` : '1 GB'
)
🤖 Prompt for AI Agents
In src/platform/assets/components/UploadModelUrlInput.vue around lines 62 to 69,
the template currently hardcodes "1 GB" which breaks the i18n parameter pattern;
replace the hardcoded size with a dynamic value and pass it into the i18n
message: add a configurable source for the limit (either a local constant
MAX_FILE_SIZE or a prop like maxFileSizeMB with a small computed that formats
MB→GB), update the i18n key to accept a parameter (or keep the key and supply
the size param), and modify the <i18n-t> usage to inject that formatted size
instead of the hardcoded span so the displayed value is driven by code/config
rather than template text.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:models enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants