Rework AI
This commit is contained in:
parent
e46c4427cc
commit
aebee54562
10 changed files with 79 additions and 20 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "aslobot-matrix",
|
"name": "aslobot-matrix",
|
||||||
"version": "0.7.2",
|
"version": "0.8.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"author": "",
|
"author": "",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"baseUrl": "https://",
|
"baseUrl": "https://",
|
||||||
|
"server": "",
|
||||||
"userId": "@",
|
"userId": "@",
|
||||||
"authPath": "auth.json",
|
"authPath": "auth.json",
|
||||||
"storePath": "store.json",
|
"storePath": "store.json",
|
||||||
|
|
@ -25,7 +26,14 @@
|
||||||
"api": {
|
"api": {
|
||||||
"key": ""
|
"key": ""
|
||||||
},
|
},
|
||||||
"prompt": "Your name is Aslobot. Be concise, try to keep text as short as possible. Be helpful."
|
"personalities": [
|
||||||
|
{
|
||||||
|
"personality": "You are Aslobot. Be helpful. Be concise, keep text as short as possible.",
|
||||||
|
"likes": [],
|
||||||
|
"dislikes": [],
|
||||||
|
"timeout": 3600000
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@ import type { ICallbackStore } from "../types.js";
|
||||||
import { config } from "../../config.js";
|
import { config } from "../../config.js";
|
||||||
import { getTextGemini, getImageGemini } from "../../services/ai/ai.js";
|
import { getTextGemini, getImageGemini } from "../../services/ai/ai.js";
|
||||||
import { alts } from "./alts.js";
|
import { alts } from "./alts.js";
|
||||||
import type { IAdminInstructions, IAIAlt } from "./types.js";
|
import type { IAIInstructions } from "./types.js";
|
||||||
import { getUserById, getUserName } from "../../helpers.js";
|
import { getUserById, getUserName } from "../../helpers.js";
|
||||||
import { prices } from "./prices.js";
|
import { prices } from "./prices.js";
|
||||||
|
import { state } from "../../store/store.js";
|
||||||
|
|
||||||
let client: MatrixClient;
|
let client: MatrixClient;
|
||||||
|
|
||||||
|
|
@ -34,21 +35,41 @@ const onAI = async (text: string, roomId: string, sender: string) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let personality = config.app.ai.personalities[state.personality.index];
|
||||||
|
if (
|
||||||
|
Date.now() >
|
||||||
|
state.personality.startTime + (personality?.timeout ?? 0)
|
||||||
|
) {
|
||||||
|
const randomInt = Math.floor(
|
||||||
|
Math.random() * (config.app.ai.personalities.length + 1),
|
||||||
|
);
|
||||||
|
state.personality = {
|
||||||
|
index: randomInt,
|
||||||
|
startTime: Date.now(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
personality = config.app.ai.personalities[state.personality.index];
|
||||||
|
|
||||||
let textMod = text.replace("!ai", "").trim().toLowerCase();
|
let textMod = text.replace("!ai", "").trim().toLowerCase();
|
||||||
let instructions = {
|
let instructions = {
|
||||||
prefferedLanguages: ["english", "slovak"],
|
prefferedLanguages: ["english", "slovak"],
|
||||||
adminText: config.app.ai.prompt,
|
users: alts.map((alt) => ({
|
||||||
alts: alts.map((alt) => ({
|
names: alt.keys,
|
||||||
keys: alt.keys,
|
|
||||||
alt: alt.alt,
|
alt: alt.alt,
|
||||||
information: user.information,
|
backstory: alt.id
|
||||||
|
? getUserById(`${alt.id}:${config.server}`).information
|
||||||
|
: undefined,
|
||||||
})),
|
})),
|
||||||
} as IAdminInstructions;
|
aiPersonality: personality?.personality ?? "",
|
||||||
|
aiLikes: personality?.likes ?? "",
|
||||||
|
aiDislikes: personality?.dislikes ?? "",
|
||||||
|
} as IAIInstructions;
|
||||||
|
|
||||||
const username = getUserName(user);
|
const username = getUserName(user);
|
||||||
textMod = `Admin Instructions:\n${JSON.stringify(instructions)}\nPrompt by ${username}:\n${textMod}`;
|
textMod = `${username}:\n${textMod}`;
|
||||||
|
|
||||||
const responseAI = await getTextGemini(textMod);
|
const responseAI = await getTextGemini(instructions, textMod);
|
||||||
|
|
||||||
user.aiCost += responseAI.tokens * prices.text;
|
user.aiCost += responseAI.tokens * prices.text;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import type { IAIAlt } from "./types.js";
|
||||||
|
|
||||||
const alts: IAIAlt[] = [
|
const alts: IAIAlt[] = [
|
||||||
{
|
{
|
||||||
|
id: "@coty",
|
||||||
keys: [
|
keys: [
|
||||||
"satek",
|
"satek",
|
||||||
"sateg",
|
"sateg",
|
||||||
|
|
@ -22,10 +23,12 @@ const alts: IAIAlt[] = [
|
||||||
alt: "white cat",
|
alt: "white cat",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: "@marketing",
|
||||||
keys: ["gabor", "gaber", "martin", "marting"],
|
keys: ["gabor", "gaber", "martin", "marting"],
|
||||||
alt: "hedgehog",
|
alt: "hedgehog",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: "@madys",
|
||||||
keys: [
|
keys: [
|
||||||
"madys",
|
"madys",
|
||||||
"mandak",
|
"mandak",
|
||||||
|
|
@ -39,10 +42,12 @@ const alts: IAIAlt[] = [
|
||||||
alt: "beaver",
|
alt: "beaver",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: "@aslan2142",
|
||||||
keys: ["janys", "jano", "janeg", "janek", "aslanek", "aslan", "aslo"],
|
keys: ["janys", "jano", "janeg", "janek", "aslanek", "aslan", "aslo"],
|
||||||
alt: "lion",
|
alt: "lion",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: "@rod",
|
||||||
keys: ["marek", "mareg", "macek", "maceg", "rod"],
|
keys: ["marek", "mareg", "macek", "maceg", "rod"],
|
||||||
alt: "purple snake",
|
alt: "purple snake",
|
||||||
},
|
},
|
||||||
|
|
@ -56,7 +61,7 @@ const alts: IAIAlt[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
keys: ["mama", "monika", "monik"],
|
keys: ["mama", "monika", "monik"],
|
||||||
alt: "god's peasant",
|
alt: "god's peasant woman",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
keys: ["puk", "pucik", "pucig"],
|
keys: ["puk", "pucik", "pucig"],
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,21 @@
|
||||||
interface IAIAlt {
|
interface IAIAlt {
|
||||||
|
id?: string;
|
||||||
keys: string[];
|
keys: string[];
|
||||||
alt: string;
|
alt: string;
|
||||||
information?: string | undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IAdminInstructions {
|
interface IAIUser {
|
||||||
|
names: string[];
|
||||||
|
alt: string;
|
||||||
|
backstory?: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAIInstructions {
|
||||||
prefferedLanguages: string[];
|
prefferedLanguages: string[];
|
||||||
adminText: string;
|
users: IAIUser[];
|
||||||
alts: IAIAlt[];
|
aiPersonality: string;
|
||||||
|
aiLikes: string;
|
||||||
|
aiDislikes: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { type IAIAlt, type IAdminInstructions };
|
export { type IAIAlt, type IAIUser, type IAIInstructions };
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ const onMissingRole = (
|
||||||
client.sendHtmlMessage(
|
client.sendHtmlMessage(
|
||||||
roomId,
|
roomId,
|
||||||
"",
|
"",
|
||||||
`You are missing the required role.<br/>Your current role is <b>${userRole}</b>`,
|
`You don't have a permission to do that!<br/>Your current role is <b>${userRole}</b>`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ const onAILeaderboard = (_text: string, roomId: string) => {
|
||||||
const cost = user.aiCost;
|
const cost = user.aiCost;
|
||||||
const username = getUserName(user);
|
const username = getUserName(user);
|
||||||
|
|
||||||
return `<li>${username}: cost <b>${cost.toFixed(2)}$</b></li>`;
|
return `<li>${username}: <b>${cost.toFixed(2)}$</b></li>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const users = state.users.sort(
|
const users = state.users.sort(
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,22 @@
|
||||||
import { GoogleGenAI } from "@google/genai";
|
import { GoogleGenAI } from "@google/genai";
|
||||||
import { config } from "../../config.js";
|
import { config } from "../../config.js";
|
||||||
import type { AIResponseImage, AIResponseText } from "./types.js";
|
import type { AIResponseImage, AIResponseText } from "./types.js";
|
||||||
|
import type { IAIInstructions } from "../../modules/ai/types.js";
|
||||||
|
|
||||||
const googleAI = new GoogleGenAI({
|
const googleAI = new GoogleGenAI({
|
||||||
apiKey: config.app.ai.api.key,
|
apiKey: config.app.ai.api.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
const getTextGemini = async (input: string): Promise<AIResponseText> => {
|
const getTextGemini = async (
|
||||||
|
instructions: IAIInstructions,
|
||||||
|
input: string,
|
||||||
|
): Promise<AIResponseText> => {
|
||||||
const response = await googleAI.models.generateContent({
|
const response = await googleAI.models.generateContent({
|
||||||
model: "gemini-3-flash-preview",
|
model: "gemini-3-flash-preview",
|
||||||
contents: input,
|
contents: input,
|
||||||
|
config: {
|
||||||
|
systemInstruction: JSON.stringify(instructions),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,10 @@ import type { IState } from "./types.js";
|
||||||
|
|
||||||
let state: IState = {
|
let state: IState = {
|
||||||
users: [],
|
users: [],
|
||||||
|
personality: {
|
||||||
|
index: 0,
|
||||||
|
startTime: 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const load = () => {
|
const load = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
interface IState {
|
interface IState {
|
||||||
users: IUser[];
|
users: IUser[];
|
||||||
|
personality: IPersonality;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IUser {
|
interface IUser {
|
||||||
|
|
@ -16,4 +17,9 @@ interface IUser {
|
||||||
|
|
||||||
type TRole = "NONE" | "USER" | "MODERATOR" | "ADMIN";
|
type TRole = "NONE" | "USER" | "MODERATOR" | "ADMIN";
|
||||||
|
|
||||||
export { type IState, type IUser, type TRole };
|
interface IPersonality {
|
||||||
|
index: number;
|
||||||
|
startTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { type IState, type IUser, type TRole, type IPersonality };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue