UNPKG

gpt4all-ts-client

Version:
202 lines (200 loc) 7.24 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/gpt4all.ts import { exec, spawn } from "child_process"; import { promisify } from "util"; import * as fs from "fs"; import * as os from "os"; import cliProgress from "cli-progress"; import got from "got"; import debug from "debug"; var debugging = debug("gpt4all"); var downloadFile = (url, path) => __async(void 0, null, function* () { debugging(`Downloading ${url} to ${path}`); const stream = fs.createWriteStream(path); const progressBar = new cliProgress.SingleBar( {}, cliProgress.Presets.shades_classic ); progressBar.start(100, 0); const response = got.stream(url); let totalLength = 0; let downloadedLength = 0; response.on("downloadProgress", (progress) => { downloadedLength = progress.transferred; totalLength = progress.total; if (totalLength === 0) return; const progressPercent = downloadedLength / totalLength * 100; progressBar.update(progressPercent); }); response.pipe(stream); return new Promise((resolve, reject) => { stream.on("finish", () => { progressBar.stop(); resolve(url); }); stream.on("error", reject); }); }); var GPT4All = class { constructor(model = "gpt4all-lora-quantized", decoderConfig = {}) { this.bot = null; this.model = model; this.decoderConfig = decoderConfig; if ("gpt4all-lora-quantized" !== model && "gpt4all-lora-unfiltered-quantized" !== model) { throw new Error(`Model ${model} is not supported. Current models supported are: gpt4all-lora-quantized gpt4all-lora-unfiltered-quantized`); } this.executablePath = os.platform() === "win32" ? `${os.homedir()}/.nomic/gpt4all.exe` : `${os.homedir()}/.nomic/gpt4all`; this.modelPath = `${os.homedir()}/.nomic/${model}.bin`; } init(forceDownload = false) { return __async(this, null, function* () { debugging("Initializing GPT4All"); if (forceDownload || !fs.existsSync(this.executablePath)) { yield this.downloadExecutable(); } if (forceDownload || !fs.existsSync(this.modelPath)) { yield this.downloadModel(); } }); } open() { return __async(this, null, function* () { debugging("Opening GPT4All"); if (this.bot !== null) { this.close(); } let spawnArgs = [this.executablePath, "--model", this.modelPath]; for (let [key, value] of Object.entries(this.decoderConfig)) { spawnArgs.push(`--${key}`, value.toString()); } this.bot = spawn(spawnArgs[0], spawnArgs.slice(1), { stdio: ["pipe", "pipe", "ignore"] }); yield new Promise((resolve) => { var _a, _b; (_b = (_a = this.bot) == null ? void 0 : _a.stdout) == null ? void 0 : _b.on("data", (data) => { if (data.toString().includes(">")) { resolve(true); } }); }); }); } close() { debugging("Closing GPT4All"); if (this.bot !== null) { this.bot.kill(); this.bot = null; } } downloadExecutable() { return __async(this, null, function* () { debugging("Downloading GPT4All executable"); let upstream; const platform2 = os.platform(); if (platform2 === "darwin") { const { stdout } = yield promisify(exec)("uname -m"); if (stdout.trim() === "arm64") { upstream = "https://github.com/nomic-ai/gpt4all/blob/main/chat/gpt4all-lora-quantized-OSX-m1?raw=true"; } else { upstream = "https://github.com/nomic-ai/gpt4all/blob/main/chat/gpt4all-lora-quantized-OSX-intel?raw=true"; } } else if (platform2 === "linux") { upstream = "https://github.com/nomic-ai/gpt4all/blob/main/chat/gpt4all-lora-quantized-linux-x86?raw=true"; } else if (platform2 === "win32") { upstream = "https://github.com/nomic-ai/gpt4all/blob/main/chat/gpt4all-lora-quantized-win64.exe?raw=true"; } else { throw new Error( `Your platform is not supported: ${platform2}. Current binaries supported are for OSX (ARM and Intel), Linux and Windows.` ); } yield downloadFile(upstream, this.executablePath); fs.chmod(this.executablePath, 493, (err) => { if (err) { throw err; } }); }); } // TODO: support GPT4All community models downloadModel() { return __async(this, null, function* () { debugging("Downloading GPT4All model"); const modelUrl = `https://the-eye.eu/public/AI/models/nomic-ai/gpt4all/${this.model}.bin`; return downloadFile(modelUrl, this.modelPath); }); } prompt(prompt) { var _a, _b; debugging("Prompting GPT4All with:", prompt); if (this.bot === null) { throw new Error("Bot is not initialized."); } (_b = (_a = this.bot) == null ? void 0 : _a.stdin) == null ? void 0 : _b.write(prompt + "\n"); return new Promise((resolve, reject) => { var _a2, _b2, _c, _d; let response = ""; let timeoutId; const onStdoutData = (data) => { const text = data.toString(); if (timeoutId) { clearTimeout(timeoutId); } if (text.includes(">")) { debugging("Response starts with >, end of message - Resolving..."); terminateAndResolve(response); } else { timeoutId = setTimeout(() => { debugging("Timeout reached - Resolving..."); terminateAndResolve(response); }, 4e3); } debugging("Received text:", text); response += text; debugging("Updated response:", response); }; const onStdoutError = (err) => { var _a3, _b3, _c2, _d2; (_b3 = (_a3 = this.bot) == null ? void 0 : _a3.stdout) == null ? void 0 : _b3.removeListener("data", onStdoutData); (_d2 = (_c2 = this.bot) == null ? void 0 : _c2.stdout) == null ? void 0 : _d2.removeListener("error", onStdoutError); reject(err); }; const terminateAndResolve = (finalResponse) => { var _a3, _b3, _c2, _d2; (_b3 = (_a3 = this.bot) == null ? void 0 : _a3.stdout) == null ? void 0 : _b3.removeListener("data", onStdoutData); (_d2 = (_c2 = this.bot) == null ? void 0 : _c2.stdout) == null ? void 0 : _d2.removeListener("error", onStdoutError); if (finalResponse.endsWith(">")) { finalResponse = finalResponse.slice(0, -1); } resolve(finalResponse); }; (_b2 = (_a2 = this.bot) == null ? void 0 : _a2.stdout) == null ? void 0 : _b2.on("data", onStdoutData); (_d = (_c = this.bot) == null ? void 0 : _c.stdout) == null ? void 0 : _d.on("error", onStdoutError); }); } }; export { GPT4All };