apexify.js 4.0.7 → 4.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,34 @@
1
- import { GoogleGenerativeAI } from "@google/generative-ai";
1
+ import { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold } from "@google/generative-ai";
2
2
  import path from 'path';
3
3
  import fs from 'fs';
4
4
  import config from './config';
5
5
  import { converter } from "../../canvas/utils/general functions";
6
+ import { connect } from "verse.db";
7
+ import axios from "axios";
6
8
 
7
9
  let currentApiKeyIndex = 0;
8
10
 
9
- export async function geminiPro(message: any, AI: { AiPersonality: string | null, userMsg: string, API_KEY: string | null }): Promise<any> {
11
+ export async function geminiPro(message: { userId: string, serverName: string, serverId: string, channelName: string, attachment: any, db: boolean }, AI: { AiPersonality: string | null, userMsg: string, API_KEY: string | null }): Promise<any> {
12
+
10
13
 
11
14
  try {
12
- const genAI = new GoogleGenerativeAI(AI.API_KEY || config.apiKeys[currentApiKeyIndex]);
15
+
16
+ let apiKeyIndex = currentApiKeyIndex;
17
+ let genAI: any;
18
+ while (apiKeyIndex < config.apiKeys.length) {
19
+ const validateKey = await axios.get(`https://generativelanguage.googleapis.com/v1beta/models?key=${config.apiKeys[apiKeyIndex]}`);
20
+ if (validateKey.status === 200) {
21
+ genAI = new GoogleGenerativeAI(config.apiKeys[apiKeyIndex]);
22
+
23
+ break;
24
+ } else {
25
+ apiKeyIndex++;
26
+ }
27
+ }
28
+
29
+ if (apiKeyIndex === config.apiKeys.length) {
30
+ return 'All provided API keys are invalid.';
31
+ }
13
32
 
14
33
  let personalityString: string = '';
15
34
  if (AI.AiPersonality) {
@@ -23,49 +42,85 @@ export async function geminiPro(message: any, AI: { AiPersonality: string | null
23
42
  maxOutputTokens: 750,
24
43
  };
25
44
 
26
- const systemInstruction = `${personalityString}\n And working on discord in serverName: ${message.guild.name} at channelName: ${message.channel.name} and responding to the userName: ${message.author.username}`;
27
- const model = genAI.getGenerativeModel({ model: "gemini-1.5-pro-latest", systemInstruction, generationConfig});
45
+ const safetySettings = [
46
+ {
47
+ category: HarmCategory.HARM_CATEGORY_HARASSMENT,
48
+ threshold: HarmBlockThreshold.BLOCK_ONLY_HIGH,
49
+ },
50
+ {
51
+ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
52
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
53
+ },
54
+ {
55
+ category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
56
+ threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
57
+ },
58
+ {
59
+ category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
60
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
61
+ },
62
+ ];
63
+
64
+ const systemInstruction = `${personalityString}\n And working on discord in serverName: ${message.serverName} at channelName: ${message.channelName} and responding to the userName:<@ ${message.userId}>`;
65
+ const model = genAI.getGenerativeModel({ model: "gemini-1.5-pro-latest", systemInstruction, generationConfig, safetySettings });
66
+
67
+ let historyData: any[] | undefined = undefined;
68
+
69
+ const defaultHistory = [
70
+ {
71
+ role: "user",
72
+ parts: [{ text: `${personalityString}\n And working on discord in serverName: ${message.serverName} at channelName: ${message.channelName} and responding to the userName: <@${message.userId}>` }],
73
+ },
74
+ {
75
+ role: "model",
76
+ parts: [{ text: `I will greet the user with their name: <@${message.userId}>. Feel free to ask me anything! 😊` }],
77
+ },
78
+ {
79
+ role: "user",
80
+ parts: [{ text: "Any question regarding JEDI STUDIO, verse.db, apexify.js, or djs-builder?" }],
81
+ },
82
+ {
83
+ role: "model",
84
+ parts: [{ text: `You should reply with visiting documentation online at jedi-studio.com. The development team consists of 8 people, led by Marco. The CEO/founder is Kimo.` }],
85
+ },
86
+ {
87
+ role: "user",
88
+ parts: [{ text: "How was I developed or programmed?" }],
89
+ },
90
+ {
91
+ role: "model",
92
+ parts: [{ text: `You were made by JEDI STUDIO under the development of jedi.tsx, one of the CEOs for JEDI STUDIO.` }],
93
+ },
94
+ {
95
+ role: "user",
96
+ parts: [{ text: "Tell me about verse.db." }],
97
+ },
98
+ {
99
+ role: "model",
100
+ parts: [{ text: `verse.db is a database that enables users to manage data for SQL, JSON, YAML, and SQOL. It's a new brand by JEDI STUDIO, and SOOL will support more database management with comprehensive features and security.` }],
101
+ },
102
+ ];
103
+
104
+ let db: any;
105
+
106
+ if (message.db) {
107
+ db = new connect({ adapter: 'json', dataPath: `${message.serverId}_ChatHistory` });
108
+
109
+ const data = await db.find(`${message.userId}_chatHistory`, { userId: message.userId });
110
+
111
+ if (!data.results?.history || data.results?.history?.length === 0) {
112
+ await db.update(`${message.userId}_chatHistory`, { userId: message.userId }, { $set: { history: [] } }, true);
113
+ } else {
114
+ historyData = data.results?.history || undefined;
115
+ }
116
+ }
28
117
 
29
118
  const chat = model.startChat({
30
- history: [
31
- {
32
- role: "user",
33
- parts: [{ text: `${personalityString}\n And working on discord in serverName: ${message.guild.name} at channelName: ${message.channel.name} and responding to the userName: ${message.author.username}` }],
34
- },
35
- {
36
- role: "model",
37
- parts: [{ text: `I will greet the user with their name: <@${message.author.id}>. Feel free to ask me anything! 😊` }],
38
- },
39
- {
40
- role: "user",
41
- parts: [{ text: "Any question regarding JEDI STUDIO, verse.db, apexify.js, or djs-builder?" }],
42
- },
43
- {
44
- role: "model",
45
- parts: [{ text: `You should reply with visiting documentation online at jedi-studio.com. The development team consists of 8 people, led by Marco. The CEO/founder is Kimo.` }],
46
- },
47
- {
48
- role: "user",
49
- parts: [{ text: "How was I developed or programmed?" }],
50
- },
51
- {
52
- role: "model",
53
- parts: [{ text: `You were made by JEDI STUDIO under the development of jedi.tsx, one of the CEOs for JEDI STUDIO.` }],
54
- },
55
- {
56
- role: "user",
57
- parts: [{ text: "Tell me about verse.db." }],
58
- },
59
- {
60
- role: "model",
61
- parts: [{ text: `verse.db is a database that enables users to manage data for SQL, JSON, YAML, and SQOL. It's a new brand by JEDI STUDIO, and SOOL will support more database management with comprehensive features and security.` }],
62
- },
63
- ],
119
+ history: historyData || defaultHistory,
64
120
  generationConfig
65
- });
121
+ });
66
122
 
67
- const attachment = message.attachments?.first();
68
- const imgURL = attachment?.url || null;
123
+ const imgURL = message.attachment?.url || null;
69
124
  let result: any;
70
125
 
71
126
  if (imgURL) {
@@ -80,20 +135,51 @@ export async function geminiPro(message: any, AI: { AiPersonality: string | null
80
135
  } else {
81
136
  result = await chat.sendMessage(AI.userMsg);
82
137
  }
83
- const response = result.response;
84
138
 
85
- return response.text()
86
- } catch (e: any) {
139
+ const response = await result.response.text();
140
+
141
+ if (message.db) {
142
+
143
+ const updateQuery_1 = {
144
+ $push: {
145
+ "history": {
146
+ role: "user",
147
+ parts: [{ text: `${AI.userMsg}` }]
148
+ }
149
+ },
150
+ };
151
+
152
+ historyData = await db.update(`${message.userId}_chatHistory`,
153
+ { userId: message.userId },
154
+ updateQuery_1, true
155
+ );
156
+
157
+ const updateQuery_2 = {
158
+ $push: {
159
+ "history": {
160
+ role: "model",
161
+ parts: [{ text: `${response}` }]
162
+ }
163
+ },
164
+ };
165
+
166
+ historyData = await db.update(`${message.userId}_chatHistory`,
167
+ { userId: message.userId },
168
+ updateQuery_2,
169
+ true
170
+ );
171
+ }
172
+
173
+ return response;
174
+ } catch (e: any) {
87
175
  if (e.message) {
88
176
  if (e.message === '[GoogleGenerativeAI Error]: Error fetching from https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent: [400 Bad Request] User location is not supported for the API use.') {
89
- return `<${message.author.id}> your location isn't supported by gemini AI.`;
90
- } else if (e.response && (e.response.status === 429 || e.response.status === 400)) {
91
- currentApiKeyIndex++;
92
- if (currentApiKeyIndex < config.apiKeys.length) {
93
- return geminiPro(message, { ...AI, API_KEY: config.apiKeys[currentApiKeyIndex] });
94
- } else {
95
- return 'Ai is on a cooldown for the rest of the day. Either provide your API key or wait for tomorrow. Check ai.google.dev for apikeys';
96
- }
177
+ return `The hoster/bot owner/the used host isn't supported by gemini.`;
178
+ } else if (e.response && (e.response.status === 429 || e.response.status === 403)) {
179
+ return 'Ai is on a cooldown for the rest of the day. Either provide your own API key or wait for tomorrow. Check ai.google.dev for free apikeys';
180
+ } else if (e.message === '[GoogleGenerativeAI Error]: Candidate was blocked due to SAFETY') {
181
+ console.error(e);
182
+ return `Due to safety enabled by gemini you have been blocked.`;
97
183
  } else {
98
184
  console.error(e);
99
185
  return `Try again later please... Either API is on a cooldown or an internal server error has occurred. If issue persists please contact the bot developer or owner of the npm package.`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apexify.js",
3
- "version": "4.0.7",
3
+ "version": "4.0.8",
4
4
  "description": "Ai and Canvas library. Supports typescript and javascript",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -152,7 +152,8 @@
152
152
  "jimp": "^0.3.11",
153
153
  "pdf-parse": "^1.1.1",
154
154
  "sharp": "^0.33.2",
155
- "tesseract.js": "^5.0.5"
155
+ "tesseract.js": "^5.0.5",
156
+ "verse.db": "^2.0.4"
156
157
  },
157
158
  "devDependencies": {
158
159
  "@types/gifencoder": "^2.0.3",