mirror of
https://github.com/uditkarode/bing-chat-telegram.git
synced 2025-02-22 01:02:13 +00:00
fix: make sure queue is always properly managed
This commit is contained in:
parent
bdfb91a604
commit
0fff450e38
122
src/ai.ts
122
src/ai.ts
@ -2,7 +2,7 @@ import { done, firstPos, queue } from "./queue.js";
|
||||
import { transformBingResponse } from "./transformers.js";
|
||||
import { ChatMessage } from "bing-chat";
|
||||
import { Context } from "telegraf";
|
||||
import { bold, fmt } from "telegraf/format";
|
||||
import { FmtString, bold, fmt } from "telegraf/format";
|
||||
import { Update } from "typegram";
|
||||
import { bingChat } from "./config.js";
|
||||
import pTimeout from "p-timeout";
|
||||
@ -14,7 +14,6 @@ const chats: Record<
|
||||
> = {};
|
||||
|
||||
export const variants = ["creative", "balanced", "precise"];
|
||||
|
||||
const defaultTimeoutMs = 50 * 1000;
|
||||
const defaultVariant = "Balanced";
|
||||
|
||||
@ -22,71 +21,86 @@ export async function ai(
|
||||
ctx: Context<Update>,
|
||||
prompt: string,
|
||||
): Promise<void | Message> {
|
||||
if (!prompt)
|
||||
return await ctx.reply(
|
||||
"No prompt provided! Please read /help for more information.",
|
||||
);
|
||||
|
||||
// set up the chat object in `chats`
|
||||
const chatId = ctx.chat!.id;
|
||||
chats[chatId] ||= { index: 1 };
|
||||
|
||||
const { pos, turn } = queue();
|
||||
|
||||
let message_id: number;
|
||||
async function edit(msg: string | FmtString) {
|
||||
await ctx.telegram.editMessageText(chatId, message_id, undefined, msg, {
|
||||
disable_web_page_preview: true,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
if (!prompt) {
|
||||
return await ctx.reply(
|
||||
"No prompt provided! Please read /help for more information.",
|
||||
);
|
||||
}
|
||||
|
||||
const chatId = ctx.chat!.id;
|
||||
chats[chatId] ||= { index: 1 };
|
||||
|
||||
const { pos, turn } = queue();
|
||||
// wait for our turn if we are not the first client in the queue
|
||||
if (pos > firstPos) {
|
||||
await ctx.reply(fmt`Queued at position: ${bold`${pos}`}`);
|
||||
await turn;
|
||||
}
|
||||
|
||||
const { message_id } = await ctx.reply(
|
||||
fmt`${bold`[${chats[chatId].index++}]`} Running prompt...`,
|
||||
message_id = (
|
||||
await ctx.reply(
|
||||
fmt`${bold`[${chats[chatId].index++}]`} Running prompt...`,
|
||||
)
|
||||
).message_id;
|
||||
|
||||
const bingRes = await pTimeout(
|
||||
bingChat.sendMessage(
|
||||
prompt,
|
||||
Object.assign({}, chats[chatId].res, {
|
||||
variant: chats[chatId].variant ?? defaultVariant,
|
||||
}),
|
||||
),
|
||||
{
|
||||
milliseconds: defaultTimeoutMs,
|
||||
fallback() {
|
||||
return new Error(
|
||||
`No response from Bing, waited ${defaultTimeoutMs / 1000} seconds`,
|
||||
);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
let bingRes: ChatMessage;
|
||||
try {
|
||||
bingRes = await pTimeout(
|
||||
bingChat.sendMessage(
|
||||
prompt,
|
||||
Object.assign({}, chats[chatId].res, {
|
||||
variant: chats[chatId].variant ?? defaultVariant,
|
||||
}),
|
||||
),
|
||||
{
|
||||
milliseconds: defaultTimeoutMs,
|
||||
message: `No response from Bing, waited ${
|
||||
defaultTimeoutMs / 1000
|
||||
} seconds`,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
return await ctx.reply((e as Error).message || "Something went wrong");
|
||||
// set the res to the chat object so the next message
|
||||
// can continue the same conversation
|
||||
if (!(bingRes instanceof Error)) {
|
||||
chats[chatId].res = bingRes;
|
||||
}
|
||||
|
||||
chats[chatId].res = bingRes;
|
||||
|
||||
const tgRes = (() => {
|
||||
if (bingRes.text === prompt) {
|
||||
// Bing Chat often replies with the exact prompt
|
||||
// in case it's unable to continue the conversation.
|
||||
return "Bing replied with the exact text as your prompt. This usually happens when the AI is unable to continue the conversation. Starting a new chat with /newchat is recommended.";
|
||||
}
|
||||
|
||||
if (!bingRes.text) {
|
||||
return "Received an empty response. Make sure the bot is set up properly and that you haven't crossed the daily message limit.";
|
||||
}
|
||||
|
||||
return transformBingResponse(bingRes);
|
||||
})();
|
||||
|
||||
await ctx.telegram.editMessageText(chatId, message_id, undefined, tgRes, {
|
||||
disable_web_page_preview: true,
|
||||
});
|
||||
await edit(getTgResponse(bingRes, prompt));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
await ctx.reply("Something went wrong!");
|
||||
} finally {
|
||||
done();
|
||||
await edit("Something went wrong!");
|
||||
}
|
||||
|
||||
// signal completion, let the next client proceed
|
||||
done();
|
||||
}
|
||||
|
||||
function getTgResponse(bingRes: ChatMessage | Error, prompt: string) {
|
||||
if (bingRes instanceof Error) {
|
||||
return bingRes.message;
|
||||
}
|
||||
|
||||
if (bingRes.text === prompt) {
|
||||
// Bing Chat often replies with the exact prompt
|
||||
// in case it's unable to continue the conversation.
|
||||
return "Bing replied with the exact text as your prompt. This usually happens when the AI is unable to continue the conversation. Starting a new chat with /newchat is recommended.";
|
||||
}
|
||||
|
||||
if (!bingRes.text) {
|
||||
return "Received an empty response. Make sure the bot is set up properly and that you haven't crossed the daily message limit.";
|
||||
}
|
||||
|
||||
return transformBingResponse(bingRes);
|
||||
}
|
||||
|
||||
export function newChat(chatId: number) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user