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.
- package/README.md +245 -29
- package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM.kt +301 -58
- package/cpp/HybridLiteRTLM.cpp +109 -9
- package/cpp/HybridLiteRTLM.hpp +16 -0
- package/cpp/cpp-adapter.cpp +10 -2
- package/lib/hooks.d.ts +41 -0
- package/lib/hooks.js +131 -0
- package/lib/index.d.ts +30 -3
- package/lib/index.js +53 -6
- package/lib/memoryTracker.d.ts +128 -0
- package/lib/memoryTracker.js +155 -0
- package/lib/modelFactory.d.ts +18 -0
- package/lib/modelFactory.js +104 -0
- package/lib/specs/LiteRTLM.nitro.d.ts +38 -0
- package/lib/templates.d.ts +51 -0
- package/lib/templates.js +81 -0
- package/nitrogen/generated/android/LiteRTLMOnLoad.cpp +22 -17
- package/nitrogen/generated/android/LiteRTLMOnLoad.hpp +13 -4
- package/nitrogen/generated/android/c++/JFunc_void_double.hpp +75 -0
- package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.cpp +42 -1
- package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.hpp +3 -0
- package/nitrogen/generated/android/c++/JLLMConfig.hpp +6 -1
- package/nitrogen/generated/android/c++/JMemoryUsage.hpp +69 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Func_void_double.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMSpec.kt +17 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/LLMConfig.kt +5 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/MemoryUsage.kt +47 -0
- package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.cpp +3 -0
- package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.hpp +6 -0
- package/nitrogen/generated/shared/c++/LLMConfig.hpp +7 -2
- package/nitrogen/generated/shared/c++/MemoryUsage.hpp +95 -0
- package/package.json +3 -3
- package/src/hooks.ts +195 -0
- package/src/index.ts +51 -3
- package/src/memoryTracker.ts +268 -0
- package/src/modelFactory.ts +120 -0
- package/src/specs/LiteRTLM.nitro.ts +47 -0
- 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;
|
package/lib/templates.js
ADDED
|
@@ -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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
-
|
|
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 "
|
|
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
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Func_void_double.kt
ADDED
|
@@ -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
|