Replace the 1095-line monolithic SearchService with a thin facade that
delegates to SearchOrchestrator. Split the implementation into three
focused modules:
- search_orchestrator.py: request parsing, provider coordination, and
response construction
- search_providers.py: per-source execution, progress callbacks, and
async task creation
- search_cache.py: timestamping and stable cache stamping for results
Add unit tests for the new components in
tests/test_search_service_components.py. Preserve the existing HTTP
route behavior by keeping SearchService.search_sources as the stable
route-facing API.
Replace dynamic MODEL_SERVICE_DEPENDENCIES injection with frozen dataclasses
(CivitAISearchDependencies, CustomUrlDependencies, ModelDetailsDependencies)
to make service dependencies explicit and type-safe. Update model services to
construct via RouteContext, and add tests enforcing minimal dataclass fields.
Break down the monolithic model_service into smaller, single-responsibility
services: CivitAISearchService, CustomUrlService, and ModelDetailsService.
Introduce ModelServiceDependencies base class to centralize RouteContext
dependency injection. Update model_service to act as a thin facade that
delegates to the specialized services. Add unit tests validating the new
service boundaries and basic request validation behavior.
Break monolithic model_info, search, and workflow route files into
smaller modules by responsibility: civitai_search, custom_url,
model_details, search_support, source_search, workflow_analysis,
hashes, and loaded_models. Update registry imports to preserve the
existing route registrations and API surface. Add partition coverage
tests to ensure no route endpoints are dropped or duplicated.
Move the inline route definitions out of __init__.py into a new core/routes
package (registry, base_models, helpers, settings, version). Add the
JobProgressTracker utility in core/progress.py and extract version discovery
logic into core/version.py. Update tests to cover the refactored structure.
Implement streaming SHA-256 verification for Python download backend,
writing to a .part file first and publishing to the final path only after
the hash matches the source metadata. Mismatched downloads are preserved
at .badsha instead of being silently deleted. Close the download response
in a finally block to avoid leaking handles on cancellation or errors.
Support both Comfy-Org and Kijai author indexes as known HuggingFace fallbacks, aggregate their status in the backend, refresh the cached author index, and update the frontend UI and tests.
- Skip fuzzy matching for already-resolved model references in the backend
- Keep existing nodes in their previous result positions during incremental workflow analysis
- Simplify frontend workflow sync and add a content-preserving refresh path
- Preserve scroll position and suppress progress overlay during background Missing/Loaded Models refresh
- Add backend and frontend tests for the new incremental refresh behavior
- Preserve existing image metadata when re-normalizing CivitAI model images
- Add extractComfyWorkflow helper to recover pasteable editor workflows from image metadata, including nested/double-encoded JSON and non-finite number tolerance
- Surface recovered workflows as a copyable button in the model info image preview under Other metadata
- Add focused tests for workflow extraction, metadata preservation, and edge cases
Replace the Windows-only Explorer behavior with a host-file-manager
implementation that supports Windows, macOS, and Linux. The endpoint
now validates input, handles frontend backslash paths on POSIX, returns
structured errors, and reports the launcher/platform. Update README
wording and add tests for the new module.
Treat control_after_generate widgets that are implicitly inserted after seed
widgets as non-model widgets when analyzing dynamic node layouts. This
prevents the resolver from attempting to resolve control values such as
'fixed', 'randomize', 'increment', and 'decrement' as model paths.
Treat widget values under the configs and custom_nodes dynamic
categories as non-model references so the workflow analyzer does
not falsely mark them as missing models. Added a regression test
to verify a checkpoint widget is still detected when a config
widget is present.