Kilvoctu / aiyabot

A neat Discord bot for AUTOMATIC1111's Web UI
GNU General Public License v2.0
310 stars 77 forks source link

bot should reply to message where it lists options #51

Closed carterprince closed 1 year ago

carterprince commented 2 years ago

The bot should both ping the user who made the request as well as reply to its original message where it confirms the request and lists the settings. This would make it easier to discern which prompt/options resulted in the image, for instance when sending many different prompts in the same channel.

Kilvoctu commented 2 years ago

I'm not sure exactly what you're asking.

I think the process you want is this? -user does a /draw command -aiya confirms the /draw command with a reply -when aiya provides the output image, that message is a reply to the previous message

carterprince commented 2 years ago

when aiya provides the output image, that message is a reply to the previous message

@Kilvoctu Correct. But it still pings the user who requested the image. I successfully modified the bot to get it to do this after some trial and error.

It should something like this (the message should mention me but I removed that): image

Kilvoctu commented 2 years ago

Cool, how did you do it? I'll push an update if everything looks good with the modifications, or you can open a PR.

carterprince commented 2 years ago

I'm not sure this is the best way to do it, but I changed this part of stablecog.py:

#setup the queue
if queuehandler.GlobalQueue.dream_thread.is_alive():
        user_already_in_queue = False
    for queue_object in queuehandler.GlobalQueue.queue:
        if queue_object.ctx.author.id == ctx.author.id:
            user_already_in_queue = True
            break
    if user_already_in_queue:
        await ctx.send_response(content=f'Please wait! You\'re queued up.', ephemeral=True)
    else:
        req = await ctx.send_response(f'<@{ctx.author.id}>, {self.wait_message[random.randint(0, message_row_count)]}\nQueue: ``{len(queuehandler.GlobalQueue.queue)}`` - ``{simple_prompt}``\nSteps: ``{steps}`` - Seed: ``{seed}``{append_options}')
        req = await req.original_response()
        queuehandler.GlobalQueue.queue.append(queuehandler.DrawObject(ctx, prompt, negative_prompt, data_model, steps, height, width, guidance_scale, sampler, seed, strength, init_image, copy_command, count, style, facefix, simple_prompt, highres_fix, req))
else:
    req = await ctx.send_response(f'<@{ctx.author.id}>, {self.wait_message[random.randint(0, message_row_count)]}\nQueue: ``{len(queuehandler.GlobalQueue.queue)}`` - ``{simple_prompt}``\nSteps: ``{steps}`` - Seed: ``{seed}``{append_options}')
    req = await req.original_response()
    await queuehandler.process_dream(self, queuehandler.DrawObject(ctx, prompt, negative_prompt, data_model, steps, height, width, guidance_scale, sampler, seed, strength, init_image, copy_command, count, style, facefix, simple_prompt, highres_fix, req))

You can see, I first store the response message from the bot in a variable req (it stands for request message), pass req into queuehandler.DrawObject as another attribute. Therefore you also have to add the req field to queuehandler.py

#the queue object for txt2image and img2img
class DrawObject:
    def __init__(self, ctx, prompt, negative_prompt, data_model, steps, height, width, guidance_scale, sampler, seed,
                 strength, init_image, copy_command, batch_count, style, facefix, simple_prompt, highres_fix, req):
        self.ctx = ctx
        self.prompt = prompt
        self.negative_prompt = negative_prompt
        self.data_model = data_model
        self.steps = steps
        self.height = height
        self.width = width
        self.guidance_scale = guidance_scale
        self.sampler = sampler
        self.seed = seed
        self.strength = strength
        self.init_image = init_image
        self.copy_command = copy_command
        self.batch_count = batch_count
        self.style = style
        self.facefix = facefix
        self.simple_prompt = simple_prompt
        self.highres_fix = highres_fix
        self.req = req

Then, when sending the final image, use queue_object.req.reply instead of queue_object.ctx.channel.send:


                buffer.seek(0)

            files = [discord.File(fp=buffer, filename=f'{queue_object.seed}-{i}.png') for (i, buffer) in enumerate(buffer_handles)]
            event_loop.create_task(queue_object.req.reply(content=f'<@{queue_object.ctx.author.id}>', embed=embed, files=files))

    except Exception as e:
        embed = discord.Embed(title='txt2img failed', description=f'{e}\n{traceback.print_exc()}',

I'm hesitant to make a PR because I also modified other parts of the code. But that's how I did it.

Kilvoctu commented 2 years ago

Thanks for that! My journey with Python began with this project, so I don't know what's best. And the code changes drastically and frequently as I learn the language 😅

My current goal is to get PR #52 working, because if that's done I'll have Discord buttons to work with. My idea was one button could be used to review the prompt/options.

I'm having some trouble with it, though, so if that fails I can use this. 👍 Also I see highres_fix in there 😄

carterprince commented 2 years ago

Yeah, I thought that since AUTOMATIC1111's api can take an enable_hr option for txt2img requests, why not just add that as a simple option?

So to make enable_hr (highres fix in the webUI) useful, I also increased the available range of width and height. highres_fix basically just gets added directly into the request payload as a boolean. But you also have to set a default value for denoising strength, which was originally set to None, so I just changed that to 0.7 in the code as well.

carterprince commented 2 years ago

Great software by the way, it's easy to tinker with and figure out what everything does.

Kilvoctu commented 2 years ago

Yeah, since I'm new I try to keep it easy to understand and use lots of comments. It was originally forked from the awesome and very well-written https://github.com/harubaru/discord-stable-diffusion bot, which served as a great starting point to learn. I've been having fun for the last month tinkering around, too; right now currently trying wrap my head around how the queue interacts with the event loop.

Kilvoctu commented 1 year ago

My current goal is to get PR #52 working, because if that's done I'll have Discord buttons to work with. My idea was one button could be used to review the prompt/options.

Since these events transpired, I think I won't have bot reply to its initial message.

56 provides a button after each generated image to show information for the prompt, options and command.

While I didn't implement your request, I really appreciate your using aiya and providing feedback 👍👍