@juspay/neurolink 11.27.0 → 11.28.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.
@@ -300,6 +300,7 @@ export declare class CLICommandFactory {
300
300
  };
301
301
  videoProvider: {
302
302
  type: "string";
303
+ choices: string[];
303
304
  description: string;
304
305
  };
305
306
  videoOutput: {
@@ -328,6 +329,7 @@ export declare class CLICommandFactory {
328
329
  };
329
330
  avatarProvider: {
330
331
  type: "string";
332
+ choices: string[];
331
333
  description: string;
332
334
  };
333
335
  avatarImage: {
@@ -362,6 +364,7 @@ export declare class CLICommandFactory {
362
364
  };
363
365
  musicProvider: {
364
366
  type: "string";
367
+ choices: string[];
365
368
  description: string;
366
369
  };
367
370
  musicDuration: {
@@ -1190,6 +1193,7 @@ export declare const commonOptions: {
1190
1193
  };
1191
1194
  videoProvider: {
1192
1195
  type: "string";
1196
+ choices: string[];
1193
1197
  description: string;
1194
1198
  };
1195
1199
  videoOutput: {
@@ -1218,6 +1222,7 @@ export declare const commonOptions: {
1218
1222
  };
1219
1223
  avatarProvider: {
1220
1224
  type: "string";
1225
+ choices: string[];
1221
1226
  description: string;
1222
1227
  };
1223
1228
  avatarImage: {
@@ -1252,6 +1257,7 @@ export declare const commonOptions: {
1252
1257
  };
1253
1258
  musicProvider: {
1254
1259
  type: "string";
1260
+ choices: string[];
1255
1261
  description: string;
1256
1262
  };
1257
1263
  musicDuration: {
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import chalk from "chalk";
4
4
  import ora from "ora";
5
5
  import { ModelResolver } from "../../models/modelResolver.js";
6
+ import { providerChoicesFor } from "../../factories/mediaHandlerCatalog.js";
6
7
  import { globalSession } from "../../session/globalSessionState.js";
7
8
  // Use TokenUsage from standard types - no local interface needed
8
9
  import { ContextFactory, } from "../../types/index.js";
@@ -333,7 +334,7 @@ export class CLICommandFactory {
333
334
  },
334
335
  ttsProvider: {
335
336
  type: "string",
336
- choices: ["google-ai", "vertex", "openai-tts", "elevenlabs", "azure-tts"],
337
+ choices: providerChoicesFor("tts"),
337
338
  description: "TTS provider (overrides --provider for speech synthesis)",
338
339
  },
339
340
  ttsFormat: {
@@ -381,7 +382,7 @@ export class CLICommandFactory {
381
382
  },
382
383
  sttProvider: {
383
384
  type: "string",
384
- choices: ["whisper", "deepgram", "google-stt", "azure-stt"],
385
+ choices: providerChoicesFor("stt"),
385
386
  description: "STT provider to use",
386
387
  },
387
388
  sttLanguage: {
@@ -401,6 +402,7 @@ export class CLICommandFactory {
401
402
  },
402
403
  videoProvider: {
403
404
  type: "string",
405
+ choices: providerChoicesFor("video"),
404
406
  description: "Video provider override (e.g., 'vertex' (default), 'kling', 'runway', 'replicate')",
405
407
  },
406
408
  videoOutput: {
@@ -430,6 +432,7 @@ export class CLICommandFactory {
430
432
  // Avatar Generation options (D-ID, HeyGen, MuseTalk via Replicate)
431
433
  avatarProvider: {
432
434
  type: "string",
435
+ choices: providerChoicesFor("avatar"),
433
436
  description: "Avatar provider (e.g., 'd-id' (default), 'heygen', 'replicate', 'musetalk')",
434
437
  },
435
438
  avatarImage: {
@@ -465,6 +468,7 @@ export class CLICommandFactory {
465
468
  // Music Generation options (Beatoven, ElevenLabs, Lyria, MusicGen via Replicate)
466
469
  musicProvider: {
467
470
  type: "string",
471
+ choices: providerChoicesFor("music"),
468
472
  description: "Music provider (e.g., 'beatoven' (default), 'elevenlabs-music', 'lyria', 'replicate', 'musicgen')",
469
473
  },
470
474
  musicDuration: {
@@ -1,5 +1,6 @@
1
1
  import { context, SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
2
2
  import { directAgentTools } from "../agent/directTools.js";
3
+ import { defaultProviderFor } from "../factories/mediaHandlerCatalog.js";
3
4
  import { isImageGenerationModel } from "./constants.js";
4
5
  import { MiddlewareFactory } from "../middleware/factory.js";
5
6
  import { modelSupports } from "../models/modelRegistry.js";
@@ -2139,9 +2140,10 @@ export class BaseProvider {
2139
2140
  }
2140
2141
  // Get prompt text
2141
2142
  const prompt = options.prompt || options.input?.text || "";
2142
- // Honor output.video.provider — when omitted, fall back to "vertex"
2143
- // for backward compatibility with the original implementation.
2144
- const requestedProvider = options.output?.video?.provider ?? "vertex";
2143
+ // Honor output.video.provider — when omitted, fall back to the
2144
+ // catalog-derived default (currently "vertex") for backward
2145
+ // compatibility with the original implementation.
2146
+ const requestedProvider = options.output?.video?.provider ?? defaultProviderFor("video");
2145
2147
  if (!VideoProcessor.supports(requestedProvider)) {
2146
2148
  throw new VideoError({
2147
2149
  code: VIDEO_ERROR_CODES.PROVIDER_NOT_SUPPORTED,
@@ -0,0 +1,18 @@
1
+ import type { MediaHandlerDescriptor, MediaHandlerKind } from "../types/index.js";
2
+ /**
3
+ * Static catalog of every shipped media-handler provider, across all six
4
+ * ecosystems (TTS, STT, Realtime, Video, Avatar, Music). Pure data — no
5
+ * factory functions, no class imports — mirroring the
6
+ * src/lib/factories/providerDescriptors.ts pattern for text/image
7
+ * providers.
8
+ *
9
+ * Entries mirror providerRegistry.ts's hand-constructed TTS/STT/Realtime/
10
+ * Video/Avatar/Music registration blocks (registerAllProviders()) exactly —
11
+ * this file states today's truth, not an aspirational shape. Keep it in
12
+ * sync if those blocks change.
13
+ */
14
+ export declare const MEDIA_HANDLER_CATALOG: readonly MediaHandlerDescriptor[];
15
+ /** Every selectable provider name for `kind`, primaries and aliases both. */
16
+ export declare function providerChoicesFor(kind: MediaHandlerKind): string[];
17
+ /** The first-listed primary provider name for `kind` — used as a fallback default. */
18
+ export declare function defaultProviderFor(kind: MediaHandlerKind): string;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Static catalog of every shipped media-handler provider, across all six
3
+ * ecosystems (TTS, STT, Realtime, Video, Avatar, Music). Pure data — no
4
+ * factory functions, no class imports — mirroring the
5
+ * src/lib/factories/providerDescriptors.ts pattern for text/image
6
+ * providers.
7
+ *
8
+ * Entries mirror providerRegistry.ts's hand-constructed TTS/STT/Realtime/
9
+ * Video/Avatar/Music registration blocks (registerAllProviders()) exactly —
10
+ * this file states today's truth, not an aspirational shape. Keep it in
11
+ * sync if those blocks change.
12
+ */
13
+ export const MEDIA_HANDLER_CATALOG = [
14
+ // --- TTS ---
15
+ { kind: "tts", name: "google-ai", aliases: ["vertex"] },
16
+ { kind: "tts", name: "openai-tts" },
17
+ { kind: "tts", name: "elevenlabs", aliases: ["elevenlabs-tts"] },
18
+ { kind: "tts", name: "azure-tts" },
19
+ { kind: "tts", name: "fish-audio" },
20
+ { kind: "tts", name: "cartesia" },
21
+ // --- STT ---
22
+ { kind: "stt", name: "whisper", aliases: ["openai-stt"] },
23
+ { kind: "stt", name: "deepgram" },
24
+ { kind: "stt", name: "google-stt" },
25
+ { kind: "stt", name: "azure-stt" },
26
+ // --- Realtime ---
27
+ { kind: "realtime", name: "openai-realtime" },
28
+ { kind: "realtime", name: "gemini-live" },
29
+ // --- Video ---
30
+ { kind: "video", name: "vertex" },
31
+ { kind: "video", name: "kling" },
32
+ { kind: "video", name: "runway" },
33
+ { kind: "video", name: "replicate" },
34
+ // --- Avatar ---
35
+ { kind: "avatar", name: "d-id" },
36
+ { kind: "avatar", name: "replicate", aliases: ["musetalk"] },
37
+ { kind: "avatar", name: "heygen" },
38
+ // --- Music ---
39
+ { kind: "music", name: "beatoven" },
40
+ { kind: "music", name: "replicate", aliases: ["musicgen"] },
41
+ { kind: "music", name: "elevenlabs-music", aliases: ["elevenlabs-sound"] },
42
+ { kind: "music", name: "lyria" },
43
+ ];
44
+ /** Every selectable provider name for `kind`, primaries and aliases both. */
45
+ export function providerChoicesFor(kind) {
46
+ const choices = [];
47
+ for (const entry of MEDIA_HANDLER_CATALOG) {
48
+ if (entry.kind !== kind) {
49
+ continue;
50
+ }
51
+ choices.push(entry.name);
52
+ if (entry.aliases) {
53
+ choices.push(...entry.aliases);
54
+ }
55
+ }
56
+ return choices;
57
+ }
58
+ /** The first-listed primary provider name for `kind` — used as a fallback default. */
59
+ export function defaultProviderFor(kind) {
60
+ const first = MEDIA_HANDLER_CATALOG.find((entry) => entry.kind === kind);
61
+ if (!first) {
62
+ throw new Error(`No media handler catalog entries registered for kind "${kind}"`);
63
+ }
64
+ return first.name;
65
+ }
@@ -3,6 +3,7 @@ import { logger } from "../utils/logger.js";
3
3
  import { AIProviderName, GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, HuggingFaceModels, DeepSeekModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, ReplicateModels, } from "../constants/enums.js";
4
4
  import { PROVIDER_DESCRIPTORS_BY_NAME } from "./providerDescriptors.js";
5
5
  import { OPENAI_COMPAT_CATALOG } from "../providers/openaiCompatCatalog.js";
6
+ import { providerChoicesFor } from "./mediaHandlerCatalog.js";
6
7
  /**
7
8
  * Provider Registry - registers all providers with the factory
8
9
  * This is where we migrate providers one by one to the new pattern
@@ -229,16 +230,23 @@ export class ProviderRegistry {
229
230
  return new RecraftProvider(modelName, sdk, undefined, recraftCreds);
230
231
  }, process.env.RECRAFT_MODEL || RecraftModels.RECRAFT_V3, ["recraft"], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.RECRAFT));
231
232
  logger.debug("All AI providers registered successfully");
233
+ // ===== MEDIA HANDLER REGISTRATION =====
234
+ // Single registration path (Task 11): each ecosystem barrel (voice,
235
+ // adapters/video, avatar, music) owns its own provider-name catalog
236
+ // wiring (MEDIA_HANDLER_CATALOG, Task 8) and exposes an idempotent
237
+ // registerDefault*Handlers() function (Task 10) that constructs and
238
+ // registers every shipped handler whose backing credentials are
239
+ // present in process.env. This block's only job is to invoke each of
240
+ // the six functions via dynamic import — no hand-rolled
241
+ // `new XHandler()` + `registerHandler()` calls live here anymore.
242
+ // Each ecosystem keeps its own try/catch so one broken import can't
243
+ // take down the other five (matches the previous block's isolation).
232
244
  // ===== TTS HANDLER REGISTRATION =====
233
245
  try {
234
- // Create handler instance and register explicitly
235
- const { GoogleTTSHandler } = await import("../adapters/tts/googleTTSHandler.js");
236
- const { TTSProcessor } = await import("../utils/ttsProcessor.js");
237
- const googleHandler = new GoogleTTSHandler();
238
- TTSProcessor.registerHandler("google-ai", googleHandler);
239
- TTSProcessor.registerHandler("vertex", googleHandler);
240
- logger.debug("TTS handlers registered successfully", {
241
- providers: ["google-ai", "vertex"],
246
+ const { registerDefaultTTSHandlers } = await import("../voice/index.js");
247
+ registerDefaultTTSHandlers();
248
+ logger.debug("TTS handler registration attempted", {
249
+ providers: providerChoicesFor("tts"),
242
250
  });
243
251
  }
244
252
  catch (ttsError) {
@@ -247,91 +255,12 @@ export class ProviderRegistry {
247
255
  });
248
256
  // Don't throw - TTS is optional functionality
249
257
  }
250
- // New TTS providers
251
- try {
252
- const { TTSProcessor } = await import("../utils/ttsProcessor.js");
253
- const { OpenAITTS } = await import("../voice/providers/OpenAITTS.js");
254
- TTSProcessor.registerHandler("openai-tts", new OpenAITTS());
255
- }
256
- catch (err) {
257
- logger.debug(`[ProviderRegistry] openai-tts registration skipped: ${err instanceof Error ? err.message : String(err)}`);
258
- }
259
- try {
260
- const { TTSProcessor } = await import("../utils/ttsProcessor.js");
261
- const { ElevenLabsTTS } = await import("../voice/providers/ElevenLabsTTS.js");
262
- const elevenLabsHandler = new ElevenLabsTTS();
263
- TTSProcessor.registerHandler("elevenlabs", elevenLabsHandler);
264
- TTSProcessor.registerHandler("elevenlabs-tts", elevenLabsHandler);
265
- }
266
- catch (err) {
267
- logger.debug(`[ProviderRegistry] elevenlabs registration skipped: ${err instanceof Error ? err.message : String(err)}`);
268
- }
269
- try {
270
- const { TTSProcessor } = await import("../utils/ttsProcessor.js");
271
- const { AzureTTS } = await import("../voice/providers/AzureTTS.js");
272
- TTSProcessor.registerHandler("azure-tts", new AzureTTS());
273
- }
274
- catch (err) {
275
- logger.debug(`[ProviderRegistry] azure-tts registration skipped: ${err instanceof Error ? err.message : String(err)}`);
276
- }
277
- // Fish Audio and Cartesia also auto-register via the voice/index.ts
278
- // barrel side-effect. The supports() guard here keeps registration
279
- // idempotent across entry points — same handler, no overwrite warning.
280
- try {
281
- const { TTSProcessor } = await import("../utils/ttsProcessor.js");
282
- if (!TTSProcessor.supports("fish-audio")) {
283
- const { FishAudioTTS } = await import("../voice/providers/FishAudioTTS.js");
284
- TTSProcessor.registerHandler("fish-audio", new FishAudioTTS());
285
- }
286
- }
287
- catch (err) {
288
- logger.debug(`[ProviderRegistry] fish-audio registration skipped: ${err instanceof Error ? err.message : String(err)}`);
289
- }
290
- try {
291
- const { TTSProcessor } = await import("../utils/ttsProcessor.js");
292
- if (!TTSProcessor.supports("cartesia")) {
293
- const { CartesiaTTS } = await import("../voice/providers/CartesiaTTS.js");
294
- TTSProcessor.registerHandler("cartesia", new CartesiaTTS());
295
- }
296
- }
297
- catch (err) {
298
- logger.debug(`[ProviderRegistry] cartesia registration skipped: ${err instanceof Error ? err.message : String(err)}`);
299
- }
300
258
  // ===== STT HANDLER REGISTRATION =====
301
259
  try {
302
- const { STTProcessor } = await import("../utils/sttProcessor.js");
303
- try {
304
- const { OpenAISTT } = await import("../voice/providers/OpenAISTT.js");
305
- const openAISTT = new OpenAISTT();
306
- STTProcessor.registerHandler("whisper", openAISTT);
307
- STTProcessor.registerHandler("openai-stt", openAISTT);
308
- }
309
- catch (err) {
310
- logger.debug(`[ProviderRegistry] whisper/openai-stt registration skipped: ${err instanceof Error ? err.message : String(err)}`);
311
- }
312
- try {
313
- const { DeepgramSTT } = await import("../voice/providers/DeepgramSTT.js");
314
- STTProcessor.registerHandler("deepgram", new DeepgramSTT());
315
- }
316
- catch (err) {
317
- logger.debug(`[ProviderRegistry] deepgram registration skipped: ${err instanceof Error ? err.message : String(err)}`);
318
- }
319
- try {
320
- const { GoogleSTT } = await import("../voice/providers/GoogleSTT.js");
321
- STTProcessor.registerHandler("google-stt", new GoogleSTT());
322
- }
323
- catch (err) {
324
- logger.debug(`[ProviderRegistry] google-stt registration skipped: ${err instanceof Error ? err.message : String(err)}`);
325
- }
326
- try {
327
- const { AzureSTT } = await import("../voice/providers/AzureSTT.js");
328
- STTProcessor.registerHandler("azure-stt", new AzureSTT());
329
- }
330
- catch (err) {
331
- logger.debug(`[ProviderRegistry] azure-stt registration skipped: ${err instanceof Error ? err.message : String(err)}`);
332
- }
333
- logger.debug("STT handlers registered successfully", {
334
- providers: ["whisper", "deepgram", "google-stt", "azure-stt"],
260
+ const { registerDefaultSTTHandlers } = await import("../voice/index.js");
261
+ registerDefaultSTTHandlers();
262
+ logger.debug("STT handler registration attempted", {
263
+ providers: providerChoicesFor("stt"),
335
264
  });
336
265
  }
337
266
  catch (sttError) {
@@ -341,33 +270,21 @@ export class ProviderRegistry {
341
270
  }
342
271
  // ===== REALTIME HANDLER REGISTRATION =====
343
272
  try {
344
- const { RealtimeProcessor } = await import("../voice/RealtimeVoiceAPI.js");
345
- // M9 + NEW4: track per-handler registration outcomes so the final
346
- // log accurately reflects which voice providers succeeded vs which
347
- // were skipped instead of unconditionally claiming "registered
348
- // successfully" or hiding failures at debug level.
273
+ const { registerDefaultRealtimeHandlers, RealtimeProcessor } = await import("../voice/index.js");
274
+ registerDefaultRealtimeHandlers();
275
+ // M9 + NEW4: registerDefaultRealtimeHandlers() swallows per-handler
276
+ // construction failures internally (it's a shared, idempotent
277
+ // barrel function used by every entry point — see voice/index.ts),
278
+ // so the exact per-handler exception text the old inline block
279
+ // captured is no longer available here. Recover per-name pass/fail
280
+ // via supports() instead so getRegistrationReport() stays truthful
281
+ // for callers that poll it.
282
+ const realtimeNames = providerChoicesFor("realtime");
349
283
  const realtimeOutcomes = {};
350
- try {
351
- const { OpenAIRealtime } = await import("../voice/providers/OpenAIRealtime.js");
352
- RealtimeProcessor.registerHandler("openai-realtime", new OpenAIRealtime());
353
- realtimeOutcomes["openai-realtime"] = "ok";
354
- }
355
- catch (err) {
356
- const msg = err instanceof Error ? err.message : String(err);
357
- realtimeOutcomes["openai-realtime"] = msg;
358
- // M9: promote per-handler failures to error level so users can
359
- // see which shipped voice provider failed to register at startup.
360
- logger.error(`[ProviderRegistry] openai-realtime registration failed: ${msg}`);
361
- }
362
- try {
363
- const { GeminiLive } = await import("../voice/providers/GeminiLive.js");
364
- RealtimeProcessor.registerHandler("gemini-live", new GeminiLive());
365
- realtimeOutcomes["gemini-live"] = "ok";
366
- }
367
- catch (err) {
368
- const msg = err instanceof Error ? err.message : String(err);
369
- realtimeOutcomes["gemini-live"] = msg;
370
- logger.error(`[ProviderRegistry] gemini-live registration failed: ${msg}`);
284
+ for (const name of realtimeNames) {
285
+ realtimeOutcomes[name] = RealtimeProcessor.supports(name)
286
+ ? "ok"
287
+ : "registration failed or handler unavailable";
371
288
  }
372
289
  // NEW4: report the actual per-handler outcomes instead of an
373
290
  // unconditional success log. Stored on the registry so callers can
@@ -375,7 +292,7 @@ export class ProviderRegistry {
375
292
  ProviderRegistry.realtimeRegistration = realtimeOutcomes;
376
293
  const skipped = Object.entries(realtimeOutcomes).filter(([, v]) => v !== "ok");
377
294
  if (skipped.length === 0) {
378
- logger.info("[ProviderRegistry] Realtime handlers registered: openai-realtime, gemini-live");
295
+ logger.info(`[ProviderRegistry] Realtime handlers registered: ${realtimeNames.join(", ")}`);
379
296
  }
380
297
  else {
381
298
  logger.warn(`[ProviderRegistry] Realtime handlers partial: ${skipped.length} skipped`, { outcomes: realtimeOutcomes });
@@ -390,67 +307,22 @@ export class ProviderRegistry {
390
307
  }
391
308
  // ===== VIDEO HANDLER REGISTRATION =====
392
309
  try {
393
- const { VideoProcessor } = await import("../utils/videoProcessor.js");
394
- try {
395
- const { VertexVideoHandler } = await import("../adapters/video/vertexVideoHandler.js");
396
- VideoProcessor.registerHandler("vertex", new VertexVideoHandler());
397
- }
398
- catch (err) {
399
- logger.debug(`[ProviderRegistry] vertex video registration skipped: ${err instanceof Error ? err.message : String(err)}`);
400
- }
401
- try {
402
- const { KlingVideoHandler } = await import("../adapters/video/klingVideoHandler.js");
403
- VideoProcessor.registerHandler("kling", new KlingVideoHandler());
404
- }
405
- catch (err) {
406
- logger.debug(`[ProviderRegistry] kling video registration skipped: ${err instanceof Error ? err.message : String(err)}`);
407
- }
408
- try {
409
- const { RunwayVideoHandler } = await import("../adapters/video/runwayVideoHandler.js");
410
- VideoProcessor.registerHandler("runway", new RunwayVideoHandler());
411
- }
412
- catch (err) {
413
- logger.debug(`[ProviderRegistry] runway video registration skipped: ${err instanceof Error ? err.message : String(err)}`);
414
- }
415
- try {
416
- const { ReplicateVideoHandler } = await import("../adapters/video/replicateVideoHandler.js");
417
- VideoProcessor.registerHandler("replicate", new ReplicateVideoHandler());
418
- }
419
- catch (err) {
420
- logger.debug(`[ProviderRegistry] replicate video registration skipped: ${err instanceof Error ? err.message : String(err)}`);
421
- }
422
- logger.debug("Video handlers registered");
310
+ const { registerDefaultVideoHandlers } = await import("../adapters/video/index.js");
311
+ registerDefaultVideoHandlers();
312
+ logger.debug("Video handler registration attempted", {
313
+ providers: providerChoicesFor("video"),
314
+ });
423
315
  }
424
316
  catch (err) {
425
317
  logger.warn(`[ProviderRegistry] video registration block failed: ${err instanceof Error ? err.message : String(err)}`);
426
318
  }
427
319
  // ===== AVATAR HANDLER REGISTRATION =====
428
320
  try {
429
- const { AvatarProcessor } = await import("../utils/avatarProcessor.js");
430
- try {
431
- const { DIDAvatar } = await import("../avatar/providers/DIDAvatar.js");
432
- AvatarProcessor.registerHandler("d-id", new DIDAvatar());
433
- }
434
- catch (err) {
435
- logger.debug(`[ProviderRegistry] d-id avatar registration skipped: ${err instanceof Error ? err.message : String(err)}`);
436
- }
437
- try {
438
- const { ReplicateAvatar } = await import("../avatar/providers/ReplicateAvatar.js");
439
- const replicateAvatar = new ReplicateAvatar();
440
- AvatarProcessor.registerHandler("replicate", replicateAvatar);
441
- AvatarProcessor.registerHandler("musetalk", replicateAvatar);
442
- }
443
- catch (err) {
444
- logger.debug(`[ProviderRegistry] replicate avatar registration skipped: ${err instanceof Error ? err.message : String(err)}`);
445
- }
446
- try {
447
- const { HeyGenAvatar } = await import("../avatar/providers/HeyGenAvatar.js");
448
- AvatarProcessor.registerHandler("heygen", new HeyGenAvatar());
449
- }
450
- catch (err) {
451
- logger.debug(`[ProviderRegistry] heygen avatar registration skipped: ${err instanceof Error ? err.message : String(err)}`);
452
- }
453
- logger.debug("Avatar handlers registered");
321
+ const { registerDefaultAvatarHandlers } = await import("../avatar/index.js");
322
+ registerDefaultAvatarHandlers();
323
+ logger.debug("Avatar handler registration attempted", {
324
+ providers: providerChoicesFor("avatar"),
325
+ });
454
326
  }
455
327
  catch (avatarError) {
456
328
  logger.warn("Failed to register Avatar handlers - Avatar functionality will be unavailable", {
@@ -461,40 +333,11 @@ export class ProviderRegistry {
461
333
  }
462
334
  // ===== MUSIC HANDLER REGISTRATION =====
463
335
  try {
464
- const { MusicProcessor } = await import("../utils/musicProcessor.js");
465
- try {
466
- const { BeatovenMusic } = await import("../music/providers/BeatovenMusic.js");
467
- MusicProcessor.registerHandler("beatoven", new BeatovenMusic());
468
- }
469
- catch (err) {
470
- logger.debug(`[ProviderRegistry] beatoven music registration skipped: ${err instanceof Error ? err.message : String(err)}`);
471
- }
472
- try {
473
- const { ReplicateMusic } = await import("../music/providers/ReplicateMusic.js");
474
- const replicateMusic = new ReplicateMusic();
475
- MusicProcessor.registerHandler("replicate", replicateMusic);
476
- MusicProcessor.registerHandler("musicgen", replicateMusic);
477
- }
478
- catch (err) {
479
- logger.debug(`[ProviderRegistry] replicate music registration skipped: ${err instanceof Error ? err.message : String(err)}`);
480
- }
481
- try {
482
- const { ElevenLabsMusic } = await import("../music/providers/ElevenLabsMusic.js");
483
- const elevenLabsMusic = new ElevenLabsMusic();
484
- MusicProcessor.registerHandler("elevenlabs-music", elevenLabsMusic);
485
- MusicProcessor.registerHandler("elevenlabs-sound", elevenLabsMusic);
486
- }
487
- catch (err) {
488
- logger.debug(`[ProviderRegistry] elevenlabs-music registration skipped: ${err instanceof Error ? err.message : String(err)}`);
489
- }
490
- try {
491
- const { LyriaMusic } = await import("../music/providers/LyriaMusic.js");
492
- MusicProcessor.registerHandler("lyria", new LyriaMusic());
493
- }
494
- catch (err) {
495
- logger.debug(`[ProviderRegistry] lyria music registration skipped: ${err instanceof Error ? err.message : String(err)}`);
496
- }
497
- logger.debug("Music handlers registered");
336
+ const { registerDefaultMusicHandlers } = await import("../music/index.js");
337
+ registerDefaultMusicHandlers();
338
+ logger.debug("Music handler registration attempted", {
339
+ providers: providerChoicesFor("music"),
340
+ });
498
341
  }
499
342
  catch (musicError) {
500
343
  logger.warn("Failed to register Music handlers - Music functionality will be unavailable", {
package/dist/index.d.ts CHANGED
@@ -67,10 +67,7 @@ export { STTProcessor } from "./utils/sttProcessor.js";
67
67
  export { AzureTTS, AzureTTSHandler, CartesiaTTS, CartesiaTTSHandler, ElevenLabsTTS, ElevenLabsTTSHandler, FishAudioTTS, FishAudioTTSHandler, GoogleTTSHandler, OpenAITTS, OpenAITTSHandler, AzureSTT, AzureSTTHandler, DeepgramSTT, DeepgramSTTHandler, GoogleSTT, GoogleSTTHandler, OpenAISTT, OpenAISTTHandler, WhisperSTT, WhisperSTTHandler, BaseRealtimeHandler, GeminiLive, GeminiLiveHandler, OpenAIRealtime, OpenAIRealtimeHandler, RealtimeProcessor, RealtimeError, STTError, VoiceError, registerDefaultRealtimeHandlers, registerDefaultSTTHandlers, registerDefaultTTSHandlers, } from "./voice/index.js";
68
68
  export { BeatovenMusic, BeatovenMusicHandler, ElevenLabsMusic, ElevenLabsMusicHandler, LyriaMusic, LyriaMusicHandler, registerDefaultMusicHandlers, ReplicateMusic, ReplicateMusicHandler, } from "./music/index.js";
69
69
  export { DIDAvatar, DIDAvatarHandler, HeyGenAvatar, HeyGenAvatarHandler, registerDefaultAvatarHandlers, ReplicateAvatar, ReplicateAvatarHandler, } from "./avatar/index.js";
70
- export { KlingVideoHandler } from "./adapters/video/klingVideoHandler.js";
71
- export { ReplicateVideoHandler } from "./adapters/video/replicateVideoHandler.js";
72
- export { RunwayVideoHandler } from "./adapters/video/runwayVideoHandler.js";
73
- export { VertexVideoHandler, isVertexVideoConfigured, } from "./adapters/video/vertexVideoHandler.js";
70
+ export { isVertexVideoConfigured, KlingVideoHandler, registerDefaultVideoHandlers, ReplicateVideoHandler, RunwayVideoHandler, VertexVideoHandler, } from "./adapters/video/index.js";
74
71
  export { ImageGenService } from "./image-gen/ImageGenService.js";
75
72
  export { HITLManager } from "./hitl/hitlManager.js";
76
73
  export { ProviderRegistry } from "./factories/providerRegistry.js";
package/dist/index.js CHANGED
@@ -125,11 +125,8 @@ registerDefaultRealtimeHandlers, registerDefaultSTTHandlers, registerDefaultTTSH
125
125
  export { BeatovenMusic, BeatovenMusicHandler, ElevenLabsMusic, ElevenLabsMusicHandler, LyriaMusic, LyriaMusicHandler, registerDefaultMusicHandlers, ReplicateMusic, ReplicateMusicHandler, } from "./music/index.js";
126
126
  // Avatar handlers
127
127
  export { DIDAvatar, DIDAvatarHandler, HeyGenAvatar, HeyGenAvatarHandler, registerDefaultAvatarHandlers, ReplicateAvatar, ReplicateAvatarHandler, } from "./avatar/index.js";
128
- // Video handlers (live under adapters/video; no separate video/ barrel)
129
- export { KlingVideoHandler } from "./adapters/video/klingVideoHandler.js";
130
- export { ReplicateVideoHandler } from "./adapters/video/replicateVideoHandler.js";
131
- export { RunwayVideoHandler } from "./adapters/video/runwayVideoHandler.js";
132
- export { VertexVideoHandler, isVertexVideoConfigured, } from "./adapters/video/vertexVideoHandler.js";
128
+ // Video handlers
129
+ export { isVertexVideoConfigured, KlingVideoHandler, registerDefaultVideoHandlers, ReplicateVideoHandler, RunwayVideoHandler, VertexVideoHandler, } from "./adapters/video/index.js";
133
130
  // Image generation + HITL — surfaced from their dedicated barrels
134
131
  export { ImageGenService } from "./image-gen/ImageGenService.js";
135
132
  export { HITLManager } from "./hitl/hitlManager.js";
@@ -7,9 +7,12 @@
7
7
  * Use `MusicProcessor.generate(provider, options)` to dispatch to the
8
8
  * registered handler for `provider`.
9
9
  *
10
- * Importing this module also auto-registers every shipped music handler
11
- * whose backing API key is present in `process.env`. Registration is
12
- * idempotent and silently skipped if a provider is already registered or
10
+ * Importing this module does NOT register any handlers as a side effect.
11
+ * Call `registerDefaultMusicHandlers()` explicitly (or go through
12
+ * `ProviderRegistry.registerAllProviders()`, which every documented
13
+ * `NeuroLink` entry point already calls) to register every shipped music
14
+ * handler whose backing API key is present in `process.env`. Registration
15
+ * is idempotent and silently skipped if a provider is already registered or
13
16
  * its constructor throws (e.g. missing optional native dependency).
14
17
  *
15
18
  * @module music
@@ -7,13 +7,17 @@
7
7
  * Use `MusicProcessor.generate(provider, options)` to dispatch to the
8
8
  * registered handler for `provider`.
9
9
  *
10
- * Importing this module also auto-registers every shipped music handler
11
- * whose backing API key is present in `process.env`. Registration is
12
- * idempotent and silently skipped if a provider is already registered or
10
+ * Importing this module does NOT register any handlers as a side effect.
11
+ * Call `registerDefaultMusicHandlers()` explicitly (or go through
12
+ * `ProviderRegistry.registerAllProviders()`, which every documented
13
+ * `NeuroLink` entry point already calls) to register every shipped music
14
+ * handler whose backing API key is present in `process.env`. Registration
15
+ * is idempotent and silently skipped if a provider is already registered or
13
16
  * its constructor throws (e.g. missing optional native dependency).
14
17
  *
15
18
  * @module music
16
19
  */
20
+ import { MEDIA_HANDLER_CATALOG } from "../factories/mediaHandlerCatalog.js";
17
21
  import { logger } from "../utils/logger.js";
18
22
  import { MusicProcessor } from "../utils/musicProcessor.js";
19
23
  export { MUSIC_ERROR_CODES, MusicError, MusicProcessor, } from "../utils/musicProcessor.js";
@@ -31,20 +35,21 @@ import { BeatovenMusic } from "./providers/BeatovenMusic.js";
31
35
  import { ElevenLabsMusic } from "./providers/ElevenLabsMusic.js";
32
36
  import { LyriaMusic } from "./providers/LyriaMusic.js";
33
37
  import { ReplicateMusic } from "./providers/ReplicateMusic.js";
34
- const MUSIC_HANDLER_CANDIDATES = [
35
- { name: "beatoven", factory: () => new BeatovenMusic() },
36
- {
37
- name: "elevenlabs-music",
38
- aliases: ["elevenlabs-sound"],
39
- factory: () => new ElevenLabsMusic(),
40
- },
41
- { name: "lyria", factory: () => new LyriaMusic() },
42
- {
43
- name: "replicate",
44
- aliases: ["musicgen"],
45
- factory: () => new ReplicateMusic(),
46
- },
47
- ];
38
+ // Provider names + aliases are the Task-8 catalog's job — only the factory
39
+ // (which needs the imported handler class) stays local to this module.
40
+ const MUSIC_HANDLER_FACTORIES = {
41
+ beatoven: () => new BeatovenMusic(),
42
+ "elevenlabs-music": () => new ElevenLabsMusic(),
43
+ lyria: () => new LyriaMusic(),
44
+ replicate: () => new ReplicateMusic(),
45
+ };
46
+ const MUSIC_HANDLER_CANDIDATES = MEDIA_HANDLER_CATALOG.filter((entry) => entry.kind === "music").map((entry) => {
47
+ const factory = MUSIC_HANDLER_FACTORIES[entry.name];
48
+ if (!factory) {
49
+ throw new Error(`[music] no handler factory for catalog entry "${entry.name}"`);
50
+ }
51
+ return { name: entry.name, aliases: entry.aliases, factory };
52
+ });
48
53
  /**
49
54
  * Register every shipped music handler whose backing credentials are
50
55
  * present in the environment. Safe to call multiple times — existing
@@ -87,7 +92,3 @@ export function registerDefaultMusicHandlers() {
87
92
  }
88
93
  }
89
94
  }
90
- // Run once at module import so consumers who follow the documented
91
- // `nl.generate(...)` flow get every configured handler without manually
92
- // calling `registerHandler`.
93
- registerDefaultMusicHandlers();