- Add getMappableBaseModelsDynamic to constants.js mocks in test files
- Remove refs/enums.json temporary file from repository
Fixes test failures introduced in previous commit.
Implement automatic fetching of base models from Civitai API to keep
data up-to-date without manual updates.
Backend:
- Add CivitaiBaseModelService with 7-day TTL caching
- Add /api/lm/base-models endpoints for fetching and refreshing
- Merge hardcoded and remote models for backward compatibility
- Smart abbreviation generation for unknown models
Frontend:
- Add civitaiBaseModelApi client for API communication
- Dynamic base model loading on app initialization
- Update SettingsManager to use merged model lists
- Add support for 8 new models: Anima, CogVideoX, LTXV 2.3, Mochi,
Pony V7, Wan Video 2.5 T2V/I2V
API Endpoints:
- GET /api/lm/base-models - Get merged models
- POST /api/lm/base-models/refresh - Force refresh
- GET /api/lm/base-models/categories - Get categories
- GET /api/lm/base-models/cache-status - Check cache status
Closes#854
- Add forwardWheelToCanvas() utility for vanilla JS widgets
- Implement wheel event handling in Vue widgets (LoraCyclerWidget, LoraRandomizerWidget, LoraPoolWidget)
- Update SingleSlider and DualRangeSlider to stop event propagation after value adjustment
- Ensure consistent behavior: slider adjusts value only, other areas trigger canvas zoom
- Support pinch-to-zoom (Ctrl+wheel) and horizontal scroll forwarding
Add translations for the new mature_blur_level setting across all
supported languages:
- zh-CN: 成人内容模糊阈值
- zh-TW: 成人內容模糊閾值
- ja: 成人コンテンツぼかし閾値
- ko: 성인 콘텐츠 블러 임계값
- de: Schwelle für Unschärfe bei jugendgefährdenden Inhalten
- fr: Seuil de floutage pour contenu adulte
- es: Umbral de difuminado para contenido adulto
- ru: Порог размытия взрослого контента
- he: סף טשטוש תוכן מבוגרים
Completes TODOs from previous commit.
Add new setting 'mature_blur_level' with options PG13/R/X/XXX to control
which NSFW rating level triggers blur filtering when NSFW blur is enabled.
- Backend: update preview selection logic to respect threshold
- Frontend: update UI components to use configurable threshold
- Settings: add validation and normalization for mature_blur_level
- Tests: add coverage for new threshold behavior
- Translations: add keys for all supported languages
Fixes#867
- Remove calculate_sha256 mocking from download_manager tests since
SHA256 now comes from API metadata (not recalculated during download)
- Update chunk_size assertion from 4MB to 16MB in downloader config test
Fix issue #870 where importing recipes from CivitAI image URLs would
return the wrong image when the API response did not contain the
requested image ID.
The get_image_info() method now:
- Iterates through all returned items to find matching ID
- Returns None when no match is found and logs warning with returned IDs
- Handles invalid (non-numeric) ID formats
New test cases:
- test_get_image_info_returns_matching_item
- test_get_image_info_returns_none_when_id_mismatch
- test_get_image_info_handles_invalid_id
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix the bottom corners of duplicate warning border being clipped
due to parent container overflow:hidden and mismatched border-radius.
- Changed border-radius from top-only to all corners
- Ensures yellow border displays fully without being cut off
- Add SuiImageParamsParser for sui_image_params JSON format
- Register new parser in RecipeParserFactory
- Fix metadata_provider auto-initialization when not ready
- Add 10 test cases for SuiImageParamsParser
Fixes batch import failure for images with sui_image_params metadata.
Exclude Claude Code personal configuration directory containing:
- settings.local.json (personal permissions and local paths)
- skills/ (personal skills)
These contain machine-specific paths and personal preferences
that should not be shared across the team.
Fix issue #866 where the metadata hook's async wrapper used *args/**kwargs
which caused AttributeError when ComfyUI's make_locked_method_func tried
to access __func__ on the func parameter.
The async_map_node_over_list_with_metadata wrapper now uses the exact
same signature as ComfyUI's _async_map_node_over_list:
- Removed: *args, **kwargs
- Added: explicit v3_data=None parameter
This ensures the func parameter (always a string like obj.FUNCTION) is
passed correctly to make_locked_method_func without any type conversion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements issue #808 - Allow users to customize the strength
variation range for LoRA widget arrow buttons.
Changes:
- Add 'Strength Adjustment Step' setting (0.01-0.1) in settings.js
- Replace hardcoded 0.05 increments with configurable step value
- Apply to both LoRA strength and CLIP strength controls
Fixes#808
Add name pattern filtering to LoRA Pool node allowing users to filter
LoRAs by filename or model name using either plain text or regex patterns.
Features:
- Include patterns: only show LoRAs matching at least one pattern
- Exclude patterns: exclude LoRAs matching any pattern
- Regex toggle: switch between substring and regex matching
- Case-insensitive matching for both modes
- Invalid regex automatically falls back to substring matching
- Filters apply to both file_name and model_name fields
Backend:
- Update LoraPoolLM._default_config() with namePatterns structure
- Add name pattern filtering to _apply_pool_filters() and _apply_specific_filters()
- Add API parameter parsing for name_pattern_include/exclude/use_regex
- Update LoraPoolConfig type with namePatterns field
Frontend:
- Add NamePatternsSection.vue component with pattern input UI
- Update useLoraPoolState to manage pattern state and API integration
- Update LoraPoolSummaryView to display NamePatternsSection
- Increase LORA_POOL_WIDGET_MIN_HEIGHT to accommodate new UI
Tests:
- Add 7 test cases covering text/regex include, exclude, combined
filtering, model name fallback, and invalid regex handling
Closes#839
- Add `# type: ignore` comments to comfy.sd and folder_paths imports
- Remove unused imports: os, random, and extract_lora_name
- Clean up import statements across checkpoint_loader, lora_randomizer, and unet_loader nodes
- Delay torch import until needed in load_unet and load_unet_gguf methods
- This improves module loading performance by avoiding unnecessary imports
- Maintains functionality while reducing initial import overhead
Move the 'empty/no LoRA' cycling functionality from the LoRA Pool node
to the Lora Cycler widget for cleaner architecture:
Frontend changes:
- Add include_no_lora field to CyclerConfig interface
- Add includeNoLora state and logic to useLoraCyclerState composable
- Add toggle UI in LoraCyclerSettingsView with special styling
- Show 'No LoRA' entry in LoraListModal when enabled
- Update LoraCyclerWidget to integrate new logic
Backend changes:
- lora_cycler.py reads include_no_lora from config
- Calculate effective_total_count (actual count + 1 when enabled)
- Return empty lora_stack when on No LoRA position
- Return actual LoRA count in total_count (not effective count)
Reverted files to pre-PR state:
- lora_loader.py, lora_pool.py, lora_randomizer.py, lora_stacker.py
- lora_routes.py, lora_service.py
- LoraPoolWidget.vue and related files
Related to PR #861
Co-authored-by: dogatech <dogatech@dogatech.home>
- Add validation to check if Civitai API metadata contains recipe fields
- Fall back to EXIF extraction when API returns empty metadata (meta.meta=null)
- Improve error messages to distinguish between missing metadata and unsupported format
- Add _has_recipe_fields() helper method to validate metadata content
This fixes import failures for Civitai images where the API returns
metadata wrapper but no actual generation parameters (e.g., images
edited in Photoshop that lost their original generation metadata)
- Rename nodes to 'Checkpoint Loader (LoraManager)' and 'Unet Loader (LoraManager)'\n- Use os.sep for relative path formatting in model COMBO inputs\n- Update path matching to be robust across OS separators\n- Update docstrings and comments
Refactor _prepare_checkpoint_paths() to return a tuple instead of having
side effects on instance variables. This prevents extra unet paths from
being incorrectly classified as checkpoints when processing extra paths.
- Changed return type from List[str] to Tuple[List[str], List[str], List[str]]
(all_paths, checkpoint_roots, unet_roots)
- Updated _init_checkpoint_paths() and _apply_library_paths() callers
- Fixed extra paths processing to properly isolate main and extra roots
- Updated test_checkpoint_path_overlap.py tests for new API
This ensures models in extra unet paths are correctly identified as
diffusion_model type and don't appear in checkpoints list.
Add file_path as a tie-breaker for all sort modes in ModelCache, BaseModelService, LoraService, and RecipeCache to ensure deterministic ordering when primary keys are identical. Resolves issue #859.
- Replace multiple consecutive spaces with single underscore for tag matching
(e.g., 'looking to the side' → 'looking_to_the_side')
- Support prefix/suffix matching for flexible multi-word autocomplete
(e.g., 'looking to the' → 'looking_to_the_side')
- Add comprehensive test coverage for multi-word scenarios
Test coverage:
- Multi-word exact match (Danbooru convention)
- Partial match with last token replacement
- Command mode with multi-word phrases
- Multiple consecutive spaces handling
- Backend LOG10 popularity weight validation
Fixes: 'looking to the side' input now correctly replaces with
'looking_to_the_side, ' (or 'looking to the side, ' with space replacement)