@@ -87,6 +87,26 @@ Napi::Value getGpuVramInfo(const Napi::CallbackInfo& info) {
8787 return result;
8888}
8989
90+ static Napi::Value getNapiToken (const Napi::CallbackInfo& info, llama_model* model, llama_token token) {
91+ auto tokenType = llama_token_get_type (model, token);
92+
93+ if (tokenType == LLAMA_TOKEN_TYPE_UNDEFINED || tokenType == LLAMA_TOKEN_TYPE_UNKNOWN) {
94+ return Napi::Number::From (info.Env (), -1 );
95+ }
96+
97+ return Napi::Number::From (info.Env (), token);
98+ }
99+
100+ static Napi::Value getNapiControlToken (const Napi::CallbackInfo& info, llama_model* model, llama_token token) {
101+ auto tokenType = llama_token_get_type (model, token);
102+
103+ if (tokenType != LLAMA_TOKEN_TYPE_CONTROL) {
104+ return Napi::Number::From (info.Env (), -1 );
105+ }
106+
107+ return Napi::Number::From (info.Env (), token);
108+ }
109+
90110class AddonModel : public Napi ::ObjectWrap<AddonModel> {
91111 public:
92112 llama_model_params model_params;
@@ -119,7 +139,6 @@ class AddonModel : public Napi::ObjectWrap<AddonModel> {
119139 }
120140 }
121141
122- llama_backend_init (false );
123142 model = llama_load_model_from_file (modelPath.c_str (), model_params);
124143
125144 if (model == NULL ) {
@@ -203,6 +222,15 @@ class AddonModel : public Napi::ObjectWrap<AddonModel> {
203222 return Napi::Number::From (info.Env (), llama_n_ctx_train (model));
204223 }
205224
225+ Napi::Value GetEmbeddingVectorSize (const Napi::CallbackInfo& info) {
226+ if (disposed) {
227+ Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
228+ return info.Env ().Undefined ();
229+ }
230+
231+ return Napi::Number::From (info.Env (), llama_n_embd (model));
232+ }
233+
206234 Napi::Value GetTotalSize (const Napi::CallbackInfo& info) {
207235 if (disposed) {
208236 Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
@@ -239,55 +267,55 @@ class AddonModel : public Napi::ObjectWrap<AddonModel> {
239267 return info.Env ().Undefined ();
240268 }
241269
242- return Napi::Number::From (info. Env () , llama_token_bos (model));
270+ return getNapiControlToken (info, model , llama_token_bos (model));
243271 }
244272 Napi::Value TokenEos (const Napi::CallbackInfo& info) {
245273 if (disposed) {
246274 Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
247275 return info.Env ().Undefined ();
248276 }
249277
250- return Napi::Number::From (info. Env () , llama_token_eos (model));
278+ return getNapiControlToken (info, model , llama_token_eos (model));
251279 }
252280 Napi::Value TokenNl (const Napi::CallbackInfo& info) {
253281 if (disposed) {
254282 Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
255283 return info.Env ().Undefined ();
256284 }
257285
258- return Napi::Number::From (info. Env () , llama_token_nl (model));
286+ return getNapiToken (info, model , llama_token_nl (model));
259287 }
260288 Napi::Value PrefixToken (const Napi::CallbackInfo& info) {
261289 if (disposed) {
262290 Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
263291 return info.Env ().Undefined ();
264292 }
265293
266- return Napi::Number::From (info. Env () , llama_token_prefix (model));
294+ return getNapiControlToken (info, model , llama_token_prefix (model));
267295 }
268296 Napi::Value MiddleToken (const Napi::CallbackInfo& info) {
269297 if (disposed) {
270298 Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
271299 return info.Env ().Undefined ();
272300 }
273301
274- return Napi::Number::From (info. Env () , llama_token_middle (model));
302+ return getNapiControlToken (info, model , llama_token_middle (model));
275303 }
276304 Napi::Value SuffixToken (const Napi::CallbackInfo& info) {
277305 if (disposed) {
278306 Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
279307 return info.Env ().Undefined ();
280308 }
281309
282- return Napi::Number::From (info. Env () , llama_token_suffix (model));
310+ return getNapiControlToken (info, model , llama_token_suffix (model));
283311 }
284312 Napi::Value EotToken (const Napi::CallbackInfo& info) {
285313 if (disposed) {
286314 Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
287315 return info.Env ().Undefined ();
288316 }
289317
290- return Napi::Number::From (info. Env () , llama_token_eot (model));
318+ return getNapiControlToken (info, model , llama_token_eot (model));
291319 }
292320 Napi::Value GetTokenString (const Napi::CallbackInfo& info) {
293321 if (disposed) {
@@ -308,6 +336,29 @@ class AddonModel : public Napi::ObjectWrap<AddonModel> {
308336 return Napi::String::New (info.Env (), ss.str ());
309337 }
310338
339+ Napi::Value GetTokenType (const Napi::CallbackInfo& info) {
340+ if (disposed) {
341+ Napi::Error::New (info.Env (), " Context is disposed" ).ThrowAsJavaScriptException ();
342+ return info.Env ().Undefined ();
343+ }
344+
345+ if (info[0 ].IsNumber () == false ) {
346+ return Napi::Number::From (info.Env (), int32_t (LLAMA_TOKEN_TYPE_UNDEFINED));
347+ }
348+
349+ int token = info[0 ].As <Napi::Number>().Int32Value ();
350+ auto tokenType = llama_token_get_type (model, token);
351+
352+ return Napi::Number::From (info.Env (), int32_t (tokenType));
353+ }
354+ Napi::Value ShouldPrependBosToken (const Napi::CallbackInfo& info) {
355+ const int addBos = llama_add_bos_token (model);
356+
357+ bool shouldPrependBos = addBos != -1 ? bool (addBos) : (llama_vocab_type (model) == LLAMA_VOCAB_TYPE_SPM);
358+
359+ return Napi::Boolean::New (info.Env (), shouldPrependBos);
360+ }
361+
311362 static void init (Napi::Object exports) {
312363 exports.Set (
313364 " AddonModel" ,
@@ -318,6 +369,7 @@ class AddonModel : public Napi::ObjectWrap<AddonModel> {
318369 InstanceMethod (" tokenize" , &AddonModel::Tokenize),
319370 InstanceMethod (" detokenize" , &AddonModel::Detokenize),
320371 InstanceMethod (" getTrainContextSize" , &AddonModel::GetTrainContextSize),
372+ InstanceMethod (" getEmbeddingVectorSize" , &AddonModel::GetEmbeddingVectorSize),
321373 InstanceMethod (" getTotalSize" , &AddonModel::GetTotalSize),
322374 InstanceMethod (" getTotalParameters" , &AddonModel::GetTotalParameters),
323375 InstanceMethod (" getModelDescription" , &AddonModel::GetModelDescription),
@@ -329,6 +381,8 @@ class AddonModel : public Napi::ObjectWrap<AddonModel> {
329381 InstanceMethod (" suffixToken" , &AddonModel::SuffixToken),
330382 InstanceMethod (" eotToken" , &AddonModel::EotToken),
331383 InstanceMethod (" getTokenString" , &AddonModel::GetTokenString),
384+ InstanceMethod (" getTokenType" , &AddonModel::GetTokenType),
385+ InstanceMethod (" shouldPrependBosToken" , &AddonModel::ShouldPrependBosToken),
332386 InstanceMethod (" dispose" , &AddonModel::Dispose),
333387 }
334388 )
@@ -993,7 +1047,7 @@ Napi::Value setLoggerLogLevel(const Napi::CallbackInfo& info) {
9931047}
9941048
9951049Napi::Object registerCallback (Napi::Env env, Napi::Object exports) {
996- llama_backend_init (false );
1050+ llama_backend_init ();
9971051 exports.DefineProperties ({
9981052 Napi::PropertyDescriptor::Function (" systemInfo" , systemInfo),
9991053 Napi::PropertyDescriptor::Function (" setLogger" , setLogger),
0 commit comments