react-native-litert-lm 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +245 -29
  2. package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM.kt +301 -58
  3. package/cpp/HybridLiteRTLM.cpp +109 -9
  4. package/cpp/HybridLiteRTLM.hpp +16 -0
  5. package/cpp/cpp-adapter.cpp +10 -2
  6. package/lib/hooks.d.ts +41 -0
  7. package/lib/hooks.js +131 -0
  8. package/lib/index.d.ts +30 -3
  9. package/lib/index.js +53 -6
  10. package/lib/memoryTracker.d.ts +128 -0
  11. package/lib/memoryTracker.js +155 -0
  12. package/lib/modelFactory.d.ts +18 -0
  13. package/lib/modelFactory.js +104 -0
  14. package/lib/specs/LiteRTLM.nitro.d.ts +38 -0
  15. package/lib/templates.d.ts +51 -0
  16. package/lib/templates.js +81 -0
  17. package/nitrogen/generated/android/LiteRTLMOnLoad.cpp +22 -17
  18. package/nitrogen/generated/android/LiteRTLMOnLoad.hpp +13 -4
  19. package/nitrogen/generated/android/c++/JFunc_void_double.hpp +75 -0
  20. package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.cpp +42 -1
  21. package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.hpp +3 -0
  22. package/nitrogen/generated/android/c++/JLLMConfig.hpp +6 -1
  23. package/nitrogen/generated/android/c++/JMemoryUsage.hpp +69 -0
  24. package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Func_void_double.kt +80 -0
  25. package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMSpec.kt +17 -0
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/LLMConfig.kt +5 -2
  27. package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/MemoryUsage.kt +47 -0
  28. package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.cpp +3 -0
  29. package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.hpp +6 -0
  30. package/nitrogen/generated/shared/c++/LLMConfig.hpp +7 -2
  31. package/nitrogen/generated/shared/c++/MemoryUsage.hpp +95 -0
  32. package/package.json +3 -3
  33. package/src/hooks.ts +195 -0
  34. package/src/index.ts +51 -3
  35. package/src/memoryTracker.ts +268 -0
  36. package/src/modelFactory.ts +120 -0
  37. package/src/specs/LiteRTLM.nitro.ts +47 -0
  38. package/src/templates.ts +105 -0
@@ -18,6 +18,12 @@ export type Role = "user" | "model" | "system";
18
18
  * Configuration options for loading an LLM.
19
19
  */
20
20
  export interface LLMConfig {
21
+ /**
22
+ * System prompt to set the model's behavior.
23
+ * This is prepended to the conversation to guide model responses.
24
+ * @example "You are a helpful coding assistant."
25
+ */
26
+ systemPrompt?: string;
21
27
  /**
22
28
  * Primary compute backend for text generation.
23
29
  * - 'cpu': CPU inference (slower but always available)
@@ -82,6 +88,20 @@ export interface GenerationStats {
82
88
  /** Tokens per second */
83
89
  tokensPerSecond: number;
84
90
  }
91
+ /**
92
+ * Real memory usage statistics from the native runtime.
93
+ * Measured from OS-level APIs, not estimated.
94
+ */
95
+ export interface MemoryUsage {
96
+ /** Native heap allocated bytes (Debug.getNativeHeapAllocatedSize on Android, malloc_size on iOS) */
97
+ nativeHeapBytes: number;
98
+ /** Total process resident set size (RSS) in bytes */
99
+ residentBytes: number;
100
+ /** Available system memory in bytes */
101
+ availableMemoryBytes: number;
102
+ /** Whether the system considers memory low */
103
+ isLowMemory: boolean;
104
+ }
85
105
  /**
86
106
  * LiteRT-LM: High-performance LLM inference engine.
87
107
  * Supports Gemma 3n, Phi-4, Qwen, and other .litertlm models.
@@ -125,6 +145,19 @@ export interface LiteRTLM extends HybridObject<{
125
145
  * @returns The model's response text.
126
146
  */
127
147
  sendMessageWithImage(message: string, imagePath: string): Promise<string>;
