Merge branch 'main' into nextprevcurrentimagenode

This commit is contained in:
mickr777
2023-08-27 19:50:39 +10:00
committed by GitHub
35 changed files with 595 additions and 433 deletions

View File

@ -1,11 +1,11 @@
# Copyright (c) 2022-2023 Kyle Schouviller (https://github.com/kyle0654) and the InvokeAI Team
import asyncio
from inspect import signature
import logging
import uvicorn
import socket
from inspect import signature
from pathlib import Path
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
@ -13,7 +13,6 @@ from fastapi.openapi.utils import get_openapi
from fastapi.staticfiles import StaticFiles
from fastapi_events.handlers.local import local_handler
from fastapi_events.middleware import EventHandlerASGIMiddleware
from pathlib import Path
from pydantic.schema import schema
from .services.config import InvokeAIAppConfig
@ -30,9 +29,12 @@ from .api.sockets import SocketIO
from .invocations.baseinvocation import BaseInvocation, _InputField, _OutputField, UIConfigBase
import torch
# noinspection PyUnresolvedReferences
import invokeai.backend.util.hotfixes # noqa: F401 (monkeypatching on import)
if torch.backends.mps.is_available():
# noinspection PyUnresolvedReferences
import invokeai.backend.util.mps_fixes # noqa: F401 (monkeypatching on import)
@ -40,7 +42,6 @@ app_config = InvokeAIAppConfig.get_config()
app_config.parse_args()
logger = InvokeAILogger.getLogger(config=app_config)
# fix for windows mimetypes registry entries being borked
# see https://github.com/invoke-ai/InvokeAI/discussions/3684#discussioncomment-6391352
mimetypes.add_type("application/javascript", ".js")
@ -208,6 +209,17 @@ def invoke_api():
check_invokeai_root(app_config) # note, may exit with an exception if root not set up
if app_config.dev_reload:
try:
import jurigged
except ImportError as e:
logger.error(
'Can\'t start `--dev_reload` because jurigged is not found; `pip install -e ".[dev]"` to include development dependencies.',
exc_info=e,
)
else:
jurigged.watch(logger=InvokeAILogger.getLogger(name="jurigged").info)
port = find_port(app_config.port)
if port != app_config.port:
logger.warn(f"Port {app_config.port} in use, using port {port}")

View File

@ -32,6 +32,7 @@ class CoreMetadata(BaseModelExcludeNull):
generation_mode: str = Field(
description="The generation mode that output this image",
)
created_by: Optional[str] = Field(description="The name of the creator of the image")
positive_prompt: str = Field(description="The positive prompt parameter")
negative_prompt: str = Field(description="The negative prompt parameter")
width: int = Field(description="The width parameter")

View File

