refactor
This commit is contained in:
		
							
								
								
									
										88
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								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", | ||||||
|       { |       headers: { | ||||||
|         method: "POST", |         Authorization: `Bearer ${bearerToken}`, | ||||||
|         headers: { |         "Content-Type": "application/json", | ||||||
|           Authorization: `Bearer ${process.env.INSTANCE_BEARER_TOKEN}`, |       }, | ||||||
|           "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