@juspay/neurolink 10.12.9 → 11.1.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 (241) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/browser/neurolink.min.js +504 -506
  3. package/dist/cli/commands/setup.d.ts +20 -1
  4. package/dist/cli/commands/setup.js +160 -36
  5. package/dist/cli/factories/commandFactory.d.ts +1157 -1
  6. package/dist/cli/factories/commandFactory.js +20 -53
  7. package/dist/core/baseProvider.js +3 -3
  8. package/dist/core/dynamicModels.d.ts +1 -1
  9. package/dist/core/dynamicModels.js +1 -23
  10. package/dist/core/modelConfiguration.d.ts +1 -70
  11. package/dist/core/modelConfiguration.js +0 -303
  12. package/dist/core/modules/GenerationHandler.js +2 -2
  13. package/dist/core/modules/structuredOutputPolicy.d.ts +2 -2
  14. package/dist/core/modules/structuredOutputPolicy.js +2 -2
  15. package/dist/factories/providerDescriptors.d.ts +18 -0
  16. package/dist/factories/providerDescriptors.js +536 -0
  17. package/dist/factories/providerFactory.d.ts +28 -2
  18. package/dist/factories/providerFactory.js +53 -42
  19. package/dist/factories/providerRegistry.js +33 -32
  20. package/dist/index.d.ts +10 -1
  21. package/dist/index.js +13 -3
  22. package/dist/lib/core/baseProvider.js +3 -3
  23. package/dist/lib/core/dynamicModels.d.ts +1 -1
  24. package/dist/lib/core/dynamicModels.js +1 -23
  25. package/dist/lib/core/modelConfiguration.d.ts +1 -70
  26. package/dist/lib/core/modelConfiguration.js +0 -303
  27. package/dist/lib/core/modules/GenerationHandler.js +2 -2
  28. package/dist/lib/core/modules/structuredOutputPolicy.d.ts +2 -2
  29. package/dist/lib/core/modules/structuredOutputPolicy.js +2 -2
  30. package/dist/lib/factories/providerDescriptors.d.ts +18 -0
  31. package/dist/lib/factories/providerDescriptors.js +537 -0
  32. package/dist/lib/factories/providerFactory.d.ts +28 -2
  33. package/dist/lib/factories/providerFactory.js +53 -42
  34. package/dist/lib/factories/providerRegistry.js +33 -32
  35. package/dist/lib/index.d.ts +10 -1
  36. package/dist/lib/index.js +13 -3
  37. package/dist/lib/models/anthropicModels.d.ts +0 -7
  38. package/dist/lib/models/anthropicModels.js +0 -9
  39. package/dist/lib/neurolink.js +25 -37
  40. package/dist/lib/providers/amazonBedrock/client.js +34 -16
  41. package/dist/lib/providers/anthropic/client.js +39 -34
  42. package/dist/lib/providers/anthropic/constants.d.ts +0 -1
  43. package/dist/lib/providers/anthropic/constants.js +0 -2
  44. package/dist/lib/providers/anthropic/index.d.ts +0 -1
  45. package/dist/lib/providers/anthropic/index.js +0 -1
  46. package/dist/lib/providers/azureOpenai.js +17 -15
  47. package/dist/lib/providers/cloudflare.js +12 -21
  48. package/dist/lib/providers/cohere.js +31 -25
  49. package/dist/lib/providers/deepseek.js +23 -26
  50. package/dist/lib/providers/fireworks.js +12 -21
  51. package/dist/lib/providers/googleAiStudio/client.d.ts +2 -0
  52. package/dist/lib/providers/googleAiStudio/client.js +39 -17
  53. package/dist/lib/providers/googleAiStudio/index.d.ts +0 -1
  54. package/dist/lib/providers/googleAiStudio/index.js +0 -1
  55. package/dist/lib/providers/googleNativeGemini3/index.d.ts +0 -1
  56. package/dist/lib/providers/googleNativeGemini3/index.js +0 -1
  57. package/dist/lib/providers/googleVertex/client.d.ts +0 -51
  58. package/dist/lib/providers/googleVertex/client.js +107 -777
  59. package/dist/lib/providers/groq.js +19 -22
  60. package/dist/lib/providers/huggingFace/client.d.ts +1 -1
  61. package/dist/lib/providers/huggingFace/client.js +27 -25
  62. package/dist/lib/providers/huggingFace/index.d.ts +0 -1
  63. package/dist/lib/providers/huggingFace/index.js +0 -1
  64. package/dist/lib/providers/jina.d.ts +0 -1
  65. package/dist/lib/providers/jina.js +0 -1
  66. package/dist/lib/providers/litellm/client.js +54 -39
  67. package/dist/lib/providers/litellm/index.d.ts +0 -2
  68. package/dist/lib/providers/litellm/index.js +0 -2
  69. package/dist/lib/providers/llamaCpp.d.ts +1 -0
  70. package/dist/lib/providers/llamaCpp.js +24 -18
  71. package/dist/lib/providers/lmStudio.js +25 -42
  72. package/dist/lib/providers/mistral.js +12 -24
  73. package/dist/lib/providers/nvidiaNim/client.js +37 -34
  74. package/dist/lib/providers/nvidiaNim/index.d.ts +0 -1
  75. package/dist/lib/providers/nvidiaNim/index.js +0 -1
  76. package/dist/lib/providers/ollama/client.js +51 -58
  77. package/dist/lib/providers/ollama/index.d.ts +0 -1
  78. package/dist/lib/providers/ollama/index.js +0 -1
  79. package/dist/lib/providers/openAI/client.js +37 -40
  80. package/dist/lib/providers/openAI/index.d.ts +0 -2
  81. package/dist/lib/providers/openAI/index.js +0 -2
  82. package/dist/lib/providers/openRouter/client.js +53 -47
  83. package/dist/lib/providers/openRouter/utils.d.ts +0 -2
  84. package/dist/lib/providers/openRouter/utils.js +0 -12
  85. package/dist/lib/providers/openaiChatCompletionsBase.d.ts +9 -0
  86. package/dist/lib/providers/openaiChatCompletionsBase.js +73 -16
  87. package/dist/lib/providers/openaiCompatible/client.js +36 -32
  88. package/dist/lib/providers/perplexity.d.ts +2 -1
  89. package/dist/lib/providers/perplexity.js +14 -22
  90. package/dist/lib/providers/replicate.d.ts +0 -1
  91. package/dist/lib/providers/replicate.js +22 -9
  92. package/dist/lib/providers/togetherAi.js +12 -21
  93. package/dist/lib/providers/voyage.d.ts +0 -1
  94. package/dist/lib/providers/voyage.js +0 -1
  95. package/dist/lib/providers/xai.js +17 -26
  96. package/dist/lib/server/errors.d.ts +1 -1
  97. package/dist/lib/server/errors.js +2 -2
  98. package/dist/lib/server/index.d.ts +2 -2
  99. package/dist/lib/server/index.js +5 -3
  100. package/dist/lib/server/middleware/rateLimit.d.ts +0 -4
  101. package/dist/lib/server/middleware/rateLimit.js +0 -4
  102. package/dist/lib/types/errors.d.ts +35 -0
  103. package/dist/lib/types/index.d.ts +0 -1
  104. package/dist/lib/types/index.js +0 -1
  105. package/dist/lib/types/providers.d.ts +66 -11
  106. package/dist/lib/utils/errorClassifier.d.ts +30 -0
  107. package/dist/lib/utils/errorClassifier.js +94 -0
  108. package/dist/lib/utils/fileDetector.js +6 -43
  109. package/dist/lib/utils/providerConfig.d.ts +0 -8
  110. package/dist/lib/utils/providerConfig.js +0 -37
  111. package/dist/lib/utils/providerHealth.d.ts +42 -7
  112. package/dist/lib/utils/providerHealth.js +115 -122
  113. package/dist/lib/utils/providerUtils.js +21 -87
  114. package/dist/models/anthropicModels.d.ts +0 -7
  115. package/dist/models/anthropicModels.js +0 -9
  116. package/dist/neurolink.js +25 -37
  117. package/dist/providers/amazonBedrock/client.js +34 -16
  118. package/dist/providers/amazonSagemaker.d.ts +1 -1
  119. package/dist/providers/anthropic/client.js +39 -34
  120. package/dist/providers/anthropic/constants.d.ts +0 -1
  121. package/dist/providers/anthropic/constants.js +0 -2
  122. package/dist/providers/anthropic/index.d.ts +0 -1
  123. package/dist/providers/anthropic/index.js +0 -1
  124. package/dist/providers/azureOpenai.js +17 -15
  125. package/dist/providers/cloudflare.js +12 -21
  126. package/dist/providers/cohere.js +31 -25
  127. package/dist/providers/deepseek.js +23 -26
  128. package/dist/providers/fireworks.js +12 -21
  129. package/dist/providers/googleAiStudio/client.d.ts +2 -0
  130. package/dist/providers/googleAiStudio/client.js +39 -17
  131. package/dist/providers/googleAiStudio/index.d.ts +0 -1
  132. package/dist/providers/googleAiStudio/index.js +0 -1
  133. package/dist/providers/googleNativeGemini3/index.d.ts +0 -1
  134. package/dist/providers/googleNativeGemini3/index.js +0 -1
  135. package/dist/providers/googleVertex/client.d.ts +0 -51
  136. package/dist/providers/googleVertex/client.js +107 -777
  137. package/dist/providers/groq.js +19 -22
  138. package/dist/providers/huggingFace/client.d.ts +1 -1
  139. package/dist/providers/huggingFace/client.js +27 -25
  140. package/dist/providers/huggingFace/index.d.ts +0 -1
  141. package/dist/providers/huggingFace/index.js +0 -1
  142. package/dist/providers/jina.d.ts +0 -1
  143. package/dist/providers/jina.js +0 -1
  144. package/dist/providers/litellm/client.js +54 -39
  145. package/dist/providers/litellm/index.d.ts +0 -2
  146. package/dist/providers/litellm/index.js +0 -2
  147. package/dist/providers/llamaCpp.d.ts +1 -0
  148. package/dist/providers/llamaCpp.js +24 -18
  149. package/dist/providers/lmStudio.js +25 -42
  150. package/dist/providers/mistral.js +12 -24
  151. package/dist/providers/nvidiaNim/client.js +37 -34
  152. package/dist/providers/nvidiaNim/index.d.ts +0 -1
  153. package/dist/providers/nvidiaNim/index.js +0 -1
  154. package/dist/providers/ollama/client.js +51 -58
  155. package/dist/providers/ollama/index.d.ts +0 -1
  156. package/dist/providers/ollama/index.js +0 -1
  157. package/dist/providers/openAI/client.js +37 -40
  158. package/dist/providers/openAI/index.d.ts +0 -2
  159. package/dist/providers/openAI/index.js +0 -2
  160. package/dist/providers/openRouter/client.js +53 -47
  161. package/dist/providers/openRouter/utils.d.ts +0 -2
  162. package/dist/providers/openRouter/utils.js +0 -12
  163. package/dist/providers/openaiChatCompletionsBase.d.ts +9 -0
  164. package/dist/providers/openaiChatCompletionsBase.js +73 -16
  165. package/dist/providers/openaiCompatible/client.js +36 -32
  166. package/dist/providers/perplexity.d.ts +2 -1
  167. package/dist/providers/perplexity.js +14 -22
  168. package/dist/providers/replicate.d.ts +0 -1
  169. package/dist/providers/replicate.js +22 -9
  170. package/dist/providers/sagemaker/language-model.d.ts +2 -2
  171. package/dist/providers/togetherAi.js +12 -21
  172. package/dist/providers/voyage.d.ts +0 -1
  173. package/dist/providers/voyage.js +0 -1
  174. package/dist/providers/xai.js +17 -26
  175. package/dist/server/errors.d.ts +1 -1
  176. package/dist/server/errors.js +2 -2
  177. package/dist/server/index.d.ts +2 -2
  178. package/dist/server/index.js +5 -3
  179. package/dist/server/middleware/rateLimit.d.ts +0 -4
  180. package/dist/server/middleware/rateLimit.js +0 -4
  181. package/dist/types/errors.d.ts +35 -0
  182. package/dist/types/index.d.ts +0 -1
  183. package/dist/types/index.js +0 -1
  184. package/dist/types/providers.d.ts +66 -11
  185. package/dist/utils/errorClassifier.d.ts +30 -0
  186. package/dist/utils/errorClassifier.js +93 -0
  187. package/dist/utils/fileDetector.js +6 -43
  188. package/dist/utils/providerConfig.d.ts +0 -8
  189. package/dist/utils/providerConfig.js +0 -37
  190. package/dist/utils/providerHealth.d.ts +42 -7
  191. package/dist/utils/providerHealth.js +115 -122
  192. package/dist/utils/providerUtils.js +21 -87
  193. package/package.json +21 -75
  194. package/dist/lib/providers/anthropic/utils.d.ts +0 -7
  195. package/dist/lib/providers/anthropic/utils.js +0 -150
  196. package/dist/lib/providers/googleAiStudio/utils.d.ts +0 -2
  197. package/dist/lib/providers/googleAiStudio/utils.js +0 -19
  198. package/dist/lib/providers/googleNativeGemini3/constants.d.ts +0 -1
  199. package/dist/lib/providers/googleNativeGemini3/constants.js +0 -2
  200. package/dist/lib/providers/huggingFace/utils.d.ts +0 -2
  201. package/dist/lib/providers/huggingFace/utils.js +0 -8
  202. package/dist/lib/providers/index.d.ts +0 -33
  203. package/dist/lib/providers/index.js +0 -34
  204. package/dist/lib/providers/litellm/constants.d.ts +0 -1
  205. package/dist/lib/providers/litellm/constants.js +0 -3
  206. package/dist/lib/providers/litellm/utils.d.ts +0 -5
  207. package/dist/lib/providers/litellm/utils.js +0 -11
  208. package/dist/lib/providers/nvidiaNim/utils.d.ts +0 -9
  209. package/dist/lib/providers/nvidiaNim/utils.js +0 -101
  210. package/dist/lib/providers/ollama/utils.d.ts +0 -8
  211. package/dist/lib/providers/ollama/utils.js +0 -43
  212. package/dist/lib/providers/openAI/constants.d.ts +0 -1
  213. package/dist/lib/providers/openAI/constants.js +0 -3
  214. package/dist/lib/providers/openAI/utils.d.ts +0 -2
  215. package/dist/lib/providers/openAI/utils.js +0 -8
  216. package/dist/lib/types/universalProviderOptions.d.ts +0 -89
  217. package/dist/lib/types/universalProviderOptions.js +0 -55
  218. package/dist/providers/anthropic/utils.d.ts +0 -7
  219. package/dist/providers/anthropic/utils.js +0 -149
  220. package/dist/providers/googleAiStudio/utils.d.ts +0 -2
  221. package/dist/providers/googleAiStudio/utils.js +0 -18
  222. package/dist/providers/googleNativeGemini3/constants.d.ts +0 -1
  223. package/dist/providers/googleNativeGemini3/constants.js +0 -1
  224. package/dist/providers/huggingFace/utils.d.ts +0 -2
  225. package/dist/providers/huggingFace/utils.js +0 -7
  226. package/dist/providers/index.d.ts +0 -33
  227. package/dist/providers/index.js +0 -33
  228. package/dist/providers/litellm/constants.d.ts +0 -1
  229. package/dist/providers/litellm/constants.js +0 -2
  230. package/dist/providers/litellm/utils.d.ts +0 -5
  231. package/dist/providers/litellm/utils.js +0 -10
  232. package/dist/providers/nvidiaNim/utils.d.ts +0 -9
  233. package/dist/providers/nvidiaNim/utils.js +0 -100
  234. package/dist/providers/ollama/utils.d.ts +0 -8
  235. package/dist/providers/ollama/utils.js +0 -42
  236. package/dist/providers/openAI/constants.d.ts +0 -1
  237. package/dist/providers/openAI/constants.js +0 -2
  238. package/dist/providers/openAI/utils.d.ts +0 -2
  239. package/dist/providers/openAI/utils.js +0 -7
  240. package/dist/types/universalProviderOptions.d.ts +0 -89
  241. package/dist/types/universalProviderOptions.js +0 -54
