@juspay/neurolink 12.48.1 → 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 (107) 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 +5 -3
  4. package/dist/cli/commands/serve.js +113 -20
  5. package/dist/cli/commands/server.js +13 -6
  6. package/dist/cli/commands/transcribe.d.ts +24 -0
  7. package/dist/cli/commands/transcribe.js +718 -0
  8. package/dist/cli/factories/commandFactory.d.ts +10 -0
  9. package/dist/cli/factories/commandFactory.js +13 -0
  10. package/dist/cli/parser.js +3 -0
  11. package/dist/cli/utils/serverUtils.d.ts +28 -0
  12. package/dist/cli/utils/serverUtils.js +71 -0
  13. package/dist/factories/mediaHandlerCatalog.js +11 -9
  14. package/dist/factories/sttDescriptors.d.ts +63 -0
  15. package/dist/factories/sttDescriptors.js +286 -0
  16. package/dist/index.d.ts +4 -1
  17. package/dist/index.js +7 -1
  18. package/dist/neurolink.d.ts +68 -1
  19. package/dist/neurolink.js +202 -4
  20. package/dist/processors/media/AudioProcessor.d.ts +15 -56
  21. package/dist/processors/media/AudioProcessor.js +105 -276
  22. package/dist/processors/media/VideoProcessor.d.ts +3 -5
  23. package/dist/processors/media/VideoProcessor.js +52 -51
  24. package/dist/server/abstract/baseServerAdapter.d.ts +28 -1
  25. package/dist/server/abstract/baseServerAdapter.js +84 -4
  26. package/dist/server/adapters/expressAdapter.d.ts +1 -0
  27. package/dist/server/adapters/expressAdapter.js +50 -10
  28. package/dist/server/adapters/fastifyAdapter.d.ts +1 -0
  29. package/dist/server/adapters/fastifyAdapter.js +51 -8
  30. package/dist/server/adapters/honoAdapter.d.ts +1 -4
  31. package/dist/server/adapters/honoAdapter.js +95 -8
  32. package/dist/server/adapters/koaAdapter.d.ts +7 -0
  33. package/dist/server/adapters/koaAdapter.js +71 -10
  34. package/dist/server/index.d.ts +3 -2
  35. package/dist/server/index.js +3 -2
  36. package/dist/server/routes/index.d.ts +1 -0
  37. package/dist/server/routes/index.js +3 -0
  38. package/dist/server/routes/transcribeRoutes.d.ts +23 -0
  39. package/dist/server/routes/transcribeRoutes.js +506 -0
  40. package/dist/server/utils/rawBody.d.ts +32 -0
  41. package/dist/server/utils/rawBody.js +76 -0
  42. package/dist/server/utils/validation.d.ts +192 -0
  43. package/dist/server/utils/validation.js +100 -0
  44. package/dist/server/websocket/transcribeWebSocket.d.ts +42 -0
  45. package/dist/server/websocket/transcribeWebSocket.js +264 -0
  46. package/dist/types/cli.d.ts +47 -0
  47. package/dist/types/index.d.ts +1 -0
  48. package/dist/types/index.js +1 -0
  49. package/dist/types/providers.d.ts +7 -1
  50. package/dist/types/server.d.ts +117 -1
  51. package/dist/types/stt.d.ts +160 -7
  52. package/dist/types/transcribe.d.ts +506 -0
  53. package/dist/types/transcribe.js +29 -0
  54. package/dist/utils/speakerTurns.d.ts +28 -0
  55. package/dist/utils/speakerTurns.js +93 -0
  56. package/dist/utils/sttProcessor.d.ts +20 -2
  57. package/dist/utils/sttProcessor.js +73 -5
  58. package/dist/voice/correction/dictionary.d.ts +49 -0
  59. package/dist/voice/correction/dictionary.js +134 -0
  60. package/dist/voice/correction/guard.d.ts +35 -0
  61. package/dist/voice/correction/guard.js +161 -0
  62. package/dist/voice/correction/index.d.ts +47 -0
  63. package/dist/voice/correction/index.js +211 -0
  64. package/dist/voice/correction/rewrite.d.ts +92 -0
  65. package/dist/voice/correction/rewrite.js +322 -0
  66. package/dist/voice/errors.d.ts +15 -0
  67. package/dist/voice/errors.js +45 -0
  68. package/dist/voice/index.d.ts +20 -2
  69. package/dist/voice/index.js +75 -9
  70. package/dist/voice/providers/AzureSTT.d.ts +10 -7
  71. package/dist/voice/providers/AzureSTT.js +23 -75
  72. package/dist/voice/providers/DeepgramSTT.d.ts +17 -2
  73. package/dist/voice/providers/DeepgramSTT.js +109 -13
  74. package/dist/voice/providers/ElevenLabsSTT.d.ts +12 -2
  75. package/dist/voice/providers/ElevenLabsSTT.js +34 -8
  76. package/dist/voice/providers/GoogleSTT.d.ts +10 -8
  77. package/dist/voice/providers/GoogleSTT.js +21 -75
  78. package/dist/voice/providers/OpenAISTT.d.ts +30 -9
  79. package/dist/voice/providers/OpenAISTT.js +196 -21
  80. package/dist/voice/providers/WhistleSTT.d.ts +87 -0
  81. package/dist/voice/providers/WhistleSTT.js +313 -0
  82. package/dist/voice/streaming/chunkedStreamAdapter.d.ts +19 -0
  83. package/dist/voice/streaming/chunkedStreamAdapter.js +519 -0
  84. package/dist/voice/streaming/endpointer.d.ts +81 -0
  85. package/dist/voice/streaming/endpointer.js +247 -0
  86. package/dist/voice/streaming/localAgreement.d.ts +30 -0
  87. package/dist/voice/streaming/localAgreement.js +44 -0
  88. package/dist/voice/sttEnvCredentials.d.ts +12 -0
  89. package/dist/voice/sttEnvCredentials.js +12 -0
  90. package/dist/voice/transcribe.d.ts +47 -0
  91. package/dist/voice/transcribe.js +519 -0
  92. package/dist/voice/transcribeStream.d.ts +4 -0
  93. package/dist/voice/transcribeStream.js +584 -0
  94. package/dist/voice/whistle/assets.d.ts +47 -0
  95. package/dist/voice/whistle/assets.js +270 -0
  96. package/dist/voice/whistle/audio.d.ts +32 -0
  97. package/dist/voice/whistle/audio.js +267 -0
  98. package/dist/voice/whistle/engine.d.ts +32 -0
  99. package/dist/voice/whistle/engine.js +193 -0
  100. package/dist/voice/whistle/worker.d.ts +18 -0
  101. package/dist/voice/whistle/worker.js +294 -0
  102. package/docs-site/static/search-index.json +69 -10
  103. package/models/whistle/README.md +18 -0
  104. package/models/whistle/needle.js +2 -0
  105. package/models/whistle/needle.wasm +0 -0
  106. package/models/whistle/whistle.cact +0 -0
  107. package/package.json +7 -3
