@juspay/neurolink 8.6.0 → 8.8.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/CHANGELOG.md +25 -0
- package/dist/cli/factories/commandFactory.d.ts +5 -0
- package/dist/cli/factories/commandFactory.js +96 -0
- package/dist/cli/utils/audioFileUtils.d.ts +70 -0
- package/dist/cli/utils/audioFileUtils.js +174 -0
- package/dist/lib/types/cli.d.ts +2 -0
- package/dist/lib/types/fileTypes.d.ts +56 -9
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/index.js +2 -0
- package/dist/lib/types/ttsTypes.d.ts +91 -0
- package/dist/lib/types/ttsTypes.js +58 -0
- package/dist/lib/utils/imageProcessor.d.ts +38 -5
- package/dist/lib/utils/imageProcessor.js +131 -7
- package/dist/lib/utils/pdfProcessor.js +24 -2
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/fileTypes.d.ts +56 -9
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/ttsTypes.d.ts +91 -0
- package/dist/types/ttsTypes.js +57 -0
- package/dist/utils/imageProcessor.d.ts +38 -5
- package/dist/utils/imageProcessor.js +131 -7
- package/dist/utils/pdfProcessor.js +24 -2
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
## [8.8.0](https://github.com/juspay/neurolink/compare/v8.7.0...v8.8.0) (2025-12-11)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- **(types):** add AudioProviderConfig type definition for transcription providers ([c34f437](https://github.com/juspay/neurolink/commit/c34f437455fba20b803b84811b9dda143351427e))
|
|
6
|
+
|
|
7
|
+
## [8.7.0](https://github.com/juspay/neurolink/compare/v8.6.0...v8.7.0) (2025-12-10)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- **(cli):** implement TTS audio file output (TTS-024) ([48af003](https://github.com/juspay/neurolink/commit/48af0033db12d3a7b7dd62b8fb5c965f61f20042))
|
|
12
|
+
- **(ImageProcessor):** Add output validation to ImageProcessor.process() method ([6fe3a16](https://github.com/juspay/neurolink/commit/6fe3a16e8290a1a7640ab51865343583253418d0))
|
|
13
|
+
- **(imageProcessor):** add retry logic with exponential backoff for URL downloads ([e6ab4df](https://github.com/juspay/neurolink/commit/e6ab4df4e974c3981d6a2e2de30d5b3e19ecccf9))
|
|
14
|
+
- **(types):** add AudioProcessorOptions and audioOptions to FileDetectorOptions ([2bd877b](https://github.com/juspay/neurolink/commit/2bd877bd5f41fed786cabbdea6e57df95bd7debb))
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
- **(deps):** convert canvas and pdfjs-dist to dynamic imports for SSR compatibility ([cc7d99e](https://github.com/juspay/neurolink/commit/cc7d99e33d5087ac4d8f442c0dfebdfad9c294c4))
|
|
19
|
+
- **(deps):** force @semantic-release/npm v13 via pnpm override for OIDC support ([8a528c9](https://github.com/juspay/neurolink/commit/8a528c95e8c983ce3cb8d1196b8c08ae4ed93ec1))
|
|
20
|
+
- **(lock):** add missing update for lockfile ([376b7ad](https://github.com/juspay/neurolink/commit/376b7ad0297e1f8f6fc68c5c58d30213bae9d23c))
|
|
21
|
+
- **(release):** enable OIDC trusted publishing for npm ([3ba6dd9](https://github.com/juspay/neurolink/commit/3ba6dd9d7b6156e170550315f8a208ccafa5483a))
|
|
22
|
+
- **(tts):** add audio property to GenerateResult type and improve type safety ([e85c7d0](https://github.com/juspay/neurolink/commit/e85c7d0435b6b4f81421ce816e2252b932e0b3ca))
|
|
23
|
+
- **(workflows):** add job-level OIDC permissions and remove conflicting auth ([8ee4fb1](https://github.com/juspay/neurolink/commit/8ee4fb1ed3e0a996540032ddd92d4a491a2b53a1))
|
|
24
|
+
- **(workflows):** add OIDC authentication for npm trusted publishing ([c6bb5bb](https://github.com/juspay/neurolink/commit/c6bb5bb33c34249ee89e8622d879f266025ecb9a))
|
|
25
|
+
|
|
1
26
|
## [8.6.0](https://github.com/juspay/neurolink/compare/v8.5.1...v8.6.0) (2025-12-06)
|
|
2
27
|
|
|
3
28
|
### Features
|
|
@@ -11,6 +11,11 @@ export declare class CLICommandFactory {
|
|
|
11
11
|
private static processCliFiles;
|
|
12
12
|
private static processOptions;
|
|
13
13
|
private static handleOutput;
|
|
14
|
+
/**
|
|
15
|
+
* Helper method to handle TTS audio file output
|
|
16
|
+
* Saves audio to file when --tts-output flag is provided
|
|
17
|
+
*/
|
|
18
|
+
private static handleTTSOutput;
|
|
14
19
|
private static isValidTokenUsage;
|
|
15
20
|
private static normalizeTokenUsage;
|
|
16
21
|
private static formatAnalyticsForTextMode;
|
|
@@ -16,6 +16,7 @@ import { logger } from "../../lib/utils/logger.js";
|
|
|
16
16
|
import fs from "fs";
|
|
17
17
|
import { handleSetup } from "../commands/setup.js";
|
|
18
18
|
import { checkRedisAvailability } from "../../lib/utils/conversationMemoryUtils.js";
|
|
19
|
+
import { saveAudioToFile, formatFileSize } from "../utils/audioFileUtils.js";
|
|
19
20
|
/**
|
|
20
21
|
* CLI Command Factory for generate commands
|
|
21
22
|
*/
|
|
@@ -194,6 +195,42 @@ export class CLICommandFactory {
|
|
|
194
195
|
default: false,
|
|
195
196
|
description: "Test command without making actual API calls (for testing)",
|
|
196
197
|
},
|
|
198
|
+
// TTS (Text-to-Speech) options
|
|
199
|
+
tts: {
|
|
200
|
+
type: "boolean",
|
|
201
|
+
default: false,
|
|
202
|
+
description: "Enable text-to-speech output",
|
|
203
|
+
},
|
|
204
|
+
ttsVoice: {
|
|
205
|
+
type: "string",
|
|
206
|
+
description: "TTS voice to use (e.g., 'en-US-Neural2-C')",
|
|
207
|
+
},
|
|
208
|
+
ttsFormat: {
|
|
209
|
+
type: "string",
|
|
210
|
+
choices: ["mp3", "wav", "ogg", "opus"],
|
|
211
|
+
default: "mp3",
|
|
212
|
+
description: "Audio output format",
|
|
213
|
+
},
|
|
214
|
+
ttsSpeed: {
|
|
215
|
+
type: "number",
|
|
216
|
+
default: 1.0,
|
|
217
|
+
description: "Speaking rate (0.25-4.0, default: 1.0)",
|
|
218
|
+
},
|
|
219
|
+
ttsQuality: {
|
|
220
|
+
type: "string",
|
|
221
|
+
choices: ["standard", "hd"],
|
|
222
|
+
default: "standard",
|
|
223
|
+
description: "Audio quality level",
|
|
224
|
+
},
|
|
225
|
+
ttsOutput: {
|
|
226
|
+
type: "string",
|
|
227
|
+
description: "Save TTS audio to file (supports absolute and relative paths)",
|
|
228
|
+
},
|
|
229
|
+
ttsPlay: {
|
|
230
|
+
type: "boolean",
|
|
231
|
+
default: false,
|
|
232
|
+
description: "Auto-play generated audio",
|
|
233
|
+
},
|
|
197
234
|
};
|
|
198
235
|
// Helper method to build options for commands
|
|
199
236
|
static buildOptions(yargs, additionalOptions = {}) {
|
|
@@ -302,6 +339,14 @@ export class CLICommandFactory {
|
|
|
302
339
|
noColor: argv.noColor,
|
|
303
340
|
configFile: argv.configFile,
|
|
304
341
|
dryRun: argv.dryRun,
|
|
342
|
+
// TTS options
|
|
343
|
+
tts: argv.tts,
|
|
344
|
+
ttsVoice: argv.ttsVoice,
|
|
345
|
+
ttsFormat: argv.ttsFormat,
|
|
346
|
+
ttsSpeed: argv.ttsSpeed,
|
|
347
|
+
ttsQuality: argv.ttsQuality,
|
|
348
|
+
ttsOutput: argv.ttsOutput,
|
|
349
|
+
ttsPlay: argv.ttsPlay,
|
|
305
350
|
};
|
|
306
351
|
}
|
|
307
352
|
// Helper method to handle output
|
|
@@ -343,6 +388,44 @@ export class CLICommandFactory {
|
|
|
343
388
|
logger.always(output);
|
|
344
389
|
}
|
|
345
390
|
}
|
|
391
|
+
/**
|
|
392
|
+
* Helper method to handle TTS audio file output
|
|
393
|
+
* Saves audio to file when --tts-output flag is provided
|
|
394
|
+
*/
|
|
395
|
+
static async handleTTSOutput(result, options) {
|
|
396
|
+
// Check if --tts-output flag is provided
|
|
397
|
+
const ttsOutputPath = options.ttsOutput;
|
|
398
|
+
if (!ttsOutputPath) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
// Extract audio from result with proper type checking
|
|
402
|
+
if (!result || typeof result !== "object") {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
const generateResult = result;
|
|
406
|
+
const audio = generateResult.audio;
|
|
407
|
+
if (!audio) {
|
|
408
|
+
if (!options.quiet) {
|
|
409
|
+
logger.always(chalk.yellow("⚠️ No audio available in result. TTS may not be enabled for this request."));
|
|
410
|
+
}
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
try {
|
|
414
|
+
// Save audio to file
|
|
415
|
+
const saveResult = await saveAudioToFile(audio, ttsOutputPath);
|
|
416
|
+
if (saveResult.success) {
|
|
417
|
+
if (!options.quiet) {
|
|
418
|
+
logger.always(chalk.green(`🔊 Audio saved to: ${saveResult.path} (${formatFileSize(saveResult.size)})`));
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
handleError(new Error(saveResult.error || "Failed to save audio file"), "TTS Output");
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
handleError(error, "TTS Output");
|
|
427
|
+
}
|
|
428
|
+
}
|
|
346
429
|
// Helper method to validate token usage data with fallback handling
|
|
347
430
|
static isValidTokenUsage(tokens) {
|
|
348
431
|
if (!tokens || typeof tokens !== "object" || tokens === null) {
|
|
@@ -1124,6 +1207,8 @@ export class CLICommandFactory {
|
|
|
1124
1207
|
}
|
|
1125
1208
|
// Handle output with universal formatting
|
|
1126
1209
|
this.handleOutput(result, options);
|
|
1210
|
+
// Handle TTS audio file output if --tts-output is provided
|
|
1211
|
+
await this.handleTTSOutput(result, options);
|
|
1127
1212
|
if (options.debug) {
|
|
1128
1213
|
logger.debug("\n" + chalk.yellow("Debug Information:"));
|
|
1129
1214
|
logger.debug("Provider:", result.provider);
|
|
@@ -1436,6 +1521,17 @@ export class CLICommandFactory {
|
|
|
1436
1521
|
logger.always(`\nOutput saved to ${options.output}`);
|
|
1437
1522
|
}
|
|
1438
1523
|
}
|
|
1524
|
+
// Handle TTS audio output if --tts-output is provided
|
|
1525
|
+
// Note: For streaming, TTS audio is collected during the stream
|
|
1526
|
+
// and saved at the end if available
|
|
1527
|
+
const ttsOutputPath = options.ttsOutput;
|
|
1528
|
+
if (ttsOutputPath) {
|
|
1529
|
+
// For now, streaming TTS output is not yet available
|
|
1530
|
+
// This will be enabled when the TTS streaming infrastructure is complete
|
|
1531
|
+
if (!options.quiet) {
|
|
1532
|
+
logger.always(chalk.yellow("⚠️ TTS audio output for streaming is not yet available. Use 'generate' command for TTS output."));
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1439
1535
|
// Debug output for streaming
|
|
1440
1536
|
if (options.debug) {
|
|
1441
1537
|
await this.logStreamDebugInfo({
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audio file utilities for CLI
|
|
3
|
+
*
|
|
4
|
+
* Provides functionality for saving TTS audio to files with proper
|
|
5
|
+
* error handling and directory creation.
|
|
6
|
+
*
|
|
7
|
+
* @module cli/utils/audioFileUtils
|
|
8
|
+
*/
|
|
9
|
+
import type { TTSResult, AudioSaveResult, AudioFormat } from "../../lib/types/ttsTypes.js";
|
|
10
|
+
/**
|
|
11
|
+
* Format file size in human-readable format
|
|
12
|
+
*
|
|
13
|
+
* @param bytes - Size in bytes
|
|
14
|
+
* @returns Formatted string (e.g., "32 KB", "1.5 MB")
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatFileSize(bytes: number): string;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the output path, handling both absolute and relative paths
|
|
19
|
+
*
|
|
20
|
+
* @param outputPath - User-specified output path
|
|
21
|
+
* @returns Resolved absolute path
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveOutputPath(outputPath: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Ensure parent directories exist, creating them if necessary
|
|
26
|
+
*
|
|
27
|
+
* @param filePath - Full path to the file
|
|
28
|
+
*/
|
|
29
|
+
export declare function ensureDirectoryExists(filePath: string): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Get appropriate file extension for audio format
|
|
32
|
+
*
|
|
33
|
+
* @param format - Audio format
|
|
34
|
+
* @returns File extension (including dot)
|
|
35
|
+
*/
|
|
36
|
+
export declare function getAudioExtension(format: AudioFormat): string;
|
|
37
|
+
/**
|
|
38
|
+
* Validate and normalize output path, adding extension if needed
|
|
39
|
+
*
|
|
40
|
+
* @param outputPath - User-specified output path
|
|
41
|
+
* @param format - Audio format for extension
|
|
42
|
+
* @returns Normalized output path
|
|
43
|
+
*/
|
|
44
|
+
export declare function normalizeOutputPath(outputPath: string, format?: AudioFormat): string;
|
|
45
|
+
/**
|
|
46
|
+
* Save TTS audio result to a file
|
|
47
|
+
*
|
|
48
|
+
* Creates parent directories if they don't exist and handles both
|
|
49
|
+
* absolute and relative paths.
|
|
50
|
+
*
|
|
51
|
+
* @param audio - TTS result containing audio buffer
|
|
52
|
+
* @param outputPath - Path where the audio should be saved
|
|
53
|
+
* @returns Save result with success status, path, and size
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const result = await saveAudioToFile(audioResult, "./output/audio.mp3");
|
|
58
|
+
* if (result.success) {
|
|
59
|
+
* console.log(`Saved to ${result.path} (${formatFileSize(result.size)})`);
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function saveAudioToFile(audio: TTSResult, outputPath: string): Promise<AudioSaveResult>;
|
|
64
|
+
/**
|
|
65
|
+
* Validate that a path is writable
|
|
66
|
+
*
|
|
67
|
+
* @param filePath - Path to validate
|
|
68
|
+
* @returns True if the path is writable
|
|
69
|
+
*/
|
|
70
|
+
export declare function isPathWritable(filePath: string): Promise<boolean>;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audio file utilities for CLI
|
|
3
|
+
*
|
|
4
|
+
* Provides functionality for saving TTS audio to files with proper
|
|
5
|
+
* error handling and directory creation.
|
|
6
|
+
*
|
|
7
|
+
* @module cli/utils/audioFileUtils
|
|
8
|
+
*/
|
|
9
|
+
import fs from "fs";
|
|
10
|
+
import path from "path";
|
|
11
|
+
/**
|
|
12
|
+
* Format file size in human-readable format
|
|
13
|
+
*
|
|
14
|
+
* @param bytes - Size in bytes
|
|
15
|
+
* @returns Formatted string (e.g., "32 KB", "1.5 MB")
|
|
16
|
+
*/
|
|
17
|
+
export function formatFileSize(bytes) {
|
|
18
|
+
if (bytes < 1024) {
|
|
19
|
+
return `${bytes} B`;
|
|
20
|
+
}
|
|
21
|
+
else if (bytes < 1024 * 1024) {
|
|
22
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
23
|
+
}
|
|
24
|
+
else if (bytes < 1024 * 1024 * 1024) {
|
|
25
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the output path, handling both absolute and relative paths
|
|
33
|
+
*
|
|
34
|
+
* @param outputPath - User-specified output path
|
|
35
|
+
* @returns Resolved absolute path
|
|
36
|
+
*/
|
|
37
|
+
export function resolveOutputPath(outputPath) {
|
|
38
|
+
if (path.isAbsolute(outputPath)) {
|
|
39
|
+
return outputPath;
|
|
40
|
+
}
|
|
41
|
+
return path.resolve(process.cwd(), outputPath);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Ensure parent directories exist, creating them if necessary
|
|
45
|
+
*
|
|
46
|
+
* @param filePath - Full path to the file
|
|
47
|
+
*/
|
|
48
|
+
export async function ensureDirectoryExists(filePath) {
|
|
49
|
+
const directory = path.dirname(filePath);
|
|
50
|
+
try {
|
|
51
|
+
await fs.promises.access(directory, fs.constants.F_OK);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Directory doesn't exist, create it recursively
|
|
55
|
+
await fs.promises.mkdir(directory, { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get appropriate file extension for audio format
|
|
60
|
+
*
|
|
61
|
+
* @param format - Audio format
|
|
62
|
+
* @returns File extension (including dot)
|
|
63
|
+
*/
|
|
64
|
+
export function getAudioExtension(format) {
|
|
65
|
+
switch (format) {
|
|
66
|
+
case "mp3":
|
|
67
|
+
return ".mp3";
|
|
68
|
+
case "wav":
|
|
69
|
+
return ".wav";
|
|
70
|
+
case "ogg":
|
|
71
|
+
return ".ogg";
|
|
72
|
+
case "opus":
|
|
73
|
+
return ".opus";
|
|
74
|
+
default:
|
|
75
|
+
return ".mp3";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Validate and normalize output path, adding extension if needed
|
|
80
|
+
*
|
|
81
|
+
* @param outputPath - User-specified output path
|
|
82
|
+
* @param format - Audio format for extension
|
|
83
|
+
* @returns Normalized output path
|
|
84
|
+
*/
|
|
85
|
+
export function normalizeOutputPath(outputPath, format = "mp3") {
|
|
86
|
+
const resolvedPath = resolveOutputPath(outputPath);
|
|
87
|
+
const ext = path.extname(resolvedPath).toLowerCase();
|
|
88
|
+
// If no extension or wrong extension, add the correct one
|
|
89
|
+
const validExtensions = [".mp3", ".wav", ".ogg", ".opus"];
|
|
90
|
+
if (!ext || !validExtensions.includes(ext)) {
|
|
91
|
+
return resolvedPath + getAudioExtension(format);
|
|
92
|
+
}
|
|
93
|
+
return resolvedPath;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Save TTS audio result to a file
|
|
97
|
+
*
|
|
98
|
+
* Creates parent directories if they don't exist and handles both
|
|
99
|
+
* absolute and relative paths.
|
|
100
|
+
*
|
|
101
|
+
* @param audio - TTS result containing audio buffer
|
|
102
|
+
* @param outputPath - Path where the audio should be saved
|
|
103
|
+
* @returns Save result with success status, path, and size
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* const result = await saveAudioToFile(audioResult, "./output/audio.mp3");
|
|
108
|
+
* if (result.success) {
|
|
109
|
+
* console.log(`Saved to ${result.path} (${formatFileSize(result.size)})`);
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export async function saveAudioToFile(audio, outputPath) {
|
|
114
|
+
try {
|
|
115
|
+
// Normalize the output path
|
|
116
|
+
const normalizedPath = normalizeOutputPath(outputPath, audio.format);
|
|
117
|
+
// Ensure parent directories exist
|
|
118
|
+
await ensureDirectoryExists(normalizedPath);
|
|
119
|
+
// Write the audio buffer to file
|
|
120
|
+
await fs.promises.writeFile(normalizedPath, audio.buffer);
|
|
121
|
+
// Get the actual file size
|
|
122
|
+
const stats = await fs.promises.stat(normalizedPath);
|
|
123
|
+
return {
|
|
124
|
+
success: true,
|
|
125
|
+
path: normalizedPath,
|
|
126
|
+
size: stats.size,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
131
|
+
return {
|
|
132
|
+
success: false,
|
|
133
|
+
path: outputPath,
|
|
134
|
+
size: 0,
|
|
135
|
+
error: errorMessage,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Validate that a path is writable
|
|
141
|
+
*
|
|
142
|
+
* @param filePath - Path to validate
|
|
143
|
+
* @returns True if the path is writable
|
|
144
|
+
*/
|
|
145
|
+
export async function isPathWritable(filePath) {
|
|
146
|
+
try {
|
|
147
|
+
const resolvedPath = resolveOutputPath(filePath);
|
|
148
|
+
const directory = path.dirname(resolvedPath);
|
|
149
|
+
// Check if directory exists
|
|
150
|
+
try {
|
|
151
|
+
await fs.promises.access(directory, fs.constants.W_OK);
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Directory doesn't exist, check if we can create it
|
|
156
|
+
// by checking write access to the nearest existing parent
|
|
157
|
+
let parentDir = directory;
|
|
158
|
+
while (parentDir !== path.dirname(parentDir)) {
|
|
159
|
+
try {
|
|
160
|
+
await fs.promises.access(parentDir, fs.constants.W_OK);
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
parentDir = path.dirname(parentDir);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=audioFileUtils.js.map
|
package/dist/lib/types/cli.d.ts
CHANGED
|
@@ -81,18 +81,53 @@ export type PDFProcessorOptions = {
|
|
|
81
81
|
bedrockApiMode?: "converse" | "invokeModel";
|
|
82
82
|
};
|
|
83
83
|
/**
|
|
84
|
-
*
|
|
84
|
+
* Audio provider configuration for transcription services
|
|
85
|
+
*
|
|
86
|
+
* Describes the capabilities and limitations of each audio transcription provider
|
|
87
|
+
* (e.g., OpenAI Whisper, Google Speech-to-Text, Azure Speech Services).
|
|
88
|
+
*
|
|
89
|
+
* @example OpenAI Whisper configuration
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const openaiConfig: AudioProviderConfig = {
|
|
92
|
+
* maxSizeMB: 25,
|
|
93
|
+
* maxDurationSeconds: 600,
|
|
94
|
+
* supportedFormats: ['mp3', 'mp4', 'm4a', 'wav', 'webm'],
|
|
95
|
+
* supportsLanguageDetection: true,
|
|
96
|
+
* requiresApiKey: true,
|
|
97
|
+
* costPer60s: 0.006 // $0.006 per minute
|
|
98
|
+
* };
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @example Google Speech-to-Text configuration
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const googleConfig: AudioProviderConfig = {
|
|
104
|
+
* maxSizeMB: 10,
|
|
105
|
+
* maxDurationSeconds: 480,
|
|
106
|
+
* supportedFormats: ['flac', 'wav', 'mp3', 'ogg'],
|
|
107
|
+
* supportsLanguageDetection: true,
|
|
108
|
+
* requiresApiKey: true,
|
|
109
|
+
* costPer15s: 0.004 // $0.016 per minute ($0.004 per 15 seconds)
|
|
110
|
+
* };
|
|
111
|
+
* ```
|
|
85
112
|
*/
|
|
86
|
-
export type
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
113
|
+
export type AudioProviderConfig = {
|
|
114
|
+
/** Maximum audio file size in megabytes */
|
|
115
|
+
maxSizeMB: number;
|
|
116
|
+
/** Maximum audio duration in seconds */
|
|
117
|
+
maxDurationSeconds: number;
|
|
118
|
+
/** Supported audio formats (e.g., 'mp3', 'wav', 'm4a', 'flac', 'ogg') */
|
|
119
|
+
supportedFormats: string[];
|
|
120
|
+
/** Whether the provider supports automatic language detection */
|
|
121
|
+
supportsLanguageDetection: boolean;
|
|
122
|
+
/** Whether the provider requires an API key for authentication */
|
|
123
|
+
requiresApiKey: boolean;
|
|
124
|
+
/** Optional: Cost per 60 seconds of audio in USD */
|
|
125
|
+
costPer60s?: number;
|
|
126
|
+
/** Optional: Cost per 15 seconds of audio in USD */
|
|
127
|
+
costPer15s?: number;
|
|
93
128
|
};
|
|
94
129
|
/**
|
|
95
|
-
* Audio processor options
|
|
130
|
+
* Audio processor options
|
|
96
131
|
*/
|
|
97
132
|
export type AudioProcessorOptions = {
|
|
98
133
|
/** AI provider to use for transcription (e.g., 'openai', 'google', 'azure') */
|
|
@@ -108,6 +143,18 @@ export type AudioProcessorOptions = {
|
|
|
108
143
|
/** Maximum file size in megabytes */
|
|
109
144
|
maxSizeMB?: number;
|
|
110
145
|
};
|
|
146
|
+
/**
|
|
147
|
+
* File detector options
|
|
148
|
+
*/
|
|
149
|
+
export type FileDetectorOptions = {
|
|
150
|
+
maxSize?: number;
|
|
151
|
+
timeout?: number;
|
|
152
|
+
allowedTypes?: FileType[];
|
|
153
|
+
audioOptions?: AudioProcessorOptions;
|
|
154
|
+
csvOptions?: CSVProcessorOptions;
|
|
155
|
+
confidenceThreshold?: number;
|
|
156
|
+
provider?: string;
|
|
157
|
+
};
|
|
111
158
|
/**
|
|
112
159
|
* Google AI Studio Files API types
|
|
113
160
|
*/
|
package/dist/lib/types/index.js
CHANGED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text-to-Speech (TTS) Type Definitions for NeuroLink
|
|
3
|
+
*
|
|
4
|
+
* This module defines types for TTS audio generation and output.
|
|
5
|
+
*
|
|
6
|
+
* @module types/ttsTypes
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Supported audio formats for TTS output
|
|
10
|
+
*/
|
|
11
|
+
export type AudioFormat = "mp3" | "wav" | "ogg" | "opus";
|
|
12
|
+
/**
|
|
13
|
+
* TTS quality settings
|
|
14
|
+
*/
|
|
15
|
+
export type TTSQuality = "standard" | "hd";
|
|
16
|
+
/**
|
|
17
|
+
* TTS configuration options
|
|
18
|
+
*/
|
|
19
|
+
export type TTSOptions = {
|
|
20
|
+
/** Enable TTS output */
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
/** Voice identifier (e.g., "en-US-Neural2-C") */
|
|
23
|
+
voice?: string;
|
|
24
|
+
/** Audio format (default: mp3) */
|
|
25
|
+
format?: AudioFormat;
|
|
26
|
+
/** Speaking rate 0.25-4.0 (default: 1.0) */
|
|
27
|
+
speed?: number;
|
|
28
|
+
/** Audio quality (default: standard) */
|
|
29
|
+
quality?: TTSQuality;
|
|
30
|
+
/** Output file path (optional) */
|
|
31
|
+
output?: string;
|
|
32
|
+
/** Auto-play audio after generation (default: false) */
|
|
33
|
+
play?: boolean;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* TTS audio result returned from generation
|
|
37
|
+
*/
|
|
38
|
+
export type TTSResult = {
|
|
39
|
+
/** Audio data as Buffer */
|
|
40
|
+
buffer: Buffer;
|
|
41
|
+
/** Audio format */
|
|
42
|
+
format: AudioFormat;
|
|
43
|
+
/** Audio file size in bytes */
|
|
44
|
+
size: number;
|
|
45
|
+
/** Duration in seconds (if available) */
|
|
46
|
+
duration?: number;
|
|
47
|
+
/** Voice used for generation */
|
|
48
|
+
voice?: string;
|
|
49
|
+
/** Sample rate in Hz */
|
|
50
|
+
sampleRate?: number;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Result of saving audio to file
|
|
54
|
+
*/
|
|
55
|
+
export type AudioSaveResult = {
|
|
56
|
+
/** Whether the save was successful */
|
|
57
|
+
success: boolean;
|
|
58
|
+
/** Full path to the saved file */
|
|
59
|
+
path: string;
|
|
60
|
+
/** File size in bytes */
|
|
61
|
+
size: number;
|
|
62
|
+
/** Error message if failed */
|
|
63
|
+
error?: string;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* TTS voice information
|
|
67
|
+
*/
|
|
68
|
+
export type TTSVoice = {
|
|
69
|
+
/** Voice identifier */
|
|
70
|
+
id: string;
|
|
71
|
+
/** Display name */
|
|
72
|
+
name: string;
|
|
73
|
+
/** Language code (e.g., "en-US") */
|
|
74
|
+
languageCode: string;
|
|
75
|
+
/** Gender */
|
|
76
|
+
gender: "male" | "female" | "neutral";
|
|
77
|
+
/** Voice type */
|
|
78
|
+
type: "neural" | "wavenet" | "standard";
|
|
79
|
+
};
|
|
80
|
+
/** Valid audio formats as an array for runtime validation */
|
|
81
|
+
export declare const VALID_AUDIO_FORMATS: readonly AudioFormat[];
|
|
82
|
+
/** Valid TTS quality levels as an array for runtime validation */
|
|
83
|
+
export declare const VALID_TTS_QUALITIES: readonly TTSQuality[];
|
|
84
|
+
/**
|
|
85
|
+
* Type guard to check if an object is a TTSResult
|
|
86
|
+
*/
|
|
87
|
+
export declare function isTTSResult(value: unknown): value is TTSResult;
|
|
88
|
+
/**
|
|
89
|
+
* Type guard to check if TTSOptions are valid
|
|
90
|
+
*/
|
|
91
|
+
export declare function isValidTTSOptions(options: unknown): options is TTSOptions;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text-to-Speech (TTS) Type Definitions for NeuroLink
|
|
3
|
+
*
|
|
4
|
+
* This module defines types for TTS audio generation and output.
|
|
5
|
+
*
|
|
6
|
+
* @module types/ttsTypes
|
|
7
|
+
*/
|
|
8
|
+
/** Valid audio formats as an array for runtime validation */
|
|
9
|
+
export const VALID_AUDIO_FORMATS = [
|
|
10
|
+
"mp3",
|
|
11
|
+
"wav",
|
|
12
|
+
"ogg",
|
|
13
|
+
"opus",
|
|
14
|
+
];
|
|
15
|
+
/** Valid TTS quality levels as an array for runtime validation */
|
|
16
|
+
export const VALID_TTS_QUALITIES = ["standard", "hd"];
|
|
17
|
+
/**
|
|
18
|
+
* Type guard to check if an object is a TTSResult
|
|
19
|
+
*/
|
|
20
|
+
export function isTTSResult(value) {
|
|
21
|
+
if (!value || typeof value !== "object") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const obj = value;
|
|
25
|
+
return (Buffer.isBuffer(obj.buffer) &&
|
|
26
|
+
typeof obj.format === "string" &&
|
|
27
|
+
VALID_AUDIO_FORMATS.includes(obj.format) &&
|
|
28
|
+
typeof obj.size === "number" &&
|
|
29
|
+
obj.size >= 0);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Type guard to check if TTSOptions are valid
|
|
33
|
+
*/
|
|
34
|
+
export function isValidTTSOptions(options) {
|
|
35
|
+
if (!options || typeof options !== "object") {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const opts = options;
|
|
39
|
+
if (opts.speed !== undefined) {
|
|
40
|
+
if (typeof opts.speed !== "number" ||
|
|
41
|
+
opts.speed < 0.25 ||
|
|
42
|
+
opts.speed > 4.0) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (opts.format !== undefined) {
|
|
47
|
+
if (!VALID_AUDIO_FORMATS.includes(opts.format)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (opts.quality !== undefined) {
|
|
52
|
+
if (!VALID_TTS_QUALITIES.includes(opts.quality)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=ttsTypes.js.map
|