@juspay/neurolink 13.7.0 → 13.8.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 +3 -6
- package/dist/browser/neurolink.min.js +480 -460
- package/dist/cli/commands/serve.js +11 -1
- package/dist/cli/commands/transcribe.js +39 -3
- package/dist/constants/langfuse.d.ts +2 -0
- package/dist/constants/langfuse.js +2 -0
- package/dist/factories/sttDescriptors.js +7 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4 -2
- package/dist/mcp/externalServerManager.js +4 -1
- package/dist/mcp/mcpClientFactory.d.ts +6 -0
- package/dist/mcp/mcpClientFactory.js +44 -0
- package/dist/neurolink.js +42 -3
- package/dist/observability/exporters/langfuseExporter.d.ts +4 -0
- package/dist/observability/exporters/langfuseExporter.js +29 -8
- package/dist/observability/otlpEncoding.js +2 -2
- package/dist/server/abstract/baseServerAdapter.js +2 -0
- package/dist/server/adapters/expressAdapter.js +1 -1
- package/dist/server/adapters/fastifyAdapter.js +4 -1
- package/dist/server/adapters/honoAdapter.js +1 -1
- package/dist/server/adapters/koaAdapter.js +1 -1
- package/dist/server/routes/transcribeRoutes.d.ts +0 -8
- package/dist/server/routes/transcribeRoutes.js +130 -3
- package/dist/server/utils/validation.d.ts +409 -15
- package/dist/server/utils/validation.js +106 -4
- package/dist/server/websocket/frameQueue.d.ts +16 -0
- package/dist/server/websocket/frameQueue.js +55 -0
- package/dist/server/websocket/realtimeTranscription.d.ts +48 -0
- package/dist/server/websocket/realtimeTranscription.js +603 -0
- package/dist/server/websocket/transcribeWebSocket.d.ts +17 -1
- package/dist/server/websocket/transcribeWebSocket.js +263 -64
- package/dist/services/server/ai/observability/langfuseSetup.js +6 -1
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/exporter.d.ts +3 -1
- package/dist/types/server.d.ts +304 -2
- package/dist/types/stt.d.ts +38 -3
- package/dist/types/transcribe.d.ts +401 -5
- package/dist/voice/audioLevel.d.ts +14 -0
- package/dist/voice/audioLevel.js +60 -0
- package/dist/voice/codeMix.d.ts +40 -0
- package/dist/voice/codeMix.js +282 -0
- package/dist/voice/correction/align.d.ts +12 -0
- package/dist/voice/correction/align.js +48 -0
- package/dist/voice/correction/guards.d.ts +39 -0
- package/dist/voice/correction/guards.js +122 -0
- package/dist/voice/correction/index.d.ts +25 -3
- package/dist/voice/correction/index.js +132 -4
- package/dist/voice/correction/rewrite.d.ts +64 -3
- package/dist/voice/correction/rewrite.js +295 -25
- package/dist/voice/eval/sttEvalLangfuse.d.ts +14 -0
- package/dist/voice/eval/sttEvalLangfuse.js +182 -0
- package/dist/voice/eval/sttEvalStore.d.ts +27 -0
- package/dist/voice/eval/sttEvalStore.js +397 -0
- package/dist/voice/index.js +3 -0
- package/dist/voice/languages.d.ts +34 -0
- package/dist/voice/languages.js +290 -0
- package/dist/voice/modelAssets.d.ts +28 -0
- package/dist/voice/modelAssets.js +113 -0
- package/dist/voice/output/render.d.ts +32 -0
- package/dist/voice/output/render.js +368 -0
- package/dist/voice/providers/OpenAISTT.d.ts +11 -1
- package/dist/voice/providers/OpenAISTT.js +57 -6
- package/dist/voice/session/transcriptionSession.d.ts +55 -0
- package/dist/voice/session/transcriptionSession.js +225 -0
- package/dist/voice/streaming/chunkedStreamAdapter.d.ts +7 -0
- package/dist/voice/streaming/chunkedStreamAdapter.js +711 -28
- package/dist/voice/streaming/endpointer.d.ts +50 -17
- package/dist/voice/streaming/endpointer.js +115 -19
- package/dist/voice/transcribe.d.ts +18 -1
- package/dist/voice/transcribe.js +459 -18
- package/dist/voice/transcribeStream.d.ts +18 -1
- package/dist/voice/transcribeStream.js +413 -16
- package/dist/voice/vad/assets.d.ts +36 -0
- package/dist/voice/vad/assets.js +142 -0
- package/dist/voice/vad/frameScorer.d.ts +28 -0
- package/dist/voice/vad/frameScorer.js +90 -0
- package/dist/voice/vad/sileroVad.d.ts +43 -0
- package/dist/voice/vad/sileroVad.js +178 -0
- package/dist/voice/whistle/assets.d.ts +3 -4
- package/dist/voice/whistle/assets.js +11 -95
- package/docs-site/static/search-index.json +21 -6
- package/models/silero-vad/README.md +19 -0
- package/models/silero-vad/silero_vad.onnx +0 -0
- package/package.json +3 -1
package/dist/types/server.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { JsonObject, JsonValue } from "./common.js";
|
|
|
9
9
|
import type { ExternalMCPServerStatus } from "./externalMcp.js";
|
|
10
10
|
import type { ProxyRuntimeConfigProvider } from "./proxy.js";
|
|
11
11
|
import type { TTSAudioFormat } from "./tts.js";
|
|
12
|
-
import type { STTCorrectionOptions, STTDictionaryEntry, STTFallbackOptions,
|
|
12
|
+
import type { STTCorrectionOptions, STTDecisionRecord, STTDictionaryEntry, STTEngineInfo, STTFallbackOptions, STTOutputOptions, STTOutputRendering, STTRoutingOptions, STTStreamingOptions, TranscribeTimings } from "./transcribe.js";
|
|
13
13
|
/**
|
|
14
14
|
* Server adapter configuration
|
|
15
15
|
*/
|
|
@@ -124,10 +124,18 @@ export type RequiredRateLimitConfig = {
|
|
|
124
124
|
export type BodyParserConfig = {
|
|
125
125
|
/** Enable body parsing (default: true) */
|
|
126
126
|
enabled?: boolean;
|
|
127
|
-
/** Maximum body size (default: "10mb") */
|
|
127
|
+
/** Maximum body size for parsed bodies (default: "10mb") */
|
|
128
128
|
maxSize?: string;
|
|
129
129
|
/** JSON body limit (default: "10mb") */
|
|
130
130
|
jsonLimit?: string;
|
|
131
|
+
/**
|
|
132
|
+
* Maximum size of a raw upload: `multipart/form-data`, `audio/*` and
|
|
133
|
+
* `application/octet-stream` bodies, which reach a route as bytes
|
|
134
|
+
* (the transcription routes). Default: `maxSize` when set, else "64mb";
|
|
135
|
+
* the transcription routes apply their own `maxAudioBytes` (50 MB)
|
|
136
|
+
* beneath it.
|
|
137
|
+
*/
|
|
138
|
+
rawMaxSize?: string;
|
|
131
139
|
/** Enable URL-encoded body parsing */
|
|
132
140
|
urlEncoded?: boolean;
|
|
133
141
|
};
|
|
@@ -138,6 +146,7 @@ export type RequiredBodyParserConfig = {
|
|
|
138
146
|
enabled: boolean;
|
|
139
147
|
maxSize: string;
|
|
140
148
|
jsonLimit: string;
|
|
149
|
+
rawMaxSize: string;
|
|
141
150
|
urlEncoded: boolean;
|
|
142
151
|
};
|
|
143
152
|
/**
|
|
@@ -1170,6 +1179,37 @@ export type CreateRoutesOptions = {
|
|
|
1170
1179
|
agent?: ServerAgentRouteOptions;
|
|
1171
1180
|
};
|
|
1172
1181
|
/** Options for `createTranscribeRoutes()`. */
|
|
1182
|
+
/**
|
|
1183
|
+
* What `GET /agent/transcribe/providers` reports: the engines this server
|
|
1184
|
+
* can transcribe with, which one a request without a provider gets, and the
|
|
1185
|
+
* models behind the correction layer. Never a key or a URL with a secret.
|
|
1186
|
+
*/
|
|
1187
|
+
export type ServerTranscribeCapabilities = {
|
|
1188
|
+
/** The provider a request without one goes to. */
|
|
1189
|
+
default: string;
|
|
1190
|
+
providers: Array<{
|
|
1191
|
+
name: string;
|
|
1192
|
+
/** `builtin` ships with NeuroLink, `endpoint` comes from `NEUROLINK_STT_ENDPOINTS`, `registered` was added at runtime. */
|
|
1193
|
+
kind: "builtin" | "endpoint" | "registered";
|
|
1194
|
+
model?: string;
|
|
1195
|
+
/** The endpoint can answer a language verdict without transcribing (batch probe). */
|
|
1196
|
+
languageProbe?: boolean;
|
|
1197
|
+
/** The endpoint takes a language prior between utterances. */
|
|
1198
|
+
languagePrior?: boolean;
|
|
1199
|
+
}>;
|
|
1200
|
+
correction: {
|
|
1201
|
+
/** The decision model that judges dictionary candidates; `null` when none is configured (the dictionary is then applied as is). */
|
|
1202
|
+
decision: {
|
|
1203
|
+
provider: string;
|
|
1204
|
+
model: string;
|
|
1205
|
+
} | null;
|
|
1206
|
+
/** The text model of the rewrite; `provider` is `null` when the instance default applies. */
|
|
1207
|
+
rewrite: {
|
|
1208
|
+
provider: string | null;
|
|
1209
|
+
model: string | null;
|
|
1210
|
+
};
|
|
1211
|
+
};
|
|
1212
|
+
};
|
|
1173
1213
|
export type ServerTranscribeRouteOptions = {
|
|
1174
1214
|
/**
|
|
1175
1215
|
* Directories a request's `audioPath` may point into. Empty or omitted (the
|
|
@@ -1185,6 +1225,165 @@ export type ServerTranscribeRouteOptions = {
|
|
|
1185
1225
|
* `http://host:port/v1` works unchanged.
|
|
1186
1226
|
*/
|
|
1187
1227
|
openaiBasePath?: string;
|
|
1228
|
+
/**
|
|
1229
|
+
* The STT evaluation collector, `POST <openaiBasePath>/v1/evals/stt`.
|
|
1230
|
+
* On by default; `false` removes its routes.
|
|
1231
|
+
*/
|
|
1232
|
+
evals?: ServerSTTEvalOptions | false;
|
|
1233
|
+
};
|
|
1234
|
+
/** Where and how much the STT evaluation collector keeps. */
|
|
1235
|
+
export type ServerSTTEvalOptions = {
|
|
1236
|
+
/**
|
|
1237
|
+
* Directory for one JSON-lines file per call, replayed on start. Default
|
|
1238
|
+
* `NEUROLINK_STT_EVAL_DIR`; without either, calls live in memory only.
|
|
1239
|
+
*/
|
|
1240
|
+
dir?: string;
|
|
1241
|
+
/** Calls held in memory; the least recently updated are evicted (still on disk). Default 1000. */
|
|
1242
|
+
maxCalls?: number;
|
|
1243
|
+
/** Segments kept per call; later new ids are counted as `ignored`. Default 50,000. */
|
|
1244
|
+
maxSegmentsPerCall?: number;
|
|
1245
|
+
};
|
|
1246
|
+
/** One finalized transcript segment, from the STT people saw or the one run alongside it. */
|
|
1247
|
+
export type ServerSTTEvalSegment = {
|
|
1248
|
+
/** Stable per segment: a resend with the same id replaces it. */
|
|
1249
|
+
id: string;
|
|
1250
|
+
/** `primary` = shown to users, `shadow` = run for evaluation only. */
|
|
1251
|
+
source: "primary" | "shadow";
|
|
1252
|
+
model: string;
|
|
1253
|
+
participant_identity: string;
|
|
1254
|
+
participant_name?: string;
|
|
1255
|
+
text: string;
|
|
1256
|
+
language?: string | null;
|
|
1257
|
+
/** Epoch seconds, when the STT reports timings. */
|
|
1258
|
+
start_time?: number | null;
|
|
1259
|
+
end_time?: number | null;
|
|
1260
|
+
/** Epoch seconds the sender received the final. */
|
|
1261
|
+
received_at: number;
|
|
1262
|
+
};
|
|
1263
|
+
/** Body of `POST /v1/evals/stt`: one batch of a call's segments. */
|
|
1264
|
+
export type ServerSTTEvalBatchRequest = {
|
|
1265
|
+
call_id: string;
|
|
1266
|
+
room?: string;
|
|
1267
|
+
/** 1, 2, … per call. Numbers may skip when a send failed and was folded into the next. */
|
|
1268
|
+
batch: number;
|
|
1269
|
+
/** True on the batch sent after the last participant left. */
|
|
1270
|
+
final?: boolean;
|
|
1271
|
+
models: {
|
|
1272
|
+
primary: string;
|
|
1273
|
+
shadow: string;
|
|
1274
|
+
};
|
|
1275
|
+
segments: ServerSTTEvalSegment[];
|
|
1276
|
+
};
|
|
1277
|
+
/** Answer to `POST /v1/evals/stt`. */
|
|
1278
|
+
export type ServerSTTEvalBatchResponse = {
|
|
1279
|
+
call_id: string;
|
|
1280
|
+
batch: number;
|
|
1281
|
+
final: boolean;
|
|
1282
|
+
/** New segment ids. */
|
|
1283
|
+
inserted: number;
|
|
1284
|
+
/** Ids already held (a resend), replaced. */
|
|
1285
|
+
updated: number;
|
|
1286
|
+
/** New ids refused because the call is at `maxSegmentsPerCall`. */
|
|
1287
|
+
ignored: number;
|
|
1288
|
+
segments: {
|
|
1289
|
+
primary: number;
|
|
1290
|
+
shadow: number;
|
|
1291
|
+
};
|
|
1292
|
+
};
|
|
1293
|
+
/** One call in `GET /v1/evals/stt`. */
|
|
1294
|
+
export type ServerSTTEvalCallSummary = {
|
|
1295
|
+
call_id: string;
|
|
1296
|
+
room: string | null;
|
|
1297
|
+
models: {
|
|
1298
|
+
primary: string;
|
|
1299
|
+
shadow: string;
|
|
1300
|
+
};
|
|
1301
|
+
final: boolean;
|
|
1302
|
+
batches: number;
|
|
1303
|
+
segments: {
|
|
1304
|
+
primary: number;
|
|
1305
|
+
shadow: number;
|
|
1306
|
+
};
|
|
1307
|
+
speakers: number;
|
|
1308
|
+
first_received_at: number | null;
|
|
1309
|
+
last_received_at: number | null;
|
|
1310
|
+
/** Epoch ms this server last accepted a batch. */
|
|
1311
|
+
updated_at: number;
|
|
1312
|
+
};
|
|
1313
|
+
/** One STT's side of a speaker's comparison. */
|
|
1314
|
+
export type ServerSTTEvalSide = {
|
|
1315
|
+
model: string;
|
|
1316
|
+
segments: number;
|
|
1317
|
+
words: number;
|
|
1318
|
+
/** Languages the STT reported, most frequent first. */
|
|
1319
|
+
languages: string[];
|
|
1320
|
+
/** Mean seconds from the end of speech to the final, when the STT reports timings. */
|
|
1321
|
+
mean_latency_s: number | null;
|
|
1322
|
+
};
|
|
1323
|
+
/**
|
|
1324
|
+
* Agreement between the two STTs for one speaker. Neither side is ground
|
|
1325
|
+
* truth: `disagreement` is the word edit distance between them divided by the
|
|
1326
|
+
* primary's word count, so 0 means both wrote the same words.
|
|
1327
|
+
*/
|
|
1328
|
+
export type ServerSTTEvalComparison = {
|
|
1329
|
+
participant_identity: string;
|
|
1330
|
+
participant_name: string;
|
|
1331
|
+
primary: ServerSTTEvalSide;
|
|
1332
|
+
shadow: ServerSTTEvalSide;
|
|
1333
|
+
/** Word edit distance / primary words, on normalized text. Null when the primary wrote nothing. */
|
|
1334
|
+
disagreement: number | null;
|
|
1335
|
+
/** The same on phonetic word keys, so one STT writing Devanagari and the other Latin is not counted as a difference. */
|
|
1336
|
+
phonetic_disagreement: number | null;
|
|
1337
|
+
/** `full` aligns the whole speaker; `windowed` aligns 5-minute windows of a long speaker. */
|
|
1338
|
+
method: "full" | "windowed";
|
|
1339
|
+
};
|
|
1340
|
+
/**
|
|
1341
|
+
* Where the STT evaluation collector exports to Langfuse. Read only from the
|
|
1342
|
+
* server's environment (`NEUROLINK_STT_EVAL_LANGFUSE_*`): neither a request
|
|
1343
|
+
* nor a route option can redirect evaluation data.
|
|
1344
|
+
*/
|
|
1345
|
+
export type ServerSTTEvalLangfuseConfig = {
|
|
1346
|
+
publicKey: string;
|
|
1347
|
+
secretKey: string;
|
|
1348
|
+
/** Default `https://cloud.langfuse.com`. */
|
|
1349
|
+
baseUrl: string;
|
|
1350
|
+
environment?: string;
|
|
1351
|
+
};
|
|
1352
|
+
/** One event of Langfuse's public ingestion API (`POST /api/public/ingestion`). */
|
|
1353
|
+
export type ServerSTTEvalLangfuseEvent = {
|
|
1354
|
+
id: string;
|
|
1355
|
+
timestamp: string;
|
|
1356
|
+
type: "trace-create" | "event-create" | "score-create";
|
|
1357
|
+
body: Record<string, unknown>;
|
|
1358
|
+
};
|
|
1359
|
+
/** A call as the evaluation store holds it in memory. */
|
|
1360
|
+
export type ServerSTTEvalCallRecord = {
|
|
1361
|
+
callId: string;
|
|
1362
|
+
room: string | null;
|
|
1363
|
+
models: {
|
|
1364
|
+
primary: string;
|
|
1365
|
+
shadow: string;
|
|
1366
|
+
};
|
|
1367
|
+
final: boolean;
|
|
1368
|
+
batches: Set<number>;
|
|
1369
|
+
segments: Map<string, ServerSTTEvalSegment>;
|
|
1370
|
+
updatedAt: number;
|
|
1371
|
+
};
|
|
1372
|
+
/** Word edit distance between two readings, and the reference's word count. */
|
|
1373
|
+
export type ServerSTTEvalAlignment = {
|
|
1374
|
+
distance: number;
|
|
1375
|
+
refWords: number;
|
|
1376
|
+
};
|
|
1377
|
+
/** `GET /v1/evals/stt/:callId`. */
|
|
1378
|
+
export type ServerSTTEvalReport = ServerSTTEvalCallSummary & {
|
|
1379
|
+
/** Over every speaker: summed edit distances / summed primary words. */
|
|
1380
|
+
overall: {
|
|
1381
|
+
disagreement: number | null;
|
|
1382
|
+
phonetic_disagreement: number | null;
|
|
1383
|
+
};
|
|
1384
|
+
speakers_compared: ServerSTTEvalComparison[];
|
|
1385
|
+
/** Present with `?segments=true`, ordered by time. */
|
|
1386
|
+
segment_list?: ServerSTTEvalSegment[];
|
|
1188
1387
|
};
|
|
1189
1388
|
/**
|
|
1190
1389
|
* Body of `POST <basePath>/agent/transcribe`. Exactly one of `audio`,
|
|
@@ -1206,6 +1405,13 @@ export type ServerTranscribeRequest = {
|
|
|
1206
1405
|
dictionary?: STTDictionaryEntry[];
|
|
1207
1406
|
correction?: STTCorrectionOptions;
|
|
1208
1407
|
fallback?: STTFallbackOptions;
|
|
1408
|
+
routing?: STTRoutingOptions;
|
|
1409
|
+
/** `"utterances"` runs the recording through the live pipeline (see `TranscribeOptions.chunking`). */
|
|
1410
|
+
chunking?: "engine" | "utterances";
|
|
1411
|
+
/** Renderings in other languages and scripts (see `TranscribeOptions.output`). */
|
|
1412
|
+
output?: Omit<STTOutputOptions, "languages"> & {
|
|
1413
|
+
languages: string[];
|
|
1414
|
+
};
|
|
1209
1415
|
diarization?: boolean;
|
|
1210
1416
|
wordTimestamps?: boolean;
|
|
1211
1417
|
timeoutMs?: number;
|
|
@@ -1251,6 +1457,8 @@ export type ServerOpenAITranscriptionResponse = {
|
|
|
1251
1457
|
language_detected?: boolean;
|
|
1252
1458
|
steps: string[];
|
|
1253
1459
|
timings: TranscribeTimings;
|
|
1460
|
+
/** NeuroLink extension: one rendering per requested output language. */
|
|
1461
|
+
outputs?: Record<string, STTOutputRendering>;
|
|
1254
1462
|
};
|
|
1255
1463
|
/** Options for `attachTranscribeWebSocket()`. */
|
|
1256
1464
|
export type ServerTranscribeWebSocketOptions = {
|
|
@@ -1273,6 +1481,100 @@ export type ServerTranscribeWebSocketOptions = {
|
|
|
1273
1481
|
allowedOrigins?: readonly string[];
|
|
1274
1482
|
/** Largest single frame, in bytes. Default 1 MiB. */
|
|
1275
1483
|
maxPayload?: number;
|
|
1484
|
+
/**
|
|
1485
|
+
* Listener path of transcription sessions: a socket here reads one
|
|
1486
|
+
* session's speakers in its own languages. Default `<path>/subscribe`;
|
|
1487
|
+
* `false` turns sessions off (a `?session=` on the stream path is then
|
|
1488
|
+
* ignored).
|
|
1489
|
+
*/
|
|
1490
|
+
subscribePath?: string | false;
|
|
1491
|
+
/**
|
|
1492
|
+
* OpenAI Realtime transcription path (`?intent=transcription`): the
|
|
1493
|
+
* protocol of OpenAI's `/v1/realtime`, so any OpenAI-Realtime client — the
|
|
1494
|
+
* LiveKit `openai.STT(use_realtime=True)` plugin, Pipecat, the OpenAI SDK —
|
|
1495
|
+
* streams to NeuroLink with no adapter. Default `/v1/realtime`; `false`
|
|
1496
|
+
* turns it off.
|
|
1497
|
+
*/
|
|
1498
|
+
realtimePath?: string | false;
|
|
1499
|
+
/**
|
|
1500
|
+
* Profiles a realtime client selects with its `model` name. Merged over
|
|
1501
|
+
* `NEUROLINK_STT_REALTIME_PROFILES` (a JSON object of the same shape);
|
|
1502
|
+
* these win on a name in both.
|
|
1503
|
+
*/
|
|
1504
|
+
realtimeProfiles?: Readonly<Record<string, ServerSTTRealtimeProfile>>;
|
|
1505
|
+
};
|
|
1506
|
+
/**
|
|
1507
|
+
* What an OpenAI-Realtime client gets when it names this profile as its
|
|
1508
|
+
* `model`. A realtime client can send only a model, a language, a prompt and
|
|
1509
|
+
* turn-detection numbers, so everything NeuroLink-specific (engine, fallback,
|
|
1510
|
+
* dictionary, correction, output languages) is the operator's, here.
|
|
1511
|
+
*
|
|
1512
|
+
* A `model` that is no profile but a configured STT provider uses that
|
|
1513
|
+
* provider with the defaults; any other name (OpenAI's own
|
|
1514
|
+
* `gpt-4o-mini-transcribe`, say) uses the profile named `default`, or the
|
|
1515
|
+
* server's defaults when there is none.
|
|
1516
|
+
*/
|
|
1517
|
+
export type ServerSTTRealtimeProfile = Omit<ServerTranscribeStreamConfig, "mode"> & {
|
|
1518
|
+
/**
|
|
1519
|
+
* What `…input_audio_transcription.completed` carries: the corrected text
|
|
1520
|
+
* (`"corrected"`, default; it waits up to `correctionWaitMs` for the
|
|
1521
|
+
* correction, then sends the raw final) or the raw final at once.
|
|
1522
|
+
*/
|
|
1523
|
+
completed?: "corrected" | "final";
|
|
1524
|
+
/** Longest wait for the correction before `completed` goes out with the final. Default 3000. */
|
|
1525
|
+
correctionWaitMs?: number;
|
|
1526
|
+
/**
|
|
1527
|
+
* Whether the client's `language` pins the transcription. Default `true`.
|
|
1528
|
+
* Note the LiveKit plugin sends `"en"` unless `detect_language=True`.
|
|
1529
|
+
*/
|
|
1530
|
+
clientLanguage?: boolean;
|
|
1531
|
+
/**
|
|
1532
|
+
* Whether the client's `turn_detection.silence_duration_ms` sets the
|
|
1533
|
+
* utterance's closing pause. Default `false`: NeuroLink's endpointer keeps
|
|
1534
|
+
* its own (750 ms), since a client default such as LiveKit's 350 ms cuts
|
|
1535
|
+
* conversational speech mid-sentence.
|
|
1536
|
+
*/
|
|
1537
|
+
clientTurnDetection?: boolean;
|
|
1538
|
+
};
|
|
1539
|
+
/** The parts of a `ws` socket the realtime handler uses. */
|
|
1540
|
+
export type ServerRealtimeSocket = {
|
|
1541
|
+
readonly readyState: number;
|
|
1542
|
+
send(data: string): void;
|
|
1543
|
+
close(code?: number, reason?: string): void;
|
|
1544
|
+
on(event: "message", listener: (data: Buffer | ArrayBuffer | Buffer[], isBinary: boolean) => void): unknown;
|
|
1545
|
+
on(event: "close" | "error", listener: () => void): unknown;
|
|
1546
|
+
};
|
|
1547
|
+
/** What a realtime client configured, read from either session dialect. */
|
|
1548
|
+
export type ServerRealtimeSessionConfig = {
|
|
1549
|
+
dialect: "ga" | "beta";
|
|
1550
|
+
rate: number;
|
|
1551
|
+
model?: string;
|
|
1552
|
+
language?: string;
|
|
1553
|
+
prompt?: string;
|
|
1554
|
+
silenceMs?: number;
|
|
1555
|
+
};
|
|
1556
|
+
/** One utterance on the realtime wire: a conversation item. */
|
|
1557
|
+
export type ServerRealtimeItem = {
|
|
1558
|
+
utterance: number;
|
|
1559
|
+
itemId: string;
|
|
1560
|
+
/** `speech_started` went out. */
|
|
1561
|
+
started: boolean;
|
|
1562
|
+
/** The committed prefix already sent as deltas. */
|
|
1563
|
+
sent: string;
|
|
1564
|
+
/** Server events held until every earlier item has completed. */
|
|
1565
|
+
pending: Array<{
|
|
1566
|
+
type: string;
|
|
1567
|
+
body: Record<string, unknown>;
|
|
1568
|
+
}>;
|
|
1569
|
+
finalText?: string;
|
|
1570
|
+
engine?: string;
|
|
1571
|
+
language?: string;
|
|
1572
|
+
languageDetected?: boolean;
|
|
1573
|
+
corrected: boolean;
|
|
1574
|
+
/** The transcript `completed` will carry, once known. */
|
|
1575
|
+
ready?: string;
|
|
1576
|
+
done: boolean;
|
|
1577
|
+
timer?: ReturnType<typeof setTimeout>;
|
|
1276
1578
|
};
|
|
1277
1579
|
/** Data stream finish event. */
|
|
1278
1580
|
export type FinishEvent = DataStreamEvent & {
|
package/dist/types/stt.d.ts
CHANGED
|
@@ -45,6 +45,13 @@ export type STTOptions = {
|
|
|
45
45
|
* `vocabulary` terms are appended by the handlers that accept a prompt.
|
|
46
46
|
*/
|
|
47
47
|
prompt?: string;
|
|
48
|
+
/**
|
|
49
|
+
* The language a previous utterance was confidently detected as. Engines
|
|
50
|
+
* that take a prior (the IndicConformer wrapper, through its
|
|
51
|
+
* `priorLanguageForm`) keep it unless the audio clearly says otherwise;
|
|
52
|
+
* every other engine ignores it. Only sent when no `language` is pinned.
|
|
53
|
+
*/
|
|
54
|
+
languagePrior?: string;
|
|
48
55
|
/** Per-request timeout in milliseconds, for handlers that honour one. */
|
|
49
56
|
timeoutMs?: number;
|
|
50
57
|
/** Minimum confidence threshold */
|
|
@@ -97,6 +104,12 @@ export type STTResult = {
|
|
|
97
104
|
provider?: string;
|
|
98
105
|
/** Model used */
|
|
99
106
|
model?: string;
|
|
107
|
+
/** Set by the output guards: what the engine produced was not speech. */
|
|
108
|
+
hallucination?: "prompt-echo";
|
|
109
|
+
/** Share of the words a collapsed decoding loop had taken (0 when none). */
|
|
110
|
+
loopShare?: number;
|
|
111
|
+
/** Set by language routing: the provider whose text this is, when not the pass's own engine. */
|
|
112
|
+
routedProvider?: string;
|
|
100
113
|
/** What `confidence` was derived from, for providers that must choose. */
|
|
101
114
|
confidenceSource?: STTConfidenceSource;
|
|
102
115
|
/** Additional provider-specific metadata */
|
|
@@ -175,6 +188,13 @@ export type STTHandler = {
|
|
|
175
188
|
* what to do rather than "set the required API keys".
|
|
176
189
|
*/
|
|
177
190
|
describeConfiguration?(): string;
|
|
191
|
+
/**
|
|
192
|
+
* The model name that runs this engine in language-identification-only
|
|
193
|
+
* mode (no transcript, just the language verdict and scores, in a fraction
|
|
194
|
+
* of the time), when the server has one. The batch path probes with it
|
|
195
|
+
* before deciding which engine transcribes.
|
|
196
|
+
*/
|
|
197
|
+
languageProbeModel?(): string | undefined;
|
|
178
198
|
maxAudioDuration?: number;
|
|
179
199
|
supportsStreaming?: boolean;
|
|
180
200
|
};
|
|
@@ -460,6 +480,17 @@ export type WhisperTranscriptionSegment = {
|
|
|
460
480
|
* segment with a speaker; the handler surfaces it as `TranscriptionSegment.speaker`.
|
|
461
481
|
*/
|
|
462
482
|
speaker?: string;
|
|
483
|
+
/**
|
|
484
|
+
* Extension, same meaning as the response-level fields: a gateway that
|
|
485
|
+
* normalises the top level of `verbose_json` to OpenAI's schema (LiteLLM
|
|
486
|
+
* does) keeps unknown keys inside segments, so a server may repeat its
|
|
487
|
+
* language-detection verdict here and it survives the hop.
|
|
488
|
+
*/
|
|
489
|
+
language_detected?: boolean;
|
|
490
|
+
language_scores?: Array<{
|
|
491
|
+
language: string;
|
|
492
|
+
score: number;
|
|
493
|
+
}>;
|
|
463
494
|
};
|
|
464
495
|
export type WhisperVerboseResponse = {
|
|
465
496
|
task: string;
|
|
@@ -692,14 +723,18 @@ export type GeminiResponse = {
|
|
|
692
723
|
};
|
|
693
724
|
/** The three files the built-in Whistle engine needs on disk. */
|
|
694
725
|
export type WhistleAssetName = "needle.js" | "needle.wasm" | "whistle.cact";
|
|
695
|
-
/** One pinned
|
|
696
|
-
export type
|
|
697
|
-
name:
|
|
726
|
+
/** One pinned model file NeuroLink ships or fetches on first use: where it comes from and what it must hash to. */
|
|
727
|
+
export type LocalModelAsset = {
|
|
728
|
+
name: string;
|
|
698
729
|
url: string;
|
|
699
730
|
sha256: string;
|
|
700
731
|
/** Exact size in bytes, used for the download notice and a cheap pre-check. */
|
|
701
732
|
bytes: number;
|
|
702
733
|
};
|
|
734
|
+
/** One pinned Whistle asset. */
|
|
735
|
+
export type WhistleAsset = LocalModelAsset & {
|
|
736
|
+
name: WhistleAssetName;
|
|
737
|
+
};
|
|
703
738
|
/** Absolute paths of the three Whistle files once they are present and verified. */
|
|
704
739
|
export type WhistleAssetPaths = Record<WhistleAssetName, string>;
|
|
705
740
|
/** One word as the Whistle engine reports it (seconds from the start of the audio). */
|