@@ -96,6 +96,7 @@ export type NeurolinkCredentials = {
96
96
  };
97
97
  googleAiStudio?: {
98
98
  apiKey?: string;
99
+ baseURL?: string;
99
100
  };
100
101
  vertex?: {
101
102
  projectId?: string;
@@ -200,6 +201,8 @@ export type NeurolinkCredentials = {
200
201
  replicate?: {
201
202
  apiToken?: string;
202
203
  baseUrl?: string;
204
+ apiKey?: string;
205
+ baseURL?: string;
203
206
  };
204
207
  voyage?: {
205
208
  apiKey?: string;
@@ -886,6 +889,8 @@ export type GenAIClient = {
886
889
  export type GoogleGenAIHttpOptions = {
887
890
  /** Custom fetch implementation for proxy support */
888
891
  fetch?: typeof fetch;
892
+ /** Override the API base URL (e.g. a corporate proxy or mock endpoint) */
893
+ baseUrl?: string;
889
894
  };
890
895
  /**
891
896
  * Google GenAI constructor type
@@ -1531,17 +1536,6 @@ export declare namespace TelemetryTypes {
1531
1536
  recordException(exception: unknown): void;
1532
1537
  };
1533
1538
  }
1534
- /**
1535
- * OpenRouter provider configuration
1536
- */
1537
- export type OpenRouterConfig = {
1538
- /** OpenRouter API key */
1539
- apiKey: string;
1540
- /** HTTP Referer header for attribution on openrouter.ai/activity */
1541
- referer?: string;
1542
- /** App name for X-Title header attribution */
1543
- appName?: string;
1544
- };
1545
1539
  /**
1546
1540
  * OpenRouter model information from /api/v1/models endpoint
1547
1541
  */
@@ -1686,6 +1680,67 @@ export type ProviderRegistration = {
1686
1680
  constructor: ProviderConstructor;
1687
1681
  defaultModel?: string;
1688
1682
  aliases?: string[];
1683
+ descriptor?: ProviderDescriptor;
1684
+ };
1685
+ /**
1686
+ * Single source of truth for one AI provider's static identity: how it's
1687
+ * addressed (name/aliases), how it's authenticated (credentialsKey/envVars),
1688
+ * what it defaults to (defaultModel), and how the rest of the codebase
1689
+ * should treat it (toolSupport/localRuntime/healthCheck). Every consumer
1690
+ * that used to hand-maintain its own provider table (CLI choices,
1691
+ * CREDENTIAL_KEY_MAP, env-var checks, health-check dispatch, auto-select
1692
+ * priority, PROMPT_ONLY_TOOL_PROVIDERS) derives from PROVIDER_DESCRIPTORS
1693
+ * instead. See src/lib/factories/providerDescriptors.ts for the data.
1694
+ */
1695
+ export type ProviderDescriptor = {
1696
+ /** Canonical identity — matches an AIProviderName enum member (never AUTO). */
1697
+ name: AIProviderName;
1698
+ /** Alternate spellings accepted by the CLI and the alias index (kebab-case, shorthand, legacy names). Does not include `name` itself. */
1699
+ aliases: readonly string[];
1700
+ /** Key into NeurolinkCredentials for per-call/per-instance credential overrides. */
1701
+ credentialsKey: keyof NeurolinkCredentials;
1702
+ /** Environment variables this provider reads at runtime. */
1703
+ envVars: {
1704
+ /** Primary identity/secret env var. Absent for providers with no required credential (Ollama, LM Studio, llama.cpp) or that use extraRequired instead of a single key (Vertex). */
1705
+ apiKey?: string;
1706
+ /** Alternate env vars accepted in place of apiKey, checked in order after apiKey. */
1707
+ fallbacks?: readonly string[];
1708
+ baseURL?: string;
1709
+ /** Alternate env vars accepted in place of baseURL. */
1710
+ baseURLFallbacks?: readonly string[];
1711
+ /** Env var that overrides the static defaultModel at runtime. */
1712
+ model?: string;
1713
+ /** Alternate env vars accepted in place of model, checked in order after model. */
1714
+ modelFallbacks?: readonly string[];
1715
+ /** Additional env vars required alongside apiKey (e.g. AWS secret key, Azure endpoint). */
1716
+ extraRequired?: readonly string[];
1717
+ /** Alternate ways to satisfy extraRequired when it isn't a plain env-var list (e.g. Vertex's file-path-OR-individual-fields auth). */
1718
+ extraRequiredFallbacks?: readonly string[];
1719
+ /** True when the provider is usable with zero configuration (local runtime with a documented default URL, or a documented non-secret default like LiteLLM's "sk-anything"). */
1720
+ optional?: boolean;
1721
+ };
1722
+ /**
1723
+ * Static fallback model. The empty string "" is a documented sentinel
1724
+ * meaning "no static default — resolved at runtime via envVars.model or
1725
+ * provider-side auto-discovery" (used by Bedrock, OpenAI-Compatible,
1726
+ * LM Studio, llama.cpp, matching how providerRegistry.ts already passes
1727
+ * `undefined` as their defaultModel argument today).
1728
+ */
1729
+ defaultModel: string;
1730
+ toolSupport: "native" | "prompt-only" | "none" | "model-dependent";
1731
+ /** True only for providers that run entirely on the caller's machine with no cloud account (Ollama, LM Studio, llama.cpp). LiteLLM is a local proxy but commonly points at cloud models, so it is deliberately false. */
1732
+ localRuntime: boolean;
1733
+ /** How ProviderHealthChecker should verify this provider is reachable. */
1734
+ healthCheck: "env-only" | "models-probe" | "live-generate";
1735
+ setupUrl?: string;
1736
+ timeouts?: {
1737
+ generateMs?: number;
1738
+ streamMs?: number;
1739
+ };
1740
+ /** Ascending priority (1 = tried first) in the auto-select fallback chain used by getBestProvider(). Undefined = not part of the auto-select chain. */
1741
+ autoSelectPriority?: number;
1742
+ /** Format-validation regex sourced from providerConfig.ts's API_KEY_FORMATS, when one exists for this provider. */
1743
+ apiKeyFormatPattern?: RegExp;
1689
1744
  };
1690
1745
  /** Minimal NeuroLink-like instance accepted by the image generation service. */
1691
1746
  export type NeuroLinkInstance = {
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Shared provider-error classification. Every provider's
3
+ * `formatProviderError(error)` delegates here instead of hand-rolling its
4
+ * own TimeoutError-check → .includes()-chain → `new XError(...)` ladder.
5
+ *
6
+ * `classifyProviderError` picks the Error subclass + message; it does NOT
7
+ * stamp statusCode/isRetryable/retryAfterMs onto the result — that
8
+ * passthrough already happens generically in
9
+ * `BaseProvider.handleProviderError()` (src/lib/core/baseProvider.ts) for
10
+ * every provider's returned error, migrated or not, so duplicating it here
11
+ * would risk the two copies disagreeing.
12
+ */
13
+ import { type ProviderErrorRule } from "../types/index.js";
14
+ /**
15
+ * Classify a raw provider error into a NeuroLink `ProviderError` subclass.
16
+ * `rules` are tried in order; the first match wins. `TimeoutError` is
17
+ * always handled first, ahead of any rule table — every provider treated
18
+ * it identically before this change, so it is not made overridable.
19
+ */
20
+ export declare function classifyProviderError(error: unknown, rules: ProviderErrorRule[], provider: string, modelName?: string): Error;
21
+ /**
22
+ * Generic fallback rule table covering the five categories every
23
+ * OpenAI-compatible provider already hand-rolled near-identically:
24
+ * auth (401), rate limit (429), model-not-found (404), network/connection
25
+ * errors, and 5xx server errors. Providers with a provider-specific auth
26
+ * message (naming the exact env var) prepend one override rule and spread
27
+ * this table after it — see errorClassifier usage in any migrated
28
+ * provider's formatProviderError for the pattern.
29
+ */
30
+ export declare const DEFAULT_ERROR_RULES: ProviderErrorRule[];
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Shared provider-error classification. Every provider's
3
+ * `formatProviderError(error)` delegates here instead of hand-rolling its
4
+ * own TimeoutError-check → .includes()-chain → `new XError(...)` ladder.
5
+ *
6
+ * `classifyProviderError` picks the Error subclass + message; it does NOT
7
+ * stamp statusCode/isRetryable/retryAfterMs onto the result — that
8
+ * passthrough already happens generically in
9
+ * `BaseProvider.handleProviderError()` (src/lib/core/baseProvider.ts) for
10
+ * every provider's returned error, migrated or not, so duplicating it here
11
+ * would risk the two copies disagreeing.
12
+ */
13
+ import { ProviderError, AuthenticationError, RateLimitError, InvalidModelError, NetworkError, } from "../types/index.js";
14
+ import { TimeoutError } from "./timeout.js";
15
+ import { duckTypedStatusCode } from "./providerRetry.js";
16
+ function buildErrorContext(error, provider, modelName) {
17
+ const record = error && typeof error === "object"
18
+ ? error
19
+ : undefined;
20
+ const message = typeof record?.message === "string"
21
+ ? record.message
22
+ : error instanceof Error
23
+ ? error.message
24
+ : "Unknown error";
25
+ return {
26
+ error,
27
+ message,
28
+ statusCode: duckTypedStatusCode(error),
29
+ errorName: typeof record?.name === "string" ? record.name : undefined,
30
+ errorCode: typeof record?.code === "string" ? record.code : undefined,
31
+ provider,
32
+ modelName,
33
+ };
34
+ }
35
+ /**
36
+ * Classify a raw provider error into a NeuroLink `ProviderError` subclass.
37
+ * `rules` are tried in order; the first match wins. `TimeoutError` is
38
+ * always handled first, ahead of any rule table — every provider treated
39
+ * it identically before this change, so it is not made overridable.
40
+ */
41
+ export function classifyProviderError(error, rules, provider, modelName) {
42
+ if (error instanceof TimeoutError) {
43
+ return new NetworkError(`Request timed out: ${error.message}`, provider);
44
+ }
45
+ const ctx = buildErrorContext(error, provider, modelName);
46
+ const rule = rules.find((r) => r.match(ctx));
47
+ if (!rule) {
48
+ return new ProviderError(`${provider} error: ${ctx.message}`, provider);
49
+ }
50
+ const message = typeof rule.message === "function" ? rule.message(ctx) : rule.message;
51
+ return new rule.errorClass(message, provider);
52
+ }
53
+ /**
54
+ * Generic fallback rule table covering the five categories every
55
+ * OpenAI-compatible provider already hand-rolled near-identically:
56
+ * auth (401), rate limit (429), model-not-found (404), network/connection
57
+ * errors, and 5xx server errors. Providers with a provider-specific auth
58
+ * message (naming the exact env var) prepend one override rule and spread
59
+ * this table after it — see errorClassifier usage in any migrated
60
+ * provider's formatProviderError for the pattern.
61
+ */
62
+ export const DEFAULT_ERROR_RULES = [
63
+ {
64
+ match: (ctx) => ctx.statusCode === 401 ||
65
+ /API_KEY_INVALID|Invalid API key|Unauthorized|invalid_api_key/i.test(ctx.message),
66
+ errorClass: AuthenticationError,
67
+ message: (ctx) => `Invalid ${ctx.provider} API key. Please check your credentials.`,
68
+ },
69
+ {
70
+ match: (ctx) => ctx.statusCode === 429 || /rate limit/i.test(ctx.message),
71
+ errorClass: RateLimitError,
72
+ message: (ctx) => `${ctx.provider} rate limit exceeded. Please try again later.`,
73
+ },
74
+ {
75
+ match: (ctx) => ctx.statusCode === 404 ||
76
+ /model_not_found|model not found/i.test(ctx.message),
77
+ errorClass: InvalidModelError,
78
+ message: (ctx) => ctx.modelName
79
+ ? `${ctx.provider} model '${ctx.modelName}' not found.`
80
+ : `${ctx.provider} model not found.`,
81
+ },
82
+ {
83
+ match: (ctx) => /ECONNRESET|ENOTFOUND|ECONNREFUSED|ETIMEDOUT|network|connection/i.test(ctx.message),
84
+ errorClass: NetworkError,
85
+ message: (ctx) => `Connection error: ${ctx.message}`,
86
+ },
87
+ {
88
+ match: (ctx) => (ctx.statusCode !== undefined && ctx.statusCode >= 500) ||
89
+ /\b5\d\d\b|server error/i.test(ctx.message),
90
+ errorClass: ProviderError,
91
+ message: (ctx) => `${ctx.provider} server error: ${ctx.message}`,
92
+ },
93
+ ];
94
+ //# sourceMappingURL=errorClassifier.js.map
@@ -26,6 +26,7 @@ import { fileTypeForExtension, lookupByMimeType, normalizeExtension, } from "../
26
26
  import { LANGUAGE_MAP } from "../processors/config/languageMap.js";
27
27
  import { getMimeTypeForExtension, TEXT_EXTENSION_MIME_MAP, } from "../processors/config/mimeConstants.js";
28
28
  import { CSVProcessor } from "./csvProcessor.js";
29
+ import { withRetry } from "../core/infrastructure/retry.js";
29
30
  import { ImageProcessor } from "./imageProcessor.js";
30
31
  import { detectIsoBmffImageMimeType, hasFtypBoxSignature } from "./isoBmff.js";
31
32
  import { logger } from "./logger.js";
@@ -34,11 +35,6 @@ import { withTimeout } from "./errorHandling.js";
34
35
  import { normalizeUrlForCache, redactUrlForError, sanitizeErrorCause, } from "./logSanitize.js";
35
36
  import { mimeHintToExtension, mimeHintToFileType, normalizeMimeHint, } from "./mimeTypeHints.js";
36
37
  import { PDFProcessor } from "./pdfProcessor.js";
37
- /**
38
- * Default retry configuration constants
39
- */
40
- const DEFAULT_MAX_RETRIES = 3;
41
- const DEFAULT_RETRY_DELAY = 1000; // milliseconds
42
38
  /**
43
39
  * Short-TTL cache of URL → Content-Type (#323). A URL is commonly detected more
44
40
  * than once (repeated multimodal prompts reuse the same asset URL); caching the
@@ -202,41 +198,6 @@ function isRetryableNetworkError(error) {
202
198
  ];
203
199
  return transientKeywords.some((keyword) => errorMessage.includes(keyword));
204
200
  }
205
- /**
206
- * Execute an operation with automatic retry logic on transient network errors
207
- *
208
- * @param operation - Async function to execute
209
- * @param options - Retry configuration options
210
- * @returns Promise resolving to the operation result
211
- * @throws Error if all retry attempts fail or error is non-retryable
212
- */
213
- async function withRetry(operation, options = {}) {
214
- const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
215
- const retryDelay = options.retryDelay ?? DEFAULT_RETRY_DELAY;
216
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
217
- try {
218
- return await operation();
219
- }
220
- catch (error) {
221
- const isRetryable = isRetryableNetworkError(error);
222
- const isLastAttempt = attempt === maxRetries;
223
- if (!isRetryable || isLastAttempt) {
224
- throw error;
225
- }
226
- // Calculate exponential backoff delay
227
- const delay = retryDelay * 2 ** attempt;
228
- logger.debug("Retrying network operation after transient error", {
229
- attempt: attempt + 1,
230
- maxRetries,
231
- delay,
232
- error: error instanceof Error ? error.message : String(error),
233
- });
234
- await new Promise((resolve) => setTimeout(resolve, delay));
235
- }
236
- }
237
- // TypeScript exhaustiveness check - should never reach here
238
- throw new Error("Retry logic failed unexpectedly");
239
- }
240
201
  /**
241
202
  * Check if text has JSON markers (starts with { or [ and ends with corresponding closing bracket)
242
203
  */
@@ -1542,8 +1503,6 @@ export class FileDetector {
1542
1503
  static async loadFromURL(url, options) {
1543
1504
  const maxSize = options?.maxSize || 200 * 1024 * 1024; // 200MB default (matches Curator memory-safety cap)
1544
1505
  const timeout = options?.timeout || FileDetector.DEFAULT_NETWORK_TIMEOUT;
1545
- const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
1546
- const retryDelay = options?.retryDelay ?? DEFAULT_RETRY_DELAY;
1547
1506
  // #317: pre-flight HEAD to reject an oversized file BEFORE downloading any
1548
1507
  // body. content-length is advisory (chunked responses omit it), so a
1549
1508
  // missing/invalid header — or a server that refuses HEAD — falls through to
@@ -1641,7 +1600,11 @@ export class FileDetector {
1641
1600
  }
1642
1601
  throw redacted;
1643
1602
  }
1644
- }, { maxRetries, retryDelay });
1603
+ }, {
1604
+ maxRetries: options?.maxRetries ?? 3,
1605
+ baseDelayMs: options?.retryDelay ?? 1000,
1606
+ shouldRetry: isRetryableNetworkError,
1607
+ });
1645
1608
  }
