cactus-react-native 1.4.0 → 1.7.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/Cactus.podspec +1 -1
- package/README.md +465 -174
- package/android/CMakeLists.txt +24 -5
- package/android/src/main/jniLibs/arm64-v8a/libcactus.a +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcurl.a +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libmbedcrypto.a +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libmbedtls.a +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libmbedx509.a +0 -0
- package/cpp/HybridCactus.cpp +157 -6
- package/cpp/HybridCactus.hpp +20 -3
- package/cpp/cactus_ffi.h +65 -30
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus.h +0 -1
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_ffi.h +65 -30
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_utils.h +357 -122
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/engine.h +184 -63
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/gemma_tools.h +549 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/graph.h +153 -27
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/kernel.h +90 -178
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/kernel_utils.h +276 -151
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/cactus +0 -0
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus.h +0 -1
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_ffi.h +65 -30
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_utils.h +357 -122
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/engine.h +184 -63
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/gemma_tools.h +549 -0
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/graph.h +153 -27
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/kernel.h +90 -178
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/kernel_utils.h +276 -151
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/cactus +0 -0
- package/lib/module/classes/CactusLM.js +43 -58
- package/lib/module/classes/CactusLM.js.map +1 -1
- package/lib/module/classes/CactusSTT.js +64 -38
- package/lib/module/classes/CactusSTT.js.map +1 -1
- package/lib/module/classes/CactusVAD.js +95 -0
- package/lib/module/classes/CactusVAD.js.map +1 -0
- package/lib/module/hooks/useCactusLM.js +23 -15
- package/lib/module/hooks/useCactusLM.js.map +1 -1
- package/lib/module/hooks/useCactusSTT.js +85 -28
- package/lib/module/hooks/useCactusSTT.js.map +1 -1
- package/lib/module/hooks/useCactusVAD.js +171 -0
- package/lib/module/hooks/useCactusVAD.js.map +1 -0
- package/lib/module/index.js +2 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/modelRegistry.js +52 -0
- package/lib/module/modelRegistry.js.map +1 -0
- package/lib/module/native/Cactus.js +107 -8
- package/lib/module/native/Cactus.js.map +1 -1
- package/lib/module/native/CactusIndex.js.map +1 -1
- package/lib/module/native/index.js +0 -3
- package/lib/module/native/index.js.map +1 -1
- package/lib/module/types/CactusLM.js +2 -0
- package/lib/module/types/CactusSTT.js +2 -0
- package/lib/module/types/CactusVAD.js +4 -0
- package/lib/module/types/{CactusModel.js.map → CactusVAD.js.map} +1 -1
- package/lib/module/types/common.js +2 -0
- package/lib/module/types/{CactusSTTModel.js.map → common.js.map} +1 -1
- package/lib/typescript/src/classes/CactusLM.d.ts +8 -6
- package/lib/typescript/src/classes/CactusLM.d.ts.map +1 -1
- package/lib/typescript/src/classes/CactusSTT.d.ts +11 -6
- package/lib/typescript/src/classes/CactusSTT.d.ts.map +1 -1
- package/lib/typescript/src/classes/CactusVAD.d.ts +20 -0
- package/lib/typescript/src/classes/CactusVAD.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useCactusLM.d.ts +3 -3
- package/lib/typescript/src/hooks/useCactusLM.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useCactusSTT.d.ts +11 -5
- package/lib/typescript/src/hooks/useCactusSTT.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useCactusVAD.d.ts +15 -0
- package/lib/typescript/src/hooks/useCactusVAD.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +7 -6
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/modelRegistry.d.ts +5 -0
- package/lib/typescript/src/modelRegistry.d.ts.map +1 -0
- package/lib/typescript/src/native/Cactus.d.ts +12 -6
- package/lib/typescript/src/native/Cactus.d.ts.map +1 -1
- package/lib/typescript/src/native/CactusIndex.d.ts +2 -2
- package/lib/typescript/src/native/CactusIndex.d.ts.map +1 -1
- package/lib/typescript/src/native/index.d.ts +0 -3
- package/lib/typescript/src/native/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/Cactus.nitro.d.ts +6 -1
- package/lib/typescript/src/specs/Cactus.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types/CactusIndex.d.ts +2 -2
- package/lib/typescript/src/types/CactusIndex.d.ts.map +1 -1
- package/lib/typescript/src/types/CactusLM.d.ts +19 -9
- package/lib/typescript/src/types/CactusLM.d.ts.map +1 -1
- package/lib/typescript/src/types/CactusSTT.d.ts +45 -4
- package/lib/typescript/src/types/CactusSTT.d.ts.map +1 -1
- package/lib/typescript/src/types/CactusVAD.d.ts +34 -0
- package/lib/typescript/src/types/CactusVAD.d.ts.map +1 -0
- package/lib/typescript/src/types/common.d.ts +23 -0
- package/lib/typescript/src/types/common.d.ts.map +1 -0
- package/nitro.json +0 -11
- package/nitrogen/generated/android/cactus+autolinking.cmake +0 -5
- package/nitrogen/generated/android/cactusOnLoad.cpp +0 -30
- package/nitrogen/generated/ios/Cactus-Swift-Cxx-Bridge.cpp +0 -50
- package/nitrogen/generated/ios/Cactus-Swift-Cxx-Bridge.hpp +9 -147
- package/nitrogen/generated/ios/Cactus-Swift-Cxx-Umbrella.hpp +0 -13
- package/nitrogen/generated/ios/CactusAutolinking.mm +0 -26
- package/nitrogen/generated/ios/CactusAutolinking.swift +0 -30
- package/nitrogen/generated/shared/c++/HybridCactusSpec.cpp +5 -0
- package/nitrogen/generated/shared/c++/HybridCactusSpec.hpp +6 -1
- package/package.json +3 -3
- package/src/classes/CactusLM.ts +59 -74
- package/src/classes/CactusSTT.ts +92 -49
- package/src/classes/CactusVAD.ts +129 -0
- package/src/hooks/useCactusLM.ts +26 -9
- package/src/hooks/useCactusSTT.ts +105 -44
- package/src/hooks/useCactusVAD.ts +215 -0
- package/src/index.tsx +20 -10
- package/src/modelRegistry.ts +65 -0
- package/src/native/Cactus.ts +130 -14
- package/src/native/CactusIndex.ts +2 -2
- package/src/native/index.ts +0 -3
- package/src/specs/Cactus.nitro.ts +11 -2
- package/src/types/CactusIndex.ts +2 -2
- package/src/types/CactusLM.ts +20 -9
- package/src/types/CactusSTT.ts +50 -4
- package/src/types/CactusVAD.ts +39 -0
- package/src/types/common.ts +23 -0
- package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusCrypto.kt +0 -46
- package/android/src/main/java/com/margelo/nitro/cactus/HybridCactusDeviceInfo.kt +0 -27
- package/android/src/main/jniLibs/arm64-v8a/libcactus_util.a +0 -0
- package/cpp/HybridCactusUtil.cpp +0 -47
- package/cpp/HybridCactusUtil.hpp +0 -27
- package/cpp/cactus_util.h +0 -25
- package/ios/HybridCactusCrypto.swift +0 -37
- package/ios/HybridCactusDeviceInfo.swift +0 -32
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_telemetry.h +0 -656
- package/ios/cactus.xcframework/ios-arm64-simulator/cactus.framework/Headers/cactus_telemetry.h +0 -656
- package/ios/cactus_util.xcframework/Info.plist +0 -39
- package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/cactus_util.h +0 -25
- package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/database.h +0 -27
- package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/ios_utils.h +0 -10
- package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Headers/logging.h +0 -25
- package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/Info.plist +0 -0
- package/ios/cactus_util.xcframework/ios-arm64/cactus_util.framework/cactus_util +0 -0
- package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/cactus_util.h +0 -25
- package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/database.h +0 -27
- package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/ios_utils.h +0 -10
- package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Headers/logging.h +0 -25
- package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/Info.plist +0 -0
- package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/_CodeSignature/CodeResources +0 -135
- package/ios/cactus_util.xcframework/ios-arm64-simulator/cactus_util.framework/cactus_util +0 -0
- package/lib/module/api/Database.js +0 -137
- package/lib/module/api/Database.js.map +0 -1
- package/lib/module/api/RemoteLM.js +0 -201
- package/lib/module/api/RemoteLM.js.map +0 -1
- package/lib/module/config/CactusConfig.js +0 -12
- package/lib/module/config/CactusConfig.js.map +0 -1
- package/lib/module/native/CactusCrypto.js +0 -10
- package/lib/module/native/CactusCrypto.js.map +0 -1
- package/lib/module/native/CactusDeviceInfo.js +0 -13
- package/lib/module/native/CactusDeviceInfo.js.map +0 -1
- package/lib/module/native/CactusUtil.js +0 -36
- package/lib/module/native/CactusUtil.js.map +0 -1
- package/lib/module/specs/CactusCrypto.nitro.js +0 -4
- package/lib/module/specs/CactusCrypto.nitro.js.map +0 -1
- package/lib/module/specs/CactusDeviceInfo.nitro.js +0 -4
- package/lib/module/specs/CactusDeviceInfo.nitro.js.map +0 -1
- package/lib/module/specs/CactusUtil.nitro.js +0 -4
- package/lib/module/specs/CactusUtil.nitro.js.map +0 -1
- package/lib/module/telemetry/Telemetry.js +0 -154
- package/lib/module/telemetry/Telemetry.js.map +0 -1
- package/lib/module/types/CactusModel.js +0 -2
- package/lib/module/types/CactusSTTModel.js +0 -2
- package/lib/typescript/src/api/Database.d.ts +0 -18
- package/lib/typescript/src/api/Database.d.ts.map +0 -1
- package/lib/typescript/src/api/RemoteLM.d.ts +0 -14
- package/lib/typescript/src/api/RemoteLM.d.ts.map +0 -1
- package/lib/typescript/src/config/CactusConfig.d.ts +0 -7
- package/lib/typescript/src/config/CactusConfig.d.ts.map +0 -1
- package/lib/typescript/src/native/CactusCrypto.d.ts +0 -5
- package/lib/typescript/src/native/CactusCrypto.d.ts.map +0 -1
- package/lib/typescript/src/native/CactusDeviceInfo.d.ts +0 -7
- package/lib/typescript/src/native/CactusDeviceInfo.d.ts.map +0 -1
- package/lib/typescript/src/native/CactusUtil.d.ts +0 -6
- package/lib/typescript/src/native/CactusUtil.d.ts.map +0 -1
- package/lib/typescript/src/specs/CactusCrypto.nitro.d.ts +0 -8
- package/lib/typescript/src/specs/CactusCrypto.nitro.d.ts.map +0 -1
- package/lib/typescript/src/specs/CactusDeviceInfo.nitro.d.ts +0 -16
- package/lib/typescript/src/specs/CactusDeviceInfo.nitro.d.ts.map +0 -1
- package/lib/typescript/src/specs/CactusUtil.nitro.d.ts +0 -10
- package/lib/typescript/src/specs/CactusUtil.nitro.d.ts.map +0 -1
- package/lib/typescript/src/telemetry/Telemetry.d.ts +0 -34
- package/lib/typescript/src/telemetry/Telemetry.d.ts.map +0 -1
- package/lib/typescript/src/types/CactusModel.d.ts +0 -13
- package/lib/typescript/src/types/CactusModel.d.ts.map +0 -1
- package/lib/typescript/src/types/CactusSTTModel.d.ts +0 -8
- package/lib/typescript/src/types/CactusSTTModel.d.ts.map +0 -1
- package/nitrogen/generated/android/c++/JDeviceInfo.hpp +0 -74
- package/nitrogen/generated/android/c++/JHybridCactusCryptoSpec.cpp +0 -65
- package/nitrogen/generated/android/c++/JHybridCactusCryptoSpec.hpp +0 -65
- package/nitrogen/generated/android/c++/JHybridCactusDeviceInfoSpec.cpp +0 -85
- package/nitrogen/generated/android/c++/JHybridCactusDeviceInfoSpec.hpp +0 -66
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/DeviceInfo.kt +0 -50
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusCryptoSpec.kt +0 -58
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/cactus/HybridCactusDeviceInfoSpec.kt +0 -62
- package/nitrogen/generated/ios/c++/HybridCactusCryptoSpecSwift.cpp +0 -11
- package/nitrogen/generated/ios/c++/HybridCactusCryptoSpecSwift.hpp +0 -77
- package/nitrogen/generated/ios/c++/HybridCactusDeviceInfoSpecSwift.cpp +0 -11
- package/nitrogen/generated/ios/c++/HybridCactusDeviceInfoSpecSwift.hpp +0 -88
- package/nitrogen/generated/ios/swift/DeviceInfo.swift +0 -98
- package/nitrogen/generated/ios/swift/Func_void_DeviceInfo.swift +0 -47
- package/nitrogen/generated/ios/swift/Func_void_std__optional_std__string_.swift +0 -54
- package/nitrogen/generated/ios/swift/HybridCactusCryptoSpec.swift +0 -57
- package/nitrogen/generated/ios/swift/HybridCactusCryptoSpec_cxx.swift +0 -139
- package/nitrogen/generated/ios/swift/HybridCactusDeviceInfoSpec.swift +0 -58
- package/nitrogen/generated/ios/swift/HybridCactusDeviceInfoSpec_cxx.swift +0 -164
- package/nitrogen/generated/shared/c++/DeviceInfo.hpp +0 -92
- package/nitrogen/generated/shared/c++/HybridCactusCryptoSpec.cpp +0 -21
- package/nitrogen/generated/shared/c++/HybridCactusCryptoSpec.hpp +0 -63
- package/nitrogen/generated/shared/c++/HybridCactusDeviceInfoSpec.cpp +0 -22
- package/nitrogen/generated/shared/c++/HybridCactusDeviceInfoSpec.hpp +0 -67
- package/nitrogen/generated/shared/c++/HybridCactusUtilSpec.cpp +0 -23
- package/nitrogen/generated/shared/c++/HybridCactusUtilSpec.hpp +0 -66
- package/src/api/Database.ts +0 -188
- package/src/api/RemoteLM.ts +0 -273
- package/src/config/CactusConfig.ts +0 -11
- package/src/native/CactusCrypto.ts +0 -11
- package/src/native/CactusDeviceInfo.ts +0 -18
- package/src/native/CactusUtil.ts +0 -43
- package/src/specs/CactusCrypto.nitro.ts +0 -6
- package/src/specs/CactusDeviceInfo.nitro.ts +0 -15
- package/src/specs/CactusUtil.nitro.ts +0 -8
- package/src/telemetry/Telemetry.ts +0 -236
- package/src/types/CactusModel.ts +0 -15
- package/src/types/CactusSTTModel.ts +0 -10
package/src/classes/CactusSTT.ts
CHANGED
|
@@ -6,37 +6,47 @@ import type {
|
|
|
6
6
|
CactusSTTParams,
|
|
7
7
|
CactusSTTAudioEmbedParams,
|
|
8
8
|
CactusSTTAudioEmbedResult,
|
|
9
|
+
CactusSTTStreamTranscribeStartOptions,
|
|
10
|
+
CactusSTTStreamTranscribeProcessParams,
|
|
11
|
+
CactusSTTStreamTranscribeProcessResult,
|
|
12
|
+
CactusSTTStreamTranscribeStopResult,
|
|
9
13
|
} from '../types/CactusSTT';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { Database } from '../api/Database';
|
|
13
|
-
import { getErrorMessage } from '../utils/error';
|
|
14
|
-
import type { CactusSTTModel } from '../types/CactusSTTModel';
|
|
14
|
+
import { getRegistry } from '../modelRegistry';
|
|
15
|
+
import type { CactusModel } from '../types/common';
|
|
15
16
|
|
|
16
17
|
export class CactusSTT {
|
|
17
18
|
private readonly cactus = new Cactus();
|
|
18
19
|
|
|
19
20
|
private readonly model: string;
|
|
20
|
-
private readonly
|
|
21
|
+
private readonly options: {
|
|
22
|
+
quantization: 'int4' | 'int8';
|
|
23
|
+
pro: boolean;
|
|
24
|
+
};
|
|
21
25
|
|
|
22
26
|
private isDownloading = false;
|
|
23
27
|
private isInitialized = false;
|
|
24
28
|
private isGenerating = false;
|
|
29
|
+
private isStreamTranscribing = false;
|
|
25
30
|
|
|
26
31
|
private static readonly defaultModel = 'whisper-small';
|
|
27
|
-
private static readonly
|
|
32
|
+
private static readonly defaultOptions = {
|
|
33
|
+
quantization: 'int8' as const,
|
|
34
|
+
pro: false,
|
|
35
|
+
};
|
|
28
36
|
private static readonly defaultPrompt =
|
|
29
37
|
'<|startoftranscript|><|en|><|transcribe|><|notimestamps|>';
|
|
30
38
|
private static readonly defaultTranscribeOptions = {
|
|
31
|
-
maxTokens:
|
|
39
|
+
maxTokens: 384,
|
|
32
40
|
};
|
|
33
41
|
private static readonly defaultEmbedBufferSize = 4096;
|
|
34
42
|
|
|
35
|
-
constructor({ model,
|
|
36
|
-
Telemetry.init(CactusConfig.telemetryToken);
|
|
37
|
-
|
|
43
|
+
constructor({ model, options }: CactusSTTParams = {}) {
|
|
38
44
|
this.model = model ?? CactusSTT.defaultModel;
|
|
39
|
-
this.
|
|
45
|
+
this.options = {
|
|
46
|
+
quantization:
|
|
47
|
+
options?.quantization ?? CactusSTT.defaultOptions.quantization,
|
|
48
|
+
pro: options?.pro ?? CactusSTT.defaultOptions.pro,
|
|
49
|
+
};
|
|
40
50
|
}
|
|
41
51
|
|
|
42
52
|
public async download({
|
|
@@ -51,17 +61,26 @@ export class CactusSTT {
|
|
|
51
61
|
throw new Error('CactusSTT is already downloading');
|
|
52
62
|
}
|
|
53
63
|
|
|
54
|
-
if (await CactusFileSystem.modelExists(this.
|
|
64
|
+
if (await CactusFileSystem.modelExists(this.getModelName())) {
|
|
65
|
+
console.log('Model already exists', this.getModelName());
|
|
55
66
|
onProgress?.(1.0);
|
|
56
67
|
return;
|
|
57
68
|
}
|
|
58
69
|
|
|
59
70
|
this.isDownloading = true;
|
|
60
71
|
try {
|
|
61
|
-
const
|
|
72
|
+
const registry = await getRegistry();
|
|
73
|
+
const modelConfig =
|
|
74
|
+
registry[this.model]?.quantization[this.options.quantization];
|
|
75
|
+
const url = this.options.pro ? modelConfig?.pro?.apple : modelConfig?.url;
|
|
76
|
+
|
|
77
|
+
if (!url) {
|
|
78
|
+
throw new Error(`Model ${this.model} with specified options not found`);
|
|
79
|
+
}
|
|
80
|
+
|
|
62
81
|
await CactusFileSystem.downloadModel(
|
|
63
|
-
this.
|
|
64
|
-
|
|
82
|
+
this.getModelName(),
|
|
83
|
+
url,
|
|
65
84
|
onProgress
|
|
66
85
|
);
|
|
67
86
|
} finally {
|
|
@@ -78,20 +97,19 @@ export class CactusSTT {
|
|
|
78
97
|
if (this.isModelPath(this.model)) {
|
|
79
98
|
modelPath = this.model.replace('file://', '');
|
|
80
99
|
} else {
|
|
81
|
-
if (!(await CactusFileSystem.modelExists(this.
|
|
82
|
-
|
|
100
|
+
if (!(await CactusFileSystem.modelExists(this.getModelName()))) {
|
|
101
|
+
console.log('Model does not exist', this.getModelName());
|
|
102
|
+
throw new Error(
|
|
103
|
+
`Model "${this.model}" with options ${JSON.stringify(this.options)} is not downloaded`
|
|
104
|
+
);
|
|
83
105
|
}
|
|
84
|
-
modelPath = await CactusFileSystem.getModelPath(this.
|
|
106
|
+
modelPath = await CactusFileSystem.getModelPath(this.getModelName());
|
|
85
107
|
}
|
|
86
108
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
} catch (error) {
|
|
92
|
-
Telemetry.logInit(this.model, false, getErrorMessage(error));
|
|
93
|
-
throw error;
|
|
94
|
-
}
|
|
109
|
+
const cacheDir = await CactusFileSystem.getCactusDirectory();
|
|
110
|
+
await this.cactus.setTelemetryEnvironment(cacheDir);
|
|
111
|
+
await this.cactus.init(modelPath);
|
|
112
|
+
this.isInitialized = true;
|
|
95
113
|
}
|
|
96
114
|
|
|
97
115
|
public async transcribe({
|
|
@@ -115,28 +133,52 @@ export class CactusSTT {
|
|
|
115
133
|
|
|
116
134
|
this.isGenerating = true;
|
|
117
135
|
try {
|
|
118
|
-
|
|
136
|
+
return await this.cactus.transcribe(
|
|
119
137
|
audio,
|
|
120
138
|
prompt,
|
|
121
139
|
responseBufferSize,
|
|
122
140
|
options,
|
|
123
141
|
onToken
|
|
124
142
|
);
|
|
125
|
-
Telemetry.logTranscribe(
|
|
126
|
-
this.model,
|
|
127
|
-
result.success,
|
|
128
|
-
result.success ? undefined : result.response,
|
|
129
|
-
result
|
|
130
|
-
);
|
|
131
|
-
return result;
|
|
132
|
-
} catch (error) {
|
|
133
|
-
Telemetry.logTranscribe(this.model, false, getErrorMessage(error));
|
|
134
|
-
throw error;
|
|
135
143
|
} finally {
|
|
136
144
|
this.isGenerating = false;
|
|
137
145
|
}
|
|
138
146
|
}
|
|
139
147
|
|
|
148
|
+
public async streamTranscribeStart(
|
|
149
|
+
options?: CactusSTTStreamTranscribeStartOptions
|
|
150
|
+
): Promise<void> {
|
|
151
|
+
if (this.isStreamTranscribing) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
await this.init();
|
|
156
|
+
await this.cactus.streamTranscribeStart(options);
|
|
157
|
+
this.isStreamTranscribing = true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public async streamTranscribeProcess({
|
|
161
|
+
audio,
|
|
162
|
+
}: CactusSTTStreamTranscribeProcessParams): Promise<CactusSTTStreamTranscribeProcessResult> {
|
|
163
|
+
if (!this.isStreamTranscribing) {
|
|
164
|
+
throw new Error('CactusSTT stream transcribe is not started');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return this.cactus.streamTranscribeProcess(audio);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
public async streamTranscribeStop(): Promise<CactusSTTStreamTranscribeStopResult> {
|
|
171
|
+
if (!this.isStreamTranscribing) {
|
|
172
|
+
throw new Error('CactusSTT stream transcribe is not started');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
return await this.cactus.streamTranscribeStop();
|
|
177
|
+
} finally {
|
|
178
|
+
this.isStreamTranscribing = false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
140
182
|
public async audioEmbed({
|
|
141
183
|
audioPath,
|
|
142
184
|
}: CactusSTTAudioEmbedParams): Promise<CactusSTTAudioEmbedResult> {
|
|
@@ -152,11 +194,7 @@ export class CactusSTT {
|
|
|
152
194
|
audioPath,
|
|
153
195
|
CactusSTT.defaultEmbedBufferSize
|
|
154
196
|
);
|
|
155
|
-
Telemetry.logAudioEmbedding(this.model, true);
|
|
156
197
|
return { embedding };
|
|
157
|
-
} catch (error) {
|
|
158
|
-
Telemetry.logAudioEmbedding(this.model, false, getErrorMessage(error));
|
|
159
|
-
throw error;
|
|
160
198
|
} finally {
|
|
161
199
|
this.isGenerating = false;
|
|
162
200
|
}
|
|
@@ -177,20 +215,25 @@ export class CactusSTT {
|
|
|
177
215
|
}
|
|
178
216
|
|
|
179
217
|
await this.stop();
|
|
180
|
-
await this.cactus.destroy();
|
|
181
218
|
|
|
219
|
+
if (this.isStreamTranscribing) {
|
|
220
|
+
await this.cactus.streamTranscribeStop().catch(() => {});
|
|
221
|
+
this.isStreamTranscribing = false;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
await this.cactus.destroy();
|
|
182
225
|
this.isInitialized = false;
|
|
183
226
|
}
|
|
184
227
|
|
|
185
|
-
public async getModels(): Promise<
|
|
186
|
-
|
|
187
|
-
for (const model of models) {
|
|
188
|
-
model.isDownloaded = await CactusFileSystem.modelExists(model.slug);
|
|
189
|
-
}
|
|
190
|
-
return models;
|
|
228
|
+
public async getModels(): Promise<CactusModel[]> {
|
|
229
|
+
return Object.values(await getRegistry());
|
|
191
230
|
}
|
|
192
231
|
|
|
193
232
|
private isModelPath(model: string): boolean {
|
|
194
233
|
return model.startsWith('file://') || model.startsWith('/');
|
|
195
234
|
}
|
|
235
|
+
|
|
236
|
+
public getModelName(): string {
|
|
237
|
+
return `${this.model}-${this.options.quantization}${this.options.pro ? '-pro' : ''}`;
|
|
238
|
+
}
|
|
196
239
|
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Cactus, CactusFileSystem } from '../native';
|
|
2
|
+
import type {
|
|
3
|
+
CactusVADParams,
|
|
4
|
+
CactusVADDownloadParams,
|
|
5
|
+
CactusVADVadParams,
|
|
6
|
+
CactusVADResult,
|
|
7
|
+
} from '../types/CactusVAD';
|
|
8
|
+
import { getRegistry } from '../modelRegistry';
|
|
9
|
+
import type { CactusModel } from '../types/common';
|
|
10
|
+
|
|
11
|
+
export class CactusVAD {
|
|
12
|
+
private readonly cactus = new Cactus();
|
|
13
|
+
|
|
14
|
+
private readonly model: string;
|
|
15
|
+
private readonly options: {
|
|
16
|
+
quantization: 'int4' | 'int8';
|
|
17
|
+
pro: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
private isDownloading = false;
|
|
21
|
+
private isInitialized = false;
|
|
22
|
+
|
|
23
|
+
private static readonly defaultModel = 'silero-vad';
|
|
24
|
+
private static readonly defaultOptions = {
|
|
25
|
+
quantization: 'int8' as const,
|
|
26
|
+
pro: false,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
constructor({ model, options }: CactusVADParams = {}) {
|
|
30
|
+
this.model = model ?? CactusVAD.defaultModel;
|
|
31
|
+
this.options = {
|
|
32
|
+
quantization:
|
|
33
|
+
options?.quantization ?? CactusVAD.defaultOptions.quantization,
|
|
34
|
+
pro: options?.pro ?? CactusVAD.defaultOptions.pro,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public async download({
|
|
39
|
+
onProgress,
|
|
40
|
+
}: CactusVADDownloadParams = {}): Promise<void> {
|
|
41
|
+
if (this.isModelPath(this.model)) {
|
|
42
|
+
onProgress?.(1.0);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (this.isDownloading) {
|
|
47
|
+
throw new Error('CactusVAD is already downloading');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (await CactusFileSystem.modelExists(this.getModelName())) {
|
|
51
|
+
console.log('Model already exists', this.getModelName());
|
|
52
|
+
onProgress?.(1.0);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.isDownloading = true;
|
|
57
|
+
try {
|
|
58
|
+
const registry = await getRegistry();
|
|
59
|
+
const modelConfig =
|
|
60
|
+
registry[this.model]?.quantization[this.options.quantization];
|
|
61
|
+
const url = this.options.pro ? modelConfig?.pro?.apple : modelConfig?.url;
|
|
62
|
+
|
|
63
|
+
if (!url) {
|
|
64
|
+
throw new Error(`Model ${this.model} with specified options not found`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
await CactusFileSystem.downloadModel(
|
|
68
|
+
this.getModelName(),
|
|
69
|
+
url,
|
|
70
|
+
onProgress
|
|
71
|
+
);
|
|
72
|
+
} finally {
|
|
73
|
+
this.isDownloading = false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public async init(): Promise<void> {
|
|
78
|
+
if (this.isInitialized) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let modelPath: string;
|
|
83
|
+
if (this.isModelPath(this.model)) {
|
|
84
|
+
modelPath = this.model.replace('file://', '');
|
|
85
|
+
} else {
|
|
86
|
+
if (!(await CactusFileSystem.modelExists(this.getModelName()))) {
|
|
87
|
+
console.log('Model does not exist', this.getModelName());
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Model "${this.model}" with options ${JSON.stringify(this.options)} is not downloaded`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
modelPath = await CactusFileSystem.getModelPath(this.getModelName());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const cacheDir = await CactusFileSystem.getCactusDirectory();
|
|
96
|
+
await this.cactus.setTelemetryEnvironment(cacheDir);
|
|
97
|
+
await this.cactus.init(modelPath);
|
|
98
|
+
this.isInitialized = true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public async vad({
|
|
102
|
+
audio,
|
|
103
|
+
options,
|
|
104
|
+
}: CactusVADVadParams): Promise<CactusVADResult> {
|
|
105
|
+
await this.init();
|
|
106
|
+
return this.cactus.vad(audio, options);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public async destroy(): Promise<void> {
|
|
110
|
+
if (!this.isInitialized) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
await this.cactus.destroy();
|
|
115
|
+
this.isInitialized = false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public async getModels(): Promise<CactusModel[]> {
|
|
119
|
+
return Object.values(await getRegistry());
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private isModelPath(model: string): boolean {
|
|
123
|
+
return model.startsWith('file://') || model.startsWith('/');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public getModelName(): string {
|
|
127
|
+
return `${this.model}-${this.options.quantization}${this.options.pro ? '-pro' : ''}`;
|
|
128
|
+
}
|
|
129
|
+
}
|
package/src/hooks/useCactusLM.ts
CHANGED
|
@@ -16,15 +16,19 @@ import type {
|
|
|
16
16
|
CactusLMImageEmbedResult,
|
|
17
17
|
CactusLMDownloadParams,
|
|
18
18
|
} from '../types/CactusLM';
|
|
19
|
-
import type { CactusModel } from '../types/
|
|
19
|
+
import type { CactusModel } from '../types/common';
|
|
20
20
|
|
|
21
21
|
export const useCactusLM = ({
|
|
22
|
-
model = 'qwen3-0.
|
|
23
|
-
contextSize = 2048,
|
|
22
|
+
model = 'qwen3-0.6b',
|
|
24
23
|
corpusDir = undefined,
|
|
24
|
+
cacheIndex = false,
|
|
25
|
+
options: modelOptions = {
|
|
26
|
+
quantization: undefined,
|
|
27
|
+
pro: false,
|
|
28
|
+
},
|
|
25
29
|
}: CactusLMParams = {}) => {
|
|
26
30
|
const [cactusLM, setCactusLM] = useState(
|
|
27
|
-
() => new CactusLM({ model,
|
|
31
|
+
() => new CactusLM({ model, corpusDir, cacheIndex, options: modelOptions })
|
|
28
32
|
);
|
|
29
33
|
|
|
30
34
|
// State
|
|
@@ -44,7 +48,16 @@ export const useCactusLM = ({
|
|
|
44
48
|
}, [model]);
|
|
45
49
|
|
|
46
50
|
useEffect(() => {
|
|
47
|
-
|
|
51
|
+
const newInstance = new CactusLM({
|
|
52
|
+
model,
|
|
53
|
+
corpusDir,
|
|
54
|
+
cacheIndex,
|
|
55
|
+
options: {
|
|
56
|
+
quantization: modelOptions.quantization,
|
|
57
|
+
pro: modelOptions.pro,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
setCactusLM(newInstance);
|
|
48
61
|
|
|
49
62
|
setCompletion('');
|
|
50
63
|
setIsGenerating(false);
|
|
@@ -55,7 +68,7 @@ export const useCactusLM = ({
|
|
|
55
68
|
setError(null);
|
|
56
69
|
|
|
57
70
|
let mounted = true;
|
|
58
|
-
CactusFileSystem.modelExists(
|
|
71
|
+
CactusFileSystem.modelExists(newInstance.getModelName())
|
|
59
72
|
.then((exists) => {
|
|
60
73
|
if (!mounted) {
|
|
61
74
|
return;
|
|
@@ -73,7 +86,13 @@ export const useCactusLM = ({
|
|
|
73
86
|
return () => {
|
|
74
87
|
mounted = false;
|
|
75
88
|
};
|
|
76
|
-
}, [
|
|
89
|
+
}, [
|
|
90
|
+
model,
|
|
91
|
+
corpusDir,
|
|
92
|
+
cacheIndex,
|
|
93
|
+
modelOptions.quantization,
|
|
94
|
+
modelOptions.pro,
|
|
95
|
+
]);
|
|
77
96
|
|
|
78
97
|
useEffect(() => {
|
|
79
98
|
return () => {
|
|
@@ -173,7 +192,6 @@ export const useCactusLM = ({
|
|
|
173
192
|
options,
|
|
174
193
|
tools,
|
|
175
194
|
onToken,
|
|
176
|
-
mode,
|
|
177
195
|
}: CactusLMCompleteParams): Promise<CactusLMCompleteResult> => {
|
|
178
196
|
if (isGenerating) {
|
|
179
197
|
const message = 'CactusLM is already generating';
|
|
@@ -193,7 +211,6 @@ export const useCactusLM = ({
|
|
|
193
211
|
setCompletion((prev) => prev + token);
|
|
194
212
|
onToken?.(token);
|
|
195
213
|
},
|
|
196
|
-
mode,
|
|
197
214
|
});
|
|
198
215
|
} catch (e) {
|
|
199
216
|
setError(getErrorMessage(e));
|
|
@@ -9,20 +9,31 @@ import type {
|
|
|
9
9
|
CactusSTTDownloadParams,
|
|
10
10
|
CactusSTTAudioEmbedParams,
|
|
11
11
|
CactusSTTAudioEmbedResult,
|
|
12
|
+
CactusSTTStreamTranscribeStartOptions,
|
|
13
|
+
CactusSTTStreamTranscribeProcessParams,
|
|
14
|
+
CactusSTTStreamTranscribeProcessResult,
|
|
15
|
+
CactusSTTStreamTranscribeStopResult,
|
|
12
16
|
} from '../types/CactusSTT';
|
|
13
|
-
import type {
|
|
17
|
+
import type { CactusModel } from '../types/common';
|
|
14
18
|
|
|
15
19
|
export const useCactusSTT = ({
|
|
16
20
|
model = 'whisper-small',
|
|
17
|
-
|
|
21
|
+
options: modelOptions = {
|
|
22
|
+
quantization: undefined,
|
|
23
|
+
pro: false,
|
|
24
|
+
},
|
|
18
25
|
}: CactusSTTParams = {}) => {
|
|
19
26
|
const [cactusSTT, setCactusSTT] = useState(
|
|
20
|
-
() => new CactusSTT({ model,
|
|
27
|
+
() => new CactusSTT({ model, options: modelOptions })
|
|
21
28
|
);
|
|
22
29
|
|
|
23
30
|
// State
|
|
24
31
|
const [transcription, setTranscription] = useState('');
|
|
32
|
+
const [streamTranscribeConfirmed, setStreamTranscribeConfirmed] =
|
|
33
|
+
useState('');
|
|
34
|
+
const [streamTranscribePending, setStreamTranscribePending] = useState('');
|
|
25
35
|
const [isGenerating, setIsGenerating] = useState(false);
|
|
36
|
+
const [isStreamTranscribing, setIsStreamTranscribing] = useState(false);
|
|
26
37
|
const [isInitializing, setIsInitializing] = useState(false);
|
|
27
38
|
const [isDownloaded, setIsDownloaded] = useState(false);
|
|
28
39
|
const [isDownloading, setIsDownloading] = useState(false);
|
|
@@ -37,10 +48,20 @@ export const useCactusSTT = ({
|
|
|
37
48
|
}, [model]);
|
|
38
49
|
|
|
39
50
|
useEffect(() => {
|
|
40
|
-
|
|
51
|
+
const newInstance = new CactusSTT({
|
|
52
|
+
model,
|
|
53
|
+
options: {
|
|
54
|
+
quantization: modelOptions.quantization,
|
|
55
|
+
pro: modelOptions.pro,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
setCactusSTT(newInstance);
|
|
41
59
|
|
|
42
60
|
setTranscription('');
|
|
61
|
+
setStreamTranscribeConfirmed('');
|
|
62
|
+
setStreamTranscribePending('');
|
|
43
63
|
setIsGenerating(false);
|
|
64
|
+
setIsStreamTranscribing(false);
|
|
44
65
|
setIsInitializing(false);
|
|
45
66
|
setIsDownloaded(false);
|
|
46
67
|
setIsDownloading(false);
|
|
@@ -48,25 +69,21 @@ export const useCactusSTT = ({
|
|
|
48
69
|
setError(null);
|
|
49
70
|
|
|
50
71
|
let mounted = true;
|
|
51
|
-
CactusFileSystem.modelExists(
|
|
72
|
+
CactusFileSystem.modelExists(newInstance.getModelName())
|
|
52
73
|
.then((exists) => {
|
|
53
|
-
if (
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
setIsDownloaded(exists);
|
|
74
|
+
if (mounted) setIsDownloaded(exists);
|
|
57
75
|
})
|
|
58
76
|
.catch((e) => {
|
|
59
|
-
if (
|
|
60
|
-
|
|
77
|
+
if (mounted) {
|
|
78
|
+
setIsDownloaded(false);
|
|
79
|
+
setError(getErrorMessage(e));
|
|
61
80
|
}
|
|
62
|
-
setIsDownloaded(false);
|
|
63
|
-
setError(getErrorMessage(e));
|
|
64
81
|
});
|
|
65
82
|
|
|
66
83
|
return () => {
|
|
67
84
|
mounted = false;
|
|
68
85
|
};
|
|
69
|
-
}, [model,
|
|
86
|
+
}, [model, modelOptions.quantization, modelOptions.pro]);
|
|
70
87
|
|
|
71
88
|
useEffect(() => {
|
|
72
89
|
return () => {
|
|
@@ -91,49 +108,29 @@ export const useCactusSTT = ({
|
|
|
91
108
|
const thisModel = currentModelRef.current;
|
|
92
109
|
const thisDownloadId = ++currentDownloadIdRef.current;
|
|
93
110
|
|
|
111
|
+
const isCurrent = () =>
|
|
112
|
+
currentModelRef.current === thisModel &&
|
|
113
|
+
currentDownloadIdRef.current === thisDownloadId;
|
|
114
|
+
|
|
94
115
|
setDownloadProgress(0);
|
|
95
116
|
setIsDownloading(true);
|
|
96
117
|
try {
|
|
97
118
|
await cactusSTT.download({
|
|
98
119
|
onProgress: (progress) => {
|
|
99
|
-
if (
|
|
100
|
-
currentModelRef.current !== thisModel ||
|
|
101
|
-
currentDownloadIdRef.current !== thisDownloadId
|
|
102
|
-
) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
|
|
120
|
+
if (!isCurrent()) return;
|
|
106
121
|
setDownloadProgress(progress);
|
|
107
122
|
onProgress?.(progress);
|
|
108
123
|
},
|
|
109
124
|
});
|
|
110
125
|
|
|
111
|
-
if (
|
|
112
|
-
currentModelRef.current !== thisModel ||
|
|
113
|
-
currentDownloadIdRef.current !== thisDownloadId
|
|
114
|
-
) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
126
|
+
if (!isCurrent()) return;
|
|
118
127
|
setIsDownloaded(true);
|
|
119
128
|
} catch (e) {
|
|
120
|
-
if (
|
|
121
|
-
currentModelRef.current !== thisModel ||
|
|
122
|
-
currentDownloadIdRef.current !== thisDownloadId
|
|
123
|
-
) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
|
|
129
|
+
if (!isCurrent()) return;
|
|
127
130
|
setError(getErrorMessage(e));
|
|
128
131
|
throw e;
|
|
129
132
|
} finally {
|
|
130
|
-
if (
|
|
131
|
-
currentModelRef.current !== thisModel ||
|
|
132
|
-
currentDownloadIdRef.current !== thisDownloadId
|
|
133
|
-
) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
133
|
+
if (!isCurrent()) return;
|
|
137
134
|
setIsDownloading(false);
|
|
138
135
|
setDownloadProgress(0);
|
|
139
136
|
}
|
|
@@ -220,6 +217,61 @@ export const useCactusSTT = ({
|
|
|
220
217
|
[cactusSTT, isGenerating]
|
|
221
218
|
);
|
|
222
219
|
|
|
220
|
+
const streamTranscribeStart = useCallback(
|
|
221
|
+
async (options?: CactusSTTStreamTranscribeStartOptions) => {
|
|
222
|
+
if (isStreamTranscribing) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
setError(null);
|
|
227
|
+
setStreamTranscribeConfirmed('');
|
|
228
|
+
setStreamTranscribePending('');
|
|
229
|
+
setIsStreamTranscribing(true);
|
|
230
|
+
try {
|
|
231
|
+
await cactusSTT.streamTranscribeStart(options);
|
|
232
|
+
} catch (e) {
|
|
233
|
+
setError(getErrorMessage(e));
|
|
234
|
+
setIsStreamTranscribing(false);
|
|
235
|
+
throw e;
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
[cactusSTT, isStreamTranscribing]
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
const streamTranscribeProcess = useCallback(
|
|
242
|
+
async ({
|
|
243
|
+
audio,
|
|
244
|
+
}: CactusSTTStreamTranscribeProcessParams): Promise<CactusSTTStreamTranscribeProcessResult> => {
|
|
245
|
+
setError(null);
|
|
246
|
+
try {
|
|
247
|
+
const result = await cactusSTT.streamTranscribeProcess({ audio });
|
|
248
|
+
setStreamTranscribeConfirmed((prev) => prev + result.confirmed);
|
|
249
|
+
setStreamTranscribePending(result.pending);
|
|
250
|
+
return result;
|
|
251
|
+
} catch (e) {
|
|
252
|
+
setError(getErrorMessage(e));
|
|
253
|
+
throw e;
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
[cactusSTT]
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
const streamTranscribeStop =
|
|
260
|
+
useCallback(async (): Promise<CactusSTTStreamTranscribeStopResult> => {
|
|
261
|
+
setError(null);
|
|
262
|
+
try {
|
|
263
|
+
const result = await cactusSTT.streamTranscribeStop();
|
|
264
|
+
setStreamTranscribeConfirmed((prev) => prev + result.confirmed);
|
|
265
|
+
setStreamTranscribePending('');
|
|
266
|
+
return result;
|
|
267
|
+
} catch (e) {
|
|
268
|
+
setError(getErrorMessage(e));
|
|
269
|
+
throw e;
|
|
270
|
+
} finally {
|
|
271
|
+
setIsStreamTranscribing(false);
|
|
272
|
+
}
|
|
273
|
+
}, [cactusSTT]);
|
|
274
|
+
|
|
223
275
|
const stop = useCallback(async () => {
|
|
224
276
|
setError(null);
|
|
225
277
|
try {
|
|
@@ -251,10 +303,13 @@ export const useCactusSTT = ({
|
|
|
251
303
|
throw e;
|
|
252
304
|
} finally {
|
|
253
305
|
setTranscription('');
|
|
306
|
+
setStreamTranscribeConfirmed('');
|
|
307
|
+
setStreamTranscribePending('');
|
|
308
|
+
setIsStreamTranscribing(false);
|
|
254
309
|
}
|
|
255
310
|
}, [cactusSTT]);
|
|
256
311
|
|
|
257
|
-
const getModels = useCallback(async (): Promise<
|
|
312
|
+
const getModels = useCallback(async (): Promise<CactusModel[]> => {
|
|
258
313
|
setError(null);
|
|
259
314
|
try {
|
|
260
315
|
return await cactusSTT.getModels();
|
|
@@ -266,7 +321,10 @@ export const useCactusSTT = ({
|
|
|
266
321
|
|
|
267
322
|
return {
|
|
268
323
|
transcription,
|
|
324
|
+
streamTranscribeConfirmed,
|
|
325
|
+
streamTranscribePending,
|
|
269
326
|
isGenerating,
|
|
327
|
+
isStreamTranscribing,
|
|
270
328
|
isInitializing,
|
|
271
329
|
isDownloaded,
|
|
272
330
|
isDownloading,
|
|
@@ -277,8 +335,11 @@ export const useCactusSTT = ({
|
|
|
277
335
|
init,
|
|
278
336
|
transcribe,
|
|
279
337
|
audioEmbed,
|
|
280
|
-
|
|
338
|
+
streamTranscribeStart,
|
|
339
|
+
streamTranscribeProcess,
|
|
340
|
+
streamTranscribeStop,
|
|
281
341
|
stop,
|
|
342
|
+
reset,
|
|
282
343
|
destroy,
|
|
283
344
|
getModels,
|
|
284
345
|
};
|