125 lines
3.7 KiB
TypeScript
125 lines
3.7 KiB
TypeScript
import { MatrixClient, MsgType } from "matrix-js-sdk";
|
|
import type { ICallbackStore } from "../types.js";
|
|
import { config } from "../../config.js";
|
|
import { getTextGemini, getImageGemini } from "../../services/ai/ai.js";
|
|
import { alts } from "./alts.js";
|
|
import type { IAIInstructions } from "./types.js";
|
|
import { getUserById, getUserName } from "../../helpers.js";
|
|
import { prices } from "./prices.js";
|
|
import { state } from "../../store/store.js";
|
|
|
|
let client: MatrixClient;
|
|
|
|
const registerModuleAI = (
|
|
matrixClient: MatrixClient,
|
|
callbackStore: ICallbackStore,
|
|
) => {
|
|
client = matrixClient;
|
|
|
|
callbackStore.messageCallbacks.push({
|
|
startConditions: [`${config.app.triggerPrefix}ai`],
|
|
callbackFunc: onAI,
|
|
allowedRoles: ["USER", "MODERATOR", "ADMIN"],
|
|
});
|
|
callbackStore.messageCallbacks.push({
|
|
startConditions: [`${config.app.triggerPrefix}img `],
|
|
callbackFunc: onImageGen,
|
|
allowedRoles: ["USER", "MODERATOR", "ADMIN"],
|
|
});
|
|
};
|
|
|
|
const onAI = async (
|
|
text: string,
|
|
roomId: string,
|
|
sender: string,
|
|
repliedMessage?: string,
|
|
repliedSender?: string,
|
|
) => {
|
|
const user = getUserById(sender);
|
|
|
|
const date = Date.now();
|
|
let personality = config.app.ai.personalities[state.personality.index];
|
|
|
|
if (date > state.personality.startTime + (personality?.timeout ?? 0)) {
|
|
const randomInt = Math.floor(
|
|
Math.random() * config.app.ai.personalities.length,
|
|
);
|
|
state.personality = {
|
|
index: randomInt,
|
|
startTime: date,
|
|
};
|
|
client.setDisplayName(
|
|
`AsloBot (${config.app.ai.personalities[state.personality.index]?.personalityName})`,
|
|
);
|
|
}
|
|
|
|
personality = config.app.ai.personalities[state.personality.index];
|
|
|
|
let textMod = text.replace("!ai", "").trim().toLowerCase();
|
|
let instructions = {
|
|
prefferedLanguages: ["english", "slovak"],
|
|
users: alts.map((alt) => ({
|
|
names: alt.keys,
|
|
alt: alt.alt,
|
|
backstory: alt.id
|
|
? getUserById(`${alt.id}:${config.server}`).information
|
|
: undefined,
|
|
})),
|
|
aiPersonality: personality?.personality ?? "",
|
|
aiLikes: personality?.likes ?? "",
|
|
aiDislikes: personality?.dislikes ?? "",
|
|
} as IAIInstructions;
|
|
|
|
const username = getUserName(user);
|
|
let repliedUsername = "";
|
|
if (repliedSender) {
|
|
repliedUsername = getUserName(getUserById(repliedSender));
|
|
}
|
|
|
|
const responseAI = await getTextGemini(
|
|
instructions,
|
|
`${username}: ${textMod}`,
|
|
`${repliedUsername}: ${repliedMessage}`,
|
|
);
|
|
|
|
user.aiCost += responseAI.tokens * prices.text;
|
|
|
|
client.sendTextMessage(roomId, responseAI.text);
|
|
};
|
|
|
|
const onImageGen = async (text: string, roomId: string, sender: string) => {
|
|
const user = getUserById(sender);
|
|
|
|
let textMod = text.replace("!img", "").trim().toLowerCase();
|
|
alts.forEach((alt) => {
|
|
alt.keys.forEach((key) => {
|
|
textMod = textMod.replaceAll(key, alt.alt);
|
|
});
|
|
});
|
|
|
|
const responseAI = await getImageGemini(textMod);
|
|
|
|
user.aiCost += responseAI.tokens * prices.image;
|
|
if (!responseAI.image || responseAI.image.length < 10) {
|
|
return;
|
|
}
|
|
|
|
const imageName = `photo-img-gen.png`;
|
|
|
|
const uploadResult = await client.uploadContent(responseAI.image, {
|
|
type: "image/png",
|
|
name: imageName,
|
|
});
|
|
|
|
await client.sendMessage(roomId, {
|
|
msgtype: MsgType.Image,
|
|
body: imageName,
|
|
url: uploadResult.content_uri,
|
|
info: {
|
|
mimetype: "image/png",
|
|
size: responseAI.image.length,
|
|
},
|
|
});
|
|
};
|
|
|
|
export { registerModuleAI, onImageGen };
|