fix(ui): control adapters require control images

There wasn't enough validation of control adapters during graph building. It would be possible for a graph to be built with empty collect node, causing an error. Addressed with an extra check.

This should never happen in practice, because the invoke button should be disabled if an invalid CA is active.
This commit is contained in:
psychedelicious 2024-03-14 10:07:15 +11:00
parent 4bb5aba70e
commit ee3a1a95ef
3 changed files with 22 additions and 7 deletions

View File

@ -18,7 +18,13 @@ export const addControlNetToLinearGraph = async (
baseNodeId: string baseNodeId: string
): Promise<void> => { ): Promise<void> => {
const validControlNets = selectValidControlNets(state.controlAdapters).filter( const validControlNets = selectValidControlNets(state.controlAdapters).filter(
(ca) => ca.model?.base === state.generation.model?.base ({ model, processedControlImage, processorType, controlImage, isEnabled }) => {
const hasModel = Boolean(model);
const doesBaseMatch = model?.base === state.generation.model?.base;
const hasControlImage = (processedControlImage && processorType !== 'none') || controlImage;
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
}
); );
// const metadataAccumulator = graph.nodes[METADATA_ACCUMULATOR] as // const metadataAccumulator = graph.nodes[METADATA_ACCUMULATOR] as
@ -83,7 +89,7 @@ export const addControlNetToLinearGraph = async (
image_name: controlImage, image_name: controlImage,
}; };
} else { } else {
// Skip ControlNets without an unprocessed image - should never happen if everything is working correctly // Skip CAs without an unprocessed image - should never happen, we already filtered the list of valid CAs
return; return;
} }

View File

@ -17,9 +17,12 @@ export const addIPAdapterToLinearGraph = async (
graph: NonNullableGraph, graph: NonNullableGraph,
baseNodeId: string baseNodeId: string
): Promise<void> => { ): Promise<void> => {
const validIPAdapters = selectValidIPAdapters(state.controlAdapters).filter( const validIPAdapters = selectValidIPAdapters(state.controlAdapters).filter(({ model, controlImage, isEnabled }) => {
(ca) => ca.model?.base === state.generation.model?.base const hasModel = Boolean(model);
); const doesBaseMatch = model?.base === state.generation.model?.base;
const hasControlImage = controlImage;
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
});
if (validIPAdapters.length) { if (validIPAdapters.length) {
// Even though denoise_latents' ip adapter input is collection or scalar, keep it simple and always use a collect // Even though denoise_latents' ip adapter input is collection or scalar, keep it simple and always use a collect

View File

@ -18,7 +18,13 @@ export const addT2IAdaptersToLinearGraph = async (
baseNodeId: string baseNodeId: string
): Promise<void> => { ): Promise<void> => {
const validT2IAdapters = selectValidT2IAdapters(state.controlAdapters).filter( const validT2IAdapters = selectValidT2IAdapters(state.controlAdapters).filter(
(ca) => ca.model?.base === state.generation.model?.base ({ model, processedControlImage, processorType, controlImage, isEnabled }) => {
const hasModel = Boolean(model);
const doesBaseMatch = model?.base === state.generation.model?.base;
const hasControlImage = (processedControlImage && processorType !== 'none') || controlImage;
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
}
); );
if (validT2IAdapters.length) { if (validT2IAdapters.length) {
@ -77,7 +83,7 @@ export const addT2IAdaptersToLinearGraph = async (
image_name: controlImage, image_name: controlImage,
}; };
} else { } else {
// Skip ControlNets without an unprocessed image - should never happen if everything is working correctly // Skip CAs without an unprocessed image - should never happen, we already filtered the list of valid CAs
return; return;
} }