@storyteller-platform/ghost-story 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/LICENSE.md +611 -0
  2. package/README.md +18 -0
  3. package/dist/api/APIOptions.cjs +16 -0
  4. package/dist/api/APIOptions.d.cts +18 -0
  5. package/dist/api/APIOptions.d.ts +18 -0
  6. package/dist/api/APIOptions.js +0 -0
  7. package/dist/api/Recognition.cjs +263 -0
  8. package/dist/api/Recognition.d.cts +77 -0
  9. package/dist/api/Recognition.d.ts +77 -0
  10. package/dist/api/Recognition.js +233 -0
  11. package/dist/api/VoiceActivityDetection.cjs +77 -0
  12. package/dist/api/VoiceActivityDetection.d.cts +24 -0
  13. package/dist/api/VoiceActivityDetection.d.ts +24 -0
  14. package/dist/api/VoiceActivityDetection.js +43 -0
  15. package/dist/audio/AudioConverter.cjs +331 -0
  16. package/dist/audio/AudioConverter.d.cts +53 -0
  17. package/dist/audio/AudioConverter.d.ts +53 -0
  18. package/dist/audio/AudioConverter.js +310 -0
  19. package/dist/audio/AudioFormat.cjs +151 -0
  20. package/dist/audio/AudioFormat.d.cts +25 -0
  21. package/dist/audio/AudioFormat.d.ts +25 -0
  22. package/dist/audio/AudioFormat.js +123 -0
  23. package/dist/audio/AudioSource.cjs +119 -0
  24. package/dist/audio/AudioSource.d.cts +33 -0
  25. package/dist/audio/AudioSource.d.ts +33 -0
  26. package/dist/audio/AudioSource.js +88 -0
  27. package/dist/audio/index.cjs +74 -0
  28. package/dist/audio/index.d.cts +6 -0
  29. package/dist/audio/index.d.ts +6 -0
  30. package/dist/audio/index.js +54 -0
  31. package/dist/cli/bin.cjs +277 -0
  32. package/dist/cli/bin.d.cts +1 -0
  33. package/dist/cli/bin.d.ts +1 -0
  34. package/dist/cli/bin.js +275 -0
  35. package/dist/cli/config.cjs +347 -0
  36. package/dist/cli/config.d.cts +33 -0
  37. package/dist/cli/config.d.ts +33 -0
  38. package/dist/cli/config.js +285 -0
  39. package/dist/cli/install.cjs +334 -0
  40. package/dist/cli/install.d.cts +62 -0
  41. package/dist/cli/install.d.ts +62 -0
  42. package/dist/cli/install.js +316 -0
  43. package/dist/cli/whisper-server.cjs +172 -0
  44. package/dist/cli/whisper-server.d.cts +24 -0
  45. package/dist/cli/whisper-server.d.ts +24 -0
  46. package/dist/cli/whisper-server.js +152 -0
  47. package/dist/config.cjs +60 -0
  48. package/dist/config.d.cts +12 -0
  49. package/dist/config.d.ts +12 -0
  50. package/dist/config.js +32 -0
  51. package/dist/convert.cjs +88 -0
  52. package/dist/convert.d.cts +12 -0
  53. package/dist/convert.d.ts +12 -0
  54. package/dist/convert.js +63 -0
  55. package/dist/encodings/Ascii.cjs +75 -0
  56. package/dist/encodings/Ascii.d.cts +13 -0
  57. package/dist/encodings/Ascii.d.ts +13 -0
  58. package/dist/encodings/Ascii.js +48 -0
  59. package/dist/encodings/Base64.cjs +155 -0
  60. package/dist/encodings/Base64.d.cts +5 -0
  61. package/dist/encodings/Base64.d.ts +5 -0
  62. package/dist/encodings/Base64.js +129 -0
  63. package/dist/encodings/TextEncodingsCommon.cjs +16 -0
  64. package/dist/encodings/TextEncodingsCommon.d.cts +6 -0
  65. package/dist/encodings/TextEncodingsCommon.d.ts +6 -0
  66. package/dist/encodings/TextEncodingsCommon.js +0 -0
  67. package/dist/index.cjs +153 -0
  68. package/dist/index.d.cts +15 -0
  69. package/dist/index.d.ts +15 -0
  70. package/dist/index.js +140 -0
  71. package/dist/recognition/AmazonTranscribeSTT.cjs +188 -0
  72. package/dist/recognition/AmazonTranscribeSTT.d.cts +21 -0
  73. package/dist/recognition/AmazonTranscribeSTT.d.ts +21 -0
  74. package/dist/recognition/AmazonTranscribeSTT.js +160 -0
  75. package/dist/recognition/AzureCognitiveServicesSTT.cjs +124 -0
  76. package/dist/recognition/AzureCognitiveServicesSTT.d.cts +21 -0
  77. package/dist/recognition/AzureCognitiveServicesSTT.d.ts +21 -0
  78. package/dist/recognition/AzureCognitiveServicesSTT.js +95 -0
  79. package/dist/recognition/DeepgramSTT.cjs +172 -0
  80. package/dist/recognition/DeepgramSTT.d.cts +23 -0
  81. package/dist/recognition/DeepgramSTT.d.ts +23 -0
  82. package/dist/recognition/DeepgramSTT.js +153 -0
  83. package/dist/recognition/GoogleCloudSTT.cjs +125 -0
  84. package/dist/recognition/GoogleCloudSTT.d.cts +35 -0
  85. package/dist/recognition/GoogleCloudSTT.d.ts +35 -0
  86. package/dist/recognition/GoogleCloudSTT.js +107 -0
  87. package/dist/recognition/OpenAICloudSTT.cjs +180 -0
  88. package/dist/recognition/OpenAICloudSTT.d.cts +29 -0
  89. package/dist/recognition/OpenAICloudSTT.d.ts +29 -0
  90. package/dist/recognition/OpenAICloudSTT.js +150 -0
  91. package/dist/recognition/WhisperCppSTT.cjs +296 -0
  92. package/dist/recognition/WhisperCppSTT.d.cts +40 -0
  93. package/dist/recognition/WhisperCppSTT.d.ts +40 -0
  94. package/dist/recognition/WhisperCppSTT.js +275 -0
  95. package/dist/recognition/WhisperServerSTT.cjs +119 -0
  96. package/dist/recognition/WhisperServerSTT.d.cts +24 -0
  97. package/dist/recognition/WhisperServerSTT.d.ts +24 -0
  98. package/dist/recognition/WhisperServerSTT.js +105 -0
  99. package/dist/utilities/FileSystem.cjs +54 -0
  100. package/dist/utilities/FileSystem.d.cts +3 -0
  101. package/dist/utilities/FileSystem.d.ts +3 -0
  102. package/dist/utilities/FileSystem.js +20 -0
  103. package/dist/utilities/Locale.cjs +46 -0
  104. package/dist/utilities/Locale.d.cts +9 -0
  105. package/dist/utilities/Locale.d.ts +9 -0
  106. package/dist/utilities/Locale.js +20 -0
  107. package/dist/utilities/ObjectUtilities.cjs +41 -0
  108. package/dist/utilities/ObjectUtilities.d.cts +3 -0
  109. package/dist/utilities/ObjectUtilities.d.ts +3 -0
  110. package/dist/utilities/ObjectUtilities.js +7 -0
  111. package/dist/utilities/Timeline.cjs +120 -0
  112. package/dist/utilities/Timeline.d.cts +23 -0
  113. package/dist/utilities/Timeline.d.ts +23 -0
  114. package/dist/utilities/Timeline.js +94 -0
  115. package/dist/utilities/Timing.cjs +287 -0
  116. package/dist/utilities/Timing.d.cts +64 -0
  117. package/dist/utilities/Timing.d.ts +64 -0
  118. package/dist/utilities/Timing.js +256 -0
  119. package/dist/utilities/WhisperTimeline.cjs +344 -0
  120. package/dist/utilities/WhisperTimeline.d.cts +86 -0
  121. package/dist/utilities/WhisperTimeline.d.ts +86 -0
  122. package/dist/utilities/WhisperTimeline.js +313 -0
  123. package/dist/vad/ActiveGate.cjs +357 -0
  124. package/dist/vad/ActiveGate.d.cts +53 -0
  125. package/dist/vad/ActiveGate.d.ts +53 -0
  126. package/dist/vad/ActiveGate.js +329 -0
  127. package/dist/vad/ActiveGateOg.cjs +1366 -0
  128. package/dist/vad/ActiveGateOg.d.cts +33 -0
  129. package/dist/vad/ActiveGateOg.d.ts +33 -0
  130. package/dist/vad/ActiveGateOg.js +1341 -0
  131. package/dist/vad/Silero.cjs +174 -0
  132. package/dist/vad/Silero.d.cts +25 -0
  133. package/dist/vad/Silero.d.ts +25 -0
  134. package/dist/vad/Silero.js +153 -0
  135. package/package.json +125 -0
