@juspay/neurolink 11.29.0 → 11.29.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.
@@ -7,11 +7,10 @@ import type { RequestKind, RequestKindInput } from "../types/index.js";
7
7
  * stream()/runGenerateInActiveContext (image/video/tts-direct routing) call
8
8
  * this instead of independently re-deriving the decision.
9
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.
10
+ * Also the only copy at the provider-override level: replicate.ts's
11
+ * generate() override and googleVertex/client.ts's generate()/stream()
12
+ * overrides (which bypass BaseProvider's paths) call this too, so an edit
13
+ * to this precedence table reaches every dispatch site.
15
14
  *
16
15
  * Precedence, checked in order:
17
16
  * 1. output.mode (music/avatar/video/ppt) — an explicit mode always wins.
@@ -7,11 +7,10 @@ import { isImageGenerationModel } from "./constants.js";
7
7
  * stream()/runGenerateInActiveContext (image/video/tts-direct routing) call
8
8
  * this instead of independently re-deriving the decision.
9
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.
10
+ * Also the only copy at the provider-override level: replicate.ts's
11
+ * generate() override and googleVertex/client.ts's generate()/stream()
12
+ * overrides (which bypass BaseProvider's paths) call this too, so an edit
13
+ * to this precedence table reaches every dispatch site.
15
14
  *
16
15
  * Precedence, checked in order:
17
16
  * 1. output.mode (music/avatar/video/ppt) — an explicit mode always wins.
@@ -8,7 +8,8 @@ import { BaseProvider } from "../../core/baseProvider.js";
8
8
  import { unwrapImagePayload } from "../../adapters/imageFormatSupport.js";
9
9
  import { appendNativeAudioParts } from "../googleNativeGemini3/utils.js";
10
10
  import { getMimeTypeForExtension } from "../../processors/config/mimeConstants.js";
11
- import { DEFAULT_GEMINI_STREAM_TIMEOUT_MS, DEFAULT_MAX_STEPS, DEFAULT_TOOL_EXECUTION_TIMEOUT_MS, DEFAULT_TOOL_MAX_RETRIES, GLOBAL_LOCATION_MODELS, IMAGE_GENERATION_MODELS, TOOL_STORAGE_TIMEOUT_MS, } from "../../core/constants.js";
11
+ import { DEFAULT_GEMINI_STREAM_TIMEOUT_MS, DEFAULT_MAX_STEPS, DEFAULT_TOOL_EXECUTION_TIMEOUT_MS, DEFAULT_TOOL_MAX_RETRIES, GLOBAL_LOCATION_MODELS, TOOL_STORAGE_TIMEOUT_MS, } from "../../core/constants.js";
12
+ import { resolveRequestKind } from "../../core/resolveRequestKind.js";
12
13
  import { ModelConfigurationManager } from "../../core/modelConfiguration.js";
13
14
  import { isSchemaComplexityError } from "../../core/modules/structuredOutputPolicy.js";
14
15
  import { redactUrlForError, stringifyContentSafe, } from "../../utils/logSanitize.js";
@@ -5089,9 +5090,11 @@ export class GoogleVertexProvider extends BaseProvider {
5089
5090
  ? { input: { text: optionsOrPrompt } }
5090
5091
  : optionsOrPrompt;
5091
5092
  const modelName = options.model || this.modelName || getDefaultVertexModel();
5092
- // Check if this is an image generation model - image models don't support streaming
5093
- const isImageModel = IMAGE_GENERATION_MODELS.some((m) => modelName.toLowerCase().startsWith(m.toLowerCase()));
5094
- if (isImageModel) {
5093
+ // Image-generation requests can't stream fall back to generate.
5094
+ // Same single dispatch decision as generate(): resolveRequestKind
5095
+ // keeps dual-mode models streaming text when the caller explicitly
5096
+ // asked for a non-image output.format.
5097
+ if (resolveRequestKind(options, modelName) === "image") {
5095
5098
  logger.warn("[GoogleVertex] Image generation models don't support streaming, falling back to generate", { model: modelName });
5096
5099
  // Convert stream options to text generation options
5097
5100
  const generateOptions = {
@@ -5150,13 +5153,20 @@ export class GoogleVertexProvider extends BaseProvider {
5150
5153
  },
5151
5154
  }, async (generateSpan) => {
5152
5155
  const generateStartTime = Date.now();
5156
+ // One dispatch decision for the whole override: Vertex's generate()
5157
+ // bypasses BaseProvider.generate(), so it re-runs the same
5158
+ // resolveRequestKind() the core call sites use rather than keeping
5159
+ // a hand-rolled copy of the precedence (which had drifted: tts
5160
+ // checked before image, and a cruder case-insensitive startsWith
5161
+ // image match without boundary awareness).
5162
+ const requestKind = resolveRequestKind(options, modelName);
5153
5163
  // Video-mode requests must route through BaseProvider's
5154
5164
  // handleVideoGeneration (which loads the Veo 3 adapter). Vertex's
5155
5165
  // native @google/genai path is text/image only — without this
5156
5166
  // gate, video requests fall through to gemini-2.5-flash and the
5157
5167
  // model politely declines ("I cannot create animations") instead
5158
5168
  // of producing video bytes.
5159
- if (options.output?.mode === "video") {
5169
+ if (requestKind === "video") {
5160
5170
  logger.info("[GoogleVertex] Routing video-mode generate to handleVideoGeneration", { model: modelName });
5161
5171
  const videoResult = await this.handleVideoGeneration(options, generateStartTime);
5162
5172
  this.attachUsageAndCostAttributes(generateSpan, modelName, videoResult?.usage);
@@ -5168,15 +5178,17 @@ export class GoogleVertexProvider extends BaseProvider {
5168
5178
  // (synthesise the input text directly; no LLM call). BaseProvider's
5169
5179
  // standard generate() does the same dispatch — we replicate it here
5170
5180
  // because Vertex's override bypasses that path.
5171
- if (options.tts?.enabled && !options.tts?.useAiResponse) {
5181
+ if (requestKind === "tts-direct") {
5172
5182
  logger.info("[GoogleVertex] Routing TTS direct-synthesis to handleDirectTTSSynthesis", { model: modelName });
5173
5183
  const ttsResult = await this.handleDirectTTSSynthesis(options, generateStartTime);
5174
5184
  this.emitGenerationEnd(modelName, ttsResult, generateStartTime, true);
5175
5185
  return ttsResult;
5176
5186
  }
5177
- // Check if this is an image generation model - route to executeImageGeneration without tools
5178
- const isImageModel = IMAGE_GENERATION_MODELS.some((m) => modelName.toLowerCase().startsWith(m.toLowerCase()));
5179
- if (isImageModel) {
5187
+ // Image-generation models route to executeImageGeneration without
5188
+ // tools. resolveRequestKind also carries the dual-mode exception:
5189
+ // an explicit non-image output.format keeps models like
5190
+ // gemini-3.1-flash-image-preview on the text path.
5191
+ if (requestKind === "image") {
5180
5192
  logger.info("[GoogleVertex] Routing image generation model to executeImageGeneration", { model: modelName });
5181
5193
  const imageResult = await this.executeImageGeneration(options);
5182
5194
  this.attachUsageAndCostAttributes(generateSpan, modelName, imageResult?.usage);
@@ -1,5 +1,6 @@
1
1
  import { ErrorCategory, ErrorSeverity, ReplicateModels, } from "../constants/enums.js";
2
2
  import { BaseProvider } from "../core/baseProvider.js";
3
+ import { resolveRequestKind } from "../core/resolveRequestKind.js";
3
4
  import { getReplicateAuth } from "../adapters/replicate/auth.js";
4
5
  import { downloadPredictionOutput, predict, } from "../adapters/replicate/predictionLifecycle.js";
5
6
  import { MAX_IMAGE_BYTES } from "../utils/sizeGuard.js";
@@ -121,19 +122,18 @@ export class ReplicateProvider extends BaseProvider {
121
122
  const options = typeof optionsOrPrompt === "string"
122
123
  ? { prompt: optionsOrPrompt }
123
124
  : optionsOrPrompt;
124
- const { isImageGenerationModel } = await import("../core/constants.js");
125
- // Delegate special output modes to base class (which never calls getAISDKModel for these)
126
- if (options.output?.mode === "video" ||
127
- options.output?.mode === "avatar" ||
128
- options.output?.mode === "music") {
129
- return super.generate(options, _analysisSchema);
130
- }
131
- // Image-gen models: delegate to base which calls executeImageGeneration()
132
- const isImageModel = isImageGenerationModel(this.modelName);
133
- const requestsNonImageOutput = options.output?.format === "json" ||
134
- options.output?.format === "structured" ||
135
- options.output?.format === "text";
136
- if (isImageModel && !requestsNonImageOutput) {
125
+ // Delegate media kinds to the base class (which never calls
126
+ // getAISDKModel for these). resolveRequestKind owns the precedence
127
+ // including the dual-mode exception where an explicit non-image
128
+ // output.format keeps an image-gen model on the text path. "ppt" and
129
+ // "tts-direct" deliberately stay on the local text path below:
130
+ // super.generate() would hit prepareGenerationContext()
131
+ // getAISDKModel(), which throws for Replicate.
132
+ const kind = resolveRequestKind(options, this.modelName);
133
+ if (kind === "video" ||
134
+ kind === "avatar" ||
135
+ kind === "music" ||
136
+ kind === "image") {
137
137
  return super.generate(options, _analysisSchema);
138
138
  }
139
139
  // Structured / JSON output is not natively supported by the Replicate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "11.29.0",
3
+ "version": "11.29.1",
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": {