- core/workflow_analyzer.py: add dynamic widget category hint extraction via threaded cache and sentinel-prefix matching; get_model_widget_category_hints now returns all inferred categories including dynamic ones, improving model folder detection for workflows with encoded category metadata.
- web: add ? help icon with context-aware tooltip to download folder selector explaining why a category was auto-selected (preserved manual choice, node type hint, workflow-detected category, default fallback, or best available). Tooltip refreshes live as the user changes the folder selection.
- web/css/resolver-main.css: style the new category help badge.
- metadata/huggingface-author-index.json: update index entry.
Add early-return optimizations so both backend and frontend avoid unnecessary
URL extraction and disk scanning when a workflow has no nodes or contains
no potential model references.
Also tighten API input validation by rejecting non-object workflow_json.
- Add CivitAI badge overlay on example images with icon and direct link
- Extract denoise, scheduler, and cfgScale from metadata in civitai.py
- Support additionalResources alongside resources in both parser paths
- Redesign resource display with clickable links, version badges, and type/weight pills
- Drop prompt tags section and getInfoImagePromptTags; focus preview on generation data and resources
- Include full metadata rows and resources in copy-to-clipboard output
- Add matching CSS for badge, resource layout, and interactive states
- Add rapidfuzz as optional dependency with SequenceMatcher fallback
- Use stable path identity (realpath) for deduplication in scanner and resolver
- Prevent duplicate scans and duplicate model entries across symlinks/junctions
- Improve matching performance with RapidFuzz when available
Report resolved (already-existing) models alongside missing ones in the
missing-browser view. Resolved models are hidden by default; a new
'Show resolved' toggle in the toolbar reveals them with a badge and
reduced-opacity row styling. The toggle state is persisted in
localStorage.
Backend: include resolved_models and total_resolved in the analysis
payload so the frontend can merge them into the display list.
Frontend: normalize resolved workflow models into the missing-models
display shape, compute visibility-aware counts, and refresh the
missing-browser view on queue mutating actions.
- Add version-trimmed alias generation to handle trailing version zeros (e.g. '4.0' -> '4')
- Track newly added base model names in 'new_models_added_list' field
- Include Ideogram 4.0, Boogu, and PolyGen in base-models registry
- Update web resolver to match aliases using both original and version-trimmed tokens
- Enhance base models update UI to show which new models were added
core/downloader.py: When a file already exists at dest_path, extract the expected
SHA256 from metadata, prefers a trusted LoRA Manager sidecar hash, falls back to
calculating the file hash, and returns already_exists=true plus sha256_source
when the hashes match. If the hashes differ, the download is skipped with a
clear warning instead of silently re-downloading.
web/resolver/actions/resolve_download_methods.js: Thread already_exists through
resolveDownloadMethods so notifications, progress messages, and snapshot payloads
reflect 'Already downloaded' when the backend determined the model was a SHA256
match.
- Add force_rescan end-to-end so callers can bypass the short-lived local model scan cache: backend entry in __init__.py and core/resolver.py, lifecycle_graph_methods forwards it through the workflow analysis body, and download_target_methods passes ?force=1 from the refresh flow.
- Rewrite combo dropdown lifecycle in missing_browser_methods with show/hide helpers, pointer-capture tracking, and a capture-phase outside-click listener so the list stays open during drag/hover and closes reliably otherwise.
- Animate refresh buttons (CSS keyframes + JS Web Animations) with reduced-motion fallback.
- Encode selected model path into the selected-bar data-model attribute and wire contextmenu so users can open the containing folder from the selection.
- Fix XSS risk in selected-bar label by escaping label HTML; change queue/selected Remove buttons to danger style.
- Increase max missing-browser model column width clamp from 430 to 820 and stop truncating missing-filename display; show full filename with tooltip instead.
- Update huggingface-author-index.json metadata timestamp/counts (1 file changed, 1 line).
- workflow_analyzer: refactor widget category hint resolution and add widget name candidate extraction across widgets, inputs, proxyWidgets, and localized names; expose new helpers get_widget_name_candidates/get_widget_name_hint
- workflow_analyzer: add get_model_widget_category_hint and get_effective_model_category_hint to unify category fallback logic
- workflow_analyzer: include widget_name on model refs emitted by get_node_model_info
- workflow_analyzer: introduce promoted-widget context resolution (_build_promoted_widget_contexts, _find_promoted_widget_targets, etc.) and wire it into analyze_workflow_models so instance widgets and promoted widget locators are tracked with subgraph scope
- lifecycle_graph_methods: refactor locateNodeInGraph into subgraph-aware resolver using findLocateTarget/getGraphNodeById/findSubgraphById/findNodeInGraphTree; support targeting nodes inside specific subgraphs with proper canvas focus and notifications
- missing_browser_methods: use unified getMissingLocateTarget for locate button/display fields; pass subgraphId and isTopLevel to locateNodeInGraph; add promoted-widget-aware tooltips and canLocate handling
Add support for additional ComfyUI model types including diffusers, gligen,
style models (latent/regular upscale), audio encoders, background removal,
frame interpolation, geometry estimation, detection, model patches/photomaker,
and optical flow models.
Backend changes:
- Extend CATEGORY_MAP, URN_TYPE_MAP, and node type hints in workflow analyzer
to cover dozens of new loader node types and singular/plural aliases.
- Add MODEL_OUTPUT_TYPE_TO_CATEGORY and get_node_output_category_hint() so
loader output types can contribute category hints.
- Make widget name matching normalize underscores, hyphens, and spaces.
- Improve directory discovery to enumerate folders from folder_paths while
filtering unsupported categories.
- Include folders as model entries in directory scanning (with a diffusers
guard requiring model_index.json).
Frontend changes:
- Update download target category maps, display names, token name maps, and
per-node widget index lists to match the expanded backend coverage.
Implements a new download path configuration UI and backend logic:
- Add Subfolder fill mode: Suggested (existing), Template, Manual
- Add Base Model Path Mappings to override detected base-model folders
- Add Default Root settings to control root directory per category
- Add Detect From Existing Folders button that infers templates and mappings from local model folders
- Add backend /model_resolver/root-directories and /model_resolver/path-template-suggestions routes
- Refactor resolver settings into core/settings.py for shared frontend/backend use
- Extract path template inference logic into core/path_templates.py
- Update download panel, context menu, and loading flow to use new path settings
- Add model_title match type for CivArchive and CivitAI sources, resolving
extensionless workflow values by title similarity (threshold 82.0)
- Recognize new node types and widget indices across model categories
(GGUF, CLIP, ControlNet, StyleModel, Hypernetwork, etc.)
- Scan known model combo widget indices even when the stored value has no
file extension, treating non-placeholder strings as model references
- Strip known model extensions during workflow URL lookup so filename stems
match regardless of extension
- Update HuggingFace author index metadata
- README.md: updated badge labelColor from 111827 to 1a1a1a for consistency
- core/workflow_analyzer.py: add LoaderGGUF and gguf_name mapping to diffusion_models
- web/resolver/model_resolver.js: rename panel title from 'Model Resolver' to 'Resolver'
- Add frontend_logs_enabled/frontend_log_level and backend_logs_enabled/backend_log_level
toggles and selectors in the Options panel (web/resolver/views/options_methods.js)
- Sync frontend logging settings from localStorage / server settings into the
frontend logger on startup and settings load (download_target_methods.js)
- Apply backend logging settings from server settings in the Python backend
(__init__.py), loading control state on startup and after saves
- Make frontend Logger resilient to stored configs that lack an 'enabled' flag
and to legacy/invalid moduleSettings levels (logger.js)
- Guard default module logger level initialization against undefined settings
(log_funcs.js)
- Replace scattered console.log/usages with module-level log.debug calls across
resolve_download_methods.js, model_resolver.js, and workflow_state_methods.js
- Bump log system package version to 1.5.6 (core + web)
Pass available_models through to the workflow analyzer, enabling
case-sensitive relative path lookups against scanned model data.
Normalize paths for comparison while preserving letter casing.
Skip irrelevant categories (custom_nodes, configs) upfront.
Fall back gracefully when no scanner data is available.
Also ignore the tests/ directory in .gitignore.
Add a shared normalize_download_category helper (with CATEGORY_MAP) in Python
and use it in get_download_directory to prefer redirected paths and to rank
diffusion_models above legacy unet folders. Mirror the same normalization in
the JS downloadTargetMethods, applying it consistently when coalescing
downloadDirectories, building dropdown keys, and reading/writing selections.
Also fix display labels to use 'diffusion_models' instead of 'unet'.
Propagate the resolved download directory and file path from the backend
download flow into frontend progress UI: add \path\ and \directory\ fields
to download progress state, render right-clickable context menu entries on
progress bars and status messages, and allow opening the download folder
directly from completion or error notifications. Also update the HuggingFace
author index.
Update search logging to use reusable formatters for values, sizes, and field
pairs, and add append-only extra kwargs so downstream logs stay on one line.
Tighten HuggingFace source messages, refresh the author index metadata, and
consolidate LoraManager/CivitAI log text.
backend:
- add 429 retry handling with backoff in CivArchive API requests
- add page-scraping fallback for CivArchive model payloads
- normalize CivArchive mirrors with dead/gated/paid/sha256 metadata
- include file metadata and mirror data in normalized archive files
- propagate additional dead/missing status field aliases
- include metadata in normalized CivitAI files
frontend:
- render mirror lists with source grouping, dead-link indicators, and skull icons
- add file badges (primary, type, format, size, fp, mirror count, id)
- improve secondary info in resolve/download methods to include base model
- enhance search panel secondary info with base model and filename
- on selecting a version with empty files, fetch fresh version details
- propagate base model context to CivitAI search state and display labels
Adds a fullscreen image preview dialog to the model info panel with
navigation, copy-prompt support, generation metadata display, and
referenced resources listing.
Extends CivitAI backend extraction to handle varied metadata key names
(negativePrompt, Clip skip, Model, etc.) and surfaces clip_skip, width,
height, tags, resources, and raw metadata through the new preview UI.
Renames z-index variable to reserve a dedicated layer for the preview
backdrop.
Uses an exact alias membership check instead of substring matching to prevent
false positives, e.g. 'zimage' alias no longer incorrectly matches
'zimagebase'.
Replace the heavy autoResolveAfterDownload path (which re-analyzed the
entire workflow) with a more efficient refreshLocalMatchesForDownloadedMissing
call that queries /model_resolver/local-matches directly for the
specific downloaded file.
This removes the unnecessary re-analysis step, adds an explicit
force_rescan flag (coerced to bool on the backend for safe JSON
payload handling), propagates the missing model's category through
the activeDownloads tracking objects, and updates related UI text
to reflect the new narrower behavior.
Raise CivArchiveSearchError in civarchive backend, catch and store it in
source_results in the workflow analyzer, surface it in resolve_download_methods
as an 'error' status, and display error messages in search_panel progress
items and tooltips.
Adds a checkbox in the resolver footer search menu that bypasses all
search result caches for the duration of a batch search run.
Frontend (queue_methods.js, resolve_download_methods.js,
resolver_dialog.js, search_panel.js, resolver-main.css):
- Introduce checkbox-type footer menu items (type: 'checkbox').
- Add 'Force search (ignore cache)' checkbox to the search menu,
wired to a new forceBatchSearch flag on ResolverManagerDialog.
- Pass forceSearch through searchMissingBatch and searchOnline to
the backend API call.
- When the manual search button is clicked and results already exist
for that model, forceSearch defaults to true.
- mergeSearchResults respects forceRefresh: if a forced search
returns no results for a source, that source is cleared from the
cached results.
Backend (__init__.py, core/sources/huggingface.py):
- force_search is read from the incoming API request and, when true,
clears all active source search caches (local, huggingface,
civitai, civarchive, lora_manager_archive) before searching.
- force_search is forwarded as force_refresh to
search_huggingface_for_file, which folds it into the cache key so
the cache is not hit, and propagates it to _get_author_index.
- Search result timestamps are no longer inherited from prior
cached signatures when force_search is active; a fresh timestamp
is written unconditionally.
Updated metadata/huggingface-author-index.json reflects the latest
cached author index after rebuild.
Add searched_at timestamps to search results so cached entries are accurately tracked and preserved across merges. Expand the clear-search-cache command to also invalidate popular databases, model list, and the new result timestamp store. Frontend gains new cache-clearing methods and a full resolver cache reset for maintenance. The search panel and missing browser now show source result dates and toggle the search button between 'Search' and 'Search Again' when results already exist.
The previous commit introduced server-side persistence for API keys and
preferences via a model_resolver_settings.json file and POST/GET routes.
This change reverts that behavior, returning to localStorage-only storage
for settings, which is simpler and avoids persisting sensitive credentials
to disk. Also removes the now-unnecessary .gitignore entry.
Replace all link dialog terminology with resolver terminology
throughout the codebase, including module names, CSS classes,
IDs, JS variables, SVG gradient IDs, and log module names.
Remove the old web/linker/ tree and introduce the new web/resolver/
tree with parallel structure. Also replace core/linker.py with
core/resolver.py.
Add backend endpoints (/model_linker/model-list/status, /model_linker/model-list/update)
that let users check whether their bundled ComfyUI-Manager model-list.json is current
and download the latest version from GitHub, with SHA tracking and cache invalidation.
Add corresponding UI in the Options dialog under a new 'Local Database' section
with status display, remote check, and update controls.
Adds a new include_brackets parameter to ColoredFormatter that controls
whether square brackets wrap timestamps, root labels, and log level names
in formatted log output. When True, brackets are applied; when False
(the default for AzLogsLogger), brackets are omitted for cleaner output.
This allows callers like AzLogsLogger to opt-in to bracket formatting
independently via the constructor.
Console output (ColoredFormatter):
- Level name is now wrapped in [LEVEL] and left-padded via _format_level.
- Timestamp and root-label segments are individually bracket-wrapped, keeping
plain-output layout consistent with coloured output.
- Separator between fields is colourised (colour code derived from level theme)
so the table structure remains readable.
- New include_milliseconds init flag controls whether a fractional-second suffix
is appended to the timestamp; _format_time respects it.
- _display_logger_name unchanged; _split_logger_name still decomposes dotted names
into root / detail parts.
File logging (AzLogsLogger):
- file_handlers dict introduced to cache one RotatingFileHandler per top-level
root module, preventing duplicate handlers when multiple sub-modules log to
the same file (_get_file_handler / _get_log_file / _root_module_name).
- File handler formatter upgraded from a bare logging.Formatter to ColoredFormatter
(colours off, milliseconds on, datefmt hard-coded to
'%Y-%m-%d %H:%M:%S') so file output carries the same column structure as
the console formatter.
- reset_loggers method properly removes and closes all handlers (StreamHandler
and RotatingFileHandler) from every configured logger before clearing
self.loggers and self.file_handlers, allowing _get_logger to be called again
with fresh settings.
- set_file_logging now delegates to reset_loggers instead of simply clearing
the loggers dict.
- Increment log_system version from 1.5.0 to 1.5.1 in all module docstrings
- Add # ruff: noqa: T201 to log_funcs.py and logger.py to suppress
ruff T201 (favored print() usage) warning in logging utility modules
- Bump version to 1.5.0 in config.py, log_funcs.py, and logger.py
- Add USE_COLORS = True to core/log_system/config.py
- Import USE_COLORS in log_funcs.py and pass it to the logger context as
use_colors, honouring AZLOGS_USE_COLORS env var when set
- Introduce LEVEL_THEME mapping per-level RGB colors for DEBUG/INFO/WARN/ERROR
- Add TIME_BG background color for timestamp blocks
- Refactor _color_level into _color_level_badge: bold + background color badge
- Add _color_timestamp, _color_root_label, _color_separator, _color_message helpers
- Format output as: <level-badge> <timestamp> <root-label> <message> <source>
- Split logger name into root/detail via _split_logger_name; show only detail in source field
- Non-colored fallback path uses same structured layout without ANSI codes