Download root rules now accept match_type "tag": the rule hits when any
of its free-text tags equals one of the model's CivitAI tags (trimmed,
case-insensitive), so e.g. all "character" models can be routed to a NAS
root regardless of base model. Rules stay ordered — first match wins
across mixed base_model/tag rules.
- settings normalize keeps tag entries as free text (case-insensitive
dedupe, no base-model whitelist); resolve_download_root gained a tags
parameter and a match_download_root_rule helper
- the download flow passes the version's model tags into rule resolution
- the routing endpoint accepts tags and reports the matched rule; the
versions endpoint ships model-level tags with each version so the
location step can preview tag matches
- the settings rule editor gained a per-rule match-type dropdown; tag
rules edit a comma-separated list (committed on blur/Enter) instead of
the base model checkbox panel
- the download confirmation modal shows "Routed by rule: ..." next to
the preselected root
Add a download_root_rules setting: ordered per-type rules
({match_type: base_model, match: [...], root: path}) that replace the
default download root when 'use default paths' is on. The first matching
rule wins; unmatched downloads fall back to default_*_root. Rules are
consulted under the final download type, so a checkpoint routed to the
unet roots uses the unet rule set.
- settings_manager: normalize/get/set with root validation against the
configured roots (folder_paths + extra_folder_paths); invalid rules
are dropped with a warning
- download_manager: apply the resolved root in the use_default_paths
branches for lora/checkpoint(unet)/embedding downloads
- download routing handler: expose resolved_root so the download
confirmation modal preselects the rule-routed root
- settings UI: per-type rule editor in the Organization section with
base-model multi-select panels, root dropdowns, reorder and remove
CivitAI labels new DiT architectures (MiniMax H3, future Flux/Wan/Qwen
variants) as model.type "Checkpoint" with plain "Model" file entries,
so the DIFFUSION_MODEL_BASE_MODELS allowlist could never keep up and
such downloads were mis-routed to the checkpoint roots (e.g. model
2877206 / version 3374439). The set of true full-checkpoint families is
closed, so the baseModel fallback is inverted:
1. file type UNet/Diffusion Model -> unet (unchanged)
2. baseModel in DIFFUSION_MODEL_BASE_MODELS (now incl. MiniMax H3) -> unet
3. baseModel in new CHECKPOINT_BASE_MODELS (SD 1.x/2.x/3.x, SDXL, Pony,
Illustrious, NoobAI) -> checkpoint
4. unknown/empty baseModel -> new unknown_base_model_routing setting,
defaulting to diffusion models
The setting is exposed under Settings > Downloads, validated in
SettingsManager, and threaded into both the download manager and the
download routing endpoint so they keep agreeing.
The download modal's location step decided between checkpoint and unet
roots using only the CivitAI file-type signal, while the backend also
falls back to DIFFUSION_MODEL_BASE_MODELS. Models like Anima (file type
"Model") were offered checkpoint roots in the UI even though
use_default_paths would route them to the unet root.
- Extract the two-tier decision into py/services/download_routing.py and
reuse it in DownloadManager._execute_download
- Add POST /api/lm/download/routing so the UI asks the backend for the
routing decision; fall back to the local file-type check on failure
- ModelVersionsTab: search both checkpoint and unet roots when resolving
an existing version's download path