1646
1609
  /**
1647
1610
  * Load file from filesystem path
@@ -115,14 +115,6 @@ export declare function createDeepSeekConfig(): ProviderConfigOptions;
115
115
  * Creates NVIDIA NIM provider configuration
116
116
  */
117
117
  export declare function createNvidiaNimConfig(): ProviderConfigOptions;
118
- /**
119
- * Creates LM Studio provider configuration (local server)
120
- */
121
- export declare function createLmStudioConfig(): ProviderConfigOptions;
122
- /**
123
- * Creates llama.cpp provider configuration (local server)
124
- */
125
- export declare function createLlamaCppConfig(): ProviderConfigOptions;
126
118
  /**
127
119
  * Creates xAI Grok provider configuration.
128
120
  */
@@ -411,43 +411,6 @@ export function createNvidiaNimConfig() {
411
411
  ],
412
412
  };
413
413
  }
414
- /**
415
- * Creates LM Studio provider configuration (local server)
416
- */
417
- export function createLmStudioConfig() {
418
- return {
419
- providerName: "LM Studio",
420
- envVarName: "LM_STUDIO_BASE_URL",
421
- setupUrl: "https://lmstudio.ai/",
422
- description: "LM Studio server URL",
423
- instructions: [
424
- "1. Install LM Studio: https://lmstudio.ai/",
425
- "2. Open LM Studio and download a model (e.g. Llama 3.2 3B Instruct)",
426
- '3. Click "Local Server" → Start Server',
427
- "4. Default URL is http://localhost:1234/v1 (override via LM_STUDIO_BASE_URL)",
428
- ],
429
- // Base URL is optional — defaults to http://localhost:1234/v1 if unset.
430
- optional: true,
431
- };
432
- }
433
- /**
434
- * Creates llama.cpp provider configuration (local server)
435
- */
436
- export function createLlamaCppConfig() {
437
- return {
438
- providerName: "llama.cpp",
439
- envVarName: "LLAMACPP_BASE_URL",
440
- setupUrl: "https://github.com/ggerganov/llama.cpp",
441
- description: "llama.cpp server URL",
442
- instructions: [
443
- "1. Build llama.cpp: https://github.com/ggerganov/llama.cpp#build",
444
- "2. Run: ./llama-server -m model.gguf --port 8080",
445
- "3. Default URL is http://localhost:8080/v1 (override via LLAMACPP_BASE_URL)",
446
- ],
447
- // Base URL is optional — defaults to http://localhost:8080/v1 if unset.
448
- optional: true,
449
- };
450
- }
451
414
  /**
452
415
  * Creates xAI Grok provider configuration.
453
416
  */
