[{"id":"image_gen_desc","user_id":"e1491f4c-c762-4886-87a4-1dda2db4fcd8","name":"Image gen","meta":{"description":"Anima model image gen desc","manifest":{}},"access_grants":[],"updated_at":1776549288,"created_at":1776449372,"user":null,"write_access":true,"content":"import os\nimport requests\nimport math\nimport json\nfrom datetime import datetime\nfrom pydantic import BaseModel, Field\nfrom open_webui.models.users import UserModel\nfrom open_webui.routers.images import (\n    image_generations,\n    image_edits,\n    CreateImageForm,\n    EditImageForm,\n)\nfrom fastapi import Request\nimport logging\nfrom open_webui.models.chats import Chats\n\n\nclass Tools:\n    class UserValves(BaseModel):\n        total_pixels: int = Field(\n            default=2073600,\n            description=\"Pixels count\",\n        )\n        pass\n\n    def __init__(self):\n        self.valves = self.UserValves()\n        self.logger = logging.getLogger(__name__)\n        pass\n\n    def get_image_generation_prompting_rules(self, __user__: dict = {}) -> str:\n        \"\"\"\n        Get prompting rules for active model for image generation. Must call it before call image generation\n        \"\"\"\n\n        result = \"\"\"\n# Prompting\nThe model is trained on Danbooru-style tags, natural language captions, and combinations of tags and captions.\n- Use lowercase for tags, and spaces instead of underscores. Score tags are the only tags that use underscores.\n- Recommended positive prefix: \"masterpiece, best quality, score_7, safe, \"\n- Recommended negative: \"worst quality, low quality, score_1, score_2, score_3, artist name\"\n- When using a tag that is different between Danbooru and Gelbooru, prefer the Gelbooru version.\n- Model also trained on NSFW content\n- Text allowed, but only english\n## Tag order\n[quality/meta/year/safety tags] [1girl/1boy/1other etc] [character] [series] [artist] [general tags]\nWithin each tag section, the tags can be in arbitrary order.\n## Quality tags\nHuman score based: masterpiece, best quality, good quality, normal quality, low quality, worst quality\nPonyV7 aesthetic model based: score_9, score_8, ..., score_1\n\nYou can use either the human score quality tags, the aesthetic model tags, both together, or neither. All combinations work.\n\n## Time period tags\nSpecific year: year 2025, year 2024, ...\n\nPeriod: newest, recent, mid, early, old\n\n## Meta tags\nhighres, absurdres, anime screenshot, jpeg artifacts, official art, etc\n\n## Safety tags\nsafe, sensitive, nsfw, explicit\n\n## Artist tags\nPrefix artist with @. E.g. \"@big chungus\". **You must put @ in front of the artist.** The effect will be very weak if you don't.\n\n## Full tag example\nyear 2025, newest, normal quality, score_5, highres, safe, 1girl, oomuro sakurako, yuru yuri, @nnn yryr, smile, brown hair, hat, solo, fur-trimmed gloves, open mouth, long hair, gift box, fang, skirt, red gloves, blunt bangs, gloves, one eye closed, shirt, brown eyes, santa costume, red hat, skin fang, twitter username, white background, holding bag, fur trim, simple background, brown skirt, bag, gift bag, looking at viewer, santa hat, ;d, red shirt, box, gift, fur-trimmed headwear, holding, red capelet, holding box, capelet\n## Tag dropout\nThe model was trained with random tag dropout. You don't need to include every single relevant tag for the image.\n## Dataset tags\nTo improve style and content diversity, the model was additionally trained on two non-anime datasets: LAION-POP (specifically the ye-pop version) and DeviantArt. Both were filtered to exclude photos. Because these datasets are qualitatively different from anime datasets, captions from them have been labeled with a \"dataset tag\". This occurs at the very beginning of a prompt followed by a newline. Optionally, the second line can contain either the image alt-text (ye-pop) or the title of the work (DeviantArt).\n        \"\"\"\n        return result\n\n    async def generate_image(\n        self,\n        prompt: str,\n        negative_prompt: str = \"\",\n        aspect_ratio: str = \"1:1\",\n        __request__: Request = None,\n        __user__: dict = None,\n        __event_emitter__: callable = None,\n        __chat_id__: str = None,\n        __message_id__: str = None,\n    ) -> str:\n        \"\"\"\n        Generate an image based on a text prompt.\n\n        :param prompt: A detailed description of the image to generate\n        :param negative_prompt: A negative prompt\n        :param aspect_ratio: Image aspect ratio in format `width:height`\n        :return: Confirmation that the image was generated, or an error message\n        \"\"\"\n        if __request__ is None:\n            return json.dumps({\"error\": \"Request context not available\"})\n\n        if negative_prompt is None or negative_prompt is \"\":\n            negative_prompt = \"worst quality, low quality, score_1, score_2, score_3, blurry, jpeg artifacts, sepia, text, watermarks\"\n\n        try:\n            user = UserModel(**__user__) if __user__ else None\n\n            if not (aspect_ratio and \":\" in aspect_ratio):\n                aspect_ratio = \"1:1\"\n\n            width_v, height_v = tuple(map(int, aspect_ratio.split(\":\")))\n            width = int(\n                math.sqrt(__user__[\"valves\"].total_pixels)\n                / (width_v + height_v)\n                * width_v\n                / 2\n                * 2\n            )\n            height = int(\n                math.sqrt(self.valves.total_pixels)\n                / (width_v + height_v)\n                * height_v\n                / 2\n                * 2\n            )\n\n            images = await image_generations(\n                request=__request__,\n                form_data=CreateImageForm(\n                    prompt=prompt,\n                    negative_prompt=negative_prompt,\n                    size=f\"{width}x{height}\",\n                ),\n                user=user,\n            )\n\n            # Prepare file entries for the images\n            image_files = [{\"type\": \"image\", \"url\": img[\"url\"]} for img in images]\n\n            # Persist files to DB if chat context is available\n            if __chat_id__ and __message_id__ and images:\n                db_files = Chats.add_message_files_by_id_and_message_id(\n                    __chat_id__,\n                    __message_id__,\n                    image_files,\n                )\n                if db_files is not None:\n                    image_files = db_files\n\n            # Emit the images to the UI if event emitter is available\n            if __event_emitter__ and image_files:\n                # await __event_emitter__(\n                #    {\n                #        \"type\": \"chat:message:files\",\n                #        \"data\": {\n                #            \"files\": image_files,\n                #        },\n                #    }\n                # )\n                # Return a message indicating the image is already displayed\n                return json.dumps(\n                    {\n                        \"status\": \"success\",\n                        \"message\": \"The image has been successfully generated and you must embed it as Markdown image `![](<images[].url>)`\",\n                        \"images\": images,\n                    },\n                    ensure_ascii=False,\n                )\n\n            return json.dumps(\n                {\"status\": \"success\", \"images\": images}, ensure_ascii=False\n            )\n        except Exception as e:\n            self.logger.exception(f\"generate_image error: {e}\")\n            return json.dumps({\"error\": str(e)})\n","specs":[{"name":"generate_image","description":"Generate an image based on a text prompt.","parameters":{"properties":{"prompt":{"description":"A detailed description of the image to generate","type":"string"},"negative_prompt":{"default":"","description":"A negative prompt","type":"string"},"aspect_ratio":{"default":"1:1","description":"Image aspect ratio in format `width:height`","type":"string"}},"required":["prompt"],"type":"object"}},{"name":"get_image_generation_prompting_rules","description":"Get prompting rules for active model for image generation. Must call it before call image generation","parameters":{"properties":{},"type":"object"}}]}]