apexify.js 4.5.58 → 4.5.591
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.
- package/dist/cjs/ai/ApexAI.d.ts +132 -1
- package/dist/cjs/ai/ApexAI.d.ts.map +1 -1
- package/dist/cjs/ai/ApexAI.js +234 -190
- package/dist/cjs/ai/ApexAI.js.map +1 -1
- package/dist/cjs/ai/ApexModules.d.ts +7 -3
- package/dist/cjs/ai/ApexModules.d.ts.map +1 -1
- package/dist/cjs/ai/ApexModules.js +40 -7
- package/dist/cjs/ai/ApexModules.js.map +1 -1
- package/dist/cjs/ai/buttons/tools.d.ts.map +1 -1
- package/dist/cjs/ai/buttons/tools.js +1 -0
- package/dist/cjs/ai/buttons/tools.js.map +1 -1
- package/dist/cjs/ai/functions/readFiles.d.ts.map +1 -1
- package/dist/cjs/ai/functions/readFiles.js +12 -27
- package/dist/cjs/ai/functions/readFiles.js.map +1 -1
- package/dist/cjs/ai/functions/validOptions.d.ts +18 -10
- package/dist/cjs/ai/functions/validOptions.d.ts.map +1 -1
- package/dist/cjs/ai/functions/validOptions.js +82 -44
- package/dist/cjs/ai/functions/validOptions.js.map +1 -1
- package/dist/cjs/ai/modals-chat/electronHub/speechModels.d.ts +2 -2
- package/dist/cjs/ai/modals-chat/electronHub/speechModels.d.ts.map +1 -1
- package/dist/cjs/ai/modals-chat/groq/whisper.d.ts +3 -0
- package/dist/cjs/ai/modals-chat/groq/whisper.d.ts.map +1 -1
- package/dist/cjs/ai/modals-chat/groq/whisper.js +30 -21
- package/dist/cjs/ai/modals-chat/groq/whisper.js.map +1 -1
- package/dist/cjs/ai/utils.d.ts +2 -6
- package/dist/cjs/ai/utils.d.ts.map +1 -1
- package/dist/cjs/ai/utils.js +2 -9
- package/dist/cjs/ai/utils.js.map +1 -1
- package/dist/cjs/canvas/utils/Image/imageProperties.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/Image/imageProperties.js +11 -76
- package/dist/cjs/canvas/utils/Image/imageProperties.js.map +1 -1
- package/dist/cjs/canvas/utils/types.d.ts +26 -0
- package/dist/cjs/canvas/utils/types.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/types.js.map +1 -1
- package/dist/cjs/index.d.ts +9 -12
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +22 -18
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +2 -2
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +2 -2
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/ai/ApexAI.d.ts +132 -1
- package/dist/esm/ai/ApexAI.d.ts.map +1 -1
- package/dist/esm/ai/ApexAI.js +234 -190
- package/dist/esm/ai/ApexAI.js.map +1 -1
- package/dist/esm/ai/ApexModules.d.ts +7 -3
- package/dist/esm/ai/ApexModules.d.ts.map +1 -1
- package/dist/esm/ai/ApexModules.js +40 -7
- package/dist/esm/ai/ApexModules.js.map +1 -1
- package/dist/esm/ai/buttons/tools.d.ts.map +1 -1
- package/dist/esm/ai/buttons/tools.js +1 -0
- package/dist/esm/ai/buttons/tools.js.map +1 -1
- package/dist/esm/ai/functions/readFiles.d.ts.map +1 -1
- package/dist/esm/ai/functions/readFiles.js +12 -27
- package/dist/esm/ai/functions/readFiles.js.map +1 -1
- package/dist/esm/ai/functions/validOptions.d.ts +18 -10
- package/dist/esm/ai/functions/validOptions.d.ts.map +1 -1
- package/dist/esm/ai/functions/validOptions.js +82 -44
- package/dist/esm/ai/functions/validOptions.js.map +1 -1
- package/dist/esm/ai/modals-chat/electronHub/speechModels.d.ts +2 -2
- package/dist/esm/ai/modals-chat/electronHub/speechModels.d.ts.map +1 -1
- package/dist/esm/ai/modals-chat/groq/whisper.d.ts +3 -0
- package/dist/esm/ai/modals-chat/groq/whisper.d.ts.map +1 -1
- package/dist/esm/ai/modals-chat/groq/whisper.js +30 -21
- package/dist/esm/ai/modals-chat/groq/whisper.js.map +1 -1
- package/dist/esm/ai/utils.d.ts +2 -6
- package/dist/esm/ai/utils.d.ts.map +1 -1
- package/dist/esm/ai/utils.js +2 -9
- package/dist/esm/ai/utils.js.map +1 -1
- package/dist/esm/canvas/utils/Image/imageProperties.d.ts.map +1 -1
- package/dist/esm/canvas/utils/Image/imageProperties.js +11 -76
- package/dist/esm/canvas/utils/Image/imageProperties.js.map +1 -1
- package/dist/esm/canvas/utils/types.d.ts +26 -0
- package/dist/esm/canvas/utils/types.d.ts.map +1 -1
- package/dist/esm/canvas/utils/types.js.map +1 -1
- package/dist/esm/index.d.ts +9 -12
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +22 -18
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +2 -2
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +2 -2
- package/dist/esm/utils.js.map +1 -1
- package/lib/ai/ApexAI.ts +442 -195
- package/lib/ai/ApexModules.ts +45 -12
- package/lib/ai/buttons/tools.ts +1 -0
- package/lib/ai/functions/readFiles.ts +14 -31
- package/lib/ai/functions/validOptions.ts +96 -49
- package/lib/ai/modals-chat/electronHub/speechModels.ts +2 -2
- package/lib/ai/modals-chat/groq/whisper.ts +34 -20
- package/lib/ai/utils.ts +3 -10
- package/lib/canvas/utils/Image/imageProperties.ts +18 -104
- package/lib/canvas/utils/types.ts +21 -1
- package/lib/index.ts +44 -28
- package/lib/utils.ts +2 -2
- package/package.json +2 -5
- package/dist/cjs/ai/functions/chunkString.d.ts +0 -2
- package/dist/cjs/ai/functions/chunkString.d.ts.map +0 -1
- package/dist/cjs/ai/functions/chunkString.js +0 -7
- package/dist/cjs/ai/functions/chunkString.js.map +0 -1
- package/dist/cjs/ai/functions/draw.d.ts +0 -10
- package/dist/cjs/ai/functions/draw.d.ts.map +0 -1
- package/dist/cjs/ai/functions/draw.js +0 -649
- package/dist/cjs/ai/functions/draw.js.map +0 -1
- package/dist/cjs/ai/functions/imageReader.d.ts +0 -3
- package/dist/cjs/ai/functions/imageReader.d.ts.map +0 -1
- package/dist/cjs/ai/functions/imageReader.js +0 -22
- package/dist/cjs/ai/functions/imageReader.js.map +0 -1
- package/dist/cjs/ai/functions/shouldDrawImage.d.ts +0 -2
- package/dist/cjs/ai/functions/shouldDrawImage.d.ts.map +0 -1
- package/dist/cjs/ai/functions/shouldDrawImage.js +0 -10
- package/dist/cjs/ai/functions/shouldDrawImage.js.map +0 -1
- package/dist/cjs/ai/modals-chat/others/otherModels.d.ts +0 -9
- package/dist/cjs/ai/modals-chat/others/otherModels.d.ts.map +0 -1
- package/dist/cjs/ai/modals-chat/others/otherModels.js +0 -101
- package/dist/cjs/ai/modals-chat/others/otherModels.js.map +0 -1
- package/dist/esm/ai/functions/chunkString.d.ts +0 -2
- package/dist/esm/ai/functions/chunkString.d.ts.map +0 -1
- package/dist/esm/ai/functions/chunkString.js +0 -7
- package/dist/esm/ai/functions/chunkString.js.map +0 -1
- package/dist/esm/ai/functions/draw.d.ts +0 -10
- package/dist/esm/ai/functions/draw.d.ts.map +0 -1
- package/dist/esm/ai/functions/draw.js +0 -649
- package/dist/esm/ai/functions/draw.js.map +0 -1
- package/dist/esm/ai/functions/imageReader.d.ts +0 -3
- package/dist/esm/ai/functions/imageReader.d.ts.map +0 -1
- package/dist/esm/ai/functions/imageReader.js +0 -22
- package/dist/esm/ai/functions/imageReader.js.map +0 -1
- package/dist/esm/ai/functions/shouldDrawImage.d.ts +0 -2
- package/dist/esm/ai/functions/shouldDrawImage.d.ts.map +0 -1
- package/dist/esm/ai/functions/shouldDrawImage.js +0 -10
- package/dist/esm/ai/functions/shouldDrawImage.js.map +0 -1
- package/dist/esm/ai/modals-chat/others/otherModels.d.ts +0 -9
- package/dist/esm/ai/modals-chat/others/otherModels.d.ts.map +0 -1
- package/dist/esm/ai/modals-chat/others/otherModels.js +0 -101
- package/dist/esm/ai/modals-chat/others/otherModels.js.map +0 -1
- package/lib/ai/functions/chunkString.ts +0 -3
- package/lib/ai/functions/draw.ts +0 -695
- package/lib/ai/functions/imageReader.ts +0 -24
- package/lib/ai/functions/shouldDrawImage.ts +0 -7
- package/lib/ai/modals-chat/others/otherModels.ts +0 -115
package/lib/ai/ApexModules.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { Hercai } from 'hercai';
|
|
|
2
2
|
import { validateModels } from "./functions/validOptions";
|
|
3
3
|
import { whisper } from './modals-chat/groq/whisper';
|
|
4
4
|
import { connect } from 'verse.db';
|
|
5
|
-
import { otherChatModels } from './modals-chat/others/otherModels';
|
|
6
5
|
import { chatGroq } from './modals-chat/groq/chatgroq';
|
|
7
6
|
import { groqAnalyzer } from './utils';
|
|
8
7
|
import { electronImagine } from './modals-chat/electronHub/imageModels';
|
|
@@ -52,7 +51,7 @@ async function ApexImagine(model: string, prompt: string, options?: ApexImagineO
|
|
|
52
51
|
if ((width || height) <= 0) throw new Error("Inavlid usage. Image width/height can't be less than 0 or more than 1024.");
|
|
53
52
|
|
|
54
53
|
for (let i = 0; i < count; i++) {
|
|
55
|
-
if (imageType.
|
|
54
|
+
if (imageType.validHercImageModels.includes(model)) {
|
|
56
55
|
if (model === 'prodia-v2') {
|
|
57
56
|
imageURL = (await hercai.betaDrawImage({
|
|
58
57
|
prompt: translatedText,
|
|
@@ -643,6 +642,45 @@ async function ApexChat(model: string, prompt: string, { userId, memory, limit,
|
|
|
643
642
|
}
|
|
644
643
|
}
|
|
645
644
|
|
|
645
|
+
async function resetHistory({ id, last }: { id: string; last: number | string }): Promise<boolean> {
|
|
646
|
+
if (!id) return false;
|
|
647
|
+
|
|
648
|
+
try {
|
|
649
|
+
|
|
650
|
+
const getUserData = (await db.findCollection(`${id}`, 'normal')).results;
|
|
651
|
+
|
|
652
|
+
if (!getUserData) return false;
|
|
653
|
+
|
|
654
|
+
const userRecord = (await db.find(`${id}`, { userId: id })).results;
|
|
655
|
+
if (!userRecord || !userRecord.history) return false;
|
|
656
|
+
|
|
657
|
+
const countHistory = userRecord.history.length;
|
|
658
|
+
|
|
659
|
+
let updateQuery: any = {};
|
|
660
|
+
|
|
661
|
+
if (typeof last === "string" && last.toLowerCase() === "all") {
|
|
662
|
+
updateQuery = { $set: { history: [] } };
|
|
663
|
+
} else if (typeof last === "number" && last > 0) {
|
|
664
|
+
const keep = Math.max(countHistory - last, 0);
|
|
665
|
+
if (keep === 0) {
|
|
666
|
+
updateQuery = { $set: { history: [] } };
|
|
667
|
+
} else {
|
|
668
|
+
updateQuery = { $slice: { history: keep } };
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
console.log("Invalid value for 'last'. Must be a positive number or 'all'.");
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
await db.update(`${id}`, { userId: id }, updateQuery);
|
|
676
|
+
return true
|
|
677
|
+
} catch (error) {
|
|
678
|
+
console.error("Error resetting history:", error);
|
|
679
|
+
return false
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
|
|
646
684
|
async function processChunk(
|
|
647
685
|
model: string,
|
|
648
686
|
prompt: string,
|
|
@@ -660,12 +698,7 @@ async function processChunk(
|
|
|
660
698
|
})
|
|
661
699
|
).reply;
|
|
662
700
|
break;
|
|
663
|
-
|
|
664
|
-
case validOptions.validotherChatModels.includes(model):
|
|
665
|
-
response = await otherChatModels({ modelName: model as any, prompt });
|
|
666
|
-
break;
|
|
667
|
-
|
|
668
|
-
case validOptions.validgroqChatModels.includes(model):
|
|
701
|
+
case validOptions.validGroqChatModels.includes(model):
|
|
669
702
|
response = await chatGroq({
|
|
670
703
|
API_KEY: ApiKey,
|
|
671
704
|
apiName: model,
|
|
@@ -693,7 +726,7 @@ async function processChunk(
|
|
|
693
726
|
|
|
694
727
|
async function ApexListener(options: { filepath: string, model: string, prompt?: string, lang?: string, apiKey?: string }) {
|
|
695
728
|
|
|
696
|
-
const { filepath, model = '
|
|
729
|
+
const { filepath, model = 'v3', prompt = '', lang = 'en', apiKey = undefined } = options;
|
|
697
730
|
|
|
698
731
|
const validatedLang = validateLanguageInput(lang);
|
|
699
732
|
|
|
@@ -765,9 +798,9 @@ function validateLanguageInput(lang: string): string | null {
|
|
|
765
798
|
async function ApexText2Speech({ ApiKey, inputText, modelName, personality }: {
|
|
766
799
|
ApiKey?: string;
|
|
767
800
|
inputText: string;
|
|
768
|
-
modelName?: "elevenlabs" | "myshell-tts" | "deepinfra-tts";
|
|
801
|
+
modelName?: "elevenlabs" | "myshell-tts" | "deepinfra-tts" | "whisper-large-v3" | "distil-large-v3" | string;
|
|
769
802
|
personality?: string;
|
|
770
|
-
}): Promise<
|
|
803
|
+
}): Promise<Buffer> {
|
|
771
804
|
return await electronSpeech({ ApiKey, inputText, modelName, personality })
|
|
772
805
|
}
|
|
773
806
|
|
|
@@ -779,4 +812,4 @@ async function ApexVideo({ ApiKey, prompt, modelName }: {
|
|
|
779
812
|
return await electronVideo({ ApiKey, prompt, modelName })
|
|
780
813
|
}
|
|
781
814
|
|
|
782
|
-
export { ApexImagine, ApexChat, ApexListener, ApexText2Speech, ApexVideo };
|
|
815
|
+
export { ApexImagine, ApexChat, ApexListener, ApexText2Speech, ApexVideo, resetHistory };
|
package/lib/ai/buttons/tools.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import pdf from "pdf-parse";
|
|
2
2
|
import * as fs from "fs";
|
|
3
3
|
import * as https from "https";
|
|
4
|
-
import { createWriteStream
|
|
4
|
+
import { createWriteStream } from "fs";
|
|
5
5
|
import { promisify } from "util";
|
|
6
|
-
import
|
|
7
|
-
import Tesseract from 'tesseract.js';
|
|
8
|
-
import path from 'path';
|
|
6
|
+
import path from "path";
|
|
9
7
|
|
|
10
8
|
const readFileAsync = promisify(fs.readFile);
|
|
11
9
|
|
|
@@ -14,17 +12,15 @@ export async function readFile(pathOrUrl: string, type?: string): Promise<string
|
|
|
14
12
|
const ext = type || getFileExtension(pathOrUrl);
|
|
15
13
|
|
|
16
14
|
switch (ext) {
|
|
17
|
-
case
|
|
15
|
+
case "pdf":
|
|
18
16
|
return readPdf(buffer);
|
|
19
|
-
case 'csv':
|
|
20
|
-
return readCSV(buffer);
|
|
21
17
|
default:
|
|
22
18
|
return buffer.toString();
|
|
23
19
|
}
|
|
24
20
|
}
|
|
25
21
|
|
|
26
22
|
function getFileExtension(pathOrUrl: string): string | undefined {
|
|
27
|
-
const parsedPath = new URL(pathOrUrl,
|
|
23
|
+
const parsedPath = new URL(pathOrUrl, "file://");
|
|
28
24
|
const pathname = parsedPath.pathname || pathOrUrl;
|
|
29
25
|
const ext = path.extname(pathname).toLowerCase();
|
|
30
26
|
|
|
@@ -32,11 +28,7 @@ function getFileExtension(pathOrUrl: string): string | undefined {
|
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
async function loadFile(pathOrUrl: string): Promise<Buffer> {
|
|
35
|
-
|
|
36
|
-
return downloadFile(pathOrUrl);
|
|
37
|
-
} else {
|
|
38
|
-
return readFileAsync(pathOrUrl);
|
|
39
|
-
}
|
|
31
|
+
return isUrl(pathOrUrl) ? downloadFile(pathOrUrl) : readFileAsync(pathOrUrl);
|
|
40
32
|
}
|
|
41
33
|
|
|
42
34
|
function isUrl(pathOrUrl: string): boolean {
|
|
@@ -44,16 +36,16 @@ function isUrl(pathOrUrl: string): boolean {
|
|
|
44
36
|
}
|
|
45
37
|
|
|
46
38
|
async function downloadFile(url: string): Promise<Buffer> {
|
|
47
|
-
const tempFilePath =
|
|
39
|
+
const tempFilePath = "temp";
|
|
48
40
|
const file = createWriteStream(tempFilePath);
|
|
49
41
|
|
|
50
42
|
await new Promise<void>((resolve, reject) => {
|
|
51
43
|
https.get(url, (response) => {
|
|
52
44
|
// @ts-ignore
|
|
53
45
|
response.pipe(file);
|
|
54
|
-
file.on(
|
|
55
|
-
file.on(
|
|
56
|
-
}).on(
|
|
46
|
+
file.on("finish", resolve);
|
|
47
|
+
file.on("error", reject);
|
|
48
|
+
}).on("error", reject);
|
|
57
49
|
});
|
|
58
50
|
|
|
59
51
|
const buffer = await readFileAsync(tempFilePath);
|
|
@@ -64,20 +56,11 @@ async function downloadFile(url: string): Promise<Buffer> {
|
|
|
64
56
|
async function readPdf(buffer: Buffer): Promise<string> {
|
|
65
57
|
try {
|
|
66
58
|
const data = await pdf(buffer);
|
|
67
|
-
console.log(
|
|
68
|
-
console.log(
|
|
69
|
-
return data.text;
|
|
59
|
+
console.log("PDF Metadata:", data.metadata);
|
|
60
|
+
console.log("PDF Text:", data.text);
|
|
61
|
+
return data.text || "No readable text found in PDF.";
|
|
70
62
|
} catch (err) {
|
|
71
|
-
console.error(
|
|
72
|
-
|
|
73
|
-
return text;
|
|
63
|
+
console.error("Error parsing PDF:", err);
|
|
64
|
+
return "Failed to extract text from PDF.";
|
|
74
65
|
}
|
|
75
66
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
function readCSV(buffer: Buffer): string {
|
|
79
|
-
const csvData = buffer.toString();
|
|
80
|
-
const records = parseCSV(csvData, { columns: true });
|
|
81
|
-
return JSON.stringify(records, null, 2);
|
|
82
|
-
}
|
|
83
|
-
|
|
@@ -1,69 +1,116 @@
|
|
|
1
|
-
import Groq from
|
|
1
|
+
import Groq from "groq-sdk";
|
|
2
2
|
import OpenAI from "openai";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Define static models as readonly to prevent accidental modifications
|
|
5
|
+
export const HERC_CHAT_MODELS = Object.freeze([
|
|
5
6
|
"v3", "v3-32k", "turbo", "turbo-16k", "gemini",
|
|
6
|
-
"llama3-70b", "llama3-8b", "mixtral-8x7b",
|
|
7
|
-
"gemma-7b", "gemma2-9b"
|
|
8
|
-
];
|
|
9
|
-
|
|
10
|
-
export const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
7
|
+
"llama3-70b", "llama3-8b", "mixtral-8x7b",
|
|
8
|
+
"gemma-7b", "gemma2-9b",
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
export const HERC_IMAGE_MODELS = Object.freeze([
|
|
12
|
+
"v3", "lexica", "prodia", "prodia-v2", "simurg",
|
|
13
|
+
"animefy", "raava", "shonin",
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
// API Keys (ensure they are securely stored, do not hardcode in production)
|
|
17
|
+
const GROQ_API_KEY = "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";
|
|
18
|
+
const ELECTRON_HUB_API_KEY = "ek-3gmOPmvuljmrl4NQrohpnp1ryNXQG5bNn08zNuzhX6bcxBrndR";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Initializes the Groq SDK instance.
|
|
22
|
+
*/
|
|
23
|
+
const initializeGroqInstance = (): Groq => new Groq({ apiKey: GROQ_API_KEY });
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Fetches available models from ElectronHub API.
|
|
27
|
+
*/
|
|
28
|
+
export async function getElectronHubModels(apiKey?: string): Promise<string[]> {
|
|
29
|
+
try {
|
|
30
|
+
const openai = new OpenAI({
|
|
31
|
+
apiKey: apiKey ?? ELECTRON_HUB_API_KEY,
|
|
32
|
+
baseURL: "https://api.electronhub.top/v1",
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const models = await openai.models.list();
|
|
36
|
+
|
|
37
|
+
// Ensure models are valid and correctly formatted
|
|
38
|
+
if (!models?.data || !Array.isArray(models.data)) {
|
|
39
|
+
console.warn("Warning: Unexpected ElectronHub models response", models);
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return models.data.map((model) => model.id).filter(Boolean); // Filter out any undefined/null values
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error("Error fetching ElectronHub models:", error);
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
24
48
|
}
|
|
25
49
|
|
|
26
|
-
|
|
27
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Fetches available chat models from Groq API.
|
|
52
|
+
*/
|
|
53
|
+
export async function getGroqChatModels(groqInstance: Groq): Promise<string[]> {
|
|
54
|
+
try {
|
|
55
|
+
const response = await groqInstance.models.list();
|
|
28
56
|
|
|
29
|
-
|
|
30
|
-
!
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
57
|
+
// Ensure response is valid
|
|
58
|
+
if (!response?.data || !Array.isArray(response.data)) {
|
|
59
|
+
console.warn("Warning: Unexpected Groq models response", response);
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
34
62
|
|
|
35
|
-
|
|
36
|
-
|
|
63
|
+
return response.data
|
|
64
|
+
.map((model) => model.id)
|
|
65
|
+
.filter(
|
|
66
|
+
(id) =>
|
|
67
|
+
id &&
|
|
68
|
+
!id.startsWith("whisper") &&
|
|
69
|
+
!id.startsWith("llava") &&
|
|
70
|
+
!id.startsWith("distil-whisper")
|
|
71
|
+
); // Remove unwanted prefixes
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error("Error fetching Groq models:", error);
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
37
77
|
|
|
38
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Fetches and compiles all valid model options.
|
|
80
|
+
*/
|
|
81
|
+
async function initializeValidOptions(): Promise<{
|
|
82
|
+
validHercChatModels: readonly string[];
|
|
83
|
+
validGroqChatModels: string[];
|
|
84
|
+
validElectronModels: string[];
|
|
85
|
+
validHercImageModels: readonly string[];
|
|
86
|
+
allModels: string[];
|
|
87
|
+
}> {
|
|
39
88
|
const groq = initializeGroqInstance();
|
|
40
89
|
|
|
90
|
+
// Fetch models in parallel for better performance
|
|
41
91
|
const [groqModels, electronModels] = await Promise.all([
|
|
42
|
-
|
|
43
|
-
|
|
92
|
+
getGroqChatModels(groq),
|
|
93
|
+
getElectronHubModels(),
|
|
44
94
|
]);
|
|
45
95
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
96
|
+
// Use Set to prevent duplicate entries in `allModels`
|
|
97
|
+
const allModelsSet = new Set([
|
|
98
|
+
...HERC_IMAGE_MODELS,
|
|
99
|
+
...HERC_CHAT_MODELS,
|
|
100
|
+
...groqModels,
|
|
101
|
+
...electronModels,
|
|
102
|
+
]);
|
|
50
103
|
|
|
51
104
|
return {
|
|
52
|
-
validHercChatModels:
|
|
53
|
-
|
|
105
|
+
validHercChatModels: HERC_CHAT_MODELS,
|
|
106
|
+
validGroqChatModels: groqModels,
|
|
54
107
|
validElectronModels: electronModels,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
validEnhancers: [
|
|
58
|
-
"ESRGAN_4x", "Lanczos", "Nearest", "LDSR",
|
|
59
|
-
"R-ESRGAN 4x+", "R-ESRGAN 4x+ Anime6B",
|
|
60
|
-
"ScuNET GAN", "ScuNET PSNR", "SwinIR 4x"
|
|
61
|
-
],
|
|
62
|
-
allModels: [
|
|
63
|
-
...HercImageModels,
|
|
64
|
-
...hercChatModels, ...otherChatModel, ...groqModels, ...electronModels
|
|
65
|
-
]
|
|
108
|
+
validHercImageModels: HERC_IMAGE_MODELS,
|
|
109
|
+
allModels: Array.from(allModelsSet), // Convert Set to array for uniqueness
|
|
66
110
|
};
|
|
67
111
|
}
|
|
68
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Returns all valid model lists asynchronously.
|
|
115
|
+
*/
|
|
69
116
|
export const validateModels = async () => await initializeValidOptions();
|
|
@@ -9,9 +9,9 @@ export async function electronSpeech({
|
|
|
9
9
|
}: {
|
|
10
10
|
ApiKey?: string;
|
|
11
11
|
inputText: string;
|
|
12
|
-
modelName?:
|
|
12
|
+
modelName?: "elevenlabs" | "myshell-tts" | "deepinfra-tts" | "whisper-large-v3" | "distil-large-v3" | string;
|
|
13
13
|
personality?: string;
|
|
14
|
-
}) {
|
|
14
|
+
}): Promise<Buffer> {
|
|
15
15
|
try {
|
|
16
16
|
const apiKey = ApiKey || "ek-3gmOPmvuljmrl4NQrohpnp1ryNXQG5bNn08zNuzhX6bcxBrndR";
|
|
17
17
|
|
|
@@ -3,12 +3,19 @@ import fs from 'fs';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { URL } from 'url';
|
|
5
5
|
import https from 'https';
|
|
6
|
+
import { Uploadable } from 'groq-sdk/uploads.mjs';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Gets the file size of a given path.
|
|
10
|
+
*/
|
|
7
11
|
function getFileSize(filePath: string): number {
|
|
8
12
|
const stats = fs.statSync(filePath);
|
|
9
13
|
return stats.size;
|
|
10
14
|
}
|
|
11
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Creates a readable stream from a local file or a remote URL.
|
|
18
|
+
*/
|
|
12
19
|
async function createReadableStream(filepathOrUrl: string): Promise<NodeJS.ReadableStream | string> {
|
|
13
20
|
const maxFileSizeBytes = 25 * 1024 * 1024;
|
|
14
21
|
|
|
@@ -19,17 +26,18 @@ async function createReadableStream(filepathOrUrl: string): Promise<NodeJS.Reada
|
|
|
19
26
|
|
|
20
27
|
return new Promise((resolve, reject) => {
|
|
21
28
|
const file = fs.createWriteStream(tempFilePath);
|
|
22
|
-
|
|
23
|
-
https.get(filepathOrUrl, (response) => {
|
|
29
|
+
const request = https.get(filepathOrUrl, (response) => {
|
|
24
30
|
let fileSize = 0;
|
|
25
31
|
|
|
26
32
|
response.on('data', (chunk) => {
|
|
27
33
|
fileSize += chunk.length;
|
|
28
34
|
if (fileSize > maxFileSizeBytes) {
|
|
35
|
+
request.destroy(); // Stop downloading
|
|
29
36
|
file.close();
|
|
30
37
|
fs.unlink(tempFilePath, () => {
|
|
31
38
|
resolve('File size exceeds the limit (25MB)');
|
|
32
39
|
});
|
|
40
|
+
return; // Ensure function stops here
|
|
33
41
|
}
|
|
34
42
|
});
|
|
35
43
|
|
|
@@ -42,37 +50,45 @@ async function createReadableStream(filepathOrUrl: string): Promise<NodeJS.Reada
|
|
|
42
50
|
}
|
|
43
51
|
});
|
|
44
52
|
});
|
|
45
|
-
})
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
request.on('error', (err) => {
|
|
46
56
|
fs.unlink(tempFilePath, () => {
|
|
47
57
|
reject(err);
|
|
48
58
|
});
|
|
49
59
|
});
|
|
50
60
|
});
|
|
51
61
|
} else {
|
|
52
|
-
|
|
53
|
-
if (fileSize > maxFileSizeBytes) {
|
|
62
|
+
if (getFileSize(filepathOrUrl) > maxFileSizeBytes) {
|
|
54
63
|
return 'File size exceeds the limit (25MB)';
|
|
55
64
|
}
|
|
56
65
|
return fs.createReadStream(filepathOrUrl);
|
|
57
66
|
}
|
|
58
67
|
}
|
|
59
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Transcribes audio using Groq Whisper API.
|
|
71
|
+
*/
|
|
60
72
|
export async function whisper(prompt: string, filepath: string, lang?: string, API_KEY?: string) {
|
|
61
73
|
try {
|
|
62
74
|
const groq = new Groq({
|
|
63
75
|
apiKey: API_KEY || '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',
|
|
64
76
|
});
|
|
65
77
|
|
|
66
|
-
|
|
78
|
+
// Ensure filepath is properly resolved
|
|
79
|
+
const resolvedFilePath = filepath.startsWith('http') || path.isAbsolute(filepath)
|
|
80
|
+
? filepath
|
|
81
|
+
: path.join(process.cwd(), filepath);
|
|
82
|
+
|
|
83
|
+
const fileStream = await createReadableStream(resolvedFilePath);
|
|
67
84
|
|
|
68
85
|
if (typeof fileStream === 'string') {
|
|
69
86
|
return fileStream;
|
|
70
87
|
}
|
|
71
88
|
|
|
72
89
|
const transcription = await groq.audio.transcriptions.create({
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
model: "whisper-large-v3",
|
|
90
|
+
file: fileStream as Uploadable,
|
|
91
|
+
model: "whisper-large-v3-turbo",
|
|
76
92
|
prompt: prompt,
|
|
77
93
|
temperature: 1,
|
|
78
94
|
language: lang || 'eng',
|
|
@@ -81,19 +97,17 @@ export async function whisper(prompt: string, filepath: string, lang?: string, A
|
|
|
81
97
|
|
|
82
98
|
return transcription.text;
|
|
83
99
|
} catch (err: any) {
|
|
84
|
-
if (err
|
|
85
|
-
|
|
86
|
-
return 'Bad request, try again after a minute please.';
|
|
87
|
-
|
|
88
|
-
return '
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
console.error(err);
|
|
93
|
-
return "Unknown error occurred.";
|
|
100
|
+
if (err?.status) {
|
|
101
|
+
switch (err.status) {
|
|
102
|
+
case 400: return 'Bad request, try again after a minute please.';
|
|
103
|
+
case 429: return 'Rate limit exceeded, try again later or provide your own API key.';
|
|
104
|
+
case 401: return 'Invalid API key provided.';
|
|
105
|
+
default:
|
|
106
|
+
console.error(err);
|
|
107
|
+
return "An unknown error occurred.";
|
|
94
108
|
}
|
|
95
109
|
}
|
|
96
110
|
console.error(err);
|
|
97
|
-
return '
|
|
111
|
+
return 'An unknown error occurred.';
|
|
98
112
|
}
|
|
99
113
|
}
|
package/lib/ai/utils.ts
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
import { imageReader } from "./functions/imageReader";
|
|
2
|
-
import { chunkString } from "./functions/chunkString";
|
|
3
|
-
import { toDraw } from "./functions/shouldDrawImage";
|
|
4
|
-
import { aiImagine } from "./functions/draw";
|
|
5
1
|
import { readFile } from "./functions/readFiles";
|
|
6
|
-
import { ApexChat, ApexImagine, ApexListener, ApexVideo, ApexText2Speech } from "./ApexModules";
|
|
2
|
+
import { ApexChat, ApexImagine, ApexListener, ApexVideo, ApexText2Speech, resetHistory } from "./ApexModules";
|
|
7
3
|
import { typeWriter } from "./functions/typeWriter" ;
|
|
8
4
|
import { groqAnalyzer } from "./modals-chat/groq/imageAnalyzer";
|
|
9
5
|
|
|
10
6
|
|
|
11
7
|
export {
|
|
12
|
-
chunkString,
|
|
13
|
-
imageReader,
|
|
14
|
-
toDraw,
|
|
15
|
-
aiImagine,
|
|
16
8
|
readFile,
|
|
17
9
|
ApexChat,
|
|
18
10
|
ApexImagine,
|
|
@@ -20,5 +12,6 @@ export {
|
|
|
20
12
|
typeWriter,
|
|
21
13
|
groqAnalyzer,
|
|
22
14
|
ApexVideo,
|
|
23
|
-
ApexText2Speech
|
|
15
|
+
ApexText2Speech,
|
|
16
|
+
resetHistory
|
|
24
17
|
};
|
|
@@ -89,120 +89,34 @@ export function applyZoom(
|
|
|
89
89
|
height: number
|
|
90
90
|
): void {
|
|
91
91
|
if (!stroke) return;
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
ctx.save();
|
|
94
|
+
ctx.beginPath();
|
|
95
|
+
|
|
96
|
+
const gradient = createGradient(ctx, stroke.gradient, x, y, x + width, y + height);
|
|
97
|
+
ctx.strokeStyle = gradient;
|
|
94
98
|
|
|
95
|
-
ctx.
|
|
96
|
-
|
|
97
|
-
: stroke.color || "transparent";
|
|
98
|
-
|
|
99
|
-
ctx.lineWidth = stroke.width ?? 0;
|
|
100
|
-
|
|
99
|
+
ctx.lineWidth = stroke.width && stroke.width > 0 ? stroke.width : 2;
|
|
100
|
+
|
|
101
101
|
const positionOffset = stroke.position ?? 0;
|
|
102
102
|
const halfStroke = ctx.lineWidth / 2;
|
|
103
|
-
const totalOffset = positionOffset + halfStroke;
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
103
|
+
const totalOffset = positionOffset > 0 ? positionOffset + halfStroke : 0;
|
|
104
|
+
|
|
105
|
+
const adjustedBorderRadius = stroke.borderRadius === "circular"
|
|
106
|
+
? "circular"
|
|
107
|
+
: (stroke.borderRadius ?? 2) + halfStroke;
|
|
108
|
+
|
|
109
|
+
const adjustedX = x - totalOffset;
|
|
110
|
+
const adjustedY = y - totalOffset;
|
|
107
111
|
const adjustedWidth = width + totalOffset * 2;
|
|
108
112
|
const adjustedHeight = height + totalOffset * 2;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
objectRadius(
|
|
112
|
-
ctx,
|
|
113
|
-
adjustedX,
|
|
114
|
-
adjustedY,
|
|
115
|
-
adjustedWidth,
|
|
116
|
-
adjustedHeight,
|
|
117
|
-
stroke.borderRadius ?? 2,
|
|
118
|
-
"all"
|
|
119
|
-
);
|
|
120
|
-
ctx.stroke();
|
|
121
|
-
ctx.restore();
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const bp = stroke.borderPosition.toLowerCase();
|
|
126
|
-
const positions = bp.split(',').map(s => s.trim());
|
|
127
|
-
|
|
128
|
-
ctx.beginPath();
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
positions.includes("top") ||
|
|
132
|
-
positions.includes("top-left") ||
|
|
133
|
-
positions.includes("top-right")
|
|
134
|
-
) {
|
|
135
|
-
const tl = positions.includes("top-left") || positions.includes("top")
|
|
136
|
-
? (stroke.borderRadius ? +stroke.borderRadius : 0)
|
|
137
|
-
: 0;
|
|
138
|
-
const tr = positions.includes("top-right") || positions.includes("top")
|
|
139
|
-
? (stroke.borderRadius ? +stroke.borderRadius : 0)
|
|
140
|
-
: 0;
|
|
141
|
-
ctx.moveTo(adjustedX + tl, adjustedY);
|
|
142
|
-
ctx.lineTo(adjustedX + adjustedWidth - tr, adjustedY);
|
|
143
|
-
if (tr > 0) {
|
|
144
|
-
ctx.quadraticCurveTo(adjustedX + adjustedWidth, adjustedY, adjustedX + adjustedWidth, adjustedY + tr);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
positions.includes("right") ||
|
|
150
|
-
positions.includes("top-right") ||
|
|
151
|
-
positions.includes("bottom-right")
|
|
152
|
-
) {
|
|
153
|
-
const tr = positions.includes("top-right") || positions.includes("right")
|
|
154
|
-
? (stroke.borderRadius ? +stroke.borderRadius : 0)
|
|
155
|
-
: 0;
|
|
156
|
-
const br = positions.includes("bottom-right") || positions.includes("right")
|
|
157
|
-
? (stroke.borderRadius ? +stroke.borderRadius : 0)
|
|
158
|
-
: 0;
|
|
159
|
-
ctx.moveTo(adjustedX + adjustedWidth, adjustedY + tr);
|
|
160
|
-
ctx.lineTo(adjustedX + adjustedWidth, adjustedY + adjustedHeight - br);
|
|
161
|
-
if (br > 0) {
|
|
162
|
-
ctx.quadraticCurveTo(adjustedX + adjustedWidth, adjustedY + adjustedHeight, adjustedX + adjustedWidth - br, adjustedY + adjustedHeight);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
positions.includes("bottom") ||
|
|
168
|
-
positions.includes("bottom-left") ||
|
|
169
|
-
positions.includes("bottom-right")
|
|
170
|
-
) {
|
|
171
|
-
const bl = positions.includes("bottom-left") || positions.includes("bottom")
|
|
172
|
-
? (stroke.borderRadius ? +stroke.borderRadius : 0)
|
|
173
|
-
: 0;
|
|
174
|
-
const br = positions.includes("bottom-right") || positions.includes("bottom")
|
|
175
|
-
? (stroke.borderRadius ? +stroke.borderRadius : 0)
|
|
176
|
-
: 0;
|
|
177
|
-
ctx.moveTo(adjustedX + bl, adjustedY + adjustedHeight);
|
|
178
|
-
ctx.lineTo(adjustedX + adjustedWidth - br, adjustedY + adjustedHeight);
|
|
179
|
-
if (br > 0) {
|
|
180
|
-
ctx.quadraticCurveTo(adjustedX + adjustedWidth, adjustedY + adjustedHeight, adjustedX + adjustedWidth, adjustedY + adjustedHeight - br);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (
|
|
185
|
-
positions.includes("left") ||
|
|
186
|
-
positions.includes("top-left") ||
|
|
187
|
-
positions.includes("bottom-left")
|
|
188
|
-
) {
|
|
189
|
-
const tl = positions.includes("top-left") || positions.includes("left")
|
|
190
|
-
? (stroke.borderRadius ? +stroke.borderRadius : 0)
|
|
191
|
-
: 0;
|
|
192
|
-
const bl = positions.includes("bottom-left") || positions.includes("left")
|
|
193
|
-
? (stroke.borderRadius ? +stroke.borderRadius : 0)
|
|
194
|
-
: 0;
|
|
195
|
-
ctx.moveTo(adjustedX, adjustedY + tl);
|
|
196
|
-
ctx.lineTo(adjustedX, adjustedY + adjustedHeight - bl);
|
|
197
|
-
if (bl > 0) {
|
|
198
|
-
ctx.quadraticCurveTo(adjustedX, adjustedY + adjustedHeight, adjustedX + bl, adjustedY + adjustedHeight);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
113
|
+
|
|
114
|
+
objectRadius(ctx, adjustedX, adjustedY, adjustedWidth, adjustedHeight, adjustedBorderRadius, "all");
|
|
201
115
|
|
|
202
116
|
ctx.stroke();
|
|
203
117
|
ctx.restore();
|
|
204
118
|
}
|
|
205
|
-
|
|
119
|
+
|
|
206
120
|
/**
|
|
207
121
|
* Draws a shape on the canvas context based on the provided settings.
|
|
208
122
|
* Supports built‑in shapes as well as a custom polygon.
|