cactus-react-native 1.5.0 → 1.10.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 (221) hide show
  1. package/Cactus.podspec +1 -1
  2. package/README.md +347 -241
  3. package/android/CMakeLists.txt +24 -5
  4. package/android/src/main/jniLibs/arm64-v8a/libcactus.a +0 -0
  5. package/android/src/main/jniLibs/arm64-v8a/libcurl.a +0 -0
  6. package/android/src/main/jniLibs/arm64-v8a/libmbedcrypto.a +0 -0
  7. package/android/src/main/jniLibs/arm64-v8a/libmbedtls.a +0 -0
  8. package/android/src/main/jniLibs/arm64-v8a/libmbedx509.a +0 -0
  9. package/cpp/HybridCactus.cpp +197 -117
  10. package/cpp/HybridCactus.hpp +18 -9
  11. package/cpp/cactus_ffi.h +66 -42
  12. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus.h +0 -1
  13. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_cloud.h +48 -0
  14. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_ffi.h +66 -42
  15. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_utils.h +568 -135
  16. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/engine.h +148 -17
  17. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/graph.h +145 -36
  18. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/kernel.h +187 -6
  19. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/kernel_utils.h +49 -149
  20. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Info.plist +0 -0
  21. package/ios/cactus.xcframework/ios-arm64/cactus.framework/cactus +0 -0
  22. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus.h +0 -1
  23. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_cloud.h +48 -0
  24. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_ffi.h +66 -42
  25. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_utils.h +568 -135
  26. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/engine.h +148 -17
  27. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/graph.h +145 -36
  28. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/kernel.h +187 -6
  29. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/kernel_utils.h +49 -149
  30. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Info.plist +0 -0
  31. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/_CodeSignature/CodeResources +1 -1
  32. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/cactus +0 -0
  33. package/lib/module/classes/CactusLM.js +16 -49
  34. package/lib/module/classes/CactusLM.js.map +1 -1
  35. package/lib/module/classes/CactusSTT.js +41 -75
  36. package/lib/module/classes/CactusSTT.js.map +1 -1
  37. package/lib/module/classes/CactusVAD.js +95 -0
  38. package/lib/module/classes/CactusVAD.js.map +1 -0
  39. package/lib/module/hooks/useCactusLM.js +10 -11
  40. package/lib/module/hooks/useCactusLM.js.map +1 -1
  41. package/lib/module/hooks/useCactusSTT.js +23 -62
  42. package/lib/module/hooks/useCactusSTT.js.map +1 -1
  43. package/lib/module/hooks/useCactusVAD.js +171 -0
  44. package/lib/module/hooks/useCactusVAD.js.map +1 -0
  45. package/lib/module/index.js +2 -3
  46. package/lib/module/index.js.map +1 -1
  47. package/lib/module/modelRegistry.js +52 -0
  48. package/lib/module/modelRegistry.js.map +1 -0
  49. package/lib/module/native/Cactus.js +103 -23
  50. package/lib/module/native/Cactus.js.map +1 -1
  51. package/lib/module/native/CactusIndex.js.map +1 -1
  52. package/lib/module/native/index.js +0 -3
  53. package/lib/module/native/index.js.map +1 -1
  54. package/lib/module/types/CactusVAD.js +4 -0
  55. package/lib/module/{specs/CactusUtil.nitro.js.map → types/CactusVAD.js.map} +1 -1
  56. package/lib/typescript/src/classes/CactusLM.d.ts +5 -7
  57. package/lib/typescript/src/classes/CactusLM.d.ts.map +1 -1
  58. package/lib/typescript/src/classes/CactusSTT.d.ts +9 -12
  59. package/lib/typescript/src/classes/CactusSTT.d.ts.map +1 -1
  60. package/lib/typescript/src/classes/CactusVAD.d.ts +20 -0
  61. package/lib/typescript/src/classes/CactusVAD.d.ts.map +1 -0
  62. package/lib/typescript/src/hooks/useCactusLM.d.ts +2 -2
  63. package/lib/typescript/src/hooks/useCactusLM.d.ts.map +1 -1
  64. package/lib/typescript/src/hooks/useCactusSTT.d.ts +6 -8
  65. package/lib/typescript/src/hooks/useCactusSTT.d.ts.map +1 -1
  66. package/lib/typescript/src/hooks/useCactusVAD.d.ts +15 -0
  67. package/lib/typescript/src/hooks/useCactusVAD.d.ts.map +1 -0
  68. package/lib/typescript/src/index.d.ts +7 -5
  69. package/lib/typescript/src/index.d.ts.map +1 -1
  70. package/lib/typescript/src/modelRegistry.d.ts +5 -0
  71. package/lib/typescript/src/modelRegistry.d.ts.map +1 -0
  72. package/lib/typescript/src/native/Cactus.d.ts +13 -11
  73. package/lib/typescript/src/native/Cactus.d.ts.map +1 -1
  74. package/lib/typescript/src/native/CactusIndex.d.ts +2 -2
  75. package/lib/typescript/src/native/CactusIndex.d.ts.map +1 -1
  76. package/lib/typescript/src/native/index.d.ts +0 -3
  77. package/lib/typescript/src/native/index.d.ts.map +1 -1
  78. package/lib/typescript/src/specs/Cactus.nitro.d.ts +7 -6
  79. package/lib/typescript/src/specs/Cactus.nitro.d.ts.map +1 -1
  80. package/lib/typescript/src/types/CactusIndex.d.ts +2 -2
  81. package/lib/typescript/src/types/CactusIndex.d.ts.map +1 -1
  82. package/lib/typescript/src/types/CactusLM.d.ts +19 -11
  83. package/lib/typescript/src/types/CactusLM.d.ts.map +1 -1
  84. package/lib/typescript/src/types/CactusSTT.d.ts +44 -12
  85. package/lib/typescript/src/types/CactusSTT.d.ts.map +1 -1
  86. package/lib/typescript/src/types/CactusVAD.d.ts +34 -0
  87. package/lib/typescript/src/types/CactusVAD.d.ts.map +1 -0
  88. package/lib/typescript/src/types/common.d.ts +1 -6
  89. package/lib/typescript/src/types/common.d.ts.map +1 -1
  90. package/nitro.json +0 -11
  91. package/nitrogen/generated/android/cactus+autolinking.cmake +0 -5
  92. package/nitrogen/generated/android/cactusOnLoad.cpp +0 -30
  93. package/nitrogen/generated/ios/Cactus-Swift-Cxx-Bridge.cpp +0 -50
  94. package/nitrogen/generated/ios/Cactus-Swift-Cxx-Bridge.hpp +9 -147
  95. package/nitrogen/generated/ios/Cactus-Swift-Cxx-Umbrella.hpp +0 -13
  96. package/nitrogen/generated/ios/CactusAutolinking.mm +0 -26
  97. package/nitrogen/generated/ios/CactusAutolinking.swift +0 -30
  98. package/nitrogen/generated/shared/c++/HybridCactusSpec.cpp +5 -4
  99. package/nitrogen/generated/shared/c++/HybridCactusSpec.hpp +7 -6
  100. package/package.json +3 -3
  101. package/src/classes/CactusLM.ts +18 -65
  102. package/src/classes/CactusSTT.ts +52 -90
  103. package/src/classes/CactusVAD.ts +129 -0
  104. package/src/hooks/useCactusLM.ts +14 -17
  105. package/src/hooks/useCactusSTT.ts +47 -98
  106. package/src/hooks/useCactusVAD.ts +215 -0
  107. package/src/index.tsx +21 -12
  108. package/src/modelRegistry.ts +65 -0
  109. package/src/native/Cactus.ts +131 -38
  110. package/src/native/CactusIndex.ts +2 -2
  111. package/src/native/index.ts +0 -3
  112. package/src/specs/Cactus.nitro.ts +16 -7
  113. package/src/types/CactusIndex.ts +2 -2
  114. package/src/types/CactusLM.ts +19 -11
  115. package/src/types/CactusSTT.ts +47 -13
  116. package/src/types/CactusVAD.ts +39 -0
  117. package/src/types/common.ts +1 -6
  118. package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusCrypto.kt +0 -46
  119. package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusDeviceInfo.kt +0 -27
  120. package/android/src/main/jniLibs/arm64-v8a/libcactus_util.a +0 -0
  121. package/cpp/HybridCactusUtil.cpp +0 -47
  122. package/cpp/HybridCactusUtil.hpp +0 -27
  123. package/cpp/cactus_util.h +0 -25
  124. package/ios/HybridCactusCrypto.swift +0 -37
  125. package/ios/HybridCactusDeviceInfo.swift +0 -32
  126. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_telemetry.h +0 -656
  127. package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_telemetry.h +0 -656
  128. package/ios/cactus_util.xcframework/Info.plist +0 -39
  129. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/cactus_util.h +0 -25
  130. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/database.h +0 -27
  131. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/ios_utils.h +0 -10
  132. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/logging.h +0 -25
  133. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Info.plist +0 -0
  134. package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/cactus_util +0 -0
  135. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/cactus_util.h +0 -25
  136. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/database.h +0 -27
  137. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/ios_utils.h +0 -10
  138. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/logging.h +0 -25
  139. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Info.plist +0 -0
  140. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/_CodeSignature/CodeResources +0 -135
  141. package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/cactus_util +0 -0
  142. package/lib/module/api/Database.js +0 -45
  143. package/lib/module/api/Database.js.map +0 -1
  144. package/lib/module/api/RemoteLM.js +0 -201
  145. package/lib/module/api/RemoteLM.js.map +0 -1
  146. package/lib/module/config/CactusConfig.js +0 -12
  147. package/lib/module/config/CactusConfig.js.map +0 -1
  148. package/lib/module/models.js +0 -336
  149. package/lib/module/models.js.map +0 -1
  150. package/lib/module/native/CactusCrypto.js +0 -10
  151. package/lib/module/native/CactusCrypto.js.map +0 -1
  152. package/lib/module/native/CactusDeviceInfo.js +0 -13
  153. package/lib/module/native/CactusDeviceInfo.js.map +0 -1
  154. package/lib/module/native/CactusUtil.js +0 -36
  155. package/lib/module/native/CactusUtil.js.map +0 -1
  156. package/lib/module/specs/CactusCrypto.nitro.js +0 -4
  157. package/lib/module/specs/CactusCrypto.nitro.js.map +0 -1
  158. package/lib/module/specs/CactusDeviceInfo.nitro.js +0 -4
  159. package/lib/module/specs/CactusDeviceInfo.nitro.js.map +0 -1
  160. package/lib/module/specs/CactusUtil.nitro.js +0 -4
  161. package/lib/module/telemetry/Telemetry.js +0 -154
  162. package/lib/module/telemetry/Telemetry.js.map +0 -1
  163. package/lib/typescript/src/api/Database.d.ts +0 -12
  164. package/lib/typescript/src/api/Database.d.ts.map +0 -1
  165. package/lib/typescript/src/api/RemoteLM.d.ts +0 -14
  166. package/lib/typescript/src/api/RemoteLM.d.ts.map +0 -1
  167. package/lib/typescript/src/config/CactusConfig.d.ts +0 -7
  168. package/lib/typescript/src/config/CactusConfig.d.ts.map +0 -1
  169. package/lib/typescript/src/models.d.ts +0 -6
  170. package/lib/typescript/src/models.d.ts.map +0 -1
  171. package/lib/typescript/src/native/CactusCrypto.d.ts +0 -5
  172. package/lib/typescript/src/native/CactusCrypto.d.ts.map +0 -1
  173. package/lib/typescript/src/native/CactusDeviceInfo.d.ts +0 -7
  174. package/lib/typescript/src/native/CactusDeviceInfo.d.ts.map +0 -1
  175. package/lib/typescript/src/native/CactusUtil.d.ts +0 -6
  176. package/lib/typescript/src/native/CactusUtil.d.ts.map +0 -1
  177. package/lib/typescript/src/specs/CactusCrypto.nitro.d.ts +0 -8
  178. package/lib/typescript/src/specs/CactusCrypto.nitro.d.ts.map +0 -1
  179. package/lib/typescript/src/specs/CactusDeviceInfo.nitro.d.ts +0 -16
  180. package/lib/typescript/src/specs/CactusDeviceInfo.nitro.d.ts.map +0 -1
  181. package/lib/typescript/src/specs/CactusUtil.nitro.d.ts +0 -10
  182. package/lib/typescript/src/specs/CactusUtil.nitro.d.ts.map +0 -1
  183. package/lib/typescript/src/telemetry/Telemetry.d.ts +0 -34
  184. package/lib/typescript/src/telemetry/Telemetry.d.ts.map +0 -1
  185. package/nitrogen/generated/android/c++/JDeviceInfo.hpp +0 -74
  186. package/nitrogen/generated/android/c++/JHybridCactusCryptoSpec.cpp +0 -65
  187. package/nitrogen/generated/android/c++/JHybridCactusCryptoSpec.hpp +0 -65
  188. package/nitrogen/generated/android/c++/JHybridCactusDeviceInfoSpec.cpp +0 -85
  189. package/nitrogen/generated/android/c++/JHybridCactusDeviceInfoSpec.hpp +0 -66
  190. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/DeviceInfo.kt +0 -50
  191. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusCryptoSpec.kt +0 -58
  192. package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusDeviceInfoSpec.kt +0 -62
  193. package/nitrogen/generated/ios/c++/HybridCactusCryptoSpecSwift.cpp +0 -11
  194. package/nitrogen/generated/ios/c++/HybridCactusCryptoSpecSwift.hpp +0 -77
  195. package/nitrogen/generated/ios/c++/HybridCactusDeviceInfoSpecSwift.cpp +0 -11
  196. package/nitrogen/generated/ios/c++/HybridCactusDeviceInfoSpecSwift.hpp +0 -88
  197. package/nitrogen/generated/ios/swift/DeviceInfo.swift +0 -98
  198. package/nitrogen/generated/ios/swift/Func_void_DeviceInfo.swift +0 -47
  199. package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +0 -54
  200. package/nitrogen/generated/ios/swift/HybridCactusCryptoSpec.swift +0 -57
  201. package/nitrogen/generated/ios/swift/HybridCactusCryptoSpec_cxx.swift +0 -139
  202. package/nitrogen/generated/ios/swift/HybridCactusDeviceInfoSpec.swift +0 -58
  203. package/nitrogen/generated/ios/swift/HybridCactusDeviceInfoSpec_cxx.swift +0 -164
  204. package/nitrogen/generated/shared/c++/DeviceInfo.hpp +0 -92
  205. package/nitrogen/generated/shared/c++/HybridCactusCryptoSpec.cpp +0 -21
  206. package/nitrogen/generated/shared/c++/HybridCactusCryptoSpec.hpp +0 -63
  207. package/nitrogen/generated/shared/c++/HybridCactusDeviceInfoSpec.cpp +0 -22
  208. package/nitrogen/generated/shared/c++/HybridCactusDeviceInfoSpec.hpp +0 -67
  209. package/nitrogen/generated/shared/c++/HybridCactusUtilSpec.cpp +0 -23
  210. package/nitrogen/generated/shared/c++/HybridCactusUtilSpec.hpp +0 -66
  211. package/src/api/Database.ts +0 -55
  212. package/src/api/RemoteLM.ts +0 -273
  213. package/src/config/CactusConfig.ts +0 -11
  214. package/src/models.ts +0 -344
  215. package/src/native/CactusCrypto.ts +0 -11
  216. package/src/native/CactusDeviceInfo.ts +0 -18
  217. package/src/native/CactusUtil.ts +0 -43
  218. package/src/specs/CactusCrypto.nitro.ts +0 -6
  219. package/src/specs/CactusDeviceInfo.nitro.ts +0 -15
  220. package/src/specs/CactusUtil.nitro.ts +0 -8
  221. package/src/telemetry/Telemetry.ts +0 -236
