@qvac/sdk 0.1.0-dev.1760648187.328e967
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/LICENSE +202 -0
- package/README.md +301 -0
- package/dist/client/api/cancel.d.ts +25 -0
- package/dist/client/api/cancel.js +37 -0
- package/dist/client/api/completion-stream.d.ts +50 -0
- package/dist/client/api/completion-stream.js +103 -0
- package/dist/client/api/download-asset.d.ts +39 -0
- package/dist/client/api/download-asset.js +72 -0
- package/dist/client/api/embed.d.ts +11 -0
- package/dist/client/api/embed.js +24 -0
- package/dist/client/api/index.d.ts +13 -0
- package/dist/client/api/index.js +12 -0
- package/dist/client/api/load-model.d.ts +98 -0
- package/dist/client/api/load-model.js +154 -0
- package/dist/client/api/logging-stream.d.ts +21 -0
- package/dist/client/api/logging-stream.js +32 -0
- package/dist/client/api/ping.d.ts +11 -0
- package/dist/client/api/ping.js +18 -0
- package/dist/client/api/provide.d.ts +18 -0
- package/dist/client/api/provide.js +27 -0
- package/dist/client/api/rag.d.ts +42 -0
- package/dist/client/api/rag.js +97 -0
- package/dist/client/api/transcribe.d.ts +24 -0
- package/dist/client/api/transcribe.js +52 -0
- package/dist/client/api/translate.d.ts +47 -0
- package/dist/client/api/translate.js +114 -0
- package/dist/client/api/unload-model.d.ts +11 -0
- package/dist/client/api/unload-model.js +26 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +1 -0
- package/dist/client/logging-stream-registry.d.ts +5 -0
- package/dist/client/logging-stream-registry.js +60 -0
- package/dist/client/rpc/bare-client.d.ts +112 -0
- package/dist/client/rpc/bare-client.js +82 -0
- package/dist/client/rpc/bare-rpc-client.d.ts +4 -0
- package/dist/client/rpc/bare-rpc-client.js +87 -0
- package/dist/client/rpc/expo-rpc-client.d.ts +3 -0
- package/dist/client/rpc/expo-rpc-client.js +57 -0
- package/dist/client/rpc/node-rpc-client.d.ts +9 -0
- package/dist/client/rpc/node-rpc-client.js +99 -0
- package/dist/client/rpc/rpc-client.d.ts +5 -0
- package/dist/client/rpc/rpc-client.js +91 -0
- package/dist/client/rpc/rpc-error.d.ts +19 -0
- package/dist/client/rpc/rpc-error.js +39 -0
- package/dist/constants/audio.d.ts +3 -0
- package/dist/constants/audio.js +17 -0
- package/dist/constants/index.d.ts +2 -0
- package/dist/constants/index.js +1 -0
- package/dist/examples/delegated-inference/consumer.d.ts +2 -0
- package/dist/examples/delegated-inference/consumer.js +56 -0
- package/dist/examples/delegated-inference/provider.d.ts +2 -0
- package/dist/examples/delegated-inference/provider.js +57 -0
- package/dist/examples/download-with-cancel.d.ts +2 -0
- package/dist/examples/download-with-cancel.js +46 -0
- package/dist/examples/embed-hyperdrive.d.ts +2 -0
- package/dist/examples/embed-hyperdrive.js +19 -0
- package/dist/examples/kv-cache-example.d.ts +2 -0
- package/dist/examples/kv-cache-example.js +74 -0
- package/dist/examples/llamacpp-file-logging.d.ts +2 -0
- package/dist/examples/llamacpp-file-logging.js +62 -0
- package/dist/examples/llamacpp-filesystem.d.ts +2 -0
- package/dist/examples/llamacpp-filesystem.js +40 -0
- package/dist/examples/llamacpp-http.d.ts +2 -0
- package/dist/examples/llamacpp-http.js +41 -0
- package/dist/examples/llamacpp-hyperdrive.d.ts +2 -0
- package/dist/examples/llamacpp-hyperdrive.js +39 -0
- package/dist/examples/llamacpp-multimodal.d.ts +2 -0
- package/dist/examples/llamacpp-multimodal.js +62 -0
- package/dist/examples/llamacpp-native-tools.d.ts +2 -0
- package/dist/examples/llamacpp-native-tools.js +64 -0
- package/dist/examples/llamacpp-tools-routing.d.ts +2 -0
- package/dist/examples/llamacpp-tools-routing.js +364 -0
- package/dist/examples/llamacpp-tools.d.ts +2 -0
- package/dist/examples/llamacpp-tools.js +81 -0
- package/dist/examples/multi-model-demo.d.ts +2 -0
- package/dist/examples/multi-model-demo.js +75 -0
- package/dist/examples/parallel-download.d.ts +2 -0
- package/dist/examples/parallel-download.js +21 -0
- package/dist/examples/rag/rag-chromadb.d.ts +2 -0
- package/dist/examples/rag/rag-chromadb.js +130 -0
- package/dist/examples/rag/rag-hyperdb-workspaces.d.ts +2 -0
- package/dist/examples/rag/rag-hyperdb-workspaces.js +106 -0
- package/dist/examples/rag/rag-hyperdb.d.ts +2 -0
- package/dist/examples/rag/rag-hyperdb.js +50 -0
- package/dist/examples/rag/rag-lancedb.d.ts +2 -0
- package/dist/examples/rag/rag-lancedb.js +95 -0
- package/dist/examples/rag/rag-sqlite.d.ts +2 -0
- package/dist/examples/rag/rag-sqlite.js +107 -0
- package/dist/examples/seed-hyperdrive.d.ts +2 -0
- package/dist/examples/seed-hyperdrive.js +21 -0
- package/dist/examples/translation/translation-indic.d.ts +2 -0
- package/dist/examples/translation/translation-indic.js +30 -0
- package/dist/examples/translation/translation-llm-context.d.ts +2 -0
- package/dist/examples/translation/translation-llm-context.js +30 -0
- package/dist/examples/translation/translation-llm.d.ts +2 -0
- package/dist/examples/translation/translation-llm.js +38 -0
- package/dist/examples/translation/translation-opus.d.ts +2 -0
- package/dist/examples/translation/translation-opus.js +30 -0
- package/dist/examples/translation/translation-stream.d.ts +2 -0
- package/dist/examples/translation/translation-stream.js +35 -0
- package/dist/examples/whispercpp-filesystem.d.ts +2 -0
- package/dist/examples/whispercpp-filesystem.js +43 -0
- package/dist/examples/whispercpp-microphone-record.d.ts +2 -0
- package/dist/examples/whispercpp-microphone-record.js +311 -0
- package/dist/expo/plugins/index.d.ts +5 -0
- package/dist/expo/plugins/index.js +5 -0
- package/dist/expo/plugins/withMobileBundle.d.ts +8 -0
- package/dist/expo/plugins/withMobileBundle.js +60 -0
- package/dist/expo/plugins/withOpenCL.d.ts +9 -0
- package/dist/expo/plugins/withOpenCL.js +118 -0
- package/dist/expo/plugins/withQvacSDK.d.ts +9 -0
- package/dist/expo/plugins/withQvacSDK.js +13 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8 -0
- package/dist/logging/base-logger.d.ts +7 -0
- package/dist/logging/base-logger.js +55 -0
- package/dist/logging/index.d.ts +4 -0
- package/dist/logging/index.js +2 -0
- package/dist/logging/logger.d.ts +5 -0
- package/dist/logging/logger.js +28 -0
- package/dist/logging/stream-logger.d.ts +3 -0
- package/dist/logging/stream-logger.js +9 -0
- package/dist/logging/transport.d.ts +3 -0
- package/dist/logging/transport.js +15 -0
- package/dist/logging/types.d.ts +18 -0
- package/dist/logging/types.js +1 -0
- package/dist/logging/utils.d.ts +4 -0
- package/dist/logging/utils.js +47 -0
- package/dist/models/hyperdrive/index.d.ts +2 -0
- package/dist/models/hyperdrive/index.js +2 -0
- package/dist/models/hyperdrive/models.d.ts +475 -0
- package/dist/models/hyperdrive/models.js +534 -0
- package/dist/schemas/cancel.d.ts +33 -0
- package/dist/schemas/cancel.js +25 -0
- package/dist/schemas/common.d.ts +626 -0
- package/dist/schemas/common.js +47 -0
- package/dist/schemas/completion-stream.d.ts +125 -0
- package/dist/schemas/completion-stream.js +53 -0
- package/dist/schemas/delegate.d.ts +9 -0
- package/dist/schemas/delegate.js +9 -0
- package/dist/schemas/download-asset.d.ts +75 -0
- package/dist/schemas/download-asset.js +43 -0
- package/dist/schemas/embed.d.ts +20 -0
- package/dist/schemas/embed.js +14 -0
- package/dist/schemas/error.d.ts +13 -0
- package/dist/schemas/error.js +35 -0
- package/dist/schemas/index.d.ts +19 -0
- package/dist/schemas/index.js +19 -0
- package/dist/schemas/llamacpp-config.d.ts +30 -0
- package/dist/schemas/llamacpp-config.js +39 -0
- package/dist/schemas/load-model.d.ts +1259 -0
- package/dist/schemas/load-model.js +108 -0
- package/dist/schemas/logging-stream.d.ts +27 -0
- package/dist/schemas/logging-stream.js +16 -0
- package/dist/schemas/ping.d.ts +11 -0
- package/dist/schemas/ping.js +8 -0
- package/dist/schemas/provide.d.ts +43 -0
- package/dist/schemas/provide.js +25 -0
- package/dist/schemas/rag.d.ts +159 -0
- package/dist/schemas/rag.js +78 -0
- package/dist/schemas/transcription.d.ts +24 -0
- package/dist/schemas/transcription.js +15 -0
- package/dist/schemas/translate.d.ts +82 -0
- package/dist/schemas/translate.js +42 -0
- package/dist/schemas/translation-config.d.ts +83 -0
- package/dist/schemas/translation-config.js +46 -0
- package/dist/schemas/unload-model.d.ts +19 -0
- package/dist/schemas/unload-model.js +13 -0
- package/dist/schemas/whispercpp-config.d.ts +25 -0
- package/dist/schemas/whispercpp-config.js +18 -0
- package/dist/server/bare/addons/cancel.d.ts +3 -0
- package/dist/server/bare/addons/cancel.js +12 -0
- package/dist/server/bare/addons/index.d.ts +4 -0
- package/dist/server/bare/addons/index.js +3 -0
- package/dist/server/bare/addons/llamacpp/create-model.d.ts +5 -0
- package/dist/server/bare/addons/llamacpp/create-model.js +57 -0
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.d.ts +3 -0
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.js +65 -0
- package/dist/server/bare/addons/llamacpp/handlers/embed.d.ts +4 -0
- package/dist/server/bare/addons/llamacpp/handlers/embed.js +40 -0
- package/dist/server/bare/addons/llamacpp/index.d.ts +4 -0
- package/dist/server/bare/addons/llamacpp/index.js +3 -0
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.d.ts +19 -0
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.js +46 -0
- package/dist/server/bare/addons/load-model.d.ts +3 -0
- package/dist/server/bare/addons/load-model.js +55 -0
- package/dist/server/bare/addons/translation/create-model.d.ts +4 -0
- package/dist/server/bare/addons/translation/create-model.js +45 -0
- package/dist/server/bare/addons/translation/handlers/translate.d.ts +3 -0
- package/dist/server/bare/addons/translation/handlers/translate.js +86 -0
- package/dist/server/bare/addons/translation/index.d.ts +3 -0
- package/dist/server/bare/addons/translation/index.js +2 -0
- package/dist/server/bare/addons/unload-model.d.ts +3 -0
- package/dist/server/bare/addons/unload-model.js +20 -0
- package/dist/server/bare/addons/whispercpp/create-model.d.ts +6 -0
- package/dist/server/bare/addons/whispercpp/create-model.js +55 -0
- package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.d.ts +3 -0
- package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.js +42 -0
- package/dist/server/bare/addons/whispercpp/index.d.ts +3 -0
- package/dist/server/bare/addons/whispercpp/index.js +2 -0
- package/dist/server/bare/delegate-rpc-client.d.ts +4 -0
- package/dist/server/bare/delegate-rpc-client.js +70 -0
- package/dist/server/bare/hyperswarm.d.ts +7 -0
- package/dist/server/bare/hyperswarm.js +62 -0
- package/dist/server/bare/rag-hyperdb/handlers/delete-embeddings.d.ts +3 -0
- package/dist/server/bare/rag-hyperdb/handlers/delete-embeddings.js +12 -0
- package/dist/server/bare/rag-hyperdb/handlers/save-embeddings.d.ts +6 -0
- package/dist/server/bare/rag-hyperdb/handlers/save-embeddings.js +16 -0
- package/dist/server/bare/rag-hyperdb/handlers/search.d.ts +3 -0
- package/dist/server/bare/rag-hyperdb/handlers/search.js +15 -0
- package/dist/server/bare/rag-hyperdb/index.d.ts +5 -0
- package/dist/server/bare/rag-hyperdb/index.js +4 -0
- package/dist/server/bare/rag-hyperdb/rag-manager.d.ts +5 -0
- package/dist/server/bare/rag-hyperdb/rag-manager.js +61 -0
- package/dist/server/bare/registry/logging-stream-registry.d.ts +12 -0
- package/dist/server/bare/registry/logging-stream-registry.js +46 -0
- package/dist/server/bare/registry/model-registry.d.ts +64 -0
- package/dist/server/bare/registry/model-registry.js +95 -0
- package/dist/server/error-handlers.d.ts +4 -0
- package/dist/server/error-handlers.js +27 -0
- package/dist/server/http-server.d.ts +2 -0
- package/dist/server/http-server.js +189 -0
- package/dist/server/rpc/create-server.d.ts +4 -0
- package/dist/server/rpc/create-server.js +19 -0
- package/dist/server/rpc/handle-request.d.ts +12 -0
- package/dist/server/rpc/handle-request.js +220 -0
- package/dist/server/rpc/handlers/cancelHandler.d.ts +3 -0
- package/dist/server/rpc/handlers/cancelHandler.js +27 -0
- package/dist/server/rpc/handlers/completion-stream-delegated.d.ts +3 -0
- package/dist/server/rpc/handlers/completion-stream-delegated.js +30 -0
- package/dist/server/rpc/handlers/completion-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/completion-stream.js +52 -0
- package/dist/server/rpc/handlers/download-asset.d.ts +3 -0
- package/dist/server/rpc/handlers/download-asset.js +21 -0
- package/dist/server/rpc/handlers/embed.d.ts +3 -0
- package/dist/server/rpc/handlers/embed.js +21 -0
- package/dist/server/rpc/handlers/index.d.ts +23 -0
- package/dist/server/rpc/handlers/index.js +22 -0
- package/dist/server/rpc/handlers/load-model/download-manager.d.ts +31 -0
- package/dist/server/rpc/handlers/load-model/download-manager.js +88 -0
- package/dist/server/rpc/handlers/load-model/http.d.ts +3 -0
- package/dist/server/rpc/handlers/load-model/http.js +337 -0
- package/dist/server/rpc/handlers/load-model/hyperdrive.d.ts +4 -0
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +332 -0
- package/dist/server/rpc/handlers/load-model/index.d.ts +4 -0
- package/dist/server/rpc/handlers/load-model/index.js +3 -0
- package/dist/server/rpc/handlers/load-model/resolve.d.ts +3 -0
- package/dist/server/rpc/handlers/load-model/resolve.js +121 -0
- package/dist/server/rpc/handlers/load-model-delegated.d.ts +3 -0
- package/dist/server/rpc/handlers/load-model-delegated.js +93 -0
- package/dist/server/rpc/handlers/load-model.d.ts +3 -0
- package/dist/server/rpc/handlers/load-model.js +41 -0
- package/dist/server/rpc/handlers/logging-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/logging-stream.js +37 -0
- package/dist/server/rpc/handlers/provideHandler/connection.d.ts +3 -0
- package/dist/server/rpc/handlers/provideHandler/connection.js +25 -0
- package/dist/server/rpc/handlers/provideHandler/handler.d.ts +3 -0
- package/dist/server/rpc/handlers/provideHandler/handler.js +50 -0
- package/dist/server/rpc/handlers/provideHandler/proxy.d.ts +3 -0
- package/dist/server/rpc/handlers/provideHandler/proxy.js +22 -0
- package/dist/server/rpc/handlers/provideHandler.d.ts +2 -0
- package/dist/server/rpc/handlers/provideHandler.js +2 -0
- package/dist/server/rpc/handlers/rag.d.ts +3 -0
- package/dist/server/rpc/handlers/rag.js +67 -0
- package/dist/server/rpc/handlers/transcribe-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/transcribe-stream.js +26 -0
- package/dist/server/rpc/handlers/translate.d.ts +3 -0
- package/dist/server/rpc/handlers/translate.js +51 -0
- package/dist/server/rpc/handlers/unload-model.d.ts +3 -0
- package/dist/server/rpc/handlers/unload-model.js +20 -0
- package/dist/server/rpc/index.d.ts +3 -0
- package/dist/server/rpc/index.js +2 -0
- package/dist/server/utils/audio/decoder.d.ts +4 -0
- package/dist/server/utils/audio/decoder.js +41 -0
- package/dist/server/utils/cache.d.ts +15 -0
- package/dist/server/utils/cache.js +32 -0
- package/dist/server/utils/hash.d.ts +5 -0
- package/dist/server/utils/hash.js +11 -0
- package/dist/server/utils/index.d.ts +5 -0
- package/dist/server/utils/index.js +4 -0
- package/dist/server/utils/model-path.d.ts +5 -0
- package/dist/server/utils/model-path.js +7 -0
- package/dist/server/worker.d.ts +6 -0
- package/dist/server/worker.js +77 -0
- package/dist/utils/withTimeout.d.ts +11 -0
- package/dist/utils/withTimeout.js +37 -0
- package/package.json +129 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { loadModel, downloadAsset, unloadModel, transcribe, transcribeStream, WHISPER_TINY, VAD_SILERO_5_1_2, } from "@qvac/sdk";
|
|
2
|
+
import { spawn, spawnSync } from "child_process";
|
|
3
|
+
import * as readline from "readline";
|
|
4
|
+
import { platform } from "os";
|
|
5
|
+
function checkFFmpegAvailable() {
|
|
6
|
+
try {
|
|
7
|
+
const result = spawnSync("ffmpeg", ["-version"], { stdio: "ignore" });
|
|
8
|
+
if (result.error || result.status !== 0) {
|
|
9
|
+
throw new Error("FFmpeg not available");
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
throw new Error("FFmpeg is not installed or not available in PATH. Please install FFmpeg to use microphone recording.");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function getAudioDevice(platformName) {
|
|
17
|
+
switch (platformName) {
|
|
18
|
+
case "darwin":
|
|
19
|
+
return ":0";
|
|
20
|
+
case "win32":
|
|
21
|
+
// Change as per your system
|
|
22
|
+
return "audio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\\wave_{58C07110-A4FD-4FF8-BA10-5A3C14389F71}";
|
|
23
|
+
case "linux":
|
|
24
|
+
return "default";
|
|
25
|
+
default:
|
|
26
|
+
throw new Error(`Unsupported platform for audio recording: ${platformName}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Parse command line arguments
|
|
30
|
+
const args = process.argv.slice(2);
|
|
31
|
+
const isStreamingMode = args.includes("--stream");
|
|
32
|
+
// Show help if needed
|
|
33
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
34
|
+
console.log("🎤 Microphone Transcription Demo");
|
|
35
|
+
console.log("");
|
|
36
|
+
console.log("Usage:");
|
|
37
|
+
console.log(" bun run examples/microphone-record-transcription.ts [options]");
|
|
38
|
+
console.log("");
|
|
39
|
+
console.log("Options:");
|
|
40
|
+
console.log(" --stream Enable real-time streaming transcription");
|
|
41
|
+
console.log(" --help, -h Show this help message");
|
|
42
|
+
console.log("");
|
|
43
|
+
console.log("Default behavior: Record audio, then transcribe when you stop recording");
|
|
44
|
+
console.log("With --stream: Transcribe audio in real-time as you speak");
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
// Clean readline-based transcription session
|
|
48
|
+
function startInteractiveSession(rl, modelId) {
|
|
49
|
+
let isRecording = false;
|
|
50
|
+
let ffmpeg = null;
|
|
51
|
+
let audioBuffer = Buffer.alloc(0);
|
|
52
|
+
let audioChunkBuffer = Buffer.alloc(0);
|
|
53
|
+
const chunkSizeBytes = 96000; // ~3 seconds of audio at 16kHz 16-bit mono
|
|
54
|
+
let lastProcessTime = 0;
|
|
55
|
+
const showInstructions = () => {
|
|
56
|
+
if (isStreamingMode) {
|
|
57
|
+
console.log("🎤 Real-Time Transcription Session");
|
|
58
|
+
console.log("📊 Format: 16kHz, 32-bit float, mono, f32le");
|
|
59
|
+
console.log(`🎙️ Using ${platform() === "darwin" ? "macOS" : platform() === "win32" ? "Windows" : "Linux"} microphone`);
|
|
60
|
+
console.log("⏯️ Press Enter to START/STOP real-time transcription");
|
|
61
|
+
console.log("🛑 Type 'q' and press Enter to quit");
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log("🎤 Record-and-Transcribe Session");
|
|
65
|
+
console.log("📊 Format: 16kHz, 32-bit float, mono, f32le");
|
|
66
|
+
console.log(`🎙️ Using ${platform() === "darwin" ? "macOS" : platform() === "win32" ? "Windows" : "Linux"} microphone`);
|
|
67
|
+
console.log("⏯️ Press Enter to START/STOP recording");
|
|
68
|
+
console.log("🛑 Type 'q' and press Enter to quit");
|
|
69
|
+
}
|
|
70
|
+
console.log("");
|
|
71
|
+
};
|
|
72
|
+
const startRecording = () => {
|
|
73
|
+
if (isStreamingMode) {
|
|
74
|
+
console.log("🔴 Starting real-time transcription...");
|
|
75
|
+
audioChunkBuffer = Buffer.alloc(0);
|
|
76
|
+
console.log("\n" + "═".repeat(80));
|
|
77
|
+
console.log("🗣️ REAL-TIME TRANSCRIPTION");
|
|
78
|
+
console.log("═".repeat(80));
|
|
79
|
+
console.log("📝 Speak now, transcription will appear as you talk...");
|
|
80
|
+
console.log("");
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.log("🔴 Starting recording...");
|
|
84
|
+
audioBuffer = Buffer.alloc(0);
|
|
85
|
+
}
|
|
86
|
+
const currentPlatform = platform();
|
|
87
|
+
const audioInputArgs = (() => {
|
|
88
|
+
switch (currentPlatform) {
|
|
89
|
+
case "darwin":
|
|
90
|
+
return ["-f", "avfoundation", "-i", getAudioDevice(currentPlatform)];
|
|
91
|
+
case "win32":
|
|
92
|
+
return ["-f", "dshow", "-i", getAudioDevice(currentPlatform)];
|
|
93
|
+
case "linux":
|
|
94
|
+
return ["-f", "pulse", "-i", getAudioDevice(currentPlatform)];
|
|
95
|
+
default:
|
|
96
|
+
throw new Error(`Unsupported platform for audio recording: ${currentPlatform}`);
|
|
97
|
+
}
|
|
98
|
+
})();
|
|
99
|
+
ffmpeg = spawn("ffmpeg", [
|
|
100
|
+
...audioInputArgs,
|
|
101
|
+
"-ar",
|
|
102
|
+
"16000", // 16kHz
|
|
103
|
+
"-ac",
|
|
104
|
+
"1", // Mono
|
|
105
|
+
"-sample_fmt",
|
|
106
|
+
"flt", // 32-bit float
|
|
107
|
+
"-f",
|
|
108
|
+
"f32le", // f32le output format
|
|
109
|
+
"pipe:1", // Output to stdout
|
|
110
|
+
], { stdio: ["ignore", "pipe", "ignore"] });
|
|
111
|
+
if (!ffmpeg.stdout) {
|
|
112
|
+
console.error("Failed to create microphone stream");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (isStreamingMode) {
|
|
116
|
+
// Process audio chunks in real-time
|
|
117
|
+
ffmpeg.stdout.on("data", (chunk) => {
|
|
118
|
+
audioChunkBuffer = Buffer.concat([audioChunkBuffer, chunk]);
|
|
119
|
+
const now = Date.now();
|
|
120
|
+
if (audioChunkBuffer.length >= chunkSizeBytes &&
|
|
121
|
+
now - lastProcessTime > 1000) {
|
|
122
|
+
const chunkToProcess = audioChunkBuffer.slice(0, chunkSizeBytes);
|
|
123
|
+
audioChunkBuffer = audioChunkBuffer.slice(chunkSizeBytes);
|
|
124
|
+
lastProcessTime = now;
|
|
125
|
+
if (chunkToProcess.length < 32000)
|
|
126
|
+
return;
|
|
127
|
+
void (async () => {
|
|
128
|
+
try {
|
|
129
|
+
for await (const textChunk of transcribeStream({
|
|
130
|
+
modelId,
|
|
131
|
+
audioChunk: chunkToProcess,
|
|
132
|
+
})) {
|
|
133
|
+
if (textChunk.trim() && !textChunk.includes("[BLANK_AUDIO]")) {
|
|
134
|
+
process.stdout.write(textChunk);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
console.error("\n⚠️ Transcription error:", error instanceof Error ? error.message : String(error));
|
|
140
|
+
}
|
|
141
|
+
})();
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// Buffer all audio data for later transcription
|
|
147
|
+
ffmpeg.stdout.on("data", (chunk) => {
|
|
148
|
+
audioBuffer = Buffer.concat([audioBuffer, chunk]);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
isRecording = true;
|
|
152
|
+
if (isStreamingMode) {
|
|
153
|
+
console.log("✅ Real-time transcription active!");
|
|
154
|
+
console.log("⏹️ Press Enter to STOP");
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
console.log("✅ Recording... speak now!");
|
|
158
|
+
console.log("⏹️ Press Enter to STOP and transcribe");
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const stopRecording = async () => {
|
|
162
|
+
if (!isRecording)
|
|
163
|
+
return;
|
|
164
|
+
if (ffmpeg) {
|
|
165
|
+
ffmpeg.kill();
|
|
166
|
+
}
|
|
167
|
+
isRecording = false;
|
|
168
|
+
if (isStreamingMode) {
|
|
169
|
+
console.log("\n🛑 Stopping real-time transcription...");
|
|
170
|
+
if (audioChunkBuffer.length > 0) {
|
|
171
|
+
try {
|
|
172
|
+
for await (const textChunk of transcribeStream({
|
|
173
|
+
modelId,
|
|
174
|
+
audioChunk: audioChunkBuffer,
|
|
175
|
+
})) {
|
|
176
|
+
if (textChunk.trim() && !textChunk.includes("[BLANK_AUDIO]")) {
|
|
177
|
+
process.stdout.write(textChunk);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
console.error("\n❌ Final transcription failed:", error instanceof Error ? error.message : String(error));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
console.log("\n═".repeat(80));
|
|
186
|
+
console.log("✅ Real-time transcription stopped");
|
|
187
|
+
console.log("⏯️ Press Enter to start again...");
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
console.log("🛑 Stopping recording...");
|
|
191
|
+
console.log(`📦 Recorded ${audioBuffer.length} bytes of audio`);
|
|
192
|
+
console.log("🔄 Transcribing...");
|
|
193
|
+
const startTime = Date.now();
|
|
194
|
+
console.log("\n" + "═".repeat(80));
|
|
195
|
+
console.log("🗣️ TRANSCRIPTION RESULT");
|
|
196
|
+
console.log("═".repeat(80));
|
|
197
|
+
try {
|
|
198
|
+
const text = await transcribe({ modelId, audioChunk: audioBuffer });
|
|
199
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
200
|
+
console.log(`📝 "${text}"`);
|
|
201
|
+
console.log("═".repeat(80));
|
|
202
|
+
console.log(`✅ Transcription completed in ${elapsed}s`);
|
|
203
|
+
console.log("\n⏯️ Press Enter to record again...");
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.error("\n❌ Transcription failed:", error instanceof Error ? error.message : String(error));
|
|
207
|
+
console.log("\n⏯️ Press Enter to record again...");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
showInstructions();
|
|
212
|
+
const handleInput = (input) => {
|
|
213
|
+
const command = input.trim().toLowerCase();
|
|
214
|
+
if (command === "") {
|
|
215
|
+
// Just pressed Enter - toggle recording
|
|
216
|
+
if (isRecording) {
|
|
217
|
+
void stopRecording();
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
startRecording();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else if (command === "q") {
|
|
224
|
+
console.log("\n🛑 Exiting...");
|
|
225
|
+
if (ffmpeg) {
|
|
226
|
+
ffmpeg.kill();
|
|
227
|
+
}
|
|
228
|
+
rl.close();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
console.log(`❓ Unknown command: ${command}`);
|
|
233
|
+
console.log("💡 Press Enter to start/stop, 'q' to quit");
|
|
234
|
+
}
|
|
235
|
+
rl.prompt();
|
|
236
|
+
};
|
|
237
|
+
rl.on("line", handleInput);
|
|
238
|
+
rl.on("close", () => {
|
|
239
|
+
if (ffmpeg) {
|
|
240
|
+
ffmpeg.kill();
|
|
241
|
+
}
|
|
242
|
+
process.exit(0);
|
|
243
|
+
});
|
|
244
|
+
rl.prompt();
|
|
245
|
+
}
|
|
246
|
+
async function main() {
|
|
247
|
+
let modelId = null;
|
|
248
|
+
let rl = null;
|
|
249
|
+
// Set up readline interface FIRST to keep event loop alive during model loading
|
|
250
|
+
rl = readline.createInterface({
|
|
251
|
+
input: process.stdin,
|
|
252
|
+
output: process.stdout,
|
|
253
|
+
});
|
|
254
|
+
try {
|
|
255
|
+
if (isStreamingMode) {
|
|
256
|
+
console.log("🎤 Streaming Transcription Microphone Demo");
|
|
257
|
+
console.log("✨ Mode: Real-time streaming transcription");
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
console.log("🎤 Record-and-Transcribe Microphone Demo");
|
|
261
|
+
console.log("✨ Mode: Record first, then transcribe");
|
|
262
|
+
console.log("💡 Tip: Use --stream flag for real-time transcription");
|
|
263
|
+
}
|
|
264
|
+
console.log("⚠️ Requirements:");
|
|
265
|
+
console.log(" - Microphone connected and accessible");
|
|
266
|
+
console.log(" - FFmpeg installed");
|
|
267
|
+
// Check FFmpeg availability
|
|
268
|
+
checkFFmpegAvailable();
|
|
269
|
+
// Download VAD model (asset download only - doesn't load into memory)
|
|
270
|
+
console.log("\n📥 Ensuring VAD model is available...");
|
|
271
|
+
await downloadAsset({ assetSrc: VAD_SILERO_5_1_2 });
|
|
272
|
+
// Load the Whisper model with VAD
|
|
273
|
+
console.log("\n📥 Loading Whisper model...");
|
|
274
|
+
modelId = await loadModel({
|
|
275
|
+
modelSrc: WHISPER_TINY,
|
|
276
|
+
modelType: "whisper",
|
|
277
|
+
modelConfig: {
|
|
278
|
+
mode: "caption",
|
|
279
|
+
update_frequency: "on_end",
|
|
280
|
+
audio_format: "f32le",
|
|
281
|
+
},
|
|
282
|
+
onProgress: (progress) => {
|
|
283
|
+
console.log(progress);
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
console.log(`✅ Whisper model loaded with ID: ${modelId}`);
|
|
287
|
+
// Start interactive session using the existing readline interface
|
|
288
|
+
console.log("\n🎧 Starting interactive session...");
|
|
289
|
+
startInteractiveSession(rl, modelId);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
console.error("❌ Error during transcription setup:", error instanceof Error ? error.message : String(error));
|
|
293
|
+
// Clean up on error
|
|
294
|
+
if (rl) {
|
|
295
|
+
rl.close();
|
|
296
|
+
}
|
|
297
|
+
if (modelId) {
|
|
298
|
+
console.log("\n🧹 Unloading Whisper model...");
|
|
299
|
+
await unloadModel({ modelId });
|
|
300
|
+
console.log("✅ Whisper model unloaded successfully");
|
|
301
|
+
}
|
|
302
|
+
process.exit(1);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// Handle graceful shutdown
|
|
306
|
+
process.on("SIGINT", () => {
|
|
307
|
+
console.log("\n🛑 Stopping microphone transcription...");
|
|
308
|
+
process.exit(0);
|
|
309
|
+
});
|
|
310
|
+
// Start the application
|
|
311
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as withMobileBundle } from "./withMobileBundle.js";
|
|
2
|
+
export { default as withOpenCL } from "./withOpenCL.js";
|
|
3
|
+
export { default as withQvacSDK } from "./withQvacSDK.js";
|
|
4
|
+
// Export the main plugin as default for easy usage
|
|
5
|
+
export { default } from "./withQvacSDK.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ExpoConfig } from "expo/config";
|
|
2
|
+
/**
|
|
3
|
+
* Expo plugin that automatically generates the mobile worker bundle during build
|
|
4
|
+
* using the user's installed bare library versions.
|
|
5
|
+
*/
|
|
6
|
+
declare function withMobileBundle(config: ExpoConfig): ExpoConfig;
|
|
7
|
+
export default withMobileBundle;
|
|
8
|
+
//# sourceMappingURL=withMobileBundle.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import configPlugins from "@expo/config-plugins";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
const { withDangerousMod } = configPlugins;
|
|
6
|
+
/**
|
|
7
|
+
* Expo plugin that automatically generates the mobile worker bundle during build
|
|
8
|
+
* using the user's installed bare library versions.
|
|
9
|
+
*/
|
|
10
|
+
function withMobileBundle(config) {
|
|
11
|
+
function buildMobileBundle(config) {
|
|
12
|
+
console.log("🕚 QVAC: Generating mobile worker bundle with current dependencies...");
|
|
13
|
+
const projectRoot = config.modRequest.projectRoot;
|
|
14
|
+
const qvacSdkPath = path.join(projectRoot, "node_modules", "@qvac/sdk");
|
|
15
|
+
// Ensure package exists
|
|
16
|
+
if (!fs.existsSync(qvacSdkPath)) {
|
|
17
|
+
throw new Error("@qvac/sdk not found in node_modules");
|
|
18
|
+
}
|
|
19
|
+
const workerPath = path.join(qvacSdkPath, "dist", "server", "worker.js");
|
|
20
|
+
const outputPath = path.join(qvacSdkPath, "dist/worker.mobile.bundle.js");
|
|
21
|
+
// Check if worker.js exists
|
|
22
|
+
if (!fs.existsSync(workerPath)) {
|
|
23
|
+
throw new Error(`Worker file not found at ${workerPath}`);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
// Truncate incompatible RPC clients for mobile (keep only rpc-client.js and expo-rpc-client.js)
|
|
27
|
+
const rpcClientsToTruncate = [
|
|
28
|
+
"node-rpc-client.js",
|
|
29
|
+
"bare-rpc-client.js",
|
|
30
|
+
"bare-client.js",
|
|
31
|
+
];
|
|
32
|
+
const truncatedContent = "// This RPC client is not available in mobile environments";
|
|
33
|
+
for (const clientFile of rpcClientsToTruncate) {
|
|
34
|
+
const clientPath = path.join(qvacSdkPath, "dist", "client", "rpc", clientFile);
|
|
35
|
+
if (fs.existsSync(clientPath)) {
|
|
36
|
+
fs.writeFileSync(clientPath, truncatedContent);
|
|
37
|
+
console.log(`🔧 QVAC: Truncated ${clientFile} for mobile compatibility`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Remove optional modules from the bundle
|
|
41
|
+
const optionalModules = ["crypto"];
|
|
42
|
+
const deferFlags = optionalModules
|
|
43
|
+
.map((mod) => `--defer "${mod}"`)
|
|
44
|
+
.join(" ");
|
|
45
|
+
// Generate the bundle using bun bare-pack with the current project's dependencies
|
|
46
|
+
// We use the project root as working directory so bare-pack uses the user's node_modules
|
|
47
|
+
execSync(`cd "${projectRoot}" && npx bare-pack --target android-arm64 --target ios-arm64 --target ios-arm64-simulator --linked ${deferFlags} --out "${outputPath}" "${workerPath}"`, { stdio: "inherit", cwd: projectRoot });
|
|
48
|
+
console.log("🫡 QVAC: Mobile worker bundle generated successfully");
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error("❌ QVAC: Failed to generate mobile worker bundle:", error);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
return config;
|
|
55
|
+
}
|
|
56
|
+
config = withDangerousMod(config, ["android", buildMobileBundle]);
|
|
57
|
+
config = withDangerousMod(config, ["ios", buildMobileBundle]);
|
|
58
|
+
return config;
|
|
59
|
+
}
|
|
60
|
+
export default withMobileBundle;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ExpoConfig } from "expo/config";
|
|
2
|
+
/**
|
|
3
|
+
* Plugin to add OpenCL native library support to Android build
|
|
4
|
+
* This plugin was written by the most helpful folk in the QVAC team: Luis Moromisato.
|
|
5
|
+
* Thank you Luis!
|
|
6
|
+
*/
|
|
7
|
+
declare function withOpenCL(config: ExpoConfig): ExpoConfig;
|
|
8
|
+
export default withOpenCL;
|
|
9
|
+
//# sourceMappingURL=withOpenCL.d.ts.map
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import configPlugins from "@expo/config-plugins";
|
|
2
|
+
const { withAndroidManifest, withAppBuildGradle } = configPlugins;
|
|
3
|
+
/**
|
|
4
|
+
* Plugin to add OpenCL native library support to Android build
|
|
5
|
+
* This plugin was written by the most helpful folk in the QVAC team: Luis Moromisato.
|
|
6
|
+
* Thank you Luis!
|
|
7
|
+
*/
|
|
8
|
+
function withOpenCL(config) {
|
|
9
|
+
config = withOpenCLAndroidManifest(config);
|
|
10
|
+
config = withOpenCLBuildGradle(config);
|
|
11
|
+
return config;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Modify AndroidManifest.xml to include OpenCL native library
|
|
15
|
+
*/
|
|
16
|
+
function withOpenCLAndroidManifest(config) {
|
|
17
|
+
return withAndroidManifest(config, (config) => {
|
|
18
|
+
const androidManifest = config.modResults;
|
|
19
|
+
// Find the application element
|
|
20
|
+
const application = androidManifest.manifest.application?.[0];
|
|
21
|
+
if (application) {
|
|
22
|
+
// Type assertion for dynamic manifest properties
|
|
23
|
+
const appWithNativeLibs = application;
|
|
24
|
+
// Check if uses-native-library already exists
|
|
25
|
+
const existingNativeLib = appWithNativeLibs["uses-native-library"]?.find((lib) => lib.$["android:name"] === "libOpenCL.so");
|
|
26
|
+
if (!existingNativeLib) {
|
|
27
|
+
// Add uses-native-library if it doesn't exist
|
|
28
|
+
if (!appWithNativeLibs["uses-native-library"]) {
|
|
29
|
+
appWithNativeLibs["uses-native-library"] = [];
|
|
30
|
+
}
|
|
31
|
+
appWithNativeLibs["uses-native-library"].push({
|
|
32
|
+
$: {
|
|
33
|
+
"android:name": "libOpenCL.so",
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return config;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Modify build.gradle to exclude OpenCL library from packaging
|
|
43
|
+
* FIXED VERSION: Properly handles existing packagingOptions blocks
|
|
44
|
+
*/
|
|
45
|
+
function withOpenCLBuildGradle(config) {
|
|
46
|
+
return withAppBuildGradle(config, (config) => {
|
|
47
|
+
let buildGradleContent = config.modResults.contents;
|
|
48
|
+
// Check if the exclusion already exists anywhere in the file
|
|
49
|
+
if (buildGradleContent.includes('excludes += "/lib/**/libOpenCL.so"')) {
|
|
50
|
+
console.log("[withOpenCL] OpenCL exclusion already exists in build.gradle");
|
|
51
|
+
return config;
|
|
52
|
+
}
|
|
53
|
+
// Find ALL packagingOptions blocks in the android block
|
|
54
|
+
const androidBlockMatch = buildGradleContent.match(/android\s*{([\s\S]*?)^}/m);
|
|
55
|
+
if (!androidBlockMatch) {
|
|
56
|
+
console.error("[withOpenCL] Could not find android block in build.gradle");
|
|
57
|
+
return config;
|
|
58
|
+
}
|
|
59
|
+
const androidBlockContent = androidBlockMatch[1];
|
|
60
|
+
// Check if there's already a packagingOptions block with jniLibs
|
|
61
|
+
const existingJniLibsMatch = androidBlockContent?.match(/packagingOptions\s*{[\s\S]*?jniLibs\s*{[\s\S]*?}/g);
|
|
62
|
+
if (existingJniLibsMatch && existingJniLibsMatch.length > 0) {
|
|
63
|
+
// Find the FIRST packagingOptions block with jniLibs and modify it
|
|
64
|
+
// This ensures we don't create duplicate blocks
|
|
65
|
+
const firstJniLibsBlockRegex = /(packagingOptions\s*{[\s\S]*?jniLibs\s*{[\s\S]*?)(})/;
|
|
66
|
+
buildGradleContent = buildGradleContent.replace(firstJniLibsBlockRegex, (match, before, closing) => {
|
|
67
|
+
// Check if this specific block already has the exclusion
|
|
68
|
+
if (match.includes('excludes += "/lib/**/libOpenCL.so"')) {
|
|
69
|
+
return match;
|
|
70
|
+
}
|
|
71
|
+
// Add the exclusion before the closing brace of jniLibs
|
|
72
|
+
return (before +
|
|
73
|
+
' excludes += "/lib/**/libOpenCL.so"\n ' +
|
|
74
|
+
closing);
|
|
75
|
+
});
|
|
76
|
+
console.log("[withOpenCL] Added OpenCL exclusion to existing packagingOptions block");
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// No existing packagingOptions with jniLibs found
|
|
80
|
+
// Check if there's ANY packagingOptions block
|
|
81
|
+
const anyPackagingOptionsMatch = androidBlockContent?.match(/packagingOptions\s*{[\s\S]*?}/);
|
|
82
|
+
if (anyPackagingOptionsMatch) {
|
|
83
|
+
// Add jniLibs section to existing packagingOptions
|
|
84
|
+
const packagingOptionsRegex = /(packagingOptions\s*{)([\s\S]*?)(^\s*})/m;
|
|
85
|
+
buildGradleContent = buildGradleContent.replace(packagingOptionsRegex, (_, opening, content, closing) => {
|
|
86
|
+
const jniLibsSection = `
|
|
87
|
+
jniLibs {
|
|
88
|
+
def enableLegacyPackaging = findProperty('expo.useLegacyPackaging') ?: 'false'
|
|
89
|
+
useLegacyPackaging enableLegacyPackaging.toBoolean()
|
|
90
|
+
excludes += "/lib/**/libOpenCL.so"
|
|
91
|
+
}`;
|
|
92
|
+
return opening + content + jniLibsSection + "\n" + closing;
|
|
93
|
+
});
|
|
94
|
+
console.log("[withOpenCL] Added jniLibs section to existing packagingOptions block");
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// No packagingOptions at all, add a new one before the closing of android block
|
|
98
|
+
const androidBlockRegex = /(android\s*{[\s\S]*?)(^})/m;
|
|
99
|
+
buildGradleContent = buildGradleContent.replace(androidBlockRegex, (_, before, closing) => {
|
|
100
|
+
const packagingConfig = `
|
|
101
|
+
packagingOptions {
|
|
102
|
+
jniLibs {
|
|
103
|
+
def enableLegacyPackaging = findProperty('expo.useLegacyPackaging') ?: 'false'
|
|
104
|
+
useLegacyPackaging enableLegacyPackaging.toBoolean()
|
|
105
|
+
excludes += "/lib/**/libOpenCL.so"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
`;
|
|
109
|
+
return before + packagingConfig + closing;
|
|
110
|
+
});
|
|
111
|
+
console.log("[withOpenCL] Added new packagingOptions block with OpenCL exclusion");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
config.modResults.contents = buildGradleContent;
|
|
115
|
+
return config;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
export default withOpenCL;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ExpoConfig } from "expo/config";
|
|
2
|
+
/**
|
|
3
|
+
* Main Qvac SDK Expo plugin that combines all necessary mobile configurations:
|
|
4
|
+
* - Mobile worker bundle generation
|
|
5
|
+
* - OpenCL native library support for Android
|
|
6
|
+
*/
|
|
7
|
+
declare function withQvacSDK(config: ExpoConfig): ExpoConfig;
|
|
8
|
+
export default withQvacSDK;
|
|
9
|
+
//# sourceMappingURL=withQvacSDK.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import configPlugins from "@expo/config-plugins";
|
|
2
|
+
import withMobileBundle from "./withMobileBundle.js";
|
|
3
|
+
import withOpenCL from "./withOpenCL.js";
|
|
4
|
+
const { withPlugins } = configPlugins;
|
|
5
|
+
/**
|
|
6
|
+
* Main Qvac SDK Expo plugin that combines all necessary mobile configurations:
|
|
7
|
+
* - Mobile worker bundle generation
|
|
8
|
+
* - OpenCL native library support for Android
|
|
9
|
+
*/
|
|
10
|
+
function withQvacSDK(config) {
|
|
11
|
+
return withPlugins(config, [withMobileBundle, withOpenCL]);
|
|
12
|
+
}
|
|
13
|
+
export default withQvacSDK;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { completion, loadModel, downloadAsset, ping, startQVACProvider, unloadModel, transcribe, transcribeStream, embed, translate, cancel, ragSaveEmbeddings, ragSearch, ragDeleteEmbeddings, } from "./client/api/index";
|
|
2
|
+
export { type ModelProgressUpdate, type LoadModelOptions, type DownloadAssetOptions, type Tool, VERBOSITY, type Attachment, type CompletionParams, type RagSearchResult, type RagSaveEmbeddingsResult, } from "./schemas/index";
|
|
3
|
+
export * from "./models/hyperdrive/index";
|
|
4
|
+
export { SUPPORTED_AUDIO_FORMATS } from "./constants/audio";
|
|
5
|
+
export { getLogger, setGlobalLogLevel } from "./logging/index";
|
|
6
|
+
export type { Logger, LogTransport, LoggerOptions } from "./logging/index";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Public API exports only
|
|
2
|
+
export { completion, loadModel, downloadAsset, ping, startQVACProvider, unloadModel, transcribe, transcribeStream, embed, translate, cancel, ragSaveEmbeddings, ragSearch, ragDeleteEmbeddings, } from "./client/api/index.js";
|
|
3
|
+
export { VERBOSITY, } from "./schemas/index.js";
|
|
4
|
+
// Hyperdrive model constants
|
|
5
|
+
export * from "./models/hyperdrive/index.js";
|
|
6
|
+
export { SUPPORTED_AUDIO_FORMATS } from "./constants/audio.js";
|
|
7
|
+
// Logging exports
|
|
8
|
+
export { getLogger, setGlobalLogLevel } from "./logging/index.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type LogLevel } from "@qvac/logging";
|
|
2
|
+
import type { Logger, LoggerOptions } from "./types";
|
|
3
|
+
export interface LoggerExtensions {
|
|
4
|
+
onLog?: (level: LogLevel, namespace: string, message: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function createBaseLogger(namespace: string, options?: LoggerOptions, extensions?: LoggerExtensions): Logger;
|
|
7
|
+
//# sourceMappingURL=base-logger.d.ts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import QvacLogger, {} from "@qvac/logging";
|
|
2
|
+
import { LOG_LEVELS } from "@qvac/logging/constants.js";
|
|
3
|
+
import { isLevelEnabled, formatArg } from "./utils.js";
|
|
4
|
+
export function createBaseLogger(namespace, options, extensions) {
|
|
5
|
+
const qvacLogger = new QvacLogger(console);
|
|
6
|
+
const initialLevel = options?.level ?? LOG_LEVELS.INFO;
|
|
7
|
+
qvacLogger.setLevel(initialLevel);
|
|
8
|
+
const transports = options?.transports || [];
|
|
9
|
+
const log = (level, ...args) => {
|
|
10
|
+
if (!isLevelEnabled(level, qvacLogger.getLevel())) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const message = args.map(formatArg).join(" ");
|
|
14
|
+
switch (level) {
|
|
15
|
+
case LOG_LEVELS.ERROR:
|
|
16
|
+
qvacLogger.error(`[${namespace}]`, ...args);
|
|
17
|
+
break;
|
|
18
|
+
case LOG_LEVELS.WARN:
|
|
19
|
+
qvacLogger.warn(`[${namespace}]`, ...args);
|
|
20
|
+
break;
|
|
21
|
+
case LOG_LEVELS.INFO:
|
|
22
|
+
qvacLogger.info(`[${namespace}]`, ...args);
|
|
23
|
+
break;
|
|
24
|
+
case LOG_LEVELS.DEBUG:
|
|
25
|
+
qvacLogger.debug(`[${namespace}]`, ...args);
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
extensions?.onLog?.(level, namespace, message);
|
|
29
|
+
for (const transport of transports) {
|
|
30
|
+
try {
|
|
31
|
+
const result = transport(level, namespace, message);
|
|
32
|
+
if (result instanceof Promise) {
|
|
33
|
+
result.catch((error) => {
|
|
34
|
+
console.error(`Transport error in ${namespace}:`, error);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(`Transport error in ${namespace}:`, error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
error: (...args) => log(LOG_LEVELS.ERROR, ...args),
|
|
45
|
+
warn: (...args) => log(LOG_LEVELS.WARN, ...args),
|
|
46
|
+
info: (...args) => log(LOG_LEVELS.INFO, ...args),
|
|
47
|
+
debug: (...args) => log(LOG_LEVELS.DEBUG, ...args),
|
|
48
|
+
trace: (...args) => log(LOG_LEVELS.DEBUG, ...args),
|
|
49
|
+
setLevel: (level) => qvacLogger.setLevel(level),
|
|
50
|
+
getLevel: () => qvacLogger.getLevel(),
|
|
51
|
+
addTransport: (transport) => {
|
|
52
|
+
transports.push(transport);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LogLevel } from "@qvac/logging";
|
|
2
|
+
import type { Logger, LoggerOptions } from "./types";
|
|
3
|
+
export declare function getLogger(namespace: string, options?: LoggerOptions): Logger;
|
|
4
|
+
export declare function setGlobalLogLevel(level: LogLevel): void;
|
|
5
|
+
//# sourceMappingURL=logger.d.ts.map
|