Skip to content

Commit 190ef96

Browse files
authored
feat: export llama.cpp release info (#91)
* feat: export `llama.cpp` release info * feat: make it easier to use imported `build` and `download` commands from other libraries
1 parent 8f29277 commit 190ef96

File tree

10 files changed

+115
-12
lines changed

10 files changed

+115
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ node_modules
1414

1515
/llama/compile_commands.json
1616
/llama/llama.cpp
17+
/llama/llama.cpp.tag.json
1718
/llama/gitRelease.bundle
1819
/llama/.temp
1920
/llama/build

src/cli/commands/BuildCommand.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import {getIsInDocumentationMode} from "../../state.js";
1313
type BuildCommand = {
1414
arch?: string,
1515
nodeTarget?: string,
16-
metal: boolean,
17-
cuda: boolean
16+
metal?: boolean,
17+
cuda?: boolean
1818
};
1919

2020
export const BuildCommand: CommandModule<object, BuildCommand> = {
@@ -48,7 +48,12 @@ export const BuildCommand: CommandModule<object, BuildCommand> = {
4848
handler: BuildLlamaCppCommand
4949
};
5050

51-
export async function BuildLlamaCppCommand({arch, nodeTarget, metal, cuda}: BuildCommand) {
51+
export async function BuildLlamaCppCommand({
52+
arch = undefined,
53+
nodeTarget = undefined,
54+
metal = defaultLlamaCppMetalSupport,
55+
cuda = defaultLlamaCppCudaSupport
56+
}: BuildCommand) {
5257
if (!(await fs.pathExists(llamaCppDirectory))) {
5358
console.log(chalk.red('llama.cpp is not downloaded. Please run "node-llama-cpp download" first'));
5459
process.exit(1);

src/cli/commands/ClearCommand.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {CommandModule} from "yargs";
22
import fs from "fs-extra";
33
import chalk from "chalk";
4-
import {llamaCppDirectory} from "../../config.js";
4+
import {llamaCppDirectory, llamaCppDirectoryTagFilePath} from "../../config.js";
55
import withOra from "../../utils/withOra.js";
66
import {clearLlamaBuild} from "../../utils/clearLlamaBuild.js";
77
import {setUsedBinFlag} from "../../utils/usedBinFlag.js";
@@ -35,6 +35,7 @@ export async function ClearLlamaCppBuildCommand({type}: ClearCommand) {
3535
fail: chalk.blue("Failed to clear source")
3636
}, async () => {
3737
await fs.remove(llamaCppDirectory);
38+
await fs.remove(llamaCppDirectoryTagFilePath);
3839
});
3940
}
4041

src/cli/commands/DownloadCommand.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {Octokit} from "octokit";
44
import fs from "fs-extra";
55
import chalk from "chalk";
66
import {
7-
defaultLlamaCppCudaSupport, defaultLlamaCppGitHubRepo, defaultLlamaCppMetalSupport, defaultLlamaCppRelease, isCI, llamaCppDirectory
7+
defaultLlamaCppCudaSupport, defaultLlamaCppGitHubRepo, defaultLlamaCppMetalSupport, defaultLlamaCppRelease, isCI,
8+
llamaCppDirectory, llamaCppDirectoryTagFilePath
89
} from "../../config.js";
910
import {compileLlamaCpp} from "../../utils/compileLLamaCpp.js";
1011
import withOra from "../../utils/withOra.js";
@@ -20,14 +21,16 @@ import {
2021
import {cloneLlamaCppRepo} from "../../utils/cloneLlamaCppRepo.js";
2122

2223
type DownloadCommandArgs = {
23-
repo: string,
24-
release: "latest" | string,
24+
repo?: string,
25+
release?: "latest" | string,
2526
arch?: string,
2627
nodeTarget?: string,
27-
metal: boolean,
28-
cuda: boolean,
28+
metal?: boolean,
29+
cuda?: boolean,
2930
skipBuild?: boolean,
3031
noBundle?: boolean,
32+
33+
/** @internal */
3134
updateBinariesReleaseMetadataAndSaveGitBundle?: boolean
3235
};
3336

@@ -92,7 +95,15 @@ export const DownloadCommand: CommandModule<object, DownloadCommandArgs> = {
9295
};
9396

9497
export async function DownloadLlamaCppCommand({
95-
repo, release, arch, nodeTarget, metal, cuda, skipBuild, noBundle, updateBinariesReleaseMetadataAndSaveGitBundle
98+
repo = defaultLlamaCppGitHubRepo,
99+
release = defaultLlamaCppRelease,
100+
arch = undefined,
101+
nodeTarget = undefined,
102+
metal = defaultLlamaCppMetalSupport,
103+
cuda = defaultLlamaCppCudaSupport,
104+
skipBuild = false,
105+
noBundle = false,
106+
updateBinariesReleaseMetadataAndSaveGitBundle = false
96107
}: DownloadCommandArgs) {
97108
const useBundle = noBundle != true;
98109
const octokit = new Octokit();
@@ -162,6 +173,7 @@ export async function DownloadLlamaCppCommand({
162173
fail: chalk.blue("Failed to remove existing llama.cpp directory")
163174
}, async () => {
164175
await fs.remove(llamaCppDirectory);
176+
await fs.remove(llamaCppDirectoryTagFilePath);
165177
});
166178

167179
console.log(chalk.blue("Cloning llama.cpp"));

src/commands.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {BuildLlamaCppCommand} from "./cli/commands/BuildCommand.js";
22
import {DownloadLlamaCppCommand} from "./cli/commands/DownloadCommand.js";
33
import {ClearLlamaCppBuildCommand} from "./cli/commands/ClearCommand.js";
4+
import {getBuildDefaults} from "./utils/getBuildDefaults.js";
45

5-
export {BuildLlamaCppCommand, DownloadLlamaCppCommand, ClearLlamaCppBuildCommand};
6+
export {BuildLlamaCppCommand, DownloadLlamaCppCommand, ClearLlamaCppBuildCommand, getBuildDefaults};

src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const tempDownloadDirectory = path.join(os.tmpdir(), "node-llama-cpp", uu
2121
export const chatCommandHistoryFilePath = path.join(os.homedir(), ".node-llama-cpp.chat_repl_history");
2222
export const usedBinFlagJsonPath = path.join(llamaDirectory, "usedBin.json");
2323
export const binariesGithubReleasePath = path.join(llamaDirectory, "binariesGithubRelease.json");
24+
export const llamaCppDirectoryTagFilePath = path.join(llamaDirectory, "llama.cpp.tag.json");
2425
export const currentReleaseGitBundlePath = path.join(llamaDirectory, "gitRelease.bundle");
2526
export const xpackDirectory = path.join(llamaDirectory, "xpack");
2627
export const localXpacksStoreDirectory = path.join(xpackDirectory, "store");

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {GeneralChatPromptWrapper} from "./chatWrappers/GeneralChatPromptWrapper.
1515
import {ChatMLChatPromptWrapper} from "./chatWrappers/ChatMLChatPromptWrapper.js";
1616
import {FalconChatPromptWrapper} from "./chatWrappers/FalconChatPromptWrapper.js";
1717
import {getChatWrapperByBos} from "./chatWrappers/createChatWrapperByBos.js";
18+
import {getReleaseInfo} from "./utils/getReleaseInfo.js";
1819

1920
import {type ConversationInteraction, type Token} from "./types.js";
2021
import {
@@ -48,6 +49,7 @@ export {
4849
ChatMLChatPromptWrapper,
4950
FalconChatPromptWrapper,
5051
getChatWrapperByBos,
52+
getReleaseInfo,
5153
type Token,
5254
type GbnfJsonSchema,
5355
type GbnfJsonSchemaToType,

src/utils/cloneLlamaCppRepo.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ import simpleGit, {SimpleGit} from "simple-git";
22
import cliProgress from "cli-progress";
33
import chalk from "chalk";
44
import fs from "fs-extra";
5-
import {llamaCppDirectory} from "../config.js";
5+
import {llamaCppDirectory, llamaCppDirectoryTagFilePath} from "../config.js";
66
import {getGitBundlePathForRelease} from "./gitReleaseBundles.js";
77

8+
type ClonedLlamaCppRepoTagFile = {
9+
tag: string
10+
};
11+
812

913
export async function cloneLlamaCppRepo(githubOwner: string, githubRepo: string, tag: string, useBundles: boolean = true) {
1014
const gitBundleForTag = !useBundles ? null : await getGitBundlePathForRelease(githubOwner, githubRepo, tag);
@@ -54,6 +58,7 @@ export async function cloneLlamaCppRepo(githubOwner: string, githubRepo: string,
5458
return;
5559
} catch (err) {
5660
await fs.remove(llamaCppDirectory);
61+
await fs.remove(llamaCppDirectoryTagFilePath);
5762
console.error("Failed to clone git bundle, cloning from GitHub instead", err);
5863

5964
printCloneErrorHelp(String(err));
@@ -73,6 +78,20 @@ export async function cloneLlamaCppRepo(githubOwner: string, githubRepo: string,
7378

7479
throw err;
7580
}
81+
82+
try {
83+
const clonedLlamaCppRepoTagJson: ClonedLlamaCppRepoTagFile = {
84+
tag
85+
};
86+
87+
await fs.writeJson(llamaCppDirectoryTagFilePath, clonedLlamaCppRepoTagJson, {
88+
spaces: 4
89+
});
90+
} catch (err) {
91+
console.error("Failed to write llama.cpp tag file", err);
92+
93+
throw err;
94+
}
7695
}
7796

7897
function printCloneErrorHelp(error: string) {
@@ -87,3 +106,17 @@ function printCloneErrorHelp(error: string) {
87106
'git config --global --add safe.directory "*"'
88107
);
89108
}
109+
110+
export async function getClonedLlamaCppRepoReleaseTag() {
111+
if (!(await fs.pathExists(llamaCppDirectoryTagFilePath)))
112+
return null;
113+
114+
try {
115+
const clonedLlamaCppRepoTagJson: ClonedLlamaCppRepoTagFile = await fs.readJson(llamaCppDirectoryTagFilePath);
116+
117+
return clonedLlamaCppRepoTagJson.tag;
118+
} catch (err) {
119+
console.error("Failed to read llama.cpp tag file", err);
120+
return null;
121+
}
122+
}

src/utils/getBuildDefaults.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {
2+
defaultLlamaCppCudaSupport, defaultLlamaCppGitHubRepo, defaultLlamaCppMetalSupport, defaultLlamaCppRelease
3+
} from "../config.js";
4+
5+
export async function getBuildDefaults() {
6+
return {
7+
repo: defaultLlamaCppGitHubRepo,
8+
release: defaultLlamaCppRelease,
9+
metalSupport: defaultLlamaCppMetalSupport,
10+
cudaSupport: defaultLlamaCppCudaSupport
11+
};
12+
}

src/utils/getReleaseInfo.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import path from "path";
2+
import {fileURLToPath} from "url";
3+
import fs from "fs-extra";
4+
import {getUsedBinFlag} from "./usedBinFlag.js";
5+
import {getClonedLlamaCppRepoReleaseTag} from "./cloneLlamaCppRepo.js";
6+
import {getBinariesGithubRelease} from "./binariesGithubRelease.js";
7+
8+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
9+
10+
export async function getReleaseInfo() {
11+
const [usedBinFlag, moduleVersion] = await Promise.all([
12+
getUsedBinFlag(),
13+
getModuleVersion()
14+
]);
15+
16+
const release = usedBinFlag === "prebuiltBinaries"
17+
? await getBinariesGithubRelease()
18+
: (await getClonedLlamaCppRepoReleaseTag() ?? await getBinariesGithubRelease());
19+
20+
return {
21+
llamaCpp: {
22+
binarySource: usedBinFlag === "prebuiltBinaries"
23+
? "included"
24+
: "builtLocally",
25+
release
26+
},
27+
moduleVersion
28+
};
29+
}
30+
31+
async function getModuleVersion(): Promise<string> {
32+
const packageJson = await fs.readJson(path.join(__dirname, "..", "..", "package.json"));
33+
34+
return packageJson.version;
35+
}

0 commit comments

Comments
 (0)