@juspay/neurolink 12.48.2 → 12.49.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 +3 -3
- package/dist/browser/neurolink.min.js +616 -595
- package/dist/cli/commands/serve.d.ts +0 -3
- package/dist/cli/commands/serve.js +85 -3
- package/dist/cli/commands/transcribe.d.ts +24 -0
- package/dist/cli/commands/transcribe.js +718 -0
- package/dist/cli/factories/commandFactory.d.ts +10 -0
- package/dist/cli/factories/commandFactory.js +13 -0
- package/dist/cli/parser.js +3 -0
- package/dist/factories/mediaHandlerCatalog.js +11 -9
- package/dist/factories/sttDescriptors.d.ts +63 -0
- package/dist/factories/sttDescriptors.js +286 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +7 -1
- package/dist/neurolink.d.ts +68 -1
- package/dist/neurolink.js +202 -4
- package/dist/processors/media/AudioProcessor.d.ts +15 -56
- package/dist/processors/media/AudioProcessor.js +105 -276
- package/dist/processors/media/VideoProcessor.d.ts +3 -5
- package/dist/processors/media/VideoProcessor.js +52 -51
- package/dist/server/abstract/baseServerAdapter.d.ts +7 -0
- package/dist/server/abstract/baseServerAdapter.js +13 -1
- package/dist/server/adapters/expressAdapter.d.ts +1 -0
- package/dist/server/adapters/expressAdapter.js +48 -4
- package/dist/server/adapters/fastifyAdapter.d.ts +1 -0
- package/dist/server/adapters/fastifyAdapter.js +38 -1
- package/dist/server/adapters/honoAdapter.d.ts +1 -4
- package/dist/server/adapters/honoAdapter.js +83 -1
- package/dist/server/adapters/koaAdapter.d.ts +1 -0
- package/dist/server/adapters/koaAdapter.js +43 -0
- package/dist/server/index.d.ts +3 -2
- package/dist/server/index.js +3 -2
- package/dist/server/routes/index.d.ts +1 -0
- package/dist/server/routes/index.js +3 -0
- package/dist/server/routes/transcribeRoutes.d.ts +23 -0
- package/dist/server/routes/transcribeRoutes.js +506 -0
- package/dist/server/utils/rawBody.d.ts +32 -0
- package/dist/server/utils/rawBody.js +76 -0
- package/dist/server/utils/validation.d.ts +192 -0
- package/dist/server/utils/validation.js +100 -0
- package/dist/server/websocket/transcribeWebSocket.d.ts +42 -0
- package/dist/server/websocket/transcribeWebSocket.js +264 -0
- package/dist/types/cli.d.ts +46 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/providers.d.ts +7 -1
- package/dist/types/server.d.ts +117 -1
- package/dist/types/stt.d.ts +160 -7
- package/dist/types/transcribe.d.ts +506 -0
- package/dist/types/transcribe.js +29 -0
- package/dist/utils/speakerTurns.d.ts +28 -0
- package/dist/utils/speakerTurns.js +93 -0
- package/dist/utils/sttProcessor.d.ts +20 -2
- package/dist/utils/sttProcessor.js +73 -5
- package/dist/voice/correction/dictionary.d.ts +49 -0
- package/dist/voice/correction/dictionary.js +134 -0
- package/dist/voice/correction/guard.d.ts +35 -0
- package/dist/voice/correction/guard.js +161 -0
- package/dist/voice/correction/index.d.ts +47 -0
- package/dist/voice/correction/index.js +211 -0
- package/dist/voice/correction/rewrite.d.ts +92 -0
- package/dist/voice/correction/rewrite.js +322 -0
- package/dist/voice/errors.d.ts +15 -0
- package/dist/voice/errors.js +45 -0
- package/dist/voice/index.d.ts +20 -2
- package/dist/voice/index.js +75 -9
- package/dist/voice/providers/AzureSTT.d.ts +10 -7
- package/dist/voice/providers/AzureSTT.js +23 -75
- package/dist/voice/providers/DeepgramSTT.d.ts +17 -2
- package/dist/voice/providers/DeepgramSTT.js +109 -13
- package/dist/voice/providers/ElevenLabsSTT.d.ts +12 -2
- package/dist/voice/providers/ElevenLabsSTT.js +34 -8
- package/dist/voice/providers/GoogleSTT.d.ts +10 -8
- package/dist/voice/providers/GoogleSTT.js +21 -75
- package/dist/voice/providers/OpenAISTT.d.ts +30 -9
- package/dist/voice/providers/OpenAISTT.js +196 -21
- package/dist/voice/providers/WhistleSTT.d.ts +87 -0
- package/dist/voice/providers/WhistleSTT.js +313 -0
- package/dist/voice/streaming/chunkedStreamAdapter.d.ts +19 -0
- package/dist/voice/streaming/chunkedStreamAdapter.js +519 -0
- package/dist/voice/streaming/endpointer.d.ts +81 -0
- package/dist/voice/streaming/endpointer.js +247 -0
- package/dist/voice/streaming/localAgreement.d.ts +30 -0
- package/dist/voice/streaming/localAgreement.js +44 -0
- package/dist/voice/sttEnvCredentials.d.ts +12 -0
- package/dist/voice/sttEnvCredentials.js +12 -0
- package/dist/voice/transcribe.d.ts +47 -0
- package/dist/voice/transcribe.js +519 -0
- package/dist/voice/transcribeStream.d.ts +4 -0
- package/dist/voice/transcribeStream.js +584 -0
- package/dist/voice/whistle/assets.d.ts +47 -0
- package/dist/voice/whistle/assets.js +270 -0
- package/dist/voice/whistle/audio.d.ts +32 -0
- package/dist/voice/whistle/audio.js +267 -0
- package/dist/voice/whistle/engine.d.ts +32 -0
- package/dist/voice/whistle/engine.js +193 -0
- package/dist/voice/whistle/worker.d.ts +18 -0
- package/dist/voice/whistle/worker.js +294 -0
- package/docs-site/static/search-index.json +66 -8
- package/models/whistle/README.md +18 -0
- package/models/whistle/needle.js +2 -0
- package/models/whistle/needle.wasm +0 -0
- package/models/whistle/whistle.cact +0 -0
- package/package.json +7 -3
|
@@ -134,6 +134,50 @@ function createFileWatcher(onRestart, quiet) {
|
|
|
134
134
|
/**
|
|
135
135
|
* Serve CLI command factory
|
|
136
136
|
*/
|
|
137
|
+
/** A Node `http.Server` (or `https.Server`): it can take an `upgrade` listener. */
|
|
138
|
+
function isNodeHttpServer(value) {
|
|
139
|
+
return (typeof value === "object" &&
|
|
140
|
+
value !== null &&
|
|
141
|
+
typeof value.on === "function" &&
|
|
142
|
+
typeof value.listen === "function");
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Live transcription streams over a WebSocket upgrade, which the HTTP
|
|
146
|
+
* adapters cannot route; it attaches to the Node server once it listens, on
|
|
147
|
+
* the first start and on every watch-mode restart. Bun and Deno serve
|
|
148
|
+
* without one, and then the route is simply absent. Guarded by the same
|
|
149
|
+
* NEUROLINK_SERVER_API_KEY(s) as the HTTP routes.
|
|
150
|
+
*/
|
|
151
|
+
/** `--cors-origin` values, split on commas and trimmed; `undefined` when none were given. */
|
|
152
|
+
function corsOriginsFromArgv(values) {
|
|
153
|
+
if (!values || values.length === 0) {
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
const origins = values
|
|
157
|
+
.flatMap((value) => String(value).split(","))
|
|
158
|
+
.map((origin) => origin.trim())
|
|
159
|
+
.filter((origin) => origin.length > 0);
|
|
160
|
+
return origins.length > 0 ? origins : undefined;
|
|
161
|
+
}
|
|
162
|
+
async function attachTranscriptionWebSocket(server, neurolink, serverConfig) {
|
|
163
|
+
const native = server.getNativeServer?.();
|
|
164
|
+
if (!isNodeHttpServer(native)) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const { attachTranscribeWebSocket } = await import("../../server/websocket/transcribeWebSocket.js");
|
|
168
|
+
const apiKeys = readServerApiKeys();
|
|
169
|
+
// The same origin allow-list as the HTTP routes: with CORS on and a list
|
|
170
|
+
// that is not "*", a page from an unlisted origin cannot open the stream.
|
|
171
|
+
const origins = serverConfig.cors?.origins;
|
|
172
|
+
const allowedOrigins = serverConfig.cors?.enabled !== false && origins && !origins.includes("*")
|
|
173
|
+
? origins
|
|
174
|
+
: undefined;
|
|
175
|
+
await attachTranscribeWebSocket(native, neurolink, {
|
|
176
|
+
...(apiKeys.length > 0 ? { authToken: apiKeys } : {}),
|
|
177
|
+
...(allowedOrigins ? { allowedOrigins } : {}),
|
|
178
|
+
});
|
|
179
|
+
logger.debug("[serve] transcription WebSocket attached at /v1/audio/transcriptions/stream");
|
|
180
|
+
}
|
|
137
181
|
export class ServeCommandFactory {
|
|
138
182
|
/**
|
|
139
183
|
* Create the main serve command
|
|
@@ -180,6 +224,13 @@ export class ServeCommandFactory {
|
|
|
180
224
|
.option("cors", {
|
|
181
225
|
type: "boolean",
|
|
182
226
|
description: "Enable CORS middleware (default: true)",
|
|
227
|
+
})
|
|
228
|
+
.option("cors-origin", {
|
|
229
|
+
type: "array",
|
|
230
|
+
string: true,
|
|
231
|
+
alias: "corsOrigin",
|
|
232
|
+
description: "Browser origin allowed by CORS (repeat or comma-separate; '*' for any). " +
|
|
233
|
+
"Default: none, so no web page can call the server cross-origin",
|
|
183
234
|
})
|
|
184
235
|
.option("rate-limit", {
|
|
185
236
|
type: "number",
|
|
@@ -351,6 +402,9 @@ export class ServeCommandFactory {
|
|
|
351
402
|
enabled: argv.cors !== undefined
|
|
352
403
|
? argv.cors
|
|
353
404
|
: (fileConfig.cors?.enabled ?? defaultConfig.cors.enabled),
|
|
405
|
+
...(corsOriginsFromArgv(argv.corsOrigin)
|
|
406
|
+
? { origins: corsOriginsFromArgv(argv.corsOrigin) }
|
|
407
|
+
: {}),
|
|
354
408
|
},
|
|
355
409
|
rateLimit: {
|
|
356
410
|
...defaultConfig.rateLimit,
|
|
@@ -366,7 +420,13 @@ export class ServeCommandFactory {
|
|
|
366
420
|
},
|
|
367
421
|
bodyParser: fileConfig.bodyParser,
|
|
368
422
|
logging: fileConfig.logging,
|
|
369
|
-
|
|
423
|
+
// Transcription of a long recording through a remote engine can take
|
|
424
|
+
// longer than the 30 s default, so the request timeout is also
|
|
425
|
+
// settable from the environment (milliseconds); the config file wins.
|
|
426
|
+
timeout: fileConfig.timeout ??
|
|
427
|
+
(Number(process.env.NEUROLINK_SERVER_TIMEOUT_MS) > 0
|
|
428
|
+
? Number(process.env.NEUROLINK_SERVER_TIMEOUT_MS)
|
|
429
|
+
: undefined),
|
|
370
430
|
enableMetrics: fileConfig.enableMetrics ?? true,
|
|
371
431
|
enableSwagger: argv.swagger !== undefined
|
|
372
432
|
? argv.swagger
|
|
@@ -394,6 +454,7 @@ export class ServeCommandFactory {
|
|
|
394
454
|
}
|
|
395
455
|
await withTimeout(serverRef.current.initialize(), 30000, new ServerStartError("Server initialization timed out after 30 seconds", undefined, opts.port, opts.host));
|
|
396
456
|
await withTimeout(serverRef.current.start(), 30000, new ServerStartError("Server startup timed out after 30 seconds", undefined, opts.port, opts.host));
|
|
457
|
+
await attachTranscriptionWebSocket(serverRef.current, neurolink, opts.serverConfig);
|
|
397
458
|
return serverRef;
|
|
398
459
|
}
|
|
399
460
|
/**
|
|
@@ -426,6 +487,11 @@ export class ServeCommandFactory {
|
|
|
426
487
|
}
|
|
427
488
|
const url = `http://${opts.host === "0.0.0.0" ? "localhost" : opts.host}:${opts.port}`;
|
|
428
489
|
const corsEnabled = opts.argv.cors ?? opts.serverConfig.cors?.enabled ?? true;
|
|
490
|
+
// The origin list and the API key together decide whether any browser
|
|
491
|
+
// page may call this server; the banner says which case this is.
|
|
492
|
+
const corsOrigins = opts.serverConfig.cors?.origins ?? [];
|
|
493
|
+
const corsWildcard = corsEnabled && corsOrigins.includes("*");
|
|
494
|
+
const corsNoOrigins = corsEnabled && corsOrigins.length === 0;
|
|
429
495
|
const rateLimitValue = opts.argv.rateLimit ?? opts.serverConfig.rateLimit?.maxRequests ?? 100;
|
|
430
496
|
const rateLimitEnabled = rateLimitValue > 0;
|
|
431
497
|
const swaggerEnabled = opts.argv.swagger ?? opts.serverConfig.enableSwagger ?? false;
|
|
@@ -436,6 +502,8 @@ export class ServeCommandFactory {
|
|
|
436
502
|
pid: state.pid,
|
|
437
503
|
configFile: opts.argv.config,
|
|
438
504
|
corsEnabled,
|
|
505
|
+
corsWildcard,
|
|
506
|
+
corsNoOrigins,
|
|
439
507
|
rateLimitEnabled,
|
|
440
508
|
rateLimitValue,
|
|
441
509
|
swaggerEnabled,
|
|
@@ -461,7 +529,16 @@ export class ServeCommandFactory {
|
|
|
461
529
|
}
|
|
462
530
|
logger.always("");
|
|
463
531
|
logger.always(chalk.bold("Middleware:"));
|
|
464
|
-
logger.always(` CORS: ${info.corsEnabled
|
|
532
|
+
logger.always(` CORS: ${!info.corsEnabled
|
|
533
|
+
? chalk.yellow("disabled")
|
|
534
|
+
: info.corsWildcard
|
|
535
|
+
? info.authEnabled
|
|
536
|
+
? chalk.green("enabled (any origin; API key required)")
|
|
537
|
+
: chalk.yellow("enabled for ANY origin and no API key — any web page can call this server; set " +
|
|
538
|
+
SERVER_API_KEY_ENV)
|
|
539
|
+
: info.corsNoOrigins
|
|
540
|
+
? chalk.yellow("enabled, no origins listed — browsers cannot call this server; pass --cors-origin or set cors.origins")
|
|
541
|
+
: chalk.green("enabled (listed origins)")}`);
|
|
465
542
|
logger.always(` Rate Limit: ${info.rateLimitEnabled ? chalk.green(`enabled (${info.rateLimitValue} req/15min)`) : chalk.yellow("disabled")}`);
|
|
466
543
|
logger.always(` Swagger: ${info.swaggerEnabled ? chalk.green("enabled") : chalk.yellow("disabled")}`);
|
|
467
544
|
if (info.watchEnabled) {
|
|
@@ -513,7 +590,8 @@ export class ServeCommandFactory {
|
|
|
513
590
|
const timestamp = Date.now();
|
|
514
591
|
const { createServer: createNewServer, registerAllRoutes: registerNewRoutes, } = await import(`../../server/index.js?t=${timestamp}`);
|
|
515
592
|
// Create new server
|
|
516
|
-
const
|
|
593
|
+
const newNeurolink = new NeuroLink();
|
|
594
|
+
const newServer = await createNewServer(newNeurolink, {
|
|
517
595
|
framework: ctx.framework,
|
|
518
596
|
config: ctx.serverConfig,
|
|
519
597
|
});
|
|
@@ -522,6 +600,10 @@ export class ServeCommandFactory {
|
|
|
522
600
|
// Initialize and start with timeouts
|
|
523
601
|
await withTimeout(newServer.initialize(), 30000, new ServerStartError("Server initialization timed out during restart", undefined, ctx.port, ctx.host));
|
|
524
602
|
await withTimeout(newServer.start(), 30000, new ServerStartError("Server startup timed out during restart", undefined, ctx.port, ctx.host));
|
|
603
|
+
// The upgrade handler lives on the old adapter's http.Server; the
|
|
604
|
+
// restarted one needs its own, or the stream route is gone after the
|
|
605
|
+
// first file change.
|
|
606
|
+
await attachTranscriptionWebSocket(newServer, newNeurolink, ctx.serverConfig);
|
|
525
607
|
// Update the reference so signal handlers use the new server instance
|
|
526
608
|
ctx.serverRef.current = newServer;
|
|
527
609
|
logger.always(chalk.green("Server restarted successfully"));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* NeuroLink CLI Transcribe Command
|
|
4
|
+
*
|
|
5
|
+
* Calls `NeuroLink.transcribe()` — audio in, text out — or, with `--stream`,
|
|
6
|
+
* `NeuroLink.transcribeStream()` over the file decoded to 16 kHz mono PCM16.
|
|
7
|
+
* See src/lib/types/transcribe.ts for the full vocabulary (dictionary,
|
|
8
|
+
* correction, second opinion, fallback).
|
|
9
|
+
*
|
|
10
|
+
* Credentials are env-only here, exactly as every other CLI command: each STT
|
|
11
|
+
* handler reads its own settings, and `NEUROLINK_STT_PROVIDER`,
|
|
12
|
+
* `NEUROLINK_STT_MODEL` and `NEUROLINK_STT_LANGUAGE` pick the defaults. With
|
|
13
|
+
* nothing configured the built-in local engine (Whistle) is used.
|
|
14
|
+
*/
|
|
15
|
+
import type { CommandModule } from "yargs";
|
|
16
|
+
import type { CliTranscribeArgs } from "../../types/index.js";
|
|
17
|
+
export declare const transcribeCommand: CommandModule<object, CliTranscribeArgs>;
|
|
18
|
+
/**
|
|
19
|
+
* Create transcribe command factory for CLICommandFactory-style registration,
|
|
20
|
+
* matching the DecideCommandFactory pattern.
|
|
21
|
+
*/
|
|
22
|
+
export declare class TranscribeCommandFactory {
|
|
23
|
+
static createTranscribeCommand(): CommandModule;
|
|
24
|
+
}
|