Files
AEmotionStudio-ComfyUI-Disc…/bot/cogs/generate.py
T

121 lines
4.3 KiB
Python

import discord
from discord import app_commands
from discord.ext import commands
import logging
import json
from pathlib import Path
from ..embeds.builders import EmbedBuilder
from ..services.permissions import require_permission, Permissions
from shared.workflow import WorkflowBuilder
logger = logging.getLogger(__name__)
class GenerateCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(name="generate", description="Generate an image using ComfyUI")
@app_commands.describe(
prompt="The positive prompt to generate",
negative_prompt="Aspects to avoid (optional)",
seed="Seed for generation (optional)",
steps="Number of steps (optional)",
cfg="CFG Scale (optional)",
delivery="Delivery method (channel or dm)"
)
@app_commands.choices(delivery=[
app_commands.Choice(name="Current Channel", value="channel"),
app_commands.Choice(name="Direct Message", value="dm")
])
@require_permission(Permissions.USER.value)
async def generate(self, interaction: discord.Interaction,
prompt: str,
negative_prompt: str = "",
seed: int = None,
steps: int = None,
cfg: float = None,
delivery: app_commands.Choice[str] = None):
await interaction.response.defer()
# Load default workflow
# TODO: Move this path to config or database
workflow_path = Path(__file__).parent.parent / "data" / "default_workflow_api.json"
if not workflow_path.exists():
await interaction.followup.send("❌ Error: Default workflow not found.", ephemeral=True)
return
try:
with open(workflow_path, "r") as f:
workflow_json = json.load(f)
except Exception as e:
logger.error(f"Failed to load workflow: {e}")
await interaction.followup.send("❌ Error: Failed to load workflow configuration.", ephemeral=True)
return
# Prepare parameters for tracking
parameters = {
"seed": seed,
"steps": steps,
"cfg": cfg
}
# Modify workflow
builder = WorkflowBuilder(workflow_json)
builder.set_prompt(prompt, negative_prompt)
if seed is not None:
builder.set_seed(seed)
else:
# Random seed if not provided
import random
generated_seed = random.randint(1, 1000000000000000)
builder.set_seed(generated_seed)
parameters["seed"] = generated_seed # Track actual seed
if steps is not None:
builder.set_steps(steps)
if cfg is not None:
builder.set_cfg(cfg)
final_workflow = builder.get_workflow()
# Determine delivery method
delivery_method = delivery.value if delivery else "channel"
# Check server context
server_id = str(interaction.guild_id) if interaction.guild else None
channel_id = str(interaction.channel_id)
try:
# Create Job
job = await self.bot.job_manager.create_job(
user_discord_id=str(interaction.user.id),
workflow=final_workflow,
positive_prompt=prompt,
negative_prompt=negative_prompt,
parameters=parameters,
server_discord_id=server_id,
channel_id=channel_id,
delivery_type=delivery_method
)
# Send Queued Embed
embed = EmbedBuilder.job_queued(job)
await interaction.followup.send(embed=embed)
# Store the interaction message ID if we want to update it later
# (JobManager could use this to update the specific message)
original_message = await interaction.original_response()
await self.bot.repository.update_job_message(job.prompt_id, str(original_message.id))
except Exception as e:
logger.error(f"Failed to start generation: {e}")
await interaction.followup.send(f"❌ Error starting generation: {str(e)}", ephemeral=True)
async def setup(bot):
await bot.add_cog(GenerateCog(bot))