@@ -15,7 +15,7 @@ import type { DynamicOptions } from "./types/index.js";
15
15
  import { SkillsManager } from "./skills/skillsManager.js";
16
16
  import type { CostAnalysisOptions, CostAnalysisResult, ProviderMetricsOptions, ProviderMetricsResult, TeamAnalyticsOptions, TeamAnalyticsResult } from "./types/index.js";
17
17
  import { TaskManager } from "./tasks/taskManager.js";
18
- import type { SessionExport, SessionListItem } from "./types/index.js";
18
+ import type { TranscribeOptions, TranscribeResult, TranscribeStreamEvent, TranscribeStreamOptions, SessionExport, SessionListItem } from "./types/index.js";
19
19
  /**
20
20
  * Curator P2-4 dedup (concurrency-safe): native providers emit
21
21
  * `generation:end` on the shared SDK emitter. We attach a fresh
@@ -2689,6 +2689,73 @@ export declare class NeuroLink {
2689
2689
  * `decisionHooks` and emits `decision:before` / `decision:after`.
2690
2690
  */
2691
2691
  tryDecide(options: DecisionCallerOptions): Promise<DecisionResult | null>;
2692
+ /**
2693
+ * Transcribe a recording to text through any STT provider, with the
2694
+ * optional layers that make self-hosted engines usable: a dictionary of
2695
+ * names and jargon (sent to the engine as context, then repaired after the
2696
+ * fact behind a `tryDecide` guard), an LLM rewrite, a second-opinion
2697
+ * engine, and a fallback engine for audio the primary cannot read.
2698
+ *
2699
+ * The provider defaults to `NEUROLINK_STT_PROVIDER`, then the first
2700
+ * configured STT provider, then the built-in local engine, so an instance
2701
+ * with no STT configuration still transcribes. Per-call
2702
+ * `credentials.stt` beats the instance's, which beats the environment.
2703
+ *
2704
+ * @example
2705
+ * ```typescript
2706
+ * const result = await neurolink.transcribe({
2707
+ * audio: "./meeting.wav",
2708
+ * dictionary: [{ term: "NeuroLink", heardAs: ["neural link"] }],
2709
+ * });
2710
+ * console.log(result.text, result.engine.provider, result.steps);
2711
+ * ```
2712
+ *
2713
+ * @throws STTError when the audio cannot be read, the provider is unknown,
2714
+ * or the engine fails with no fallback that covers errors
2715
+ */
2716
+ transcribe(options: TranscribeOptions): Promise<TranscribeResult>;
2717
+ /**
2718
+ * Transcribe a live stream of PCM16LE frames. Engines with a native stream
2719
+ * use it; every other engine is streamed through the chunked adapter
2720
+ * (energy-gated utterances, rolling re-transcription, LocalAgreement
2721
+ * commits). Emits `interim`, `final`, `corrected` and the other
2722
+ * {@link TranscribeStreamEvent}s; the same correction, fallback and
2723
+ * provider rules as {@link NeuroLink.transcribe} apply per utterance.
2724
+ *
2725
+ * @example
2726
+ * ```typescript
2727
+ * for await (const event of neurolink.transcribeStream({ audio: micFrames })) {
2728
+ * if (event.type === "final") console.log(event.text);
2729
+ * }
2730
+ * ```
2731
+ */
2732
+ transcribeStream(options: TranscribeStreamOptions): AsyncIterable<TranscribeStreamEvent>;
2733
+ /**
2734
+ * Instance `credentials.stt` with a per-call `stt` slice merged on top,
2735
+ * provider by provider and field by field (a per-call `apiKey` keeps the
2736
+ * instance's `baseURL`). Undefined when neither has one.
2737
+ */
2738
+ private resolveSTTCredentials;
2739
+ /**
2740
+ * The STT provider for a call: an explicit name (or alias) as its
2741
+ * canonical name, a name only a caller-registered handler knows as is, and
2742
+ * no name as the default provider for these credentials.
2743
+ */
2744
+ private resolveSTTProvider;
2745
+ /**
2746
+ * Everything the transcribe orchestration needs from this instance: STT
2747
+ * handlers with the request's credentials applied, provider resolution,
2748
+ * the fail-open decision model and a rewrite model.
2749
+ */
2750
+ private buildTranscribeDeps;
2751
+ /**
2752
+ * The correction layer's two model calls: `decide` is {@link tryDecide}
2753
+ * (fail-open — `null` on any failure), `rewrite` a plain text call with
2754
+ * tools and memory off (`onPartial`, when given, receives the finished
2755
+ * text once — see the note inside on why it is not streamed) and aborted
2756
+ * at its timeout.
2757
+ */
2758
+ private buildSTTCorrectionDeps;
2692
2759
  /**
2693
2760
  * `tryDecide` without the site handling: the try/catch around the call.
2694
2761
  * Dispatches through `this.decide`, so a subclass override or an instance
package/dist/neurolink.js CHANGED
@@ -31,6 +31,7 @@ import { ToolRoutingCache } from "./core/toolRoutingCache.js";
31
31
  import { DEFAULT_RECENT_TURNS, KnowledgeGroundingEngine, } from "./knowledge/index.js";
32
32
  import { AIProviderFactory } from "./core/factory.js";
33
33
  import { describeDecisionProviderKeys, PROVIDER_ALIAS_INDEX, PROVIDER_DESCRIPTORS_BY_NAME, resolveDefaultDecisionProvider, } from "./factories/providerDescriptors.js";
34
+ import { describeSTTProviderKeys, getSTTProviderDescriptor, listConfiguredSTTProviders, resolveCallSTTEndpoints, resolveDefaultSTTProvider, resolveSTTProviderName, } from "./factories/sttDescriptors.js";
34
35
  import { MAX_PARALLEL_DECISION_BATCHES, mergeDecisionResults, splitDecisionRequest, } from "./utils/decisionBatches.js";
35
36
  import { decisionKey, HOST_DECISION_NAMESPACE, isHostDecisionKey, snapshotDecisionQuestion, stripHostAnswers, } from "./utils/decisionAnswers.js";
36
37
  import { resolveDecisionLimitsReading } from "./utils/decisionLimits.js";
@@ -4238,8 +4239,9 @@ Current user's request: ${currentInput}`;
4238
4239
  // registration failed silently after AI providers were registered.
4239
4240
  await ProviderRegistry.registerAllProviders();
4240
4241
  const { STTProcessor } = await import("./utils/sttProcessor.js");
4241
- const sttProvider = options.stt.provider ?? "whisper";
4242
- sttTranscription = await STTProcessor.transcribe(options.stt.audio, sttProvider, options.stt);
4242
+ const sttCredentials = this.resolveSTTCredentials(options.credentials?.stt);
4243
+ const sttProvider = this.resolveSTTProvider(options.stt.provider, sttCredentials);
4244
+ sttTranscription = await STTProcessor.transcribe(options.stt.audio, sttProvider, options.stt, sttCredentials);
4243
4245
  // Inject transcription into the LLM prompt
4244
4246
  if (sttTranscription.text) {
4245
4247
  const existingText = textOptions.prompt || textOptions.input?.text || "";
@@ -7606,8 +7608,9 @@ Current user's request: ${currentInput}`;
7606
7608
  // registerAllProviders() is idempotent; always call.
7607
7609
  await ProviderRegistry.registerAllProviders();
7608
7610
  const { STTProcessor } = await import("./utils/sttProcessor.js");
7609
- const sttProvider = sttOptions.provider ?? "whisper";
7610
- streamSttTranscription = await STTProcessor.transcribe(sttAudio, sttProvider, sttOptions);
7611
+ const sttCredentials = this.resolveSTTCredentials(options.credentials?.stt);
7612
+ const sttProvider = this.resolveSTTProvider(sttOptions.provider, sttCredentials);
7613
+ streamSttTranscription = await STTProcessor.transcribe(sttAudio, sttProvider, sttOptions, sttCredentials);
7611
7614
  if (streamSttTranscription.text) {
7612
7615
  const existingText = options.input.text || "";
7613
7616
  options.input.text = existingText
@@ -13979,6 +13982,201 @@ Current user's request: ${currentInput}`;
13979
13982
  async tryDecide(options) {
13980
13983
  return this.siteDecide(options);
13981
13984
  }
13985
+ // ==========================================================================
13986
+ // TRANSCRIBE — the speech-to-text inference type
13987
+ // ==========================================================================
13988
+ /**
13989
+ * Transcribe a recording to text through any STT provider, with the
13990
+ * optional layers that make self-hosted engines usable: a dictionary of
13991
+ * names and jargon (sent to the engine as context, then repaired after the
13992
+ * fact behind a `tryDecide` guard), an LLM rewrite, a second-opinion
13993
+ * engine, and a fallback engine for audio the primary cannot read.
13994
+ *
13995
+ * The provider defaults to `NEUROLINK_STT_PROVIDER`, then the first
13996
+ * configured STT provider, then the built-in local engine, so an instance
13997
+ * with no STT configuration still transcribes. Per-call
13998
+ * `credentials.stt` beats the instance's, which beats the environment.
13999
+ *
14000
+ * @example
14001
+ * ```typescript
14002
+ * const result = await neurolink.transcribe({
14003
+ * audio: "./meeting.wav",
14004
+ * dictionary: [{ term: "NeuroLink", heardAs: ["neural link"] }],
14005
+ * });
14006
+ * console.log(result.text, result.engine.provider, result.steps);
14007
+ * ```
14008
+ *
14009
+ * @throws STTError when the audio cannot be read, the provider is unknown,
14010
+ * or the engine fails with no fallback that covers errors
14011
+ */
14012
+ async transcribe(options) {
14013
+ const [deps, { runTranscribe }] = await Promise.all([
14014
+ this.buildTranscribeDeps(options.credentials?.stt),
14015
+ import("./voice/transcribe.js"),
14016
+ ]);
14017
+ return runTranscribe(options, deps);
14018
+ }
14019
+ /**
14020
+ * Transcribe a live stream of PCM16LE frames. Engines with a native stream
14021
+ * use it; every other engine is streamed through the chunked adapter
14022
+ * (energy-gated utterances, rolling re-transcription, LocalAgreement
14023
+ * commits). Emits `interim`, `final`, `corrected` and the other
14024
+ * {@link TranscribeStreamEvent}s; the same correction, fallback and
14025
+ * provider rules as {@link NeuroLink.transcribe} apply per utterance.
14026
+ *
14027
+ * @example
14028
+ * ```typescript
14029
+ * for await (const event of neurolink.transcribeStream({ audio: micFrames })) {
14030
+ * if (event.type === "final") console.log(event.text);
14031
+ * }
14032
+ * ```
14033
+ */
14034
+ async *transcribeStream(options) {
14035
+ const [deps, { runTranscribeStream }] = await Promise.all([
14036
+ this.buildTranscribeDeps(options.credentials?.stt),
14037
+ import("./voice/transcribeStream.js"),
14038
+ ]);
14039
+ yield* runTranscribeStream(options, deps);
14040
+ }
14041
+ /**
14042
+ * Instance `credentials.stt` with a per-call `stt` slice merged on top,
14043
+ * provider by provider and field by field (a per-call `apiKey` keeps the
14044
+ * instance's `baseURL`). Undefined when neither has one.
14045
+ */
14046
+ resolveSTTCredentials(callCredentials) {
14047
+ const instance = this.credentials?.stt;
14048
+ if (!instance || !callCredentials) {
14049
+ return callCredentials ?? instance;
14050
+ }
14051
+ const merged = { ...instance };
14052
+ for (const [key, callSlice] of Object.entries(callCredentials)) {
14053
+ const instanceSlice = merged[key];
14054
+ merged[key] =
14055
+ instanceSlice &&
14056
+ typeof instanceSlice === "object" &&
14057
+ callSlice &&
14058
+ typeof callSlice === "object"
14059
+ ? { ...instanceSlice, ...callSlice }
14060
+ : (callSlice ?? instanceSlice);
14061
+ }
14062
+ return merged;
14063
+ }
14064
+ /**
14065
+ * The STT provider for a call: an explicit name (or alias) as its
14066
+ * canonical name, a name only a caller-registered handler knows as is, and
14067
+ * no name as the default provider for these credentials.
14068
+ */
14069
+ resolveSTTProvider(name, credentials) {
14070
+ const trimmed = name?.trim();
14071
+ if (!trimmed) {
14072
+ return resolveDefaultSTTProvider(credentials);
14073
+ }
14074
+ return resolveSTTProviderName(trimmed) ?? trimmed;
14075
+ }
14076
+ /**
14077
+ * Everything the transcribe orchestration needs from this instance: STT
14078
+ * handlers with the request's credentials applied, provider resolution,
14079
+ * the fail-open decision model and a rewrite model.
14080
+ */
14081
+ async buildTranscribeDeps(callCredentials) {
14082
+ await ProviderRegistry.registerAllProviders();
14083
+ const [{ STTProcessor }, { createSTTHandler }, { STTError }] = await Promise.all([
14084
+ import("./utils/sttProcessor.js"),
14085
+ import("./voice/index.js"),
14086
+ import("./voice/errors.js"),
14087
+ ]);
14088
+ const credentials = this.resolveSTTCredentials(callCredentials);
14089
+ const resolveProvider = (name) => {
14090
+ const resolved = this.resolveSTTProvider(name, credentials);
14091
+ if (resolveSTTProviderName(resolved) === undefined &&
14092
+ !STTProcessor.supports(resolved) &&
14093
+ !resolveCallSTTEndpoints(credentials)[resolved.trim().toLowerCase()]) {
14094
+ throw STTError.unknownProvider(resolved, listConfiguredSTTProviders(credentials), describeSTTProviderKeys());
14095
+ }
14096
+ return resolved;
14097
+ };
14098
+ // Same precedence as STTProcessor.resolveHandler, synchronously: a
14099
+ // credentials slice for the provider builds a handler from it; else the
14100
+ // registered handler; else, for a shipped provider, one from the env.
14101
+ const getHandler = (name) => {
14102
+ if (resolveCallSTTEndpoints(credentials)[name.trim().toLowerCase()]) {
14103
+ return createSTTHandler(name, credentials);
14104
+ }
14105
+ const descriptor = getSTTProviderDescriptor(name);
14106
+ if (!descriptor) {
14107
+ return STTProcessor.getHandler(name);
14108
+ }
14109
+ if (credentials?.[descriptor.credentialsKey] !== undefined) {
14110
+ return createSTTHandler(descriptor.name, credentials);
14111
+ }
14112
+ return (STTProcessor.getHandler(descriptor.name) ??
14113
+ createSTTHandler(descriptor.name));
14114
+ };
14115
+ return {
14116
+ ...this.buildSTTCorrectionDeps(),
14117
+ transcribe: (audio, provider, options) => STTProcessor.transcribe(audio, provider, options, credentials),
14118
+ resolveProvider,
14119
+ getHandler,
14120
+ };
14121
+ }
14122
+ /**
14123
+ * The correction layer's two model calls: `decide` is {@link tryDecide}
14124
+ * (fail-open — `null` on any failure), `rewrite` a plain text call with
14125
+ * tools and memory off (`onPartial`, when given, receives the finished
14126
+ * text once — see the note inside on why it is not streamed) and aborted
14127
+ * at its timeout.
14128
+ */
14129
+ buildSTTCorrectionDeps() {
14130
+ return {
14131
+ decide: async (o) => {
14132
+ // The correction layer builds plain JSON states and question maps;
14133
+ // the decision provider validates them on its side.
14134
+ const result = await this.tryDecide({
14135
+ state: o.state,
14136
+ questions: o.questions,
14137
+ ...(o.timeoutMs !== undefined ? { timeoutMs: o.timeoutMs } : {}),
14138
+ });
14139
+ return result ? { answers: result.answers } : null;
14140
+ },
14141
+ rewrite: async (o) => {
14142
+ const controller = new AbortController();
14143
+ const timer = setTimeout(() => controller.abort(), o.timeoutMs);
14144
+ // A server runs many transcriptions with one rewrite model, so the
14145
+ // model is configurable once, in the environment; a request's own
14146
+ // `correction.rewrite.provider/model` still wins.
14147
+ const provider = o.provider ?? process.env.NEUROLINK_STT_REWRITE_PROVIDER?.trim();
14148
+ const model = o.model ?? process.env.NEUROLINK_STT_REWRITE_MODEL?.trim();
14149
+ const request = {
14150
+ input: { text: o.user },
14151
+ systemPrompt: o.system,
14152
+ ...(provider ? { provider } : {}),
14153
+ ...(model ? { model } : {}),
14154
+ maxTokens: o.maxTokens,
14155
+ temperature: 0,
14156
+ disableTools: true,
14157
+ memory: { enabled: false },
14158
+ abortSignal: controller.signal,
14159
+ };
14160
+ try {
14161
+ // Always `generate()`. Measured on the same rewrite against the same
14162
+ // model: generate 0.7 s; stream() 3.4 s with the first chunk at
14163
+ // 3.3 s — the stream path's setup costs more than the whole answer
14164
+ // and delivers it in one burst anyway, so a "streamed" rewrite only
14165
+ // risked the 12 s timeout. `onPartial` still fires once with the
14166
+ // full text so a live caller replaces the sentence the same way.
14167
+ const generated = await this.generate(request);
14168
+ const text = generated.content ?? "";
14169
+ if (o.onPartial && text) {
14170
+ o.onPartial(text);
14171
+ }
14172
+ return text;
14173
+ }
14174
+ finally {
14175
+ clearTimeout(timer);
14176
+ }
14177
+ },
14178
+ };
14179
+ }
13982
14180
  /**
13983
14181
  * `tryDecide` without the site handling: the try/catch around the call.
13984
14182
  * Dispatches through `this.decide`, so a subclass override or an instance
@@ -90,28 +90,22 @@ export declare class AudioProcessor extends BaseFileProcessor<ProcessedAudio> {
90
90
  */
