Skip to content

Commit

Permalink
Chunk response
Browse files Browse the repository at this point in the history
  • Loading branch information
smartinio committed Jun 26, 2024
1 parent f2a3733 commit 508e3dc
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 18 deletions.
47 changes: 29 additions & 18 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { createLog } from "./logger.ts";
import { shutdown } from "./shutdown.ts";
import { retry } from "./retry.ts";
import { ContentType, supportedContentTypes } from "./ai.ts";
import { chunkString } from "./strings.ts";

// todo: Don't hardcode these role ids
const AI_CURIOUS_ROLE_IDS = [1098370802526724206n, 1123952489562132540n];
Expand Down Expand Up @@ -46,6 +47,8 @@ const getProvider = async (channelId: bigint): Promise<Provider> => {

export const deployment = new Date().toISOString();

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

const bot = createBot({
token: DISCORD_TOKEN,
intents: Intents.GuildMessages | Intents.MessageContent,
Expand Down Expand Up @@ -91,36 +94,44 @@ const bot = createBot({

bot.helpers.startTyping(channelId);

const respond = (
const respond = async (
response: string | { answer: string; imageUrl?: string },
{ finished = true }: { finished?: boolean } = {},
) =>
retry(async () => {
log.info("Sending response", { response });
) => {
log.info("Sending response", { response });

const embeds = typeof response !== "string" && response.imageUrl
? [{ image: { url: response.imageUrl } }]
: undefined;

const embeds = typeof response !== "string" && response.imageUrl
? [{ image: { url: response.imageUrl } }]
: undefined;
const answer = typeof response === "string"
? response
: response.answer;

const answer = typeof response === "string"
? response
: response.answer;
const prefix = `<@${authorId}> `;
const chunks = chunkString(answer, 2000 - prefix.length);

try {
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];

try {
await retry(() =>
bot.helpers.sendMessage(channelId, {
embeds,
content: `<@${authorId}> ${answer}`,
content: i === 0 ? `${prefix}${chunk}` : chunk,
})
);
} catch (error: unknown) {
log.error("Failed sending response to Discord", {
errorMessage: (error as Error).message,
});

await sleep(500);
}
} catch (error: unknown) {
log.error("Failed sending response to Discord", {
errorMessage: (error as Error).message,
});
}

if (finished) shutdown.allow();
});
if (finished) shutdown.allow();
};

if (!member?.roles?.some((role) => AI_CURIOUS_ROLE_IDS.includes(role))) {
return respond(
Expand Down
34 changes: 34 additions & 0 deletions strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const chunkString = (str: string, maxChunkSize = 2000) => {
const chunks = [];
let start = 0;

while (start < str.length) {
// Determine the end of the chunk
let end = start + maxChunkSize;

// If end exceeds the string length, adjust it to the end of the string
if (end >= str.length) {
chunks.push(str.slice(start));
break;
}

// If the character at the end index is not a whitespace, find the nearest whitespace before it
if (str[end] !== " " && str[end] !== "\n" && str[end] !== "\t") {
const lastWhitespace = str.lastIndexOf(" ", end);
if (lastWhitespace > start) {
end = lastWhitespace;
} else {
// If no whitespace found, use the max chunk size (this case is rare)
end = start + maxChunkSize;
}
}

// Push the chunk to the array
chunks.push(str.slice(start, end));

// Move the start index to the end of the current chunk
start = end + 1;
}

return chunks;
};

0 comments on commit 508e3dc

Please sign in to comment.