148
+ /**
149
+ * Download a model file from a URL.
150
+ * @param url URL to download from.
151
+ * @param fileName Filename to save as (in app's files directory).
152
+ * @param onProgress Callback for download progress (0.0 - 1.0).
153
+ * @returns Absolute path to the downloaded file.
154
+ */
155
+ downloadModel(url: string, fileName: string, onProgress?: (progress: number) => void): Promise<string>;
156
+ /**
157
+ * Delete a downloaded model file.
158
+ * @param fileName Filename to delete (in app's files directory).
159
+ */
160
+ deleteModel(fileName: string): Promise<void>;
128
161
  /**
129
162
  * Send a text message with audio (multimodal).
130
163
  * @param message User message text.
@@ -156,6 +189,11 @@ export interface LiteRTLM extends HybridObject<{
156
189
  * Get the last generation statistics.
157
190
  */
158
191
  getStats(): GenerationStats;
192
+ /**
193
+ * Get real memory usage from the native runtime.
194
+ * Uses OS-level APIs to report actual memory consumption.
195
+ */
196
+ getMemoryUsage(): MemoryUsage;
159
197
  /**
160
198
  * Release all native resources.
161
199
  * Call this when done with the LLM instance.
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Prompt template utilities for different LLM families.
3
+ *
4
+ * LiteRT-LM's Conversation API may handle templates internally for some models,
5
+ * but these utilities give developers explicit control for custom workflows
6
+ * or when using models with different template formats.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { applyGemmaTemplate, ChatMessage } from 'react-native-litert-lm';
11
+ *
12
+ * const history: ChatMessage[] = [
13
+ * { role: 'user', content: 'What is React Native?' },
14
+ * { role: 'model', content: 'React Native is a framework for building...' },
15
+ * { role: 'user', content: 'How do I use hooks?' }
16
+ * ];
17
+ *
18
+ * const prompt = applyGemmaTemplate(history, 'You are a helpful coding assistant.');
19
+ * ```
20
+ */
21
+ /**
22
+ * A message in a conversation.
23
+ */
24
+ export type ChatMessage = {
25
+ role: "user" | "model" | "system";
26
+ content: string;
27
+ };
28
+ /**
29
+ * Apply Gemma chat template (Gemma 2, Gemma 3, Gemma 3n).
30
+ *
31
+ * @param history Array of previous messages
32
+ * @param systemPrompt Optional system prompt
33
+ * @returns Formatted prompt string
34
+ */
35
+ export declare function applyGemmaTemplate(history: ChatMessage[], systemPrompt?: string): string;
36
+ /**
37
+ * Apply Phi chat template (Phi-3, Phi-4).
38
+ *
39
+ * @param history Array of previous messages
40
+ * @param systemPrompt Optional system prompt
41
+ * @returns Formatted prompt string
42
+ */
43
+ export declare function applyPhiTemplate(history: ChatMessage[], systemPrompt?: string): string;
44
+ /**
45
+ * Apply Llama 3 chat template.
46
+ *
47
+ * @param history Array of previous messages
48
+ * @param systemPrompt Optional system prompt
49
+ * @returns Formatted prompt string
50
+ */
51
+ export declare function applyLlamaTemplate(history: ChatMessage[], systemPrompt?: string): string;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ /**
3
+ * Prompt template utilities for different LLM families.
4
+ *
5
+ * LiteRT-LM's Conversation API may handle templates internally for some models,
6
+ * but these utilities give developers explicit control for custom workflows
7
+ * or when using models with different template formats.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { applyGemmaTemplate, ChatMessage } from 'react-native-litert-lm';
12
+ *
13
+ * const history: ChatMessage[] = [
14
+ * { role: 'user', content: 'What is React Native?' },
15
+ * { role: 'model', content: 'React Native is a framework for building...' },
16
+ * { role: 'user', content: 'How do I use hooks?' }
17
+ * ];
18
+ *
19
+ * const prompt = applyGemmaTemplate(history, 'You are a helpful coding assistant.');
20
+ * ```
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.applyGemmaTemplate = applyGemmaTemplate;
24
+ exports.applyPhiTemplate = applyPhiTemplate;
25
+ exports.applyLlamaTemplate = applyLlamaTemplate;
26
+ /**
27
+ * Apply Gemma chat template (Gemma 2, Gemma 3, Gemma 3n).
28
+ *
29
+ * @param history Array of previous messages
30
+ * @param systemPrompt Optional system prompt
31
+ * @returns Formatted prompt string
32
+ */
33
+ function applyGemmaTemplate(history, systemPrompt) {
34
+ let result = "";
35
+ if (systemPrompt) {
36
+ result += `<start_of_turn>system\n${systemPrompt}<end_of_turn>\n`;
37
+ }
38
+ for (const m of history) {
39
+ result += `<start_of_turn>${m.role}\n${m.content}<end_of_turn>\n`;
40
+ }
41
+ result += "<start_of_turn>model\n";
42
+ return result;
43
+ }
44
+ /**
45
+ * Apply Phi chat template (Phi-3, Phi-4).
46
+ *
47
+ * @param history Array of previous messages
48
+ * @param systemPrompt Optional system prompt
49
+ * @returns Formatted prompt string
50
+ */
51
+ function applyPhiTemplate(history, systemPrompt) {
52
+ let result = "";
53
+ if (systemPrompt) {
54
+ result += `<|system|>\n${systemPrompt}<|end|>\n`;
55
+ }
56
+ for (const m of history) {
57
+ const role = m.role === "model" ? "assistant" : m.role;
58
+ result += `<|${role}|>\n${m.content}<|end|>\n`;
59
+ }
60
+ result += "<|assistant|>\n";
61
+ return result;
62
+ }
63
+ /**
64
+ * Apply Llama 3 chat template.
65
+ *
66
+ * @param history Array of previous messages
67
+ * @param systemPrompt Optional system prompt
68
+ * @returns Formatted prompt string
69
+ */
70
+ function applyLlamaTemplate(history, systemPrompt) {
71
+ let result = "<|begin_of_text|>";
72
+ if (systemPrompt) {
73
+ result += `<|start_header_id|>system<|end_header_id|>\n\n${systemPrompt}<|eot_id|>`;
74
+ }
75
+ for (const m of history) {
76
+ const role = m.role === "model" ? "assistant" : m.role;
77
+ result += `<|start_header_id|>${role}<|end_header_id|>\n\n${m.content}<|eot_id|>`;
78
+ }
79
+ result += "<|start_header_id|>assistant<|end_header_id|>\n\n";
80
+ return result;
81
+ }
@@ -16,31 +16,36 @@
16
16
  #include <NitroModules/HybridObjectRegistry.hpp>
