diff --git a/_conf_schema.json b/_conf_schema.json index deb8dce..eea8278 100644 --- a/_conf_schema.json +++ b/_conf_schema.json @@ -9,25 +9,25 @@ "type": "bool", "description": "控制回复的详略程度", "default": true, - "hint": "设置为true时,将输出生成步骤,否则只输出图片" + "hint": "设置为true时,将实时输出AI生图进行到了哪个阶段,否则仅输出最终图片" }, "session_timeout_time": { "type": "int", "description": "会话判定超时时间,单位秒(s)", "default": 120, - "hint": "默认为两分钟,根据需要修改" + "hint": "默认为两分钟,根据需要修改。如果在这个时间内图片未能生成完毕,则终止本次请求,并发送提示消息。" }, "max_concurrent_tasks": { "type": "int", "description": "最大并发任务数", "default": 10, - "hint": "根据显存大小进行设定,防止 OOM" + "hint": "决定同一时间能处理的AI生图请求数量,请根据GPU显存大小和其他AI生图设置来酌情设定,免得在高频AI生图请求下爆显存导致程序运行缓慢甚至卡死" }, "enable_generate_prompt": { "type": "bool", "description": "启用使用LLM生成正向提示词", "default": true, - "hint": "设置为true时启用" + "hint": "设置为true时启用,开启时,当使用sd gen XXXX指令时,将XXXX先发送给LLM,再由LLM来生成正向提示词;关闭时,XXXX内容将直接作为提示词送入Stable diffusion" }, "enable_upscale": { "type": "bool", @@ -39,19 +39,29 @@ "type": "bool", "description": "启用输出正向提示词", "default": false, - "hint": "设置为true时启用" + "hint": "设置为true时启用,开启时,用户发起AI生图请求后,将发送一条消息,内容为送入到Stable diffusion的正向提示词" }, "positive_prompt_global": { "type": "string", - "description": "全局正面提示词", + "description": "全局正向提示词", "default": "", - "hint": "会自动附加到所有生成请求" + "hint": "会自动附加到所有AI生图请求的提示词词组中" + }, + + "enable_positive_prompt_add_in_head_or_tail": { + "type": "bool", + "description": "加在头还是加在尾?", + "default": true, + "hint": "设置为true时,全局提示词将会附着在用户输入的提示词组的开头,起到最大权重,如定义画风、设置安全等级。否则附着在尾部,权重偏低,适合用于修饰画面、提高出图质量、设定不重要的背景等。根据开关情况,记得在全局提示词的头部或尾部留逗号,免得最终的提示词黏在一起" + }, + + "negative_prompt_global": { "type": "string", "description": "全局负面提示词", - "default": "(worst quality, low quality:1.4), deformed, bad anatomy", - "hint": "会自动附加到所有生成请求" + "default": "", + "hint": "用户只能在QQ等操作界面中只能输入正向提示词,无法输入负面提示词。所以请在这里设定全局负面提示词,它会自动附加到AI生图请求中,用于降低画面中特定的元素比例。" }, "default_params": { "type": "object", @@ -61,21 +71,17 @@ "type": "int", "description": "图像宽度", "default": 512, - "options": [ - 512, - 768, - 1024 - ] + "min": 1, + "max": 2048, + "hint": "应当填入1-2048之间的整数" }, "height": { "type": "int", "description": "图像高度", "default": 512, - "options": [ - 512, - 768, - 1024 - ] + "min": 1, + "max": 2048, + "hint": "应当填入1-2048之间的整数" }, "steps": { "type": "int", @@ -113,7 +119,7 @@ }, "batch_size": { "type": "int", - "description": "每批数量", + "description": "每一次轮生成的图片数量", "default": 1 }, "n_iter": { @@ -134,5 +140,12 @@ "description": "LMM生成提示词时的附加限制", "default": "", "hint": "屏蔽色情内容等, 例如`任何被判断为色情的提示词都应该被替换,避免出现色情内容`" + }, + "replace_space": { + "type": "string", + "description": "用于替代提示词中空格的字符", + "default": "~", + "hint": "因Astrbot底层原因,读取到提示词中的空格时会发生中断,因此需要将所有空格替换为另一个字符来绕开这个限制,在将提示词组送入AI生图软件前,它最终会被重新处理为空格。因此,请在此处填入一个必定不会出现在提示词中的字符,而你在写提示词时,也要将所有的空格都替换为这个字符,此处默认为英文波浪号“~”,且不得为空。" + } } diff --git a/main.py b/main.py index 1bfbd7c..9b0a0ba 100644 --- a/main.py +++ b/main.py @@ -5,6 +5,7 @@ from astrbot.api.all import * + TEMP_PATH = os.path.abspath("data/temp") @register("SDGen", "buding(AstrBot)", "Stable Diffusion图像生成器", "1.1.2") @@ -114,9 +115,13 @@ async def _generate_payload(self, prompt: str) -> dict: def _trans_prompt(self, prompt: str) -> str: """ - 替换提示词中的所有下划线为空格 + 将提示词中的“用于替代空格的字符”替换为为空格 """ - return prompt.replace("_", " ") + replace_space = self.config.get("replace_space") + return prompt.replace(replace_space, " ") + + + async def _generate_prompt(self, prompt: str) -> str: provider = self.context.get_using_provider() @@ -296,12 +301,23 @@ async def generate_image(self, event: AstrMessageEvent, prompt: str): yield event.plain_result("🖌️ 生成图像阶段,这可能需要一段时间...") # 生成提示词 + if self.config.get("enable_generate_prompt"): generated_prompt = await self._generate_prompt(prompt) logger.debug(f"LLM generated prompt: {generated_prompt}") - positive_prompt = self.config.get("positive_prompt_global", "") + generated_prompt + enable_positive_prompt_add_in_head_or_tail = self.config.get("enable_positive_prompt_add_in_head_or_tail",True) + if enable_positive_prompt_add_in_head_or_tail: + positive_prompt = self.config.get("positive_prompt_global", "") + generated_prompt + + else: + positive_prompt = generated_prompt + self.config.get("positive_prompt_global", "") else: - positive_prompt = self.config.get("positive_prompt_global", "") + self._trans_prompt(prompt) + enable_positive_prompt_add_in_head_or_tail = self.config.get("enable_positive_prompt_add_in_head_or_tail",True) + if enable_positive_prompt_add_in_head_or_tail: + positive_prompt = self.config.get("positive_prompt_global", "") + self._trans_prompt(prompt) + else: + positive_prompt = self._trans_prompt(prompt) + self.config.get("positive_prompt_global", "") + #输出正向提示词 if self.config.get("enable_show_positive_prompt", False): @@ -502,19 +518,19 @@ async def show_help(self, event: AstrMessageEvent): "- `/sd help`:显示本帮助信息。", "", "🔧 **高级功能指令**:", - "- `/sd verbose`:切换详细输出模式,用于显示图像生成步骤。", + "- `/sd verbose`:切换详细输出模式,用于实时告知目前AI生图进行到了哪个阶段。", "- `/sd upscale`:切换图像增强模式(用于超分辨率放大或高分修复)。", - "- `/sd LLM`:切换是否使用 LLM 自动生成提示词。", - "- `/sd prompt`:切换是否在生成过程显示正向提示词。", - "- `/sd timeout [秒数]`:设置连接超时时间(范围:10 到 300 秒)。", - "- `/sd res [高度] [宽度]`:设置图像生成的分辨率(支持: 512, 768, 1024)。", + "- `/sd LLM`:在使用/sd gen指令时,将内容先发送给LLM,再由LLM来生成正向提示词", + "- `/sd prompt`:开启时,用户发起AI生图请求后,将发送一条消息,内容为送入到Stable diffusion的正向提示词", + "- `/sd timeout [秒数]`:设置连接超时时间(建议范围:10 到 300 秒)。", + "- `/sd res [宽度] [高度]`:设置图像生成的分辨率(高度和宽度均支持:1-2048之间的任意整数)。", "- `/sd step [步数]`:设置图像生成的步数(范围:10 到 50 步)。", - "- `/sd batch [数量]`:设置生成图像的批数量(范围: 1 到 10 张)。" + "- `/sd batch [数量]`:设置发出AI生图请求后,每轮生成的图片数量(范围: 1 到 10 张)。" "- `/sd iter [次数]`:设置迭代次数(范围: 1 到 5 次)。" "", "🖼️ **基本模型与微调模型指令**:", "- `/sd model list`:列出 WebUI 当前可用的模型。", - "- `/sd model set [索引]`:根据索引设置模型,索引可通过 `model list` 查询。", + "- `/sd model set [索引]`:利用索引设置模型,索引可通过 `model list` 查询。", "- `/sd lora`:列出所有可用的 LoRA 模型。", "- `/sd embedding`:显示所有已加载的 Embedding 模型。", "", @@ -525,25 +541,25 @@ async def show_help(self, event: AstrMessageEvent): "- `/sd upscaler set [索引]`:根据索引设置上采样算法。", "", "ℹ️ **注意事项**:", - "- 如启用自动生成提示词功能,则会使用 LLM 根据提供的信息随机生成提示词。", - "- 如未启用自动生成提示词功能,若自定义的提示词包含空格,则应使用 `_` 替代提示词中的空格。", + "- 如启用自动生成提示词功能,则会使用 LLM 利用提供的内容来生成提示词。", + "- 如未启用自动生成提示词功能,若提供的自定义提示词中包含空格,则应使用 “~”(英文波浪号) 替代所有提示词中的空格,否则输入的自定义提示词组将在空格处中断。你可以在配置中修改想使用的字符。", "- 模型、采样器和其他资源的索引需要使用对应 `list` 命令获取后设置!", ] yield event.plain_result("\n".join(help_msg)) @sd.command("res") - async def set_resolution(self, event: AstrMessageEvent, height: int, width: int): + async def set_resolution(self, event: AstrMessageEvent, width: int,height: int ): """设置分辨率""" try: - if height not in [512, 768, 1024] or width not in [512, 768, 1024]: - yield event.plain_result("⚠️ 分辨率仅支持: 512, 768, 1024") + if not isinstance(height, int) or not isinstance(width, int) or height < 1 or width < 1 or height > 2048 or width > 2048: + yield event.plain_result("⚠️ 分辨率仅支持:1-2048之间的任意整数") return self.config["default_params"]["height"] = height self.config["default_params"]["width"] = width self.config.save_config() - yield event.plain_result(f"✅ 分辨率已设置为: {width}x{height}") + yield event.plain_result(f"✅ 图像生成的分辨率已设置为: 宽度——{width},高度——{height}") except Exception as e: logger.error(f"设置分辨率失败: {e}") yield event.plain_result("❌ 设置分辨率失败,请检查日志")