91
91
  processFile(fileInfo: FileInfo, options?: ProcessOptions & AudioProcessorOptions): Promise<ProcessorFileProcessingResult<ProcessedAudio>>;
92
92
  /**
93
- * Whether a transcription backend has the credentials it needs (#413).
93
+ * Choose the transcription backend for this file (#413).
94
+ *
95
+ * With no `requested` backend, the STT default applies: the provider named
96
+ * by `NEUROLINK_STT_PROVIDER`, else the first configured STT provider in
97
+ * descriptor order, else the built-in local engine when it can run here.
98
+ * With one, it is resolved through the legacy names and the STT aliases and
99
+ * validated for availability — a backend the caller explicitly asked for is
100
+ * never silently swapped for a different one, because a caller who pinned
101
+ * Azure for a data-residency reason would not want OpenAI chosen behind
102
+ * their back. The mismatch is reported instead.
94
103
  *
95
104
  * Availability is decided from the environment only — no network call — so
96
105
  * selection stays cheap and cannot itself fail. A key that is present but
97
106
  * rejected upstream surfaces later, as a transcription failure with the
98
107
  * provider's own message, not as "unavailable".
99
108
  *
100
- * @param provider - Backend to check
101
- * @returns True when at least one of the backend's credential vars is set
102
- */
103
- private isProviderAvailable;
104
- /**
105
- * Choose the transcription backend for this file (#413).
106
- *
107
- * With no `requested` backend, the first configured entry of
108
- * {@link TRANSCRIPTION_PROVIDER_ORDER} wins (OpenAI, then Google, then
109
- * Azure). With one, it is normalised through the alias table and validated
110
- * for availability — a backend the caller explicitly asked for is never
111
- * silently swapped for a different one, because a caller who pinned Azure
112
- * for a data-residency reason would not want OpenAI chosen behind their
113
- * back. The mismatch is reported instead.
114
- *
115
109
  * @param requested - Caller's `AudioProcessorOptions.provider`, if any
116
110
  * @returns The chosen backend, or the reason no backend could be chosen
117
111
  */
