mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-16 09:15:59 -05:00
Merge branch 'main' into model-classification-api
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import queryString from 'query-string';
|
||||
import type { paths } from 'services/api/schema';
|
||||
|
||||
import type { ApiTagDescription } from '..';
|
||||
import { api, buildV1Url, LIST_TAG } from '..';
|
||||
|
||||
/**
|
||||
@@ -19,15 +20,6 @@ export const workflowsApi = api.injectEndpoints({
|
||||
>({
|
||||
query: (workflow_id) => buildWorkflowsUrl(`i/${workflow_id}`),
|
||||
providesTags: (result, error, workflow_id) => [{ type: 'Workflow', id: workflow_id }, 'FetchOnReconnect'],
|
||||
onQueryStarted: async (arg, api) => {
|
||||
const { dispatch, queryFulfilled } = api;
|
||||
try {
|
||||
await queryFulfilled;
|
||||
dispatch(workflowsApi.util.invalidateTags([{ type: 'WorkflowsRecent', id: LIST_TAG }]));
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
},
|
||||
}),
|
||||
deleteWorkflow: build.mutation<void, string>({
|
||||
query: (workflow_id) => ({
|
||||
@@ -35,9 +27,11 @@ export const workflowsApi = api.injectEndpoints({
|
||||
method: 'DELETE',
|
||||
}),
|
||||
invalidatesTags: (result, error, workflow_id) => [
|
||||
// Because this may change the order of the list, we need to invalidate the whole list
|
||||
{ type: 'Workflow', id: LIST_TAG },
|
||||
{ type: 'Workflow', id: workflow_id },
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
'WorkflowTagCounts',
|
||||
'WorkflowCategoryCounts',
|
||||
],
|
||||
}),
|
||||
createWorkflow: build.mutation<
|
||||
@@ -50,8 +44,10 @@ export const workflowsApi = api.injectEndpoints({
|
||||
body: { workflow },
|
||||
}),
|
||||
invalidatesTags: [
|
||||
// Because this may change the order of the list, we need to invalidate the whole list
|
||||
{ type: 'Workflow', id: LIST_TAG },
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
'WorkflowTagCounts',
|
||||
'WorkflowCategoryCounts',
|
||||
],
|
||||
}),
|
||||
updateWorkflow: build.mutation<
|
||||
@@ -64,27 +60,28 @@ export const workflowsApi = api.injectEndpoints({
|
||||
body: { workflow },
|
||||
}),
|
||||
invalidatesTags: (response, error, workflow) => [
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
{ type: 'Workflow', id: LIST_TAG },
|
||||
{ type: 'Workflow', id: workflow.id },
|
||||
'WorkflowTagCounts',
|
||||
'WorkflowCategoryCounts',
|
||||
],
|
||||
}),
|
||||
listWorkflows: build.query<
|
||||
paths['/api/v1/workflows/']['get']['responses']['200']['content']['application/json'],
|
||||
NonNullable<paths['/api/v1/workflows/']['get']['parameters']['query']>
|
||||
getCountsByTag: build.query<
|
||||
paths['/api/v1/workflows/counts_by_tag']['get']['responses']['200']['content']['application/json'],
|
||||
NonNullable<paths['/api/v1/workflows/counts_by_tag']['get']['parameters']['query']>
|
||||
>({
|
||||
query: (params) => ({
|
||||
url: `${buildWorkflowsUrl()}?${queryString.stringify(params, { arrayFormat: 'none' })}`,
|
||||
url: `${buildWorkflowsUrl('counts_by_tag')}?${queryString.stringify(params, { arrayFormat: 'none' })}`,
|
||||
}),
|
||||
providesTags: ['FetchOnReconnect', { type: 'Workflow', id: LIST_TAG }],
|
||||
providesTags: ['WorkflowTagCounts'],
|
||||
}),
|
||||
getCounts: build.query<
|
||||
paths['/api/v1/workflows/counts']['get']['responses']['200']['content']['application/json'],
|
||||
NonNullable<paths['/api/v1/workflows/counts']['get']['parameters']['query']>
|
||||
getCountsByCategory: build.query<
|
||||
paths['/api/v1/workflows/counts_by_category']['get']['responses']['200']['content']['application/json'],
|
||||
NonNullable<paths['/api/v1/workflows/counts_by_category']['get']['parameters']['query']>
|
||||
>({
|
||||
query: (params) => ({
|
||||
url: `${buildWorkflowsUrl('counts')}?${queryString.stringify(params, { arrayFormat: 'none' })}`,
|
||||
url: `${buildWorkflowsUrl('counts_by_category')}?${queryString.stringify(params, { arrayFormat: 'none' })}`,
|
||||
}),
|
||||
providesTags: ['WorkflowCategoryCounts'],
|
||||
}),
|
||||
listWorkflowsInfinite: build.infiniteQuery<
|
||||
paths['/api/v1/workflows/']['get']['responses']['200']['content']['application/json'],
|
||||
@@ -108,13 +105,29 @@ export const workflowsApi = api.injectEndpoints({
|
||||
return firstPageParam > -1 ? firstPageParam - 1 : undefined;
|
||||
},
|
||||
},
|
||||
providesTags: (result) => {
|
||||
const tags: ApiTagDescription[] = ['FetchOnReconnect', { type: 'Workflow', id: LIST_TAG }];
|
||||
if (result) {
|
||||
tags.push(
|
||||
...result.pages
|
||||
.map(({ items }) => items)
|
||||
.flat()
|
||||
.map((workflow) => ({ type: 'Workflow', id: workflow.workflow_id }) as const)
|
||||
);
|
||||
}
|
||||
return tags;
|
||||
},
|
||||
}),
|
||||
updateOpenedAt: build.mutation<void, { workflow_id: string }>({
|
||||
query: ({ workflow_id }) => ({
|
||||
url: buildWorkflowsUrl(`i/${workflow_id}/opened_at`),
|
||||
method: 'PUT',
|
||||
}),
|
||||
invalidatesTags: (result, error, { workflow_id }) => [{ type: 'Workflow', id: workflow_id }],
|
||||
invalidatesTags: (result, error, { workflow_id }) => [
|
||||
{ type: 'Workflow', id: workflow_id },
|
||||
// Because this may change the order of the list, we need to invalidate the whole list
|
||||
{ type: 'Workflow', id: LIST_TAG },
|
||||
],
|
||||
}),
|
||||
setWorkflowThumbnail: build.mutation<void, { workflow_id: string; image: File }>({
|
||||
query: ({ workflow_id, image }) => {
|
||||
@@ -126,33 +139,27 @@ export const workflowsApi = api.injectEndpoints({
|
||||
body: formData,
|
||||
};
|
||||
},
|
||||
invalidatesTags: (result, error, { workflow_id }) => [
|
||||
{ type: 'Workflow', id: workflow_id },
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
],
|
||||
invalidatesTags: (result, error, { workflow_id }) => [{ type: 'Workflow', id: workflow_id }],
|
||||
}),
|
||||
deleteWorkflowThumbnail: build.mutation<void, string>({
|
||||
query: (workflow_id) => ({
|
||||
url: buildWorkflowsUrl(`i/${workflow_id}/thumbnail`),
|
||||
method: 'DELETE',
|
||||
}),
|
||||
invalidatesTags: (result, error, workflow_id) => [
|
||||
{ type: 'Workflow', id: workflow_id },
|
||||
{ type: 'WorkflowsRecent', id: LIST_TAG },
|
||||
],
|
||||
invalidatesTags: (result, error, workflow_id) => [{ type: 'Workflow', id: workflow_id }],
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const {
|
||||
useUpdateOpenedAtMutation,
|
||||
useGetCountsQuery,
|
||||
useGetCountsByTagQuery,
|
||||
useGetCountsByCategoryQuery,
|
||||
useLazyGetWorkflowQuery,
|
||||
useGetWorkflowQuery,
|
||||
useCreateWorkflowMutation,
|
||||
useDeleteWorkflowMutation,
|
||||
useUpdateWorkflowMutation,
|
||||
useListWorkflowsQuery,
|
||||
useListWorkflowsInfiniteInfiniteQuery,
|
||||
useSetWorkflowThumbnailMutation,
|
||||
useDeleteWorkflowThumbnailMutation,
|
||||
|
||||
@@ -39,7 +39,7 @@ const buildModelsHook =
|
||||
typeGuard: (config: AnyModelConfig, excludeSubmodels?: boolean) => config is T,
|
||||
excludeSubmodels?: boolean
|
||||
) =>
|
||||
() => {
|
||||
(filter: (config: T) => boolean = () => true) => {
|
||||
const result = useGetModelConfigsQuery(undefined);
|
||||
const modelConfigs = useMemo(() => {
|
||||
if (!result.data) {
|
||||
@@ -48,8 +48,9 @@ const buildModelsHook =
|
||||
|
||||
return modelConfigsAdapterSelectors
|
||||
.selectAll(result.data)
|
||||
.filter((config) => typeGuard(config, excludeSubmodels));
|
||||
}, [result]);
|
||||
.filter((config) => typeGuard(config, excludeSubmodels))
|
||||
.filter(filter);
|
||||
}, [filter, result.data]);
|
||||
|
||||
return [modelConfigs, result] as const;
|
||||
};
|
||||
@@ -78,6 +79,9 @@ export const useFluxVAEModels = (args?: ModelHookArgs) =>
|
||||
export const useCLIPVisionModels = buildModelsHook(isCLIPVisionModelConfig);
|
||||
export const useSigLipModels = buildModelsHook(isSigLipModelConfig);
|
||||
export const useFluxReduxModels = buildModelsHook(isFluxReduxModelConfig);
|
||||
export const useIPAdapterOrFLUXReduxModels = buildModelsHook(
|
||||
(config) => isIPAdapterModelConfig(config) || isFluxReduxModelConfig(config)
|
||||
);
|
||||
|
||||
// const buildModelsSelector =
|
||||
// <T extends AnyModelConfig>(typeGuard: (config: AnyModelConfig) => config is T): Selector<RootState, T[]> =>
|
||||
|
||||
@@ -44,7 +44,8 @@ const tagTypes = [
|
||||
'LoRAModel',
|
||||
'SDXLRefinerModel',
|
||||
'Workflow',
|
||||
'WorkflowsRecent',
|
||||
'WorkflowTagCounts',
|
||||
'WorkflowCategoryCounts',
|
||||
'StylePreset',
|
||||
'Schema',
|
||||
'QueueCountsByDestination',
|
||||
|
||||
@@ -1438,7 +1438,7 @@ export type paths = {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/workflows/counts": {
|
||||
"/api/v1/workflows/counts_by_tag": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
@@ -1446,10 +1446,30 @@ export type paths = {
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* Get Counts
|
||||
* @description Gets a the count of workflows that include the specified tags and categories
|
||||
* Get Counts By Tag
|
||||
* @description Counts workflows by tag
|
||||
*/
|
||||
get: operations["get_counts"];
|
||||
get: operations["get_counts_by_tag"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/workflows/counts_by_category": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* Counts By Category
|
||||
* @description Counts workflows by category
|
||||
*/
|
||||
get: operations["counts_by_category"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
@@ -7970,12 +7990,6 @@ export type components = {
|
||||
* @default null
|
||||
*/
|
||||
redux_model?: components["schemas"]["ModelIdentifierField"];
|
||||
/**
|
||||
* SigLIP Model
|
||||
* @description The SigLIP model to use.
|
||||
* @default null
|
||||
*/
|
||||
siglip_model?: components["schemas"]["ModelIdentifierField"];
|
||||
/**
|
||||
* type
|
||||
* @default flux_redux
|
||||
@@ -21100,7 +21114,7 @@ export type components = {
|
||||
* Opened At
|
||||
* @description The opened timestamp of the workflow.
|
||||
*/
|
||||
opened_at: string;
|
||||
opened_at: string | null;
|
||||
/** @description The workflow. */
|
||||
workflow: components["schemas"]["Workflow"];
|
||||
};
|
||||
@@ -21130,7 +21144,7 @@ export type components = {
|
||||
* Opened At
|
||||
* @description The opened timestamp of the workflow.
|
||||
*/
|
||||
opened_at: string;
|
||||
opened_at: string | null;
|
||||
/**
|
||||
* Description
|
||||
* @description The description of the workflow.
|
||||
@@ -21181,7 +21195,7 @@ export type components = {
|
||||
* Opened At
|
||||
* @description The opened timestamp of the workflow.
|
||||
*/
|
||||
opened_at: string;
|
||||
opened_at: string | null;
|
||||
/** @description The workflow. */
|
||||
workflow: components["schemas"]["Workflow"];
|
||||
/**
|
||||
@@ -24243,6 +24257,8 @@ export interface operations {
|
||||
tags?: string[] | null;
|
||||
/** @description The text to query by (matches name and description) */
|
||||
query?: string | null;
|
||||
/** @description Whether to include/exclude recent workflows */
|
||||
has_been_opened?: boolean | null;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
@@ -24417,13 +24433,15 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
get_counts: {
|
||||
get_counts_by_tag: {
|
||||
parameters: {
|
||||
query?: {
|
||||
/** @description The tags to include */
|
||||
tags?: string[] | null;
|
||||
query: {
|
||||
/** @description The tags to get counts for */
|
||||
tags: string[];
|
||||
/** @description The categories to include */
|
||||
categories?: components["schemas"]["WorkflowCategory"][] | null;
|
||||
/** @description Whether to include/exclude recent workflows */
|
||||
has_been_opened?: boolean | null;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
@@ -24437,7 +24455,45 @@ export interface operations {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": number;
|
||||
"application/json": {
|
||||
[key: string]: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
counts_by_category: {
|
||||
parameters: {
|
||||
query: {
|
||||
/** @description The categories to include */
|
||||
categories: components["schemas"]["WorkflowCategory"][];
|
||||
/** @description Whether to include/exclude recent workflows */
|
||||
has_been_opened?: boolean | null;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": {
|
||||
[key: string]: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
|
||||
@@ -63,7 +63,7 @@ type DiffusersModelConfig = S['MainDiffusersConfig'];
|
||||
export type CheckpointModelConfig = S['MainCheckpointConfig'];
|
||||
type CLIPVisionDiffusersConfig = S['CLIPVisionDiffusersConfig'];
|
||||
export type SigLipModelConfig = S['SigLIPConfig'];
|
||||
export type FluxReduxModelConfig = S['FluxReduxConfig'];
|
||||
export type FLUXReduxModelConfig = S['FluxReduxConfig'];
|
||||
export type MainModelConfig = DiffusersModelConfig | CheckpointModelConfig;
|
||||
export type AnyModelConfig =
|
||||
| ControlLoRAModelConfig
|
||||
@@ -80,7 +80,7 @@ export type AnyModelConfig =
|
||||
| MainModelConfig
|
||||
| CLIPVisionDiffusersConfig
|
||||
| SigLipModelConfig
|
||||
| FluxReduxModelConfig;
|
||||
| FLUXReduxModelConfig;
|
||||
|
||||
/**
|
||||
* Checks if a list of submodels contains any that match a given variant or type
|
||||
@@ -217,7 +217,7 @@ export const isSigLipModelConfig = (config: AnyModelConfig): config is SigLipMod
|
||||
return config.type === 'siglip';
|
||||
};
|
||||
|
||||
export const isFluxReduxModelConfig = (config: AnyModelConfig): config is FluxReduxModelConfig => {
|
||||
export const isFluxReduxModelConfig = (config: AnyModelConfig): config is FLUXReduxModelConfig => {
|
||||
return config.type === 'flux_redux';
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user