17
17
 
18
18
  #include "JHybridLiteRTLMSpec.hpp"
19
+ #include "JFunc_void_double.hpp"
19
20
  #include "JFunc_void_std__string_bool.hpp"
20
21
  #include <NitroModules/DefaultConstructableObject.hpp>
21
22
 
22
23
  namespace margelo::nitro::litertlm {
23
24
 
24
25
  int initialize(JavaVM* vm) {
26
+ return facebook::jni::initialize(vm, []() {
27
+ ::margelo::nitro::litertlm::registerAllNatives();
28
+ });
29
+ }
30
+
31
+ void registerAllNatives() {
25
32
  using namespace margelo::nitro;
26
33
  using namespace margelo::nitro::litertlm;
27
- using namespace facebook;
28
-
29
- return facebook::jni::initialize(vm, [] {
30
- // Register native JNI methods
31
- margelo::nitro::litertlm::JHybridLiteRTLMSpec::registerNatives();
32
- margelo::nitro::litertlm::JFunc_void_std__string_bool_cxx::registerNatives();
33
-
34
- // Register Nitro Hybrid Objects
35
- HybridObjectRegistry::registerHybridObjectConstructor(
36
- "LiteRTLM",
37
- []() -> std::shared_ptr<HybridObject> {
38
- static DefaultConstructableObject<JHybridLiteRTLMSpec::javaobject> object("com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM");
39
- auto instance = object.create();
40
- return instance->cthis()->shared();
41
- }
42
- );
43
- });
34
+
35
+ // Register native JNI methods
36
+ margelo::nitro::litertlm::JHybridLiteRTLMSpec::registerNatives();
37
+ margelo::nitro::litertlm::JFunc_void_double_cxx::registerNatives();
38
+ margelo::nitro::litertlm::JFunc_void_std__string_bool_cxx::registerNatives();
39
+
40
+ // Register Nitro Hybrid Objects
41
+ HybridObjectRegistry::registerHybridObjectConstructor(
42
+ "LiteRTLM",
43
+ []() -> std::shared_ptr<HybridObject> {
44
+ static DefaultConstructableObject<JHybridLiteRTLMSpec::javaobject> object("com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM");
45
+ auto instance = object.create();
46
+ return instance->cthis()->shared();
47
+ }
48
+ );
44
49
  }
45
50
 
46
51
  } // namespace margelo::nitro::litertlm
