Skip to content

feat(models): default component models per main model - #10263

Draft
Pfannkuchensack wants to merge 5 commits into
invoke-ai:mainfrom
Pfannkuchensack:feat/main-model-default-components
Draft

Pfannkuchensack wants to merge 5 commits into
invoke-ai:mainfrom
Pfannkuchensack:feat/main-model-default-components

Conversation

@Pfannkuchensack

@Pfannkuchensack Pfannkuchensack commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Stacked on #10246. Until it merges, the diff also shows its commits. This PR's changes are cc64a06ca2 (feature) and 8e750ff775 (docs). Draft until #10246 lands; I'll rebase onto main then.

Summary

A main model could only store a default VAE. Its other components (T5/CLIP, Qwen3, Qwen3-VL, Mistral, a component source, a PiD decoder, …) had to be picked by hand after every switch. The default VAE itself was applied only by Reset all to model defaults and by recall, never on switch.

  • Backend: MainModelDefaultSettings.components (optional map). Its keys are the component's generation metadata name (t5_encoder, qwen3_vl_encoder, …) and its values are model keys. Validation: snake_case keys, vae rejected (it keeps its own field), at most 16 entries, no blank values, {} → null. The field is left out of the stored JSON when unset. Re-identify now keeps the default VAE and components while the base is unchanged, and keeps the curated fields when the probe returns no settings.
  • Switching models (Generate and Canvas): after the existing compatibility pass, each slot that is empty or was cleared as incompatible gets the new model's default. The default VAE is filled the same way, including the SD VAE picker. A selection that already fits stays. Re-selecting the same model changes nothing. Fills don't make the switch "lossy". The model a new project starts with gets its defaults too.
  • Reset and Recall: both apply the defaults, replacing current picks. In recall, a recorded component still wins. Headless graph export applies them like the default VAE.
  • Model Manager: a Default Components group lists one picker per slot of the model's family. The slots and filters are Generate's, loaded lazily with the existing scheduler rules, whose source is renamed to defaults rules. Slots with nothing installed and nothing stored are hidden.
  • Default VAE picker: it now offers the VAEs Generate accepts, including cross-base ones: FLUX.2's for MOSS-Image, FLUX's for Z-Image, and so on. Before, it filtered on the same base and showed nothing for these families.
  • One slot ↔ metadata-name table: recall's component list is derived from it, so the two can't drift.

Related Issues / Discussions

Follow-up to #10246. Supersedes #10260 (FrankBro), which found the cross-base VAE picker gap.

QA Instructions

  • Backend:
    • uv run --no-sync pytest tests/app/services/model_manager/test_model_record_changes.py tests/backend/model_manager/configs/test_main_default_components.py tests/backend/model_manager/configs/test_identified_default_settings.py tests/app/services/model_records/test_model_records_sql.py: 134 passed.
    • Ruff check/format clean.
  • Generated API: openapi.json and schema.ts regenerated; they add only the new field. In invokeai/frontend/api: pnpm lint and pnpm test pass.
  • Frontend:
    • pnpm run lint:code and pnpm run architecture:check pass.
    • Full unit run: 5 failures. Browser runs over features/generation, features/models, app and workbench/image-actions: 2 failures. All 7 are local de-DE number/keyboard formatting in untouched files (hotkeys, image-map, model cache, UpscaleCapabilityGate); CI runs en-US.
  • Browser (mock backend, FLUX/T5/CLIP/VAE/MOSS fixtures injected):
    1. Model Manager → a FLUX.1 model → Default Components: set T5 and CLIP, Save Defaults. The PATCH sends components: {t5_encoder, clip_embed_model} and the section is clean afterwards.
    2. Generate: switch to that model. T5 and CLIP are filled, with no confirm dialog.
    3. Switch to another FLUX model, pick a different T5, switch back: the fitting pick stays.
    4. Reset all to model defaults sets the defaults again.
    5. MOSS-Image model → Default VAE offers the FLUX.2 VAEs and no SDXL VAE.
  • Not run: check:release, the performance gate, Family E2E. No graph builder changed; only which installed models the slots start with.

Review

Resolved:

  • Stored JSON: the field is excluded from the record when unset, so a downgrade only affects models that actually store components (see Compatibility).
  • FLUX.2 component source: a stored default for it was overwritten by the automatic pick on the next resolve. Defaults now apply only to slots the family offers.
  • Recall: it replaces like Reset.
  • Re-identify: it no longer carries a VAE/components across a base change.
  • Model Manager:
    • the components group no longer duplicates the scheduler's Retry or drops focus;
    • draft equality is structural;
    • dependent slots (the Qwen3-VL vision tower) are pruned when they close.

Remaining:

  • Upscale and Video don't use default components yet.
  • A stored component or default VAE whose model was deleted shows as "No default" in the Model Manager; it is ignored when applying, as vae was before.
  • Conflicts with another session's edit are detected per map, not per slot.

Compatibility / Rollout

  • No migration: the field is optional and absent by default.
  • Downgrade: a main model that stores components is rejected by an older server (extra="forbid" on MainModelDefaultSettings) and drops out of its model list until the components are cleared. Records without components are unaffected.
  • PATCH: default_settings still replaces the whole object, and the UI sends the full object.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Meaningful regression coverage added / updated where needed; obsolete tests/code removed
  • Persisted-state and API changes include required migrations / compatibility validation
  • Relevant performance/efficiency opportunities considered; material claims have evidence
  • Material review findings resolved and relevant checks rerun
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)

Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

ModelSelect takes a `relatedTo` anchor instead of using its own value, which never had linkable candidates.
Generate, Video and Upscale component, LoRA, VAE and reference pickers anchor on the active main model; model default settings anchor on the edited model.
Linked models rank first in their base group with an icon naming the anchor model.
Chakra hides icons from assistive technology, so the link icon's label
never reached screen readers, and the tooltip is unreachable while focus
stays in the search field. Put the label into the option's text as
visually hidden content and assert the option's accessible name.
Main models store default components (encoders, component source, PiD decoder) next to the default VAE; switching to
the model fills empty or incompatible slots, and Reset and Recall apply them. The Model Manager edits them per slot
and offers the VAEs Generate accepts, including cross-base ones. Re-identify keeps the default VAE and components.
@github-actions github-actions Bot added python PRs that change python files backend PRs that change backend files services PRs that change app services frontend PRs that change frontend files python-tests PRs that change python tests docs PRs that change docs labels Nov 13, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend PRs that change backend files docs PRs that change docs frontend PRs that change frontend files python PRs that change python files python-tests PRs that change python tests services PRs that change app services

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants