@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.
Files changed (104) hide show
  1. package/CHANGELOG.md +3 -3
  2. package/dist/browser/neurolink.min.js +616 -595
  3. package/dist/cli/commands/serve.d.ts +0 -3
  4. package/dist/cli/commands/serve.js +85 -3
  5. package/dist/cli/commands/transcribe.d.ts +24 -0
  6. package/dist/cli/commands/transcribe.js +718 -0
  7. package/dist/cli/factories/commandFactory.d.ts +10 -0
  8. package/dist/cli/factories/commandFactory.js +13 -0
  9. package/dist/cli/parser.js +3 -0
  10. package/dist/factories/mediaHandlerCatalog.js +11 -9
  11. package/dist/factories/sttDescriptors.d.ts +63 -0
  12. package/dist/factories/sttDescriptors.js +286 -0
  13. package/dist/index.d.ts +4 -1
  14. package/dist/index.js +7 -1
  15. package/dist/neurolink.d.ts +68 -1
  16. package/dist/neurolink.js +202 -4
  17. package/dist/processors/media/AudioProcessor.d.ts +15 -56
  18. package/dist/processors/media/AudioProcessor.js +105 -276
  19. package/dist/processors/media/VideoProcessor.d.ts +3 -5
  20. package/dist/processors/media/VideoProcessor.js +52 -51
  21. package/dist/server/abstract/baseServerAdapter.d.ts +7 -0
  22. package/dist/server/abstract/baseServerAdapter.js +13 -1
  23. package/dist/server/adapters/expressAdapter.d.ts +1 -0
  24. package/dist/server/adapters/expressAdapter.js +48 -4
  25. package/dist/server/adapters/fastifyAdapter.d.ts +1 -0
  26. package/dist/server/adapters/fastifyAdapter.js +38 -1
  27. package/dist/server/adapters/honoAdapter.d.ts +1 -4
  28. package/dist/server/adapters/honoAdapter.js +83 -1
  29. package/dist/server/adapters/koaAdapter.d.ts +1 -0
  30. package/dist/server/adapters/koaAdapter.js +43 -0
  31. package/dist/server/index.d.ts +3 -2
  32. package/dist/server/index.js +3 -2
  33. package/dist/server/routes/index.d.ts +1 -0
  34. package/dist/server/routes/index.js +3 -0
  35. package/dist/server/routes/transcribeRoutes.d.ts +23 -0
  36. package/dist/server/routes/transcribeRoutes.js +506 -0
  37. package/dist/server/utils/rawBody.d.ts +32 -0
  38. package/dist/server/utils/rawBody.js +76 -0
  39. package/dist/server/utils/validation.d.ts +192 -0
  40. package/dist/server/utils/validation.js +100 -0
  41. package/dist/server/websocket/transcribeWebSocket.d.ts +42 -0
  42. package/dist/server/websocket/transcribeWebSocket.js +264 -0
  43. package/dist/types/cli.d.ts +46 -0
  44. package/dist/types/index.d.ts +1 -0
  45. package/dist/types/index.js +1 -0
  46. package/dist/types/providers.d.ts +7 -1
  47. package/dist/types/server.d.ts +117 -1
  48. package/dist/types/stt.d.ts +160 -7
  49. package/dist/types/transcribe.d.ts +506 -0
  50. package/dist/types/transcribe.js +29 -0
  51. package/dist/utils/speakerTurns.d.ts +28 -0
  52. package/dist/utils/speakerTurns.js +93 -0
  53. package/dist/utils/sttProcessor.d.ts +20 -2
  54. package/dist/utils/sttProcessor.js +73 -5
  55. package/dist/voice/correction/dictionary.d.ts +49 -0
  56. package/dist/voice/correction/dictionary.js +134 -0
  57. package/dist/voice/correction/guard.d.ts +35 -0
  58. package/dist/voice/correction/guard.js +161 -0
  59. package/dist/voice/correction/index.d.ts +47 -0
  60. package/dist/voice/correction/index.js +211 -0
  61. package/dist/voice/correction/rewrite.d.ts +92 -0
  62. package/dist/voice/correction/rewrite.js +322 -0
  63. package/dist/voice/errors.d.ts +15 -0
  64. package/dist/voice/errors.js +45 -0
  65. package/dist/voice/index.d.ts +20 -2
  66. package/dist/voice/index.js +75 -9
  67. package/dist/voice/providers/AzureSTT.d.ts +10 -7
  68. package/dist/voice/providers/AzureSTT.js +23 -75
  69. package/dist/voice/providers/DeepgramSTT.d.ts +17 -2
  70. package/dist/voice/providers/DeepgramSTT.js +109 -13
  71. package/dist/voice/providers/ElevenLabsSTT.d.ts +12 -2
  72. package/dist/voice/providers/ElevenLabsSTT.js +34 -8
  73. package/dist/voice/providers/GoogleSTT.d.ts +10 -8
  74. package/dist/voice/providers/GoogleSTT.js +21 -75
  75. package/dist/voice/providers/OpenAISTT.d.ts +30 -9
  76. package/dist/voice/providers/OpenAISTT.js +196 -21
  77. package/dist/voice/providers/WhistleSTT.d.ts +87 -0
  78. package/dist/voice/providers/WhistleSTT.js +313 -0
  79. package/dist/voice/streaming/chunkedStreamAdapter.d.ts +19 -0
  80. package/dist/voice/streaming/chunkedStreamAdapter.js +519 -0
  81. package/dist/voice/streaming/endpointer.d.ts +81 -0
  82. package/dist/voice/streaming/endpointer.js +247 -0
  83. package/dist/voice/streaming/localAgreement.d.ts +30 -0
  84. package/dist/voice/streaming/localAgreement.js +44 -0
  85. package/dist/voice/sttEnvCredentials.d.ts +12 -0
  86. package/dist/voice/sttEnvCredentials.js +12 -0
  87. package/dist/voice/transcribe.d.ts +47 -0
  88. package/dist/voice/transcribe.js +519 -0
  89. package/dist/voice/transcribeStream.d.ts +4 -0
  90. package/dist/voice/transcribeStream.js +584 -0
  91. package/dist/voice/whistle/assets.d.ts +47 -0
  92. package/dist/voice/whistle/assets.js +270 -0
  93. package/dist/voice/whistle/audio.d.ts +32 -0
  94. package/dist/voice/whistle/audio.js +267 -0
  95. package/dist/voice/whistle/engine.d.ts +32 -0
  96. package/dist/voice/whistle/engine.js +193 -0
  97. package/dist/voice/whistle/worker.d.ts +18 -0
  98. package/dist/voice/whistle/worker.js +294 -0
  99. package/docs-site/static/search-index.json +66 -8
  100. package/models/whistle/README.md +18 -0
  101. package/models/whistle/needle.js +2 -0
  102. package/models/whistle/needle.wasm +0 -0
  103. package/models/whistle/whistle.cact +0 -0
  104. package/package.json +7 -3
@@ -81,6 +81,7 @@ export * from "./tools.js";
81
81
  export * from "./vectorStoreChroma.js";
82
82
  export * from "./vectorStorePinecone.js";
83
83
  export * from "./voice.js";
84
+ export * from "./transcribe.js";
84
85
  export * from "./utilities.js";
85
86
  export * from "./workflow.js";
86
87
  // Processor base types are re-exported via ./processor.js
@@ -5,6 +5,7 @@ import type { UnknownRecord, JsonValue, StreamingCapability } from "./common.js"
5
5
  import type { NeuroLink } from "../neurolink.js";
6
6
  import { AIProviderName, AnthropicModels, BedrockModels, DeepSeekModels, GoogleAIModels, LlamaCppModels, LMStudioModels, NvidiaNimModels, OpenAIModels, VertexModels } from "../constants/enums.js";
7
7
  import type { ValidationSchema } from "./aliases.js";
8
+ import type { STTCredentials } from "./transcribe.js";
8
9
  import type { DecisionLimits, DecisionRequest, DecisionResult } from "./decision.js";
9
10
  import type { FileToolRootPolicy } from "./fileToolRoots.js";
10
11
  import type { EnhancedGenerateResult, TextGenerationOptions } from "./generate.js";
@@ -105,6 +106,11 @@ export type NeurolinkCredentials = {
105
106
  apiKey?: string;
106
107
  baseURL?: string;
107
108
  };
109
+ /**
110
+ * Speech-to-text handlers (`transcribe()`, and `generate`/`stream` with
111
+ * `stt`). One slice per STT provider; see `STTCredentials`.
112
+ */
113
+ stt?: STTCredentials;
108
114
  /**
109
115
  * Anthropic. `baseURL` points the official SDK client at a gateway or proxy
110
116
  * instead of `api.anthropic.com` (with or without a trailing `/v1`); it
@@ -2293,7 +2299,7 @@ export type ProviderRegistration = {
2293
2299
  * calibrated judgements and no text at all — see src/lib/types/decision.ts.
2294
2300
  * They are peers: a provider may serve any subset.
2295
2301
  */