@@ -36,21 +36,56 @@ export declare class ProviderHealthChecker {
36
36
  */
37
37
  private static checkModelAvailability;
38
38
  /**
39
- * Get required environment variables for a provider
40
- */
41
- private static getRequiredEnvironmentVariables;
39
+ * Providers whose credential model can't be reduced to "every one of
40
+ * these exact env vars must be literally set" — the check in
41
+ * checkEnvironmentConfiguration() below ANDs every entry in the
42
+ * returned list together, which can't express Vertex's file-OR-
43
+ * individual-creds-OR-service-account auth, Bedrock's AWS SDK default
44
+ * provider chain (profile / IAM role, no env vars at all), or
45
+ * LiteLLM's documented zero-config local proxy. Their real requirement
46
+ * is validated by checkProviderSpecificConfig()'s dedicated per-provider
47
+ * checks instead — matches the original hand-written switch's
48
+ * deliberate `return []` for exactly these three. Naively deriving
49
+ * [apiKey, ...extraRequired] from the descriptor here (as for the other
50
+ * 27 providers) would make checkEnvironmentConfiguration() push a false
51
+ * "missing environment variables" issue — and therefore isHealthy=false
52
+ * — for legitimate fallback-based Vertex auth, AWS_PROFILE/IAM-role
53
+ * Bedrock auth, and unauthenticated local LiteLLM proxies. See
54
+ * hasProviderEnvVars() in providerUtils.ts for the equivalent OR-aware
55
+ * check used for auto-select gating.
56
+ */
57
+ private static readonly ENV_CHECK_DELEGATED_TO_SPECIFIC_CONFIG;
42
58
  /**
43
- * Get API key environment variable for a provider
59
+ * Get required environment variables for a provider
44
60
  */
45
- private static getApiKeyEnvironmentVariable;
61
+ static getRequiredEnvironmentVariables(providerName: string): string[];
62
+ /**
63
+ * Get API key environment variable for a provider.
64
+ *
65
+ * Dead code at its sole call site today (checkApiKeyValidity() early-
66
+ * returns for VERTEX/OLLAMA/BEDROCK/LITELLM before reaching this), but
67
+ * now `static` (public) so a future direct caller is plausible — hence
68
+ * the two intentional diffs from the original hand-written switch are
69
+ * documented here rather than left silent:
70
+ * - vertex: old switch returned "GOOGLE_APPLICATION_CREDENTIALS"
71
+ * (one of several valid auth vars); the descriptor's `envVars.apiKey`
72
+ * is "GOOGLE_CLOUD_PROJECT_ID" instead — the actual identity var for
73
+ * the provider, not one specific credential-supply mechanism.
74
+ * - ollama: old switch returned "OLLAMA_BASE_URL"; the descriptor has
75
+ * no `envVars.apiKey` for ollama (it's a local, unauthenticated
76
+ * runtime), so this now returns "".
77
+ * Both are kept deliberately (semantically truer identity vars) rather
78
+ * than reproduced byte-for-byte from the old switch.
79
+ */
80
+ static getApiKeyEnvironmentVariable(providerName: string): string;
46
81
  /**
47
82
  * Validate API key format for a provider
48
83
  */
49
- private static validateApiKeyFormat;
84
+ static validateApiKeyFormat(providerName: string, apiKey: string): boolean;
50
85
  /**
51
86
  * Get health check endpoint for connectivity testing
52
87
  */
53
- private static getProviderHealthEndpoint;
88
+ static getProviderHealthEndpoint(providerName: string): string | null;
54
89
  /**
55
90
  * Provider-specific configuration checks
56
91
  */