cactus-react-native 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +378 -21
- package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusCrypto.kt +23 -15
- package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusDeviceInfo.kt +12 -9
- package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusFileSystem.kt +42 -41
- package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusImage.kt +81 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus.a +0 -0
- package/cpp/HybridCactus.cpp +105 -0
- package/cpp/HybridCactus.hpp +13 -0
- package/cpp/cactus_ffi.h +27 -0
- package/ios/HybridCactusImage.swift +53 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_ffi.h +27 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/engine.h +35 -3
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ffi_utils.h +10 -9
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/graph.h +3 -1
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/kernel.h +31 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/cactus +0 -0
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_ffi.h +27 -0
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/engine.h +35 -3
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/ffi_utils.h +10 -9
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/graph.h +3 -1
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/kernel.h +31 -0
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/cactus +0 -0
- package/lib/module/api/Database.js +23 -0
- package/lib/module/api/Database.js.map +1 -1
- package/lib/module/api/RemoteLM.js +201 -0
- package/lib/module/api/RemoteLM.js.map +1 -0
- package/lib/module/classes/CactusLM.js +52 -26
- package/lib/module/classes/CactusLM.js.map +1 -1
- package/lib/module/classes/CactusSTT.js +137 -0
- package/lib/module/classes/CactusSTT.js.map +1 -0
- package/lib/module/config/CactusConfig.js +4 -0
- package/lib/module/config/CactusConfig.js.map +1 -1
- package/lib/module/constants/packageVersion.js +1 -1
- package/lib/module/hooks/useCactusLM.js +33 -10
- package/lib/module/hooks/useCactusLM.js.map +1 -1
- package/lib/module/hooks/useCactusSTT.js +234 -0
- package/lib/module/hooks/useCactusSTT.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/native/Cactus.js +50 -1
- package/lib/module/native/Cactus.js.map +1 -1
- package/lib/module/native/CactusFileSystem.js +2 -3
- package/lib/module/native/CactusFileSystem.js.map +1 -1
- package/lib/module/native/CactusImage.js +13 -0
- package/lib/module/native/CactusImage.js.map +1 -0
- package/lib/module/native/index.js +1 -0
- package/lib/module/native/index.js.map +1 -1
- package/lib/module/specs/CactusImage.nitro.js +4 -0
- package/lib/module/specs/CactusImage.nitro.js.map +1 -0
- package/lib/module/telemetry/Telemetry.js +53 -1
- package/lib/module/telemetry/Telemetry.js.map +1 -1
- package/lib/module/types/CactusSTT.js +2 -0
- package/lib/module/types/CactusSTT.js.map +1 -0
- package/lib/typescript/src/api/Database.d.ts +1 -0
- package/lib/typescript/src/api/Database.d.ts.map +1 -1
- package/lib/typescript/src/api/RemoteLM.d.ts +14 -0
- package/lib/typescript/src/api/RemoteLM.d.ts.map +1 -0
- package/lib/typescript/src/classes/CactusLM.d.ts +6 -4
- package/lib/typescript/src/classes/CactusLM.d.ts.map +1 -1
- package/lib/typescript/src/classes/CactusSTT.d.ts +25 -0
- package/lib/typescript/src/classes/CactusSTT.d.ts.map +1 -0
- package/lib/typescript/src/config/CactusConfig.d.ts +1 -0
- package/lib/typescript/src/config/CactusConfig.d.ts.map +1 -1
- package/lib/typescript/src/constants/packageVersion.d.ts +1 -1
- package/lib/typescript/src/hooks/useCactusLM.d.ts +4 -3
- package/lib/typescript/src/hooks/useCactusLM.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useCactusSTT.d.ts +20 -0
- package/lib/typescript/src/hooks/useCactusSTT.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native/Cactus.d.ts +9 -2
- package/lib/typescript/src/native/Cactus.d.ts.map +1 -1
- package/lib/typescript/src/native/CactusFileSystem.d.ts +1 -1
- package/lib/typescript/src/native/CactusFileSystem.d.ts.map +1 -1
- package/lib/typescript/src/native/CactusImage.d.ts +6 -0
- package/lib/typescript/src/native/CactusImage.d.ts.map +1 -0
- package/lib/typescript/src/native/index.d.ts +1 -0
- package/lib/typescript/src/native/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/Cactus.nitro.d.ts +3 -0
- package/lib/typescript/src/specs/Cactus.nitro.d.ts.map +1 -1
- package/lib/typescript/src/specs/CactusImage.nitro.d.ts +9 -0
- package/lib/typescript/src/specs/CactusImage.nitro.d.ts.map +1 -0
- package/lib/typescript/src/telemetry/Telemetry.d.ts +5 -1
- package/lib/typescript/src/telemetry/Telemetry.d.ts.map +1 -1
- package/lib/typescript/src/types/CactusLM.d.ts +8 -5
- package/lib/typescript/src/types/CactusLM.d.ts.map +1 -1
- package/lib/typescript/src/types/CactusSTT.d.ts +37 -0
- package/lib/typescript/src/types/CactusSTT.d.ts.map +1 -0
- package/nitro.json +4 -0
- package/nitrogen/generated/android/c++/JHybridCactusImageSpec.cpp +81 -0
- package/nitrogen/generated/android/c++/JHybridCactusImageSpec.hpp +66 -0
- package/nitrogen/generated/android/cactus+autolinking.cmake +2 -0
- package/nitrogen/generated/android/cactusOnLoad.cpp +10 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusImageSpec.kt +62 -0
- package/nitrogen/generated/ios/Cactus-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/Cactus-Swift-Cxx-Bridge.hpp +17 -0
- package/nitrogen/generated/ios/Cactus-Swift-Cxx-Umbrella.hpp +5 -0
- package/nitrogen/generated/ios/CactusAutolinking.mm +8 -0
- package/nitrogen/generated/ios/CactusAutolinking.swift +15 -0
- package/nitrogen/generated/ios/c++/HybridCactusImageSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridCactusImageSpecSwift.hpp +85 -0
- package/nitrogen/generated/ios/swift/HybridCactusImageSpec.swift +58 -0
- package/nitrogen/generated/ios/swift/HybridCactusImageSpec_cxx.swift +158 -0
- package/nitrogen/generated/shared/c++/HybridCactusImageSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridCactusImageSpec.hpp +64 -0
- package/nitrogen/generated/shared/c++/HybridCactusSpec.cpp +3 -0
- package/nitrogen/generated/shared/c++/HybridCactusSpec.hpp +3 -0
- package/package.json +1 -1
- package/src/api/Database.ts +27 -0
- package/src/api/RemoteLM.ts +273 -0
- package/src/classes/CactusLM.ts +72 -38
- package/src/classes/CactusSTT.ts +182 -0
- package/src/config/CactusConfig.ts +4 -0
- package/src/constants/packageVersion.ts +1 -1
- package/src/hooks/useCactusLM.ts +45 -17
- package/src/hooks/useCactusSTT.ts +285 -0
- package/src/index.tsx +14 -2
- package/src/native/Cactus.ts +94 -4
- package/src/native/CactusFileSystem.ts +2 -2
- package/src/native/CactusImage.ts +20 -0
- package/src/native/index.ts +1 -0
- package/src/specs/Cactus.nitro.ts +9 -0
- package/src/specs/CactusImage.nitro.ts +12 -0
- package/src/telemetry/Telemetry.ts +78 -1
- package/src/types/CactusLM.ts +9 -5
- package/src/types/CactusSTT.ts +42 -0
package/README.md
CHANGED
|
@@ -185,7 +185,6 @@ import { CactusLM, type Message, type Tool } from 'cactus-react-native';
|
|
|
185
185
|
|
|
186
186
|
const tools: Tool[] = [
|
|
187
187
|
{
|
|
188
|
-
type: 'function',
|
|
189
188
|
name: 'get_weather',
|
|
190
189
|
description: 'Get current weather for a location',
|
|
191
190
|
parameters: {
|
|
@@ -219,7 +218,6 @@ import { useCactusLM, type Message, type Tool } from 'cactus-react-native';
|
|
|
219
218
|
|
|
220
219
|
const tools: Tool[] = [
|
|
221
220
|
{
|
|
222
|
-
type: 'function',
|
|
223
221
|
name: 'get_weather',
|
|
224
222
|
description: 'Get current weather for a location',
|
|
225
223
|
parameters: {
|
|
@@ -302,9 +300,11 @@ const App = () => {
|
|
|
302
300
|
|
|
303
301
|
### Embedding
|
|
304
302
|
|
|
305
|
-
Convert text into numerical vector representations that capture semantic meaning, useful for similarity search and semantic understanding.
|
|
303
|
+
Convert text and images into numerical vector representations that capture semantic meaning, useful for similarity search and semantic understanding.
|
|
306
304
|
|
|
307
|
-
####
|
|
305
|
+
#### Text Embedding
|
|
306
|
+
|
|
307
|
+
##### Class
|
|
308
308
|
|
|
309
309
|
```typescript
|
|
310
310
|
import { CactusLM } from 'cactus-react-native';
|
|
@@ -316,7 +316,7 @@ console.log('Embedding vector:', result.embedding);
|
|
|
316
316
|
console.log('Embedding vector length:', result.embedding.length);
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
-
|
|
319
|
+
##### Hook
|
|
320
320
|
|
|
321
321
|
```tsx
|
|
322
322
|
import { useCactusLM } from 'cactus-react-native';
|
|
@@ -334,6 +334,179 @@ const App = () => {
|
|
|
334
334
|
};
|
|
335
335
|
```
|
|
336
336
|
|
|
337
|
+
#### Image Embedding
|
|
338
|
+
|
|
339
|
+
##### Class
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
import { CactusLM } from 'cactus-react-native';
|
|
343
|
+
|
|
344
|
+
const cactusLM = new CactusLM({ model: 'lfm2-vl-450m' });
|
|
345
|
+
|
|
346
|
+
const result = await cactusLM.imageEmbed({ imagePath: 'path/to/your/image.jpg' });
|
|
347
|
+
console.log('Image embedding vector:', result.embedding);
|
|
348
|
+
console.log('Embedding vector length:', result.embedding.length);
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
##### Hook
|
|
352
|
+
|
|
353
|
+
```tsx
|
|
354
|
+
import { useCactusLM } from 'cactus-react-native';
|
|
355
|
+
|
|
356
|
+
const App = () => {
|
|
357
|
+
const cactusLM = useCactusLM({ model: 'lfm2-vl-450m' });
|
|
358
|
+
|
|
359
|
+
const handleImageEmbed = async () => {
|
|
360
|
+
const result = await cactusLM.imageEmbed({ imagePath: 'path/to/your/image.jpg' });
|
|
361
|
+
console.log('Image embedding vector:', result.embedding);
|
|
362
|
+
console.log('Embedding vector length:', result.embedding.length);
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
return <Button title="Embed Image" onPress={handleImageEmbed} />;
|
|
366
|
+
};
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Hybrid Mode (Cloud Fallback)
|
|
370
|
+
|
|
371
|
+
The CactusLM supports a hybrid completion mode that falls back to a cloud-based LLM provider `OpenRouter` if local inference fails.
|
|
372
|
+
|
|
373
|
+
#### Class
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
import { CactusLM, type Message } from 'cactus-react-native';
|
|
377
|
+
|
|
378
|
+
const cactusLM = new CactusLM();
|
|
379
|
+
|
|
380
|
+
const messages: Message[] = [
|
|
381
|
+
{ role: 'user', content: 'Hello, World!' }
|
|
382
|
+
];
|
|
383
|
+
|
|
384
|
+
// Falls back to remote if local fails
|
|
385
|
+
const result = await cactusLM.complete({
|
|
386
|
+
messages,
|
|
387
|
+
mode: 'hybrid'
|
|
388
|
+
});
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
#### Hook
|
|
392
|
+
|
|
393
|
+
```tsx
|
|
394
|
+
import { useCactusLM, type Message } from 'cactus-react-native';
|
|
395
|
+
|
|
396
|
+
const App = () => {
|
|
397
|
+
const cactusLM = useCactusLM();
|
|
398
|
+
|
|
399
|
+
const handleComplete = async () => {
|
|
400
|
+
const messages: Message[] = [
|
|
401
|
+
{ role: 'user', content: 'Hello, World!' }
|
|
402
|
+
];
|
|
403
|
+
|
|
404
|
+
// Falls back to remote if local fails
|
|
405
|
+
await cactusLM.complete({
|
|
406
|
+
messages,
|
|
407
|
+
mode: 'hybrid'
|
|
408
|
+
});
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
return (
|
|
412
|
+
<>
|
|
413
|
+
<Button title="Complete" onPress={handleComplete} />
|
|
414
|
+
<Text>{cactusLM.completion}</Text>
|
|
415
|
+
</>
|
|
416
|
+
);
|
|
417
|
+
};
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Speech-to-Text (STT)
|
|
421
|
+
|
|
422
|
+
The `CactusSTT` class provides audio transcription and audio embedding capabilities using Whisper models.
|
|
423
|
+
|
|
424
|
+
### Transcription
|
|
425
|
+
|
|
426
|
+
Transcribe audio files to text with streaming support.
|
|
427
|
+
|
|
428
|
+
#### Class
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
import { CactusSTT } from 'cactus-react-native';
|
|
432
|
+
|
|
433
|
+
const cactusSTT = new CactusSTT({ model: 'whisper-small' });
|
|
434
|
+
|
|
435
|
+
await cactusSTT.init();
|
|
436
|
+
|
|
437
|
+
const result = await cactusSTT.transcribe({
|
|
438
|
+
audioFilePath: 'path/to/audio.wav',
|
|
439
|
+
onToken: (token) => console.log('Token:', token)
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
console.log('Transcription:', result.response);
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
#### Hook
|
|
446
|
+
|
|
447
|
+
```tsx
|
|
448
|
+
import { useCactusSTT } from 'cactus-react-native';
|
|
449
|
+
|
|
450
|
+
const App = () => {
|
|
451
|
+
const cactusSTT = useCactusSTT({ model: 'whisper-small' });
|
|
452
|
+
|
|
453
|
+
const handleTranscribe = async () => {
|
|
454
|
+
const result = await cactusSTT.transcribe({
|
|
455
|
+
audioFilePath: 'path/to/audio.wav',
|
|
456
|
+
});
|
|
457
|
+
console.log('Transcription:', result.response);
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
return (
|
|
461
|
+
<>
|
|
462
|
+
<Button onPress={handleTranscribe} title="Transcribe" />
|
|
463
|
+
<Text>{cactusSTT.response}</Text>
|
|
464
|
+
</>
|
|
465
|
+
);
|
|
466
|
+
};
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Audio Embedding
|
|
470
|
+
|
|
471
|
+
Generate embeddings from audio files for audio understanding.
|
|
472
|
+
|
|
473
|
+
#### Class
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
import { CactusSTT } from 'cactus-react-native';
|
|
477
|
+
|
|
478
|
+
const cactusSTT = new CactusSTT();
|
|
479
|
+
|
|
480
|
+
await cactusSTT.init();
|
|
481
|
+
|
|
482
|
+
const result = await cactusSTT.audioEmbed({
|
|
483
|
+
audioPath: 'path/to/audio.wav'
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
console.log('Audio embedding vector:', result.embedding);
|
|
487
|
+
console.log('Embedding vector length:', result.embedding.length);
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
#### Hook
|
|
491
|
+
|
|
492
|
+
```tsx
|
|
493
|
+
import { useCactusSTT } from 'cactus-react-native';
|
|
494
|
+
|
|
495
|
+
const App = () => {
|
|
496
|
+
const cactusSTT = useCactusSTT();
|
|
497
|
+
|
|
498
|
+
const handleAudioEmbed = async () => {
|
|
499
|
+
const result = await cactusSTT.audioEmbed({
|
|
500
|
+
audioPath: 'path/to/audio.wav'
|
|
501
|
+
});
|
|
502
|
+
console.log('Audio embedding vector:', result.embedding);
|
|
503
|
+
console.log('Embedding vector length:', result.embedding.length);
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
return <Button title="Embed Audio" onPress={handleAudioEmbed} />;
|
|
507
|
+
};
|
|
508
|
+
```
|
|
509
|
+
|
|
337
510
|
## API Reference
|
|
338
511
|
|
|
339
512
|
### CactusLM Class
|
|
@@ -351,14 +524,14 @@ const App = () => {
|
|
|
351
524
|
|
|
352
525
|
**`download(params?: CactusLMDownloadParams): Promise<void>`**
|
|
353
526
|
|
|
354
|
-
Downloads the model. If the model is already downloaded, returns immediately with progress
|
|
527
|
+
Downloads the model. If the model is already downloaded, returns immediately with progress `1`. Throws an error if a download is already in progress.
|
|
355
528
|
|
|
356
529
|
**Parameters:**
|
|
357
530
|
- `onProgress` - Callback for download progress (0-1).
|
|
358
531
|
|
|
359
532
|
**`init(): Promise<void>`**
|
|
360
533
|
|
|
361
|
-
Initializes the model and prepares it for inference. Safe to call multiple times (idempotent). Throws an error if the model is not downloaded yet.
|
|
534
|
+
Initializes the model and prepares it for inference. Safe to call multiple times (idempotent). Throws an error if the model is not downloaded yet.
|
|
362
535
|
|
|
363
536
|
**`complete(params: CactusLMCompleteParams): Promise<CactusLMCompleteResult>`**
|
|
364
537
|
|
|
@@ -374,6 +547,7 @@ Performs text completion with optional streaming and tool support. Automatically
|
|
|
374
547
|
- `stopSequences` - Array of strings to stop generation (default: `undefined`).
|
|
375
548
|
- `tools` - Array of `Tool` objects for function calling (default: `undefined`).
|
|
376
549
|
- `onToken` - Callback for streaming tokens.
|
|
550
|
+
- `mode` - Completion mode: `'local'` | `'hybrid'` (default: `'local'`)
|
|
377
551
|
|
|
378
552
|
**`embed(params: CactusLMEmbedParams): Promise<CactusLMEmbedResult>`**
|
|
379
553
|
|
|
@@ -382,6 +556,13 @@ Generates embeddings for the given text. Automatically calls `init()` if not alr
|
|
|
382
556
|
**Parameters:**
|
|
383
557
|
- `text` - Text to embed.
|
|
384
558
|
|
|
559
|
+
**`imageEmbed(params: CactusLMImageEmbedParams): Promise<CactusLMImageEmbedResult>`**
|
|
560
|
+
|
|
561
|
+
Generates embeddings for the given image. Requires a vision-capable model. Automatically calls `init()` if not already initialized. Throws an error if a generation (completion or embedding) is already in progress.
|
|
562
|
+
|
|
563
|
+
**Parameters:**
|
|
564
|
+
- `imagePath` - Path to the image file.
|
|
565
|
+
|
|
385
566
|
**`stop(): Promise<void>`**
|
|
386
567
|
|
|
387
568
|
Stops ongoing generation.
|
|
@@ -394,12 +575,9 @@ Resets the model's internal state, clearing any cached context. Automatically ca
|
|
|
394
575
|
|
|
395
576
|
Releases all resources associated with the model. Automatically calls `stop()` first. Safe to call even if the model is not initialized.
|
|
396
577
|
|
|
397
|
-
**`getModels(
|
|
398
|
-
|
|
399
|
-
Fetches available models and persists the results locally for caching. Returns cached results if available, unless `forceRefresh` is `true`. Checks the download status for each model and includes it in the results.
|
|
578
|
+
**`getModels(): Promise<CactusModel[]>`**
|
|
400
579
|
|
|
401
|
-
|
|
402
|
-
- `forceRefresh` - If `true`, fetches from the server and updates the local cache (default: `false`).
|
|
580
|
+
Fetches available models from the database and checks their download status. Results are cached in memory after the first call and subsequent calls return the cached results.
|
|
403
581
|
|
|
404
582
|
### useCactusLM Hook
|
|
405
583
|
|
|
@@ -421,10 +599,97 @@ The `useCactusLM` hook manages a `CactusLM` instance with reactive state. When m
|
|
|
421
599
|
- `init(): Promise<void>` - Initializes the model for inference. Sets `isInitializing` to `true` during initialization.
|
|
422
600
|
- `complete(params: CactusLMCompleteParams): Promise<CactusLMCompleteResult>` - Generates text completions. Automatically accumulates tokens in the `completion` state during streaming. Sets `isGenerating` to `true` while generating. Clears `completion` before starting.
|
|
423
601
|
- `embed(params: CactusLMEmbedParams): Promise<CactusLMEmbedResult>` - Generates embeddings for the given text. Sets `isGenerating` to `true` during operation.
|
|
602
|
+
- `imageEmbed(params: CactusLMImageEmbedParams): Promise<CactusLMImageEmbedResult>` - Generates embeddings for the given image. Sets `isGenerating` to `true` while generating.
|
|
424
603
|
- `stop(): Promise<void>` - Stops ongoing generation. Clears any errors.
|
|
425
604
|
- `reset(): Promise<void>` - Resets the model's internal state, clearing cached context. Also clears the `completion` state.
|
|
426
605
|
- `destroy(): Promise<void>` - Releases all resources associated with the model. Clears the `completion` state. Automatically called when the component unmounts.
|
|
427
|
-
- `getModels(
|
|
606
|
+
- `getModels(): Promise<CactusModel[]>` - Fetches available models from the database and checks their download status. Results are cached in memory and reused on subsequent calls.
|
|
607
|
+
|
|
608
|
+
### CactusSTT Class
|
|
609
|
+
|
|
610
|
+
#### Constructor
|
|
611
|
+
|
|
612
|
+
**`new CactusSTT(params?: CactusSTTParams)`**
|
|
613
|
+
|
|
614
|
+
**Parameters:**
|
|
615
|
+
- `model` - Model slug (default: `'whisper-small'`).
|
|
616
|
+
- `contextSize` - Context window size (default: `2048`).
|
|
617
|
+
|
|
618
|
+
#### Methods
|
|
619
|
+
|
|
620
|
+
**`download(params?: CactusSTTDownloadParams): Promise<void>`**
|
|
621
|
+
|
|
622
|
+
Downloads the model. If the model is already downloaded, returns immediately with progress `1`. Throws an error if a download is already in progress.
|
|
623
|
+
|
|
624
|
+
**Parameters:**
|
|
625
|
+
- `onProgress` - Callback for download progress (0-1).
|
|
626
|
+
|
|
627
|
+
**`init(): Promise<void>`**
|
|
628
|
+
|
|
629
|
+
Initializes the model and prepares it for inference. Safe to call multiple times (idempotent). Throws an error if the model is not downloaded yet.
|
|
630
|
+
|
|
631
|
+
**`transcribe(params: CactusSTTTranscribeParams): Promise<CactusSTTTranscribeResult>`**
|
|
632
|
+
|
|
633
|
+
Transcribes audio to text with optional streaming support. Automatically calls `init()` if not already initialized. Throws an error if a generation is already in progress.
|
|
634
|
+
|
|
635
|
+
**Parameters:**
|
|
636
|
+
- `audioFilePath` - Path to the audio file.
|
|
637
|
+
- `prompt` - Optional prompt to guide transcription (default: `'<|startoftranscript|><|en|><|transcribe|><|notimestamps|>'`).
|
|
638
|
+
- `options` - Transcription options:
|
|
639
|
+
- `temperature` - Sampling temperature (default: model-optimized).
|
|
640
|
+
- `topP` - Nucleus sampling threshold (default: model-optimized).
|
|
641
|
+
- `topK` - Top-K sampling limit (default: model-optimized).
|
|
642
|
+
- `maxTokens` - Maximum number of tokens to generate (default: `512`).
|
|
643
|
+
- `stopSequences` - Array of strings to stop generation (default: `undefined`).
|
|
644
|
+
- `onToken` - Callback for streaming tokens.
|
|
645
|
+
|
|
646
|
+
**`audioEmbed(params: CactusSTTAudioEmbedParams): Promise<CactusSTTAudioEmbedResult>`**
|
|
647
|
+
|
|
648
|
+
Generates embeddings for the given audio file. Automatically calls `init()` if not already initialized. Throws an error if a generation is already in progress.
|
|
649
|
+
|
|
650
|
+
**Parameters:**
|
|
651
|
+
- `audioPath` - Path to the audio file.
|
|
652
|
+
|
|
653
|
+
**`stop(): Promise<void>`**
|
|
654
|
+
|
|
655
|
+
Stops ongoing transcription or embedding generation.
|
|
656
|
+
|
|
657
|
+
**`reset(): Promise<void>`**
|
|
658
|
+
|
|
659
|
+
Resets the model's internal state. Automatically calls `stop()` first.
|
|
660
|
+
|
|
661
|
+
**`destroy(): Promise<void>`**
|
|
662
|
+
|
|
663
|
+
Releases all resources associated with the model. Automatically calls `stop()` first. Safe to call even if the model is not initialized.
|
|
664
|
+
|
|
665
|
+
**`getModels(): Promise<CactusModel[]>`**
|
|
666
|
+
|
|
667
|
+
Fetches available models from the database and checks their download status. Results are cached in memory after the first call and subsequent calls return the cached results.
|
|
668
|
+
|
|
669
|
+
### useCactusSTT Hook
|
|
670
|
+
|
|
671
|
+
The `useCactusSTT` hook manages a `CactusSTT` instance with reactive state. When model parameters (`model`, `contextSize`) change, the hook creates a new instance and resets all state. The hook automatically cleans up resources when the component unmounts.
|
|
672
|
+
|
|
673
|
+
#### State
|
|
674
|
+
|
|
675
|
+
- `response: string` - Current transcription text. Automatically accumulated during streaming. Cleared before each new transcription and when calling `reset()` or `destroy()`.
|
|
676
|
+
- `isGenerating: boolean` - Whether the model is currently generating (transcription or embedding). Both operations share this flag.
|
|
677
|
+
- `isInitializing: boolean` - Whether the model is initializing.
|
|
678
|
+
- `isDownloaded: boolean` - Whether the model is downloaded locally. Automatically checked when the hook mounts or model changes.
|
|
679
|
+
- `isDownloading: boolean` - Whether the model is being downloaded.
|
|
680
|
+
- `downloadProgress: number` - Download progress (0-1). Reset to `0` after download completes.
|
|
681
|
+
- `error: string | null` - Last error message from any operation, or `null` if there is no error. Cleared before starting new operations.
|
|
682
|
+
|
|
683
|
+
#### Methods
|
|
684
|
+
|
|
685
|
+
- `download(params?: CactusSTTDownloadParams): Promise<void>` - Downloads the model. Updates `isDownloading` and `downloadProgress` state during download. Sets `isDownloaded` to `true` on success.
|
|
686
|
+
- `init(): Promise<void>` - Initializes the model for inference. Sets `isInitializing` to `true` during initialization.
|
|
687
|
+
- `transcribe(params: CactusSTTTranscribeParams): Promise<CactusSTTTranscribeResult>` - Transcribes audio to text. Automatically accumulates tokens in the `response` state during streaming. Sets `isGenerating` to `true` while generating. Clears `response` before starting.
|
|
688
|
+
- `audioEmbed(params: CactusSTTAudioEmbedParams): Promise<CactusSTTAudioEmbedResult>` - Generates embeddings for the given audio. Sets `isGenerating` to `true` during operation.
|
|
689
|
+
- `stop(): Promise<void>` - Stops ongoing generation. Clears any errors.
|
|
690
|
+
- `reset(): Promise<void>` - Resets the model's internal state. Also clears the `response` state.
|
|
691
|
+
- `destroy(): Promise<void>` - Releases all resources associated with the model. Clears the `response` state. Automatically called when the component unmounts.
|
|
692
|
+
- `getModels(): Promise<CactusModel[]>` - Fetches available models from the database and checks their download status. Results are cached in memory and reused on subsequent calls.
|
|
428
693
|
|
|
429
694
|
## Type Definitions
|
|
430
695
|
|
|
@@ -456,10 +721,10 @@ interface Message {
|
|
|
456
721
|
}
|
|
457
722
|
```
|
|
458
723
|
|
|
459
|
-
###
|
|
724
|
+
### CompleteOptions
|
|
460
725
|
|
|
461
726
|
```typescript
|
|
462
|
-
interface
|
|
727
|
+
interface CompleteOptions {
|
|
463
728
|
temperature?: number;
|
|
464
729
|
topP?: number;
|
|
465
730
|
topK?: number;
|
|
@@ -472,7 +737,6 @@ interface Options {
|
|
|
472
737
|
|
|
473
738
|
```typescript
|
|
474
739
|
interface Tool {
|
|
475
|
-
type: 'function';
|
|
476
740
|
name: string;
|
|
477
741
|
description: string;
|
|
478
742
|
parameters: {
|
|
@@ -493,9 +757,10 @@ interface Tool {
|
|
|
493
757
|
```typescript
|
|
494
758
|
interface CactusLMCompleteParams {
|
|
495
759
|
messages: Message[];
|
|
496
|
-
options?:
|
|
760
|
+
options?: CompleteOptions;
|
|
497
761
|
tools?: Tool[];
|
|
498
762
|
onToken?: (token: string) => void;
|
|
763
|
+
mode?: 'local' | 'hybrid';
|
|
499
764
|
}
|
|
500
765
|
```
|
|
501
766
|
|
|
@@ -534,11 +799,19 @@ interface CactusLMEmbedResult {
|
|
|
534
799
|
}
|
|
535
800
|
```
|
|
536
801
|
|
|
537
|
-
###
|
|
802
|
+
### CactusLMImageEmbedParams
|
|
803
|
+
|
|
804
|
+
```typescript
|
|
805
|
+
interface CactusLMImageEmbedParams {
|
|
806
|
+
imagePath: string;
|
|
807
|
+
}
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
### CactusLMImageEmbedResult
|
|
538
811
|
|
|
539
812
|
```typescript
|
|
540
|
-
interface
|
|
541
|
-
|
|
813
|
+
interface CactusLMImageEmbedResult {
|
|
814
|
+
embedding: number[];
|
|
542
815
|
}
|
|
543
816
|
```
|
|
544
817
|
|
|
@@ -558,6 +831,79 @@ interface CactusModel {
|
|
|
558
831
|
}
|
|
559
832
|
```
|
|
560
833
|
|
|
834
|
+
### CactusSTTParams
|
|
835
|
+
|
|
836
|
+
```typescript
|
|
837
|
+
interface CactusSTTParams {
|
|
838
|
+
model?: string;
|
|
839
|
+
contextSize?: number;
|
|
840
|
+
}
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
### CactusSTTDownloadParams
|
|
844
|
+
|
|
845
|
+
```typescript
|
|
846
|
+
interface CactusSTTDownloadParams {
|
|
847
|
+
onProgress?: (progress: number) => void;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
### TranscribeOptions
|
|
853
|
+
|
|
854
|
+
```ts
|
|
855
|
+
interface TranscribeOptions {
|
|
856
|
+
temperature?: number;
|
|
857
|
+
topP?: number;
|
|
858
|
+
topK?: number;
|
|
859
|
+
maxTokens?: number;
|
|
860
|
+
stopSequences?: string[];
|
|
861
|
+
}
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
### CactusSTTTranscribeParams
|
|
865
|
+
|
|
866
|
+
```typescript
|
|
867
|
+
interface CactusSTTTranscribeParams {
|
|
868
|
+
audioFilePath: string;
|
|
869
|
+
prompt?: string;
|
|
870
|
+
options?: TranscribeOptions;
|
|
871
|
+
onToken?: (token: string) => void;
|
|
872
|
+
}
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
### CactusSTTTranscribeResult
|
|
876
|
+
|
|
877
|
+
```typescript
|
|
878
|
+
interface CactusSTTTranscribeResult {
|
|
879
|
+
success: boolean;
|
|
880
|
+
response: string;
|
|
881
|
+
timeToFirstTokenMs: number;
|
|
882
|
+
totalTimeMs: number;
|
|
883
|
+
tokensPerSecond: number;
|
|
884
|
+
prefillTokens: number;
|
|
885
|
+
decodeTokens: number;
|
|
886
|
+
totalTokens: number;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
### CactusSTTAudioEmbedParams
|
|
892
|
+
|
|
893
|
+
```typescript
|
|
894
|
+
interface CactusSTTAudioEmbedParams {
|
|
895
|
+
audioPath: string;
|
|
896
|
+
}
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
### CactusSTTAudioEmbedResult
|
|
900
|
+
|
|
901
|
+
```typescript
|
|
902
|
+
interface CactusSTTAudioEmbedResult {
|
|
903
|
+
embedding: number[];
|
|
904
|
+
}
|
|
905
|
+
```
|
|
906
|
+
|
|
561
907
|
## Configuration
|
|
562
908
|
|
|
563
909
|
### Telemetry
|
|
@@ -568,12 +914,23 @@ Cactus offers powerful telemetry for all your projects. Create a token on the [C
|
|
|
568
914
|
import { CactusConfig } from 'cactus-react-native';
|
|
569
915
|
|
|
570
916
|
// Enable Telemetry for your project
|
|
571
|
-
CactusConfig.telemetryToken = 'your-token-here';
|
|
917
|
+
CactusConfig.telemetryToken = 'your-telemetry-token-here';
|
|
572
918
|
|
|
573
919
|
// Disable telemetry
|
|
574
920
|
CactusConfig.isTelemetryEnabled = false;
|
|
575
921
|
```
|
|
576
922
|
|
|
923
|
+
### Hybrid Mode
|
|
924
|
+
|
|
925
|
+
Enable cloud fallback.
|
|
926
|
+
|
|
927
|
+
```typescript
|
|
928
|
+
import { CactusConfig } from 'cactus-react-native';
|
|
929
|
+
|
|
930
|
+
// Set your Cactus token for hybrid mode
|
|
931
|
+
CactusConfig.cactusToken = 'your-cactus-token-here';
|
|
932
|
+
```
|
|
933
|
+
|
|
577
934
|
## Performance Tips
|
|
578
935
|
|
|
579
936
|
- **Model Selection** - Choose smaller models for faster inference on mobile devices.
|
|
@@ -7,23 +7,32 @@ import java.util.Locale
|
|
|
7
7
|
import java.util.UUID
|
|
8
8
|
|
|
9
9
|
class HybridCactusCrypto : HybridCactusCryptoSpec() {
|
|
10
|
-
override fun uuidv5(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
+
}
|
|
17
21
|
|
|
18
|
-
val nsBytes =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
val nsBytes =
|
|
23
|
+
ByteBuffer
|
|
24
|
+
.allocate(16)
|
|
25
|
+
.apply {
|
|
26
|
+
putLong(nsUuid.mostSignificantBits)
|
|
27
|
+
putLong(nsUuid.leastSignificantBits)
|
|
28
|
+
}.array()
|
|
22
29
|
val nameBytes = name.toByteArray(Charsets.UTF_8)
|
|
23
30
|
|
|
24
|
-
val sha1 =
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
val sha1 =
|
|
32
|
+
MessageDigest
|
|
33
|
+
.getInstance("SHA-1")
|
|
34
|
+
.apply { update(nsBytes) }
|
|
35
|
+
.digest(nameBytes)
|
|
27
36
|
val uuidBytes = sha1.copyOfRange(0, 16)
|
|
28
37
|
uuidBytes[6] = (uuidBytes[6].toInt() and 0x0F or 0x50).toByte()
|
|
29
38
|
uuidBytes[8] = (uuidBytes[8].toInt() and 0x3F or 0x80).toByte()
|
|
@@ -34,5 +43,4 @@ class HybridCactusCrypto : HybridCactusCryptoSpec() {
|
|
|
34
43
|
|
|
35
44
|
uuid.toString().lowercase(Locale.ROOT)
|
|
36
45
|
}
|
|
37
|
-
}
|
|
38
46
|
}
|
|
@@ -8,17 +8,20 @@ import com.margelo.nitro.core.Promise
|
|
|
8
8
|
class HybridCactusDeviceInfo : HybridCactusDeviceInfoSpec() {
|
|
9
9
|
private val context = NitroModules.applicationContext ?: error("Android context not found")
|
|
10
10
|
|
|
11
|
-
override fun getAppIdentifier(): Promise<String?> {
|
|
12
|
-
return Promise.async { context.packageName }
|
|
13
|
-
}
|
|
11
|
+
override fun getAppIdentifier(): Promise<String?> = Promise.async { context.packageName }
|
|
14
12
|
|
|
15
|
-
override fun getDeviceInfo(): Promise<DeviceInfo>
|
|
16
|
-
|
|
13
|
+
override fun getDeviceInfo(): Promise<DeviceInfo> =
|
|
14
|
+
Promise.async {
|
|
17
15
|
DeviceInfo(
|
|
18
|
-
brand = Build.MANUFACTURER,
|
|
19
|
-
|
|
20
|
-
|
|
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,
|
|
21
25
|
)
|
|
22
26
|
}
|
|
23
|
-
}
|
|
24
27
|
}
|