Skip to content

Commit 0f60420

Browse files
authored
Merge pull request #123 from LlmKira/dev
✨ improve(generate_image): Params is now identical to the website.
2 parents f68526a + 3468cd9 commit 0f60420

File tree

4 files changed

+79
-27
lines changed

4 files changed

+79
-27
lines changed

src/novelai_python/sdk/ai/_enum.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ def get_modifiers(model: Model) -> Modifier:
464464
]:
465465
return Modifier(
466466
qualityTags="",
467-
suffix=", location, very aesthetic, masterpiece, no text"
467+
suffix=", very aesthetic, masterpiece, no text"
468468
)
469469
if model in [
470470
Model.NAI_DIFFUSION_4_5_CURATED,
@@ -661,12 +661,12 @@ def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
661661
UcPrompt(
662662
category="heavy",
663663
name="lowQualityPlusBadAnatomy",
664-
text="lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"
664+
text="nsfw, lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"
665665
),
666666
UcPrompt(
667667
category="light",
668668
name="lowQuality",
669-
text="lowres, text, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"
669+
text="nsfw, lowres, text, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry"
670670
),
671671
UcPrompt(
672672
category="none",
@@ -682,12 +682,12 @@ def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
682682
UcPrompt(
683683
category="light",
684684
name="lowQuality",
685-
text="worst quality, low quality, what has science done, what, nightmare fuel, eldritch horror, where is your god now, why"
685+
text="nsfw, worst quality, low quality, what has science done, what, nightmare fuel, eldritch horror, where is your god now, why"
686686
),
687687
UcPrompt(
688688
category="heavy",
689689
name="badAnatomy",
690-
text="{worst quality}, low quality, distracting watermark, [nightmare fuel], {{unfinished}}, deformed, outline, pattern, simple background"
690+
text="nsfw, {worst quality}, low quality, distracting watermark, [nightmare fuel], {{unfinished}}, deformed, outline, pattern, simple background"
691691
),
692692
UcPrompt(
693693
category="none",
@@ -702,12 +702,12 @@ def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
702702
UcPrompt(
703703
category="heavy",
704704
name="heavy",
705-
text="lowres, bad, text, error, missing, extra, fewer, cropped, jpeg artifacts, worst quality, bad quality, watermark, displeasing, unfinished, chromatic aberration, scan, scan artifacts"
705+
text="nsfw, lowres, bad, text, error, missing, extra, fewer, cropped, jpeg artifacts, worst quality, bad quality, watermark, displeasing, unfinished, chromatic aberration, scan, scan artifacts"
706706
),
707707
UcPrompt(
708708
category="light",
709709
name="light",
710-
text="lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"
710+
text="nsfw, lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"
711711
),
712712
UcPrompt(
713713
category="none",
@@ -723,17 +723,17 @@ def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
723723
UcPrompt(
724724
category="heavy",
725725
name="heavy",
726-
text="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]"
726+
text="nsfw, lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]"
727727
),
728728
UcPrompt(
729729
category="light",
730730
name="light",
731-
text="lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"
731+
text="nsfw, lowres, jpeg artifacts, worst quality, watermark, blurry, very displeasing"
732732
),
733733
UcPrompt(
734734
category="human",
735735
name="humanFocus",
736-
text="lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract], bad anatomy, bad hands, @_@, mismatched pupils, heart-shaped pupils, glowing eyes"
736+
text="nsfw, lowres, {bad}, error, fewer, extra, missing, worst quality, jpeg artifacts, bad quality, watermark, unfinished, displeasing, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract], bad anatomy, bad hands, @_@, mismatched pupils, heart-shaped pupils, glowing eyes"
737737
),
738738
UcPrompt(
739739
category="none",
@@ -749,12 +749,12 @@ def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
749749
UcPrompt(
750750
category="heavy",
751751
name="heavy",
752-
text="{{worst quality}}, [displeasing], {unusual pupils}, guide lines, {{unfinished}}, {bad}, url, artist name, {{tall image}}, mosaic, {sketch page}, comic panel, impact (font), [dated], {logo}, ych, {what}, {where is your god now}, {distorted text}, repeated text, {floating head}, {1994}, {widescreen}, absolutely everyone, sequence, {compression artifacts}, hard translated, {cropped}, {commissioner name}, unknown text, high contrast"
752+
text="nsfw, {{worst quality}}, [displeasing], {unusual pupils}, guide lines, {{unfinished}}, {bad}, url, artist name, {{tall image}}, mosaic, {sketch page}, comic panel, impact (font), [dated], {logo}, ych, {what}, {where is your god now}, {distorted text}, repeated text, {floating head}, {1994}, {widescreen}, absolutely everyone, sequence, {compression artifacts}, hard translated, {cropped}, {commissioner name}, unknown text, high contrast"
753753
),
754754
UcPrompt(
755755
category="light",
756756
name="light",
757-
text="{worst quality}, guide lines, unfinished, bad, url, tall image, widescreen, compression artifacts, unknown text"
757+
text="nsfw, {worst quality}, guide lines, unfinished, bad, url, tall image, widescreen, compression artifacts, unknown text"
758758
),
759759
UcPrompt(
760760
category="none",
@@ -791,12 +791,12 @@ def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
791791
UcPrompt(
792792
category="heavy",
793793
name="heavy",
794-
text="blurry, lowres, error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, multiple views, logo, too many watermarks, white blank page, blank page"
794+
text="nsfw, blurry, lowres, error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, multiple views, logo, too many watermarks, white blank page, blank page"
795795
),
796796
UcPrompt(
797797
category="light",
798798
name="light",
799-
text="blurry, lowres, error, worst quality, bad quality, jpeg artifacts, very displeasing, white blank page, blank page"
799+
text="nsfw, blurry, lowres, error, worst quality, bad quality, jpeg artifacts, very displeasing, white blank page, blank page"
800800
),
801801
UcPrompt(
802802
category="none",
@@ -839,22 +839,22 @@ def get_uc_preset(model: ModelTypeAlias) -> List[UcPrompt]:
839839
UcPrompt(
840840
category="heavy",
841841
name="heavy",
842-
text="lowres, artistic error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, dithering, halftone, screentone, multiple views, logo, too many watermarks, negative space, blank page"
842+
text="nsfw, lowres, artistic error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, dithering, halftone, screentone, multiple views, logo, too many watermarks, negative space, blank page"
843843
),
844844
UcPrompt(
845845
category="light",
846846
name="light",
847-
text="lowres, artistic error, scan artifacts, worst quality, bad quality, jpeg artifacts, multiple views, very displeasing, too many watermarks, negative space, blank page"
847+
text="nsfw, lowres, artistic error, scan artifacts, worst quality, bad quality, jpeg artifacts, multiple views, very displeasing, too many watermarks, negative space, blank page"
848848
),
849849
UcPrompt(
850850
category="furry",
851851
name="furryFocus",
852-
text="{worst quality}, distracting watermark, unfinished, bad quality, {widescreen}, upscale, {sequence}, {{grandfathered content}}, blurred foreground, chromatic aberration, sketch, everyone, [sketch background], simple, [flat colors], ych (character), outline, multiple scenes, [[horror (theme)]], comic"
852+
text="nsfw, {worst quality}, distracting watermark, unfinished, bad quality, {widescreen}, upscale, {sequence}, {{grandfathered content}}, blurred foreground, chromatic aberration, sketch, everyone, [sketch background], simple, [flat colors], ych (character), outline, multiple scenes, [[horror (theme)]], comic"
853853
),
854854
UcPrompt(
855855
category="human",
856856
name="humanFocus",
857-
text="lowres, artistic error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, dithering, halftone, screentone, multiple views, logo, too many watermarks, negative space, blank page, @_@, mismatched pupils, glowing eyes, bad anatomy"
857+
text="nsfw, lowres, artistic error, film grain, scan artifacts, worst quality, bad quality, jpeg artifacts, very displeasing, chromatic aberration, dithering, halftone, screentone, multiple views, logo, too many watermarks, negative space, blank page, @_@, mismatched pupils, glowing eyes, bad anatomy"
858858
),
859859
UcPrompt(
860860
category="none",

src/novelai_python/sdk/ai/generate_image/__init__.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ def set_mutual_exclusion(self, value: bool):
6565
action: Union[str, Action] = Field(Action.GENERATE, description="Mode for img generate")
6666
parameters: Union[Params]
6767
model_config = ConfigDict(extra="ignore")
68+
69+
# forced params integration
70+
def model_dump(self, *args, **kwargs):
71+
"""
72+
Overrides model_dump for own features
73+
"""
74+
data = super().model_dump(*args, **kwargs)
75+
data["parameters"] = self.parameters.model_dump(*args, **kwargs)
76+
77+
return data
6878

6979
@override
7080
def model_post_init(self, *args) -> None:
@@ -158,6 +168,13 @@ def enhance_message(_prompt):
158168
if key in uc_prompt:
159169
uc_prompt.pop(key)
160170
self.parameters.negative_prompt = ",".join(uc_prompt.values())
171+
172+
# Instantly remove nsfw if input contains it
173+
elif "nsfw" in self.input and "nsfw" in self.parameters.negative_prompt:
174+
uc_prompt = {x.strip(): x for x in self.parameters.negative_prompt.split(",")}
175+
uc_prompt.pop("nsfw", None)
176+
177+
self.parameters.negative_prompt = ",".join(uc_prompt.values())
161178

162179
@model_validator(mode="after")
163180
def _build_nai4_prompt(self):
@@ -187,9 +204,9 @@ def _build_nai4_prompt(self):
187204
if not get_supported_params(self.model).vibetransfer:
188205
if self.parameters.reference_image_multiple:
189206
logger.warning("Vibe transfer is not supported for this model.")
190-
self.parameters.reference_image_multiple = []
191-
self.parameters.reference_information_extracted_multiple = []
192-
self.parameters.reference_strength_multiple = []
207+
self.parameters.reference_image_multiple = None # Auto exclude None values
208+
self.parameters.reference_information_extracted_multiple = None # Auto exclude None values
209+
self.parameters.reference_strength_multiple = None # Auto exclude None values
193210

194211
if not get_supported_params(self.model).controlnet:
195212
if self.parameters.controlnet_condition is not None:
@@ -210,6 +227,9 @@ def _backend_logic(self):
210227
"""
211228
if self.parameters.characterPrompts:
212229
self.parameters.use_coords = any([c.center != PositionMap.AUTO for c in self.parameters.characterPrompts])
230+
231+
if get_supported_params(self.model).v4Prompts and self.parameters.v4_prompt is not None:
232+
self.parameters.v4_prompt.use_coords = self.parameters.use_coords
213233
# Mix Prompt Warning
214234
if self.input.count('|') > 6:
215235
logger.warning("Maximum prompt mixes exceeded. Extra will be ignored.")

src/novelai_python/sdk/ai/generate_image/params.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import base64
22
import random
33
from io import BytesIO
4-
from typing import Optional, List, Union, Tuple
4+
from typing import Optional, List, OrderedDict, Set, Union, Tuple
55

66
import cv2
77
import numpy as np
@@ -62,6 +62,8 @@ class Params(BaseModel):
6262
"""Use Coordinates"""
6363
legacy_uc: bool = False
6464
normalize_reference_strength_multiple: bool = True
65+
inpaintImg2ImgStrength: Optional[float] = Field(None, ge=0, le=1, multiple_of=0.01)
66+
"""For SameFeel"""
6567
seed: int = Field(
6668
default_factory=lambda: random.randint(0, 4294967295 - 7),
6769
gt=0,
@@ -107,15 +109,45 @@ class Params(BaseModel):
107109
"""Extra Noise Seed"""
108110
color_correct: Optional[bool] = None
109111
"""For Inpaint"""
110-
inpaintImg2ImgStrength: Optional[float] = Field(None, ge=0, le=1, multiple_of=0.01)
111-
"""For SameFeel"""
112112
controlnet_condition: Optional[str] = None
113113
"""ControlNet Condition"""
114114
controlnet_model: Optional[ControlNetModel] = None
115115
"""ControlNet Model"""
116116
uncond_scale: Optional[float] = Field(None, ge=0, le=1.5, multiple_of=0.05)
117117
"""Undesired Content Strength"""
118-
118+
119+
########## Next code wants custom BaseModel
120+
__strong_values__: Set[str] = {
121+
"skip_cfg_above_sigma", # See models before Anime V3
122+
}
123+
"""Settings with none value to strongly include"""
124+
125+
def force_include(self, value: str):
126+
"""
127+
Force include some params to json
128+
"""
129+
if value not in self.__dict__:
130+
raise ValueError("Wrong value in params:", value)
131+
132+
self.__strong_values__.add(value)
133+
134+
# Also integrated into GenerateImageInfer
135+
def model_dump(self, *args, **kwargs):
136+
"""
137+
Overrides model_dump for own features
138+
"""
139+
data = super().model_dump(*args, **kwargs)
140+
ordered_fields = list(self.__fields__.keys())
141+
new_data = OrderedDict()
142+
143+
for field in ordered_fields:
144+
if field in data:
145+
new_data[field] = data[field]
146+
elif field in self.__strong_values__:
147+
new_data[field] = getattr(self, field, None)
148+
return new_data
149+
#########
150+
119151
@model_validator(mode="after")
120152
def v_character(self):
121153
if len(self.characterPrompts) > 6:

src/novelai_python/sdk/ai/generate_image/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ class Caption(BaseModel):
8484

8585
class V4Prompt(BaseModel):
8686
caption: Caption = Field(default_factory=Caption, description="Caption")
87-
use_coords: bool = Field(True, description="Use Coordinates")
87+
use_coords: bool = Field(False, description="Use Coordinates")
8888
use_order: bool = Field(True, description="Use Order")
8989

9090
@classmethod
9191
def build_from_character_prompts(cls,
9292
base_caption: str,
9393
character_prompts: List[Character],
94-
use_coords: bool = True,
94+
use_coords: bool = False,
9595
use_order: bool = True
9696
) -> "V4Prompt":
9797
"""

0 commit comments

Comments
 (0)