@juspay/neurolink 12.48.2 → 12.49.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.
- package/CHANGELOG.md +2 -2
- 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/providerDescriptors.js +5 -4
- 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/providers/cloudflareClef.js +9 -1
- 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 +71 -12
- 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
package/dist/types/cli.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { VideoGenerationResult } from "./multimodal.js";
|
|
|
10
10
|
import type { PPTGenerationResult } from "./ppt.js";
|
|
11
11
|
import type { AvatarResult } from "./avatar.js";
|
|
12
12
|
import type { MusicResult } from "./music.js";
|
|
13
|
+
import type { TranscribeStreamEvent } from "./transcribe.js";
|
|
13
14
|
import type { OAuthTokens } from "./auth.js";
|
|
14
15
|
import type { AccountQuota, ProxyPassthroughAccount } from "./proxy.js";
|
|
15
16
|
import type { ClaudeSubscriptionTier } from "./subscription.js";
|
|
@@ -1144,6 +1145,8 @@ export type ServeCommandArgs = {
|
|
|
1144
1145
|
framework?: ServerFramework;
|
|
1145
1146
|
basePath?: string;
|
|
1146
1147
|
cors?: boolean;
|
|
1148
|
+
/** Browser origins allowed by CORS (`--cors-origin`, repeatable or comma-separated). */
|
|
1149
|
+
corsOrigin?: string[];
|
|
1147
1150
|
rateLimit?: number;
|
|
1148
1151
|
swagger?: boolean;
|
|
1149
1152
|
config?: string;
|
|
@@ -1320,6 +1323,47 @@ export type CliDecideArgs = {
|
|
|
1320
1323
|
format?: "text" | "json";
|
|
1321
1324
|
debug?: boolean;
|
|
1322
1325
|
};
|
|
1326
|
+
/** Arguments for `neurolink transcribe <file|->`. */
|
|
1327
|
+
export type CliTranscribeArgs = {
|
|
1328
|
+
/** Audio file path, or `-` to read the audio from stdin. */
|
|
1329
|
+
file?: string;
|
|
1330
|
+
provider?: string;
|
|
1331
|
+
model?: string;
|
|
1332
|
+
/** ISO / BCP-47 code, or `auto` (the default) to let the engine detect it. */
|
|
1333
|
+
language?: string;
|
|
1334
|
+
diarize?: boolean;
|
|
1335
|
+
wordTimestamps?: boolean;
|
|
1336
|
+
prompt?: string;
|
|
1337
|
+
/** Path to a JSON array of `{ term, heardAs, meaning }`. */
|
|
1338
|
+
dictionary?: string;
|
|
1339
|
+
/** Inline dictionary entries: `"Term|heard,as|meaning"`. */
|
|
1340
|
+
term?: string[];
|
|
1341
|
+
correct?: boolean;
|
|
1342
|
+
rewriteProvider?: string;
|
|
1343
|
+
rewriteModel?: string;
|
|
1344
|
+
/** `--no-rewrite` sets this to `false`. */
|
|
1345
|
+
rewrite?: boolean;
|
|
1346
|
+
transliterate?: "latin" | "native";
|
|
1347
|
+
secondOpinion?: string;
|
|
1348
|
+
fallback?: string;
|
|
1349
|
+
context?: string;
|
|
1350
|
+
stream?: boolean;
|
|
1351
|
+
format?: "text" | "json" | "srt" | "vtt";
|
|
1352
|
+
timeout?: number;
|
|
1353
|
+
quiet?: boolean;
|
|
1354
|
+
debug?: boolean;
|
|
1355
|
+
};
|
|
1356
|
+
/** One subtitle cue built from segment or word timings (`--format srt|vtt`). */
|
|
1357
|
+
export type CliSubtitleCue = {
|
|
1358
|
+
start: number;
|
|
1359
|
+
end: number;
|
|
1360
|
+
text: string;
|
|
1361
|
+
};
|
|
1362
|
+
/** Prints `transcribeStream()` events for one `--stream` run. */
|
|
1363
|
+
export type CliTranscribeStreamSink = {
|
|
1364
|
+
event(event: TranscribeStreamEvent): void;
|
|
1365
|
+
finish(): void;
|
|
1366
|
+
};
|
|
1323
1367
|
/** Base options shared across all `neurolink evaluate` subcommands. */
|
|
1324
1368
|
export type BaseEvaluateArgs = {
|
|
1325
1369
|
json?: boolean;
|
|
@@ -1422,6 +1466,8 @@ export type ServerInstance = {
|
|
|
1422
1466
|
registerRouteGroup: (group: import("./server.js").RouteGroup) => void;
|
|
1423
1467
|
registerMiddleware: (middleware: import("./server.js").MiddlewareDefinition) => void;
|
|
1424
1468
|
listRoutes?: () => import("./server.js").RouteDefinition[];
|
|
1469
|
+
/** The listening Node http.Server, when the adapter has one to attach WebSocket upgrades to. */
|
|
1470
|
+
getNativeServer?: () => unknown;
|
|
1425
1471
|
};
|
|
1426
1472
|
/** Persisted state for a running `neurolink serve` process. */
|
|
1427
1473
|
export type ServeState = {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -77,6 +77,7 @@ export * from "./tools.js";
|
|
|
77
77
|
export * from "./vectorStoreChroma.js";
|
|
78
78
|
export * from "./vectorStorePinecone.js";
|
|
79
79
|
export * from "./voice.js";
|
|
80
|
+
export * from "./transcribe.js";
|
|
80
81
|
export * from "./utilities.js";
|
|
81
82
|
export * from "./workflow.js";
|
|
82
83
|
export * from "./ioProcessor.js";
|
package/dist/types/index.js
CHANGED
|
@@ -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
|
/**
|
package/dist/types/server.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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 & {
|
package/dist/types/stt.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
423
|
-
temperature
|
|
424
|
-
avg_logprob
|
|
425
|
-
compression_ratio
|
|
426
|
-
no_speech_prob
|
|
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;
|