@dr33m/react-native-litert-lm 0.5.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 +627 -0
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +104 -0
- package/android/src/main/AndroidManifest.xml +19 -0
- package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLM.kt +888 -0
- package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/HybridModelStore.kt +189 -0
- package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/LiteRTLMRegistry.kt +32 -0
- package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/MultimodalPartFactories.kt +15 -0
- package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/StreamingCallbackListener.kt +89 -0
- package/android/src/main/java/dev/litert/litertlm/LiteRTLMInitProvider.kt +57 -0
- package/android/src/main/java/dev/litert/litertlm/LiteRTLMPackage.kt +43 -0
- package/android/src/test/java/com/margelo/nitro/core/Promise.kt +46 -0
- package/android/src/test/java/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMTest.kt +122 -0
- package/app.plugin.js +58 -0
- package/cpp/cpp-adapter.cpp +21 -0
- package/cpp/include/README.md +32 -0
- package/cpp/include/litert_lm_engine.h +516 -0
- package/cpp/include/stb_image.h +7988 -0
- package/ios/HybridLiteRTLM+Execute.swift +287 -0
- package/ios/HybridLiteRTLM+Streaming.swift +153 -0
- package/ios/HybridLiteRTLM.swift +541 -0
- package/ios/HybridModelStore.swift +206 -0
- package/ios/MultimodalPart+Factories.swift +22 -0
- package/ios/Tests/HybridLiteRTLMTests.swift +187 -0
- package/lib/__mocks__/react-native-nitro-modules.d.ts +81 -0
- package/lib/__mocks__/react-native-nitro-modules.js +98 -0
- package/lib/__tests__/hooks.test.d.ts +1 -0
- package/lib/__tests__/hooks.test.js +175 -0
- package/lib/__tests__/inferenceRouting.test.d.ts +1 -0
- package/lib/__tests__/inferenceRouting.test.js +28 -0
- package/lib/__tests__/memoryTracker.test.d.ts +1 -0
- package/lib/__tests__/memoryTracker.test.js +74 -0
- package/lib/__tests__/modelFactory.test.d.ts +1 -0
- package/lib/__tests__/modelFactory.test.js +107 -0
- package/lib/__tests__/modelPath.test.d.ts +1 -0
- package/lib/__tests__/modelPath.test.js +12 -0
- package/lib/__tests__/modelRegistry.test.d.ts +1 -0
- package/lib/__tests__/modelRegistry.test.js +61 -0
- package/lib/hooks.d.ts +46 -0
- package/lib/hooks.js +159 -0
- package/lib/index.d.ts +142 -0
- package/lib/index.js +184 -0
- package/lib/inferenceRouting.d.ts +18 -0
- package/lib/inferenceRouting.js +63 -0
- package/lib/memoryTracker.d.ts +128 -0
- package/lib/memoryTracker.js +155 -0
- package/lib/modelFactory.d.ts +24 -0
- package/lib/modelFactory.js +128 -0
- package/lib/modelPath.d.ts +8 -0
- package/lib/modelPath.js +18 -0
- package/lib/modelRegistry.d.ts +55 -0
- package/lib/modelRegistry.js +82 -0
- package/lib/specs/LiteRTLM.nitro.d.ts +380 -0
- package/lib/specs/LiteRTLM.nitro.js +2 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/LiteRTLM+autolinking.cmake +83 -0
- package/nitrogen/generated/android/LiteRTLM+autolinking.gradle +27 -0
- package/nitrogen/generated/android/LiteRTLMOnLoad.cpp +74 -0
- package/nitrogen/generated/android/LiteRTLMOnLoad.hpp +34 -0
- package/nitrogen/generated/android/c++/JBackend.hpp +61 -0
- package/nitrogen/generated/android/c++/JExecuteResult.hpp +86 -0
- package/nitrogen/generated/android/c++/JFunc_void_double.hpp +75 -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 +371 -0
- package/nitrogen/generated/android/c++/JHybridLiteRTLMSpec.hpp +83 -0
- package/nitrogen/generated/android/c++/JHybridModelStoreSpec.cpp +101 -0
- package/nitrogen/generated/android/c++/JHybridModelStoreSpec.hpp +67 -0
- package/nitrogen/generated/android/c++/JLLMConfig.hpp +125 -0
- package/nitrogen/generated/android/c++/JMemoryUsage.hpp +69 -0
- package/nitrogen/generated/android/c++/JMessage.hpp +63 -0
- package/nitrogen/generated/android/c++/JModelFile.hpp +69 -0
- package/nitrogen/generated/android/c++/JMultimodalPart.hpp +78 -0
- package/nitrogen/generated/android/c++/JPartType.hpp +61 -0
- package/nitrogen/generated/android/c++/JRole.hpp +61 -0
- package/nitrogen/generated/android/c++/JToolCall.hpp +61 -0
- package/nitrogen/generated/android/c++/JToolDefinition.hpp +65 -0
- package/nitrogen/generated/android/c++/JToolResponse.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/ExecuteResult.kt +61 -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/Func_void_std__string_bool.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/GenerationStats.kt +76 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/HybridLiteRTLMSpec.kt +165 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/HybridModelStoreSpec.kt +76 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/LLMConfig.kt +106 -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/MemoryUsage.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Message.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/ModelFile.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/MultimodalPart.kt +71 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/PartType.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/Role.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/ToolCall.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/ToolDefinition.kt +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/dev/litert/litertlm/ToolResponse.kt +56 -0
- package/nitrogen/generated/ios/LiteRTLM+autolinking.rb +62 -0
- package/nitrogen/generated/ios/LiteRTLM-Swift-Cxx-Bridge.cpp +98 -0
- package/nitrogen/generated/ios/LiteRTLM-Swift-Cxx-Bridge.hpp +585 -0
- package/nitrogen/generated/ios/LiteRTLM-Swift-Cxx-Umbrella.hpp +93 -0
- package/nitrogen/generated/ios/LiteRTLMAutolinking.mm +41 -0
- package/nitrogen/generated/ios/LiteRTLMAutolinking.swift +38 -0
- package/nitrogen/generated/ios/c++/HybridLiteRTLMSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridLiteRTLMSpecSwift.hpp +279 -0
- package/nitrogen/generated/ios/c++/HybridModelStoreSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridModelStoreSpecSwift.hpp +117 -0
- package/nitrogen/generated/ios/swift/Backend.swift +44 -0
- package/nitrogen/generated/ios/swift/ExecuteResult.swift +45 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_ExecuteResult.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_double.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string_bool.swift +46 -0
- package/nitrogen/generated/ios/swift/GenerationStats.swift +54 -0
- package/nitrogen/generated/ios/swift/HybridLiteRTLMSpec.swift +75 -0
- package/nitrogen/generated/ios/swift/HybridLiteRTLMSpec_cxx.swift +516 -0
- package/nitrogen/generated/ios/swift/HybridModelStoreSpec.swift +59 -0
- package/nitrogen/generated/ios/swift/HybridModelStoreSpec_cxx.swift +203 -0
- package/nitrogen/generated/ios/swift/LLMConfig.swift +239 -0
- package/nitrogen/generated/ios/swift/MemoryUsage.swift +44 -0
- package/nitrogen/generated/ios/swift/Message.swift +34 -0
- package/nitrogen/generated/ios/swift/ModelFile.swift +44 -0
- package/nitrogen/generated/ios/swift/MultimodalPart.swift +101 -0
- package/nitrogen/generated/ios/swift/PartType.swift +44 -0
- package/nitrogen/generated/ios/swift/Role.swift +44 -0
- package/nitrogen/generated/ios/swift/ToolCall.swift +34 -0
- package/nitrogen/generated/ios/swift/ToolDefinition.swift +39 -0
- package/nitrogen/generated/ios/swift/ToolResponse.swift +34 -0
- package/nitrogen/generated/shared/c++/Backend.hpp +80 -0
- package/nitrogen/generated/shared/c++/ExecuteResult.hpp +94 -0
- package/nitrogen/generated/shared/c++/GenerationStats.hpp +103 -0
- package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.cpp +41 -0
- package/nitrogen/generated/shared/c++/HybridLiteRTLMSpec.hpp +109 -0
- package/nitrogen/generated/shared/c++/HybridModelStoreSpec.cpp +25 -0
- package/nitrogen/generated/shared/c++/HybridModelStoreSpec.hpp +71 -0
- package/nitrogen/generated/shared/c++/LLMConfig.hpp +134 -0
- package/nitrogen/generated/shared/c++/MemoryUsage.hpp +95 -0
- package/nitrogen/generated/shared/c++/Message.hpp +89 -0
- package/nitrogen/generated/shared/c++/ModelFile.hpp +95 -0
- package/nitrogen/generated/shared/c++/MultimodalPart.hpp +103 -0
- package/nitrogen/generated/shared/c++/PartType.hpp +80 -0
- package/nitrogen/generated/shared/c++/Role.hpp +80 -0
- package/nitrogen/generated/shared/c++/ToolCall.hpp +87 -0
- package/nitrogen/generated/shared/c++/ToolDefinition.hpp +91 -0
- package/nitrogen/generated/shared/c++/ToolResponse.hpp +87 -0
- package/package.json +115 -0
- package/react-native-litert-lm.podspec +62 -0
- package/react-native.config.js +16 -0
- package/scripts/download-ios-frameworks.sh +39 -0
- package/scripts/framework-source.js +46 -0
- package/scripts/postinstall.js +145 -0
- package/src/__mocks__/react-native-nitro-modules.ts +132 -0
- package/src/__tests__/hooks.test.ts +216 -0
- package/src/__tests__/inferenceRouting.test.ts +36 -0
- package/src/__tests__/memoryTracker.test.ts +87 -0
- package/src/__tests__/modelFactory.test.ts +153 -0
- package/src/__tests__/modelPath.test.ts +14 -0
- package/src/__tests__/modelRegistry.test.ts +73 -0
- package/src/hooks.ts +234 -0
- package/src/index.ts +214 -0
- package/src/inferenceRouting.ts +80 -0
- package/src/memoryTracker.ts +268 -0
- package/src/modelFactory.ts +163 -0
- package/src/modelPath.ts +16 -0
- package/src/modelRegistry.ts +104 -0
- package/src/specs/LiteRTLM.nitro.ts +451 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory tracking utilities for LiteRT-LM using real native memory metrics.
|
|
3
|
+
*
|
|
4
|
+
* Records real memory usage from OS-level APIs via `getMemoryUsage()`,
|
|
5
|
+
* and stores snapshots in a native-backed ArrayBuffer allocated via
|
|
6
|
+
* `NitroModules.createNativeArrayBuffer()` (v0.35+) for zero-copy interop.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { createMemoryTracker } from 'react-native-litert-lm';
|
|
11
|
+
*
|
|
12
|
+
* const tracker = createMemoryTracker(100);
|
|
13
|
+
*
|
|
14
|
+
* // Record a real snapshot (typically called internally after inference)
|
|
15
|
+
* tracker.record({
|
|
16
|
+
* timestamp: Date.now(),
|
|
17
|
+
* nativeHeapBytes: usage.nativeHeapBytes,
|
|
18
|
+
* residentBytes: usage.residentBytes,
|
|
19
|
+
* availableMemoryBytes: usage.availableMemoryBytes,
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* console.log(`Peak RSS: ${tracker.getPeakMemory()} bytes`);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* A single memory usage snapshot with real data from OS APIs.
|
|
27
|
+
*/
|
|
28
|
+
export interface MemorySnapshot {
|
|
29
|
+
/** Unix timestamp in milliseconds */
|
|
30
|
+
timestamp: number;
|
|
31
|
+
/** Native heap allocated bytes (Debug.getNativeHeapAllocatedSize on Android, task_info on iOS) */
|
|
32
|
+
nativeHeapBytes: number;
|
|
33
|
+
/** Process resident set size (RSS) in bytes */
|
|
34
|
+
residentBytes: number;
|
|
35
|
+
/** Available system memory in bytes */
|
|
36
|
+
availableMemoryBytes: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Memory tracker that stores snapshots in a native-backed ArrayBuffer.
|
|
40
|
+
*
|
|
41
|
+
* Uses `NitroModules.createNativeArrayBuffer()` to allocate the backing
|
|
42
|
+
* buffer in native (C++) memory, ensuring zero-copy interop with native
|
|
43
|
+
* methods and keeping memory tracking data off the JS heap.
|
|
44
|
+
*/
|
|
45
|
+
export interface MemoryTracker {
|
|
46
|
+
/**
|
|
47
|
+
* Record a new memory snapshot.
|
|
48
|
+
* @param snapshot The memory usage data to record
|
|
49
|
+
* @returns true if recorded, false if buffer is full
|
|
50
|
+
*/
|
|
51
|
+
record(snapshot: MemorySnapshot): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Get all recorded snapshots as structured objects.
|
|
54
|
+
*/
|
|
55
|
+
getSnapshots(): MemorySnapshot[];
|
|
56
|
+
/**
|
|
57
|
+
* Get the number of recorded snapshots.
|
|
58
|
+
*/
|
|
59
|
+
getSnapshotCount(): number;
|
|
60
|
+
/**
|
|
61
|
+
* Get the maximum number of snapshots this tracker can hold.
|
|
62
|
+
*/
|
|
63
|
+
getCapacity(): number;
|
|
64
|
+
/**
|
|
65
|
+
* Get the peak resident set size across all snapshots.
|
|
66
|
+
*/
|
|
67
|
+
getPeakMemory(): number;
|
|
68
|
+
/**
|
|
69
|
+
* Get the latest memory snapshot, or undefined if none recorded.
|
|
70
|
+
*/
|
|
71
|
+
getLatestSnapshot(): MemorySnapshot | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* Get the underlying native ArrayBuffer.
|
|
74
|
+
* This buffer is allocated via `NitroModules.createNativeArrayBuffer()`
|
|
75
|
+
* and lives in native memory, enabling zero-copy transfer to native methods.
|
|
76
|
+
*/
|
|
77
|
+
getNativeBuffer(): ArrayBuffer;
|
|
78
|
+
/**
|
|
79
|
+
* Get the Float64Array view over the native buffer.
|
|
80
|
+
*/
|
|
81
|
+
getView(): Float64Array;
|
|
82
|
+
/**
|
|
83
|
+
* Reset the tracker, clearing all recorded snapshots.
|
|
84
|
+
* The native buffer is preserved (not reallocated).
|
|
85
|
+
*/
|
|
86
|
+
reset(): void;
|
|
87
|
+
/**
|
|
88
|
+
* Get a summary of memory usage statistics.
|
|
89
|
+
*/
|
|
90
|
+
getSummary(): MemoryTrackerSummary;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Summary statistics from the memory tracker.
|
|
94
|
+
*/
|
|
95
|
+
export interface MemoryTrackerSummary {
|
|
96
|
+
/** Number of snapshots recorded */
|
|
97
|
+
snapshotCount: number;
|
|
98
|
+
/** Peak resident set size in bytes */
|
|
99
|
+
peakResidentBytes: number;
|
|
100
|
+
/** Average resident set size in bytes */
|
|
101
|
+
averageResidentBytes: number;
|
|
102
|
+
/** Latest resident set size in bytes */
|
|
103
|
+
currentResidentBytes: number;
|
|
104
|
+
/** Peak native heap allocated in bytes */
|
|
105
|
+
peakNativeHeapBytes: number;
|
|
106
|
+
/** Latest native heap allocated in bytes */
|
|
107
|
+
currentNativeHeapBytes: number;
|
|
108
|
+
/** RSS delta from first to last snapshot in bytes */
|
|
109
|
+
residentDeltaBytes: number;
|
|
110
|
+
/** Size of the native tracking buffer itself in bytes */
|
|
111
|
+
trackerBufferSizeBytes: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Create a new memory tracker backed by a native ArrayBuffer.
|
|
115
|
+
*
|
|
116
|
+
* @param maxSnapshots Maximum number of snapshots to store (default: 256)
|
|
117
|
+
* @returns A MemoryTracker instance
|
|
118
|
+
*/
|
|
119
|
+
export declare function createMemoryTracker(maxSnapshots?: number): MemoryTracker;
|
|
120
|
+
/**
|
|
121
|
+
* Create a native ArrayBuffer for efficient data transfer.
|
|
122
|
+
*
|
|
123
|
+
* A convenience wrapper around `NitroModules.createNativeArrayBuffer()`.
|
|
124
|
+
*
|
|
125
|
+
* @param size Size in bytes
|
|
126
|
+
* @returns A native-backed ArrayBuffer
|
|
127
|
+
*/
|
|
128
|
+
export declare function createNativeBuffer(size: number): ArrayBuffer;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Memory tracking utilities for LiteRT-LM using real native memory metrics.
|
|
4
|
+
*
|
|
5
|
+
* Records real memory usage from OS-level APIs via `getMemoryUsage()`,
|
|
6
|
+
* and stores snapshots in a native-backed ArrayBuffer allocated via
|
|
7
|
+
* `NitroModules.createNativeArrayBuffer()` (v0.35+) for zero-copy interop.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createMemoryTracker } from 'react-native-litert-lm';
|
|
12
|
+
*
|
|
13
|
+
* const tracker = createMemoryTracker(100);
|
|
14
|
+
*
|
|
15
|
+
* // Record a real snapshot (typically called internally after inference)
|
|
16
|
+
* tracker.record({
|
|
17
|
+
* timestamp: Date.now(),
|
|
18
|
+
* nativeHeapBytes: usage.nativeHeapBytes,
|
|
19
|
+
* residentBytes: usage.residentBytes,
|
|
20
|
+
* availableMemoryBytes: usage.availableMemoryBytes,
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* console.log(`Peak RSS: ${tracker.getPeakMemory()} bytes`);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.createMemoryTracker = createMemoryTracker;
|
|
28
|
+
exports.createNativeBuffer = createNativeBuffer;
|
|
29
|
+
const react_native_nitro_modules_1 = require("react-native-nitro-modules");
|
|
30
|
+
/** Number of Float64 fields per snapshot */
|
|
31
|
+
const FIELDS_PER_SNAPSHOT = 4;
|
|
32
|
+
/** Bytes per Float64 value */
|
|
33
|
+
const BYTES_PER_FIELD = Float64Array.BYTES_PER_ELEMENT; // 8
|
|
34
|
+
/**
|
|
35
|
+
* Create a new memory tracker backed by a native ArrayBuffer.
|
|
36
|
+
*
|
|
37
|
+
* @param maxSnapshots Maximum number of snapshots to store (default: 256)
|
|
38
|
+
* @returns A MemoryTracker instance
|
|
39
|
+
*/
|
|
40
|
+
function createMemoryTracker(maxSnapshots = 256) {
|
|
41
|
+
const bufferSize = maxSnapshots * FIELDS_PER_SNAPSHOT * BYTES_PER_FIELD;
|
|
42
|
+
// Use NitroModules.createNativeArrayBuffer for native-backed allocation.
|
|
43
|
+
const nativeBuffer = react_native_nitro_modules_1.NitroModules.createNativeArrayBuffer(bufferSize);
|
|
44
|
+
const view = new Float64Array(nativeBuffer);
|
|
45
|
+
let currentIndex = 0;
|
|
46
|
+
return {
|
|
47
|
+
record(snapshot) {
|
|
48
|
+
if (currentIndex >= maxSnapshots) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const offset = currentIndex * FIELDS_PER_SNAPSHOT;
|
|
52
|
+
view[offset] = snapshot.timestamp;
|
|
53
|
+
view[offset + 1] = snapshot.nativeHeapBytes;
|
|
54
|
+
view[offset + 2] = snapshot.residentBytes;
|
|
55
|
+
view[offset + 3] = snapshot.availableMemoryBytes;
|
|
56
|
+
currentIndex++;
|
|
57
|
+
return true;
|
|
58
|
+
},
|
|
59
|
+
getSnapshots() {
|
|
60
|
+
const snapshots = [];
|
|
61
|
+
for (let i = 0; i < currentIndex; i++) {
|
|
62
|
+
const offset = i * FIELDS_PER_SNAPSHOT;
|
|
63
|
+
snapshots.push({
|
|
64
|
+
timestamp: view[offset],
|
|
65
|
+
nativeHeapBytes: view[offset + 1],
|
|
66
|
+
residentBytes: view[offset + 2],
|
|
67
|
+
availableMemoryBytes: view[offset + 3],
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return snapshots;
|
|
71
|
+
},
|
|
72
|
+
getSnapshotCount() {
|
|
73
|
+
return currentIndex;
|
|
74
|
+
},
|
|
75
|
+
getCapacity() {
|
|
76
|
+
return maxSnapshots;
|
|
77
|
+
},
|
|
78
|
+
getPeakMemory() {
|
|
79
|
+
let peak = 0;
|
|
80
|
+
for (let i = 0; i < currentIndex; i++) {
|
|
81
|
+
const rss = view[i * FIELDS_PER_SNAPSHOT + 2];
|
|
82
|
+
if (rss > peak) {
|
|
83
|
+
peak = rss;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return peak;
|
|
87
|
+
},
|
|
88
|
+
getLatestSnapshot() {
|
|
89
|
+
if (currentIndex === 0)
|
|
90
|
+
return undefined;
|
|
91
|
+
const offset = (currentIndex - 1) * FIELDS_PER_SNAPSHOT;
|
|
92
|
+
return {
|
|
93
|
+
timestamp: view[offset],
|
|
94
|
+
nativeHeapBytes: view[offset + 1],
|
|
95
|
+
residentBytes: view[offset + 2],
|
|
96
|
+
availableMemoryBytes: view[offset + 3],
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
getNativeBuffer() {
|
|
100
|
+
return nativeBuffer;
|
|
101
|
+
},
|
|
102
|
+
getView() {
|
|
103
|
+
return view;
|
|
104
|
+
},
|
|
105
|
+
reset() {
|
|
106
|
+
view.fill(0);
|
|
107
|
+
currentIndex = 0;
|
|
108
|
+
},
|
|
109
|
+
getSummary() {
|
|
110
|
+
let peakRss = 0;
|
|
111
|
+
let peakHeap = 0;
|
|
112
|
+
let sumRss = 0;
|
|
113
|
+
let firstRss = 0;
|
|
114
|
+
let lastRss = 0;
|
|
115
|
+
let lastHeap = 0;
|
|
116
|
+
for (let i = 0; i < currentIndex; i++) {
|
|
117
|
+
const offset = i * FIELDS_PER_SNAPSHOT;
|
|
118
|
+
const heap = view[offset + 1];
|
|
119
|
+
const rss = view[offset + 2];
|
|
120
|
+
if (rss > peakRss)
|
|
121
|
+
peakRss = rss;
|
|
122
|
+
if (heap > peakHeap)
|
|
123
|
+
peakHeap = heap;
|
|
124
|
+
sumRss += rss;
|
|
125
|
+
if (i === 0)
|
|
126
|
+
firstRss = rss;
|
|
127
|
+
if (i === currentIndex - 1) {
|
|
128
|
+
lastRss = rss;
|
|
129
|
+
lastHeap = heap;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
snapshotCount: currentIndex,
|
|
134
|
+
peakResidentBytes: peakRss,
|
|
135
|
+
averageResidentBytes: currentIndex > 0 ? sumRss / currentIndex : 0,
|
|
136
|
+
currentResidentBytes: lastRss,
|
|
137
|
+
peakNativeHeapBytes: peakHeap,
|
|
138
|
+
currentNativeHeapBytes: lastHeap,
|
|
139
|
+
residentDeltaBytes: lastRss - firstRss,
|
|
140
|
+
trackerBufferSizeBytes: bufferSize,
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Create a native ArrayBuffer for efficient data transfer.
|
|
147
|
+
*
|
|
148
|
+
* A convenience wrapper around `NitroModules.createNativeArrayBuffer()`.
|
|
149
|
+
*
|
|
150
|
+
* @param size Size in bytes
|
|
151
|
+
* @returns A native-backed ArrayBuffer
|
|
152
|
+
*/
|
|
153
|
+
function createNativeBuffer(size) {
|
|
154
|
+
return react_native_nitro_modules_1.NitroModules.createNativeArrayBuffer(size);
|
|
155
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { LiteRTLM, LLMConfig } from "./specs/LiteRTLM.nitro";
|
|
2
|
+
import { MemoryTracker } from "./memoryTracker";
|
|
3
|
+
/**
|
|
4
|
+
* Extended LiteRT-LM instance with optional memory tracking and
|
|
5
|
+
* augmented loadModel that accepts a download progress callback.
|
|
6
|
+
*/
|
|
7
|
+
export type LiteRTLMInstance = Omit<LiteRTLM, "loadModel"> & {
|
|
8
|
+
memoryTracker?: MemoryTracker;
|
|
9
|
+
loadModel: (pathOrUrl: string, config?: LLMConfig, onDownloadProgress?: (progress: number) => void) => Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new LiteRT-LM inference engine instance.
|
|
13
|
+
*
|
|
14
|
+
* Optionally creates a native-backed memory tracker using
|
|
15
|
+
* `NitroModules.createNativeArrayBuffer()` (v0.35+) for efficient
|
|
16
|
+
* zero-copy memory usage tracking.
|
|
17
|
+
*
|
|
18
|
+
* @param options.enableMemoryTracking Enable automatic memory tracking (default: false)
|
|
19
|
+
* @param options.maxMemorySnapshots Maximum number of memory snapshots to store (default: 256)
|
|
20
|
+
*/
|
|
21
|
+
export declare function createLLM(options?: {
|
|
22
|
+
enableMemoryTracking?: boolean;
|
|
23
|
+
maxMemorySnapshots?: number;
|
|
24
|
+
}): LiteRTLMInstance;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLLM = createLLM;
|
|
4
|
+
const react_native_nitro_modules_1 = require("react-native-nitro-modules");
|
|
5
|
+
const memoryTracker_1 = require("./memoryTracker");
|
|
6
|
+
const modelRegistry_1 = require("./modelRegistry");
|
|
7
|
+
const inferenceRouting_1 = require("./inferenceRouting");
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new LiteRT-LM inference engine instance.
|
|
10
|
+
*
|
|
11
|
+
* Optionally creates a native-backed memory tracker using
|
|
12
|
+
* `NitroModules.createNativeArrayBuffer()` (v0.35+) for efficient
|
|
13
|
+
* zero-copy memory usage tracking.
|
|
14
|
+
*
|
|
15
|
+
* @param options.enableMemoryTracking Enable automatic memory tracking (default: false)
|
|
16
|
+
* @param options.maxMemorySnapshots Maximum number of memory snapshots to store (default: 256)
|
|
17
|
+
*/
|
|
18
|
+
function createLLM(options) {
|
|
19
|
+
const native = react_native_nitro_modules_1.NitroModules.createHybridObject("LiteRTLM");
|
|
20
|
+
const enableTracking = options?.enableMemoryTracking ?? false;
|
|
21
|
+
const tracker = enableTracking
|
|
22
|
+
? (0, memoryTracker_1.createMemoryTracker)(options?.maxMemorySnapshots ?? 256)
|
|
23
|
+
: undefined;
|
|
24
|
+
const recordMemorySnapshot = () => {
|
|
25
|
+
if (!tracker)
|
|
26
|
+
return;
|
|
27
|
+
try {
|
|
28
|
+
const usage = native.getMemoryUsage();
|
|
29
|
+
tracker.record({
|
|
30
|
+
timestamp: Date.now(),
|
|
31
|
+
nativeHeapBytes: usage.nativeHeapBytes,
|
|
32
|
+
residentBytes: usage.residentBytes,
|
|
33
|
+
availableMemoryBytes: usage.availableMemoryBytes,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Non-critical
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const augmentedLoadModel = async (pathOrUrl, config, onDownloadProgress) => {
|
|
41
|
+
console.log(`Resolving model at ${pathOrUrl}...`);
|
|
42
|
+
const modelPath = await modelRegistry_1.ModelRegistry.resolveModel(pathOrUrl, {
|
|
43
|
+
onProgress: onDownloadProgress,
|
|
44
|
+
});
|
|
45
|
+
console.log(`Model resolved to: ${modelPath}`);
|
|
46
|
+
const result = await native.loadModel(modelPath, config);
|
|
47
|
+
if (tracker) {
|
|
48
|
+
tracker.reset();
|
|
49
|
+
recordMemorySnapshot();
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
/** Single JS inference path — always calls native execute(). */
|
|
54
|
+
const runExecute = (parts, onToken) => {
|
|
55
|
+
const processedParts = parts.map((part) => {
|
|
56
|
+
if (part.path?.startsWith("file://")) {
|
|
57
|
+
return { ...part, path: part.path.substring(7) };
|
|
58
|
+
}
|
|
59
|
+
return part;
|
|
60
|
+
});
|
|
61
|
+
if (onToken) {
|
|
62
|
+
const wrapped = (token, done) => {
|
|
63
|
+
onToken(token, done);
|
|
64
|
+
if (done)
|
|
65
|
+
recordMemorySnapshot();
|
|
66
|
+
};
|
|
67
|
+
return native.execute(processedParts, wrapped);
|
|
68
|
+
}
|
|
69
|
+
return native.execute(processedParts, undefined).then((result) => {
|
|
70
|
+
recordMemorySnapshot();
|
|
71
|
+
return result;
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
return new Proxy(native, {
|
|
75
|
+
get(target, prop, receiver) {
|
|
76
|
+
if (typeof prop !== "string") {
|
|
77
|
+
return Reflect.get(target, prop, receiver);
|
|
78
|
+
}
|
|
79
|
+
if (prop === "memoryTracker") {
|
|
80
|
+
return tracker;
|
|
81
|
+
}
|
|
82
|
+
if (prop === "loadModel") {
|
|
83
|
+
return augmentedLoadModel;
|
|
84
|
+
}
|
|
85
|
+
if (prop === "execute") {
|
|
86
|
+
return (parts, onToken) => runExecute(parts, onToken);
|
|
87
|
+
}
|
|
88
|
+
if (prop === "stopGeneration") {
|
|
89
|
+
return () => target.stopGeneration();
|
|
90
|
+
}
|
|
91
|
+
if (prop === "resetConversation") {
|
|
92
|
+
return () => {
|
|
93
|
+
const result = target.resetConversation();
|
|
94
|
+
recordMemorySnapshot();
|
|
95
|
+
return result;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (prop === "sendToolResponse") {
|
|
99
|
+
return (responses, onToken) => {
|
|
100
|
+
if (onToken) {
|
|
101
|
+
const wrapped = (token, done) => {
|
|
102
|
+
onToken(token, done);
|
|
103
|
+
if (done)
|
|
104
|
+
recordMemorySnapshot();
|
|
105
|
+
};
|
|
106
|
+
return native.sendToolResponse(responses, wrapped);
|
|
107
|
+
}
|
|
108
|
+
return native.sendToolResponse(responses, undefined).then((result) => {
|
|
109
|
+
recordMemorySnapshot();
|
|
110
|
+
return result;
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if ((0, inferenceRouting_1.isLegacyInferenceMethod)(prop)) {
|
|
115
|
+
return (...args) => {
|
|
116
|
+
const route = (0, inferenceRouting_1.routeLegacyInference)(prop, args);
|
|
117
|
+
const promise = runExecute(route.parts, route.onToken);
|
|
118
|
+
return prop.endsWith("Async") ? promise.then(() => { }) : promise;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const original = target[prop];
|
|
122
|
+
if (typeof original === "function") {
|
|
123
|
+
return original.bind(target);
|
|
124
|
+
}
|
|
125
|
+
return original;
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical path/URL helpers for model files.
|
|
3
|
+
* Used by ModelRegistry, hooks, and any download/cache logic.
|
|
4
|
+
*/
|
|
5
|
+
/** Extract a filename from a URL or file path (query string stripped). */
|
|
6
|
+
export declare function extractFileName(pathOrUrl: string): string;
|
|
7
|
+
/** Resolve a cache key from a filename, local path, or HTTPS URL. */
|
|
8
|
+
export declare function resolveModelFileName(pathOrUrl: string): string;
|
package/lib/modelPath.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical path/URL helpers for model files.
|
|
4
|
+
* Used by ModelRegistry, hooks, and any download/cache logic.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.extractFileName = extractFileName;
|
|
8
|
+
exports.resolveModelFileName = resolveModelFileName;
|
|
9
|
+
/** Extract a filename from a URL or file path (query string stripped). */
|
|
10
|
+
function extractFileName(pathOrUrl) {
|
|
11
|
+
const urlWithoutQuery = pathOrUrl.split("?")[0];
|
|
12
|
+
const name = urlWithoutQuery.split("/").pop();
|
|
13
|
+
return name || "model.bin";
|
|
14
|
+
}
|
|
15
|
+
/** Resolve a cache key from a filename, local path, or HTTPS URL. */
|
|
16
|
+
function resolveModelFileName(pathOrUrl) {
|
|
17
|
+
return pathOrUrl.includes("/") ? extractFileName(pathOrUrl) : pathOrUrl;
|
|
18
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ModelFile } from "./specs/LiteRTLM.nitro";
|
|
2
|
+
export type { ModelFile } from "./specs/LiteRTLM.nitro";
|
|
3
|
+
export interface ModelDownloadOptions {
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
onProgress?: (progress: number) => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* High-performance Model Registry for react-native-litert-lm.
|
|
9
|
+
*
|
|
10
|
+
* Coordinates URL sniffing, HTTPS enforcement, atomic downloading with progress,
|
|
11
|
+
* and cache queries. Serves as the single source of truth for model storage status.
|
|
12
|
+
*/
|
|
13
|
+
export declare const ModelRegistry: {
|
|
14
|
+
/**
|
|
15
|
+
* Check if a model file is cached locally.
|
|
16
|
+
* Accepts a filename, local path, or HTTPS URL.
|
|
17
|
+
*
|
|
18
|
+
* @param pathOrUrl Filename, local path, or download URL
|
|
19
|
+
* @returns true if cached and has size > 0
|
|
20
|
+
*/
|
|
21
|
+
isCached(pathOrUrl: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Get the absolute local path of a cached model.
|
|
24
|
+
* Accepts a filename, local path, or HTTPS URL.
|
|
25
|
+
*
|
|
26
|
+
* @param pathOrUrl Filename, local path, or download URL
|
|
27
|
+
* @returns The absolute local path
|
|
28
|
+
*/
|
|
29
|
+
getFilePath(pathOrUrl: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* List all locally cached model files.
|
|
32
|
+
*
|
|
33
|
+
* @returns Array of ModelFile descriptors containing path, size, and mod time
|
|
34
|
+
*/
|
|
35
|
+
listCachedFiles(): ModelFile[];
|
|
36
|
+
/**
|
|
37
|
+
* Delete a cached model file.
|
|
38
|
+
* Accepts a filename, local path, or HTTPS URL.
|
|
39
|
+
*
|
|
40
|
+
* @param pathOrUrl Filename, local path, or download URL to delete
|
|
41
|
+
*/
|
|
42
|
+
deleteFile(pathOrUrl: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a model path or URL.
|
|
45
|
+
*
|
|
46
|
+
* Sniffs the protocol. If it is an HTTPS URL, downloads it to the native
|
|
47
|
+
* cache directory (and throttles callbacks) if not already cached. If it is a
|
|
48
|
+
* local path, returns it directly.
|
|
49
|
+
*
|
|
50
|
+
* @param pathOrUrl Local filepath or HTTPS download URL
|
|
51
|
+
* @param options Custom HTTP headers and progress callback
|
|
52
|
+
* @returns Promise resolving to the absolute local path of the model
|
|
53
|
+
*/
|
|
54
|
+
resolveModel(pathOrUrl: string, options?: ModelDownloadOptions): Promise<string>;
|
|
55
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModelRegistry = void 0;
|
|
4
|
+
const react_native_nitro_modules_1 = require("react-native-nitro-modules");
|
|
5
|
+
const modelPath_1 = require("./modelPath");
|
|
6
|
+
const nativeStore = react_native_nitro_modules_1.NitroModules.createHybridObject("ModelStore");
|
|
7
|
+
/**
|
|
8
|
+
* High-performance Model Registry for react-native-litert-lm.
|
|
9
|
+
*
|
|
10
|
+
* Coordinates URL sniffing, HTTPS enforcement, atomic downloading with progress,
|
|
11
|
+
* and cache queries. Serves as the single source of truth for model storage status.
|
|
12
|
+
*/
|
|
13
|
+
exports.ModelRegistry = {
|
|
14
|
+
/**
|
|
15
|
+
* Check if a model file is cached locally.
|
|
16
|
+
* Accepts a filename, local path, or HTTPS URL.
|
|
17
|
+
*
|
|
18
|
+
* @param pathOrUrl Filename, local path, or download URL
|
|
19
|
+
* @returns true if cached and has size > 0
|
|
20
|
+
*/
|
|
21
|
+
isCached(pathOrUrl) {
|
|
22
|
+
return nativeStore.isCached((0, modelPath_1.resolveModelFileName)(pathOrUrl));
|
|
23
|
+
},
|
|
24
|
+
/**
|
|
25
|
+
* Get the absolute local path of a cached model.
|
|
26
|
+
* Accepts a filename, local path, or HTTPS URL.
|
|
27
|
+
*
|
|
28
|
+
* @param pathOrUrl Filename, local path, or download URL
|
|
29
|
+
* @returns The absolute local path
|
|
30
|
+
*/
|
|
31
|
+
getFilePath(pathOrUrl) {
|
|
32
|
+
return nativeStore.getFilePath((0, modelPath_1.resolveModelFileName)(pathOrUrl));
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* List all locally cached model files.
|
|
36
|
+
*
|
|
37
|
+
* @returns Array of ModelFile descriptors containing path, size, and mod time
|
|
38
|
+
*/
|
|
39
|
+
listCachedFiles() {
|
|
40
|
+
return nativeStore.listCachedFiles();
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Delete a cached model file.
|
|
44
|
+
* Accepts a filename, local path, or HTTPS URL.
|
|
45
|
+
*
|
|
46
|
+
* @param pathOrUrl Filename, local path, or download URL to delete
|
|
47
|
+
*/
|
|
48
|
+
deleteFile(pathOrUrl) {
|
|
49
|
+
nativeStore.deleteFile((0, modelPath_1.resolveModelFileName)(pathOrUrl));
|
|
50
|
+
},
|
|
51
|
+
/**
|
|
52
|
+
* Resolve a model path or URL.
|
|
53
|
+
*
|
|
54
|
+
* Sniffs the protocol. If it is an HTTPS URL, downloads it to the native
|
|
55
|
+
* cache directory (and throttles callbacks) if not already cached. If it is a
|
|
56
|
+
* local path, returns it directly.
|
|
57
|
+
*
|
|
58
|
+
* @param pathOrUrl Local filepath or HTTPS download URL
|
|
59
|
+
* @param options Custom HTTP headers and progress callback
|
|
60
|
+
* @returns Promise resolving to the absolute local path of the model
|
|
61
|
+
*/
|
|
62
|
+
async resolveModel(pathOrUrl, options) {
|
|
63
|
+
const cleanPath = pathOrUrl.startsWith("file://") ? pathOrUrl.substring(7) : pathOrUrl;
|
|
64
|
+
if (cleanPath.startsWith("http://") || cleanPath.startsWith("https://")) {
|
|
65
|
+
if (cleanPath.startsWith("http://")) {
|
|
66
|
+
throw new Error("Insecure HTTP URLs are not allowed for model downloads. " +
|
|
67
|
+
"Use HTTPS instead: " +
|
|
68
|
+
cleanPath.replace("http://", "https://"));
|
|
69
|
+
}
|
|
70
|
+
const urlWithoutQuery = cleanPath.split("?")[0];
|
|
71
|
+
const fileName = urlWithoutQuery.split("/").pop();
|
|
72
|
+
if (!fileName) {
|
|
73
|
+
throw new Error(`Invalid model URL: ${cleanPath}`);
|
|
74
|
+
}
|
|
75
|
+
const headersJson = options?.headers ? JSON.stringify(options.headers) : "{}";
|
|
76
|
+
return nativeStore.downloadFile(cleanPath, fileName, headersJson, (progress) => {
|
|
77
|
+
options?.onProgress?.(progress);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return cleanPath;
|
|
81
|
+
}
|
|
82
|
+
};
|