@@ -120,10 +114,14 @@ export declare class AudioProcessor extends BaseFileProcessor<ProcessedAudio> {
120
114
  * Attempt to transcribe audio with whichever backend is configured (#413).
121
115
  *
122
116
  * Transcription is attempted when:
123
- * 1. A backend's credentials are present (see {@link selectProvider})
117
+ * 1. A backend is available (see {@link selectProvider})
124
118
  * 2. File size is within the 25MB ceiling
125
119
  * 3. The file format is one the backend accepts
126
120
  *
121
+ * The call itself goes through `STTProcessor`, the same path as
122
+ * `transcribe()` and `generate({ stt })`, so `OPENAI_STT_*`, the default
123
+ * provider rule and every STT handler apply here too.
124
+ *
127
125
  * Gracefully degrades: if transcription fails for any reason, metadata-only
128
126
  * output is returned (transcription is additive, never blocks processing).
129
127
  *
@@ -134,45 +132,6 @@ export declare class AudioProcessor extends BaseFileProcessor<ProcessedAudio> {
134
132
  * @returns Transcription result with transcript text, or the reason there is none
135
133
  */
136
134
  private attemptTranscription;
137
- /**
138
- * Transcribe via OpenAI Whisper (#416).
139
- *
140
- * A native multipart POST to OpenAI's transcription endpoint. This used to
141
- * go through @ai-sdk/openai's createOpenAI().transcription() plus the ai
142
- * package's experimental_transcribe; both were dropped, and this is the
143
- * only wire behaviour of theirs the processor ever depended on. The same
144
- * request is already made natively by voice/providers/OpenAISTT.ts.
145
- *
146
- * `verbose_json` is requested for `language` and `duration` alongside the
147
- * text — the response was previously parsed for `text` alone, so both were
148
- * received and discarded, and `FileProcessingResult.metadata.language` had
149
- * nothing to report (#409).
150
- *
151
- * @param buffer - Audio file content
152
- * @param filename - Original filename, sent as the multipart part name
153
- * @param mimetype - MIME type used for the upload blob
154
- * @param options - Caller's language / model / prompt overrides
155
- * @param skipped - Builds the "no transcript, and here is why" outcome
156
- * @returns Transcription result, or the reason there is none
157
- */
158
- private transcribeWithOpenAI;
159
- /**
160
- * Transcribe via one of the non-OpenAI STT handlers (#413).
161
- *
162
- * Google and Azure already have working, tested implementations under
163
- * `src/lib/voice/providers/`, reached here through a dynamic import so a
164
- * file-processing run that never transcribes does not pay to load them —
165
- * the same reason `music-metadata` is loaded lazily above.
166
- *
167
- * @param chosen - Backend and display label from {@link selectProvider}
168
- * @param buffer - Audio file content
169
- * @param filename - Original filename; its extension picks the wire format
170
- * @param mimetype - MIME type, used as the fallback format signal
171
- * @param options - Caller's language / model overrides
172
- * @param skipped - Builds the "no transcript, and here is why" outcome
173
- * @returns Transcription result, or the reason there is none
174
- */
175
- private transcribeWithHandler;
176
135
  /**
177
136
  * Stub implementation required by BaseFileProcessor.
178
137
  * Not used because processFile is fully overridden.