@juspay/neurolink 9.70.5 → 9.70.6

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.
@@ -76,7 +76,7 @@ import { resolveModel } from "./utils/modelAliasResolver.js";
76
76
  // Import orchestration components
77
77
  import { ModelRouter } from "./utils/modelRouter.js";
78
78
  import { getBestProvider } from "./utils/providerUtils.js";
79
- import { NON_RETRYABLE_HTTP_STATUS_CODES } from "./utils/retryability.js";
79
+ import { NON_RETRYABLE_HTTP_STATUS_CODES, isDeterministicClientErrorMessage, } from "./utils/retryability.js";
80
80
  import { isZodSchema } from "./utils/schemaConversion.js";
81
81
  import { BinaryTaskClassifier } from "./utils/taskClassifier.js";
82
82
  // Tool detection and execution imports
@@ -226,6 +226,15 @@ function isNonRetryableProviderError(error) {
226
226
  msg.includes("UNAUTHENTICATED")) {
227
227
  return true;
228
228
  }
229
+ // A deterministic 400 / malformed-request whose status is only present in
230
+ // the message string (e.g. Vertex wraps `{"code":400,"status":
231
+ // "INVALID_ARGUMENT"}` inside the message). The object-level status check
232
+ // above misses it, so without this the fallback orchestrator retries the
233
+ // identical bad payload on every other provider — they reject it the same
234
+ // way. The request itself is malformed, so abort fast.
235
+ if (isDeterministicClientErrorMessage(msg)) {
236
+ return true;
237
+ }
229
238
  }
230
239
  return false;
231
240
  }
@@ -12,3 +12,16 @@ export declare const NON_RETRYABLE_HTTP_STATUS_CODES: readonly number[];
12
12
  export declare function isRetryableStatusCode(code: number): boolean;
13
13
  /** Check whether an HTTP status code is non-retryable. */
14
14
  export declare function isNonRetryableStatusCode(code: number): boolean;
15
+ /**
16
+ * Detect a deterministic client-error (HTTP 400 / malformed request) signature
17
+ * embedded in a provider error MESSAGE, for cases where the numeric status is
18
+ * not exposed as a structured `status`/`statusCode` field. Vertex/Gemini wrap a
19
+ * 400 INVALID_ARGUMENT inside the message string (e.g. `Google Vertex AI Invalid
20
+ * Request: {"error":{"code":400,"status":"INVALID_ARGUMENT", …}}`), so the
21
+ * object-level status check misses it and the fallback orchestrator keeps
22
+ * retrying the identical, malformed payload on every other provider — they
23
+ * reject it the same way. A 400 means the request itself is bad, so retrying is
24
+ * pointless regardless of provider. Matches only unambiguous markers to avoid
25
+ * misclassifying transient (5xx/429) failures.
26
+ */
27
+ export declare function isDeterministicClientErrorMessage(message: string): boolean;
@@ -20,4 +20,26 @@ export function isRetryableStatusCode(code) {
20
20
  export function isNonRetryableStatusCode(code) {
21
21
  return NON_RETRYABLE_HTTP_STATUS_CODES.includes(code);
22
22
  }
23
+ /**
24
+ * Detect a deterministic client-error (HTTP 400 / malformed request) signature
25
+ * embedded in a provider error MESSAGE, for cases where the numeric status is
26
+ * not exposed as a structured `status`/`statusCode` field. Vertex/Gemini wrap a
27
+ * 400 INVALID_ARGUMENT inside the message string (e.g. `Google Vertex AI Invalid
28
+ * Request: {"error":{"code":400,"status":"INVALID_ARGUMENT", …}}`), so the
29
+ * object-level status check misses it and the fallback orchestrator keeps
30
+ * retrying the identical, malformed payload on every other provider — they
31
+ * reject it the same way. A 400 means the request itself is bad, so retrying is
32
+ * pointless regardless of provider. Matches only unambiguous markers to avoid
33
+ * misclassifying transient (5xx/429) failures.
34
+ */
35
+ export function isDeterministicClientErrorMessage(message) {
36
+ if (!message) {
37
+ return false;
38
+ }
39
+ return (message.includes("INVALID_ARGUMENT") ||
40
+ message.includes("Invalid JSON payload") ||
41
+ /\bInvalid Request\b/i.test(message) ||
42
+ /"code"\s*:\s*400\b/.test(message) ||
43
+ /\b400\s+Bad Request\b/i.test(message));
44
+ }
23
45
  //# sourceMappingURL=retryability.js.map
package/dist/neurolink.js CHANGED
@@ -76,7 +76,7 @@ import { resolveModel } from "./utils/modelAliasResolver.js";
76
76
  // Import orchestration components
77
77
  import { ModelRouter } from "./utils/modelRouter.js";
78
78
  import { getBestProvider } from "./utils/providerUtils.js";
79
- import { NON_RETRYABLE_HTTP_STATUS_CODES } from "./utils/retryability.js";
79
+ import { NON_RETRYABLE_HTTP_STATUS_CODES, isDeterministicClientErrorMessage, } from "./utils/retryability.js";
80
80
  import { isZodSchema } from "./utils/schemaConversion.js";
81
81
  import { BinaryTaskClassifier } from "./utils/taskClassifier.js";
82
82
  // Tool detection and execution imports
@@ -226,6 +226,15 @@ function isNonRetryableProviderError(error) {
226
226
  msg.includes("UNAUTHENTICATED")) {
227
227
  return true;
228
228
  }
229
+ // A deterministic 400 / malformed-request whose status is only present in
230
+ // the message string (e.g. Vertex wraps `{"code":400,"status":
231
+ // "INVALID_ARGUMENT"}` inside the message). The object-level status check
232
+ // above misses it, so without this the fallback orchestrator retries the
233
+ // identical bad payload on every other provider — they reject it the same
234
+ // way. The request itself is malformed, so abort fast.
235
+ if (isDeterministicClientErrorMessage(msg)) {
236
+ return true;
237
+ }
229
238
  }
