mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): improve session invoked handling
This commit is contained in:
parent
8f190169db
commit
b599c40099
@ -546,7 +546,6 @@
|
|||||||
"availableSchedulers": "Available Schedulers"
|
"availableSchedulers": "Available Schedulers"
|
||||||
},
|
},
|
||||||
"toast": {
|
"toast": {
|
||||||
"problemCreatingSession": "Problem Creating Session",
|
|
||||||
"serverError": "Server Error",
|
"serverError": "Server Error",
|
||||||
"disconnected": "Disconnected from Server",
|
"disconnected": "Disconnected from Server",
|
||||||
"connected": "Connected to Server",
|
"connected": "Connected to Server",
|
||||||
|
@ -49,6 +49,11 @@ import {
|
|||||||
addSessionCreatedPendingListener,
|
addSessionCreatedPendingListener,
|
||||||
addSessionCreatedRejectedListener,
|
addSessionCreatedRejectedListener,
|
||||||
} from './listeners/sessionCreated';
|
} from './listeners/sessionCreated';
|
||||||
|
import {
|
||||||
|
addSessionInvokedFulfilledListener,
|
||||||
|
addSessionInvokedPendingListener,
|
||||||
|
addSessionInvokedRejectedListener,
|
||||||
|
} from './listeners/sessionInvoked';
|
||||||
|
|
||||||
export const listenerMiddleware = createListenerMiddleware();
|
export const listenerMiddleware = createListenerMiddleware();
|
||||||
|
|
||||||
@ -88,13 +93,18 @@ addImageMetadataReceivedRejectedListener();
|
|||||||
addImageUrlsReceivedFulfilledListener();
|
addImageUrlsReceivedFulfilledListener();
|
||||||
addImageUrlsReceivedRejectedListener();
|
addImageUrlsReceivedRejectedListener();
|
||||||
|
|
||||||
// Invoking stuff
|
// Invoking on tabs
|
||||||
addUserInvokedCanvasListener();
|
addUserInvokedCanvasListener();
|
||||||
addUserInvokedNodesListener();
|
addUserInvokedNodesListener();
|
||||||
addUserInvokedTextToImageListener();
|
addUserInvokedTextToImageListener();
|
||||||
addUserInvokedImageToImageListener();
|
addUserInvokedImageToImageListener();
|
||||||
addSessionReadyToInvokeListener();
|
addSessionReadyToInvokeListener();
|
||||||
|
|
||||||
|
// Actual session invoking
|
||||||
|
addSessionInvokedPendingListener();
|
||||||
|
addSessionInvokedFulfilledListener();
|
||||||
|
addSessionInvokedRejectedListener();
|
||||||
|
|
||||||
// Canvas actions
|
// Canvas actions
|
||||||
addCanvasSavedToGalleryListener();
|
addCanvasSavedToGalleryListener();
|
||||||
addCanvasDownloadedAsImageListener();
|
addCanvasDownloadedAsImageListener();
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
import { log } from 'app/logging/useLogger';
|
||||||
|
import { startAppListening } from '..';
|
||||||
|
import { sessionInvoked } from 'services/thunks/session';
|
||||||
|
import { serializeError } from 'serialize-error';
|
||||||
|
|
||||||
|
const moduleLog = log.child({ namespace: 'session' });
|
||||||
|
|
||||||
|
export const addSessionInvokedPendingListener = () => {
|
||||||
|
startAppListening({
|
||||||
|
actionCreator: sessionInvoked.pending,
|
||||||
|
effect: (action, { getState, dispatch }) => {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addSessionInvokedFulfilledListener = () => {
|
||||||
|
startAppListening({
|
||||||
|
actionCreator: sessionInvoked.fulfilled,
|
||||||
|
effect: (action, { getState, dispatch }) => {
|
||||||
|
const { sessionId } = action.meta.arg;
|
||||||
|
moduleLog.info({ data: { sessionId } }, `Session invoked (${sessionId})`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addSessionInvokedRejectedListener = () => {
|
||||||
|
startAppListening({
|
||||||
|
actionCreator: sessionInvoked.rejected,
|
||||||
|
effect: (action, { getState, dispatch }) => {
|
||||||
|
if (action.payload) {
|
||||||
|
const { arg, error } = action.payload;
|
||||||
|
moduleLog.error(
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
arg,
|
||||||
|
error: serializeError(error),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
`Problem invoking session`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
@ -3,7 +3,7 @@ import { sessionInvoked } from 'services/thunks/session';
|
|||||||
import { log } from 'app/logging/useLogger';
|
import { log } from 'app/logging/useLogger';
|
||||||
import { sessionReadyToInvoke } from 'features/system/store/actions';
|
import { sessionReadyToInvoke } from 'features/system/store/actions';
|
||||||
|
|
||||||
const moduleLog = log.child({ namespace: 'invoke' });
|
const moduleLog = log.child({ namespace: 'session' });
|
||||||
|
|
||||||
export const addSessionReadyToInvokeListener = () => {
|
export const addSessionReadyToInvokeListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
@ -11,7 +11,10 @@ export const addSessionReadyToInvokeListener = () => {
|
|||||||
effect: (action, { getState, dispatch }) => {
|
effect: (action, { getState, dispatch }) => {
|
||||||
const { sessionId } = getState().system;
|
const { sessionId } = getState().system;
|
||||||
if (sessionId) {
|
if (sessionId) {
|
||||||
moduleLog.info({ sessionId }, `Session invoked (${sessionId})})`);
|
moduleLog.info(
|
||||||
|
{ sessionId },
|
||||||
|
`Session ready to invoke (${sessionId})})`
|
||||||
|
);
|
||||||
dispatch(sessionInvoked({ sessionId }));
|
dispatch(sessionInvoked({ sessionId }));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { UseToastOptions } from '@chakra-ui/react';
|
import { UseToastOptions } from '@chakra-ui/react';
|
||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import { PayloadAction, isAnyOf } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
import * as InvokeAI from 'app/types/invokeai';
|
import * as InvokeAI from 'app/types/invokeai';
|
||||||
import {
|
import {
|
||||||
@ -349,13 +349,6 @@ export const systemSlice = createSlice({
|
|||||||
state.statusTranslationKey = 'common.statusPreparing';
|
state.statusTranslationKey = 'common.statusPreparing';
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.addCase(sessionInvoked.rejected, (state, action) => {
|
|
||||||
const error = action.payload as string | undefined;
|
|
||||||
state.toastQueue.push(
|
|
||||||
makeToast({ title: error || t('toast.serverError'), status: 'error' })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session Canceled - FULFILLED
|
* Session Canceled - FULFILLED
|
||||||
*/
|
*/
|
||||||
@ -374,23 +367,6 @@ export const systemSlice = createSlice({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Session Created - REJECTED
|
|
||||||
*/
|
|
||||||
builder.addCase(sessionCreated.rejected, (state, action) => {
|
|
||||||
state.isProcessing = false;
|
|
||||||
state.isCancelable = false;
|
|
||||||
state.isCancelScheduled = false;
|
|
||||||
state.currentStep = 0;
|
|
||||||
state.totalSteps = 0;
|
|
||||||
state.statusTranslationKey = 'common.statusConnected';
|
|
||||||
state.progressImage = null;
|
|
||||||
|
|
||||||
state.toastQueue.push(
|
|
||||||
makeToast({ title: t('toast.problemCreatingSession'), status: 'error' })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Session Canceled
|
* Session Canceled
|
||||||
*/
|
*/
|
||||||
@ -437,6 +413,26 @@ export const systemSlice = createSlice({
|
|||||||
builder.addCase(imageUploaded.fulfilled, (state) => {
|
builder.addCase(imageUploaded.fulfilled, (state) => {
|
||||||
state.isUploading = false;
|
state.isUploading = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// *** Matchers - must be after all cases ***
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session Invoked - REJECTED
|
||||||
|
* Session Created - REJECTED
|
||||||
|
*/
|
||||||
|
builder.addMatcher(isAnySessionRejected, (state, action) => {
|
||||||
|
state.isProcessing = false;
|
||||||
|
state.isCancelable = false;
|
||||||
|
state.isCancelScheduled = false;
|
||||||
|
state.currentStep = 0;
|
||||||
|
state.totalSteps = 0;
|
||||||
|
state.statusTranslationKey = 'common.statusConnected';
|
||||||
|
state.progressImage = null;
|
||||||
|
|
||||||
|
state.toastQueue.push(
|
||||||
|
makeToast({ title: t('toast.serverError'), status: 'error' })
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -465,3 +461,8 @@ export const {
|
|||||||
} = systemSlice.actions;
|
} = systemSlice.actions;
|
||||||
|
|
||||||
export default systemSlice.reducer;
|
export default systemSlice.reducer;
|
||||||
|
|
||||||
|
const isAnySessionRejected = isAnyOf(
|
||||||
|
sessionCreated.rejected,
|
||||||
|
sessionInvoked.rejected
|
||||||
|
);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { createAppAsyncThunk } from 'app/store/storeUtils';
|
import { createAppAsyncThunk } from 'app/store/storeUtils';
|
||||||
import { GraphExecutionState, SessionsService } from 'services/api';
|
import { GraphExecutionState, SessionsService } from 'services/api';
|
||||||
import { log } from 'app/logging/useLogger';
|
import { log } from 'app/logging/useLogger';
|
||||||
|
import { isObject } from 'lodash-es';
|
||||||
|
|
||||||
const sessionLog = log.child({ namespace: 'session' });
|
const sessionLog = log.child({ namespace: 'session' });
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ export const sessionCreated = createAppAsyncThunk<
|
|||||||
GraphExecutionState,
|
GraphExecutionState,
|
||||||
SessionCreatedArg,
|
SessionCreatedArg,
|
||||||
SessionCreatedThunkConfig
|
SessionCreatedThunkConfig
|
||||||
>('api/sessionCreated', async (arg: SessionCreatedArg, { rejectWithValue }) => {
|
>('api/sessionCreated', async (arg, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const response = await SessionsService.createSession({
|
const response = await SessionsService.createSession({
|
||||||
requestBody: arg.graph,
|
requestBody: arg.graph,
|
||||||
@ -32,57 +33,26 @@ export const sessionCreated = createAppAsyncThunk<
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
type NodeAddedArg = Parameters<(typeof SessionsService)['addNode']>[0];
|
type SessionInvokedArg = { sessionId: string };
|
||||||
|
|
||||||
/**
|
type SessionInvokedThunkConfig = {
|
||||||
* `SessionsService.addNode()` thunk
|
rejectValue: {
|
||||||
*/
|
arg: SessionInvokedArg;
|
||||||
export const nodeAdded = createAppAsyncThunk(
|
error: unknown;
|
||||||
'api/nodeAdded',
|
};
|
||||||
async (
|
};
|
||||||
arg: { node: NodeAddedArg['requestBody']; sessionId: string },
|
|
||||||
_thunkApi
|
|
||||||
) => {
|
|
||||||
const response = await SessionsService.addNode({
|
|
||||||
requestBody: arg.node,
|
|
||||||
sessionId: arg.sessionId,
|
|
||||||
});
|
|
||||||
|
|
||||||
sessionLog.info({ arg, response }, `Node added (${response})`);
|
const isErrorWithStatus = (error: unknown): error is { status: number } =>
|
||||||
|
isObject(error) && 'status' in error;
|
||||||
return response;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
type NodeUpdatedArg = Parameters<(typeof SessionsService)['updateNode']>[0];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `SessionsService.addNode()` thunk
|
|
||||||
*/
|
|
||||||
export const nodeUpdated = createAppAsyncThunk(
|
|
||||||
'api/nodeUpdated',
|
|
||||||
async (
|
|
||||||
arg: { node: NodeUpdatedArg['requestBody']; sessionId: string },
|
|
||||||
_thunkApi
|
|
||||||
) => {
|
|
||||||
const response = await SessionsService.updateNode({
|
|
||||||
requestBody: arg.node,
|
|
||||||
sessionId: arg.sessionId,
|
|
||||||
nodePath: arg.node.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
sessionLog.info({ arg, response }, `Node updated (${response})`);
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `SessionsService.invokeSession()` thunk
|
* `SessionsService.invokeSession()` thunk
|
||||||
*/
|
*/
|
||||||
export const sessionInvoked = createAppAsyncThunk(
|
export const sessionInvoked = createAppAsyncThunk<
|
||||||
'api/sessionInvoked',
|
any,
|
||||||
async (arg: { sessionId: string }, { rejectWithValue }) => {
|
SessionInvokedArg,
|
||||||
|
SessionInvokedThunkConfig
|
||||||
|
>('api/sessionInvoked', async (arg, { rejectWithValue }) => {
|
||||||
const { sessionId } = arg;
|
const { sessionId } = arg;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -90,18 +60,14 @@ export const sessionInvoked = createAppAsyncThunk(
|
|||||||
sessionId,
|
sessionId,
|
||||||
all: true,
|
all: true,
|
||||||
});
|
});
|
||||||
sessionLog.info({ arg, response }, `Session invoked (${sessionId})`);
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const err = error as any;
|
if (isErrorWithStatus(error) && error.status === 403) {
|
||||||
if (err.status === 403) {
|
return rejectWithValue({ arg, error: (error as any).body.detail });
|
||||||
return rejectWithValue(err.body.detail);
|
|
||||||
}
|
}
|
||||||
throw error;
|
return rejectWithValue({ arg, error });
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
type SessionCanceledArg = Parameters<
|
type SessionCanceledArg = Parameters<
|
||||||
(typeof SessionsService)['cancelSessionInvoke']
|
(typeof SessionsService)['cancelSessionInvoke']
|
||||||
|
Loading…
Reference in New Issue
Block a user