cactus-react-native 1.2.1 → 1.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.
Files changed (238) hide show
  1. package/README.md +765 -33
  2. package/android/CMakeLists.txt +4 -3
  3. package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusFileSystem.kt +20 -1
  4. package/android/src/main/jniLibs/arm64-v8a/libcactus.a +0 -0
  5. package/android/src/main/jniLibs/arm64-v8a/libcactus_util.a +0 -0
  6. package/cpp/HybridCactus.cpp +231 -19
  7. package/cpp/HybridCactus.hpp +25 -3
  8. package/cpp/HybridCactusIndex.cpp +325 -0
  9. package/cpp/HybridCactusIndex.hpp +43 -0
  10. package/cpp/HybridCactusUtil.cpp +3 -3
  11. package/cpp/HybridCactusUtil.hpp +2 -1
  12. package/cpp/cactus_ffi.h +107 -2
  13. package/cpp/cactus_util.h +1 -1
  14. package/ios/HybridCactusFileSystem.swift +23 -2
  15. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus.h +2 -0
  16. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_ffi.h +107 -2
  17. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_telemetry.h +656 -0
  18. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/{ffi_utils.h → cactus_utils.h} +145 -18
  19. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/engine.h +135 -7
  20. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/gemma_tools.h +549 -0
  21. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/graph.h +193 -26
  22. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/kernel.h +54 -195
  23. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/kernel_utils.h +399 -140
  24. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Info.plist +0 -0
  25. package/ios/cactus.xcframework/ios-arm64/cactus.framework/cactus +0 -0
  26. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus.h +2 -0
  27. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_ffi.h +107 -2
  28. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_telemetry.h +656 -0
  29. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/{ffi_utils.h → cactus_utils.h} +145 -18
  30. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/engine.h +135 -7
  31. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/gemma_tools.h +549 -0
  32. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/graph.h +193 -26
  33. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/kernel.h +54 -195
  34. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/kernel_utils.h +399 -140
  35. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Info.plist +0 -0
  36. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/_CodeSignature/CodeResources +1 -1
  37. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/cactus +0 -0
  38. package/ios/cactus_util.xcframework/Info.plist +4 -4
  39. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/cactus_util.h +1 -1
  40. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/database.h +27 -0
  41. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Info.plist +0 -0
  42. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/cactus_util +0 -0
  43. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/cactus_util.h +1 -1
  44. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/database.h +27 -0
  45. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Info.plist +0 -0
  46. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/_CodeSignature/CodeResources +3 -3
  47. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/cactus_util +0 -0
  48. package/lib/module/api/Database.js +12 -95
  49. package/lib/module/api/Database.js.map +1 -1
  50. package/lib/module/classes/CactusIndex.js +45 -0
  51. package/lib/module/classes/CactusIndex.js.map +1 -0
  52. package/lib/module/classes/CactusLM.js +65 -17
  53. package/lib/module/classes/CactusLM.js.map +1 -1
  54. package/lib/module/classes/CactusSTT.js +104 -17
  55. package/lib/module/classes/CactusSTT.js.map +1 -1
  56. package/lib/module/config/CactusConfig.js +2 -0
  57. package/lib/module/config/CactusConfig.js.map +1 -1
  58. package/lib/module/constants/packageVersion.js +1 -1
  59. package/lib/module/hooks/useCactusIndex.js +175 -0
  60. package/lib/module/hooks/useCactusIndex.js.map +1 -0
  61. package/lib/module/hooks/useCactusLM.js +68 -7
  62. package/lib/module/hooks/useCactusLM.js.map +1 -1
  63. package/lib/module/hooks/useCactusSTT.js +102 -6
  64. package/lib/module/hooks/useCactusSTT.js.map +1 -1
  65. package/lib/module/index.js +2 -0
  66. package/lib/module/index.js.map +1 -1
  67. package/lib/module/models.js +336 -0
  68. package/lib/module/models.js.map +1 -0
  69. package/lib/module/native/Cactus.js +61 -13
  70. package/lib/module/native/Cactus.js.map +1 -1
  71. package/lib/module/native/CactusFileSystem.js +3 -0
  72. package/lib/module/native/CactusFileSystem.js.map +1 -1
  73. package/lib/module/native/CactusIndex.js +32 -0
  74. package/lib/module/native/CactusIndex.js.map +1 -0
  75. package/lib/module/native/CactusUtil.js +16 -3
  76. package/lib/module/native/CactusUtil.js.map +1 -1
  77. package/lib/module/native/index.js +1 -0
  78. package/lib/module/native/index.js.map +1 -1
  79. package/lib/module/specs/CactusIndex.nitro.js +4 -0
  80. package/lib/module/specs/CactusIndex.nitro.js.map +1 -0
  81. package/lib/module/telemetry/Telemetry.js +3 -1
  82. package/lib/module/telemetry/Telemetry.js.map +1 -1
  83. package/lib/module/types/CactusIndex.js +2 -0
  84. package/lib/module/types/{CactusModel.js.map → CactusIndex.js.map} +1 -1
  85. package/lib/module/types/CactusLM.js +2 -0
  86. package/lib/module/types/CactusSTT.js +2 -0
  87. package/lib/module/types/common.js +2 -0
  88. package/lib/module/types/{CactusSTTModel.js.map → common.js.map} +1 -1
  89. package/lib/typescript/src/api/Database.d.ts +4 -7
  90. package/lib/typescript/src/api/Database.d.ts.map +1 -1
  91. package/lib/typescript/src/classes/CactusIndex.d.ts +15 -0
  92. package/lib/typescript/src/classes/CactusIndex.d.ts.map +1 -0
  93. package/lib/typescript/src/classes/CactusLM.d.ts +12 -5
  94. package/lib/typescript/src/classes/CactusLM.d.ts.map +1 -1
  95. package/lib/typescript/src/classes/CactusSTT.d.ts +15 -5
  96. package/lib/typescript/src/classes/CactusSTT.d.ts.map +1 -1
  97. package/lib/typescript/src/config/CactusConfig.d.ts +1 -0
  98. package/lib/typescript/src/config/CactusConfig.d.ts.map +1 -1
  99. package/lib/typescript/src/constants/packageVersion.d.ts +1 -1
  100. package/lib/typescript/src/hooks/useCactusIndex.d.ts +14 -0
  101. package/lib/typescript/src/hooks/useCactusIndex.d.ts.map +1 -0
  102. package/lib/typescript/src/hooks/useCactusLM.d.ts +6 -4
  103. package/lib/typescript/src/hooks/useCactusLM.d.ts.map +1 -1
  104. package/lib/typescript/src/hooks/useCactusSTT.d.ts +13 -5
  105. package/lib/typescript/src/hooks/useCactusSTT.d.ts.map +1 -1
  106. package/lib/typescript/src/index.d.ts +6 -4
  107. package/lib/typescript/src/index.d.ts.map +1 -1
  108. package/lib/typescript/src/models.d.ts +6 -0
  109. package/lib/typescript/src/models.d.ts.map +1 -0
  110. package/lib/typescript/src/native/Cactus.d.ts +10 -3
  111. package/lib/typescript/src/native/Cactus.d.ts.map +1 -1
  112. package/lib/typescript/src/native/CactusFileSystem.d.ts +1 -0
  113. package/lib/typescript/src/native/CactusFileSystem.d.ts.map +1 -1
  114. package/lib/typescript/src/native/CactusIndex.d.ts +12 -0
  115. package/lib/typescript/src/native/CactusIndex.d.ts.map +1 -0
  116. package/lib/typescript/src/native/CactusUtil.d.ts.map +1 -1
  117. package/lib/typescript/src/native/index.d.ts +1 -0
  118. package/lib/typescript/src/native/index.d.ts.map +1 -1
  119. package/lib/typescript/src/specs/Cactus.nitro.d.ts +9 -2
  120. package/lib/typescript/src/specs/Cactus.nitro.d.ts.map +1 -1
  121. package/lib/typescript/src/specs/CactusFileSystem.nitro.d.ts +1 -0
  122. package/lib/typescript/src/specs/CactusFileSystem.nitro.d.ts.map +1 -1
  123. package/lib/typescript/src/specs/CactusIndex.nitro.d.ts +24 -0
  124. package/lib/typescript/src/specs/CactusIndex.nitro.d.ts.map +1 -0
  125. package/lib/typescript/src/specs/CactusUtil.nitro.d.ts +1 -1
  126. package/lib/typescript/src/specs/CactusUtil.nitro.d.ts.map +1 -1
  127. package/lib/typescript/src/types/CactusIndex.d.ts +34 -0
  128. package/lib/typescript/src/types/CactusIndex.d.ts.map +1 -0
  129. package/lib/typescript/src/types/CactusLM.d.ts +19 -0
  130. package/lib/typescript/src/types/CactusLM.d.ts.map +1 -1
  131. package/lib/typescript/src/types/CactusSTT.d.ts +21 -1
  132. package/lib/typescript/src/types/CactusSTT.d.ts.map +1 -1
  133. package/lib/typescript/src/types/common.d.ts +28 -0
  134. package/lib/typescript/src/types/common.d.ts.map +1 -0
  135. package/nitro.json +3 -0
  136. package/nitrogen/generated/android/c++/JDeviceInfo.hpp +1 -1
  137. package/nitrogen/generated/android/c++/JFunc_void_double.hpp +1 -1
  138. package/nitrogen/generated/android/c++/JHybridCactusCryptoSpec.cpp +1 -1
  139. package/nitrogen/generated/android/c++/JHybridCactusCryptoSpec.hpp +1 -1
  140. package/nitrogen/generated/android/c++/JHybridCactusDeviceInfoSpec.cpp +1 -1
  141. package/nitrogen/generated/android/c++/JHybridCactusDeviceInfoSpec.hpp +1 -1
  142. package/nitrogen/generated/android/c++/JHybridCactusFileSystemSpec.cpp +17 -1
  143. package/nitrogen/generated/android/c++/JHybridCactusFileSystemSpec.hpp +2 -1
  144. package/nitrogen/generated/android/c++/JHybridCactusImageSpec.cpp +1 -1
  145. package/nitrogen/generated/android/c++/JHybridCactusImageSpec.hpp +1 -1
  146. package/nitrogen/generated/android/cactus+autolinking.cmake +2 -1
  147. package/nitrogen/generated/android/cactus+autolinking.gradle +1 -1
  148. package/nitrogen/generated/android/cactusOnLoad.cpp +11 -1
  149. package/nitrogen/generated/android/cactusOnLoad.hpp +1 -1
  150. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/DeviceInfo.kt +1 -1
  151. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/Func_void_double.kt +1 -1
  152. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusCryptoSpec.kt +1 -1
  153. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusDeviceInfoSpec.kt +1 -1
  154. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusFileSystemSpec.kt +5 -1
  155. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusImageSpec.kt +1 -1
  156. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/cactusOnLoad.kt +1 -1
  157. package/nitrogen/generated/ios/Cactus+autolinking.rb +1 -1
  158. package/nitrogen/generated/ios/Cactus-Swift-Cxx-Bridge.cpp +1 -1
  159. package/nitrogen/generated/ios/Cactus-Swift-Cxx-Bridge.hpp +1 -1
  160. package/nitrogen/generated/ios/Cactus-Swift-Cxx-Umbrella.hpp +1 -1
  161. package/nitrogen/generated/ios/CactusAutolinking.mm +11 -1
  162. package/nitrogen/generated/ios/CactusAutolinking.swift +1 -1
  163. package/nitrogen/generated/ios/c++/HybridCactusCryptoSpecSwift.cpp +1 -1
  164. package/nitrogen/generated/ios/c++/HybridCactusCryptoSpecSwift.hpp +1 -1
  165. package/nitrogen/generated/ios/c++/HybridCactusDeviceInfoSpecSwift.cpp +1 -1
  166. package/nitrogen/generated/ios/c++/HybridCactusDeviceInfoSpecSwift.hpp +1 -1
  167. package/nitrogen/generated/ios/c++/HybridCactusFileSystemSpecSwift.cpp +1 -1
  168. package/nitrogen/generated/ios/c++/HybridCactusFileSystemSpecSwift.hpp +9 -1
  169. package/nitrogen/generated/ios/c++/HybridCactusImageSpecSwift.cpp +1 -1
  170. package/nitrogen/generated/ios/c++/HybridCactusImageSpecSwift.hpp +1 -1
  171. package/nitrogen/generated/ios/swift/DeviceInfo.swift +1 -1
  172. package/nitrogen/generated/ios/swift/Func_void.swift +1 -1
  173. package/nitrogen/generated/ios/swift/Func_void_DeviceInfo.swift +1 -1
  174. package/nitrogen/generated/ios/swift/Func_void_bool.swift +1 -1
  175. package/nitrogen/generated/ios/swift/Func_void_double.swift +1 -1
  176. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +1 -1
  177. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +1 -1
  178. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +1 -1
  179. package/nitrogen/generated/ios/swift/HybridCactusCryptoSpec.swift +1 -1
  180. package/nitrogen/generated/ios/swift/HybridCactusCryptoSpec_cxx.swift +1 -1
  181. package/nitrogen/generated/ios/swift/HybridCactusDeviceInfoSpec.swift +1 -1
  182. package/nitrogen/generated/ios/swift/HybridCactusDeviceInfoSpec_cxx.swift +1 -1
  183. package/nitrogen/generated/ios/swift/HybridCactusFileSystemSpec.swift +2 -1
  184. package/nitrogen/generated/ios/swift/HybridCactusFileSystemSpec_cxx.swift +20 -1
  185. package/nitrogen/generated/ios/swift/HybridCactusImageSpec.swift +1 -1
  186. package/nitrogen/generated/ios/swift/HybridCactusImageSpec_cxx.swift +1 -1
  187. package/nitrogen/generated/shared/c++/CactusIndexGetResult.hpp +84 -0
  188. package/nitrogen/generated/shared/c++/CactusIndexQueryResult.hpp +79 -0
  189. package/nitrogen/generated/shared/c++/DeviceInfo.hpp +1 -1
  190. package/nitrogen/generated/shared/c++/HybridCactusCryptoSpec.cpp +1 -1
  191. package/nitrogen/generated/shared/c++/HybridCactusCryptoSpec.hpp +1 -1
  192. package/nitrogen/generated/shared/c++/HybridCactusDeviceInfoSpec.cpp +1 -1
  193. package/nitrogen/generated/shared/c++/HybridCactusDeviceInfoSpec.hpp +1 -1
  194. package/nitrogen/generated/shared/c++/HybridCactusFileSystemSpec.cpp +2 -1
  195. package/nitrogen/generated/shared/c++/HybridCactusFileSystemSpec.hpp +2 -1
  196. package/nitrogen/generated/shared/c++/HybridCactusImageSpec.cpp +1 -1
  197. package/nitrogen/generated/shared/c++/HybridCactusImageSpec.hpp +1 -1
  198. package/nitrogen/generated/shared/c++/HybridCactusIndexSpec.cpp +27 -0
  199. package/nitrogen/generated/shared/c++/HybridCactusIndexSpec.hpp +76 -0
  200. package/nitrogen/generated/shared/c++/HybridCactusSpec.cpp +8 -1
  201. package/nitrogen/generated/shared/c++/HybridCactusSpec.hpp +11 -3
  202. package/nitrogen/generated/shared/c++/HybridCactusUtilSpec.cpp +1 -1
  203. package/nitrogen/generated/shared/c++/HybridCactusUtilSpec.hpp +2 -2
  204. package/package.json +2 -2
  205. package/src/api/Database.ts +14 -135
  206. package/src/classes/CactusIndex.ts +58 -0
  207. package/src/classes/CactusLM.ts +87 -19
  208. package/src/classes/CactusSTT.ts +134 -20
  209. package/src/config/CactusConfig.ts +3 -0
  210. package/src/constants/packageVersion.ts +1 -1
  211. package/src/hooks/useCactusIndex.ts +195 -0
  212. package/src/hooks/useCactusLM.ts +88 -8
  213. package/src/hooks/useCactusSTT.ts +119 -7
  214. package/src/index.tsx +22 -2
  215. package/src/models.ts +344 -0
  216. package/src/native/Cactus.ts +95 -13
  217. package/src/native/CactusFileSystem.ts +4 -0
  218. package/src/native/CactusIndex.ts +54 -0
  219. package/src/native/CactusUtil.ts +19 -3
  220. package/src/native/index.ts +1 -0
  221. package/src/specs/Cactus.nitro.ts +18 -2
  222. package/src/specs/CactusFileSystem.nitro.ts +2 -0
  223. package/src/specs/CactusIndex.nitro.ts +31 -0
  224. package/src/specs/CactusUtil.nitro.ts +1 -1
  225. package/src/telemetry/Telemetry.ts +1 -1
  226. package/src/types/CactusIndex.ts +40 -0
  227. package/src/types/CactusLM.ts +24 -0
  228. package/src/types/CactusSTT.ts +27 -1
  229. package/src/types/common.ts +28 -0
  230. package/android/src/main/jniLibs/arm64-v8a/libcactus_util.so +0 -0
  231. package/lib/module/types/CactusModel.js +0 -2
  232. package/lib/module/types/CactusSTTModel.js +0 -2
  233. package/lib/typescript/src/types/CactusModel.d.ts +0 -13
  234. package/lib/typescript/src/types/CactusModel.d.ts.map +0 -1
  235. package/lib/typescript/src/types/CactusSTTModel.d.ts +0 -8
  236. package/lib/typescript/src/types/CactusSTTModel.d.ts.map +0 -1
  237. package/src/types/CactusModel.ts +0 -15
  238. package/src/types/CactusSTTModel.ts +0 -10
