react-native-litert-lm 0.1.0
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/LICENSE +21 -0
- package/README.md +259 -0
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +88 -0
- package/android/src/main/AndroidManifest.xml +11 -0
- package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM.kt +280 -0
- package/android/src/main/java/dev/litert/litertlm/LiteRTLMInitProvider.kt +43 -0
- package/android/src/main/java/dev/litert/litertlm/LiteRTLMPackage.kt +26 -0
- package/cpp/HybridLiteRTLM.cpp +483 -0
- package/cpp/HybridLiteRTLM.hpp +120 -0
- package/cpp/cpp-adapter.cpp +13 -0
- package/cpp/include/README.md +34 -0
- package/lib/index.d.ts +82 -0
- package/lib/index.js +106 -0
- package/lib/specs/LiteRTLM.nitro.d.ts +165 -0
- package/lib/specs/LiteRTLM.nitro.js +2 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/LiteRTLM+autolinking.cmake +81 -0
- package/nitrogen/generated/android/LiteRTLM+autolinking.gradle +27 -0
- package/nitrogen/generated/android/LiteRTLMOnLoad.cpp +46 -0
- package/nitrogen/generated/android/LiteRTLMOnLoad.hpp +25 -0
- package/nitrogen/generated/android/c++/JBackend.hpp +61 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string_bool.hpp +76 -0
- package/nitrogen/generated/android/c++/JGenerationStats.hpp +77 -0
- package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.cpp +133 -0
- package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.hpp +75 -0
- package/nitrogen/generated/android/c++/JLLMConfig.hpp +75 -0
- package/nitrogen/generated/android/c++/JMessage.hpp +63 -0
- package/nitrogen/generated/android/c++/JRole.hpp +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Backend.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Func_void_std__string_bool.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/GenerationStats.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMSpec.kt +98 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/LLMConfig.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/LiteRTLMOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Message.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Role.kt +24 -0
- package/nitrogen/generated/ios/LiteRTLM+autolinking.rb +60 -0
- package/nitrogen/generated/ios/LiteRTLM-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/LiteRTLM-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/LiteRTLM-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/shared/c++/Backend.hpp +80 -0
- package/nitrogen/generated/shared/c++/GenerationStats.hpp +103 -0
- package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.cpp +30 -0
- package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.hpp +82 -0
- package/nitrogen/generated/shared/c++/LLMConfig.hpp +101 -0
- package/nitrogen/generated/shared/c++/Message.hpp +89 -0
- package/nitrogen/generated/shared/c++/Role.hpp +80 -0
- package/package.json +87 -0
- package/react-native-litert-lm.podspec +51 -0
- package/react-native.config.js +16 -0
- package/src/index.ts +125 -0
- package/src/specs/LiteRTLM.nitro.ts +187 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// HybridLiteRTLMSpec.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
|
+
#if __has_include(<NitroModules/HybridObject.hpp>)
|
|
11
|
+
#include <NitroModules/HybridObject.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
// Forward declaration of `LLMConfig` to properly resolve imports.
|
|
17
|
+
namespace margelo::nitro::litertlm { struct LLMConfig; }
|
|
18
|
+
// Forward declaration of `Message` to properly resolve imports.
|
|
19
|
+
namespace margelo::nitro::litertlm { struct Message; }
|
|
20
|
+
// Forward declaration of `GenerationStats` to properly resolve imports.
|
|
21
|
+
namespace margelo::nitro::litertlm { struct GenerationStats; }
|
|
22
|
+
|
|
23
|
+
#include <string>
|
|
24
|
+
#include "LLMConfig.hpp"
|
|
25
|
+
#include <optional>
|
|
26
|
+
#include <functional>
|
|
27
|
+
#include "Message.hpp"
|
|
28
|
+
#include <vector>
|
|
29
|
+
#include "GenerationStats.hpp"
|
|
30
|
+
|
|
31
|
+
namespace margelo::nitro::litertlm {
|
|
32
|
+
|
|
33
|
+
using namespace margelo::nitro;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* An abstract base class for `LiteRTLM`
|
|
37
|
+
* Inherit this class to create instances of `HybridLiteRTLMSpec` in C++.
|
|
38
|
+
* You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
|
|
39
|
+
* @example
|
|
40
|
+
* ```cpp
|
|
41
|
+
* class HybridLiteRTLM: public HybridLiteRTLMSpec {
|
|
42
|
+
* public:
|
|
43
|
+
* HybridLiteRTLM(...): HybridObject(TAG) { ... }
|
|
44
|
+
* // ...
|
|
45
|
+
* };
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
class HybridLiteRTLMSpec: public virtual HybridObject {
|
|
49
|
+
public:
|
|
50
|
+
// Constructor
|
|
51
|
+
explicit HybridLiteRTLMSpec(): HybridObject(TAG) { }
|
|
52
|
+
|
|
53
|
+
// Destructor
|
|
54
|
+
~HybridLiteRTLMSpec() override = default;
|
|
55
|
+
|
|
56
|
+
public:
|
|
57
|
+
// Properties
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
public:
|
|
61
|
+
// Methods
|
|
62
|
+
virtual void loadModel(const std::string& modelPath, const std::optional<LLMConfig>& config) = 0;
|
|
63
|
+
virtual std::string sendMessage(const std::string& message) = 0;
|
|
64
|
+
virtual std::string sendMessageWithImage(const std::string& message, const std::string& imagePath) = 0;
|
|
65
|
+
virtual std::string sendMessageWithAudio(const std::string& message, const std::string& audioPath) = 0;
|
|
66
|
+
virtual void sendMessageAsync(const std::string& message, const std::function<void(const std::string& /* token */, bool /* done */)>& onToken) = 0;
|
|
67
|
+
virtual std::vector<Message> getHistory() = 0;
|
|
68
|
+
virtual void resetConversation() = 0;
|
|
69
|
+
virtual bool isReady() = 0;
|
|
70
|
+
virtual GenerationStats getStats() = 0;
|
|
71
|
+
virtual void close() = 0;
|
|
72
|
+
|
|
73
|
+
protected:
|
|
74
|
+
// Hybrid Setup
|
|
75
|
+
void loadHybridMethods() override;
|
|
76
|
+
|
|
77
|
+
protected:
|
|
78
|
+
// Tag for logging
|
|
79
|
+
static constexpr auto TAG = "LiteRTLM";
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
} // namespace margelo::nitro::litertlm
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// LLMConfig.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
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
// Forward declaration of `Backend` to properly resolve imports.
|
|
32
|
+
namespace margelo::nitro::litertlm { enum class Backend; }
|
|
33
|
+
|
|
34
|
+
#include "Backend.hpp"
|
|
35
|
+
#include <optional>
|
|
36
|
+
|
|
37
|
+
namespace margelo::nitro::litertlm {
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A struct which can be represented as a JavaScript object (LLMConfig).
|
|
41
|
+
*/
|
|
42
|
+
struct LLMConfig final {
|
|
43
|
+
public:
|
|
44
|
+
std::optional<Backend> backend SWIFT_PRIVATE;
|
|
45
|
+
std::optional<double> maxTokens SWIFT_PRIVATE;
|
|
46
|
+
std::optional<double> temperature SWIFT_PRIVATE;
|
|
47
|
+
std::optional<double> topK SWIFT_PRIVATE;
|
|
48
|
+
std::optional<double> topP SWIFT_PRIVATE;
|
|
49
|
+
|
|
50
|
+
public:
|
|
51
|
+
LLMConfig() = default;
|
|
52
|
+
explicit LLMConfig(std::optional<Backend> backend, std::optional<double> maxTokens, std::optional<double> temperature, std::optional<double> topK, std::optional<double> topP): backend(backend), maxTokens(maxTokens), temperature(temperature), topK(topK), topP(topP) {}
|
|
53
|
+
|
|
54
|
+
public:
|
|
55
|
+
friend bool operator==(const LLMConfig& lhs, const LLMConfig& rhs) = default;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
} // namespace margelo::nitro::litertlm
|
|
59
|
+
|
|
60
|
+
namespace margelo::nitro {
|
|
61
|
+
|
|
62
|
+
// C++ LLMConfig <> JS LLMConfig (object)
|
|
63
|
+
template <>
|
|
64
|
+
struct JSIConverter<margelo::nitro::litertlm::LLMConfig> final {
|
|
65
|
+
static inline margelo::nitro::litertlm::LLMConfig fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
66
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
67
|
+
return margelo::nitro::litertlm::LLMConfig(
|
|
68
|
+
JSIConverter<std::optional<margelo::nitro::litertlm::Backend>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "backend"))),
|
|
69
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "maxTokens"))),
|
|
70
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "temperature"))),
|
|
71
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topK"))),
|
|
72
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topP")))
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::litertlm::LLMConfig& arg) {
|
|
76
|
+
jsi::Object obj(runtime);
|
|
77
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "backend"), JSIConverter<std::optional<margelo::nitro::litertlm::Backend>>::toJSI(runtime, arg.backend));
|
|
78
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "maxTokens"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.maxTokens));
|
|
79
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "temperature"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.temperature));
|
|
80
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "topK"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.topK));
|
|
81
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "topP"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.topP));
|
|
82
|
+
return obj;
|
|
83
|
+
}
|
|
84
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
85
|
+
if (!value.isObject()) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
jsi::Object obj = value.getObject(runtime);
|
|
89
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (!JSIConverter<std::optional<margelo::nitro::litertlm::Backend>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "backend")))) return false;
|
|
93
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "maxTokens")))) return false;
|
|
94
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "temperature")))) return false;
|
|
95
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topK")))) return false;
|
|
96
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topP")))) return false;
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// Message.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
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
// Forward declaration of `Role` to properly resolve imports.
|
|
32
|
+
namespace margelo::nitro::litertlm { enum class Role; }
|
|
33
|
+
|
|
34
|
+
#include "Role.hpp"
|
|
35
|
+
#include <string>
|
|
36
|
+
|
|
37
|
+
namespace margelo::nitro::litertlm {
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A struct which can be represented as a JavaScript object (Message).
|
|
41
|
+
*/
|
|
42
|
+
struct Message final {
|
|
43
|
+
public:
|
|
44
|
+
Role role SWIFT_PRIVATE;
|
|
45
|
+
std::string content SWIFT_PRIVATE;
|
|
46
|
+
|
|
47
|
+
public:
|
|
48
|
+
Message() = default;
|
|
49
|
+
explicit Message(Role role, std::string content): role(role), content(content) {}
|
|
50
|
+
|
|
51
|
+
public:
|
|
52
|
+
friend bool operator==(const Message& lhs, const Message& rhs) = default;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
} // namespace margelo::nitro::litertlm
|
|
56
|
+
|
|
57
|
+
namespace margelo::nitro {
|
|
58
|
+
|
|
59
|
+
// C++ Message <> JS Message (object)
|
|
60
|
+
template <>
|
|
61
|
+
struct JSIConverter<margelo::nitro::litertlm::Message> final {
|
|
62
|
+
static inline margelo::nitro::litertlm::Message fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
63
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
64
|
+
return margelo::nitro::litertlm::Message(
|
|
65
|
+
JSIConverter<margelo::nitro::litertlm::Role>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "role"))),
|
|
66
|
+
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "content")))
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::litertlm::Message& arg) {
|
|
70
|
+
jsi::Object obj(runtime);
|
|
71
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "role"), JSIConverter<margelo::nitro::litertlm::Role>::toJSI(runtime, arg.role));
|
|
72
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "content"), JSIConverter<std::string>::toJSI(runtime, arg.content));
|
|
73
|
+
return obj;
|
|
74
|
+
}
|
|
75
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
76
|
+
if (!value.isObject()) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
jsi::Object obj = value.getObject(runtime);
|
|
80
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
if (!JSIConverter<margelo::nitro::litertlm::Role>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "role")))) return false;
|
|
84
|
+
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "content")))) return false;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
} // namespace margelo::nitro
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// Role.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
|
+
#if __has_include(<NitroModules/NitroHash.hpp>)
|
|
11
|
+
#include <NitroModules/NitroHash.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
16
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
21
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
namespace margelo::nitro::litertlm {
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An enum which can be represented as a JavaScript union (Role).
|
|
30
|
+
*/
|
|
31
|
+
enum class Role {
|
|
32
|
+
USER SWIFT_NAME(user) = 0,
|
|
33
|
+
MODEL SWIFT_NAME(model) = 1,
|
|
34
|
+
SYSTEM SWIFT_NAME(system) = 2,
|
|
35
|
+
} CLOSED_ENUM;
|
|
36
|
+
|
|
37
|
+
} // namespace margelo::nitro::litertlm
|
|
38
|
+
|
|
39
|
+
namespace margelo::nitro {
|
|
40
|
+
|
|
41
|
+
// C++ Role <> JS Role (union)
|
|
42
|
+
template <>
|
|
43
|
+
struct JSIConverter<margelo::nitro::litertlm::Role> final {
|
|
44
|
+
static inline margelo::nitro::litertlm::Role fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
45
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
|
|
46
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
47
|
+
case hashString("user"): return margelo::nitro::litertlm::Role::USER;
|
|
48
|
+
case hashString("model"): return margelo::nitro::litertlm::Role::MODEL;
|
|
49
|
+
case hashString("system"): return margelo::nitro::litertlm::Role::SYSTEM;
|
|
50
|
+
default: [[unlikely]]
|
|
51
|
+
throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum Role - invalid value!");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::litertlm::Role arg) {
|
|
55
|
+
switch (arg) {
|
|
56
|
+
case margelo::nitro::litertlm::Role::USER: return JSIConverter<std::string>::toJSI(runtime, "user");
|
|
57
|
+
case margelo::nitro::litertlm::Role::MODEL: return JSIConverter<std::string>::toJSI(runtime, "model");
|
|
58
|
+
case margelo::nitro::litertlm::Role::SYSTEM: return JSIConverter<std::string>::toJSI(runtime, "system");
|
|
59
|
+
default: [[unlikely]]
|
|
60
|
+
throw std::invalid_argument("Cannot convert Role to JS - invalid value: "
|
|
61
|
+
+ std::to_string(static_cast<int>(arg)) + "!");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
65
|
+
if (!value.isString()) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
|
|
69
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
70
|
+
case hashString("user"):
|
|
71
|
+
case hashString("model"):
|
|
72
|
+
case hashString("system"):
|
|
73
|
+
return true;
|
|
74
|
+
default:
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
} // namespace margelo::nitro
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-litert-lm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "High-performance LLM inference for React Native using LiteRT-LM. Optimized for Gemma 3n and other on-device language models.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Hugh Chen (https://github.com/hung-yueh)",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/hung-yueh/react-native-litert-lm.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/hung-yueh/react-native-litert-lm#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/hung-yueh/react-native-litert-lm/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"react-native",
|
|
17
|
+
"nitro",
|
|
18
|
+
"litert",
|
|
19
|
+
"litert-lm",
|
|
20
|
+
"llm",
|
|
21
|
+
"gemma",
|
|
22
|
+
"gemma-3n",
|
|
23
|
+
"ai",
|
|
24
|
+
"machine-learning",
|
|
25
|
+
"on-device",
|
|
26
|
+
"inference",
|
|
27
|
+
"expo"
|
|
28
|
+
],
|
|
29
|
+
"main": "lib/index",
|
|
30
|
+
"module": "lib/index",
|
|
31
|
+
"types": "lib/index.d.ts",
|
|
32
|
+
"react-native": "src/index",
|
|
33
|
+
"source": "src/index",
|
|
34
|
+
"files": [
|
|
35
|
+
"src",
|
|
36
|
+
"lib",
|
|
37
|
+
"android/src",
|
|
38
|
+
"android/build.gradle",
|
|
39
|
+
"android/CMakeLists.txt",
|
|
40
|
+
"ios",
|
|
41
|
+
"cpp",
|
|
42
|
+
"nitrogen/generated",
|
|
43
|
+
"react-native.config.js",
|
|
44
|
+
"react-native-litert-lm.podspec",
|
|
45
|
+
"app.plugin.js",
|
|
46
|
+
"README.md"
|
|
47
|
+
],
|
|
48
|
+
"sideEffects": false,
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=22"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsc",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\" --fix",
|
|
56
|
+
"prepack": "npm run build",
|
|
57
|
+
"specs": "npx nitrogen",
|
|
58
|
+
"clean": "rm -rf lib android/build ios/build nitrogen/generated",
|
|
59
|
+
"android": "expo run:android",
|
|
60
|
+
"android:clean": "cd android && ./gradlew clean",
|
|
61
|
+
"ios": "expo run:ios",
|
|
62
|
+
"release": "release-it"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@expo/config-plugins": "~54.0.4",
|
|
66
|
+
"@types/react": "~19.1.10",
|
|
67
|
+
"expo": "^54.0.31",
|
|
68
|
+
"nitrogen": "^0.33.2",
|
|
69
|
+
"react": "19.1.0",
|
|
70
|
+
"react-native": "0.81.5",
|
|
71
|
+
"release-it": "^19.2.4",
|
|
72
|
+
"typescript": "^5.0.0"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"expo": ">=54.0.0",
|
|
76
|
+
"react": "*",
|
|
77
|
+
"react-native": "*"
|
|
78
|
+
},
|
|
79
|
+
"peerDependenciesMeta": {
|
|
80
|
+
"expo": {
|
|
81
|
+
"optional": true
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"dependencies": {
|
|
85
|
+
"react-native-nitro-modules": "^0.33.2"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "react-native-litert-lm"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
s.platforms = { :ios => "15.0" }
|
|
13
|
+
s.source = { :git => package["repository"]["url"], :tag => "#{s.version}" }
|
|
14
|
+
|
|
15
|
+
s.swift_version = '5.0'
|
|
16
|
+
|
|
17
|
+
s.source_files = [
|
|
18
|
+
# Implementation (C++)
|
|
19
|
+
"cpp/**/*.{hpp,cpp}",
|
|
20
|
+
# Autolinking (Objective-C++)
|
|
21
|
+
"ios/**/*.{m,mm}",
|
|
22
|
+
# Nitrogen generated iOS bridge
|
|
23
|
+
"nitrogen/generated/ios/**/*.{mm,swift}",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
s.pod_target_xcconfig = {
|
|
27
|
+
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++20',
|
|
28
|
+
'CLANG_CXX_LIBRARY' => 'libc++',
|
|
29
|
+
'HEADER_SEARCH_PATHS' => [
|
|
30
|
+
'"$(PODS_TARGET_SRCROOT)/cpp"',
|
|
31
|
+
'"$(PODS_TARGET_SRCROOT)/nitrogen/generated/shared/c++"',
|
|
32
|
+
'"$(PODS_TARGET_SRCROOT)/nitrogen/generated/ios"',
|
|
33
|
+
].join(' '),
|
|
34
|
+
# Stub mode - LiteRT-LM iOS not yet available
|
|
35
|
+
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) LITERT_LM_IOS_STUB=1',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Load nitrogen autolinking
|
|
39
|
+
load 'nitrogen/generated/ios/LiteRTLM+autolinking.rb'
|
|
40
|
+
add_nitrogen_files(s)
|
|
41
|
+
|
|
42
|
+
# Core dependencies only - no LLM runtime yet
|
|
43
|
+
s.dependency 'React-jsi'
|
|
44
|
+
s.dependency 'React-callinvoker'
|
|
45
|
+
s.dependency 'ReactCommon/turbomodule/core'
|
|
46
|
+
|
|
47
|
+
# TODO: Add LiteRT-LM iOS dependency when officially released
|
|
48
|
+
# s.dependency 'LiteRTLM', '~> 1.0'
|
|
49
|
+
|
|
50
|
+
install_modules_dependencies(s)
|
|
51
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
dependency: {
|
|
3
|
+
platforms: {
|
|
4
|
+
android: {
|
|
5
|
+
sourceDir: "./android",
|
|
6
|
+
packageImportPath: "import dev.litert.litertlm.LiteRTLMPackage;",
|
|
7
|
+
packageInstance: "new LiteRTLMPackage()",
|
|
8
|
+
componentDescriptors: [],
|
|
9
|
+
cmakeListsPath: "CMakeLists.txt",
|
|
10
|
+
},
|
|
11
|
+
ios: {
|
|
12
|
+
podspecPath: "./react-native-litert-lm.podspec",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { NitroModules } from "react-native-nitro-modules";
|
|
2
|
+
import { Platform } from "react-native";
|
|
3
|
+
import type {
|
|
4
|
+
LiteRTLM,
|
|
5
|
+
LLMConfig,
|
|
6
|
+
Message,
|
|
7
|
+
Backend,
|
|
8
|
+
Role,
|
|
9
|
+
GenerationStats,
|
|
10
|
+
} from "./specs/LiteRTLM.nitro";
|
|
11
|
+
|
|
12
|
+
export type {
|
|
13
|
+
LiteRTLM,
|
|
14
|
+
LLMConfig,
|
|
15
|
+
Message,
|
|
16
|
+
Backend,
|
|
17
|
+
Role,
|
|
18
|
+
GenerationStats,
|
|
19
|
+
} from "./specs/LiteRTLM.nitro";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new LiteRT-LM inference engine instance.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { createLLM } from 'react-native-litert-lm';
|
|
27
|
+
*
|
|
28
|
+
* // Basic usage with Gemma 3n
|
|
29
|
+
* const llm = createLLM();
|
|
30
|
+
* llm.loadModel('/path/to/gemma-3n-e2b.litertlm', {
|
|
31
|
+
* backend: 'gpu',
|
|
32
|
+
* temperature: 0.7,
|
|
33
|
+
* maxTokens: 512
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Simple text generation
|
|
37
|
+
* const response = llm.sendMessage('Hello, how are you?');
|
|
38
|
+
* console.log(response);
|
|
39
|
+
*
|
|
40
|
+
* // Streaming generation
|
|
41
|
+
* llm.sendMessageAsync('Tell me about React Native', (token, done) => {
|
|
42
|
+
* process.stdout.write(token);
|
|
43
|
+
* if (done) console.log('\n--- Done ---');
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* // Check stats
|
|
47
|
+
* const stats = llm.getStats();
|
|
48
|
+
* console.log(`Generated at ${stats.tokensPerSecond} tokens/sec`);
|
|
49
|
+
*
|
|
50
|
+
* // Cleanup
|
|
51
|
+
* llm.close();
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function createLLM(): LiteRTLM {
|
|
55
|
+
return NitroModules.createHybridObject<LiteRTLM>("LiteRTLM");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Pre-defined model identifiers for common models.
|
|
60
|
+
* Use with model download utilities or as reference.
|
|
61
|
+
*/
|
|
62
|
+
export const Models = {
|
|
63
|
+
/** Gemma 3n E2B (2B parameters, efficient) */
|
|
64
|
+
GEMMA_3N_E2B: "gemma-3n-E2B-it-litert-lm-preview",
|
|
65
|
+
/** Gemma 3n E4B (4B parameters, higher quality) */
|
|
66
|
+
GEMMA_3N_E4B: "gemma-3n-E4B-it-litert-lm-preview",
|
|
67
|
+
/** Gemma 3 1B (smallest Gemma) */
|
|
68
|
+
GEMMA_3_1B: "Gemma3-1B-IT_multi-prefill-seq_q4_ekv4096",
|
|
69
|
+
/** Phi-4 Mini Instruct */
|
|
70
|
+
PHI_4_MINI: "Phi-4-mini-instruct_multi-prefill-seq_q8_ekv4096",
|
|
71
|
+
/** Qwen 2.5 1.5B Instruct */
|
|
72
|
+
QWEN_2_5_1_5B: "Qwen2.5-1.5B-Instruct_multi-prefill-seq_q8_ekv4096",
|
|
73
|
+
} as const;
|
|
74
|
+
|
|
75
|
+
export type ModelId = (typeof Models)[keyof typeof Models];
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Get the recommended backend for the current platform.
|
|
79
|
+
* Returns 'gpu' for most devices as it provides the best balance of speed and compatibility.
|
|
80
|
+
*
|
|
81
|
+
* @returns The recommended backend ('gpu' for most cases)
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const backend = getRecommendedBackend();
|
|
86
|
+
* llm.loadModel(path, { backend });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export function getRecommendedBackend(): Backend {
|
|
90
|
+
// GPU is the recommended default for all platforms
|
|
91
|
+
// It provides good performance and broad compatibility
|
|
92
|
+
return "gpu";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check if a backend configuration is supported on the current platform.
|
|
97
|
+
* Returns a warning message if the configuration may have issues.
|
|
98
|
+
*
|
|
99
|
+
* @param backend The backend to check
|
|
100
|
+
* @returns Warning message if there may be issues, undefined if OK
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const warning = checkBackendSupport('npu');
|
|
105
|
+
* if (warning) {
|
|
106
|
+
* console.warn(warning);
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export function checkBackendSupport(backend: Backend): string | undefined {
|
|
111
|
+
if (backend === "npu") {
|
|
112
|
+
if (Platform.OS === "android") {
|
|
113
|
+
return "NPU backend requires compatible hardware (Qualcomm Hexagon, MediaTek APU, etc.). Will fall back to GPU if unavailable.";
|
|
114
|
+
}
|
|
115
|
+
if (Platform.OS === "ios") {
|
|
116
|
+
return "NPU/CoreML is not yet supported on iOS. LiteRT-LM iOS support is pending.";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (Platform.OS === "ios" && backend !== "cpu") {
|
|
121
|
+
return "LiteRT-LM iOS is not yet released. Only CPU backend may work via fallback.";
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|