@@ -0,0 +1,285 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync, readdirSync } from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { getAppDataDir } from "../utilities/FileSystem.js";
6
+ const WHISPER_CPP_VERSION = "1.8.2";
7
+ const WHISPER_MODEL_VERSION = "1.0.0";
8
+ const SILERO_VAD_VERSION = "6.2.0";
9
+ const GITLAB_PROJECT_PATH = "storyteller-platform/storyteller";
10
+ const GITLAB_PROJECT_ID = "67994333";
11
+ const GITLAB_WHIPSER_ML_ID = "2007349";
12
+ const BUILD_VARIANTS = [
13
+ "darwin-arm64-coreml",
14
+ "darwin-arm64-cpu",
15
+ "darwin-x64-cpu",
16
+ "linux-x64-cuda-12.4.0",
17
+ "linux-x64-cuda-11.8.0",
18
+ "linux-x64-vulkan",
19
+ "linux-x64-rocm",
20
+ "linux-x64-cpu",
21
+ "linux-arm64-cpu",
22
+ "windows-x64-cpu",
23
+ "windows-x64-cuda-12.4.0",
24
+ "windows-x64-cuda-11.8.0",
25
+ "windows-x64-vulkan"
26
+ ];
27
+ function getVariantPlatformInfo(variant) {
28
+ if (variant.startsWith("darwin-arm64")) {
29
+ return { platform: "darwin", arch: "arm64" };
30
+ }
31
+ if (variant.startsWith("darwin-x64")) {
32
+ return { platform: "darwin", arch: "x64" };
33
+ }
34
+ if (variant.startsWith("linux-arm64")) {
35
+ return { platform: "linux", arch: "arm64" };
36
+ }
37
+ if (variant.startsWith("linux-x64")) {
38
+ return { platform: "linux", arch: "x64" };
39
+ }
40
+ if (variant.startsWith("windows-arm64")) {
41
+ return { platform: "win32", arch: "arm64" };
42
+ }
43
+ if (variant.startsWith("windows-x64")) {
44
+ return { platform: "win32", arch: "x64" };
45
+ }
46
+ throw new Error(`Unknown variant: ${variant}`);
47
+ }
48
+ function isVariantCompatibleWithCurrentPlatform(variant) {
49
+ const currentPlatform = process.platform;
50
+ const currentArch = process.arch;
51
+ const variantInfo = getVariantPlatformInfo(variant);
52
+ return variantInfo.platform === currentPlatform && variantInfo.arch === currentArch;
53
+ }
54
+ function getCompatibleVariants() {
55
+ return BUILD_VARIANTS.filter(isVariantCompatibleWithCurrentPlatform);
56
+ }
57
+ const WHISPER_MODELS = [
58
+ "tiny",
59
+ "tiny.en",
60
+ "tiny-q5_1",
61
+ "tiny.en-q5_1",
62
+ "tiny-q8_0",
63
+ "base",
64
+ "base.en",
65
+ "base-q5_1",
66
+ "base.en-q5_1",
67
+ "base-q8_0",
68
+ "small",
69
+ "small.en",
70
+ "small-q5_1",
71
+ "small.en-q5_1",
72
+ "small-q8_0",
73
+ "medium",
74
+ "medium.en",
75
+ "medium-q5_0",
76
+ "medium.en-q5_0",
77
+ "medium-q8_0",
78
+ "large-v1",
79
+ "large-v2",
80
+ "large-v2-q5_0",
81
+ "large-v2-q8_0",
82
+ "large-v3",
83
+ "large-v3-q5_0",
84
+ "large-v3-turbo",
85
+ "large-v3-turbo-q5_0",
86
+ "large-v3-turbo-q8_0"
87
+ ];
88
+ const MODEL_SIZES = {
89
+ tiny: 77691713,
90
+ "tiny-q5_1": 32152673,
91
+ "tiny.en": 77704715,
92
+ "tiny.en-q5_1": 32166155,
93
+ "tiny-q8_0": 43537433,
94
+ base: 147951465,
95
+ "base.en": 147964211,
96
+ "base-q5_1": 59707625,
97
+ "base.en-q5_1": 59721011,
98
+ "base-q8_0": 81768585,
99
+ small: 487601967,
100
+ "small.en": 487614201,
101
+ "small-q5_1": 190085487,
102
+ "small.en-q5_1": 190098681,
103
+ "small-q8_0": 264464607,
104
+ medium: 1533763059,
105
+ "medium.en": 1533774781,
106
+ "medium-q5_0": 539212467,
107
+ "medium.en-q5_0": 539225533,
108
+ "medium-q8_0": 823369779,
109
+ "large-v1": 3094623691,
110
+ "large-v2": 3094623691,
111
+ "large-v2-q5_0": 1080732091,
112
+ "large-v2-q8_0": 1656129691,
113
+ "large-v3": 3095033483,
114
+ "large-v3-q5_0": 1081140203,
115
+ "large-v3-turbo": 1624555275,
116
+ "large-v3-turbo-q5_0": 574041195,
117
+ "large-v3-turbo-q8_0": 874188075,
118
+ "silero-vad": 884595
119
+ };
120
+ function getBinaryDownloadUrl(variant) {
121
+ const filename = `whisper-cpp-${variant}.tar.gz`;
122
+ return `https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/packages/generic/whisper-cpp/${WHISPER_CPP_VERSION}/${filename}`;
123
+ }
124
+ function getModelDownloadUrl(model) {
125
+ const filename = `ggml-${model}.bin`;
126
+ return `https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/packages/ml_models/${GITLAB_WHIPSER_ML_ID}/files/${filename}`;
127
+ }
128
+ function getCoremlModelDownloadUrl(model) {
129
+ const filename = `ggml-${model}-encoder.mlmodelc.tar.gz`;
130
+ return `https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/packages/ml_models/${GITLAB_WHIPSER_ML_ID}/files/coreml/${filename}`;
131
+ }
132
+ function getVadModelDownloadUrl() {
133
+ return `https://huggingface.co/ggml-org/whisper-vad/resolve/main/ggml-silero-v${SILERO_VAD_VERSION}.bin`;
134
+ }
135
+ function getWhisperBaseDir() {
136
+ return path.join(
137
+ getAppDataDir("ghost-story"),
138
+ "whisper-cpp",
139
+ WHISPER_CPP_VERSION
140
+ );
141
+ }
142
+ function getInstallDir(variant) {
143
+ const baseDir = getWhisperBaseDir();
144
+ if (variant) {
145
+ return path.join(baseDir, variant);
146
+ }
147
+ const installed = getInstalledVariant();
148
+ if (installed) {
149
+ return path.join(baseDir, installed);
150
+ }
151
+ return path.join(baseDir, detectPlatform());
152
+ }
153
+ function getInstalledVariant() {
154
+ const baseDir = getWhisperBaseDir();
155
+ if (!existsSync(baseDir)) {
156
+ return null;
157
+ }
158
+ const entries = readdirSync(baseDir, { withFileTypes: true });
159
+ for (const entry of entries) {
160
+ if (!entry.isDirectory()) continue;
161
+ const variant = entry.name;
162
+ if (!BUILD_VARIANTS.includes(variant)) continue;
163
+ const execPath = getWhisperExecutablePath(path.join(baseDir, variant));
164
+ if (existsSync(execPath)) {
165
+ return variant;
166
+ }
167
+ }
168
+ return null;
169
+ }
170
+ function getModelDir() {
171
+ return path.join(getAppDataDir("ghost-story"), "models");
172
+ }
173
+ function getWhisperExecutablePath(installDir) {
174
+ const dir = installDir ?? getInstallDir();
175
+ const isWindows = os.platform() === "win32";
176
+ const executable = isWindows ? "whisper-cli.exe" : "whisper-cli";
177
+ return path.join(dir, "bin", executable);
178
+ }
179
+ function getVadExecutablePath(installDir) {
180
+ const dir = installDir ?? getInstallDir();
181
+ const isWindows = os.platform() === "win32";
182
+ const executable = isWindows ? "vad-speech-segments.exe" : "vad-speech-segments";
183
+ return path.join(dir, "bin", executable);
184
+ }
185
+ function getWhisperServerExecutablePath(installDir) {
186
+ const dir = installDir ?? getInstallDir();
187
+ const isWindows = os.platform() === "win32";
188
+ const executable = isWindows ? "whisper-server.exe" : "whisper-server";
189
+ return path.join(dir, "bin", executable);
190
+ }
191
+ function getModelPath(model, modelDir) {
192
+ const dir = modelDir ?? getModelDir();
193
+ return path.join(dir, `ggml-${model}.bin`);
194
+ }
195
+ function getCoremlModelPath(model, modelDir) {
196
+ const dir = modelDir ?? getModelDir();
197
+ return path.join(dir, `ggml-${model}-encoder.mlmodelc`);
198
+ }
199
+ function needsCoremlModel(variant) {
200
+ const v = variant ?? getInstalledVariant() ?? detectPlatform();
201
+ return v.includes("coreml");
202
+ }
203
+ function getVadModelPath(modelDir) {
204
+ const dir = modelDir ?? getModelDir();
205
+ return path.join(dir, `ggml-silero-v${SILERO_VAD_VERSION}.bin`);
206
+ }
207
+ function hasCuda() {
208
+ try {
209
+ execSync("nvidia-smi", { stdio: "ignore" });
210
+ return true;
211
+ } catch {
212
+ return false;
213
+ }
214
+ }
215
+ function hasVulkan() {
216
+ try {
217
+ execSync("vulkaninfo --summary", { stdio: "ignore" });
218
+ return true;
219
+ } catch {
220
+ return false;
221
+ }
222
+ }
223
+ function detectPlatform() {
224
+ const platform = process.platform;
225
+ const arch = process.arch;
226
+ if (platform === "darwin") {
227
+ return arch === "arm64" ? "darwin-arm64-coreml" : "darwin-x64-cpu";
228
+ }
229
+ if (platform === "linux") {
230
+ if (hasCuda()) {
231
+ return "linux-x64-cuda-12.4.0";
232
+ }
233
+ if (hasVulkan()) {
234
+ return "linux-x64-vulkan";
235
+ }
236
+ return arch === "arm64" ? "linux-arm64-cpu" : "linux-x64-cpu";
237
+ }
238
+ if (platform === "win32") {
239
+ if (hasCuda()) {
240
+ return "windows-x64-cuda-12.4.0";
241
+ }
242
+ if (hasVulkan()) {
243
+ return "windows-x64-vulkan";
244
+ }
245
+ return "windows-x64-cpu";
246
+ }
247
+ throw new Error(`Unsupported platform: ${platform}-${arch}`);
248
+ }
249
+ function isValidModel(model) {
250
+ return WHISPER_MODELS.includes(model);
251
+ }
252
+ function isValidVariant(variant) {
253
+ return BUILD_VARIANTS.includes(variant);
254
+ }
255
+ export {
256
+ BUILD_VARIANTS,
257
+ GITLAB_PROJECT_ID,
258
+ GITLAB_PROJECT_PATH,
259
+ GITLAB_WHIPSER_ML_ID,
260
+ MODEL_SIZES,
261
+ SILERO_VAD_VERSION,
262
+ WHISPER_CPP_VERSION,
263
+ WHISPER_MODELS,
264
+ WHISPER_MODEL_VERSION,
265
+ detectPlatform,
266
+ getBinaryDownloadUrl,
267
+ getCompatibleVariants,
268
+ getCoremlModelDownloadUrl,
269
+ getCoremlModelPath,
270
+ getInstallDir,
271
+ getInstalledVariant,
272
+ getModelDir,
273
+ getModelDownloadUrl,
274
+ getModelPath,
275
+ getVadExecutablePath,
276
+ getVadModelDownloadUrl,
277
+ getVadModelPath,
278
+ getWhisperBaseDir,
279
+ getWhisperExecutablePath,
280
+ getWhisperServerExecutablePath,
281
+ isValidModel,
282
+ isValidVariant,
283
+ isVariantCompatibleWithCurrentPlatform,
284
+ needsCoremlModel
285
+ };
@@ -0,0 +1,334 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var install_exports = {};
30
+ __export(install_exports, {
31
+ PlatformMismatchError: () => PlatformMismatchError,
32
+ downloadFile: () => downloadFile,
33
+ ensureWhisperInstalled: () => ensureWhisperInstalled,
34
+ installBinary: () => installBinary,
35
+ installCoremlModel: () => installCoremlModel,
36
+ installModel: () => installModel,
37
+ installVadModel: () => installVadModel
38
+ });
39
+ module.exports = __toCommonJS(install_exports);
40
+ var import_node_fs = require("node:fs");
41
+ var import_promises = require("node:fs/promises");
42
+ var import_node_os = __toESM(require("node:os"), 1);
43
+ var import_node_path = __toESM(require("node:path"), 1);
44
+ var import_promises2 = require("node:stream/promises");
45
+ var import_node_zlib = require("node:zlib");
46
+ var import_tar = require("tar");
47
+ var import_config = require("./config.cjs");
48
+ async function downloadFile(options) {
49
+ const {
50
+ url,
51
+ destPath,
52
+ expectedSize,
53
+ printOutput = true,
54
+ onProgress,
55
+ signal
56
+ } = options;
57
+ console.log(`Downloading file from ${url} to ${destPath}`);
58
+ const response = await fetch(url, { signal: signal ?? null });
59
+ if (!response.ok) {
60
+ throw new Error(
61
+ `Failed to download: ${response.status} ${response.statusText}`
62
+ );
63
+ }
64
+ const contentLength = response.headers.get("content-length");
65
+ const totalSize = contentLength ? parseInt(contentLength, 10) : expectedSize ?? 0;
66
+ if (!response.body) {
67
+ throw new Error("Response body is null");
68
+ }
69
+ await (0, import_promises.mkdir)(import_node_path.default.dirname(destPath), { recursive: true });
70
+ const fileStream = (0, import_node_fs.createWriteStream)(destPath);
71
+ const reader = response.body.getReader();
72
+ let downloaded = 0;
73
+ let lastPrinted = 0;
74
+ try {
75
+ while (true) {
76
+ const { done, value } = await reader.read();
77
+ if (done) {
78
+ break;
79
+ }
80
+ downloaded += value.length;
81
+ fileStream.write(value);
82
+ onProgress == null ? void 0 : onProgress(downloaded, totalSize);
83
+ if (printOutput && totalSize > 0) {
84
+ const shouldPrint = downloaded - lastPrinted > 10 * 1024 * 1024 || downloaded === totalSize;
85
+ if (shouldPrint) {
86
+ const percent = (downloaded / totalSize * 100).toFixed(1);
87
+ console.log(
88
+ ` ${(downloaded / 1024 / 1024).toFixed(1)} MB / ${(totalSize / 1024 / 1024).toFixed(1)} MB (${percent}%)`
89
+ );
90
+ lastPrinted = downloaded;
91
+ }
92
+ }
93
+ }
94
+ } finally {
95
+ fileStream.end();
96
+ }
97
+ await new Promise((resolve, reject) => {
98
+ fileStream.on("finish", resolve);
99
+ fileStream.on("error", reject);
100
+ });
101
+ }
102
+ class PlatformMismatchError extends Error {
103
+ constructor(variant, compatibleVariants) {
104
+ const compatible = compatibleVariants.join(", ");
105
+ super(
106
+ `Variant "${variant}" is not compatible with the current platform. Compatible variants: ${compatible}. Use --force to override.`
107
+ );
108
+ this.variant = variant;
109
+ this.compatibleVariants = compatibleVariants;
110
+ this.name = "PlatformMismatchError";
111
+ }
112
+ }
113
+ async function installBinary(options = {}) {
114
+ const {
115
+ variant = (0, import_config.getInstalledVariant)() ?? (0, import_config.detectPlatform)(),
116
+ printOutput = true,
117
+ force = false,
118
+ signal
119
+ } = options;
120
+ if (!force && !(0, import_config.isVariantCompatibleWithCurrentPlatform)(variant)) {
121
+ throw new PlatformMismatchError(variant, (0, import_config.getCompatibleVariants)());
122
+ }
123
+ const installDir = (0, import_config.getInstallDir)(variant);
124
+ const executablePath = (0, import_config.getWhisperExecutablePath)(installDir);
125
+ if (!force && (0, import_node_fs.existsSync)(executablePath)) {
126
+ if (printOutput) {
127
+ console.log(`whisper.cpp (${variant}) already installed at ${installDir}`);
128
+ }
129
+ return installDir;
130
+ }
131
+ if (force && (0, import_node_fs.existsSync)(installDir)) {
132
+ if (printOutput) {
133
+ console.log(`Removing existing installation at ${installDir}`);
134
+ }
135
+ await (0, import_promises.rm)(installDir, { recursive: true });
136
+ }
137
+ const url = (0, import_config.getBinaryDownloadUrl)(variant);
138
+ const tmpDir = import_node_path.default.join(import_node_os.default.tmpdir(), "ghost-story-whisper-install");
139
+ const tarballPath = import_node_path.default.join(tmpDir, `whisper-cpp-${variant}.tar.gz`);
140
+ if (printOutput) {
141
+ console.log(`Downloading whisper.cpp (${variant}) from ${url}`);
142
+ }
143
+ await downloadFile({
144
+ url,
145
+ destPath: tarballPath,
146
+ printOutput,
147
+ signal
148
+ });
149
+ if (printOutput) {
150
+ console.log(`Extracting to ${installDir}`);
151
+ }
152
+ await (0, import_promises.mkdir)(installDir, { recursive: true });
153
+ await (0, import_promises2.pipeline)(
154
+ (0, import_node_fs.createReadStream)(tarballPath),
155
+ (0, import_node_zlib.createGunzip)(),
156
+ (0, import_tar.extract)({ cwd: installDir, strip: 1 })
157
+ );
158
+ await (0, import_promises.rm)(tmpDir, { recursive: true }).catch(() => {
159
+ });
160
+ if (printOutput) {
161
+ console.log(`whisper.cpp (${variant}) installed successfully`);
162
+ }
163
+ return installDir;
164
+ }
165
+ async function installModel(options) {
166
+ const {
167
+ model,
168
+ modelDir = (0, import_config.getModelDir)(),
169
+ printOutput = true,
170
+ force = false,
171
+ onProgress,
172
+ signal
173
+ } = options;
174
+ const modelPath = (0, import_config.getModelPath)(model, modelDir);
175
+ const expectedSize = import_config.MODEL_SIZES[model];
176
+ if (!force && (0, import_node_fs.existsSync)(modelPath)) {
177
+ const stats = (0, import_node_fs.statSync)(modelPath);
178
+ if (stats.size === expectedSize) {
179
+ if (printOutput) {
180
+ console.log(`Model ${model} already exists at ${modelPath}`);
181
+ }
182
+ const installedVariant2 = (0, import_config.getInstalledVariant)();
183
+ if ((0, import_config.needsCoremlModel)(installedVariant2 ?? void 0)) {
184
+ await installCoremlModel({
185
+ model,
186
+ modelDir,
187
+ printOutput,
188
+ force,
189
+ signal
190
+ });
191
+ }
192
+ return modelPath;
193
+ }
194
+ if (printOutput) {
195
+ console.log(
196
+ `Model ${model} exists but has wrong size (${stats.size} vs ${expectedSize}), re-downloading`
197
+ );
198
+ }
199
+ }
200
+ const url = (0, import_config.getModelDownloadUrl)(model);
201
+ if (printOutput) {
202
+ console.log(`Downloading model ${model}`);
203
+ }
204
+ await downloadFile({
205
+ url,
206
+ destPath: modelPath,
207
+ expectedSize,
208
+ printOutput,
209
+ onProgress,
210
+ signal
211
+ });
212
+ const installedVariant = (0, import_config.getInstalledVariant)();
213
+ if ((0, import_config.needsCoremlModel)(installedVariant ?? void 0)) {
214
+ await installCoremlModel({ model, modelDir, printOutput, force, signal });
215
+ }
216
+ if (printOutput) {
217
+ console.log(`Model ${model} installed successfully`);
218
+ }
219
+ return modelPath;
220
+ }
221
+ async function installCoremlModel(options) {
222
+ const {
223
+ model,
224
+ modelDir = (0, import_config.getModelDir)(),
225
+ printOutput = true,
226
+ force = false,
227
+ signal
228
+ } = options;
229
+ const coremlPath = (0, import_config.getCoremlModelPath)(model, modelDir);
230
+ if (!force && (0, import_node_fs.existsSync)(coremlPath)) {
231
+ if (printOutput) {
232
+ console.log(`CoreML model ${model} already exists at ${coremlPath}`);
233
+ }
234
+ return coremlPath;
235
+ }
236
+ const url = (0, import_config.getCoremlModelDownloadUrl)(model);
237
+ const tmpDir = import_node_path.default.join(import_node_os.default.tmpdir(), "ghost-story-coreml-install");
238
+ const tarballPath = import_node_path.default.join(tmpDir, `ggml-${model}-encoder.mlmodelc.tar.gz`);
239
+ if (printOutput) {
240
+ console.log(`Downloading CoreML model ${model}`);
241
+ }
242
+ await downloadFile({
243
+ url,
244
+ destPath: tarballPath,
245
+ printOutput,
246
+ signal
247
+ });
248
+ if (printOutput) {
249
+ console.log(`Extracting CoreML model to ${modelDir}`);
250
+ }
251
+ await (0, import_promises.mkdir)(modelDir, { recursive: true });
252
+ await (0, import_promises2.pipeline)(
253
+ (0, import_node_fs.createReadStream)(tarballPath),
254
+ (0, import_node_zlib.createGunzip)(),
255
+ (0, import_tar.extract)({ cwd: modelDir })
256
+ );
257
+ await (0, import_promises.rm)(tmpDir, { recursive: true }).catch(() => {
258
+ });
259
+ if (printOutput) {
260
+ console.log(`CoreML model ${model} installed successfully`);
261
+ }
262
+ return coremlPath;
263
+ }
264
+ async function installVadModel(options = {}) {
265
+ const {
266
+ modelDir = (0, import_config.getModelDir)(),
267
+ printOutput = true,
268
+ force = false,
269
+ onProgress,
270
+ signal
271
+ } = options;
272
+ const modelPath = (0, import_config.getVadModelPath)(modelDir);
273
+ const expectedSize = import_config.MODEL_SIZES["silero-vad"];
274
+ if (!force && (0, import_node_fs.existsSync)(modelPath)) {
275
+ const stats = (0, import_node_fs.statSync)(modelPath);
276
+ if (stats.size === expectedSize) {
277
+ if (printOutput) {
278
+ console.log(`VAD model already exists at ${modelPath}`);
279
+ }
280
+ return modelPath;
281
+ }
282
+ if (printOutput) {
283
+ console.log(
284
+ `VAD model exists but has wrong size (${stats.size} vs ${expectedSize}), re-downloading`
285
+ );
286
+ }
287
+ }
288
+ const url = (0, import_config.getVadModelDownloadUrl)();
289
+ if (printOutput) {
290
+ console.log(`Downloading Silero VAD model`);
291
+ }
292
+ await downloadFile({
293
+ url,
294
+ destPath: modelPath,
295
+ expectedSize,
296
+ printOutput,
297
+ onProgress,
298
+ signal
299
+ });
300
+ if (printOutput) {
301
+ console.log(`VAD model installed successfully`);
302
+ }
303
+ return modelPath;
304
+ }
305
+ async function ensureWhisperInstalled(options = {}) {
306
+ const { model, variant, printOutput = false, force = false, signal } = options;
307
+ const installDir = await installBinary({
308
+ variant,
309
+ printOutput,
310
+ force,
311
+ signal
312
+ });
313
+ let modelPath = null;
314
+ if (model) {
315
+ modelPath = await installModel({
316
+ model,
317
+ modelDir: options.modelDir,
318
+ printOutput,
319
+ force,
320
+ signal
321
+ });
322
+ }
323
+ return { installDir, modelPath };
324
+ }
325
+ // Annotate the CommonJS export names for ESM import in node:
326
+ 0 && (module.exports = {
327
+ PlatformMismatchError,
328
+ downloadFile,
329
+ ensureWhisperInstalled,
330
+ installBinary,
331
+ installCoremlModel,
332
+ installModel,
333
+ installVadModel
334
+ });
@@ -0,0 +1,62 @@
1
+ import { BuildVariant, WhisperModel } from './config.cjs';
2
+
3
+ interface DownloadOptions {
4
+ url: string;
5
+ destPath: string;
6
+ expectedSize?: number;
7
+ printOutput?: boolean;
8
+ onProgress?: ((downloaded: number, total: number) => void) | undefined;
9
+ signal?: AbortSignal | null | undefined;
10
+ }
11
+ declare function downloadFile(options: DownloadOptions): Promise<void>;
12
+ declare class PlatformMismatchError extends Error {
13
+ readonly variant: BuildVariant;
14
+ readonly compatibleVariants: BuildVariant[];
15
+ constructor(variant: BuildVariant, compatibleVariants: BuildVariant[]);
16
+ }
17
+ interface InstallBinaryOptions {
18
+ variant?: BuildVariant | undefined;
19
+ printOutput?: boolean | undefined;
20
+ force?: boolean | undefined;
21
+ signal?: AbortSignal | null | undefined;
22
+ }
23
+ declare function installBinary(options?: InstallBinaryOptions): Promise<string>;
24
+ interface InstallModelOptions {
25
+ model: WhisperModel;
26
+ modelDir?: string | undefined;
27
+ printOutput?: boolean;
28
+ force?: boolean;
29
+ onProgress?: ((downloaded: number, total: number) => void) | undefined;
30
+ signal?: AbortSignal | null | undefined;
31
+ }
32
+ declare function installModel(options: InstallModelOptions): Promise<string>;
33
+ interface InstallCoremlModelOptions {
34
+ model: WhisperModel;
35
+ modelDir?: string;
36
+ printOutput?: boolean;
37
+ force?: boolean;
38
+ signal?: AbortSignal | null | undefined;
39
+ }
40
+ declare function installCoremlModel(options: InstallCoremlModelOptions): Promise<string>;
41
+ interface InstallVadModelOptions {
42
+ modelDir?: string;
43
+ printOutput?: boolean;
44
+ force?: boolean;
45
+ onProgress?: (downloaded: number, total: number) => void;
46
+ signal?: AbortSignal | null | undefined;
47
+ }
48
+ declare function installVadModel(options?: InstallVadModelOptions): Promise<string>;
49
+ interface EnsureInstalledOptions {
50
+ model?: WhisperModel | undefined;
51
+ variant?: BuildVariant | undefined;
52
+ modelDir?: string | undefined;
53
+ printOutput?: boolean | undefined;
54
+ force?: boolean | undefined;
55
+ signal?: AbortSignal | null | undefined;
56
+ }
57
+ declare function ensureWhisperInstalled(options?: EnsureInstalledOptions): Promise<{
58
+ installDir: string;
59
+ modelPath: string | null;
60
+ }>;
61
+
62
+ export { type DownloadOptions, type EnsureInstalledOptions, type InstallBinaryOptions, type InstallCoremlModelOptions, type InstallModelOptions, type InstallVadModelOptions, PlatformMismatchError, downloadFile, ensureWhisperInstalled, installBinary, installCoremlModel, installModel, installVadModel };