Skip to content

Commit 7a5c810

Browse files
authored
ESM & typescript (#22)
* move to ES
1 parent 832b0fa commit 7a5c810

23 files changed

+2352
-285
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ node_modules/
22
build/
33
example/
44
model.gguf
5-
.vscode/
5+
.vscode/
6+
dist

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ sudo apt-get install -y build-essential cmake g++
4646

4747
```javascript
4848

49-
const { RunInference } = require('@duck4i/llama');
49+
import { RunInference } = from "@duck4i/llama";
5050

5151
const system_prompt = "The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly.";
5252
const user_prompt = "What is life expectancy of a duck?";
@@ -60,7 +60,7 @@ console.log("Answer", inference);
6060
It is likely you will want async functions for better memory management with multiple prompts, which is done like this:
6161

6262
```javascript
63-
const { LoadModelAsync, CreateContextAsync, RunInferenceAsync, ReleaseContextAsync, ReleaseModelAsync } = require('@duck4i/llama');
63+
import { LoadModelAsync, CreateContextAsync, RunInferenceAsync, ReleaseContextAsync, ReleaseModelAsync } = from "@duck4i/llama";
6464

6565
const system_prompt = "The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly.";
6666
const prompts = [
@@ -118,7 +118,7 @@ You can control log levels coming from llamacpp like this:
118118

119119
```javascript
120120

121-
const { SetLogLevel } = require('@duck4i/llama');
121+
import { SetLogLevel } = from '@duck4i/llama';
122122

123123
// 0 - none, 1 - debug, 2 - info, 3 - warn, 4 - error
124124
SetLogLevel(1);
Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
const { execSync } = require('child_process');
2-
const fs = require('fs');
1+
import { execSync } from 'child_process';
2+
import { existsSync } from 'fs';
3+
import assert from 'assert';
34

4-
const { ChatManager, Role } = require('../chatManager');
5-
const {
5+
import { ChatManager, Role } from '../src/chat';
6+
import {
67
RunInference,
78
LoadModelAsync,
89
CreateContextAsync,
@@ -11,83 +12,81 @@ const {
1112
ReleaseModelAsync,
1213
SetLogLevel,
1314
GetModelToken,
14-
} = require("bindings")("npm-llama");
15+
} from '../src/index';
16+
1517

1618
const model = "model.gguf";
1719
const modelUrl = "https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct-GGUF/resolve/main/qwen2.5-0.5b-instruct-fp16.gguf?download=true";
18-
const system_prompt = "The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly.";
19-
20+
const systemPrompt = "The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly.";
2021

21-
describe('Node LLaMA Test Suite', () => {
22+
describe("Llama tests - basic", () => {
2223

2324
beforeAll(() => {
24-
25-
if (!fs.existsSync(model)) {
25+
// Setup - Download model if needed
26+
if (!existsSync(model)) {
2627
execSync(`npx llama-download -p ${model} -u ${modelUrl}`, { stdio: 'inherit' });
2728
} else {
2829
console.log("Model already downloaded");
2930
}
30-
});
31+
})
3132

32-
test('log level works', () => {
33+
test('log level works', async () => {
3334
SetLogLevel(1); // debug logs
34-
expect(true).toBeTruthy();
35+
assert.ok(true);
3536
});
3637

37-
test('direct inference works', () => {
38-
const inference = RunInference(model, "How old can ducks get?", system_prompt);
38+
test('direct inference works', async () => {
39+
const inference: string = RunInference(model, "How old can ducks get?", systemPrompt);
3940
console.log("Result", inference);
40-
expect(inference.includes('10 years')).toBeTruthy();
41+
assert.ok(inference.includes('10 years'));
4142
});
4243

4344
test('async inference works', async () => {
44-
45-
const prompts = [
45+
const prompts: string[] = [
4646
"How old can ducks get?",
4747
"Why are ducks so cool?",
4848
"Is there a limit on number of ducks I can own?"
49-
]
49+
];
5050

5151
const modelHandle = await LoadModelAsync(model);
5252
const ctx = await CreateContextAsync(modelHandle);
5353
console.log("Model loaded", model);
5454

5555
for (const prompt of prompts) {
56-
const inference = await RunInferenceAsync(modelHandle, ctx, prompt, system_prompt, 64);
56+
const inference: string = await RunInferenceAsync(modelHandle, ctx, prompt, systemPrompt, 64);
5757
console.log("Reply:", inference);
58-
expect(inference.length > 0).toBeTruthy();
58+
assert.ok(inference.length > 0);
5959
}
6060

6161
await ReleaseContextAsync(ctx);
6262
await ReleaseModelAsync(modelHandle);
6363
});
6464

6565
test('custom inference works', async () => {
66-
6766
const user = "How old can ducks get?";
68-
const prompt = `"!#<|im_start|>system ${system_prompt}<|im_end|><|im_start|>user ${user}<|im_end|><|im_start|>assistant"`;
67+
const prompt = `"!#<|im_start|>system ${systemPrompt}<|im_end|><|im_start|>user ${user}<|im_end|><|im_start|>assistant"`;
6968

7069
const modelHandle = await LoadModelAsync(model);
7170
const context = await CreateContextAsync(modelHandle);
72-
const result = await RunInferenceAsync(modelHandle, context, prompt);
71+
const result: string = await RunInferenceAsync(modelHandle, context, prompt);
7372
await ReleaseContextAsync(context);
7473
await ReleaseModelAsync(modelHandle);
7574

7675
console.log("Result", result);
77-
expect(result.length > 1).toBeTruthy();
76+
assert.ok(result.length > 1);
7877
});
7978

80-
test('tokens work', async () => {
8179

80+
test('tokens work', async () => {
8281
const modelHandle = await LoadModelAsync(model);
8382
const ctx = await CreateContextAsync(modelHandle);
8483

85-
const eos = GetModelToken(modelHandle, "EOS");
86-
const bos = GetModelToken(modelHandle, "BOS");
87-
const eot = GetModelToken(modelHandle, "EOT");
88-
const sep = GetModelToken(modelHandle, "SEP");
89-
const cls = GetModelToken(modelHandle, "CLS");
90-
const nl = GetModelToken(modelHandle, "NL");
84+
const eos: string = GetModelToken(modelHandle, "EOS");
85+
const bos: string = GetModelToken(modelHandle, "BOS");
86+
const eot: string = GetModelToken(modelHandle, "EOT");
87+
const sep: string = GetModelToken(modelHandle, "SEP");
88+
const cls: string = GetModelToken(modelHandle, "CLS");
89+
const nl: string = GetModelToken(modelHandle, "NL");
9190

9291
console.log("EOS", eos);
9392
console.log("BOS", bos);
@@ -99,17 +98,17 @@ describe('Node LLaMA Test Suite', () => {
9998
await ReleaseContextAsync(ctx);
10099
await ReleaseModelAsync(modelHandle);
101100

102-
expect(eos.length > 1).toBeTruthy();
103-
expect(bos.length > 1).toBeTruthy();
104-
})
101+
assert.ok(eos.length > 1);
102+
assert.ok(bos.length > 1);
103+
});
105104

106105
test('chat works', async () => {
107106
SetLogLevel(4); // warn
108107

109108
const modelHandle = await LoadModelAsync(model);
110109
const ctx = await CreateContextAsync(modelHandle);
111110

112-
const chat = new ChatManager(system_prompt);
111+
const chat = new ChatManager(systemPrompt);
113112

114113
let reply = "";
115114
let prompt = chat.getNextPrompt("Hello, my name is Duck!");
@@ -128,8 +127,6 @@ describe('Node LLaMA Test Suite', () => {
128127
await ReleaseContextAsync(ctx);
129128
await ReleaseModelAsync(modelHandle);
130129

131-
expect(reply.includes("Duck")).toBeTruthy();
130+
assert.ok(reply.includes("Duck"));
132131
});
133-
134-
135132
});

downloadModel.js

Lines changed: 0 additions & 65 deletions
This file was deleted.

index.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

index.mjs

Lines changed: 0 additions & 18 deletions
This file was deleted.

jest.config.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
module.exports = {
2-
testTimeout: 480000, // 480 seconds (8m)
1+
/** @type {import('ts-jest').JestConfigWithTsJest} **/
2+
export default {
3+
testEnvironment: "node",
4+
transform: {
5+
"^.+.tsx?$": ["ts-jest",{}],
6+
},
7+
extensionsToTreatAsEsm: ['.ts'],
8+
testTimeout: 480000 // 480 seconds (8m)
39
};

0 commit comments

Comments
 (0)