@ -169,11 +169,13 @@ two configs are kept in separate sections of the config file:
"""
from __future__ import annotations
import os
from omegaconf import OmegaConf, DictConfig
from pathlib import Path
from typing import ClassVar, Dict, List, Literal, Union, get_type_hints, Optional
from omegaconf import OmegaConf, DictConfig
from pydantic import Field, parse_obj_as
from typing import ClassVar, Dict, List, Literal, Union, Optional, get_type_hints
from .base import InvokeAISettings
@ -233,6 +235,8 @@ class InvokeAIAppConfig(InvokeAISettings):
log_format : Literal['plain', 'color', 'syslog', 'legacy'] = Field(default="color", description='Log format. Use "plain" for text-only, "color" for colorized output, "legacy" for 2.3-style logging and "syslog" for syslog-style', category="Logging")
log_level : Literal["debug", "info", "warning", "error", "critical"] = Field(default="info", description="Emit logging messages at this level or higher", category="Logging")
dev_reload : bool = Field(default=False, description="Automatically reload when Python sources are changed.", category="Development")
version : bool = Field(default=False, description="Show InvokeAI version and exit", category="Other")
# CACHE

View File

@ -50,7 +50,7 @@ from invokeai.frontend.install.model_install import addModelsForm, process_and_e
# TO DO - Move all the frontend code into invokeai.frontend.install
from invokeai.frontend.install.widgets import (
SingleSelectColumns,
SingleSelectColumnsSimple,
MultiSelectColumns,
CenteredButtonPress,
FileBox,
@ -354,7 +354,6 @@ Use cursor arrows to make a checkbox selection, and space to toggle.
device = old_opts.device
attention_type = old_opts.attention_type
attention_slice_size = old_opts.attention_slice_size
self.nextrely += 1
self.add_widget_intelligent(
npyscreen.TitleFixedText,
@ -385,7 +384,7 @@ Use cursor arrows to make a checkbox selection, and space to toggle.
)
self.nextrely -= 2
self.precision = self.add_widget_intelligent(
SingleSelectColumns,
SingleSelectColumnsSimple,
columns=len(PRECISION_CHOICES),
name="Precision",
values=PRECISION_CHOICES,
@ -406,10 +405,10 @@ Use cursor arrows to make a checkbox selection, and space to toggle.
)
self.nextrely -= 2
self.device = self.add_widget_intelligent(
SingleSelectColumns,
SingleSelectColumnsSimple,
columns=len(DEVICE_CHOICES),
values=DEVICE_CHOICES,
value=DEVICE_CHOICES.index(device),
value=[DEVICE_CHOICES.index(device)],
begin_entry_at=3,
relx=30,
max_height=2,
@ -426,10 +425,10 @@ Use cursor arrows to make a checkbox selection, and space to toggle.
)
self.nextrely -= 2
self.attention_type = self.add_widget_intelligent(
SingleSelectColumns,
SingleSelectColumnsSimple,
columns=len(ATTENTION_CHOICES),
values=ATTENTION_CHOICES,
value=ATTENTION_CHOICES.index(attention_type),
value=[ATTENTION_CHOICES.index(attention_type)],
begin_entry_at=3,
max_height=2,
relx=30,
@ -448,17 +447,16 @@ Use cursor arrows to make a checkbox selection, and space to toggle.
)
self.nextrely -= 2
self.attention_slice_size = self.add_widget_intelligent(
SingleSelectColumns,
SingleSelectColumnsSimple,
columns=len(ATTENTION_SLICE_CHOICES),
values=ATTENTION_SLICE_CHOICES,
value=ATTENTION_SLICE_CHOICES.index(attention_slice_size),
value=[ATTENTION_SLICE_CHOICES.index(attention_slice_size)],
relx=30,
hidden=attention_type != "sliced",
max_height=2,
max_width=110,
scroll_exit=True,
)
self.add_widget_intelligent(
npyscreen.TitleFixedText,
name="Model RAM cache size (GB). Make this at least large enough to hold a single full model.",
@ -707,8 +705,6 @@ def initialize_rootdir(root: Path, yes_to_all: bool = False):
path = dest / "core"
path.mkdir(parents=True, exist_ok=True)
maybe_create_models_yaml(root)
def maybe_create_models_yaml(root: Path):
models_yaml = root / "configs" / "models.yaml"

View File

@ -177,6 +177,8 @@ class FloatTitleSlider(npyscreen.TitleText):
class SelectColumnBase:
"""Base class for selection widget arranged in columns."""
def make_contained_widgets(self):
self._my_widgets = []
column_width = self.width // self.columns
@ -253,6 +255,7 @@ class MultiSelectColumns(SelectColumnBase, npyscreen.MultiSelect):
class SingleSelectWithChanged(npyscreen.SelectOne):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.on_changed = None
def h_select(self, ch):
super().h_select(ch)
@ -260,7 +263,9 @@ class SingleSelectWithChanged(npyscreen.SelectOne):
self.on_changed(self.value)
class SingleSelectColumns(SelectColumnBase, SingleSelectWithChanged):
class SingleSelectColumnsSimple(SelectColumnBase, SingleSelectWithChanged):
"""Row of radio buttons. Spacebar to select."""
def __init__(self, screen, columns: int = 1, values: list = [], **keywords):
self.columns = columns
self.value_cnt = len(values)
@ -268,12 +273,6 @@ class SingleSelectColumns(SelectColumnBase, SingleSelectWithChanged):
self.on_changed = None
super().__init__(screen, values=values, **keywords)
def when_value_edited(self):
self.h_select(self.cursor_line)
def when_cursor_moved(self):
self.h_select(self.cursor_line)
def h_cursor_line_right(self, ch):
self.h_exit_down("bye bye")
@ -281,6 +280,13 @@ class SingleSelectColumns(SelectColumnBase, SingleSelectWithChanged):
self.h_exit_up("bye bye")
class SingleSelectColumns(SingleSelectColumnsSimple):
"""Row of radio buttons. When tabbing over a selection, it is auto selected."""
def when_cursor_moved(self):
self.h_select(self.cursor_line)
class TextBoxInner(npyscreen.MultiLineEdit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

View File

@ -1,4 +1,4 @@
import { MenuItem } from '@chakra-ui/react';
import { Flex, MenuItem, Text } from '@chakra-ui/react';
import { skipToken } from '@reduxjs/toolkit/dist/query';
import { useAppToaster } from 'app/components/Toaster';
import { useAppDispatch } from 'app/store/storeHooks';
@ -228,6 +228,18 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
>
{t('gallery.deleteImage')}
</MenuItem>
{metadata?.created_by && (
<Flex
sx={{
padding: '5px 10px',
marginTop: '5px',
}}
>
<Text fontSize="xs" fontWeight="bold">
Created by {metadata?.created_by}
</Text>
</Flex>
)}
</>
);
};

View File

@ -69,6 +69,9 @@ const ImageMetadataActions = (props: Props) => {
return (
<>
{metadata.created_by && (
<ImageMetadataItem label="Created By" value={metadata.created_by} />
)}
{metadata.generation_mode && (
<ImageMetadataItem
label="Generation Mode"

View File

@ -1453,6 +1453,11 @@ export type components = {
* @description The generation mode that output this image
*/
generation_mode: string;
/**
* Created By
* @description The name of the creator of the image
*/
created_by?: string;
/**
* Positive Prompt
* @description The positive prompt parameter
@ -6319,18 +6324,18 @@ export type components = {
* @enum {string}
*/
ControlNetModelFormat: "checkpoint" | "diffusers";
/**
* StableDiffusionOnnxModelFormat
* @description An enumeration.
* @enum {string}
*/
StableDiffusionOnnxModelFormat: "olive" | "onnx";
/**
* StableDiffusion1ModelFormat
* @description An enumeration.
* @enum {string}
*/
StableDiffusion1ModelFormat: "checkpoint" | "diffusers";
/**
* StableDiffusionOnnxModelFormat
* @description An enumeration.
* @enum {string}
*/
StableDiffusionOnnxModelFormat: "olive" | "onnx";
/**
* StableDiffusionXLModelFormat
* @description An enumeration.