Commit Graph

2136 Commits

Author SHA1 Message Date
Will Miao
fc98c752dc Fix Windows FileNotFoundError when loading LoRAs from lora_stack
lora_stack stores relative paths (e.g., 'Illustrious/style/file.safetensors'),
but comfy.utils.load_torch_file requires absolute paths. Previously, when
loading LoRAs from lora_stack, the relative path was passed directly to the
low-level API, causing FileNotFoundError on Windows.

This fix extracts the lora name from the relative path and uses
get_lora_info_absolute() to resolve the full absolute path before passing
it to load_torch_file(). This maintains compatibility with the lora_stack
format while ensuring correct file loading across all platforms.

Fixes: FileNotFoundError for relative paths in LoraLoaderLM and LoraTextLoaderLM
when processing lora_stack input.
2026-02-25 00:01:41 +08:00
Will Miao
c2754ea937 feat(ui): improve settings layout with inline help tooltips
- Remove bottom margin from setting items and last-child override
- Add flex layout to setting-info for inline label and info icon alignment
- Replace label opacity with rgba color for better tooltip visibility
- Add info-icon styling with hover tooltips using data-tooltip attribute
- Move help text from separate divs to inline tooltips on labels and section headers
- Improve tooltip positioning with edge case handling for left-aligned icons
2026-02-24 23:28:42 +08:00
Will Miao
f0cbe55040 refactor(settings): improve settings modal visual hierarchy and alignment
- Remove sidebar micro-transparent background for cleaner look
- Align Settings header with nav items using consistent left padding
- Enhance section headers: 18px, 700 weight for better visual hierarchy
- Mute setting labels: 400 weight, 0.85 opacity to de-emphasize
- Remove duplicate CSS rules and clean up styling
2026-02-24 15:44:33 +08:00
Will Miao
1f8ab377f7 refactor(settings): Move Priority Tags into Download Path Templates section
- Move Priority Tags setting from separate section to bottom of Download Path Templates
- Fix help link button position to be inline with label using flexbox layout
- Add CSS styles for .priority-tags-header-row and .priority-tags-header
2026-02-24 14:57:28 +08:00
Will Miao
de53ab9304 refactor(settings): restructure settings modal with subsection headers
- Replace duplicate section headers with meaningful subsection titles
- Group settings under logical subsections using existing i18n keys
- Add new translation key 'settings.sections.apiConfiguration'
- Update CSS for subsection styling with proper visual hierarchy
- Improve UX by making settings organization clearer

Subsections now use familiar titles from existing translations:
- API Configuration, Storage Location, Language (General)
- Content Filtering, Video Settings, Layout Settings (Interface)
- Folder Settings, Download Path Templates, Priority Tags,
  Update Flags, Example Images (Download)
- Auto-organize Exclusions, Metadata Refresh Skip Paths (Organization)
- Metadata Archive, Misc (System)
- Proxy Settings (Network)
2026-02-24 14:33:09 +08:00
Will Miao
8d7e861458 fix: correct i18n keys in settings modal for metadata archive and proxy settings
- Fix metadata archive DB setting to use correct i18n keys (enableArchiveDb, etc.)
- Restore metadata archive status display and management buttons
- Fix proxy settings to use correct i18n keys (enableProxy, proxyType, proxyHost, etc.)
- Add missing help text for proxy settings
- Add SOCKS4 proxy option
- Add onblur/onkeydown handlers for proxy input fields
- Update locales for new nav items (organization, system, network)
2026-02-24 11:30:43 +08:00
Will Miao
60674feb10 feat(ui): increase settings modal width and adjust height for better responsiveness
- Increase modal width from 800px to 1000px to accommodate more content
- Change height from fixed 600px to dynamic calculation based on viewport height
- Maintain responsive constraints with max-width and max-height properties
2026-02-24 09:12:07 +08:00
Will Miao
a221682a0d refactor(settings): implement macOS Settings style for settings modal
- Reorganize settings into 4 sections: General, Interface, Download, Advanced
- Implement section switching instead of scrolling (macOS Settings style)
- Remove collapsible/expandable sections and redundant 'SETTINGS' label
- Add accent-colored underline for section headers
- Update navigation with larger, more prominent active state
- Add fade-in animation for section transitions
- Update search to auto-switch to matching section
- Refactor CSS: 800x600 fixed modal size, remove collapse styles
- Refactor JS: simplify navigation logic, remove scroll spy and collapse code

Refs: Phase 0 settings modal optimization
2026-02-24 07:19:32 +08:00
Will Miao
3f0227ba9d feat(settings): add search functionality to settings modal (P2)
Implement Phase 2 search bar feature for settings modal:

