UNPKG

node-llama-cpp

Version:

Run AI models locally on your machine with node.js bindings for llama.cpp. Enforce a JSON schema on the model output on the generation level

143 lines 5.76 kB
import path from "path"; import fs from "fs-extra"; import which from "which"; import chalk from "chalk"; import { chmodr } from "chmodrp"; import { defaultXpacksCacheDirectory, defaultXpacksStoreDirectory, llamaDirectory, localXpacksCacheDirectory, localXpacksStoreDirectory, xpackDirectory, xpmVersion } from "../config.js"; import { logDistroInstallInstruction } from "../bindings/utils/logDistroInstallInstruction.js"; import { getPlatform } from "../bindings/utils/getPlatform.js"; import { getWindowsVisualStudioEditionPaths } from "../bindings/utils/detectBuildTools.js"; import { spawnCommand } from "./spawnCommand.js"; import withStatusLogs from "./withStatusLogs.js"; import { withLockfile } from "./withLockfile.js"; export async function hasBuiltinCmake() { try { const resolvedPath = await which("cmake"); return resolvedPath !== ""; } catch (err) { return false; } } export async function getCmakePath() { try { const resolvedPath = await which("cmake", { nothrow: true }); if (resolvedPath !== "" && resolvedPath != null) return resolvedPath; } catch (err) { } try { const existingCmake = await findExistingCmake(); if (existingCmake != null) return existingCmake; } catch (err) { } try { let resolvedPath = await which("cmake", { path: path.join(llamaDirectory, "xpack", "xpacks", ".bin") }); if (resolvedPath.toLowerCase().endsWith(".cmd")) resolvedPath = (await getBinFromWindowCmd(resolvedPath, "cmake.exe")) ?? ""; else if (resolvedPath.toLowerCase().endsWith(".ps1")) { const cmdFilePath = resolvedPath.slice(0, -".ps1".length) + ".cmd"; if (await fs.pathExists(cmdFilePath)) resolvedPath = (await getBinFromWindowCmd(cmdFilePath, "cmake.exe")) ?? ""; } if (resolvedPath !== "") return resolvedPath; } catch (err) { } throw new Error("cmake not found"); } export async function downloadCmakeIfNeeded(wrapWithStatusLogs = false) { try { await getCmakePath(); return; } catch (err) { } if (!wrapWithStatusLogs) await downloadCmake({ progressLogs: wrapWithStatusLogs }); else { try { await withStatusLogs({ loading: chalk.blue("Downloading cmake"), success: chalk.blue("Downloaded cmake"), fail: chalk.blue("Failed to download cmake") }, async () => { await downloadCmake({ progressLogs: wrapWithStatusLogs }); }); } catch (err) { await logDistroInstallInstruction('To install "cmake", ', { linuxPackages: { apt: ["cmake"], apk: ["cmake"] }, macOsPackages: { brew: ["cmake"] } }); throw err; } } } export async function clearLocalCmake() { await fs.remove(localXpacksStoreDirectory); await fs.remove(localXpacksCacheDirectory); await fs.remove(path.join(xpackDirectory, "xpacks")); } /** * There's an issue where after a compilation, the cmake binaries have permissions that don't allow them to be deleted. * This function fixes that. * It should be run after each compilation. */ export async function fixXpackPermissions() { try { await chmodr(localXpacksStoreDirectory, 0o777); await chmodr(localXpacksCacheDirectory, 0o777); await chmodr(path.join(xpackDirectory, "xpacks"), 0o777); } catch (err) { } } async function findExistingCmake() { const platform = getPlatform(); if (platform === "win") { const { vsEditionPaths } = await getWindowsVisualStudioEditionPaths(); const potentialCmakePaths = vsEditionPaths.map((editionPath) => (path.join(editionPath, "Common7", "IDE", "CommonExtensions", "Microsoft", "CMake", "CMake", "bin", "cmake.exe"))); const cmakePaths = (await Promise.all(potentialCmakePaths.map(async (cmakePath) => { if (await fs.pathExists(cmakePath)) return cmakePath; return null; }))) .filter((cmakePath) => cmakePath != null); return cmakePaths[0]; } return undefined; } async function downloadCmake({ progressLogs = true } = {}) { await withLockfile({ resourcePath: path.join(xpackDirectory, "cmakeInstall") }, async () => { const xpmEnv = { ...process.env, XPACKS_STORE_FOLDER: defaultXpacksStoreDirectory, XPACKS_CACHE_FOLDER: defaultXpacksCacheDirectory }; await spawnCommand("npm", ["exec", "--yes", "--", `xpm@${xpmVersion}`, "install", "@xpack-dev-tools/cmake@latest", "--no-save"], xpackDirectory, xpmEnv, progressLogs); await fs.remove(localXpacksCacheDirectory); await fixXpackPermissions(); }); } async function getBinFromWindowCmd(cmdFilePath, binName) { const fileContent = await fs.readFile(cmdFilePath, "utf8"); const lowercaseFileContent = fileContent.toLowerCase(); if (!lowercaseFileContent.includes(binName)) return null; const lastIndexOfBinName = lowercaseFileContent.lastIndexOf(binName); const characterAfterBinName = fileContent[lastIndexOfBinName + binName.length]; if (characterAfterBinName !== '"' && characterAfterBinName !== "'") return null; const startStringCharacter = fileContent.lastIndexOf(characterAfterBinName, lastIndexOfBinName); const binPath = fileContent.slice(startStringCharacter + 1, lastIndexOfBinName + binName.length); if (!await fs.pathExists(binPath)) return null; return binPath; } //# sourceMappingURL=cmake.js.map