Tonic-bot / app.py
not-lain's picture
Synced repo using 'sync_with_huggingface' Github Action
560c226
import gradio as gr
import gradio_client as grc
import dotenv
import discord
from discord.ext import commands
import os
import threading
from threading import Event
from typing import Literal,Optional
import asyncio
event = Event()
dotenv.load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="/",intents=intents)
# limit command to channel_name
channel_name = "🤸🏻♀anime"
# Limited to only 25 models
models = Literal['3Guofeng3_v34.safetensors [50f420de]',
'absolutereality_V16.safetensors [37db0fc3]',
'absolutereality_v181.safetensors [3d9d4d2b]',
'anythingV5_PrtRE.safetensors [893e49b9]',
'blazing_drive_v10g.safetensors [ca1c1eab]',
'cetusMix_Version35.safetensors [de2f2560]',
'childrensStories_v1ToonAnime.safetensors [2ec7b88b]',
'Counterfeit_v30.safetensors [9e2a8f19]',
'cuteyukimixAdorable_midchapter3.safetensors [04bdffe6]',
'cyberrealistic_v33.safetensors [82b0d085]',
'dreamlike-anime-1.0.safetensors [4520e090]',
'dreamlike-photoreal-2.0.safetensors [fdcf65e7]',
'dreamshaper_8.safetensors [9d40847d]',
'edgeOfRealism_eorV20.safetensors [3ed5de15]',
'elldreths-vivid-mix.safetensors [342d9d26]',
'epicrealism_naturalSinRC1VAE.safetensors [90a4c676]',
'juggernaut_aftermath.safetensors [5e20c455]',
'lofi_v4.safetensors [ccc204d6]',
'lyriel_v16.safetensors [68fceea2]',
'neverendingDream_v122.safetensors [f964ceeb]',
'openjourney_V4.ckpt [ca2f377f]',
'pastelMixStylizedAnime_pruned_fp16.safetensors [793a26e8]',
'Realistic_Vision_V5.0.safetensors [614d1063]',
'revAnimated_v122.safetensors [3f4fefd9]',
'rundiffusionFX25D_v10.safetensors [cd12b0ee]',
]
@bot.event
async def on_ready():
print(f"logged as {bot.user}")
event.set()
@bot.hybrid_command(
name="ping",
description="ping")
async def ping(ctx):
await ctx.reply(f"{bot.latency*1000:.0f}ms")
def get_client(session: Optional[str] = None) -> grc.Client:
client = grc.Client("prodia/fast-stable-diffusion")
if session:
client.session_hash = session
return client
async def text2img(pos_prompt: str, neg_promt: str = "",model="absolutereality_v181.safetensors [3d9d4d2b]"):
"""
Generates an image based on the given positive prompt and optional negative prompt.
Args:
pos_prompt (str): The positive prompt to generate the image.
neg_prompt (str, optional): The negative prompt to generate the image. Defaults to "".
Returns:
The generated image.
"""
txt2img_conf = {
"parameter_11" : pos_prompt,
"parameter_12" : neg_promt,
"stable_diffusion_checkpoint" : model,
"sampling_steps" : 25,
"sampling_method" : "DPM++ 2M Karras",
"cfg_scale" : 7,
"width" : 512,
"height" : 512,
"seed" : -1
}
loop = asyncio.get_running_loop()
client = await loop.run_in_executor(None, get_client, None)
txt2img_args = txt2img_conf.values()
job = client.predict(*txt2img_args, fn_index=0)
return job
async def img2img(pos_prompt: str, neg_promt: str = "", img = None,model="absolutereality_v181.safetensors [3d9d4d2b]"):
"""
Generates an image based on the given positive prompt, optional negative prompt and image path.
Args:
pos_prompt (str): The positive prompt for the image generation.
neg_promt (str, optional): The negative prompt for the image generation. Defaults to "".
img (filepath or URL to image): The input image for the image generation. Defaults to None.
Returns:
The generated image.
"""
img2img_conf = {
"parameter_52" : img,
"denoising_strength" : 0.7,
"parameter_44" : pos_prompt,
"parameter_45" : neg_promt,
"stable_diffusion_checkpoint" : model,
"sampling_steps" : 25,
"sampling_method" : "DPM++ 2M Karras",
"cfg_scale" : 7,
"width" : 512,
"height" : 512,
"seed" : -1
}
loop = asyncio.get_running_loop()
client = await loop.run_in_executor(None, get_client, None)
img2img_args = img2img_conf.values()
job = client.predict(*img2img_args, fn_index=1)
return job
def run_dffusion(pos_prompt: str,neg_promt: str = "",img_url= "",model="absolutereality_v181.safetensors [3d9d4d2b]"):
"""Runs the diffusion model."""
if len(img_url) == 0:
# Support for text prompts
generated_image = text2img(pos_prompt, neg_promt,model)
else:
# Support for image prompts
generated_image = img2img(pos_prompt, neg_promt, img_url,model)
return generated_image
# AI prediction command
@bot.hybrid_command(
name="diffusion",
description="creates an AI generated image"
)
async def diffusion(ctx, pos_prompt: str="",neg_promt: str = "", img_url= None,improve : Literal["True","False"] = "True",model : models = "absolutereality_v181.safetensors [3d9d4d2b]"):
"""
AI command to generate images
"""
# if channel name is == channel_name
try:
if ctx.channel.name == channel_name:
await ctx.reply(f"Creating image for {ctx.author.mention} ...")
try :
# preparing the prediction before creating the thread
_improved_pos_prompt = "ultrarealistic,8k"
_improved_neg_promt = "3d, cartoon, (deformed eyes, nose, ears, nose), bad anatomy, ugly,blur"
pos_prompt =pos_prompt.strip()
neg_promt = neg_promt.strip()
# check if the user wants to improve the results
if improve == "True":
if len(pos_prompt) == 0:
pos_prompt = _improved_pos_prompt
elif pos_prompt[-1] != ",":
pos_prompt += ", " + _improved_pos_prompt
else:
pos_prompt += _improved_pos_prompt
if len(neg_promt) == 0:
neg_promt = _improved_neg_promt
elif neg_promt[-1] != ",":
neg_promt += ", " + _improved_neg_promt
else:
neg_promt += _improved_neg_promt
# need to make sure AI sends the first message
result = run_dffusion(pos_prompt , neg_promt,img_url,model=model)
await ctx.channel.send(file=discord.File(result))
except Exception as e:
await ctx.resepond(e)
else:
# TODO:
# tag the channel #channel_name
# create the channel if we can't find it, tag it and let the user know that we created it
await ctx.respond(f"""
use this command in the channel #falcon-180b-demo\nuse `/setup` to create the channel if it doesn't exist""")
except Exception as e:
await ctx.respond(e)
# setup create the channel for the bot
@bot.hybrid_command(
name="setup",
description="setup the bot")
async def setup(ctx):
"""
create the #channel_name channel
"""
# if channel falcon-180b-demo doesn't exist create it
if not discord.utils.get(ctx.guild.channels, name=channel_name):
await ctx.guild.create_text_channel(channel_name,category=ctx.channel.category)
await ctx.reply(channel_name)
else:
# TODO: tag the channel
await ctx.reply(f"{channel_name} channel already exist")
# running in thread
def run_bot():
if not DISCORD_TOKEN:
print("DISCORD_TOKEN NOT SET")
event.set()
else:
bot.run(DISCORD_TOKEN)
threading.Thread(target=run_bot).start()
event.wait()
with gr.Blocks() as iface :
gr.Markdown("# welcome to Tonic-bot")
iface.queue().launch()