@@ -3,17 +3,20 @@ import type { Cactus as CactusSpec } from '../specs/Cactus.nitro';
3
3
  import { CactusImage } from './CactusImage';
4
4
  import type {
5
5
  CactusLMCompleteResult,
6
- Message,
7
- CompleteOptions,
8
- Tool,
6
+ CactusLMMessage,
7
+ CactusLMCompleteOptions,
8
+ CactusLMTool,
9
9
  } from '../types/CactusLM';
10
10
  import type {
11
11
  CactusSTTTranscribeResult,
12
- TranscribeOptions,
12
+ CactusSTTTranscribeOptions,
13
+ CactusSTTStreamTranscribeStartOptions,
13
14
  CactusSTTStreamTranscribeProcessResult,
14
- StreamTranscribeProcessOptions,
15
- CactusSTTStreamTranscribeFinalizeResult,
15
+ CactusSTTStreamTranscribeStopResult,
16
+ CactusSTTDetectLanguageOptions,
17
+ CactusSTTDetectLanguageResult,
16
18
  } from '../types/CactusSTT';
19
+ import type { CactusVADOptions, CactusVADResult } from '../types/CactusVAD';
17
20
 
18
21
  export class Cactus {
19
22
  private readonly hybridCactus =
@@ -21,20 +24,20 @@ export class Cactus {
21
24
 
22
25
  public init(
23
26
  modelPath: string,
24
- contextSize: number,
25
- corpusDir?: string
27
+ corpusDir?: string,
28
+ cacheIndex?: boolean
26
29
  ): Promise<void> {
27
- return this.hybridCactus.init(modelPath, contextSize, corpusDir);
30
+ return this.hybridCactus.init(modelPath, corpusDir, cacheIndex ?? false);
28
31
  }
29
32
 
30
33
  public async complete(
31
- messages: Message[],
34
+ messages: CactusLMMessage[],
32
35
  responseBufferSize: number,
33
- options?: CompleteOptions,
34
- tools?: { type: 'function'; function: Tool }[],
36
+ options?: CactusLMCompleteOptions,
37
+ tools?: { type: 'function'; function: CactusLMTool }[],
35
38
  callback?: (token: string, tokenId: number) => void
36
39
  ): Promise<CactusLMCompleteResult> {
37
- const messagesInternal: Message[] = [];
40
+ const messagesInternal: CactusLMMessage[] = [];
38
41
  for (const message of messages) {
39
42
  if (!message.images) {
40
43
  messagesInternal.push(message);
@@ -64,6 +67,11 @@ export class Cactus {
64
67
  max_tokens: options.maxTokens,
65
68
  stop_sequences: options.stopSequences,
66
69
  force_tools: options.forceTools,
70
+ telemetry_enabled: options.telemetryEnabled,
71
+ confidence_threshold: options.confidenceThreshold,
72
+ tool_rag_top_k: options.toolRagTopK,
73
+ include_stop_sequences: options.includeStopSequences,
74
+ use_vad: options.useVad,
67
75
  })
68
76
  : undefined;
69
77
  const toolsJson = JSON.stringify(tools);
@@ -83,12 +91,16 @@ export class Cactus {
83
91
  success: parsed.success,
84
92
  response: parsed.response,
85
93
  functionCalls: parsed.function_calls,
94
+ cloudHandoff: parsed.cloud_handoff,
95
+ confidence: parsed.confidence,
86
96
  timeToFirstTokenMs: parsed.time_to_first_token_ms,
87
97
  totalTimeMs: parsed.total_time_ms,
88
- tokensPerSecond: parsed.tokens_per_second,
89
98
  prefillTokens: parsed.prefill_tokens,
99
+ prefillTps: parsed.prefill_tps,
90
100
  decodeTokens: parsed.decode_tokens,
101
+ decodeTps: parsed.decode_tps,
91
102
  totalTokens: parsed.total_tokens,
103
+ ramUsageMb: parsed.ram_usage_mb,
92
104
  };
93
105
  } catch {
94
106
  throw new Error('Unable to parse completion response');
@@ -123,7 +135,7 @@ export class Cactus {
123
135
  audio: string | number[],
124
136
  prompt: string,
125
137
  responseBufferSize: number,
126
- options?: TranscribeOptions,
138
+ options?: CactusSTTTranscribeOptions,
127
139
  callback?: (token: string, tokenId: number) => void
128
140
  ): Promise<CactusSTTTranscribeResult> {
129
141
  if (typeof audio === 'string') {
@@ -137,6 +149,11 @@ export class Cactus {
137
149
  top_k: options.topK,
138
150
  max_tokens: options.maxTokens,
139
151
  stop_sequences: options.stopSequences,
152
+ use_vad: options.useVad,
153
+ telemetry_enabled: options.telemetryEnabled,
154
+ confidence_threshold: options.confidenceThreshold,
155
+ cloud_handoff_threshold: options.cloudHandoffThreshold,
156
+ include_stop_sequences: options.includeStopSequences,
140
157
  })
141
158
  : undefined;
142
159
 
@@ -154,68 +171,140 @@ export class Cactus {
154
171
  return {
155
172
  success: parsed.success,
156
173
  response: parsed.response,
174
+ cloudHandoff: parsed.cloud_handoff,
175
+ confidence: parsed.confidence,
157
176
  timeToFirstTokenMs: parsed.time_to_first_token_ms,
158
177
  totalTimeMs: parsed.total_time_ms,
159
- tokensPerSecond: parsed.tokens_per_second,
160
178
  prefillTokens: parsed.prefill_tokens,
179
+ prefillTps: parsed.prefill_tps,
161
180
  decodeTokens: parsed.decode_tokens,
181
+ decodeTps: parsed.decode_tps,
162
182
  totalTokens: parsed.total_tokens,
183
+ ramUsageMb: parsed.ram_usage_mb,
163
184
  };
164
185
  } catch {
165
186
  throw new Error('Unable to parse transcription response');
166
187
  }
167
188
  }
168
189
 
169
- public streamTranscribeInit(): Promise<void> {
170
- return this.hybridCactus.streamTranscribeInit();
171
- }
172
-
173
- public streamTranscribeInsert(audio: number[]): Promise<void> {
174
- return this.hybridCactus.streamTranscribeInsert(audio);
175
- }
176
-
177
- public async streamTranscribeProcess(
178
- options?: StreamTranscribeProcessOptions
179
- ): Promise<CactusSTTStreamTranscribeProcessResult> {
190
+ public streamTranscribeStart(
191
+ options?: CactusSTTStreamTranscribeStartOptions
192
+ ): Promise<void> {
180
193
  const optionsJson = options
181
194
  ? JSON.stringify({
182
195
  confirmation_threshold: options.confirmationThreshold,
196
+ min_chunk_size: options.minChunkSize,
197
+ telemetry_enabled: options.telemetryEnabled,
183
198
  })
184
199
  : undefined;
200
+ return this.hybridCactus.streamTranscribeStart(optionsJson);
201
+ }
185
202
 
186
- const response =
187
- await this.hybridCactus.streamTranscribeProcess(optionsJson);
188
-
203
+ public async streamTranscribeProcess(
204
+ audio: number[]
205
+ ): Promise<CactusSTTStreamTranscribeProcessResult> {
206
+ const response = await this.hybridCactus.streamTranscribeProcess(audio);
189
207
  try {
190
208
  const parsed = JSON.parse(response);
191
-
192
209
  return {
193
210
  success: parsed.success,
194
211
  confirmed: parsed.confirmed,
195
212
  pending: parsed.pending,
213
+ bufferDurationMs: parsed.buffer_duration_ms,
214
+ confidence: parsed.confidence,
215
+ cloudHandoff: parsed.cloud_handoff,
216
+ cloudResult: parsed.cloud_result,
217
+ cloudJobId: parsed.cloud_job_id,
218
+ cloudResultJobId: parsed.cloud_result_job_id,
219
+ timeToFirstTokenMs: parsed.time_to_first_token_ms,
220
+ totalTimeMs: parsed.total_time_ms,
221
+ prefillTokens: parsed.prefill_tokens,
222
+ prefillTps: parsed.prefill_tps,
223
+ decodeTokens: parsed.decode_tokens,
224
+ decodeTps: parsed.decode_tps,
225
+ totalTokens: parsed.total_tokens,
226
+ ramUsageMb: parsed.ram_usage_mb,
196
227
  };
197
228
  } catch {
198
229
  throw new Error('Unable to parse stream transcribe process response');
199
230
  }
200
231
  }
201
232
 
202
- public async streamTranscribeFinalize(): Promise<CactusSTTStreamTranscribeFinalizeResult> {
203
- const response = await this.hybridCactus.streamTranscribeFinalize();
233
+ public async detectLanguage(
234
+ audio: string | number[],
235
+ options?: CactusSTTDetectLanguageOptions
236
+ ): Promise<CactusSTTDetectLanguageResult> {
237
+ if (typeof audio === 'string') {
238
+ audio = audio.replace('file://', '');
239
+ }
240
+
241
+ const optionsJson = options
242
+ ? JSON.stringify({ use_vad: options.useVad })
243
+ : undefined;
244
+
245
+ const response = await this.hybridCactus.detectLanguage(
246
+ audio,
247
+ 1024,
248
+ optionsJson
249
+ );
204
250
 
205
251
  try {
206
252
  const parsed = JSON.parse(response);
207
253
 
208
254
  return {
209
- success: parsed.success,
210
- confirmed: parsed.confirmed,
255
+ language: parsed.language,
256
+ confidence: parsed.confidence,
211
257
  };
212
258
  } catch {
213
- throw new Error('Unable to parse stream transcribe finalize response');
259
+ throw new Error('Unable to parse detect language response');
214
260
  }
215
261
  }
216
262
 
217
- public streamTranscribeDestroy(): Promise<void> {
218
- return this.hybridCactus.streamTranscribeDestroy();
263
+ public async streamTranscribeStop(): Promise<CactusSTTStreamTranscribeStopResult> {
264
+ const response = await this.hybridCactus.streamTranscribeStop();
265
+ try {
266
+ const parsed = JSON.parse(response);
267
+ return { success: parsed.success, confirmed: parsed.confirmed };
268
+ } catch {
269
+ throw new Error('Unable to parse stream transcribe stop response');
270
+ }
271
+ }
272
+
273
+ public async vad(
274
+ audio: string | number[],
275
+ options?: CactusVADOptions
276
+ ): Promise<CactusVADResult> {
277
+ if (typeof audio === 'string') {
278
+ audio = audio.replace('file://', '');
279
+ }
280
+ const optionsJson = options
281
+ ? JSON.stringify({
282
+ threshold: options.threshold,
283
+ neg_threshold: options.negThreshold,
284
+ min_speech_duration_ms: options.minSpeechDurationMs,
285
+ max_speech_duration_s: options.maxSpeechDurationS,
286
+ min_silence_duration_ms: options.minSilenceDurationMs,
287
+ speech_pad_ms: options.speechPadMs,
288
+ window_size_samples: options.windowSizeSamples,
289
+ sampling_rate: options.samplingRate,
290
+ min_silence_at_max_speech: options.minSilenceAtMaxSpeech,
291
+ use_max_poss_sil_at_max_speech: options.useMaxPossSilAtMaxSpeech,
292
+ })
293
+ : undefined;
294
+ const response = await this.hybridCactus.vad(audio, 65536, optionsJson);
295
+ try {
296
+ const parsed = JSON.parse(response);
297
+ return {
298
+ segments: parsed.segments.map((s: { start: number; end: number }) => ({
299
+ start: s.start,
300
+ end: s.end,
301
+ })),
302
+ totalTime: parsed.total_time_ms,
303
+ ramUsage: parsed.ram_usage_mb,
304
+ };
305
+ } catch {
306
+ throw new Error('Unable to parse VAD response');
307
+ }
219
308
  }
220
309
 
221
310
  public embed(
@@ -260,4 +349,8 @@ export class Cactus {
260
349
  public destroy(): Promise<void> {
261
350
  return this.hybridCactus.destroy();
262
351
  }
352
+
353
+ public setTelemetryEnvironment(cacheDir: string): Promise<void> {
354
+ return this.hybridCactus.setTelemetryEnvironment(cacheDir);
355
+ }
263
356
  }
@@ -3,7 +3,7 @@ import type { CactusIndex as CactusIndexSpec } from '../specs/CactusIndex.nitro'
3
3
  import type {
4
4
  CactusIndexGetResult,
5
5
  CactusIndexQueryResult,
6
- IndexQueryOptions,
6
+ CactusIndexQueryOptions,
7
7
  } from '../types/CactusIndex';
8
8
 
9
9
  export class CactusIndex {
@@ -33,7 +33,7 @@ export class CactusIndex {
33
33
 
34
34
  public query(
35
35
  embeddings: number[][],
36
- options?: IndexQueryOptions
36
+ options?: CactusIndexQueryOptions
37
37
  ): Promise<CactusIndexQueryResult> {
38
38
  const optionsJson = options
39
39
  ? JSON.stringify({
@@ -1,7 +1,4 @@
1
1
  export { Cactus } from './Cactus';
2
2
  export { CactusIndex } from './CactusIndex';
3
- export { CactusCrypto } from './CactusCrypto';
4
- export { CactusDeviceInfo } from './CactusDeviceInfo';
5
3
  export { CactusFileSystem } from './CactusFileSystem';
6
4
  export { CactusImage } from './CactusImage';
7
- export { CactusUtil } from './CactusUtil';
@@ -3,8 +3,8 @@ import type { HybridObject } from 'react-native-nitro-modules';
3
3
  export interface Cactus extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
4
4
  init(
5
5
  modelPath: string,
6
- contextSize: number,
7
- corpusDir?: string
6
+ corpusDir?: string,
7
+ cacheIndex?: boolean
8
8
  ): Promise<void>;
9
9
  complete(
10
10
  messagesJson: string,
@@ -27,11 +27,19 @@ export interface Cactus extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
27
27
  optionsJson?: string,
28
28
  callback?: (token: string, tokenId: number) => void
29
29
  ): Promise<string>;
30
- streamTranscribeInit(): Promise<void>;
31
- streamTranscribeInsert(audio: number[]): Promise<void>;
32
- streamTranscribeProcess(optionsJson?: string): Promise<string>;
33
- streamTranscribeFinalize(): Promise<string>;
34
- streamTranscribeDestroy(): Promise<void>;
30
+ detectLanguage(
31
+ audio: string | number[],
32
+ responseBufferSize: number,
33
+ optionsJson?: string
34
+ ): Promise<string>;
35
+ streamTranscribeStart(optionsJson?: string): Promise<void>;
36
+ streamTranscribeProcess(audio: number[]): Promise<string>;
37
+ streamTranscribeStop(): Promise<string>;
38
+ vad(
39
+ audio: string | number[],
40
+ responseBufferSize: number,
41
+ optionsJson?: string
42
+ ): Promise<string>;
35
43
  embed(
36
44
  text: string,
37
45
  embeddingBufferSize: number,
@@ -42,4 +50,5 @@ export interface Cactus extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
42
50
  reset(): Promise<void>;
43
51
  stop(): Promise<void>;
44
52
  destroy(): Promise<void>;
53
+ setTelemetryEnvironment(cacheDir: string): Promise<void>;
45
54
  }
@@ -20,14 +20,14 @@ export interface CactusIndexGetResult {
20
20
  embeddings: number[][];
21
21
  }
22
22
 
23
- export interface IndexQueryOptions {
23
+ export interface CactusIndexQueryOptions {
24
24
  topK?: number;
25
25
  scoreThreshold?: number;
26
26
  }
27
27
 
28
28
  export interface CactusIndexQueryParams {
29
29
  embeddings: number[][];
30
- options?: IndexQueryOptions;
30
+ options?: CactusIndexQueryOptions;
31
31
  }
32
32
 
33
33
  export interface CactusIndexQueryResult {
@@ -1,32 +1,37 @@
1
- import { type ModelOptions } from './common';
1
+ import { type CactusModelOptions } from './common';
2
2
 
3
3
  export interface CactusLMParams {
4
4
  model?: string;
5
- contextSize?: number;
6
5
  corpusDir?: string;
7
- options?: ModelOptions;
6
+ cacheIndex?: boolean;
7
+ options?: CactusModelOptions;
8
8
  }
9
9
 
10
10
  export interface CactusLMDownloadParams {
11
11
  onProgress?: (progress: number) => void;
12
12
  }
13
13
 
14
- export interface Message {
14
+ export interface CactusLMMessage {
15
15
  role: 'user' | 'assistant' | 'system';
16
16
  content?: string;
17
17
  images?: string[];
18
18
  }
19
19
 
20
- export interface CompleteOptions {
20
+ export interface CactusLMCompleteOptions {
21
21
  temperature?: number;
22
22
  topP?: number;
23
23
  topK?: number;
24
24
  maxTokens?: number;
25
25
  stopSequences?: string[];
26
26
  forceTools?: boolean;
27
+ telemetryEnabled?: boolean;
28
+ confidenceThreshold?: number;
29
+ toolRagTopK?: number;
30
+ includeStopSequences?: boolean;
31
+ useVad?: boolean;
27
32
  }
28
33
 
29
- export interface Tool {
34
+ export interface CactusLMTool {
30
35
  name: string;
31
36
  description: string;
32
37
  parameters: {
@@ -42,11 +47,10 @@ export interface Tool {
42
47
  }
43
48
 
44
49
  export interface CactusLMCompleteParams {
45
- messages: Message[];
46
- options?: CompleteOptions;
47
- tools?: Tool[];
50
+ messages: CactusLMMessage[];
51
+ options?: CactusLMCompleteOptions;
52
+ tools?: CactusLMTool[];
48
53
  onToken?: (token: string) => void;
49
- mode?: 'local' | 'hybrid';
50
54
  }
51
55
 
52
56
  export interface CactusLMCompleteResult {
@@ -56,12 +60,16 @@ export interface CactusLMCompleteResult {
56
60
  name: string;
57
61
  arguments: { [key: string]: any };
58
62
  }[];
63
+ cloudHandoff?: boolean;
64
+ confidence?: number;
59
65
  timeToFirstTokenMs: number;
60
66
  totalTimeMs: number;
61
- tokensPerSecond: number;
62
67
  prefillTokens: number;
68
+ prefillTps: number;
63
69
  decodeTokens: number;
70
+ decodeTps: number;
64
71
  totalTokens: number;
72
+ ramUsageMb?: number;
65
73
  }
66
74
 
67
75
  export interface CactusLMTokenizeParams {
@@ -1,39 +1,47 @@
1
- import { type ModelOptions } from './common';
1
+ import { type CactusModelOptions } from './common';
2
2
 
3
3
  export interface CactusSTTParams {
4
4
  model?: string;
5
- contextSize?: number;
6
- options?: ModelOptions;
5
+ options?: CactusModelOptions;
7
6
  }
8
7
 
9
8
  export interface CactusSTTDownloadParams {
10
9
  onProgress?: (progress: number) => void;
11
10
  }
12
11
 
13
- export interface TranscribeOptions {
12
+ export interface CactusSTTTranscribeOptions {
14
13
  temperature?: number;
15
14
  topP?: number;
16
15
  topK?: number;
17
16
  maxTokens?: number;
18
17
  stopSequences?: string[];
18
+ useVad?: boolean;
19
+ telemetryEnabled?: boolean;
20
+ confidenceThreshold?: number;
21
+ cloudHandoffThreshold?: number;
22
+ includeStopSequences?: boolean;
19
23
  }
20
24
 
21
25
  export interface CactusSTTTranscribeParams {
22
26
  audio: string | number[];
23
27
  prompt?: string;
24
- options?: TranscribeOptions;
28
+ options?: CactusSTTTranscribeOptions;
25
29
  onToken?: (token: string) => void;
26
30
  }
27
31
 
28
32
  export interface CactusSTTTranscribeResult {
29
33
  success: boolean;
30
34
  response: string;
35
+ cloudHandoff?: boolean;
36
+ confidence?: number;
31
37
  timeToFirstTokenMs: number;
32
38
  totalTimeMs: number;
33
- tokensPerSecond: number;
34
39
  prefillTokens: number;
40
+ prefillTps: number;
35
41
  decodeTokens: number;
42
+ decodeTps: number;
36
43
  totalTokens: number;
44
+ ramUsageMb?: number;
37
45
  }
38
46
 
39
47
  export interface CactusSTTAudioEmbedParams {
@@ -44,25 +52,51 @@ export interface CactusSTTAudioEmbedResult {
44
52
  embedding: number[];
45
53
  }
46
54
 
47
- export interface CactusSTTStreamTranscribeInsertParams {
48
- audio: number[];
49
- }
50
-
51
- export interface StreamTranscribeProcessOptions {
55
+ export interface CactusSTTStreamTranscribeStartOptions {
52
56
  confirmationThreshold?: number;
57
+ minChunkSize?: number;
58
+ telemetryEnabled?: boolean;
53
59
  }
54
60
 
55
61
  export interface CactusSTTStreamTranscribeProcessParams {
56
- options?: StreamTranscribeProcessOptions;
62
+ audio: number[];
57
63
  }
58
64
 
59
65
  export interface CactusSTTStreamTranscribeProcessResult {
60
66
  success: boolean;
61
67
  confirmed: string;
62
68
  pending: string;
69
+ bufferDurationMs?: number;
70
+ confidence?: number;
71
+ cloudHandoff?: boolean;
72
+ cloudResult?: string;
73
+ cloudJobId?: number;
74
+ cloudResultJobId?: number;
75
+ timeToFirstTokenMs?: number;
76
+ totalTimeMs?: number;
77
+ prefillTokens?: number;
78
+ prefillTps?: number;
79
+ decodeTokens?: number;
80
+ decodeTps?: number;
81
+ totalTokens?: number;
82
+ ramUsageMb?: number;
63
83
  }
64
84
 
65
- export interface CactusSTTStreamTranscribeFinalizeResult {
85
+ export interface CactusSTTStreamTranscribeStopResult {
66
86
  success: boolean;
67
87
  confirmed: string;
68
88
  }
89
+
90
+ export interface CactusSTTDetectLanguageOptions {
91
+ useVad?: boolean;
92
+ }
93
+
94
+ export interface CactusSTTDetectLanguageParams {
95
+ audio: string | number[];
96
+ options?: CactusSTTDetectLanguageOptions;
97
+ }
98
+
99
+ export interface CactusSTTDetectLanguageResult {
100
+ language: string;
101
+ confidence?: number;
102
+ }
@@ -0,0 +1,39 @@
1
+ import type { CactusModelOptions } from './common';
2
+
3
+ export interface CactusVADParams {
4
+ model?: string;
5
+ options?: CactusModelOptions;
6
+ }
7
+
8
+ export interface CactusVADDownloadParams {
9
+ onProgress?: (progress: number) => void;
10
+ }
11
+
12
+ export interface CactusVADOptions {
13
+ threshold?: number;
14
+ negThreshold?: number;
15
+ minSpeechDurationMs?: number;
16
+ maxSpeechDurationS?: number;
17
+ minSilenceDurationMs?: number;
18
+ speechPadMs?: number;
19
+ windowSizeSamples?: number;
20
+ samplingRate?: number;
21
+ minSilenceAtMaxSpeech?: number;
22
+ useMaxPossSilAtMaxSpeech?: boolean;
23
+ }
24
+
25
+ export interface CactusVADSegment {
26
+ start: number;
27
+ end: number;
28
+ }
29
+
30
+ export interface CactusVADResult {
31
+ segments: CactusVADSegment[];
32
+ totalTime: number;
33
+ ramUsage: number;
34
+ }
35
+
36
+ export interface CactusVADVadParams {
37
+ audio: string | number[];
38
+ options?: CactusVADOptions;
39
+ }
@@ -1,9 +1,4 @@
1
1
  export interface CactusModel {
2
- completion: boolean;
3
- tools: boolean;
4
- vision: boolean;
5
- embed: boolean;
6
- speech: boolean;
7
2
  quantization: {
8
3
  int4: {
9
4
  sizeMb: number;
@@ -22,7 +17,7 @@ export interface CactusModel {
22
17
  };
23
18
  }
24
19
 
25
- export interface ModelOptions {
20
+ export interface CactusModelOptions {
26
21
  quantization?: 'int4' | 'int8';
27
22
  pro?: boolean;
28
23
  }
@@ -1,46 +0,0 @@
1
- package com.margelo.nitro.cactus
2
-
3
- import com.margelo.nitro.core.Promise
4
- import java.nio.ByteBuffer
5
- import java.security.MessageDigest
6
- import java.util.Locale
7
- import java.util.UUID
8
-
9
- class HybridCactusCrypto : HybridCactusCryptoSpec() {
10
- override fun uuidv5(
11
- namespaceUuid: String,
12
- name: String,
13
- ): Promise<String> =
14
- Promise.async {
15
- val nsUuid =
16
- try {
17
- UUID.fromString(namespaceUuid)
18
- } catch (e: IllegalArgumentException) {
19
- throw IllegalArgumentException("Invalid namespace UUID")
20
- }
21
-
22
- val nsBytes =
23
- ByteBuffer
24
- .allocate(16)
25
- .apply {
26
- putLong(nsUuid.mostSignificantBits)
27
- putLong(nsUuid.leastSignificantBits)
28
- }.array()
29
- val nameBytes = name.toByteArray(Charsets.UTF_8)
30
-
31
- val sha1 =
32
- MessageDigest
33
- .getInstance("SHA-1")
34
- .apply { update(nsBytes) }
35
- .digest(nameBytes)
36
- val uuidBytes = sha1.copyOfRange(0, 16)
37
- uuidBytes[6] = (uuidBytes[6].toInt() and 0x0F or 0x50).toByte()
38
- uuidBytes[8] = (uuidBytes[8].toInt() and 0x3F or 0x80).toByte()
39
-
40
- val bb = ByteBuffer.wrap(uuidBytes)
41
-
42
- val uuid = UUID(bb.long, bb.long)
43
-
44
- uuid.toString().lowercase(Locale.ROOT)
45
- }
46
- }
@@ -1,27 +0,0 @@
1
- package com.margelo.nitro.cactus
2
-
3
- import android.os.Build
4
- import android.provider.Settings
5
- import com.margelo.nitro.NitroModules
6
- import com.margelo.nitro.core.Promise
7
-
8
- class HybridCactusDeviceInfo : HybridCactusDeviceInfoSpec() {
9
- private val context = NitroModules.applicationContext ?: error("Android context not found")
10
-
11
- override fun getAppIdentifier(): Promise<String?> = Promise.async { context.packageName }
12
-
13
- override fun getDeviceInfo(): Promise<DeviceInfo> =
14
- Promise.async {
15
- DeviceInfo(
16
- brand = Build.MANUFACTURER,
17
- model = Build.MODEL,
18
- device_id =
19
- Settings.Secure.getString(
20
- context.contentResolver,
21
- Settings.Secure.ANDROID_ID,
22
- ),
23
- os = "Android",
24
- os_version = Build.VERSION.RELEASE,
25
- )
26
- }
27
- }