mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): use less brutally strict workflow validation
Workflow building would fail when a current image node was in the workflow due to the strict validation. So we need to use the other workflow builder util first, which strips out extraneous data. This bug was introduced during an attempt to optimize the workflow building logic, which was causing slowdowns on the workflow editor.
This commit is contained in:
parent
7269c9f02e
commit
0809e832d4
@ -1,6 +1,6 @@
|
||||
import { enqueueRequested } from 'app/store/actions';
|
||||
import { buildNodesGraph } from 'features/nodes/util/graph/buildNodesGraph';
|
||||
import { buildWorkflowRight } from 'features/nodes/util/workflow/buildWorkflow';
|
||||
import { buildWorkflowWithValidation } from 'features/nodes/util/workflow/buildWorkflow';
|
||||
import { queueApi } from 'services/api/endpoints/queue';
|
||||
import type { BatchConfig } from 'services/api/types';
|
||||
|
||||
@ -15,7 +15,7 @@ export const addEnqueueRequestedNodes = () => {
|
||||
const { nodes, edges } = state.nodes;
|
||||
const workflow = state.workflow;
|
||||
const graph = buildNodesGraph(state.nodes);
|
||||
const builtWorkflow = buildWorkflowRight({
|
||||
const builtWorkflow = buildWorkflowWithValidation({
|
||||
nodes,
|
||||
edges,
|
||||
workflow,
|
||||
|
@ -9,10 +9,10 @@ import {
|
||||
} from 'features/nodes/store/nodesSlice';
|
||||
import type { WorkflowsState as WorkflowState } from 'features/nodes/store/types';
|
||||
import type { FieldIdentifier } from 'features/nodes/types/field';
|
||||
import type { WorkflowV2 } from 'features/nodes/types/workflow';
|
||||
import { cloneDeep, isEqual, uniqBy } from 'lodash-es';
|
||||
|
||||
export const initialWorkflowState: WorkflowState = {
|
||||
_version: 1,
|
||||
export const blankWorkflow: Omit<WorkflowV2, 'nodes' | 'edges'> = {
|
||||
name: '',
|
||||
author: '',
|
||||
description: '',
|
||||
@ -22,7 +22,12 @@ export const initialWorkflowState: WorkflowState = {
|
||||
notes: '',
|
||||
exposedFields: [],
|
||||
meta: { version: '2.0.0', category: 'user' },
|
||||
};
|
||||
|
||||
export const initialWorkflowState: WorkflowState = {
|
||||
_version: 1,
|
||||
isTouched: true,
|
||||
...blankWorkflow,
|
||||
};
|
||||
|
||||
const workflowSlice = createSlice({
|
||||
|
@ -2,9 +2,10 @@ import { logger } from 'app/logging/logger';
|
||||
import { parseify } from 'common/util/serialize';
|
||||
import type { NodesState, WorkflowsState } from 'features/nodes/store/types';
|
||||
import { isInvocationNode, isNotesNode } from 'features/nodes/types/invocation';
|
||||
import { type WorkflowV2, zWorkflowV2 } from 'features/nodes/types/workflow';
|
||||
import type { WorkflowV2 } from 'features/nodes/types/workflow';
|
||||
import { zWorkflowV2 } from 'features/nodes/types/workflow';
|
||||
import i18n from 'i18n';
|
||||
import { cloneDeep, omit } from 'lodash-es';
|
||||
import { cloneDeep, pick } from 'lodash-es';
|
||||
import { fromZodError } from 'zod-validation-error';
|
||||
|
||||
export type BuildWorkflowArg = {
|
||||
@ -13,6 +14,18 @@ export type BuildWorkflowArg = {
|
||||
workflow: WorkflowsState;
|
||||
};
|
||||
|
||||
const workflowKeys = [
|
||||
'name',
|
||||
'author',
|
||||
'description',
|
||||
'version',
|
||||
'contact',
|
||||
'tags',
|
||||
'notes',
|
||||
'exposedFields',
|
||||
'meta',
|
||||
] satisfies (keyof WorkflowV2)[];
|
||||
|
||||
export type BuildWorkflowFunction = (arg: BuildWorkflowArg) => WorkflowV2;
|
||||
|
||||
export const buildWorkflowFast: BuildWorkflowFunction = ({
|
||||
@ -20,7 +33,7 @@ export const buildWorkflowFast: BuildWorkflowFunction = ({
|
||||
edges,
|
||||
workflow,
|
||||
}: BuildWorkflowArg): WorkflowV2 => {
|
||||
const clonedWorkflow = omit(cloneDeep(workflow), 'isTouched');
|
||||
const clonedWorkflow = pick(cloneDeep(workflow), workflowKeys);
|
||||
|
||||
const newWorkflow: WorkflowV2 = {
|
||||
...clonedWorkflow,
|
||||
@ -73,25 +86,23 @@ export const buildWorkflowFast: BuildWorkflowFunction = ({
|
||||
return newWorkflow;
|
||||
};
|
||||
|
||||
export const buildWorkflowRight = ({
|
||||
export const buildWorkflowWithValidation = ({
|
||||
nodes,
|
||||
edges,
|
||||
workflow,
|
||||
}: BuildWorkflowArg): WorkflowV2 | null => {
|
||||
const newWorkflowUnsafe = {
|
||||
...workflow,
|
||||
nodes,
|
||||
edges,
|
||||
};
|
||||
// builds what really, really should be a valid workflow
|
||||
const workflowToValidate = buildWorkflowFast({ nodes, edges, workflow });
|
||||
|
||||
const result = zWorkflowV2.safeParse(newWorkflowUnsafe);
|
||||
// but bc we are storing this in the DB, let's be extra sure
|
||||
const result = zWorkflowV2.safeParse(workflowToValidate);
|
||||
|
||||
if (!result.success) {
|
||||
const { message } = fromZodError(result.error, {
|
||||
prefix: i18n.t('nodes.unableToParseNode'),
|
||||
prefix: i18n.t('nodes.unableToValidateWorkflow'),
|
||||
});
|
||||
|
||||
logger('nodes').warn({ workflow: parseify(newWorkflowUnsafe) }, message);
|
||||
logger('nodes').warn({ workflow: parseify(workflowToValidate) }, message);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user