eris/bot/txt2imgCommand.ts

118 lines
3.6 KiB
TypeScript
Raw Normal View History

2023-09-24 13:08:35 +00:00
import { CommandContext } from "grammy";
import { StatelessQuestion } from "grammy_stateless_question";
2023-10-15 19:13:38 +00:00
import { debug } from "std/log/mod.ts";
2023-09-23 18:49:05 +00:00
import { getConfig } from "../app/config.ts";
2023-09-24 13:08:35 +00:00
import { generationQueue } from "../app/generationQueue.ts";
import { formatUserChat } from "../utils/formatUserChat.ts";
2023-10-15 19:13:38 +00:00
import { ErisContext } from "./mod.ts";
2023-09-26 10:43:36 +00:00
import { getPngInfo, parsePngInfo, PngInfo } from "./parsePngInfo.ts";
import { adminStore } from "../app/adminStore.ts";
2023-09-10 18:56:17 +00:00
2023-09-24 13:08:35 +00:00
export const txt2imgQuestion = new StatelessQuestion<ErisContext>(
2023-09-10 23:59:33 +00:00
"txt2img",
async (ctx) => {
if (!ctx.message.text) return;
2023-09-11 16:03:07 +00:00
await txt2img(ctx, ctx.message.text, false);
2023-09-10 23:59:33 +00:00
},
);
2023-09-24 13:08:35 +00:00
export async function txt2imgCommand(ctx: CommandContext<ErisContext>) {
2023-09-10 23:59:33 +00:00
await txt2img(ctx, ctx.match, true);
}
2023-09-24 13:08:35 +00:00
async function txt2img(ctx: ErisContext, match: string, includeRepliedTo: boolean): Promise<void> {
2023-10-15 19:47:08 +00:00
if (!ctx.from || !ctx.message) {
return;
}
if (ctx.from.is_bot) {
2023-09-11 09:22:15 +00:00
return;
2023-09-10 18:56:17 +00:00
}
2023-09-10 23:59:33 +00:00
2023-09-22 02:59:22 +00:00
const config = await getConfig();
let priority = 0;
2023-09-22 02:59:22 +00:00
if (config.pausedReason != null) {
2023-09-24 19:58:09 +00:00
await ctx.reply(`I'm paused: ${config.pausedReason || "No reason given"}`, {
reply_to_message_id: ctx.message?.message_id,
});
2023-09-11 09:22:15 +00:00
return;
2023-09-10 18:56:17 +00:00
}
2023-09-10 23:59:33 +00:00
const adminEntry = await adminStore.get(["admins", ctx.from.id]);
2023-09-10 23:59:33 +00:00
if (adminEntry.versionstamp) {
priority = 1;
} else {
const jobs = await generationQueue.getAllJobs();
if (jobs.length >= config.maxJobs) {
await ctx.reply(`The queue is full. Try again later. (Max queue size: ${config.maxJobs})`, {
reply_to_message_id: ctx.message?.message_id,
});
return;
}
const userJobs = jobs.filter((job) => job.state.from.id === ctx.message?.from?.id);
if (userJobs.length >= config.maxUserJobs) {
await ctx.reply(`You already have ${userJobs.length} jobs in the queue. Try again later.`, {
reply_to_message_id: ctx.message?.message_id,
});
return;
}
2023-09-10 18:56:17 +00:00
}
2023-09-10 23:59:33 +00:00
2023-09-12 01:57:44 +00:00
let params: Partial<PngInfo> = {};
2023-09-11 20:43:12 +00:00
2023-09-10 23:59:33 +00:00
const repliedToMsg = ctx.message.reply_to_message;
2023-09-11 20:43:12 +00:00
if (includeRepliedTo && repliedToMsg?.document?.mime_type === "image/png") {
const file = await ctx.api.getFile(repliedToMsg.document.file_id);
const buffer = await fetch(file.getUrl()).then((resp) => resp.arrayBuffer());
params = parsePngInfo(getPngInfo(buffer) ?? "", params);
2023-09-11 20:43:12 +00:00
}
2023-09-10 23:59:33 +00:00
const repliedToText = repliedToMsg?.text || repliedToMsg?.caption;
const isReply = includeRepliedTo && repliedToText;
if (isReply) {
2023-09-11 16:03:07 +00:00
// TODO: remove bot command from replied to text
2023-09-16 11:49:12 +00:00
params = parsePngInfo(repliedToText, params);
2023-09-10 23:59:33 +00:00
}
2023-09-11 20:43:12 +00:00
params = parsePngInfo(match, params, true);
2023-09-11 20:43:12 +00:00
if (isReply) {
const parsedInfo = parsePngInfo(repliedToText, undefined, true);
if (parsedInfo.prompt !== params.prompt) {
params.seed = parsedInfo.seed ?? -1;
}
}
2023-09-10 18:56:17 +00:00
if (!params.prompt) {
2023-09-11 09:22:15 +00:00
await ctx.reply(
2023-09-10 23:59:33 +00:00
"Please tell me what you want to see." +
txt2imgQuestion.messageSuffixMarkdown(),
2023-09-24 19:58:09 +00:00
{
reply_markup: { force_reply: true, selective: true },
parse_mode: "Markdown",
reply_to_message_id: ctx.message?.message_id,
},
2023-09-10 23:59:33 +00:00
);
2023-09-11 09:22:15 +00:00
return;
2023-09-10 18:56:17 +00:00
}
2023-09-10 23:59:33 +00:00
2023-09-24 19:58:09 +00:00
const replyMessage = await ctx.reply("Accepted. You are now in queue.", {
reply_to_message_id: ctx.message?.message_id,
});
2023-09-10 23:59:33 +00:00
2023-09-22 02:59:22 +00:00
await generationQueue.pushJob({
2023-09-12 01:57:44 +00:00
task: { type: "txt2img", params },
from: ctx.message.from,
chat: ctx.message.chat,
2023-09-22 02:59:22 +00:00
requestMessage: ctx.message,
replyMessage: replyMessage,
}, { retryCount: 3, retryDelayMs: 10_000, priority: priority });
2023-09-10 23:59:33 +00:00
2023-10-15 19:13:38 +00:00
debug(`Generation (txt2img) enqueued for ${formatUserChat(ctx.message)}`);
2023-09-10 18:56:17 +00:00
}