@@ -6,20 +6,29 @@
6
6
  ///
7
7
 
8
8
  #include <jni.h>
9
+ #include <functional>
9
10
  #include <NitroModules/NitroDefines.hpp>
10
11
 
11
12
  namespace margelo::nitro::litertlm {
12
13
 
14
+ [[deprecated("Use registerNatives() instead.")]]
15
+ int initialize(JavaVM* vm);
16
+
13
17
  /**
14
- * Initializes the native (C++) part of LiteRTLM, and autolinks all Hybrid Objects.
15
- * Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`).
18
+ * Register the native (C++) part of LiteRTLM, and autolinks all Hybrid Objects.
19
+ * Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`),
20
+ * inside a `facebook::jni::initialize(vm, ...)` call.
16
21
  * Example:
17
22
  * ```cpp (cpp-adapter.cpp)
18
23
  * JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
19
- * return margelo::nitro::litertlm::initialize(vm);
24
+ * return facebook::jni::initialize(vm, []() {
25
+ * // register all LiteRTLM HybridObjects
26
+ * margelo::nitro::litertlm::registerNatives();
27
+ * // any other custom registrations go here.
28
+ * });
20
29
  * }
21
30
  * ```
22
31
  */
23
- int initialize(JavaVM* vm);
32
+ void registerAllNatives();
24
33
 
25
34
  } // namespace margelo::nitro::litertlm
@@ -0,0 +1,75 @@
1
+ ///
2
+ /// JFunc_void_double.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include <functional>
12
+
13
+ #include <functional>
14
+ #include <NitroModules/JNICallable.hpp>
15
+
16
+ namespace margelo::nitro::litertlm {
17
+
18
+ using namespace facebook;
19
+
20
+ /**
21
+ * Represents the Java/Kotlin callback `(progress: Double) -> Unit`.
22
+ * This can be passed around between C++ and Java/Kotlin.
23
+ */
24
+ struct JFunc_void_double: public jni::JavaClass<JFunc_void_double> {
25
+ public:
26
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/dev/litert/litertlm/Func_void_double;";
27
+
28
+ public:
29
+ /**
30
+ * Invokes the function this `JFunc_void_double` instance holds through JNI.
31
+ */
32
+ void invoke(double progress) const {
33
+ static const auto method = javaClassStatic()->getMethod<void(double /* progress */)>("invoke");
34
+ method(self(), progress);
35
+ }
36
+ };
37
+
38
+ /**
39
+ * An implementation of Func_void_double that is backed by a C++ implementation (using `std::function<...>`)
40
+ */
41
+ class JFunc_void_double_cxx final: public jni::HybridClass<JFunc_void_double_cxx, JFunc_void_double> {
42
+ public:
43
+ static jni::local_ref<JFunc_void_double::javaobject> fromCpp(const std::function<void(double /* progress */)>& func) {
44
+ return JFunc_void_double_cxx::newObjectCxxArgs(func);
45
+ }
46
+
47
+ public:
48
+ /**
49
+ * Invokes the C++ `std::function<...>` this `JFunc_void_double_cxx` instance holds.
50
+ */
51
+ void invoke_cxx(double progress) {
52
+ _func(progress);
53
+ }
54
+
55
+ public:
56
+ [[nodiscard]]
57
+ inline const std::function<void(double /* progress */)>& getFunction() const {
58
+ return _func;
59
+ }
60
+
61
+ public:
62
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/dev/litert/litertlm/Func_void_double_cxx;";
63
+ static void registerNatives() {
64
+ registerHybrid({makeNativeMethod("invoke_cxx", JFunc_void_double_cxx::invoke_cxx)});
65
+ }
66
+
67
+ private:
68
+ explicit JFunc_void_double_cxx(const std::function<void(double /* progress */)>& func): _func(func) { }
69
+
70
+ private:
71
+ friend HybridBase;
72
+ std::function<void(double /* progress */)> _func;
73
+ };
74
+
75
+ } // namespace margelo::nitro::litertlm
@@ -13,6 +13,8 @@ namespace margelo::nitro::litertlm { struct Message; }
13
13
  namespace margelo::nitro::litertlm { enum class Role; }
