mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into patch
This commit is contained in:
commit
2db9b3b2ae
@ -298,7 +298,7 @@ async def search_for_models(
|
|||||||
)->List[pathlib.Path]:
|
)->List[pathlib.Path]:
|
||||||
if not search_path.is_dir():
|
if not search_path.is_dir():
|
||||||
raise HTTPException(status_code=404, detail=f"The search path '{search_path}' does not exist or is not directory")
|
raise HTTPException(status_code=404, detail=f"The search path '{search_path}' does not exist or is not directory")
|
||||||
return ApiDependencies.invoker.services.model_manager.search_for_models([search_path])
|
return ApiDependencies.invoker.services.model_manager.search_for_models(search_path)
|
||||||
|
|
||||||
@models_router.get(
|
@models_router.get(
|
||||||
"/ckpt_confs",
|
"/ckpt_confs",
|
||||||
|
@ -3,7 +3,13 @@
|
|||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
from invokeai.app.models.image import ProgressImage
|
from invokeai.app.models.image import ProgressImage
|
||||||
from invokeai.app.util.misc import get_timestamp
|
from invokeai.app.util.misc import get_timestamp
|
||||||
from invokeai.app.services.model_manager_service import BaseModelType, ModelType, SubModelType, ModelInfo
|
from invokeai.app.services.model_manager_service import (
|
||||||
|
BaseModelType,
|
||||||
|
ModelType,
|
||||||
|
SubModelType,
|
||||||
|
ModelInfo,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EventServiceBase:
|
class EventServiceBase:
|
||||||
session_event: str = "session_event"
|
session_event: str = "session_event"
|
||||||
@ -38,7 +44,9 @@ class EventServiceBase:
|
|||||||
graph_execution_state_id=graph_execution_state_id,
|
graph_execution_state_id=graph_execution_state_id,
|
||||||
node=node,
|
node=node,
|
||||||
source_node_id=source_node_id,
|
source_node_id=source_node_id,
|
||||||
progress_image=progress_image.dict() if progress_image is not None else None,
|
progress_image=progress_image.dict()
|
||||||
|
if progress_image is not None
|
||||||
|
else None,
|
||||||
step=step,
|
step=step,
|
||||||
total_steps=total_steps,
|
total_steps=total_steps,
|
||||||
),
|
),
|
||||||
@ -67,6 +75,7 @@ class EventServiceBase:
|
|||||||
graph_execution_state_id: str,
|
graph_execution_state_id: str,
|
||||||
node: dict,
|
node: dict,
|
||||||
source_node_id: str,
|
source_node_id: str,
|
||||||
|
error_type: str,
|
||||||
error: str,
|
error: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Emitted when an invocation has completed"""
|
"""Emitted when an invocation has completed"""
|
||||||
@ -76,6 +85,7 @@ class EventServiceBase:
|
|||||||
graph_execution_state_id=graph_execution_state_id,
|
graph_execution_state_id=graph_execution_state_id,
|
||||||
node=node,
|
node=node,
|
||||||
source_node_id=source_node_id,
|
source_node_id=source_node_id,
|
||||||
|
error_type=error_type,
|
||||||
error=error,
|
error=error,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -102,13 +112,13 @@ class EventServiceBase:
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def emit_model_load_started (
|
def emit_model_load_started(
|
||||||
self,
|
self,
|
||||||
graph_execution_state_id: str,
|
graph_execution_state_id: str,
|
||||||
model_name: str,
|
model_name: str,
|
||||||
base_model: BaseModelType,
|
base_model: BaseModelType,
|
||||||
model_type: ModelType,
|
model_type: ModelType,
|
||||||
submodel: SubModelType,
|
submodel: SubModelType,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Emitted when a model is requested"""
|
"""Emitted when a model is requested"""
|
||||||
self.__emit_session_event(
|
self.__emit_session_event(
|
||||||
@ -123,13 +133,13 @@ class EventServiceBase:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def emit_model_load_completed(
|
def emit_model_load_completed(
|
||||||
self,
|
self,
|
||||||
graph_execution_state_id: str,
|
graph_execution_state_id: str,
|
||||||
model_name: str,
|
model_name: str,
|
||||||
base_model: BaseModelType,
|
base_model: BaseModelType,
|
||||||
model_type: ModelType,
|
model_type: ModelType,
|
||||||
submodel: SubModelType,
|
submodel: SubModelType,
|
||||||
model_info: ModelInfo,
|
model_info: ModelInfo,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Emitted when a model is correctly loaded (returns model info)"""
|
"""Emitted when a model is correctly loaded (returns model info)"""
|
||||||
self.__emit_session_event(
|
self.__emit_session_event(
|
||||||
@ -145,3 +155,37 @@ class EventServiceBase:
|
|||||||
precision=str(model_info.precision),
|
precision=str(model_info.precision),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def emit_session_retrieval_error(
|
||||||
|
self,
|
||||||
|
graph_execution_state_id: str,
|
||||||
|
error_type: str,
|
||||||
|
error: str,
|
||||||
|
) -> None:
|
||||||
|
"""Emitted when session retrieval fails"""
|
||||||
|
self.__emit_session_event(
|
||||||
|
event_name="session_retrieval_error",
|
||||||
|
payload=dict(
|
||||||
|
graph_execution_state_id=graph_execution_state_id,
|
||||||
|
error_type=error_type,
|
||||||
|
error=error,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def emit_invocation_retrieval_error(
|
||||||
|
self,
|
||||||
|
graph_execution_state_id: str,
|
||||||
|
node_id: str,
|
||||||
|
error_type: str,
|
||||||
|
error: str,
|
||||||
|
) -> None:
|
||||||
|
"""Emitted when invocation retrieval fails"""
|
||||||
|
self.__emit_session_event(
|
||||||
|
event_name="invocation_retrieval_error",
|
||||||
|
payload=dict(
|
||||||
|
graph_execution_state_id=graph_execution_state_id,
|
||||||
|
node_id=node_id,
|
||||||
|
error_type=error_type,
|
||||||
|
error=error,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
@ -600,7 +600,7 @@ class ModelManagerService(ModelManagerServiceBase):
|
|||||||
"""
|
"""
|
||||||
Return list of all models found in the designated directory.
|
Return list of all models found in the designated directory.
|
||||||
"""
|
"""
|
||||||
search = FindModels(directory,self.logger)
|
search = FindModels([directory], self.logger)
|
||||||
return search.list_models()
|
return search.list_models()
|
||||||
|
|
||||||
def sync_to_config(self):
|
def sync_to_config(self):
|
||||||
|
@ -39,21 +39,41 @@ class DefaultInvocationProcessor(InvocationProcessorABC):
|
|||||||
try:
|
try:
|
||||||
queue_item: InvocationQueueItem = self.__invoker.services.queue.get()
|
queue_item: InvocationQueueItem = self.__invoker.services.queue.get()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("Exception while getting from queue: %s" % e)
|
self.__invoker.services.logger.error("Exception while getting from queue:\n%s" % e)
|
||||||
|
|
||||||
if not queue_item: # Probably stopping
|
if not queue_item: # Probably stopping
|
||||||
# do not hammer the queue
|
# do not hammer the queue
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
graph_execution_state = (
|
try:
|
||||||
self.__invoker.services.graph_execution_manager.get(
|
graph_execution_state = (
|
||||||
queue_item.graph_execution_state_id
|
self.__invoker.services.graph_execution_manager.get(
|
||||||
|
queue_item.graph_execution_state_id
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
except Exception as e:
|
||||||
invocation = graph_execution_state.execution_graph.get_node(
|
self.__invoker.services.logger.error("Exception while retrieving session:\n%s" % e)
|
||||||
queue_item.invocation_id
|
self.__invoker.services.events.emit_session_retrieval_error(
|
||||||
)
|
graph_execution_state_id=queue_item.graph_execution_state_id,
|
||||||
|
error_type=e.__class__.__name__,
|
||||||
|
error=traceback.format_exc(),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
invocation = graph_execution_state.execution_graph.get_node(
|
||||||
|
queue_item.invocation_id
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.__invoker.services.logger.error("Exception while retrieving invocation:\n%s" % e)
|
||||||
|
self.__invoker.services.events.emit_invocation_retrieval_error(
|
||||||
|
graph_execution_state_id=queue_item.graph_execution_state_id,
|
||||||
|
node_id=queue_item.invocation_id,
|
||||||
|
error_type=e.__class__.__name__,
|
||||||
|
error=traceback.format_exc(),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
# get the source node id to provide to clients (the prepared node id is not as useful)
|
# get the source node id to provide to clients (the prepared node id is not as useful)
|
||||||
source_node_id = graph_execution_state.prepared_source_mapping[invocation.id]
|
source_node_id = graph_execution_state.prepared_source_mapping[invocation.id]
|
||||||
@ -114,11 +134,13 @@ class DefaultInvocationProcessor(InvocationProcessorABC):
|
|||||||
graph_execution_state
|
graph_execution_state
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.__invoker.services.logger.error("Error while invoking:\n%s" % e)
|
||||||
# Send error event
|
# Send error event
|
||||||
self.__invoker.services.events.emit_invocation_error(
|
self.__invoker.services.events.emit_invocation_error(
|
||||||
graph_execution_state_id=graph_execution_state.id,
|
graph_execution_state_id=graph_execution_state.id,
|
||||||
node=invocation.dict(),
|
node=invocation.dict(),
|
||||||
source_node_id=source_node_id,
|
source_node_id=source_node_id,
|
||||||
|
error_type=e.__class__.__name__,
|
||||||
error=error,
|
error=error,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -136,11 +158,12 @@ class DefaultInvocationProcessor(InvocationProcessorABC):
|
|||||||
try:
|
try:
|
||||||
self.__invoker.invoke(graph_execution_state, invoke_all=True)
|
self.__invoker.invoke(graph_execution_state, invoke_all=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Error while invoking: %s" % e)
|
self.__invoker.services.logger.error("Error while invoking:\n%s" % e)
|
||||||
self.__invoker.services.events.emit_invocation_error(
|
self.__invoker.services.events.emit_invocation_error(
|
||||||
graph_execution_state_id=graph_execution_state.id,
|
graph_execution_state_id=graph_execution_state.id,
|
||||||
node=invocation.dict(),
|
node=invocation.dict(),
|
||||||
source_node_id=source_node_id,
|
source_node_id=source_node_id,
|
||||||
|
error_type=e.__class__.__name__,
|
||||||
error=traceback.format_exc()
|
error=traceback.format_exc()
|
||||||
)
|
)
|
||||||
elif is_complete:
|
elif is_complete:
|
||||||
|
@ -474,7 +474,7 @@ class ModelPatcher:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _lora_forward_hook(
|
def _lora_forward_hook(
|
||||||
applied_loras: List[Tuple[LoraModel, float]],
|
applied_loras: List[Tuple[LoRAModel, float]],
|
||||||
layer_name: str,
|
layer_name: str,
|
||||||
):
|
):
|
||||||
|
|
||||||
@ -519,7 +519,7 @@ class ModelPatcher:
|
|||||||
def apply_lora(
|
def apply_lora(
|
||||||
cls,
|
cls,
|
||||||
model: torch.nn.Module,
|
model: torch.nn.Module,
|
||||||
loras: List[Tuple[LoraModel, float]],
|
loras: List[Tuple[LoRAModel, float]],
|
||||||
prefix: str,
|
prefix: str,
|
||||||
):
|
):
|
||||||
original_weights = dict()
|
original_weights = dict()
|
||||||
|
@ -98,6 +98,6 @@ class FindModels(ModelSearch):
|
|||||||
|
|
||||||
def list_models(self) -> List[Path]:
|
def list_models(self) -> List[Path]:
|
||||||
self.search()
|
self.search()
|
||||||
return self.models_found
|
return list(self.models_found)
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ from .base import (
|
|||||||
SubModelType,
|
SubModelType,
|
||||||
classproperty,
|
classproperty,
|
||||||
InvalidModelException,
|
InvalidModelException,
|
||||||
|
ModelNotFoundException,
|
||||||
)
|
)
|
||||||
# TODO: naming
|
# TODO: naming
|
||||||
from ..lora import LoRAModel as LoRAModelRaw
|
from ..lora import LoRAModel as LoRAModelRaw
|
||||||
|
@ -75,6 +75,8 @@ import { addUserInvokedCanvasListener } from './listeners/userInvokedCanvas';
|
|||||||
import { addUserInvokedImageToImageListener } from './listeners/userInvokedImageToImage';
|
import { addUserInvokedImageToImageListener } from './listeners/userInvokedImageToImage';
|
||||||
import { addUserInvokedNodesListener } from './listeners/userInvokedNodes';
|
import { addUserInvokedNodesListener } from './listeners/userInvokedNodes';
|
||||||
import { addUserInvokedTextToImageListener } from './listeners/userInvokedTextToImage';
|
import { addUserInvokedTextToImageListener } from './listeners/userInvokedTextToImage';
|
||||||
|
import { addSessionRetrievalErrorEventListener } from './listeners/socketio/socketSessionRetrievalError';
|
||||||
|
import { addInvocationRetrievalErrorEventListener } from './listeners/socketio/socketInvocationRetrievalError';
|
||||||
|
|
||||||
export const listenerMiddleware = createListenerMiddleware();
|
export const listenerMiddleware = createListenerMiddleware();
|
||||||
|
|
||||||
@ -153,6 +155,8 @@ addSocketDisconnectedListener();
|
|||||||
addSocketSubscribedListener();
|
addSocketSubscribedListener();
|
||||||
addSocketUnsubscribedListener();
|
addSocketUnsubscribedListener();
|
||||||
addModelLoadEventListener();
|
addModelLoadEventListener();
|
||||||
|
addSessionRetrievalErrorEventListener();
|
||||||
|
addInvocationRetrievalErrorEventListener();
|
||||||
|
|
||||||
// Session Created
|
// Session Created
|
||||||
addSessionCreatedPendingListener();
|
addSessionCreatedPendingListener();
|
||||||
|
@ -33,12 +33,11 @@ export const addSessionCreatedRejectedListener = () => {
|
|||||||
effect: (action) => {
|
effect: (action) => {
|
||||||
const log = logger('session');
|
const log = logger('session');
|
||||||
if (action.payload) {
|
if (action.payload) {
|
||||||
const { error } = action.payload;
|
const { error, status } = action.payload;
|
||||||
const graph = parseify(action.meta.arg);
|
const graph = parseify(action.meta.arg);
|
||||||
const stringifiedError = JSON.stringify(error);
|
|
||||||
log.error(
|
log.error(
|
||||||
{ graph, error: serializeError(error) },
|
{ graph, status, error: serializeError(error) },
|
||||||
`Problem creating session: ${stringifiedError}`
|
`Problem creating session`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -31,13 +31,12 @@ export const addSessionInvokedRejectedListener = () => {
|
|||||||
const { session_id } = action.meta.arg;
|
const { session_id } = action.meta.arg;
|
||||||
if (action.payload) {
|
if (action.payload) {
|
||||||
const { error } = action.payload;
|
const { error } = action.payload;
|
||||||
const stringifiedError = JSON.stringify(error);
|
|
||||||
log.error(
|
log.error(
|
||||||
{
|
{
|
||||||
session_id,
|
session_id,
|
||||||
error: serializeError(error),
|
error: serializeError(error),
|
||||||
},
|
},
|
||||||
`Problem invoking session: ${stringifiedError}`
|
`Problem invoking session`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
import { logger } from 'app/logging/logger';
|
||||||
|
import {
|
||||||
|
appSocketInvocationRetrievalError,
|
||||||
|
socketInvocationRetrievalError,
|
||||||
|
} from 'services/events/actions';
|
||||||
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
|
export const addInvocationRetrievalErrorEventListener = () => {
|
||||||
|
startAppListening({
|
||||||
|
actionCreator: socketInvocationRetrievalError,
|
||||||
|
effect: (action, { dispatch }) => {
|
||||||
|
const log = logger('socketio');
|
||||||
|
log.error(
|
||||||
|
action.payload,
|
||||||
|
`Invocation retrieval error (${action.payload.data.graph_execution_state_id})`
|
||||||
|
);
|
||||||
|
dispatch(appSocketInvocationRetrievalError(action.payload));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
@ -0,0 +1,20 @@
|
|||||||
|
import { logger } from 'app/logging/logger';
|
||||||
|
import {
|
||||||
|
appSocketSessionRetrievalError,
|
||||||
|
socketSessionRetrievalError,
|
||||||
|
} from 'services/events/actions';
|
||||||
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
|
export const addSessionRetrievalErrorEventListener = () => {
|
||||||
|
startAppListening({
|
||||||
|
actionCreator: socketSessionRetrievalError,
|
||||||
|
effect: (action, { dispatch }) => {
|
||||||
|
const log = logger('socketio');
|
||||||
|
log.error(
|
||||||
|
action.payload,
|
||||||
|
`Session retrieval error (${action.payload.data.graph_execution_state_id})`
|
||||||
|
);
|
||||||
|
dispatch(appSocketSessionRetrievalError(action.payload));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
@ -39,8 +39,22 @@ export const addUserInvokedCanvasListener = () => {
|
|||||||
|
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
|
const {
|
||||||
|
layerState,
|
||||||
|
boundingBoxCoordinates,
|
||||||
|
boundingBoxDimensions,
|
||||||
|
isMaskEnabled,
|
||||||
|
shouldPreserveMaskedArea,
|
||||||
|
} = state.canvas;
|
||||||
|
|
||||||
// Build canvas blobs
|
// Build canvas blobs
|
||||||
const canvasBlobsAndImageData = await getCanvasData(state);
|
const canvasBlobsAndImageData = await getCanvasData(
|
||||||
|
layerState,
|
||||||
|
boundingBoxCoordinates,
|
||||||
|
boundingBoxDimensions,
|
||||||
|
isMaskEnabled,
|
||||||
|
shouldPreserveMaskedArea
|
||||||
|
);
|
||||||
|
|
||||||
if (!canvasBlobsAndImageData) {
|
if (!canvasBlobsAndImageData) {
|
||||||
log.error('Unable to create canvas data');
|
log.error('Unable to create canvas data');
|
||||||
|
@ -2,8 +2,8 @@ import { Box, Flex } from '@chakra-ui/react';
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
|
import GenerationModeStatusText from 'features/parameters/components/Parameters/Canvas/GenerationModeStatusText';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import roundToHundreth from '../util/roundToHundreth';
|
import roundToHundreth from '../util/roundToHundreth';
|
||||||
import IAICanvasStatusTextCursorPos from './IAICanvasStatusText/IAICanvasStatusTextCursorPos';
|
import IAICanvasStatusTextCursorPos from './IAICanvasStatusText/IAICanvasStatusTextCursorPos';
|
||||||
@ -110,6 +110,7 @@ const IAICanvasStatusText = () => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<GenerationModeStatusText />
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
color: activeLayerColor,
|
color: activeLayerColor,
|
||||||
|
@ -2,7 +2,15 @@ import { Box, ButtonGroup, Flex } from '@chakra-ui/react';
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
|
import IAIMantineSelect from 'common/components/IAIMantineSelect';
|
||||||
|
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
|
||||||
import { useSingleAndDoubleClick } from 'common/hooks/useSingleAndDoubleClick';
|
import { useSingleAndDoubleClick } from 'common/hooks/useSingleAndDoubleClick';
|
||||||
|
import {
|
||||||
|
canvasCopiedToClipboard,
|
||||||
|
canvasDownloadedAsImage,
|
||||||
|
canvasMerged,
|
||||||
|
canvasSavedToGallery,
|
||||||
|
} from 'features/canvas/store/actions';
|
||||||
import {
|
import {
|
||||||
canvasSelector,
|
canvasSelector,
|
||||||
isStagingSelector,
|
isStagingSelector,
|
||||||
@ -21,16 +29,8 @@ import {
|
|||||||
} from 'features/canvas/store/canvasTypes';
|
} from 'features/canvas/store/canvasTypes';
|
||||||
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
import { useCopyImageToClipboard } from 'features/ui/hooks/useCopyImageToClipboard';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect';
|
|
||||||
import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
|
|
||||||
import {
|
|
||||||
canvasCopiedToClipboard,
|
|
||||||
canvasDownloadedAsImage,
|
|
||||||
canvasMerged,
|
|
||||||
canvasSavedToGallery,
|
|
||||||
} from 'features/canvas/store/actions';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
@ -48,7 +48,6 @@ import IAICanvasRedoButton from './IAICanvasRedoButton';
|
|||||||
import IAICanvasSettingsButtonPopover from './IAICanvasSettingsButtonPopover';
|
import IAICanvasSettingsButtonPopover from './IAICanvasSettingsButtonPopover';
|
||||||
import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions';
|
import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions';
|
||||||
import IAICanvasUndoButton from './IAICanvasUndoButton';
|
import IAICanvasUndoButton from './IAICanvasUndoButton';
|
||||||
import { useCopyImageToClipboard } from 'features/ui/hooks/useCopyImageToClipboard';
|
|
||||||
|
|
||||||
export const selector = createSelector(
|
export const selector = createSelector(
|
||||||
[systemSelector, canvasSelector, isStagingSelector],
|
[systemSelector, canvasSelector, isStagingSelector],
|
||||||
@ -220,7 +219,7 @@ const IAICanvasToolbar = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box w={24}>
|
<Box w={24}>
|
||||||
<IAIMantineSearchableSelect
|
<IAIMantineSelect
|
||||||
tooltip={`${t('unifiedCanvas.layer')} (Q)`}
|
tooltip={`${t('unifiedCanvas.layer')} (Q)`}
|
||||||
value={layer}
|
value={layer}
|
||||||
data={LAYER_NAMES_DICT}
|
data={LAYER_NAMES_DICT}
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { GenerationMode } from 'features/canvas/store/canvasTypes';
|
||||||
|
import { getCanvasData } from 'features/canvas/util/getCanvasData';
|
||||||
|
import { getCanvasGenerationMode } from 'features/canvas/util/getCanvasGenerationMode';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useDebounce } from 'react-use';
|
||||||
|
|
||||||
|
export const useCanvasGenerationMode = () => {
|
||||||
|
const layerState = useAppSelector((state) => state.canvas.layerState);
|
||||||
|
|
||||||
|
const boundingBoxCoordinates = useAppSelector(
|
||||||
|
(state) => state.canvas.boundingBoxCoordinates
|
||||||
|
);
|
||||||
|
const boundingBoxDimensions = useAppSelector(
|
||||||
|
(state) => state.canvas.boundingBoxDimensions
|
||||||
|
);
|
||||||
|
const isMaskEnabled = useAppSelector((state) => state.canvas.isMaskEnabled);
|
||||||
|
|
||||||
|
const shouldPreserveMaskedArea = useAppSelector(
|
||||||
|
(state) => state.canvas.shouldPreserveMaskedArea
|
||||||
|
);
|
||||||
|
const [generationMode, setGenerationMode] = useState<
|
||||||
|
GenerationMode | undefined
|
||||||
|
>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setGenerationMode(undefined);
|
||||||
|
}, [
|
||||||
|
layerState,
|
||||||
|
boundingBoxCoordinates,
|
||||||
|
boundingBoxDimensions,
|
||||||
|
isMaskEnabled,
|
||||||
|
shouldPreserveMaskedArea,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useDebounce(
|
||||||
|
async () => {
|
||||||
|
// Build canvas blobs
|
||||||
|
const canvasBlobsAndImageData = await getCanvasData(
|
||||||
|
layerState,
|
||||||
|
boundingBoxCoordinates,
|
||||||
|
boundingBoxDimensions,
|
||||||
|
isMaskEnabled,
|
||||||
|
shouldPreserveMaskedArea
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!canvasBlobsAndImageData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { baseImageData, maskImageData } = canvasBlobsAndImageData;
|
||||||
|
|
||||||
|
// Determine the generation mode
|
||||||
|
const generationMode = getCanvasGenerationMode(
|
||||||
|
baseImageData,
|
||||||
|
maskImageData
|
||||||
|
);
|
||||||
|
|
||||||
|
setGenerationMode(generationMode);
|
||||||
|
},
|
||||||
|
1000,
|
||||||
|
[
|
||||||
|
layerState,
|
||||||
|
boundingBoxCoordinates,
|
||||||
|
boundingBoxDimensions,
|
||||||
|
isMaskEnabled,
|
||||||
|
shouldPreserveMaskedArea,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return generationMode;
|
||||||
|
};
|
@ -168,4 +168,7 @@ export interface CanvasState {
|
|||||||
stageDimensions: Dimensions;
|
stageDimensions: Dimensions;
|
||||||
stageScale: number;
|
stageScale: number;
|
||||||
tool: CanvasTool;
|
tool: CanvasTool;
|
||||||
|
generationMode?: GenerationMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type GenerationMode = 'txt2img' | 'img2img' | 'inpaint' | 'outpaint';
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { RootState } from 'app/store/store';
|
import { Vector2d } from 'konva/lib/types';
|
||||||
import { isCanvasMaskLine } from '../store/canvasTypes';
|
import {
|
||||||
|
CanvasLayerState,
|
||||||
|
Dimensions,
|
||||||
|
isCanvasMaskLine,
|
||||||
|
} from '../store/canvasTypes';
|
||||||
import createMaskStage from './createMaskStage';
|
import createMaskStage from './createMaskStage';
|
||||||
import { getCanvasBaseLayer, getCanvasStage } from './konvaInstanceProvider';
|
import { getCanvasBaseLayer, getCanvasStage } from './konvaInstanceProvider';
|
||||||
import { konvaNodeToBlob } from './konvaNodeToBlob';
|
import { konvaNodeToBlob } from './konvaNodeToBlob';
|
||||||
@ -9,7 +13,13 @@ import { konvaNodeToImageData } from './konvaNodeToImageData';
|
|||||||
/**
|
/**
|
||||||
* Gets Blob and ImageData objects for the base and mask layers
|
* Gets Blob and ImageData objects for the base and mask layers
|
||||||
*/
|
*/
|
||||||
export const getCanvasData = async (state: RootState) => {
|
export const getCanvasData = async (
|
||||||
|
layerState: CanvasLayerState,
|
||||||
|
boundingBoxCoordinates: Vector2d,
|
||||||
|
boundingBoxDimensions: Dimensions,
|
||||||
|
isMaskEnabled: boolean,
|
||||||
|
shouldPreserveMaskedArea: boolean
|
||||||
|
) => {
|
||||||
const log = logger('canvas');
|
const log = logger('canvas');
|
||||||
|
|
||||||
const canvasBaseLayer = getCanvasBaseLayer();
|
const canvasBaseLayer = getCanvasBaseLayer();
|
||||||
@ -20,14 +30,6 @@ export const getCanvasData = async (state: RootState) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
|
||||||
layerState: { objects },
|
|
||||||
boundingBoxCoordinates,
|
|
||||||
boundingBoxDimensions,
|
|
||||||
isMaskEnabled,
|
|
||||||
shouldPreserveMaskedArea,
|
|
||||||
} = state.canvas;
|
|
||||||
|
|
||||||
const boundingBox = {
|
const boundingBox = {
|
||||||
...boundingBoxCoordinates,
|
...boundingBoxCoordinates,
|
||||||
...boundingBoxDimensions,
|
...boundingBoxDimensions,
|
||||||
@ -58,7 +60,7 @@ export const getCanvasData = async (state: RootState) => {
|
|||||||
|
|
||||||
// For the mask layer, use the normal boundingBox
|
// For the mask layer, use the normal boundingBox
|
||||||
const maskStage = await createMaskStage(
|
const maskStage = await createMaskStage(
|
||||||
isMaskEnabled ? objects.filter(isCanvasMaskLine) : [], // only include mask lines, and only if mask is enabled
|
isMaskEnabled ? layerState.objects.filter(isCanvasMaskLine) : [], // only include mask lines, and only if mask is enabled
|
||||||
boundingBox,
|
boundingBox,
|
||||||
shouldPreserveMaskedArea
|
shouldPreserveMaskedArea
|
||||||
);
|
);
|
||||||
|
@ -2,11 +2,12 @@ import {
|
|||||||
areAnyPixelsBlack,
|
areAnyPixelsBlack,
|
||||||
getImageDataTransparency,
|
getImageDataTransparency,
|
||||||
} from 'common/util/arrayBuffer';
|
} from 'common/util/arrayBuffer';
|
||||||
|
import { GenerationMode } from '../store/canvasTypes';
|
||||||
|
|
||||||
export const getCanvasGenerationMode = (
|
export const getCanvasGenerationMode = (
|
||||||
baseImageData: ImageData,
|
baseImageData: ImageData,
|
||||||
maskImageData: ImageData
|
maskImageData: ImageData
|
||||||
) => {
|
): GenerationMode => {
|
||||||
const {
|
const {
|
||||||
isPartiallyTransparent: baseIsPartiallyTransparent,
|
isPartiallyTransparent: baseIsPartiallyTransparent,
|
||||||
isFullyTransparent: baseIsFullyTransparent,
|
isFullyTransparent: baseIsFullyTransparent,
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
import { useCanvasGenerationMode } from 'features/canvas/hooks/useCanvasGenerationMode';
|
||||||
|
|
||||||
|
const GENERATION_MODE_NAME_MAP = {
|
||||||
|
txt2img: 'Text to Image',
|
||||||
|
img2img: 'Image to Image',
|
||||||
|
inpaint: 'Inpaint',
|
||||||
|
outpaint: 'Inpaint',
|
||||||
|
};
|
||||||
|
|
||||||
|
const GenerationModeStatusText = () => {
|
||||||
|
const generationMode = useCanvasGenerationMode();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
Mode: {generationMode ? GENERATION_MODE_NAME_MAP[generationMode] : '...'}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GenerationModeStatusText;
|
@ -1,5 +1,5 @@
|
|||||||
import { UseToastOptions } from '@chakra-ui/react';
|
import { UseToastOptions } from '@chakra-ui/react';
|
||||||
import { PayloadAction, createSlice } from '@reduxjs/toolkit';
|
import { PayloadAction, createSlice, isAnyOf } from '@reduxjs/toolkit';
|
||||||
import { InvokeLogLevel } from 'app/logging/logger';
|
import { InvokeLogLevel } from 'app/logging/logger';
|
||||||
import { userInvoked } from 'app/store/actions';
|
import { userInvoked } from 'app/store/actions';
|
||||||
import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
|
import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
|
||||||
@ -16,13 +16,16 @@ import {
|
|||||||
appSocketGraphExecutionStateComplete,
|
appSocketGraphExecutionStateComplete,
|
||||||
appSocketInvocationComplete,
|
appSocketInvocationComplete,
|
||||||
appSocketInvocationError,
|
appSocketInvocationError,
|
||||||
|
appSocketInvocationRetrievalError,
|
||||||
appSocketInvocationStarted,
|
appSocketInvocationStarted,
|
||||||
|
appSocketSessionRetrievalError,
|
||||||
appSocketSubscribed,
|
appSocketSubscribed,
|
||||||
appSocketUnsubscribed,
|
appSocketUnsubscribed,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
import { ProgressImage } from 'services/events/types';
|
import { ProgressImage } from 'services/events/types';
|
||||||
import { makeToast } from '../util/makeToast';
|
import { makeToast } from '../util/makeToast';
|
||||||
import { LANGUAGES } from './constants';
|
import { LANGUAGES } from './constants';
|
||||||
|
import { startCase } from 'lodash-es';
|
||||||
|
|
||||||
export type CancelStrategy = 'immediate' | 'scheduled';
|
export type CancelStrategy = 'immediate' | 'scheduled';
|
||||||
|
|
||||||
@ -288,25 +291,6 @@ export const systemSlice = createSlice({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Invocation Error
|
|
||||||
*/
|
|
||||||
builder.addCase(appSocketInvocationError, (state) => {
|
|
||||||
state.isProcessing = false;
|
|
||||||
state.isCancelable = true;
|
|
||||||
// state.currentIteration = 0;
|
|
||||||
// state.totalIterations = 0;
|
|
||||||
state.currentStatusHasSteps = false;
|
|
||||||
state.currentStep = 0;
|
|
||||||
state.totalSteps = 0;
|
|
||||||
state.statusTranslationKey = 'common.statusError';
|
|
||||||
state.progressImage = null;
|
|
||||||
|
|
||||||
state.toastQueue.push(
|
|
||||||
makeToast({ title: t('toast.serverError'), status: 'error' })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Graph Execution State Complete
|
* Graph Execution State Complete
|
||||||
*/
|
*/
|
||||||
@ -362,7 +346,7 @@ export const systemSlice = createSlice({
|
|||||||
* Session Invoked - REJECTED
|
* Session Invoked - REJECTED
|
||||||
* Session Created - REJECTED
|
* Session Created - REJECTED
|
||||||
*/
|
*/
|
||||||
builder.addMatcher(isAnySessionRejected, (state) => {
|
builder.addMatcher(isAnySessionRejected, (state, action) => {
|
||||||
state.isProcessing = false;
|
state.isProcessing = false;
|
||||||
state.isCancelable = false;
|
state.isCancelable = false;
|
||||||
state.isCancelScheduled = false;
|
state.isCancelScheduled = false;
|
||||||
@ -372,7 +356,35 @@ export const systemSlice = createSlice({
|
|||||||
state.progressImage = null;
|
state.progressImage = null;
|
||||||
|
|
||||||
state.toastQueue.push(
|
state.toastQueue.push(
|
||||||
makeToast({ title: t('toast.serverError'), status: 'error' })
|
makeToast({
|
||||||
|
title: t('toast.serverError'),
|
||||||
|
status: 'error',
|
||||||
|
description:
|
||||||
|
action.payload?.status === 422 ? 'Validation Error' : undefined,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any server error
|
||||||
|
*/
|
||||||
|
builder.addMatcher(isAnyServerError, (state, action) => {
|
||||||
|
state.isProcessing = false;
|
||||||
|
state.isCancelable = true;
|
||||||
|
// state.currentIteration = 0;
|
||||||
|
// state.totalIterations = 0;
|
||||||
|
state.currentStatusHasSteps = false;
|
||||||
|
state.currentStep = 0;
|
||||||
|
state.totalSteps = 0;
|
||||||
|
state.statusTranslationKey = 'common.statusError';
|
||||||
|
state.progressImage = null;
|
||||||
|
|
||||||
|
state.toastQueue.push(
|
||||||
|
makeToast({
|
||||||
|
title: t('toast.serverError'),
|
||||||
|
status: 'error',
|
||||||
|
description: startCase(action.payload.data.error_type),
|
||||||
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -400,3 +412,9 @@ export const {
|
|||||||
} = systemSlice.actions;
|
} = systemSlice.actions;
|
||||||
|
|
||||||
export default systemSlice.reducer;
|
export default systemSlice.reducer;
|
||||||
|
|
||||||
|
const isAnyServerError = isAnyOf(
|
||||||
|
appSocketInvocationError,
|
||||||
|
appSocketSessionRetrievalError,
|
||||||
|
appSocketInvocationRetrievalError
|
||||||
|
);
|
||||||
|
@ -18,7 +18,7 @@ type CreateSessionResponse = O.Required<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
type CreateSessionThunkConfig = {
|
type CreateSessionThunkConfig = {
|
||||||
rejectValue: { arg: CreateSessionArg; error: unknown };
|
rejectValue: { arg: CreateSessionArg; status: number; error: unknown };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +36,7 @@ export const sessionCreated = createAsyncThunk<
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return rejectWithValue({ arg, error });
|
return rejectWithValue({ arg, status: response.status, error });
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -53,6 +53,7 @@ type InvokedSessionThunkConfig = {
|
|||||||
rejectValue: {
|
rejectValue: {
|
||||||
arg: InvokedSessionArg;
|
arg: InvokedSessionArg;
|
||||||
error: unknown;
|
error: unknown;
|
||||||
|
status: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,9 +79,13 @@ export const sessionInvoked = createAsyncThunk<
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
if (isErrorWithStatus(error) && error.status === 403) {
|
if (isErrorWithStatus(error) && error.status === 403) {
|
||||||
return rejectWithValue({ arg, error: (error as any).body.detail });
|
return rejectWithValue({
|
||||||
|
arg,
|
||||||
|
status: response.status,
|
||||||
|
error: (error as any).body.detail,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return rejectWithValue({ arg, error });
|
return rejectWithValue({ arg, status: response.status, error });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,9 +4,11 @@ import {
|
|||||||
GraphExecutionStateCompleteEvent,
|
GraphExecutionStateCompleteEvent,
|
||||||
InvocationCompleteEvent,
|
InvocationCompleteEvent,
|
||||||
InvocationErrorEvent,
|
InvocationErrorEvent,
|
||||||
|
InvocationRetrievalErrorEvent,
|
||||||
InvocationStartedEvent,
|
InvocationStartedEvent,
|
||||||
ModelLoadCompletedEvent,
|
ModelLoadCompletedEvent,
|
||||||
ModelLoadStartedEvent,
|
ModelLoadStartedEvent,
|
||||||
|
SessionRetrievalErrorEvent,
|
||||||
} from 'services/events/types';
|
} from 'services/events/types';
|
||||||
|
|
||||||
// Create actions for each socket
|
// Create actions for each socket
|
||||||
@ -181,3 +183,35 @@ export const socketModelLoadCompleted = createAction<{
|
|||||||
export const appSocketModelLoadCompleted = createAction<{
|
export const appSocketModelLoadCompleted = createAction<{
|
||||||
data: ModelLoadCompletedEvent;
|
data: ModelLoadCompletedEvent;
|
||||||
}>('socket/appSocketModelLoadCompleted');
|
}>('socket/appSocketModelLoadCompleted');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Socket.IO Session Retrieval Error
|
||||||
|
*
|
||||||
|
* Do not use. Only for use in middleware.
|
||||||
|
*/
|
||||||
|
export const socketSessionRetrievalError = createAction<{
|
||||||
|
data: SessionRetrievalErrorEvent;
|
||||||
|
}>('socket/socketSessionRetrievalError');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App-level Session Retrieval Error
|
||||||
|
*/
|
||||||
|
export const appSocketSessionRetrievalError = createAction<{
|
||||||
|
data: SessionRetrievalErrorEvent;
|
||||||
|
}>('socket/appSocketSessionRetrievalError');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Socket.IO Invocation Retrieval Error
|
||||||
|
*
|
||||||
|
* Do not use. Only for use in middleware.
|
||||||
|
*/
|
||||||
|
export const socketInvocationRetrievalError = createAction<{
|
||||||
|
data: InvocationRetrievalErrorEvent;
|
||||||
|
}>('socket/socketInvocationRetrievalError');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App-level Invocation Retrieval Error
|
||||||
|
*/
|
||||||
|
export const appSocketInvocationRetrievalError = createAction<{
|
||||||
|
data: InvocationRetrievalErrorEvent;
|
||||||
|
}>('socket/appSocketInvocationRetrievalError');
|
||||||
|
@ -87,6 +87,7 @@ export type InvocationErrorEvent = {
|
|||||||
graph_execution_state_id: string;
|
graph_execution_state_id: string;
|
||||||
node: BaseNode;
|
node: BaseNode;
|
||||||
source_node_id: string;
|
source_node_id: string;
|
||||||
|
error_type: string;
|
||||||
error: string;
|
error: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,6 +111,29 @@ export type GraphExecutionStateCompleteEvent = {
|
|||||||
graph_execution_state_id: string;
|
graph_execution_state_id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `session_retrieval_error` socket.io event.
|
||||||
|
*
|
||||||
|
* @example socket.on('session_retrieval_error', (data: SessionRetrievalErrorEvent) => { ... }
|
||||||
|
*/
|
||||||
|
export type SessionRetrievalErrorEvent = {
|
||||||
|
graph_execution_state_id: string;
|
||||||
|
error_type: string;
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `invocation_retrieval_error` socket.io event.
|
||||||
|
*
|
||||||
|
* @example socket.on('invocation_retrieval_error', (data: InvocationRetrievalErrorEvent) => { ... }
|
||||||
|
*/
|
||||||
|
export type InvocationRetrievalErrorEvent = {
|
||||||
|
graph_execution_state_id: string;
|
||||||
|
node_id: string;
|
||||||
|
error_type: string;
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type ClientEmitSubscribe = {
|
export type ClientEmitSubscribe = {
|
||||||
session: string;
|
session: string;
|
||||||
};
|
};
|
||||||
@ -128,6 +152,8 @@ export type ServerToClientEvents = {
|
|||||||
) => void;
|
) => void;
|
||||||
model_load_started: (payload: ModelLoadStartedEvent) => void;
|
model_load_started: (payload: ModelLoadStartedEvent) => void;
|
||||||
model_load_completed: (payload: ModelLoadCompletedEvent) => void;
|
model_load_completed: (payload: ModelLoadCompletedEvent) => void;
|
||||||
|
session_retrieval_error: (payload: SessionRetrievalErrorEvent) => void;
|
||||||
|
invocation_retrieval_error: (payload: InvocationRetrievalErrorEvent) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ClientToServerEvents = {
|
export type ClientToServerEvents = {
|
||||||
|
@ -11,9 +11,11 @@ import {
|
|||||||
socketGraphExecutionStateComplete,
|
socketGraphExecutionStateComplete,
|
||||||
socketInvocationComplete,
|
socketInvocationComplete,
|
||||||
socketInvocationError,
|
socketInvocationError,
|
||||||
|
socketInvocationRetrievalError,
|
||||||
socketInvocationStarted,
|
socketInvocationStarted,
|
||||||
socketModelLoadCompleted,
|
socketModelLoadCompleted,
|
||||||
socketModelLoadStarted,
|
socketModelLoadStarted,
|
||||||
|
socketSessionRetrievalError,
|
||||||
socketSubscribed,
|
socketSubscribed,
|
||||||
} from '../actions';
|
} from '../actions';
|
||||||
import { ClientToServerEvents, ServerToClientEvents } from '../types';
|
import { ClientToServerEvents, ServerToClientEvents } from '../types';
|
||||||
@ -138,4 +140,26 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session retrieval error
|
||||||
|
*/
|
||||||
|
socket.on('session_retrieval_error', (data) => {
|
||||||
|
dispatch(
|
||||||
|
socketSessionRetrievalError({
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invocation retrieval error
|
||||||
|
*/
|
||||||
|
socket.on('invocation_retrieval_error', (data) => {
|
||||||
|
dispatch(
|
||||||
|
socketInvocationRetrievalError({
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
12
mkdocs.yml
12
mkdocs.yml
@ -101,7 +101,7 @@ plugins:
|
|||||||
|
|
||||||
nav:
|
nav:
|
||||||
- Home: 'index.md'
|
- Home: 'index.md'
|
||||||
- Installation:
|
- Installation:
|
||||||
- Overview: 'installation/index.md'
|
- Overview: 'installation/index.md'
|
||||||
- Installing with the Automated Installer: 'installation/010_INSTALL_AUTOMATED.md'
|
- Installing with the Automated Installer: 'installation/010_INSTALL_AUTOMATED.md'
|
||||||
- Installing manually: 'installation/020_INSTALL_MANUAL.md'
|
- Installing manually: 'installation/020_INSTALL_MANUAL.md'
|
||||||
@ -122,14 +122,14 @@ nav:
|
|||||||
- Community Nodes:
|
- Community Nodes:
|
||||||
- Community Nodes: 'nodes/communityNodes.md'
|
- Community Nodes: 'nodes/communityNodes.md'
|
||||||
- Overview: 'nodes/overview.md'
|
- Overview: 'nodes/overview.md'
|
||||||
- Features:
|
- Features:
|
||||||
- Overview: 'features/index.md'
|
- Overview: 'features/index.md'
|
||||||
- Concepts: 'features/CONCEPTS.md'
|
- Concepts: 'features/CONCEPTS.md'
|
||||||
- Configuration: 'features/CONFIGURATION.md'
|
- Configuration: 'features/CONFIGURATION.md'
|
||||||
- ControlNet: 'features/CONTROLNET.md'
|
- ControlNet: 'features/CONTROLNET.md'
|
||||||
- Image-to-Image: 'features/IMG2IMG.md'
|
- Image-to-Image: 'features/IMG2IMG.md'
|
||||||
- Controlling Logging: 'features/LOGGING.md'
|
- Controlling Logging: 'features/LOGGING.md'
|
||||||
- Model Mergeing: 'features/MODEL_MERGING.md'
|
- Model Merging: 'features/MODEL_MERGING.md'
|
||||||
- Nodes Editor (Experimental): 'features/NODES.md'
|
- Nodes Editor (Experimental): 'features/NODES.md'
|
||||||
- NSFW Checker: 'features/NSFW.md'
|
- NSFW Checker: 'features/NSFW.md'
|
||||||
- Postprocessing: 'features/POSTPROCESS.md'
|
- Postprocessing: 'features/POSTPROCESS.md'
|
||||||
@ -140,9 +140,9 @@ nav:
|
|||||||
- InvokeAI Web Server: 'features/WEB.md'
|
- InvokeAI Web Server: 'features/WEB.md'
|
||||||
- WebUI Hotkeys: "features/WEBUIHOTKEYS.md"
|
- WebUI Hotkeys: "features/WEBUIHOTKEYS.md"
|
||||||
- Other: 'features/OTHER.md'
|
- Other: 'features/OTHER.md'
|
||||||
- Contributing:
|
- Contributing:
|
||||||
- How to Contribute: 'contributing/CONTRIBUTING.md'
|
- How to Contribute: 'contributing/CONTRIBUTING.md'
|
||||||
- Development:
|
- Development:
|
||||||
- Overview: 'contributing/contribution_guides/development.md'
|
- Overview: 'contributing/contribution_guides/development.md'
|
||||||
- InvokeAI Architecture: 'contributing/ARCHITECTURE.md'
|
- InvokeAI Architecture: 'contributing/ARCHITECTURE.md'
|
||||||
- Frontend Documentation: 'contributing/contribution_guides/development_guides/contributingToFrontend.md'
|
- Frontend Documentation: 'contributing/contribution_guides/development_guides/contributingToFrontend.md'
|
||||||
@ -161,5 +161,3 @@ nav:
|
|||||||
- Other:
|
- Other:
|
||||||
- Contributors: 'other/CONTRIBUTORS.md'
|
- Contributors: 'other/CONTRIBUTORS.md'
|
||||||
- CompViz-README: 'other/README-CompViz.md'
|
- CompViz-README: 'other/README-CompViz.md'
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user