2296
- export type InferenceKind = "generate" | "stream" | "decide";
2302
+ export type InferenceKind = "generate" | "stream" | "decide" | "transcribe";
2297
2303
  /** What a descriptor means when it declares no `inferenceKinds`. */
2298
2304
  export declare const DEFAULT_INFERENCE_KINDS: readonly InferenceKind[];
2299
2305
  /**
@@ -8,6 +8,8 @@ import type { NeuroLink } from "../neurolink.js";
8
8
  import type { JsonObject, JsonValue } from "./common.js";
9
9
  import type { ExternalMCPServerStatus } from "./externalMcp.js";
10
10
  import type { ProxyRuntimeConfigProvider } from "./proxy.js";
11
+ import type { TTSAudioFormat } from "./tts.js";
12
+ import type { STTCorrectionOptions, STTDictionaryEntry, STTFallbackOptions, STTDecisionRecord, STTEngineInfo, STTStreamingOptions, TranscribeTimings } from "./transcribe.js";
11
13
  /**
12
14
  * Server adapter configuration
13
15
  */
@@ -63,7 +65,10 @@ export type RequiredServerAdapterConfig = {
63
65
  export type CORSConfig = {
64
66
  /** Enable CORS (default: true) */
65
67
  enabled?: boolean;
66
- /** Allowed origins (default: ["*"]) */
68
+ /**
69
+ * Allowed browser origins. Default `[]`: no cross-origin page may call the
70
+ * server until an origin is listed; `["*"]` opts in to any origin.
71
+ */
67
72
  origins?: string[];
68
73
  /** Allowed HTTP methods */
69
74
  methods?: string[];
@@ -1095,6 +1100,117 @@ export type CreateRoutesOptions = {
1095
1100
  * docs/features/codex-proxy-support.md.
1096
1101
  */
1097
1102
  runtimeConfigProvider?: ProxyRuntimeConfigProvider;
1103
+ /**
1104
+ * Options for the transcription routes (`POST <basePath>/agent/transcribe`
1105
+ * and the OpenAI-compatible `POST /v1/audio/transcriptions`), which are
1106
+ * always mounted.
1107
+ */
1108
+ transcribe?: ServerTranscribeRouteOptions;
1109
+ };
1110
+ /** Options for `createTranscribeRoutes()`. */
1111
+ export type ServerTranscribeRouteOptions = {
1112
+ /**
1113
+ * Directories a request's `audioPath` may point into. Empty or omitted (the
1114
+ * default) refuses every `audioPath`: a server must not read its own disk
1115
+ * on a caller's say-so unless the operator names where.
1116
+ */
1117
+ allowedAudioRoots?: string[];
1118
+ /** Largest audio accepted, decoded, in bytes. Default 50 MB. */
1119
+ maxAudioBytes?: number;
1120
+ /**
1121
+ * Prefix of the OpenAI-compatible route. Default `""`, so the route is
1122
+ * `/v1/audio/transcriptions` and an OpenAI client pointed at
1123
+ * `http://host:port/v1` works unchanged.
1124
+ */
1125
+ openaiBasePath?: string;
1126
+ };
1127
+ /**
1128
+ * Body of `POST <basePath>/agent/transcribe`. Exactly one of `audio`,
1129
+ * `audioUrl` or `audioPath`. There is no `credentials` field: a caller cannot
1130
+ * swap in its own key or point an engine at another host.
1131
+ */
1132
+ export type ServerTranscribeRequest = {
1133
+ /** Base64 audio, or a `data:` URL. */
1134
+ audio?: string;
1135
+ /** `http(s)` URL the server downloads (SSRF-guarded, size-capped). */
1136
+ audioUrl?: string;
1137
+ /** Server-local path; refused unless it lies under `allowedAudioRoots`. */
1138
+ audioPath?: string;
1139
+ format?: TTSAudioFormat;
1140
+ provider?: string;
1141
+ model?: string;
1142
+ language?: string;
1143
+ prompt?: string;
1144
+ dictionary?: STTDictionaryEntry[];
1145
+ correction?: STTCorrectionOptions;
1146
+ fallback?: STTFallbackOptions;
1147
+ diarization?: boolean;
1148
+ wordTimestamps?: boolean;
1149
+ timeoutMs?: number;
1150
+ };
1151
+ /** The transcribe WebSocket's first text frame: the JSON route's fields without the audio. */
1152
+ export type ServerTranscribeStreamConfig = Omit<ServerTranscribeRequest, "audio" | "audioUrl" | "audioPath" | "format"> & {
1153
+ streaming?: STTStreamingOptions;
1154
+ };
1155
+ /** One segment of the OpenAI `verbose_json` transcription shape. */
1156
+ export type ServerOpenAITranscriptionSegment = {
1157
+ id: number;
1158
+ start: number;
1159
+ end: number;
1160
+ text: string;
1161
+ /** NeuroLink extension: speaker label when diarization ran. */
1162
+ speaker?: string;
1163
+ };
1164
+ /** One word of the OpenAI `verbose_json` transcription shape. */
1165
+ export type ServerOpenAITranscriptionWord = {
1166
+ word: string;
1167
+ start: number;
1168
+ end: number;
1169
+ /** NeuroLink extension: speaker label when diarization ran. */
1170
+ speaker?: string;
1171
+ };
1172
+ /**
1173
+ * `POST /v1/audio/transcriptions` with `response_format=verbose_json`:
1174
+ * OpenAI's shape, plus NeuroLink's extras in snake_case.
1175
+ */
1176
+ export type ServerOpenAITranscriptionResponse = {
1177
+ task: "transcribe";
1178
+ text: string;
1179
+ language?: string;
1180
+ duration?: number;
1181
+ segments?: ServerOpenAITranscriptionSegment[];
1182
+ words?: ServerOpenAITranscriptionWord[];
1183
+ /** Engine text before correction. */
1184
+ raw: string;
1185
+ /** Present when the correction changed the text. */
1186
+ corrected?: string;
1187
+ decisions?: STTDecisionRecord[];
1188
+ engine: STTEngineInfo;
1189
+ language_detected?: boolean;
1190
+ steps: string[];
1191
+ timings: TranscribeTimings;
1192
+ };
1193
+ /** Options for `attachTranscribeWebSocket()`. */
1194
+ export type ServerTranscribeWebSocketOptions = {
1195
+ /** Upgrade path. Default `/v1/audio/transcriptions/stream`. */
1196
+ path?: string;
1197
+ /**
1198
+ * Token(s) required on the upgrade (`Authorization: Bearer` header or
1199
+ * `?token=`). `neurolink serve` passes the same keys as its HTTP routes
1200
+ * (`NEUROLINK_SERVER_API_KEY`, comma-separated), so one setting guards both.
1201
+ */
1202
+ authToken?: string | readonly string[];
1203
+ /**
1204
+ * Browser origins allowed to upgrade. A browser always sends `Origin` on a
1205
+ * WebSocket upgrade, and an upgrade whose `Origin` is not listed is refused
1206
+ * with 403; a request without the header (a non-browser client) is let
1207
+ * through, as CORS does not apply to it. Omitted, or containing `"*"`, means
1208
+ * any origin. `neurolink serve` passes its `cors.origins` here so one
1209
+ * allow-list covers the HTTP routes and the stream.
1210
+ */
1211
+ allowedOrigins?: readonly string[];
1212
+ /** Largest single frame, in bytes. Default 1 MiB. */
1213
+ maxPayload?: number;
1098
1214
  };
1099
1215
  /** Data stream finish event. */
1100
1216
  export type FinishEvent = DataStreamEvent & {
@@ -39,6 +39,14 @@ export type STTOptions = {
39
39
  model?: string;
40
40
  /** Custom vocabulary/phrases */
41
41
  vocabulary?: string[];
42
+ /**
43
+ * Context prompt for engines that bias on one (Whisper and other
44
+ * OpenAI-compatible servers). Engines without a prompt ignore it;
45
+ * `vocabulary` terms are appended by the handlers that accept a prompt.
46
+ */
47
+ prompt?: string;
48
+ /** Per-request timeout in milliseconds, for handlers that honour one. */
49
+ timeoutMs?: number;
42
50
  /** Minimum confidence threshold */
43
51
  confidenceThreshold?: number;
44
52
  /**
@@ -160,6 +168,13 @@ export type STTHandler = {
160
168
  getSupportedLanguages?(): Promise<STTLanguage[]>;
161
169
  getSupportedFormats(): TTSAudioFormat[];
162
170
  isConfigured(): boolean;
171
+ /**
172
+ * What would make `isConfigured()` true, in the handler's own words — the
173
+ * env var or key for a hosted engine, the files and their download URLs for
174
+ * a local one. Appended to the "not configured" error so the caller is told
175
+ * what to do rather than "set the required API keys".
176
+ */
177
+ describeConfiguration?(): string;
163
178
  maxAudioDuration?: number;
164
179
  supportsStreaming?: boolean;
165
180
  };
@@ -262,7 +277,12 @@ export type GoogleSTTOptions = STTOptions & {
262
277
  useEnhanced?: boolean;
263
278
  keywords?: string[];
264
279
  };
265
- export type WhisperModel = "whisper-1";
280
+ /**
281
+ * `whisper-1` is OpenAI's own model; any other string is passed through as-is,
282
+ * which is what a self-hosted OpenAI-compatible transcription server (vLLM,
283
+ * LiteLLM, a diarization sidecar) expects — e.g. `"qwen3-asr"`.
284
+ */
285
+ export type WhisperModel = "whisper-1" | (string & NonNullable<unknown>);
266
286
  export type WhisperSTTOptions = STTOptions & {
267
287
  model?: WhisperModel;
268
288
  responseFormat?: "json" | "text" | "srt" | "verbose_json" | "vtt";
@@ -270,6 +290,12 @@ export type WhisperSTTOptions = STTOptions & {
270
290
  prompt?: string;
271
291
  /** Translate audio to English instead of transcribing in original language */
272
292
  translate?: boolean;
293
+ /**
294
+ * Request timeout in milliseconds. Default 30_000, which suits OpenAI's
295
+ * hosted endpoint; a self-hosted server transcribing a whole meeting needs
296
+ * minutes, so raise it (or set `OPENAI_STT_TIMEOUT_MS`).
297
+ */
298
+ timeoutMs?: number;
273
299
  };
274
300
  export type AzureWord = {
275
301
  Word: string;
@@ -320,6 +346,9 @@ export type DeepgramAlternative = {
320
346
  };
321
347
  export type DeepgramChannel = {
322
348
  alternatives: DeepgramAlternative[];
349
+ /** Present when the request asked for `detect_language`. */
350
+ detected_language?: string;
351
+ language_confidence?: number;
323
352
  };
324
353
  export type DeepgramUtterance = {
325
354
  start: number;
@@ -415,15 +444,22 @@ export type WhisperTranscriptionWord = {
415
444
  };
416
445
  export type WhisperTranscriptionSegment = {
417
446
  id: number;
418
- seek: number;
447
+ /** OpenAI always sends these decoder stats; OpenAI-compatible servers may omit them. */
448
+ seek?: number;
419
449
  start: number;
420
450
  end: number;
421
451
  text: string;
422
- tokens: number[];
423
- temperature: number;
424
- avg_logprob: number;
425
- compression_ratio: number;
426
- no_speech_prob: number;
452
+ tokens?: number[];
453
+ temperature?: number;
454
+ avg_logprob?: number;
455
+ compression_ratio?: number;
456
+ no_speech_prob?: number;
457
+ /**
458
+ * Not part of OpenAI's schema. Diarizing OpenAI-compatible servers (the
459
+ * NeuroLink diarization sidecar, Deepgram's compat endpoint, …) label each
460
+ * segment with a speaker; the handler surfaces it as `TranscriptionSegment.speaker`.
461
+ */
462
+ speaker?: string;
427
463
  };
428
464
  export type WhisperVerboseResponse = {
429
465
  task: string;
@@ -432,6 +468,20 @@ export type WhisperVerboseResponse = {
432
468
  text: string;
433
469
  segments?: WhisperTranscriptionSegment[];
434
470
  words?: WhisperTranscriptionWord[];
471
+ /** Extension: distinct speaker labels, in order of first appearance. */
472
+ speakers?: string[];
473
+ /**
474
+ * Extension: a self-hosted server that scores language identification may
475
+ * say whether it trusts its own detection. Read defensively; never required.
476
+ */
477
+ language_detected?: boolean;
478
+ /** Extension: candidate languages and the server's score for each. */
479
+ language_scores?: Array<{
480
+ language: string;
481
+ score: number;
482
+ }>;
483
+ /** Extension: the server's confidence in `language`. */
484
+ language_confidence?: number;
435
485
  };
436
486
  export type WhisperSimpleResponse = {
437
487
  text: string;
@@ -640,3 +690,106 @@ export type GeminiResponse = {
640
690
  ids: string[];
641
691
  };
642
692
  };
693
+ /** The three files the built-in Whistle engine needs on disk. */
694
+ export type WhistleAssetName = "needle.js" | "needle.wasm" | "whistle.cact";
695
+ /** One pinned Whistle asset: where it comes from and what it must hash to. */
696
+ export type WhistleAsset = {
697
+ name: WhistleAssetName;
698
+ url: string;
699
+ sha256: string;
700
+ /** Exact size in bytes, used for the download notice and a cheap pre-check. */
701
+ bytes: number;
702
+ };
703
+ /** Absolute paths of the three Whistle files once they are present and verified. */
704
+ export type WhistleAssetPaths = Record<WhistleAssetName, string>;
705
+ /** One word as the Whistle engine reports it (seconds from the start of the audio). */
706
+ export type WhistleWord = {
707
+ word: string;
708
+ start: number;
709
+ end: number;
710
+ probability: number;
711
+ };
712
+ /** A finished batch transcription from the Whistle worker, all chunks joined. */
713
+ export type WhistleEngineOutput = {
714
+ text: string;
715
+ language: string | null;
716
+ words: WhistleWord[];
717
+ /** Time to first token of the first chunk. */
718
+ ttftMs: number | null;
719
+ /** Mean decode speed over the chunks, tokens per second. */
720
+ decodeTps: number | null;
721
+ /** How many ≤30 s pieces the audio was cut into. */
722
+ chunks: number;
723
+ };
724
+ /** One step of the engine's native stream: what this chunk committed, and the unconfirmed tail. */
725
+ export type WhistleStreamStep = {
726
+ text: string;
727
+ words: WhistleWord[];
728
+ pending: string;
729
+ language: string | null;
730
+ /** Seconds of audio received so far. */
731
+ received: number;
732
+ passMs: number;
733
+ };
734
+ /** Messages the handler sends to the Whistle worker thread. */
735
+ export type WhistleWorkerRequest = {
736
+ id: number;
737
+ op: "transcribe";
738
+ pcm: Float32Array;
739
+ language: string | null;
740
+ keywords: string | null;
741
+ timestamps: boolean;
742
+ } | {
743
+ id: number;
744
+ op: "streamProcess";
745
+ pcm: Float32Array;
746
+ language: string | null;
747
+ keywords: string | null;
748
+ } | {
749
+ id: number;
750
+ op: "streamStop";
751
+ };
752
+ /** Messages the Whistle worker thread sends back. */
753
+ export type WhistleWorkerResponse = {
754
+ kind: "ready";
755
+ loadMs: number;
756
+ } | {
757
+ kind: "bootError";
758
+ error: string;
759
+ } | {
760
+ kind: "transcribed";
761
+ id: number;
762
+ result: WhistleEngineOutput;
763
+ } | {
764
+ kind: "streamStep";
765
+ id: number;
766
+ result: WhistleStreamStep;
767
+ } | {
768
+ kind: "failed";
769
+ id: number;
770
+ error: string;
771
+ };
772
+ /** `workerData` for the Whistle worker thread. */
773
+ export type WhistleWorkerData = {
774
+ paths: WhistleAssetPaths;
775
+ };
776
+ /** The subset of the Emscripten "needle" module the Whistle worker calls. */
777
+ export type WhistleNeedleModule = {
778
+ HEAPU8: Uint8Array;
779
+ _malloc(size: number): number;
780
+ _free(ptr: number): void;
781
+ _needle_load(ptr: number, length: bigint): number;
782
+ _needle_last_error(): number;
783
+ _needle_transcribe(pcm: number, samples: number, language: number, keywords: number, timestamps: number, out: number, outCapacity: number): number;
784
+ _needle_stream_transcribe_process(pcm: number, samples: number, language: number, keywords: number, out: number, outCapacity: number): number;
785
+ _needle_stream_transcribe_stop(out: number, outCapacity: number): number;
786
+ UTF8ToString(ptr: number): string;
787
+ };
788
+ /** `createNeedle` — the factory `needle.js` exports. */
789
+ export type WhistleNeedleFactory = (moduleArg: {
790
+ wasmBinary?: Uint8Array;
791
+ print?: (text: string) => void;
792
+ printErr?: (text: string) => void;
793
+ }) => Promise<WhistleNeedleModule>;
794
+ /** A worker request before the engine stamps its id (the `Omit` distributes over the union). */
795
+ export type WhistleWorkerOutgoing<T = WhistleWorkerRequest> = T extends unknown ? Omit<T, "id"> : never;