@juspay/neurolink 11.28.0 → 11.29.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.
@@ -1,9 +1,9 @@
1
1
  import { context, SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
2
2
  import { directAgentTools } from "../agent/directTools.js";
3
3
  import { defaultProviderFor } from "../factories/mediaHandlerCatalog.js";
4
- import { isImageGenerationModel } from "./constants.js";
5
4
  import { MiddlewareFactory } from "../middleware/factory.js";
6
5
  import { modelSupports } from "../models/modelRegistry.js";
6
+ import { resolveRequestKind } from "./resolveRequestKind.js";
7
7
  import { ATTR, tracers } from "../telemetry/index.js";
8
8
  import { ERROR_CODES, isAbortError, NeuroLinkError, } from "../utils/errorHandling.js";
9
9
  import { ProviderError } from "../types/index.js";
@@ -239,14 +239,12 @@ export class BaseProvider {
239
239
  }
240
240
  // CRITICAL: Image generation models don't support real streaming
241
241
  // Force fake streaming for image models to ensure image output is yielded.
242
- // Skip this path when the caller explicitly requests non-image output (e.g.
243
- // JSON analysis) so dual-mode models like gemini-3.1-flash-image-preview
244
- // can still perform text/structured generation.
245
- const isImageModel = isImageGenerationModel(this.modelName);
246
- const requestsNonImageOutput = options.output?.format === "json" ||
247
- options.output?.format === "structured" ||
248
- options.output?.format === "text";
249
- if (isImageModel && !requestsNonImageOutput) {
242
+ // resolveRequestKind() skips this path when the caller explicitly requests
243
+ // non-image output (e.g. JSON analysis) so dual-mode models like
244
+ // gemini-3.1-flash-image-preview can still perform text/structured
245
+ // generation see its doc comment for the full precedence table.
246
+ const requestKind = resolveRequestKind(options, this.modelName);
247
+ if (requestKind === "image") {
250
248
  logger.info(`Image model detected, forcing fake streaming`, {
251
249
  provider: this.providerName,
252
250
  model: this.modelName,
@@ -1067,14 +1065,13 @@ export class BaseProvider {
1067
1065
  }
1068
1066
  async runGenerateInActiveContext(options, startTime, otelSpan, otelSpanState) {
1069
1067
  try {
1070
- if (options.output?.mode === "video") {
1068
+ // Single source of truth for "what kind of request is this" — see
1069
+ // resolveRequestKind's doc comment for the full precedence table.
1070
+ const requestKind = resolveRequestKind(options, this.modelName);
1071
+ if (requestKind === "video") {
1071
1072
  return await this.handleVideoGeneration(options, startTime);
1072
1073
  }
1073
- const isImageModel = isImageGenerationModel(this.modelName);
1074
- const requestsNonImageOutput = options.output?.format === "json" ||
1075
- options.output?.format === "structured" ||
1076
- options.output?.format === "text";
1077
- if (isImageModel && !requestsNonImageOutput) {
1074
+ if (requestKind === "image") {
1078
1075
  logger.info(`Image generation model detected, routing to executeImageGeneration`, {
1079
1076
  provider: this.providerName,
1080
1077
  model: this.modelName,
@@ -1082,7 +1079,7 @@ export class BaseProvider {
1082
1079
  const imageResult = await this.executeImageGeneration(options);
1083
1080
  return await this.enhanceResult(imageResult, options, startTime);
1084
1081
  }
1085
- if (options.tts?.enabled && !options.tts?.useAiResponse) {
1082
+ if (requestKind === "tts-direct") {
1086
1083
  return this.handleDirectTTSSynthesis(options, startTime);
1087
1084
  }
1088
1085
  const { tools, model } = await this.prepareGenerationContext(options);
@@ -2179,7 +2176,12 @@ export class BaseProvider {
2179
2176
  // shared timeout helper so standard video gen honors the caller's
2180
2177
  // timeout the same way director mode does (see above ~Line 2062).
2181
2178
  const videoTimeout = options.timeout ?? 600_000; // 10 min default
2182
- const videoResult = await this.executeWithTimeout(() => VideoProcessor.generate(requestedProvider, imageBuffer, prompt, options.output?.video ?? {}, options.region), { timeout: videoTimeout, operationType: "generate" });
2179
+ const videoResult = await this.executeWithTimeout(() => VideoProcessor.generate(requestedProvider, {
2180
+ ...(options.output?.video ?? {}),
2181
+ image: imageBuffer,
2182
+ prompt,
2183
+ region: options.region,
2184
+ }), { timeout: videoTimeout, operationType: "generate" });
2183
2185
  // Prefer the handler's own model id (more accurate — it knows the exact
2184
2186
  // checkpoint that ran). Fall back to the request-time value, and finally
2185
2187
  // to the Vertex default only when we're on the Vertex route.
@@ -0,0 +1,27 @@
1
+ import type { RequestKind, RequestKindInput } from "../types/index.js";
2
+ /**
3
+ * The dispatch decision for "what kind of request is this" — text, image,
4
+ * video, music, avatar, direct TTS synthesis, or PPT generation — at the
5
+ * CORE call sites: neurolink.ts's maybeHandleEarlyGenerateResult
6
+ * (music/avatar/ppt/workflow routing) and baseProvider.ts's
7
+ * stream()/runGenerateInActiveContext (image/video/tts-direct routing) call
8
+ * this instead of independently re-deriving the decision.
9
+ *
10
+ * NOT yet the only copy: replicate.ts's generate() override and
11
+ * googleVertex/client.ts's native dispatch (~6672-6718) still carry their
12
+ * own provider-internal versions — the Vertex one with a cruder
13
+ * startsWith() image match. Migrating those two is queued follow-up work;
14
+ * until it lands, an edit to this precedence table does not reach them.
15
+ *
16
+ * Precedence, checked in order:
17
+ * 1. output.mode (music/avatar/video/ppt) — an explicit mode always wins.
18
+ * 2. an image-generation model, unless the caller explicitly asked for a
19
+ * non-image output.format (json/structured/text) — this lets dual-mode
20
+ * models like gemini-3.1-flash-image-preview still perform text or
21
+ * structured generation when requested.
22
+ * 3. tts.enabled without tts.useAiResponse — direct synthesis, bypassing
23
+ * the LLM turn entirely (useAiResponse means the LLM's own text
24
+ * response gets synthesized afterward, which is NOT this branch).
25
+ * 4. otherwise, "text".
26
+ */
27
+ export declare function resolveRequestKind(options: RequestKindInput, modelName?: string): RequestKind;
@@ -0,0 +1,50 @@
1
+ import { isImageGenerationModel } from "./constants.js";
2
+ /**
3
+ * The dispatch decision for "what kind of request is this" — text, image,
4
+ * video, music, avatar, direct TTS synthesis, or PPT generation — at the
5
+ * CORE call sites: neurolink.ts's maybeHandleEarlyGenerateResult
6
+ * (music/avatar/ppt/workflow routing) and baseProvider.ts's
7
+ * stream()/runGenerateInActiveContext (image/video/tts-direct routing) call
8
+ * this instead of independently re-deriving the decision.
9
+ *
10
+ * NOT yet the only copy: replicate.ts's generate() override and
11
+ * googleVertex/client.ts's native dispatch (~6672-6718) still carry their
12
+ * own provider-internal versions — the Vertex one with a cruder
13
+ * startsWith() image match. Migrating those two is queued follow-up work;
14
+ * until it lands, an edit to this precedence table does not reach them.
15
+ *
16
+ * Precedence, checked in order:
17
+ * 1. output.mode (music/avatar/video/ppt) — an explicit mode always wins.
18
+ * 2. an image-generation model, unless the caller explicitly asked for a
19
+ * non-image output.format (json/structured/text) — this lets dual-mode
20
+ * models like gemini-3.1-flash-image-preview still perform text or
21
+ * structured generation when requested.
22
+ * 3. tts.enabled without tts.useAiResponse — direct synthesis, bypassing
23
+ * the LLM turn entirely (useAiResponse means the LLM's own text
24
+ * response gets synthesized afterward, which is NOT this branch).
25
+ * 4. otherwise, "text".
26
+ */
27
+ export function resolveRequestKind(options, modelName) {
28
+ if (options.output?.mode === "music") {
29
+ return "music";
30
+ }
31
+ if (options.output?.mode === "avatar") {
32
+ return "avatar";
33
+ }
34
+ if (options.output?.mode === "video") {
35
+ return "video";
36
+ }
37
+ if (options.output?.mode === "ppt") {
38
+ return "ppt";
39
+ }
40
+ const requestsNonImageOutput = options.output?.format === "json" ||
41
+ options.output?.format === "structured" ||
42
+ options.output?.format === "text";
43
+ if (isImageGenerationModel(modelName) && !requestsNonImageOutput) {
44
+ return "image";
45
+ }
46
+ if (options.tts?.enabled && !options.tts?.useAiResponse) {
47
+ return "tts-direct";
48
+ }
49
+ return "text";
50
+ }
package/dist/neurolink.js CHANGED
@@ -34,6 +34,7 @@ import { buildToolRoutingCatalog, buildRoutingQueryFromHistory, resolveToolRouti
34
34
  import { ToolRoutingCache } from "./core/toolRoutingCache.js";
35
35
  import { DEFAULT_RECENT_TURNS, KnowledgeGroundingEngine, } from "./knowledge/index.js";
36
36
  import { AIProviderFactory } from "./core/factory.js";
37
+ import { resolveRequestKind } from "./core/resolveRequestKind.js";
37
38
  import { createToolEventPayload } from "./core/toolEvents.js";
38
39
  import { ProviderFactory } from "./factories/providerFactory.js";
39
40
  import { ProviderRegistry } from "./factories/providerRegistry.js";
@@ -3576,13 +3577,16 @@ Current user's request: ${currentInput}`;
3576
3577
  }
3577
3578
  return this.generateWithWorkflow(options);
3578
3579
  }
3579
- if (options.output?.mode === "music") {
3580
+ // Single source of truth for "what kind of request is this" — see
3581
+ // resolveRequestKind's doc comment for the full precedence table.
3582
+ const requestKind = resolveRequestKind(options, options.model);
3583
+ if (requestKind === "music") {
3580
3584
  return this.generateWithMusic(options, generateSpan);
3581
3585
  }
3582
- if (options.output?.mode === "avatar") {
3586
+ if (requestKind === "avatar") {
3583
3587
  return this.generateWithAvatar(options, generateSpan);
3584
3588
  }
3585
- if (options.output?.mode !== "ppt") {
3589
+ if (requestKind !== "ppt") {
3586
3590
  return null;
3587
3591
  }
3588
3592
  if (options.stt?.enabled && options.stt?.audio) {
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Types backing resolveRequestKind() (src/lib/core/resolveRequestKind.ts) —
3
+ * the single function that decides which of NeuroLink's output modes a
4
+ * generate/stream request is asking for.
5
+ */
6
+ export type RequestKind = "text" | "image" | "video" | "music" | "avatar" | "tts-direct" | "ppt";
7
+ /**
8
+ * Narrow structural subset of TextGenerationOptions/GenerateOptions that
9
+ * resolveRequestKind() actually reads. Kept intentionally minimal (rather
10
+ * than importing the full options type) so this module has no dependency
11
+ * on the wider options type graph.
12
+ */
13
+ export type RequestKindInput = {
14
+ output?: {
15
+ mode?: string;
16
+ format?: string;
17
+ };
18
+ tts?: {
19
+ enabled?: boolean;
20
+ useAiResponse?: boolean;
21
+ };
22
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Types backing resolveRequestKind() (src/lib/core/resolveRequestKind.ts) —
3
+ * the single function that decides which of NeuroLink's output modes a
4
+ * generate/stream request is asking for.
5
+ */
6
+ export {};
@@ -802,23 +802,12 @@ export type ToolExecutionCaptureOptions = {
802
802
  */
803
803
  export type GenerateStopReason = "completed" | "step-cap" | "context-cap" | "time-limit" | "stalled" | "aborted" | "provider-error";
804
804
  /**
805
- * Generate function result type - Primary output format
806
- * Future-ready for multi-modal outputs while maintaining text focus
805
+ * Media generation/processing outputs shared by GenerateResult and
806
+ * TextGenerationResult. Extracted so both result types intersect (&) this
807
+ * single definition instead of each declaring its own drifting copy of the
808
+ * same audio/video/avatar/music/ppt/image/transcription fields.
807
809
  */
808
- export type GenerateResult = {
809
- content: string;
810
- /** Knowledge-grounding diagnostics for this turn (present only when grounding ran). */
811
- knowledge?: KnowledgeGroundingMetadata;
812
- /**
813
- * Parsed structured object when a `schema` was requested. Populated from
814
- * AI-SDK experimental_output, or from text-mode coercion (balanced-scan +
815
- * jsonrepair). Prefer this over JSON.parse(content) — it never requires the
816
- * caller to re-parse hand-escaped model text.
817
- */
818
- structuredData?: unknown;
819
- outputs?: {
820
- text: string;
821
- };
810
+ export type MediaGenerationOutputs = {
822
811
  /**
823
812
  * Text-to-Speech audio result
824
813
  *
@@ -911,9 +900,31 @@ export type GenerateResult = {
911
900
  * ```
912
901
  */
913
902
  ppt?: PPTGenerationResult;
903
+ /** Standard format for image generation */
914
904
  imageOutput?: {
915
905
  base64: string;
916
906
  } | null;
907
+ /** STT transcription result (present when stt.enabled is true and audio input was provided) */
908
+ transcription?: STTResult;
909
+ };
910
+ /**
911
+ * Generate function result type - Primary output format
912
+ * Future-ready for multi-modal outputs while maintaining text focus
913
+ */
914
+ export type GenerateResult = {
915
+ content: string;
916
+ /** Knowledge-grounding diagnostics for this turn (present only when grounding ran). */
917
+ knowledge?: KnowledgeGroundingMetadata;
918
+ /**
919
+ * Parsed structured object when a `schema` was requested. Populated from
920
+ * AI-SDK experimental_output, or from text-mode coercion (balanced-scan +
921
+ * jsonrepair). Prefer this over JSON.parse(content) — it never requires the
922
+ * caller to re-parse hand-escaped model text.
923
+ */
924
+ structuredData?: unknown;
925
+ outputs?: {
926
+ text: string;
927
+ };
917
928
  provider?: string;
918
929
  model?: string;
919
930
  finishReason?: string;
@@ -1013,8 +1024,6 @@ export type GenerateResult = {
1013
1024
  reasoning?: string;
1014
1025
  /** Token count for reasoning content */
1015
1026
  reasoningTokens?: number;
1016
- /** STT transcription result (present when stt.enabled is true and audio input was provided) */
1017
- transcription?: STTResult;
1018
1027
  retries?: {
1019
1028
  count: number;
1020
1029
  errors: Array<{
@@ -1033,7 +1042,7 @@ export type GenerateResult = {
1033
1042
  * absolute `requestsRemaining` / `tokensRemaining`.
1034
1043
  */
1035
1044
  limits?: ClaudeLimitSnapshot;
1036
- };
1045
+ } & MediaGenerationOutputs;
1037
1046
  /**
1038
1047
  * Unified options for both generation and streaming
1039
1048
  * Supports factory patterns and domain configuration
@@ -1467,23 +1476,6 @@ export type TextGenerationResult = {
1467
1476
  }>;
1468
1477
  analytics?: AnalyticsData;
1469
1478
  evaluation?: EvaluationData;
1470
- audio?: TTSResult;
1471
- /** Outcome of TTS synthesis, including the failure reason. */
1472
- ttsMetadata?: TTSMetadata;
1473
- /** STT transcription result (present when stt input was processed) */
1474
- transcription?: STTResult;
1475
- /** Video generation result */
1476
- video?: VideoGenerationResult;
1477
- /** Avatar (talking-head) generation result */
1478
- avatar?: AvatarResult;
1479
- /** Music generation result */
1480
- music?: MusicResult;
1481
- /** PowerPoint generation result */
1482
- ppt?: PPTGenerationResult;
1483
- /** Image generation output */
1484
- imageOutput?: {
1485
- base64: string;
1486
- } | null;
1487
1479
  /** Gemini 3 thought signature for reasoning continuity across turns */
1488
1480
  thoughtSignature?: string;
1489
1481
  /** Thinking/reasoning text from provider (Anthropic thinking blocks, Gemini thought parts, DeepSeek/NIM reasoning_content) */
@@ -1497,7 +1489,7 @@ export type TextGenerationResult = {
1497
1489
  message: string;
1498
1490
  }>;
1499
1491
  };
1500
- };
1492
+ } & MediaGenerationOutputs;
1501
1493
  /**
1502
1494
  * Enhanced result type with optional analytics/evaluation
1503
1495
  */
@@ -86,3 +86,4 @@ export * from "./requestRouter.js";
86
86
  export * from "./classifierRouter.js";
87
87
  export * from "./agentNetwork.js";
88
88
  export * from "./localUsage.js";
89
+ export * from "./dispatch.js";
@@ -97,3 +97,5 @@ export * from "./classifierRouter.js";
97
97
  // Multi-Agent orchestration types
98
98
  export * from "./agentNetwork.js";
99
99
  export * from "./localUsage.js";
100
+ // resolveRequestKind() dispatch-decision types
101
+ export * from "./dispatch.js";
@@ -13,6 +13,19 @@
13
13
  */
14
14
  import type { VideoGenerationResult, VideoOutputOptions } from "./multimodal.js";
15
15
  export type { VideoGenerationResult, VideoOutputOptions, } from "./multimodal.js";
16
+ /**
17
+ * Bag-form input to `VideoProcessor.generate()` — the primary data (image,
18
+ * prompt, region) alongside the video-specific output options, collapsed
19
+ * into a single object matching Music/Avatar's existing `generate(provider,
20
+ * options)` shape. `VideoHandler.generate()`'s own 4-positional-argument
21
+ * signature is unchanged; `VideoProcessor.generate()` translates between the
22
+ * two internally.
23
+ */
24
+ export type VideoGenerateOptions = VideoOutputOptions & {
25
+ image: Buffer;
26
+ prompt: string;
27
+ region?: string;
28
+ };
16
29
  /**
17
30
  * Director-mode transition options.
18
31
  *
@@ -11,7 +11,7 @@
11
11
  * @module utils/videoProcessor
12
12
  */
13
13
  import { VIDEO_ERROR_CODES } from "../constants/videoErrors.js";
14
- import type { VideoGenerationResult, VideoHandler, VideoOutputOptions, VideoTransitionOptions } from "../types/index.js";
14
+ import type { VideoGenerateOptions, VideoGenerationResult, VideoHandler, VideoOutputOptions, VideoTransitionOptions } from "../types/index.js";
15
15
  import { VideoError } from "../adapters/video/vertexVideoHandler.js";
16
16
  export { VideoError, VIDEO_ERROR_CODES };
17
17
  /**
@@ -45,13 +45,19 @@ export declare class VideoProcessor {
45
45
  * Generate a single video clip via the registered handler.
46
46
  *
47
47
  * @param provider - Registered provider name (e.g. "vertex", "kling")
48
- * @param image - Source image buffer
49
- * @param prompt - Text prompt describing the desired motion / content
50
- * @param options - Resolution / length / aspect-ratio / audio options
51
- * @param region - Optional region override (Vertex location, etc.)
48
+ * @param options - Bag of the source image, prompt, optional region
49
+ * override, and resolution / length / aspect-ratio / audio options.
50
+ * Translated internally into the handler-level 4-positional-argument
51
+ * call `VideoHandler.generate()`'s own signature is unchanged.
52
52
  * @throws VideoError on registry miss, handler-not-configured, or
53
53
  * generation failure
54
54
  */
55
+ static generate(provider: string, options: VideoGenerateOptions): Promise<VideoGenerationResult>;
56
+ /**
57
+ * @deprecated Positional form kept for backward compatibility with
58
+ * pre-bag callers (VideoProcessor is a public export). Use the
59
+ * options-bag overload.
60
+ */
55
61
  static generate(provider: string, image: Buffer, prompt: string, options: VideoOutputOptions, region?: string): Promise<VideoGenerationResult>;
56
62
  /**
57
63
  * Generate a transition clip via the registered handler (Director Mode).
@@ -14,6 +14,11 @@ import { ErrorCategory, ErrorSeverity } from "../constants/enums.js";
14
14
  import { VIDEO_ERROR_CODES } from "../constants/videoErrors.js";
15
15
  import { SpanSerializer, SpanStatus, SpanType, getMetricsAggregator, } from "../observability/index.js";
16
16
  import { logger } from "./logger.js";
17
+ import { withTimeout } from "./async/withTimeout.js";
18
+ // Video generation is legitimately minutes-long (Kling/Runway render queues),
19
+ // so the bound is generous — its job is to convert a wedged handler into an
20
+ // error rather than an eternal hang, not to police normal latency.
21
+ const VIDEO_GENERATION_TIMEOUT_MS = 600_000;
17
22
  // VideoError is canonical in vertexVideoHandler.ts (existing). Re-export
18
23
  // here so consumers of `VideoProcessor` can import the typed error from
19
24
  // the same module. Both throws and instanceof checks resolve to the same
@@ -69,19 +74,17 @@ export class VideoProcessor {
69
74
  "video.audio": options.audio,
70
75
  };
71
76
  }
72
- /**
73
- * Generate a single video clip via the registered handler.
74
- *
75
- * @param provider - Registered provider name (e.g. "vertex", "kling")
76
- * @param image - Source image buffer
77
- * @param prompt - Text prompt describing the desired motion / content
78
- * @param options - Resolution / length / aspect-ratio / audio options
79
- * @param region - Optional region override (Vertex location, etc.)
80
- * @throws VideoError on registry miss, handler-not-configured, or
81
- * generation failure
82
- */
83
- static async generate(provider, image, prompt, options, region) {
84
- const span = SpanSerializer.createSpan(SpanType.MEDIA_GENERATION, "video.generate", this.buildSpanAttributes(provider, options));
77
+ static async generate(provider, optionsOrImage, legacyPrompt, legacyOptions, legacyRegion) {
78
+ const bag = Buffer.isBuffer(optionsOrImage)
79
+ ? {
80
+ image: optionsOrImage,
81
+ prompt: legacyPrompt ?? "",
82
+ ...(legacyRegion !== undefined ? { region: legacyRegion } : {}),
83
+ ...(legacyOptions ?? {}),
84
+ }
85
+ : optionsOrImage;
86
+ const { image, prompt, region, ...videoOptions } = bag;
87
+ const span = SpanSerializer.createSpan(SpanType.MEDIA_GENERATION, "video.generate", this.buildSpanAttributes(provider, videoOptions));
85
88
  try {
86
89
  const handler = this.getHandler(provider);
87
90
  if (!handler) {
@@ -105,7 +108,10 @@ export class VideoProcessor {
105
108
  });
106
109
  }
107
110
  logger.debug(`[VideoProcessor] Starting video generation with provider: ${provider}`);
108
- const result = await handler.generate(image, prompt, options, region);
111
+ // Bounded per repo guideline (async provider calls wrap withTimeout):
112
+ // video generation is legitimately slow, so the deadline is generous —
113
+ // but a wedged handler must error, never hang the caller forever.
114
+ const result = await withTimeout(handler.generate(image, prompt, videoOptions, region), VIDEO_GENERATION_TIMEOUT_MS, `Video generation via "${provider}" timed out after ${VIDEO_GENERATION_TIMEOUT_MS}ms`);
109
115
  const ended = SpanSerializer.endSpan(span, SpanStatus.OK);
110
116
  getMetricsAggregator().recordSpan(ended);
111
117
  logger.info(`[VideoProcessor] Generated ${result.data.length} bytes (${provider})`);
@@ -124,7 +130,7 @@ export class VideoProcessor {
124
130
  category: ErrorCategory.EXECUTION,
125
131
  severity: ErrorSeverity.HIGH,
126
132
  retriable: true,
127
- context: { provider, options, region },
133
+ context: { provider, options: videoOptions, region },
128
134
  originalError: err instanceof Error ? err : undefined,
129
135
  });
130
136
  }
@@ -169,7 +175,8 @@ export class VideoProcessor {
169
175
  });
170
176
  }
171
177
  try {
172
- return await handler.generateTransition(firstFrame, lastFrame, prompt, options, region);
178
+ // Same bound as generate(): a wedged transition must error, not hang.
179
+ return await withTimeout(handler.generateTransition(firstFrame, lastFrame, prompt, options, region), VIDEO_GENERATION_TIMEOUT_MS, `Video transition via "${provider}" timed out after ${VIDEO_GENERATION_TIMEOUT_MS}ms`);
173
180
  }
174
181
  catch (err) {
175
182
  if (err instanceof VideoError) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "11.28.0",
3
+ "version": "11.29.0",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (connect any MCP server), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
6
6
  "author": {
@@ -73,6 +73,7 @@
73
73
  "test:context": "pnpm exec tsx test/continuous-test-suite-context.ts",
74
74
  "test:evaluation": "pnpm exec tsx test/continuous-test-suite-evaluation.ts",
75
75
  "test:handler-registry": "pnpm exec tsx test/continuous-test-suite-handler-registry.ts",
76
+ "test:resolve-request-kind": "pnpm exec tsx test/continuous-test-suite-resolve-request-kind.ts",
76
77
  "test:mcp": "pnpm exec tsx test/continuous-test-suite-mcp-infra.ts",
77
78
  "test:tool-resolution": "pnpm exec tsx test/continuous-test-suite-tool-resolution.ts",
78
79
  "test:mcp:http": "pnpm exec tsx test/continuous-test-suite-mcp-http.ts",