- Add search input to settings modal header with icon and clear button
- Implement real-time filtering with 150ms debounce for performance
- Add visual highlighting for matched search terms using accent color
- Implement empty search results state with user-friendly message
- Add keyboard shortcuts (Escape to clear search)
- Auto-expand sections containing matching content during search
- Fix header layout to prevent overlap with close button
- Update progress tracker documenting P2 completion
- Add translation keys for search feature (placeholder, clear, no results)
- Sync translations across all language files

Files changed:
- templates/components/modals/settings_modal.html
- static/css/components/modal/settings-modal.css
- static/js/managers/SettingsManager.js
- locales/*.json (10 language files)
- docs/ui-ux-optimization/progress-tracker.md
2026-02-24 06:36:49 +08:00
Will Miao
528225ffbd feat(settings): add left navigation sidebar to settings modal
Implement two-column layout for improved settings navigation:
- Add 200px fixed navigation sidebar with 4 groups (General, Interface, Download, Advanced)
- Implement scroll spy to highlight current section during scroll
- Add smooth scrolling when clicking navigation items
- Extend modal width from 700px to 950px for better content display
- Add responsive mobile layout (switches to stacked view below 768px)
- Add i18n keys for navigation group titles
- Create documentation for optimization phases and progress tracking

Files changed:
- settings-modal.css: Add sidebar, navigation, and responsive styles
- settings_modal.html: Restructure with two-column layout and section IDs
- SettingsManager.js: Add initializeNavigation() with scroll spy
- locales/*.json: Add settings.nav translations (en, zh-CN, zh-TW, ja, ru, de, fr, es, ko, he)
- docs/ui-ux-optimization/: Add proposal and progress tracker documentation
2026-02-23 21:12:15 +08:00
Will Miao
916bfb0ab0 Allow adaptive multi-line model names in cards
- Remove fixed min-height from card-footer for adaptive sizing
- Increase model-name max-height to 5.6em (4 lines)

Enables full display of long custom-trained LoRA filenames
2026-02-23 18:19:02 +08:00
Will Miao
70398ed985 feat(lora-loader): Load LoRAs using lower-level API to bypass folder_paths validation
- Add get_lora_info_absolute() function to return absolute file paths
- Replace LoraLoader().load_lora() with comfy.utils.load_torch_file() +
  comfy.sd.load_lora_for_models() to enable loading LoRAs from any path
- This allows LoRA Manager to load LoRAs from non-standard paths (multi-library support)
- Fixes #805
2026-02-23 18:06:15 +08:00
Will Miao
1f5baec7fd docs: add recipe batch import feature requirements document 2026-02-23 17:07:03 +08:00
Will Miao
f1eb89af7a refactor: Extract isNodeEnabled helper to eliminate mode check duplication
Consolidate node enabled state checks into isNodeEnabled() helper function
to improve code clarity and maintainability. Follows DRY principle.
2026-02-23 16:47:09 +08:00
pixelpaws
7a04cec08d Merge pull request #825 from RanKaze/main
feat: filter node with mode:0
2026-02-23 16:39:45 +08:00
Will Miao
ec5fd923ba fix(randomizer): Initialize RANDOMIZER_CONFIG widget with default config
Initialize internalValue with default RandomizerConfig object instead of
undefined to prevent frontend from sending empty string to backend when
widget is first created.

This fixes the 'str' object has no attribute 'get' error that occurred
when running a newly created Lora Randomizer node before any user
interaction.

Fixes #4
2026-02-23 14:25:55 +08:00
Will Miao
26b139884c perf(usage-stats): prevent unnecessary writes when idle
- Add is_dirty flag to track if statistics have changed
- Only write stats file when data actually changes
- Add enable_usage_statistics setting in ComfyUI settings
- Skip backend requests when usage statistics is disabled
- Fix standalone mode compatibility for MetadataRegistry

Fixes #826
2026-02-23 14:00:00 +08:00
Will Miao
ec76ac649b Fix long model name display issues in modal and cards
- Add overflow-wrap: anywhere to modal title for proper wrapping of hyphenated names
- Add tooltip to model cards showing full filename on hover

Fixes overlap issues with long filenames like s0r4B35G_Zibv3_Prodigy_ID_Version2_Final_00800
2026-02-23 08:53:33 +08:00
Will Miao
e08cae97f1 chore(release): bump version to 0.9.16 and update release notes v0.9.16 2026-02-22 21:06:52 +08:00
Will Miao
a0cf78842e feat(download): download to current version's directory in versions tab
Instead of always using default paths, downloads from the model versions
tab now target the same directory as the current in-library version.
Falls back silently to default paths if the current version path cannot
be resolved.
2026-02-22 15:55:04 +08:00
Will Miao
0b48654ae6 feat: add browser extension integration hooks
- Add lmExtensionHandled check to prevent duplicate downloads
- Add lm:refreshVersions event listener for extension-triggered refresh
- Expose downloadManager to window for extension access
2026-02-22 12:00:32 +08:00
Will Miao
807f4e03ee feat(autocomplete): support input element sharing for subgraph promotion
Store textarea reference on container element to allow cloned widgets to access inputEl when promoted to subgraph nodes. This ensures both original and cloned widgets can properly get and set values through the shared DOM element.
2026-02-22 09:41:54 +08:00
K1einB1ue
60324c1299 feat: filter node with mode:0 2026-02-22 07:19:08 +08:00
Will Miao
773adb27c9 feat(model_download): add file_params JSON parsing to download handler
- Parse optional file_params query parameter as JSON in ModelDownloadHandler
- Add error handling for invalid JSON with warning log
- Maintain backward compatibility with existing download parameters
2026-02-22 04:26:38 +08:00
Will Miao
d653494ee1 Clarify metadata refresh skip paths help text across all languages
Update the help text for 'Metadata Refresh Skip Paths' setting to explicitly
state that paths should be relative to the 'model root directory' instead of
just saying 'relative folder paths', which was ambiguous.

Updated translations:
- English (en)
- Chinese Simplified (zh-CN)
- Chinese Traditional (zh-TW)
- Japanese (ja)
- Korean (ko)
- Russian (ru)
- German (de)
- French (fr)
- Spanish (es)
- Hebrew (he)
2026-02-21 07:30:29 +08:00
Will Miao
9117ee60dd feat(download): add file_params support for precise file selection 2026-02-20 15:32:48 +08:00
Will Miao
879588e252 refactor(settings): invert sync logic from whitelist to blacklist
Replace _SYNC_KEYS (37 keys) with _NO_SYNC_KEYS (5 keys) in SettingsHandler.
New settings automatically sync to frontend unless explicitly excluded.

Changes:
- SettingsHandler now syncs all settings except those in _NO_SYNC_KEYS
- Added keys() method to SettingsManager for iteration
- Updated tests to use new behavior

Benefits:
- No more missing keys when adding new settings
- Reduced maintenance burden
- Explicit exclusions for sensitive/internal settings only

Fixes: #86
2026-02-20 12:14:50 +08:00
Will Miao
1725558fbc i18n: Add Early Access translations for all supported languages
Complete TODO translations from previous commit:
- Add translations for hideEarlyAccessUpdates setting
- Add translations for EA time formatting (endingSoon, hours, days)
- Add translations for EA badges and tooltips
- Translate to: de, es, fr, he, ja, ko, ru, zh-CN, zh-TW

Closes #815 translations
2026-02-20 11:12:30 +08:00
Will Miao
67869f19ff feat(early-access): implement EA filtering and UI improvements
Add Early Access version support with filtering and improved UI:

Backend:
- Add is_early_access and early_access_ends_at fields to ModelVersionRecord
- Implement two-phase EA detection (bulk API + single API enrichment)
- Add hide_early_access_updates setting to filter EA updates
- Update has_update() and has_updates_bulk() to respect EA filter setting
- Add _enrich_early_access_details() for precise EA time fetching
- Fix setting propagation through base_model_service and model_update_service

Frontend:
- Add smart relative time display for EA (in Xh, in Xd, or date)
- Replace EA label with clock icon in metadata (fa-clock)
- Show Download button with bolt icon for EA versions (fa-bolt)
- Change EA badge color to #F59F00 (CivitAI Buzz theme)
- Fix toggle UI for hide_early_access_updates setting
- Add translation keys for EA time formatting

Tests:
- Update all tests to pass with new EA functionality
- Add test coverage for EA filtering logic

Closes #815
2026-02-20 10:32:51 +08:00
Will Miao
e8b37365a6 fix: Show all tags in LoRA Pool without limit (#819)
- Backend: Support limit=0 to return all tags in top-tags API
- Frontend: Remove tags limit setting and fetch all tags by default
- UI: Implement virtual scrolling in TagsModal for performance
  - Initial display 200 tags, load more on scroll
  - Show all results when searching
- Remove lora_pool_tags_limit setting to simplify UX

Fixes #819
2026-02-19 09:59:08 +08:00
Will Miao
b9516c6b62 fix: Handle missing Civitai API response fields gracefully
Fix KeyError when 'hashes', 'name', or 'model' fields are missing from
Civitai API responses. Use .get() with defaults instead of direct dict
access in:

- LoraMetadata.from_civitai_info()
- CheckpointMetadata.from_civitai_info()
- EmbeddingMetadata.from_civitai_info()
- RecipeScanner._get_hash_from_civitai()
- DownloadManager._process_download()

Fixes #820
2026-02-18 12:02:48 +08:00
Will Miao
16c52877ad feat: add dynamic trigger_words inputs to PromptLM node
- Backend: Add _AllContainer for dynamic input validation bypass
- Backend: Modify INPUT_TYPES to support trigger_words1, trigger_words2, etc.
- Backend: Update encode() to collect all trigger_words* from kwargs
- Frontend: Create prompt_dynamic_inputs.js extension
- Frontend: Implement onConnectionsChange to auto-add/remove input slots
- Frontend: Renumber inputs sequentially on connect/disconnect

Based on Impact Pack's Switch (Any) node dynamic input pattern.
2026-02-18 07:18:12 +08:00
Will Miao
466351b23a fix: display long LoRA filenames in multiple lines in preview tooltip
Previously, long LoRA filenames were truncated from the right with ellipsis,
which hid important checkpoint step numbers (e.g., -00800, -01000) that users
need to distinguish between different training checkpoints.

Changes:
- Replace single-line truncation with multi-line display (max 3 lines)
- Add line-height and word-break properties for better readability
- Use -webkit-line-clamp to gracefully handle extremely long names

This ensures the step number suffix is always visible in the tooltip.
2026-02-15 19:14:42 +08:00
Will Miao
83fc3282d4 refactor: Simplify TriggerWord Toggle node height handling
- Remove max height setting, let ComfyUI handle widget sizing
- Widget now uses getMinHeight() to declare 150px minimum
- Container fills available space with overflow: auto for scrollbars
- Users can freely resize the node; content overflows show scrollbar
- Simplified renderTags by removing height calculation logic

Fixes #706
2026-02-12 07:40:07 +08:00
Will Miao
d8adb97af6 feat: Add configurable max height for TriggerWord Toggle node
- Add new setting 'loramanager.trigger_word_max_height' (150-600px, default 300px)
- Add getTriggerWordMaxHeight() getter to retrieve setting value
- Update tags_widget to respect max height limit with scrollbar
- Add getMaxHeight callback for ComfyUI layout system
- Add tooltip note about requiring page reload

Fixes #706
2026-02-11 18:04:11 +08:00
Will Miao
85e511d81c feat(testing): implement Phase 4 advanced testing
- Add Hypothesis property-based tests (19 tests)
- Add Syrupy snapshot tests (7 tests)
- Add pytest-benchmark performance tests (11 tests)
- Fix Hypothesis plugin compatibility by creating MockModule class
- Update pytest.ini to exclude .hypothesis directory
- Add .hypothesis/ to .gitignore
- Update requirements-dev.txt with testing dependencies
- Mark Phase 4 complete in backend-testing-improvement-plan.md

All 947 tests passing.
2026-02-11 11:58:28 +08:00
Will Miao
8e30008b29 test: complete Phase 3 of backend testing improvement plan
Centralize test fixtures:
- Add mock_downloader fixture for configurable downloader mocking
- Add mock_websocket_manager fixture for WebSocket broadcast recording
- Add reset_singletons autouse fixture for test isolation
- Consolidate singleton cleanup in conftest.py

Split large test files:
- test_download_manager.py (1422 lines) → 3 focused files:
  - test_download_manager_basic.py: 12 core functionality tests
  - test_download_manager_error.py: 15 error handling tests
  - test_download_manager_concurrent.py: 6 advanced scenario tests

- test_cache_paths.py (530 lines) → 3 focused files:
  - test_cache_paths_resolution.py: 11 path resolution tests
  - test_cache_paths_validation.py: 9 legacy validation tests
  - test_cache_paths_migration.py: 9 migration scenario tests

Update documentation:
- Mark all Phase 3 checklist items as complete
- Add Phase 3 completion summary with test results

All 894 tests passing.
2026-02-11 11:10:31 +08:00
Will Miao
e335a527d4 test: Complete Phase 2 - Integration & Coverage improvements
- Create tests/integration/ directory with conftest.py fixtures
- Add 7 download flow integration tests (test_download_flow.py)
- Add 9 recipe flow integration tests (test_recipe_flow.py)
- Add 12 ModelLifecycleService tests (exclude_model, bulk_delete, error paths)
- Add 5 PersistentRecipeCache concurrent access tests
- Update backend-testing-improvement-plan.md with Phase 2 completion

Total: 28 new tests, all passing (51/51)
2026-02-11 10:55:19 +08:00
Will Miao
25e6d72c4f test(backend): Phase 1 - Improve testing infrastructure and add error path tests
## Changes

### pytest-asyncio Integration
- Add pytest-asyncio>=0.21.0 to requirements-dev.txt
- Update pytest.ini with asyncio_mode=auto and fixture loop scope
- Remove custom pytest_pyfunc_call handler from conftest.py
- Add @pytest.mark.asyncio to 21 async test functions

### Error Path Tests
- Create test_downloader_error_paths.py with 19 new tests covering:
  - DownloadStreamControl state management (6 tests)
  - Downloader configuration and initialization (4 tests)
  - DownloadProgress dataclass validation (1 test)
  - Custom exception handling (2 tests)
  - Authentication header generation (3 tests)
  - Session management (3 tests)

### Documentation
- Update backend-testing-improvement-plan.md with Phase 1 completion status

## Test Results
- All 458 service tests pass
- No regressions introduced

Relates to backend testing improvement plan Phase 1
2026-02-11 10:29:21 +08:00
Will Miao
6b1e3f06ed refactor(example-images): minimize async lock contention by moving I/O outside critical sections
- Extract progress file loading to async methods to run in executor
- Refactor start_download to reduce lock time by pre-loading data before entering lock
- Improve check_pending_models efficiency with single-pass model collection and async loading
- Add type hints to get_status method
- Add tests for download task callback execution and error handling
2026-02-11 09:24:00 +08:00
Will Miao
94edde7744 feat(settings): add metadata_refresh_skip_paths to sync keys for UI update 2026-02-09 10:09:53 +08:00
Will Miao
024dfff021 feat: add metadata refresh skip paths setting, #790 2026-02-09 09:56:19 +08:00
Will Miao
a13fbbff48 i18n: complete translations for skip metadata refresh feature
Translate all skip metadata refresh UI strings to all supported languages:
- zh-CN, zh-TW, ja, ko, de, fr, es, ru, he

Completes the translation TODOs from the previous commit.
2026-02-09 09:56:19 +08:00
Will Miao
765c1c42a9 feat: enhance skip metadata refresh with smart UI and subtle badges, #790 2026-02-09 09:56:18 +08:00
Will Miao
2b74b2373d fix: prevent video preview persisting when switching between recipes 2026-02-08 11:18:41 +08:00
Will Miao
b4ad03c9bf fix: improve example image upload reliability and error handling, #804
- Sequential per-file upload to avoid client_max_size limits
- Add backend exception handler with proper 500 responses
- Increase standalone server upload limit to 256MB
- Add partial success localization support
2026-02-08 09:17:19 +08:00
Will Miao
199c9f742c feat(docs): update AGENTS.md with improved testing and development instructions
- Simplify pytest coverage command by consolidating --cov flags
- Remove redundant JSON coverage report
- Reorganize frontend section into "Frontend Development (Standalone Web UI)" and "Vue Widget Development"
- Add npm commands for Vue widget development (dev, build, typecheck, tests)
- Consolidate Python code style sections (imports, formatting, naming, error handling, async)
- Update architecture overview with clearer service descriptions
- Fix truncated line in API endpoints note
- Improve readability and remove redundant information
2026-02-08 08:30:57 +08:00
Will Miao
e2f1520e7f docs: update LM-Extension-Wiki with CivArchive support and v0.4.8 features
- Reframe supporter access section to emphasize sustainability and gratitude
- Add CivArchive support announcement and image
- Document new dedicated download button and hide models feature in v0.4.8
- Improve readability and flow of the overview and supporter sections
2026-02-07 23:27:01 +08:00
Will Miao
1606a3ff46 feat: add clear button to autocomplete text widget and fix external value change sync
- Add clear button inside autocomplete text widget that shows when text exists
- Support both Canvas mode and Vue DOM mode with appropriate styling
- Fix clear button visibility when value is changed externally (e.g., via 'send lora to workflow')
- Implement dual notification mechanism: CustomEvent + onSetValue callback
- Update widget interface to include onSetValue property
2026-02-06 09:15:16 +08:00
Will Miao
b313f36be9 feat(duplicates): exit duplicate mode when no duplicates found, #783
When no duplicate groups are detected, the duplicate manager now checks if it is currently in duplicate mode and calls `exitDuplicateMode()` to clear the display. This prevents the UI from showing stale duplicate information when no duplicates exist.
2026-02-05 22:54:24 +08:00