14
14
  // Forward declaration of `GenerationStats` to properly resolve imports.
15
15
  namespace margelo::nitro::litertlm { struct GenerationStats; }
16
+ // Forward declaration of `MemoryUsage` to properly resolve imports.
17
+ namespace margelo::nitro::litertlm { struct MemoryUsage; }
16
18
  // Forward declaration of `LLMConfig` to properly resolve imports.
17
19
  namespace margelo::nitro::litertlm { struct LLMConfig; }
18
20
  // Forward declaration of `Backend` to properly resolve imports.
@@ -29,14 +31,17 @@ namespace margelo::nitro::litertlm { enum class Backend; }
29
31
  #include "JRole.hpp"
30
32
  #include "GenerationStats.hpp"
31
33
  #include "JGenerationStats.hpp"
34
+ #include "MemoryUsage.hpp"
35
+ #include "JMemoryUsage.hpp"
32
36
  #include "LLMConfig.hpp"
33
37
  #include <optional>
34
38
  #include "JLLMConfig.hpp"
35
39
  #include "Backend.hpp"
36
40
  #include "JBackend.hpp"
37
41
  #include <functional>
38
- #include "JFunc_void_std__string_bool.hpp"
42
+ #include "JFunc_void_double.hpp"
39
43
  #include <NitroModules/JNICallable.hpp>
44
+ #include "JFunc_void_std__string_bool.hpp"
40
45
 
41
46
  namespace margelo::nitro::litertlm {
42
47
 
@@ -124,6 +129,37 @@ namespace margelo::nitro::litertlm {
124
129
  return __promise;
125
130
  }();
126
131
  }
132
+ std::shared_ptr<Promise<std::string>> JHybridLiteRTLMSpec::downloadModel(const std::string& url, const std::string& fileName, const std::optional<std::function<void(double /* progress */)>>& onProgress) {
133
+ static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* url */, jni::alias_ref<jni::JString> /* fileName */, jni::alias_ref<JFunc_void_double::javaobject> /* onProgress */)>("downloadModel_cxx");
134
+ auto __result = method(_javaPart, jni::make_jstring(url), jni::make_jstring(fileName), onProgress.has_value() ? JFunc_void_double_cxx::fromCpp(onProgress.value()) : nullptr);
135
+ return [&]() {
136
+ auto __promise = Promise<std::string>::create();
137
+ __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
138
+ auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
139
+ __promise->resolve(__result->toStdString());
140
+ });
141
+ __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
142
+ jni::JniException __jniError(__throwable);
143
+ __promise->reject(std::make_exception_ptr(__jniError));
144
+ });
145
+ return __promise;
146
+ }();
147
+ }
148
+ std::shared_ptr<Promise<void>> JHybridLiteRTLMSpec::deleteModel(const std::string& fileName) {
149
+ static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* fileName */)>("deleteModel");
150
+ auto __result = method(_javaPart, jni::make_jstring(fileName));
151
+ return [&]() {
152
+ auto __promise = Promise<void>::create();
153
+ __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
154
+ __promise->resolve();
155
+ });
156
+ __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
157
+ jni::JniException __jniError(__throwable);
158
+ __promise->reject(std::make_exception_ptr(__jniError));
159
+ });
160
+ return __promise;
161
+ }();
162
+ }
127
163
  std::shared_ptr<Promise<std::string>> JHybridLiteRTLMSpec::sendMessageWithAudio(const std::string& message, const std::string& audioPath) {
128
164
  static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* message */, jni::alias_ref<jni::JString> /* audioPath */)>("sendMessageWithAudio");
