refactor
This commit is contained in:
78
src/main.ts
78
src/main.ts
@ -10,14 +10,35 @@ import { PrismaClient } from "../generated/prisma/client.js";
|
|||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
const envConfig = {
|
||||||
|
pleromaInstanceUrl: process.env.PLEROMA_INSTANCE_URL || "",
|
||||||
|
pleromaInstanceDomain: process.env.PLEROMA_INSTANCE_DOMAIN || "",
|
||||||
|
onlyLocalReplies: process.env.ONLY_LOCAL_REPLIES === "true" ? true : false,
|
||||||
|
ollamaUrl: process.env.OLLAMA_URL || "",
|
||||||
|
ollamaSystemPrompt:
|
||||||
|
process.env.OLLAMA_SYSTEM_PROMPT ||
|
||||||
|
"You are a helpful AI assistant. Answer all questions concisely.",
|
||||||
|
ollamaModel: process.env.OLLAMA_MODEL || "",
|
||||||
|
fetchInterval: process.env.FETCH_INTERVAL
|
||||||
|
? parseInt(process.env.FETCH_INTERVAL)
|
||||||
|
: 15000,
|
||||||
|
bearerToken: process.env.INSTANCE_BEARER_TOKEN || "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const ollamaConfig: OllamaConfigOptions = {
|
||||||
|
temperature: 0.3,
|
||||||
|
num_predict: 400,
|
||||||
|
};
|
||||||
|
|
||||||
const getNotifications = async () => {
|
const getNotifications = async () => {
|
||||||
|
const { bearerToken, pleromaInstanceUrl } = envConfig;
|
||||||
try {
|
try {
|
||||||
const request = await fetch(
|
const request = await fetch(
|
||||||
`${process.env.PLEROMA_INSTANCE_URL}/api/v1/notifications?types[]=mention`,
|
`${pleromaInstanceUrl}/api/v1/notifications?types[]=mention`,
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`,
|
Authorization: `Bearer ${bearerToken}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -82,11 +103,12 @@ const storePromptData = async (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const trimInputData = (input: string) => {
|
const trimInputData = (input: string): string => {
|
||||||
const strippedInput = striptags(input);
|
const strippedInput = striptags(input);
|
||||||
const split = strippedInput.split(" ");
|
const split = strippedInput.split(" ");
|
||||||
const promptStringIndex = split.indexOf("!prompt");
|
const promptStringIndex = split.indexOf("!prompt");
|
||||||
return split.slice(promptStringIndex + 1).join(" "); // returns everything after the !prompt
|
split.splice(promptStringIndex, 1);
|
||||||
|
return split.join(" "); // returns everything after the !prompt
|
||||||
};
|
};
|
||||||
|
|
||||||
const recordPendingResponse = async (notification: Notification) => {
|
const recordPendingResponse = async (notification: Notification) => {
|
||||||
@ -104,6 +126,13 @@ const recordPendingResponse = async (notification: Notification) => {
|
|||||||
const generateOllamaRequest = async (
|
const generateOllamaRequest = async (
|
||||||
notification: Notification
|
notification: Notification
|
||||||
): Promise<OllamaResponse | undefined> => {
|
): Promise<OllamaResponse | undefined> => {
|
||||||
|
const {
|
||||||
|
onlyLocalReplies,
|
||||||
|
pleromaInstanceDomain,
|
||||||
|
ollamaModel,
|
||||||
|
ollamaSystemPrompt,
|
||||||
|
ollamaUrl,
|
||||||
|
} = envConfig;
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
striptags(notification.status.content).includes("!prompt") &&
|
striptags(notification.status.content).includes("!prompt") &&
|
||||||
@ -111,10 +140,8 @@ const generateOllamaRequest = async (
|
|||||||
notification.type === "mention"
|
notification.type === "mention"
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
process.env.ONLY_LOCAL_REPLIES === "true" &&
|
onlyLocalReplies &&
|
||||||
!notification.status.account.fqn.includes(
|
!notification.status.account.fqn.includes(`@${pleromaInstanceDomain}`)
|
||||||
`@${process.env.PLEROMA_INSTANCE_DOMAIN}`
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -123,20 +150,16 @@ const generateOllamaRequest = async (
|
|||||||
}
|
}
|
||||||
await recordPendingResponse(notification);
|
await recordPendingResponse(notification);
|
||||||
await storeUserData(notification);
|
await storeUserData(notification);
|
||||||
const ollamaConfig: OllamaConfigOptions = {
|
|
||||||
temperature: 1.2,
|
|
||||||
num_predict: 400,
|
|
||||||
};
|
|
||||||
const ollamaRequestBody: OllamaRequest = {
|
const ollamaRequestBody: OllamaRequest = {
|
||||||
model: process.env.OLLAMA_MODEL as string,
|
model: ollamaModel,
|
||||||
system: process.env.OLLAMA_SYSTEM_PROMPT as string,
|
system: ollamaSystemPrompt,
|
||||||
prompt: `@${notification.status.account.fqn} says: ${trimInputData(
|
prompt: `@${notification.status.account.fqn} says: ${trimInputData(
|
||||||
notification.status.content
|
notification.status.content
|
||||||
)}`,
|
)}`,
|
||||||
stream: false,
|
stream: false,
|
||||||
options: ollamaConfig,
|
options: ollamaConfig,
|
||||||
};
|
};
|
||||||
const response = await fetch(`${process.env.OLLAMA_URL}/api/generate`, {
|
const response = await fetch(`${ollamaUrl}/api/generate`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(ollamaRequestBody),
|
body: JSON.stringify(ollamaRequestBody),
|
||||||
});
|
});
|
||||||
@ -153,6 +176,7 @@ const postReplyToStatus = async (
|
|||||||
notification: Notification,
|
notification: Notification,
|
||||||
ollamaResponseBody: OllamaResponse
|
ollamaResponseBody: OllamaResponse
|
||||||
) => {
|
) => {
|
||||||
|
const { pleromaInstanceUrl, bearerToken } = envConfig;
|
||||||
try {
|
try {
|
||||||
let mentions: string[];
|
let mentions: string[];
|
||||||
const statusBody: NewStatusBody = {
|
const statusBody: NewStatusBody = {
|
||||||
@ -170,17 +194,14 @@ const postReplyToStatus = async (
|
|||||||
statusBody.to = mentions;
|
statusBody.to = mentions;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(
|
const response = await fetch(`${pleromaInstanceUrl}/api/v1/statuses`, {
|
||||||
`${process.env.PLEROMA_INSTANCE_URL}/api/v1/statuses`,
|
|
||||||
{
|
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`,
|
Authorization: `Bearer ${bearerToken}`,
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(statusBody),
|
body: JSON.stringify(statusBody),
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`New status request failed: ${response.statusText}`);
|
throw new Error(`New status request failed: ${response.statusText}`);
|
||||||
@ -193,6 +214,7 @@ const postReplyToStatus = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const deleteNotification = async (notification: Notification) => {
|
const deleteNotification = async (notification: Notification) => {
|
||||||
|
const { pleromaInstanceUrl, bearerToken } = envConfig;
|
||||||
try {
|
try {
|
||||||
if (!notification.id) {
|
if (!notification.id) {
|
||||||
return;
|
return;
|
||||||
@ -203,11 +225,11 @@ const deleteNotification = async (notification: Notification) => {
|
|||||||
data: { isProcessing: false },
|
data: { isProcessing: false },
|
||||||
});
|
});
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${process.env.PLEROMA_INSTANCE_URL}/api/v1/notifications/${notification.id}/dismiss`,
|
`${pleromaInstanceUrl}/api/v1/notifications/${notification.id}/dismiss`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`,
|
Authorization: `Bearer ${bearerToken}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -221,10 +243,6 @@ const deleteNotification = async (notification: Notification) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchInterval = process.env.FETCH_INTERVAL
|
|
||||||
? parseInt(process.env.FETCH_INTERVAL)
|
|
||||||
: 15000;
|
|
||||||
|
|
||||||
let notifications = [];
|
let notifications = [];
|
||||||
const beginFetchCycle = async () => {
|
const beginFetchCycle = async () => {
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
@ -243,12 +261,12 @@ const beginFetchCycle = async () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, fetchInterval); // lower intervals may cause the bot to respond multiple times to the same message, but we try to mitigate this with the deleteNotification function
|
}, envConfig.fetchInterval); // lower intervals may cause the bot to respond multiple times to the same message, but we try to mitigate this with the deleteNotification function
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`Fetching notifications from ${process.env.PLEROMA_INSTANCE_DOMAIN}, every ${
|
`Fetching notifications from ${envConfig.pleromaInstanceDomain}, every ${
|
||||||
fetchInterval / 1000
|
envConfig.fetchInterval / 1000
|
||||||
} seconds.`
|
} seconds.`
|
||||||
);
|
);
|
||||||
await beginFetchCycle();
|
await beginFetchCycle();
|
||||||
|
Reference in New Issue
Block a user