react-native-nobodywho 5.1.0 → 6.0.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/Nobodywho.podspec +25 -20
- package/README.md +8 -8
- package/android/CMakeLists.txt +4 -15
- package/android/build.gradle +4 -5
- package/android/proguard-rules.pro +6 -0
- package/{generated/cpp → cpp/generated}/nobodywho.cpp +424 -66
- package/{generated/cpp → cpp/generated}/nobodywho.hpp +26 -2
- package/cpp/react-native-nobodywho.cpp +1 -1
- package/package.json +28 -14
- package/src/generated/index.ts +2 -0
- package/src/generated/jsi/nobodywho-ffi.ts +937 -0
- package/src/generated/jsi/nobodywho.ts +7421 -0
- package/src/index.ts +23 -0
- package/src/{chat.ts → wrapper/chat.ts} +1 -1
- package/src/wrapper/convert_value.ts +47 -0
- package/src/{cross_encoder.ts → wrapper/cross_encoder.ts} +1 -1
- package/src/wrapper/decision.ts +112 -0
- package/src/{encoder.ts → wrapper/encoder.ts} +1 -1
- package/src/{wrapper.ts → wrapper/index.ts} +11 -24
- package/src/{message.ts → wrapper/message.ts} +1 -1
- package/src/{model.ts → wrapper/model.ts} +1 -1
- package/src/{prompt.ts → wrapper/prompt.ts} +1 -1
- package/src/{sampler_presets.ts → wrapper/sampler_presets.ts} +1 -1
- package/src/{speech_to_text.ts → wrapper/speech_to_text.ts} +2 -2
- package/src/{streaming.ts → wrapper/streaming.ts} +1 -1
- package/src/{text_to_speech.ts → wrapper/text_to_speech.ts} +1 -1
- package/src/{tool.ts → wrapper/tool.ts} +2 -51
- package/src/{vad.ts → wrapper/vad.ts} +3 -3
- package/ubrn.config.yaml +26 -5
- package/cpp/nobodywho-react-native.cpp +0 -16
- package/cpp/nobodywho-react-native.h +0 -15
- package/generated/ts/nobodywho-ffi.ts +0 -414
- package/generated/ts/nobodywho.ts +0 -5472
- package/src/index.tsx +0 -41
package/Nobodywho.podspec
CHANGED
|
@@ -6,51 +6,56 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
|
6
6
|
version = package["version"]
|
|
7
7
|
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
|
8
8
|
|
|
9
|
-
framework_name = "
|
|
9
|
+
framework_name = "NobodyWho.xcframework"
|
|
10
10
|
framework_dir = File.join(__dir__, framework_name)
|
|
11
11
|
zip_name = "#{framework_name}.zip"
|
|
12
12
|
zip_path = File.join(__dir__, zip_name)
|
|
13
13
|
url = "https://github.com/nobodywho-ooo/nobodywho/releases/download/nobodywho-react-native-v#{version}/#{zip_name}"
|
|
14
14
|
|
|
15
|
-
#
|
|
16
|
-
|
|
15
|
+
# Download the xcframework unless one is already present. When installed from
|
|
16
|
+
# npm, upgrading the package replaces this directory, so an existing framework
|
|
17
|
+
# always matches the package version. For local development, place a locally
|
|
18
|
+
# built xcframework here and it will be used as-is.
|
|
19
|
+
if File.exist?(framework_dir)
|
|
20
|
+
puts "[NobodyWho] Using existing xcframework at #{framework_dir}"
|
|
21
|
+
else
|
|
22
|
+
puts "[NobodyWho] Downloading xcframework from #{url}"
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
system("curl", "-L", "-f", "-o", zip_path, url) or
|
|
25
|
+
raise "Failed to download NobodyWho xcframework.\n" \
|
|
26
|
+
"URL: #{url}\n" \
|
|
27
|
+
"Check that the release exists: https://github.com/nobodywho-ooo/nobodywho/releases/tag/nobodywho-react-native-v#{version}\n" \
|
|
28
|
+
"For local development, manually place the xcframework at: #{framework_dir}"
|
|
19
29
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"Check that the release exists: https://github.com/nobodywho-ooo/nobodywho/releases/tag/nobodywho-react-native-v#{version}\n" \
|
|
24
|
-
"For local development, manually place the xcframework at: #{framework_dir}"
|
|
30
|
+
puts "[NobodyWho] Extracting xcframework..."
|
|
31
|
+
system("unzip", "-o", "-q", zip_path, "-d", __dir__) or
|
|
32
|
+
raise "Failed to extract #{zip_name}"
|
|
25
33
|
|
|
26
|
-
|
|
27
|
-
system("unzip", "-o", "-q", zip_path, "-d", __dir__) or
|
|
28
|
-
raise "Failed to extract #{zip_name}"
|
|
34
|
+
File.delete(zip_path) if File.exist?(zip_path)
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
unless File.exist?(framework_dir)
|
|
37
|
+
raise "xcframework not found after extraction: #{framework_dir}"
|
|
38
|
+
end
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
raise "xcframework not found after extraction: #{framework_dir}"
|
|
40
|
+
puts "[NobodyWho] xcframework ready at #{framework_dir}"
|
|
34
41
|
end
|
|
35
42
|
|
|
36
|
-
puts "[NobodyWho] xcframework ready at #{framework_dir}"
|
|
37
|
-
|
|
38
43
|
Pod::Spec.new do |s|
|
|
39
44
|
s.name = "Nobodywho"
|
|
40
45
|
s.version = package["version"]
|
|
41
46
|
s.summary = package["description"]
|
|
42
47
|
s.homepage = package["homepage"]
|
|
43
48
|
s.license = package["license"]
|
|
44
|
-
s.authors = package["author"]
|
|
49
|
+
s.authors = package["author"]
|
|
45
50
|
|
|
46
51
|
s.platforms = { :ios => min_ios_version_supported }
|
|
47
52
|
s.source = { :git => "https://github.com/nobodywho-ooo/nobodywho.git", :tag => "#{s.version}" }
|
|
48
53
|
|
|
49
|
-
s.source_files = "ios/**/*.{h,m,mm,swift}", "ios/generated/**/*.{h,m,mm}", "cpp/**/*.{hpp,cpp,c,h}", "generated
|
|
54
|
+
s.source_files = "ios/**/*.{h,m,mm,swift}", "ios/generated/**/*.{h,m,mm}", "cpp/**/*.{hpp,cpp,c,h}", "cpp/generated/**/*.{hpp,cpp,c,h}"
|
|
50
55
|
s.vendored_frameworks = framework_name
|
|
51
56
|
s.libraries = 'c++'
|
|
52
57
|
s.frameworks = 'Accelerate'
|
|
53
|
-
s.dependency "uniffi-bindgen-react-native", "0.
|
|
58
|
+
s.dependency "uniffi-bindgen-react-native", "0.31.0-6"
|
|
54
59
|
|
|
55
60
|
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
56
61
|
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ This library uses the **GGUF format** — a binary format optimized for fast loa
|
|
|
57
57
|
|
|
58
58
|
**Compatibility notes:**
|
|
59
59
|
- Most GGUF models will work, but some may fail due to formatting issues.
|
|
60
|
-
- For mobile devices, models under 1 GB
|
|
60
|
+
- For mobile devices, models under 1 GB run smoothly. As a general rule, the device should have at least twice the available RAM as the model file size. Note that available RAM differs from total RAM — iOS typically reserves around 1–2 GB for the kernel and system processes, while Android overhead varies by manufacturer: roughly 2 GB on stock Android (e.g. Pixel devices), and between 2–4 GB on Samsung, Xiaomi, and Oppo devices due to additional services.
|
|
61
61
|
|
|
62
62
|
**Minimum recommended specs:**
|
|
63
63
|
|
|
@@ -101,7 +101,7 @@ for await (const token of chat.ask("Is water wet?")) {
|
|
|
101
101
|
const response = await chat.ask("Is water wet?").completed();
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
See the [Chat documentation](https://docs.nobodywho.ooo/
|
|
104
|
+
See the [Chat documentation](https://docs.nobodywho.ooo/js/chat/) for details.
|
|
105
105
|
|
|
106
106
|
## Tool Calling
|
|
107
107
|
|
|
@@ -131,7 +131,7 @@ const chat = await Chat.fromPath({
|
|
|
131
131
|
const response = await chat.ask("What's the weather in Paris?").completed();
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
See the [Tool Calling documentation](https://docs.nobodywho.ooo/
|
|
134
|
+
See the [Tool Calling documentation](https://docs.nobodywho.ooo/js/tool-calling/) for more.
|
|
135
135
|
|
|
136
136
|
---
|
|
137
137
|
|
|
@@ -148,7 +148,7 @@ const chat = await Chat.fromPath({
|
|
|
148
148
|
});
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
See the [Sampling documentation](https://docs.nobodywho.ooo/
|
|
151
|
+
See the [Sampling documentation](https://docs.nobodywho.ooo/js/sampling/) for more.
|
|
152
152
|
|
|
153
153
|
---
|
|
154
154
|
|
|
@@ -184,7 +184,7 @@ const response = await chat
|
|
|
184
184
|
|
|
185
185
|
You can pass multiple images/audio files and interleave text between them. If the model performs poorly, try reordering the text, audio and image parts — this can make a noticeable difference. If images consume too much context, increase `contextSize` or preprocess images with compression.
|
|
186
186
|
|
|
187
|
-
See the [Vision & Hearing documentation](https://docs.nobodywho.ooo/
|
|
187
|
+
See the [Vision & Hearing documentation](https://docs.nobodywho.ooo/js/vision/) for model recommendations and advanced tips.
|
|
188
188
|
|
|
189
189
|
---
|
|
190
190
|
|
|
@@ -205,7 +205,7 @@ console.log(text);
|
|
|
205
205
|
|
|
206
206
|
You can also transcribe raw PCM buffers with `transcribePcm`, and stream the transcription token by token.
|
|
207
207
|
|
|
208
|
-
See the [Speech to Text documentation](https://docs.nobodywho.ooo/
|
|
208
|
+
See the [Speech to Text documentation](https://docs.nobodywho.ooo/js/speech-to-text/) for more.
|
|
209
209
|
|
|
210
210
|
---
|
|
211
211
|
|
|
@@ -228,7 +228,7 @@ const wav = await tts.synthesize("Hello from NobodyWho!");
|
|
|
228
228
|
|
|
229
229
|
NobodyWho supports the Kokoro, Pocket TTS, and Supertonic speech synthesis architectures.
|
|
230
230
|
|
|
231
|
-
See the [Text to Speech documentation](https://docs.nobodywho.ooo/
|
|
231
|
+
See the [Text to Speech documentation](https://docs.nobodywho.ooo/js/text-to-speech/) for more.
|
|
232
232
|
|
|
233
233
|
---
|
|
234
234
|
|
|
@@ -257,4 +257,4 @@ const speech = vad.finish(); // buffered speech, ready to pass to SpeechToText
|
|
|
257
257
|
|
|
258
258
|
You can also segment speech out of an existing recording with `segment()`.
|
|
259
259
|
|
|
260
|
-
See the [Voice Activity Detection documentation](https://docs.nobodywho.ooo/
|
|
260
|
+
See the [Voice Activity Detection documentation](https://docs.nobodywho.ooo/js/voice-activity-detection/) for more.
|
package/android/CMakeLists.txt
CHANGED
|
@@ -18,14 +18,14 @@ get_filename_component(UNIFFI_BINDGEN_PATH "${UNIFFI_BINDGEN_PATH}" DIRECTORY)
|
|
|
18
18
|
# Specifies a path to native header files.
|
|
19
19
|
include_directories(
|
|
20
20
|
../cpp
|
|
21
|
-
../generated
|
|
21
|
+
../cpp/generated
|
|
22
22
|
|
|
23
23
|
${UNIFFI_BINDGEN_PATH}/cpp/includes
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
add_library(react-native-nobodywho SHARED
|
|
27
27
|
../cpp/react-native-nobodywho.cpp
|
|
28
|
-
../generated/
|
|
28
|
+
../cpp/generated/nobodywho.cpp
|
|
29
29
|
cpp-adapter.cpp
|
|
30
30
|
)
|
|
31
31
|
|
|
@@ -40,24 +40,13 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
|
|
40
40
|
# Set linker flags for 16KB page size alignment (required for Android 15+)
|
|
41
41
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
|
|
42
42
|
|
|
43
|
-
# NOBODYWHO_NATIVE_LIBS_DIR is passed from build.gradle via cmake arguments.
|
|
44
|
-
# Fall back to src/main/jniLibs for local development where libs are placed manually.
|
|
45
|
-
# The .so files are pre-built shared libraries — fully linked at CI time — so the
|
|
46
|
-
# consumer's NDK version does not affect the Rust code.
|
|
47
|
-
if(NOT NOBODYWHO_NATIVE_LIBS_DIR)
|
|
48
|
-
set(NOBODYWHO_NATIVE_LIBS_DIR "${CMAKE_SOURCE_DIR}/src/main/jniLibs")
|
|
49
|
-
endif()
|
|
50
|
-
|
|
51
43
|
cmake_path(
|
|
52
44
|
SET MY_RUST_LIB
|
|
53
|
-
${
|
|
45
|
+
${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libnobodywho_uniffi.so
|
|
54
46
|
NORMALIZE
|
|
55
47
|
)
|
|
56
48
|
add_library(my_rust_lib SHARED IMPORTED)
|
|
57
|
-
set_target_properties(my_rust_lib PROPERTIES
|
|
58
|
-
IMPORTED_LOCATION ${MY_RUST_LIB}
|
|
59
|
-
IMPORTED_NO_SONAME TRUE
|
|
60
|
-
)
|
|
49
|
+
set_target_properties(my_rust_lib PROPERTIES IMPORTED_LOCATION ${MY_RUST_LIB} IMPORTED_NO_SONAME ON)
|
|
61
50
|
|
|
62
51
|
# Add ReactAndroid libraries, being careful to account for different versions.
|
|
63
52
|
find_package(ReactAndroid REQUIRED CONFIG)
|
package/android/build.gradle
CHANGED
|
@@ -63,7 +63,9 @@ def nobodywhoVersion = packageJson.version
|
|
|
63
63
|
// Directory for downloaded native shared libraries.
|
|
64
64
|
// These .so files are fully linked at CI time with a known-good NDK, eliminating
|
|
65
65
|
// NDK version coupling for consumers.
|
|
66
|
-
|
|
66
|
+
// This is AGP's default jniLibs directory, and the path the ubrn-generated
|
|
67
|
+
// CMakeLists.txt links against, so no extra configuration is needed.
|
|
68
|
+
def nativeLibsDir = file("src/main/jniLibs")
|
|
67
69
|
|
|
68
70
|
// Download native shared libraries from GitHub Releases if not already present.
|
|
69
71
|
task resolveNativeLibraries {
|
|
@@ -161,8 +163,7 @@ android {
|
|
|
161
163
|
}
|
|
162
164
|
externalNativeBuild {
|
|
163
165
|
cmake {
|
|
164
|
-
arguments '-DANDROID_STL=c++_shared'
|
|
165
|
-
"-DNOBODYWHO_NATIVE_LIBS_DIR=${nativeLibsDir.absolutePath}"
|
|
166
|
+
arguments '-DANDROID_STL=c++_shared'
|
|
166
167
|
abiFilters (*reactNativeArchitectures())
|
|
167
168
|
}
|
|
168
169
|
}
|
|
@@ -198,8 +199,6 @@ android {
|
|
|
198
199
|
|
|
199
200
|
sourceSets {
|
|
200
201
|
main {
|
|
201
|
-
// Include downloaded .so files so they get packaged into the APK
|
|
202
|
-
jniLibs.srcDirs += [nativeLibsDir]
|
|
203
202
|
if (isNewArchitectureEnabled()) {
|
|
204
203
|
java.srcDirs += [
|
|
205
204
|
"generated/java",
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Keep the native module, which is looked up by name from C++/JSI,
|
|
2
|
+
# in case the app enables R8.
|
|
3
|
+
#
|
|
4
|
+
# This file should be auto-generated by uniffi-bindgen-react-native
|
|
5
|
+
# in the future, see https://github.com/jhugman/uniffi-bindgen-react-native/issues/502
|
|
6
|
+
-keep class ooo.nobodywho.** { *; }
|