129
165
  auto __result = method(_javaPart, jni::make_jstring(message), jni::make_jstring(audioPath));
@@ -172,6 +208,11 @@ namespace margelo::nitro::litertlm {
172
208
  auto __result = method(_javaPart);
173
209
  return __result->toCpp();
174
210
  }
211
+ MemoryUsage JHybridLiteRTLMSpec::getMemoryUsage() {
212
+ static const auto method = javaClassStatic()->getMethod<jni::local_ref<JMemoryUsage>()>("getMemoryUsage");
213
+ auto __result = method(_javaPart);
214
+ return __result->toCpp();
215
+ }
175
216
  void JHybridLiteRTLMSpec::close() {
176
217
  static const auto method = javaClassStatic()->getMethod<void()>("close");
177
218
  method(_javaPart);
@@ -58,12 +58,15 @@ namespace margelo::nitro::litertlm {
58
58
  std::shared_ptr<Promise<void>> loadModel(const std::string& modelPath, const std::optional<LLMConfig>& config) override;
59
59
  std::shared_ptr<Promise<std::string>> sendMessage(const std::string& message) override;
60
60
  std::shared_ptr<Promise<std::string>> sendMessageWithImage(const std::string& message, const std::string& imagePath) override;
61
+ std::shared_ptr<Promise<std::string>> downloadModel(const std::string& url, const std::string& fileName, const std::optional<std::function<void(double /* progress */)>>& onProgress) override;
62
+ std::shared_ptr<Promise<void>> deleteModel(const std::string& fileName) override;
61
63
  std::shared_ptr<Promise<std::string>> sendMessageWithAudio(const std::string& message, const std::string& audioPath) override;
62
64
  void sendMessageAsync(const std::string& message, const std::function<void(const std::string& /* token */, bool /* done */)>& onToken) override;
63
65
  std::vector<Message> getHistory() override;
64
66
  void resetConversation() override;
65
67
  bool isReady() override;
66
68
  GenerationStats getStats() override;
69
+ MemoryUsage getMemoryUsage() override;
67
70
  void close() override;
68
71
 
69
72
  private:
@@ -13,6 +13,7 @@
13
13
  #include "Backend.hpp"
14
14
  #include "JBackend.hpp"
15
15
  #include <optional>
16
+ #include <string>
16
17
 
17
18
  namespace margelo::nitro::litertlm {
18
19
 
@@ -33,6 +34,8 @@ namespace margelo::nitro::litertlm {
33
34
  [[nodiscard]]
34
35
  LLMConfig toCpp() const {
35
36
  static const auto clazz = javaClassStatic();
37
+ static const auto fieldSystemPrompt = clazz->getField<jni::JString>("systemPrompt");
38
+ jni::local_ref<jni::JString> systemPrompt = this->getFieldValue(fieldSystemPrompt);
36
39
  static const auto fieldBackend = clazz->getField<JBackend>("backend");
37
40
  jni::local_ref<JBackend> backend = this->getFieldValue(fieldBackend);
38
41
  static const auto fieldMaxTokens = clazz->getField<jni::JDouble>("maxTokens");
@@ -44,6 +47,7 @@ namespace margelo::nitro::litertlm {
44
47
  static const auto fieldTopP = clazz->getField<jni::JDouble>("topP");
45
48
  jni::local_ref<jni::JDouble> topP = this->getFieldValue(fieldTopP);
46
49
  return LLMConfig(
50
+ systemPrompt != nullptr ? std::make_optional(systemPrompt->toStdString()) : std::nullopt,
47
51
  backend != nullptr ? std::make_optional(backend->toCpp()) : std::nullopt,
48
52
  maxTokens != nullptr ? std::make_optional(maxTokens->value()) : std::nullopt,
49
53
  temperature != nullptr ? std::make_optional(temperature->value()) : std::nullopt,
@@ -58,11 +62,12 @@ namespace margelo::nitro::litertlm {
58
62
  */
59
63
  [[maybe_unused]]
60
64
  static jni::local_ref<JLLMConfig::javaobject> fromCpp(const LLMConfig& value) {
61
- using JSignature = JLLMConfig(jni::alias_ref<JBackend>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>);
65
+ using JSignature = JLLMConfig(jni::alias_ref<jni::JString>, jni::alias_ref<JBackend>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>);
62
66
  static const auto clazz = javaClassStatic();
63
67
  static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
64
68
  return create(
65
69
  clazz,
70
+ value.systemPrompt.has_value() ? jni::make_jstring(value.systemPrompt.value()) : nullptr,
66
71
  value.backend.has_value() ? JBackend::fromCpp(value.backend.value()) : nullptr,
67
72
  value.maxTokens.has_value() ? jni::JDouble::valueOf(value.maxTokens.value()) : nullptr,
68
73
  value.temperature.has_value() ? jni::JDouble::valueOf(value.temperature.value()) : nullptr,
@@ -0,0 +1,69 @@
1
+ ///
2
+ /// JMemoryUsage.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include "MemoryUsage.hpp"
12
+
13
+
14
+
15
+ namespace margelo::nitro::litertlm {
16
+
17
+ using namespace facebook;
18
+
19
+ /**
20
+ * The C++ JNI bridge between the C++ struct "MemoryUsage" and the the Kotlin data class "MemoryUsage".
21
+ */
22
+ struct JMemoryUsage final: public jni::JavaClass<JMemoryUsage> {
23
+ public:
24
+ static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/dev/litert/litertlm/MemoryUsage;";
25
+
26
+ public:
27
+ /**
28
+ * Convert this Java/Kotlin-based struct to the C++ struct MemoryUsage by copying all values to C++.
29
+ */
30
+ [[maybe_unused]]
31
+ [[nodiscard]]
32
+ MemoryUsage toCpp() const {
33
+ static const auto clazz = javaClassStatic();
34
+ static const auto fieldNativeHeapBytes = clazz->getField<double>("nativeHeapBytes");
35
+ double nativeHeapBytes = this->getFieldValue(fieldNativeHeapBytes);
36
+ static const auto fieldResidentBytes = clazz->getField<double>("residentBytes");
37
+ double residentBytes = this->getFieldValue(fieldResidentBytes);
38
+ static const auto fieldAvailableMemoryBytes = clazz->getField<double>("availableMemoryBytes");
39
+ double availableMemoryBytes = this->getFieldValue(fieldAvailableMemoryBytes);
40
+ static const auto fieldIsLowMemory = clazz->getField<jboolean>("isLowMemory");
41
+ jboolean isLowMemory = this->getFieldValue(fieldIsLowMemory);
42
+ return MemoryUsage(
43
+ nativeHeapBytes,
44
+ residentBytes,
45
+ availableMemoryBytes,
46
+ static_cast<bool>(isLowMemory)
47
+ );
48
+ }
49
+
50
+ public:
51
+ /**
52
+ * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
53
+ */
54
+ [[maybe_unused]]
55
+ static jni::local_ref<JMemoryUsage::javaobject> fromCpp(const MemoryUsage& value) {
56
+ using JSignature = JMemoryUsage(double, double, double, jboolean);
57
+ static const auto clazz = javaClassStatic();
58
+ static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
59
+ return create(
60
+ clazz,
61
+ value.nativeHeapBytes,
62
+ value.residentBytes,
63
+ value.availableMemoryBytes,
64
+ value.isLowMemory
65
+ );
66
+ }
67
+ };
68
+
69
+ } // namespace margelo::nitro::litertlm
@@ -0,0 +1,80 @@
1
+ ///
2
+ /// Func_void_double.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.dev.litert.litertlm
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.jni.HybridData
12
+ import com.facebook.proguard.annotations.DoNotStrip
13
+ import dalvik.annotation.optimization.FastNative
14
+
15
+
16
+ /**
17
+ * Represents the JavaScript callback `(progress: number) => void`.
18
+ * This can be either implemented in C++ (in which case it might be a callback coming from JS),
19
+ * or in Kotlin/Java (in which case it is a native callback).
20
+ */
21
+ @DoNotStrip
22
+ @Keep
23
+ @Suppress("ClassName", "RedundantUnitReturnType")
24
+ fun interface Func_void_double: (Double) -> Unit {
25
+ /**
26
+ * Call the given JS callback.
27
+ * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.
28
+ */
29
+ @DoNotStrip
30
+ @Keep
31
+ override fun invoke(progress: Double): Unit
32
+ }
33
+
34
+ /**
35
+ * Represents the JavaScript callback `(progress: number) => void`.
36
+ * This is implemented in C++, via a `std::function<...>`.
37
+ * The callback might be coming from JS.
38
+ */
39
+ @DoNotStrip
40
+ @Keep
41
+ @Suppress(
42
+ "KotlinJniMissingFunction", "unused",
43
+ "RedundantSuppression", "RedundantUnitReturnType", "FunctionName",
44
+ "ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName",
45
+ )
46
+ class Func_void_double_cxx: Func_void_double {
47
+ @DoNotStrip
48
+ @Keep
49
+ private val mHybridData: HybridData
50
+
51
+ @DoNotStrip
52
+ @Keep
53
+ private constructor(hybridData: HybridData) {
54
+ mHybridData = hybridData
55
+ }
56
+
57
+ @DoNotStrip
58
+ @Keep
59
+ override fun invoke(progress: Double): Unit
60
+ = invoke_cxx(progress)
61
+
62
+ @FastNative
63
+ private external fun invoke_cxx(progress: Double): Unit
64
+ }
65
+
66
+ /**
67
+ * Represents the JavaScript callback `(progress: number) => void`.
68
+ * This is implemented in Java/Kotlin, via a `(Double) -> Unit`.
69
+ * The callback is always coming from native.
70
+ */
71
+ @DoNotStrip
72
+ @Keep
73
+ @Suppress("ClassName", "RedundantUnitReturnType", "unused")
74
+ class Func_void_double_java(private val function: (Double) -> Unit): Func_void_double {
75
+ @DoNotStrip
76
+ @Keep
77
+ override fun invoke(progress: Double): Unit {
78
+ return this.function(progress)
79
+ }
80
+ }
@@ -58,6 +58,19 @@ abstract class HybridLiteRTLMSpec: HybridObject() {
58
58
  @Keep
59
59
  abstract fun sendMessageWithImage(message: String, imagePath: String): Promise<String>
60
60
 
61
+ abstract fun downloadModel(url: String, fileName: String, onProgress: ((progress: Double) -> Unit)?): Promise<String>
62
+
63
+ @DoNotStrip
64
+ @Keep
65
+ private fun downloadModel_cxx(url: String, fileName: String, onProgress: Func_void_double?): Promise<String> {
66
+ val __result = downloadModel(url, fileName, onProgress?.let { it })
67
+ return __result
68
+ }
69
+
70
+ @DoNotStrip
71
+ @Keep
72
+ abstract fun deleteModel(fileName: String): Promise<Unit>
73
+
61
74
  @DoNotStrip
62
75
  @Keep
63
76
  abstract fun sendMessageWithAudio(message: String, audioPath: String): Promise<String>
@@ -87,6 +100,10 @@ abstract class HybridLiteRTLMSpec: HybridObject() {
87
100
  @Keep
88
101
  abstract fun getStats(): GenerationStats
89
102
 
103
+ @DoNotStrip
104
+ @Keep
105
+ abstract fun getMemoryUsage(): MemoryUsage
106
+
90
107
  @DoNotStrip
91
108
  @Keep
92
109
  abstract fun close(): Unit