230
239
  return false;
231
240
  }
@@ -12,3 +12,16 @@ export declare const NON_RETRYABLE_HTTP_STATUS_CODES: readonly number[];
12
12
  export declare function isRetryableStatusCode(code: number): boolean;
13
13
  /** Check whether an HTTP status code is non-retryable. */
14
14
  export declare function isNonRetryableStatusCode(code: number): boolean;
15
+ /**
16
+ * Detect a deterministic client-error (HTTP 400 / malformed request) signature
17
+ * embedded in a provider error MESSAGE, for cases where the numeric status is
18
+ * not exposed as a structured `status`/`statusCode` field. Vertex/Gemini wrap a
19
+ * 400 INVALID_ARGUMENT inside the message string (e.g. `Google Vertex AI Invalid
20
+ * Request: {"error":{"code":400,"status":"INVALID_ARGUMENT", …}}`), so the
21
+ * object-level status check misses it and the fallback orchestrator keeps
22
+ * retrying the identical, malformed payload on every other provider — they
23
+ * reject it the same way. A 400 means the request itself is bad, so retrying is
24
+ * pointless regardless of provider. Matches only unambiguous markers to avoid
25
+ * misclassifying transient (5xx/429) failures.
26
+ */
27
+ export declare function isDeterministicClientErrorMessage(message: string): boolean;
@@ -20,3 +20,25 @@ export function isRetryableStatusCode(code) {
20
20
  export function isNonRetryableStatusCode(code) {
21
21
  return NON_RETRYABLE_HTTP_STATUS_CODES.includes(code);
22
22
  }
23
+ /**
24
+ * Detect a deterministic client-error (HTTP 400 / malformed request) signature
25
+ * embedded in a provider error MESSAGE, for cases where the numeric status is
26
+ * not exposed as a structured `status`/`statusCode` field. Vertex/Gemini wrap a
27
+ * 400 INVALID_ARGUMENT inside the message string (e.g. `Google Vertex AI Invalid
28
+ * Request: {"error":{"code":400,"status":"INVALID_ARGUMENT", …}}`), so the
29
+ * object-level status check misses it and the fallback orchestrator keeps
30
+ * retrying the identical, malformed payload on every other provider — they
31
+ * reject it the same way. A 400 means the request itself is bad, so retrying is
32
+ * pointless regardless of provider. Matches only unambiguous markers to avoid
33
+ * misclassifying transient (5xx/429) failures.
34
+ */
35
+ export function isDeterministicClientErrorMessage(message) {
36
+ if (!message) {
37
+ return false;
38
+ }
39
+ return (message.includes("INVALID_ARGUMENT") ||
40
+ message.includes("Invalid JSON payload") ||
41
+ /\bInvalid Request\b/i.test(message) ||
42
+ /"code"\s*:\s*400\b/.test(message) ||
43
+ /\b400\s+Bad Request\b/i.test(message));
44
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "9.70.5",
3
+ "version": "9.70.6",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applications with 21+ providers: OpenAI, Anthropic, Google AI Studio, Google Vertex, AWS Bedrock, Azure OpenAI, Mistral, LiteLLM, SageMaker, Hugging Face, Ollama, OpenAI-compatible, OpenRouter, DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus voice (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech).",
6
6
  "author": {