mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into lstein/global-configuration
This commit is contained in:
commit
f28632980d
2
.github/workflows/mkdocs-material.yml
vendored
2
.github/workflows/mkdocs-material.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
|||||||
--verbose
|
--verbose
|
||||||
|
|
||||||
- name: deploy to gh-pages
|
- name: deploy to gh-pages
|
||||||
if: ${{ github.ref == 'refs/heads/main' }}
|
if: ${{ github.ref == 'refs/heads/v2.3' }}
|
||||||
run: |
|
run: |
|
||||||
python -m \
|
python -m \
|
||||||
mkdocs gh-deploy \
|
mkdocs gh-deploy \
|
||||||
|
@ -10,6 +10,7 @@ import ConditioningInputFieldComponent from './fields/ConditioningInputFieldComp
|
|||||||
import ModelInputFieldComponent from './fields/ModelInputFieldComponent';
|
import ModelInputFieldComponent from './fields/ModelInputFieldComponent';
|
||||||
import NumberInputFieldComponent from './fields/NumberInputFieldComponent';
|
import NumberInputFieldComponent from './fields/NumberInputFieldComponent';
|
||||||
import StringInputFieldComponent from './fields/StringInputFieldComponent';
|
import StringInputFieldComponent from './fields/StringInputFieldComponent';
|
||||||
|
import ItemInputFieldComponent from './fields/ItemInputFieldComponent';
|
||||||
|
|
||||||
type InputFieldComponentProps = {
|
type InputFieldComponentProps = {
|
||||||
nodeId: string;
|
nodeId: string;
|
||||||
@ -115,6 +116,16 @@ const InputFieldComponent = (props: InputFieldComponentProps) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === 'item' && template.type === 'item') {
|
||||||
|
return (
|
||||||
|
<ItemInputFieldComponent
|
||||||
|
nodeId={nodeId}
|
||||||
|
field={field}
|
||||||
|
template={template}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return <Box p={2}>Unknown field type: {type}</Box>;
|
return <Box p={2}>Unknown field type: {type}</Box>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
import {
|
||||||
|
ItemInputFieldTemplate,
|
||||||
|
ItemInputFieldValue,
|
||||||
|
} from 'features/nodes/types/types';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { FaAddressCard, FaList } from 'react-icons/fa';
|
||||||
|
import { FieldComponentProps } from './types';
|
||||||
|
|
||||||
|
const ItemInputFieldComponent = (
|
||||||
|
props: FieldComponentProps<ItemInputFieldValue, ItemInputFieldTemplate>
|
||||||
|
) => {
|
||||||
|
const { nodeId, field } = props;
|
||||||
|
|
||||||
|
return <FaAddressCard />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ItemInputFieldComponent);
|
@ -14,6 +14,7 @@ export const FIELD_TYPE_MAP: Record<string, FieldType> = {
|
|||||||
ConditioningField: 'conditioning',
|
ConditioningField: 'conditioning',
|
||||||
model: 'model',
|
model: 'model',
|
||||||
array: 'array',
|
array: 'array',
|
||||||
|
item: 'item',
|
||||||
};
|
};
|
||||||
|
|
||||||
const COLOR_TOKEN_VALUE = 500;
|
const COLOR_TOKEN_VALUE = 500;
|
||||||
@ -82,4 +83,10 @@ export const FIELDS: Record<FieldType, FieldUIConfig> = {
|
|||||||
title: 'Array',
|
title: 'Array',
|
||||||
description: 'TODO: Array type description.',
|
description: 'TODO: Array type description.',
|
||||||
},
|
},
|
||||||
|
item: {
|
||||||
|
color: 'gray',
|
||||||
|
colorCssVar: getColorTokenCssVariable('gray'),
|
||||||
|
title: 'Collection Item',
|
||||||
|
description: 'TODO: Collection Item type description.',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,8 @@ export type FieldType =
|
|||||||
| 'latents'
|
| 'latents'
|
||||||
| 'conditioning'
|
| 'conditioning'
|
||||||
| 'model'
|
| 'model'
|
||||||
| 'array';
|
| 'array'
|
||||||
|
| 'item';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An input field is persisted across reloads as part of the user's local state.
|
* An input field is persisted across reloads as part of the user's local state.
|
||||||
@ -78,7 +79,8 @@ export type InputFieldValue =
|
|||||||
| ConditioningInputFieldValue
|
| ConditioningInputFieldValue
|
||||||
| EnumInputFieldValue
|
| EnumInputFieldValue
|
||||||
| ModelInputFieldValue
|
| ModelInputFieldValue
|
||||||
| ArrayInputFieldValue;
|
| ArrayInputFieldValue
|
||||||
|
| ItemInputFieldValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An input field template is generated on each page load from the OpenAPI schema.
|
* An input field template is generated on each page load from the OpenAPI schema.
|
||||||
@ -96,7 +98,8 @@ export type InputFieldTemplate =
|
|||||||
| ConditioningInputFieldTemplate
|
| ConditioningInputFieldTemplate
|
||||||
| EnumInputFieldTemplate
|
| EnumInputFieldTemplate
|
||||||
| ModelInputFieldTemplate
|
| ModelInputFieldTemplate
|
||||||
| ArrayInputFieldTemplate;
|
| ArrayInputFieldTemplate
|
||||||
|
| ItemInputFieldTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An output field is persisted across as part of the user's local state.
|
* An output field is persisted across as part of the user's local state.
|
||||||
@ -185,6 +188,11 @@ export type ArrayInputFieldValue = FieldValueBase & {
|
|||||||
value?: (string | number)[];
|
value?: (string | number)[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ItemInputFieldValue = FieldValueBase & {
|
||||||
|
type: 'item';
|
||||||
|
value?: undefined;
|
||||||
|
};
|
||||||
|
|
||||||
export type InputFieldTemplateBase = {
|
export type InputFieldTemplateBase = {
|
||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
@ -255,10 +263,15 @@ export type ModelInputFieldTemplate = InputFieldTemplateBase & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type ArrayInputFieldTemplate = InputFieldTemplateBase & {
|
export type ArrayInputFieldTemplate = InputFieldTemplateBase & {
|
||||||
default: (string | number)[];
|
default: [];
|
||||||
type: 'array';
|
type: 'array';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ItemInputFieldTemplate = InputFieldTemplateBase & {
|
||||||
|
default: undefined;
|
||||||
|
type: 'item';
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JANKY CUSTOMISATION OF OpenAPI SCHEMA TYPES
|
* JANKY CUSTOMISATION OF OpenAPI SCHEMA TYPES
|
||||||
*/
|
*/
|
||||||
|
@ -16,6 +16,8 @@ import {
|
|||||||
OutputFieldTemplate,
|
OutputFieldTemplate,
|
||||||
TypeHints,
|
TypeHints,
|
||||||
FieldType,
|
FieldType,
|
||||||
|
ArrayInputFieldTemplate,
|
||||||
|
ItemInputFieldTemplate,
|
||||||
} from '../types/types';
|
} from '../types/types';
|
||||||
|
|
||||||
export type BaseFieldProperties = 'name' | 'title' | 'description';
|
export type BaseFieldProperties = 'name' | 'title' | 'description';
|
||||||
@ -230,6 +232,36 @@ const buildEnumInputFieldTemplate = ({
|
|||||||
return template;
|
return template;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const buildArrayInputFieldTemplate = ({
|
||||||
|
schemaObject,
|
||||||
|
baseField,
|
||||||
|
}: BuildInputFieldArg): ArrayInputFieldTemplate => {
|
||||||
|
const template: ArrayInputFieldTemplate = {
|
||||||
|
...baseField,
|
||||||
|
type: 'array',
|
||||||
|
inputRequirement: 'always',
|
||||||
|
inputKind: 'direct',
|
||||||
|
default: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
return template;
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildItemInputFieldTemplate = ({
|
||||||
|
schemaObject,
|
||||||
|
baseField,
|
||||||
|
}: BuildInputFieldArg): ItemInputFieldTemplate => {
|
||||||
|
const template: ItemInputFieldTemplate = {
|
||||||
|
...baseField,
|
||||||
|
type: 'item',
|
||||||
|
inputRequirement: 'always',
|
||||||
|
inputKind: 'direct',
|
||||||
|
default: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
return template;
|
||||||
|
};
|
||||||
|
|
||||||
export const getFieldType = (
|
export const getFieldType = (
|
||||||
schemaObject: OpenAPIV3.SchemaObject,
|
schemaObject: OpenAPIV3.SchemaObject,
|
||||||
name: string,
|
name: string,
|
||||||
@ -303,6 +335,12 @@ export const buildInputFieldTemplate = (
|
|||||||
if (['boolean'].includes(fieldType)) {
|
if (['boolean'].includes(fieldType)) {
|
||||||
return buildBooleanInputFieldTemplate({ schemaObject, baseField });
|
return buildBooleanInputFieldTemplate({ schemaObject, baseField });
|
||||||
}
|
}
|
||||||
|
if (['array'].includes(fieldType)) {
|
||||||
|
return buildArrayInputFieldTemplate({ schemaObject, baseField });
|
||||||
|
}
|
||||||
|
if (['item'].includes(fieldType)) {
|
||||||
|
return buildItemInputFieldTemplate({ schemaObject, baseField });
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@ export const buildIterateNode = (): IterateInvocation => {
|
|||||||
return {
|
return {
|
||||||
id: nodeId,
|
id: nodeId,
|
||||||
type: 'iterate',
|
type: 'iterate',
|
||||||
collection: [],
|
// collection: [],
|
||||||
index: 0,
|
// index: 0,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
buildOutputFieldTemplates,
|
buildOutputFieldTemplates,
|
||||||
} from './fieldTemplateBuilders';
|
} from './fieldTemplateBuilders';
|
||||||
|
|
||||||
const invocationDenylist = ['Graph', 'Collect', 'LoadImage'];
|
const invocationDenylist = ['Graph', 'LoadImage'];
|
||||||
|
|
||||||
export const parseSchema = (openAPI: OpenAPIV3.Document) => {
|
export const parseSchema = (openAPI: OpenAPIV3.Document) => {
|
||||||
// filter out non-invocation schemas, plus some tricky invocations for now
|
// filter out non-invocation schemas, plus some tricky invocations for now
|
||||||
@ -32,49 +32,62 @@ export const parseSchema = (openAPI: OpenAPIV3.Document) => {
|
|||||||
if (isInvocationSchemaObject(schema)) {
|
if (isInvocationSchemaObject(schema)) {
|
||||||
const type = schema.properties.type.default;
|
const type = schema.properties.type.default;
|
||||||
|
|
||||||
const title =
|
const title = schema.ui?.title ?? schema.title.replace('Invocation', '');
|
||||||
schema.ui?.title ??
|
|
||||||
schema.title
|
|
||||||
.replace('Invocation', '')
|
|
||||||
.split(/(?=[A-Z])/) // split PascalCase into array
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
const typeHints = schema.ui?.type_hints;
|
const typeHints = schema.ui?.type_hints;
|
||||||
|
|
||||||
const inputs = reduce(
|
const inputs: Record<string, InputFieldTemplate> = {};
|
||||||
schema.properties,
|
|
||||||
(inputsAccumulator, property, propertyName) => {
|
if (type === 'collect') {
|
||||||
if (
|
const itemProperty = schema.properties[
|
||||||
// `type` and `id` are not valid inputs/outputs
|
'item'
|
||||||
!['type', 'id'].includes(propertyName) &&
|
] as InvocationSchemaObject;
|
||||||
isSchemaObject(property)
|
// Handle the special Collect node
|
||||||
) {
|
inputs.item = {
|
||||||
let field: InputFieldTemplate | undefined;
|
type: 'item',
|
||||||
if (propertyName === 'collection') {
|
name: 'item',
|
||||||
field = {
|
description: itemProperty.description ?? '',
|
||||||
default: property.default ?? [],
|
title: 'Collection Item',
|
||||||
name: 'collection',
|
inputKind: 'connection',
|
||||||
title: property.title ?? '',
|
inputRequirement: 'always',
|
||||||
description: property.description ?? '',
|
default: undefined,
|
||||||
type: 'array',
|
};
|
||||||
inputRequirement: 'always',
|
} else if (type === 'iterate') {
|
||||||
inputKind: 'connection',
|
const itemProperty = schema.properties[
|
||||||
};
|
'collection'
|
||||||
} else {
|
] as InvocationSchemaObject;
|
||||||
field = buildInputFieldTemplate(
|
|
||||||
property,
|
inputs.collection = {
|
||||||
propertyName,
|
type: 'array',
|
||||||
typeHints
|
name: 'collection',
|
||||||
);
|
title: itemProperty.title ?? '',
|
||||||
|
default: [],
|
||||||
|
description: itemProperty.description ?? '',
|
||||||
|
inputRequirement: 'always',
|
||||||
|
inputKind: 'connection',
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// All other nodes
|
||||||
|
reduce(
|
||||||
|
schema.properties,
|
||||||
|
(inputsAccumulator, property, propertyName) => {
|
||||||
|
if (
|
||||||
|
// `type` and `id` are not valid inputs/outputs
|
||||||
|
!['type', 'id'].includes(propertyName) &&
|
||||||
|
isSchemaObject(property)
|
||||||
|
) {
|
||||||
|
const field: InputFieldTemplate | undefined =
|
||||||
|
buildInputFieldTemplate(property, propertyName, typeHints);
|
||||||
|
|
||||||
|
if (field) {
|
||||||
|
inputsAccumulator[propertyName] = field;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (field) {
|
return inputsAccumulator;
|
||||||
inputsAccumulator[propertyName] = field;
|
},
|
||||||
}
|
inputs
|
||||||
}
|
);
|
||||||
return inputsAccumulator;
|
}
|
||||||
},
|
|
||||||
{} as Record<string, InputFieldTemplate>
|
|
||||||
);
|
|
||||||
|
|
||||||
const rawOutput = (schema as InvocationSchemaObject).output;
|
const rawOutput = (schema as InvocationSchemaObject).output;
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ const initialSystemState: SystemState = {
|
|||||||
subscribedNodeIds: [],
|
subscribedNodeIds: [],
|
||||||
wereModelsReceived: false,
|
wereModelsReceived: false,
|
||||||
wasSchemaParsed: false,
|
wasSchemaParsed: false,
|
||||||
consoleLogLevel: 'error',
|
consoleLogLevel: 'debug',
|
||||||
shouldLogToConsole: true,
|
shouldLogToConsole: true,
|
||||||
statusTranslationKey: 'common.statusDisconnected',
|
statusTranslationKey: 'common.statusDisconnected',
|
||||||
canceledSession: '',
|
canceledSession: '',
|
||||||
|
Loading…
Reference in New Issue
Block a user