@@ -6,10 +6,11 @@ set(CMAKE_VERBOSE_MAKEFILE ON)
6
6
  set(CMAKE_CXX_STANDARD 20)
7
7
 
8
8
  # Define C++ library and add all sources
9
- add_library(${PACKAGE_NAME} SHARED
9
+ add_library(${PACKAGE_NAME} SHARED
10
10
  src/main/cpp/cpp-adapter.cpp
11
11
  ../cpp/HybridCactus.cpp
12
12
  ../cpp/HybridCactusUtil.cpp
13
+ ../cpp/HybridCactusIndex.cpp
13
14
  )
14
15
 
15
16
  add_library(libcactus STATIC IMPORTED)
@@ -17,9 +18,9 @@ set_target_properties(libcactus PROPERTIES
17
18
  IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/src/main/jniLibs/${ANDROID_ABI}/libcactus.a"
18
19
  )
19
20
 
20
- add_library(libcactus_util SHARED IMPORTED)
21
+ add_library(libcactus_util STATIC IMPORTED)
21
22
  set_target_properties(libcactus_util PROPERTIES
22
- IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/src/main/jniLibs/${ANDROID_ABI}/libcactus_util.so"
23
+ IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/src/main/jniLibs/${ANDROID_ABI}/libcactus_util.a"
23
24
  )
24
25
 
25
26
  # Add Nitrogen specs :)
@@ -209,6 +209,8 @@ class HybridCactusFileSystem : HybridCactusFileSystemSpec() {
209
209
  modelFile.deleteRecursively()
210
210
  }
211
211
 
212
+ override fun getIndexPath(name: String): Promise<String> = Promise.async { indexFile(name).absolutePath }
213
+
212
214
  private fun cactusFile(): File {
213
215
  val cactusDir = File(context.filesDir, "cactus")
214
216
 
@@ -221,6 +223,23 @@ class HybridCactusFileSystem : HybridCactusFileSystemSpec() {
221
223
 
222
224
  private fun modelFile(model: String): File {
223
225
  val cactusDir = cactusFile()
224
- return File(cactusDir, "models/$model")
226
+ val modelsDir = File(cactusDir, "models")
227
+
228
+ if (!modelsDir.exists()) {
229
+ modelsDir.mkdirs()
230
+ }
231
+
232
+ return File(modelsDir, model)
233
+ }
234
+
235
+ private fun indexFile(name: String): File {
236
+ val cactusDir = cactusFile()
237
+ val finalDir = File(cactusDir, "indexes/$name")
238
+
239
+ if (!finalDir.exists()) {
240
+ finalDir.mkdirs()
241
+ }
242
+
243
+ return finalDir
225
244
  }
226
245
  }
@@ -1,6 +1,7 @@
1
1
  #include "HybridCactus.hpp"
2
2
 
3
3
  namespace margelo::nitro::cactus {
4
+
4
5
  HybridCactus::HybridCactus() : HybridObject(TAG) {}
5
6
 
6
7
  std::shared_ptr<Promise<void>>
@@ -19,7 +20,8 @@ HybridCactus::init(const std::string &modelPath, double contextSize,
19
20
  corpusDir ? corpusDir->c_str() : nullptr);
20
21
 
21
22
  if (!model) {
22
- throw std::runtime_error("Failed to initialize Cactus model");
23
+ throw std::runtime_error("Cactus init failed: " +
24
+ std::string(cactus_get_last_error()));
23
25
  }
24
26
 
25
27
  this->_model = model;
@@ -65,7 +67,8 @@ std::shared_ptr<Promise<std::string>> HybridCactus::complete(
65
67
  cactusTokenCallback, &callbackCtx);
66
68
 
67
69
  if (result < 0) {
68
- throw std::runtime_error("Cactus completion failed");
70
+ throw std::runtime_error("Cactus complete failed: " +
71
+ std::string(cactus_get_last_error()));
69
72
  }
70
73
 
71
74
  // Remove null terminator
@@ -75,12 +78,78 @@ std::shared_ptr<Promise<std::string>> HybridCactus::complete(
75
78
  });
76
79
  }
77
80
 
81
+ std::shared_ptr<Promise<std::vector<double>>>
82
+ HybridCactus::tokenize(const std::string &text) {
83
+ return Promise<std::vector<double>>::async([this,
84
+ text]() -> std::vector<double> {
85
+ std::lock_guard<std::mutex> lock(this->_modelMutex);
86
+
87
+ if (!this->_model) {
88
+ throw std::runtime_error("Cactus model is not initialized");
89
+ }
90
+
91
+ std::vector<uint32_t> tokenBuffer(text.length() * 2 + 16);
92
+ size_t outTokenLen = 0;
93
+
94
+ int result = cactus_tokenize(this->_model, text.c_str(), tokenBuffer.data(),
95
+ tokenBuffer.size(), &outTokenLen);
96
+
97
+ if (result < 0) {
98
+ throw std::runtime_error("Cactus tokenize failed: " +
99
+ std::string(cactus_get_last_error()));
100
+ }
101
+
102
+ tokenBuffer.resize(outTokenLen);
103
+
104
+ return std::vector<double>(tokenBuffer.begin(), tokenBuffer.end());
105
+ });
106
+ }
107
+
108
+ std::shared_ptr<Promise<std::string>>
109
+ HybridCactus::scoreWindow(const std::vector<double> &tokens, double start,
110
+ double end, double context) {
111
+ return Promise<std::string>::async(
112
+ [this, tokens, start, end, context]() -> std::string {
113
+ std::lock_guard<std::mutex> lock(this->_modelMutex);
114
+
115
+ if (!this->_model) {
116
+ throw std::runtime_error("Cactus model is not initialized");
117
+ }
118
+
119
+ std::vector<uint32_t> tokenBuffer;
120
+ tokenBuffer.reserve(tokens.size());
121
+ for (double d : tokens) {
122
+ tokenBuffer.emplace_back(static_cast<uint32_t>(d));
123
+ }
124
+
125
+ std::string responseBuffer;
126
+ responseBuffer.resize(1024);
127
+
128
+ int result = cactus_score_window(
129
+ this->_model, tokenBuffer.data(), tokenBuffer.size(),
130
+ static_cast<size_t>(start), static_cast<size_t>(end),
131
+ static_cast<size_t>(context), responseBuffer.data(),
132
+ responseBuffer.size());
133
+
134
+ if (result < 0) {
135
+ throw std::runtime_error("Cactus score window failed: " +
136
+ std::string(cactus_get_last_error()));
137
+ }
138
+
139
+ // Remove null terminator
140
+ responseBuffer.resize(strlen(responseBuffer.c_str()));
141
+
142
+ return responseBuffer;
143
+ });
144
+ }
145
+
78
146
  std::shared_ptr<Promise<std::string>> HybridCactus::transcribe(
79
- const std::string &audioFilePath, const std::string &prompt,
80
- double responseBufferSize, const std::optional<std::string> &optionsJson,
147
+ const std::variant<std::vector<double>, std::string> &audio,
148
+ const std::string &prompt, double responseBufferSize,
149
+ const std::optional<std::string> &optionsJson,
81
150
  const std::optional<std::function<void(const std::string & /* token */,
82
151
  double /* tokenId */)>> &callback) {
83
- return Promise<std::string>::async([this, audioFilePath, prompt, optionsJson,
152
+ return Promise<std::string>::async([this, audio, prompt, optionsJson,
84
153
  callback,
85
154
  responseBufferSize]() -> std::string {
86
155
  std::lock_guard<std::mutex> lock(this->_modelMutex);
@@ -105,14 +174,34 @@ std::shared_ptr<Promise<std::string>> HybridCactus::transcribe(
105
174
  std::string responseBuffer;
106
175
  responseBuffer.resize(responseBufferSize);
107
176
 
108
- int result =
109
- cactus_transcribe(this->_model, audioFilePath.c_str(), prompt.c_str(),
110
- responseBuffer.data(), responseBufferSize,
111
- optionsJson ? optionsJson->c_str() : nullptr,
112
- cactusTokenCallback, &callbackCtx);
177
+ int result;
178
+ if (std::holds_alternative<std::string>(audio)) {
179
+ result = cactus_transcribe(
180
+ this->_model, std::get<std::string>(audio).c_str(), prompt.c_str(),
181
+ responseBuffer.data(), responseBufferSize,
182
+ optionsJson ? optionsJson->c_str() : nullptr, cactusTokenCallback,
183
+ &callbackCtx, nullptr, 0);
184
+ } else {
185
+ const auto &audioDoubles = std::get<std::vector<double>>(audio);
186
+
187
+ std::vector<uint8_t> audioBytes;
188
+ audioBytes.reserve(audioDoubles.size());
189
+
190
+ for (double d : audioDoubles) {
191
+ d = std::clamp(d, 0.0, 255.0);
192
+ audioBytes.emplace_back(static_cast<uint8_t>(d));
193
+ }
194
+
195
+ result = cactus_transcribe(this->_model, nullptr, prompt.c_str(),
196
+ responseBuffer.data(), responseBufferSize,
197
+ optionsJson ? optionsJson->c_str() : nullptr,
198
+ cactusTokenCallback, &callbackCtx,
199
+ audioBytes.data(), audioBytes.size());
200
+ }
113
201
 
114
202
  if (result < 0) {
115
- throw std::runtime_error("Cactus transcription failed");
203
+ throw std::runtime_error("Cactus transcribe failed: " +
204
+ std::string(cactus_get_last_error()));
116
205
  }
117
206
 
118
207
  // Remove null terminator
@@ -123,9 +212,10 @@ std::shared_ptr<Promise<std::string>> HybridCactus::transcribe(
123
212
  }
124
213
 
125
214
  std::shared_ptr<Promise<std::vector<double>>>
126
- HybridCactus::embed(const std::string &text, double embeddingBufferSize) {
215
+ HybridCactus::embed(const std::string &text, double embeddingBufferSize,
216
+ bool normalize) {
127
217
  return Promise<std::vector<double>>::async(
128
- [this, text, embeddingBufferSize]() -> std::vector<double> {
218
+ [this, text, embeddingBufferSize, normalize]() -> std::vector<double> {
129
219
  std::lock_guard<std::mutex> lock(this->_modelMutex);
130
220
 
131
221
  if (!this->_model) {
@@ -135,12 +225,13 @@ HybridCactus::embed(const std::string &text, double embeddingBufferSize) {
135
225
  std::vector<float> embeddingBuffer(embeddingBufferSize);
136
226
  size_t embeddingDim;
137
227
 
138
- int result =
139
- cactus_embed(this->_model, text.c_str(), embeddingBuffer.data(),
140
- embeddingBufferSize * sizeof(float), &embeddingDim);
228
+ int result = cactus_embed(
229
+ this->_model, text.c_str(), embeddingBuffer.data(),
230
+ embeddingBufferSize * sizeof(float), &embeddingDim, normalize);
141
231
 
142
232
  if (result < 0) {
143
- throw std::runtime_error("Cactus embedding failed");
233
+ throw std::runtime_error("Cactus embed failed: " +
234
+ std::string(cactus_get_last_error()));
144
235
  }
145
236
 
146
237
  embeddingBuffer.resize(embeddingDim);
@@ -169,7 +260,8 @@ HybridCactus::imageEmbed(const std::string &imagePath,
169
260
  embeddingBufferSize * sizeof(float), &embeddingDim);
170
261
 
171
262
  if (result < 0) {
172
- throw std::runtime_error("Cactus image embedding failed");
263
+ throw std::runtime_error("Cactus image embed failed: " +
264
+ std::string(cactus_get_last_error()));
173
265
  }
174
266
 
175
267
  embeddingBuffer.resize(embeddingDim);
@@ -198,7 +290,8 @@ HybridCactus::audioEmbed(const std::string &audioPath,
198
290
  embeddingBufferSize * sizeof(float), &embeddingDim);
199
291
 
200
292
  if (result < 0) {
201
- throw std::runtime_error("Cactus audio embedding failed");
293
+ throw std::runtime_error("Cactus audio embed failed: " +
294
+ std::string(cactus_get_last_error()));
202
295
  }
203
296
 
204
297
  embeddingBuffer.resize(embeddingDim);
@@ -232,9 +325,128 @@ std::shared_ptr<Promise<void>> HybridCactus::destroy() {
232
325
  throw std::runtime_error("Cactus model is not initialized");
233
326
  }
234
327
 
328
+ if (this->_streamTranscribe) {
329
+ cactus_stream_transcribe_destroy(this->_streamTranscribe);
330
+ this->_streamTranscribe = nullptr;
331
+ }
332
+
235
333
  cactus_destroy(this->_model);
236
334
  this->_model = nullptr;
237
335
  });
238
336
  }
239
337
 
338
+ std::shared_ptr<Promise<void>> HybridCactus::streamTranscribeInit() {
339
+ return Promise<void>::async([this]() -> void {
340
+ std::lock_guard<std::mutex> lock(this->_modelMutex);
341
+
342
+ if (!this->_model) {
343
+ throw std::runtime_error("Cactus model is not initialized");
344
+ }
345
+
346
+ if (this->_streamTranscribe) {
347
+ throw std::runtime_error(
348
+ "Cactus stream transcribe is already initialized");
349
+ }
350
+
351
+ this->_streamTranscribe = cactus_stream_transcribe_init(this->_model);
352
+ if (!this->_streamTranscribe) {
353
+ throw std::runtime_error("Cactus stream transcribe init failed: " +
354
+ std::string(cactus_get_last_error()));
355
+ }
356
+ });
357
+ }
358
+
359
+ std::shared_ptr<Promise<void>>
360
+ HybridCactus::streamTranscribeInsert(const std::vector<double> &audio) {
361
+ return Promise<void>::async([this, audio]() -> void {
362
+ std::lock_guard<std::mutex> lock(this->_modelMutex);
363
+
364
+ if (!this->_streamTranscribe) {
365
+ throw std::runtime_error("Cactus stream transcribe is not initialized");
366
+ }
367
+
368
+ std::vector<uint8_t> audioBytes;
369
+ audioBytes.reserve(audio.size());
370
+ for (double d : audio) {
371
+ d = std::clamp(d, 0.0, 255.0);
372
+ audioBytes.emplace_back(static_cast<uint8_t>(d));
373
+ }
374
+
375
+ int result = cactus_stream_transcribe_insert(
376
+ this->_streamTranscribe, audioBytes.data(), audioBytes.size());
377
+
378
+ if (result < 0) {
379
+ throw std::runtime_error("Cactus stream transcribe insert failed: " +
380
+ std::string(cactus_get_last_error()));
381
+ }
382
+ });
383
+ }
384
+
385
+ std::shared_ptr<Promise<std::string>> HybridCactus::streamTranscribeProcess(
386
+ const std::optional<std::string> &optionsJson) {
387
+ return Promise<std::string>::async([this, optionsJson]() -> std::string {
388
+ std::lock_guard<std::mutex> lock(this->_modelMutex);
389
+
390
+ if (!this->_streamTranscribe) {
391
+ throw std::runtime_error("Cactus stream transcribe is not initialized");
392
+ }
393
+
394
+ std::string responseBuffer;
395
+ responseBuffer.resize(32768);
396
+
397
+ int result = cactus_stream_transcribe_process(
398
+ this->_streamTranscribe, responseBuffer.data(), responseBuffer.size(),
399
+ optionsJson ? optionsJson->c_str() : nullptr);
400
+
401
+ if (result < 0) {
402
+ throw std::runtime_error("Cactus stream transcribe process failed: " +
403
+ std::string(cactus_get_last_error()));
404
+ }
405
+
406
+ // Remove null terminator
407
+ responseBuffer.resize(strlen(responseBuffer.c_str()));
408
+
409
+ return responseBuffer;
410
+ });
411
+ }
412
+
413
+ std::shared_ptr<Promise<std::string>> HybridCactus::streamTranscribeFinalize() {
414
+ return Promise<std::string>::async([this]() -> std::string {
415
+ std::lock_guard<std::mutex> lock(this->_modelMutex);
416
+
417
+ if (!this->_streamTranscribe) {
418
+ throw std::runtime_error("Cactus stream transcribe is not initialized");
419
+ }
420
+
421
+ std::string responseBuffer;
422
+ responseBuffer.resize(32768);
423
+
424
+ int result = cactus_stream_transcribe_finalize(
425
+ this->_streamTranscribe, responseBuffer.data(), responseBuffer.size());
426
+
427
+ if (result < 0) {
428
+ throw std::runtime_error("Cactus stream transcribe finalize failed: " +
429
+ std::string(cactus_get_last_error()));
430
+ }
431
+
432
+ // Remove null terminator
433
+ responseBuffer.resize(strlen(responseBuffer.c_str()));
434
+
435
+ return responseBuffer;
436
+ });
437
+ }
438
+
439
+ std::shared_ptr<Promise<void>> HybridCactus::streamTranscribeDestroy() {
440
+ return Promise<void>::async([this]() -> void {
441
+ std::lock_guard<std::mutex> lock(this->_modelMutex);
442
+
443
+ if (!this->_streamTranscribe) {
444
+ throw std::runtime_error("Cactus stream transcribe is not initialized");
445
+ }
446
+
447
+ cactus_stream_transcribe_destroy(this->_streamTranscribe);
448
+ this->_streamTranscribe = nullptr;
449
+ });
450
+ }
451
+
240
452
  } // namespace margelo::nitro::cactus
@@ -23,15 +23,36 @@ public:
23
23
  double /* tokenId */)>> &callback)
24
24
  override;
25
25
 
26
+ std::shared_ptr<Promise<std::vector<double>>>
27
+ tokenize(const std::string &text) override;
28
+
29
+ std::shared_ptr<Promise<std::string>>
30
+ scoreWindow(const std::vector<double> &tokens, double start, double end,
31
+ double context) override;
32
+
26
33
  std::shared_ptr<Promise<std::string>> transcribe(
27
- const std::string &audioFilePath, const std::string &prompt,
28
- double responseBufferSize, const std::optional<std::string> &optionsJson,
34
+ const std::variant<std::vector<double>, std::string> &audio,
35
+ const std::string &prompt, double responseBufferSize,
36
+ const std::optional<std::string> &optionsJson,
29
37
  const std::optional<std::function<void(const std::string & /* token */,
30
38
  double /* tokenId */)>> &callback)
31
39
  override;
32
40
 
41
+ std::shared_ptr<Promise<void>> streamTranscribeInit() override;
42
+
43
+ std::shared_ptr<Promise<void>>
44
+ streamTranscribeInsert(const std::vector<double> &audio) override;
45
+
46
+ std::shared_ptr<Promise<std::string>> streamTranscribeProcess(
47
+ const std::optional<std::string> &optionsJson) override;
48
+
49
+ std::shared_ptr<Promise<std::string>> streamTranscribeFinalize() override;
50
+
51
+ std::shared_ptr<Promise<void>> streamTranscribeDestroy() override;
52
+
33
53
  std::shared_ptr<Promise<std::vector<double>>>
34
- embed(const std::string &text, double embeddingBufferSize) override;
54
+ embed(const std::string &text, double embeddingBufferSize,
55
+ bool normalize) override;
35
56
 
36
57
  std::shared_ptr<Promise<std::vector<double>>>
37
58
  imageEmbed(const std::string &imagePath, double embeddingBufferSize) override;
@@ -47,6 +68,7 @@ public:
47
68
 
48
69
  private:
49
70
  cactus_model_t _model = nullptr;
71
+ cactus_stream_transcribe_t _streamTranscribe = nullptr;
50
72
  size_t _contextSize;
51
73
 
52
74
  std::mutex _modelMutex;