@juspay/neurolink 10.8.4 → 10.8.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.
Files changed (217) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/browser/neurolink.min.js +497 -478
  3. package/dist/factories/providerRegistry.js +11 -11
  4. package/dist/lib/factories/providerRegistry.js +11 -11
  5. package/dist/lib/providers/{amazonBedrock.d.ts → amazonBedrock/client.d.ts} +4 -4
  6. package/dist/{providers/amazonBedrock.js → lib/providers/amazonBedrock/client.js} +15 -18
  7. package/dist/lib/providers/amazonBedrock/constants.d.ts +1 -0
  8. package/dist/lib/providers/amazonBedrock/constants.js +3 -0
  9. package/dist/lib/providers/amazonBedrock/index.d.ts +3 -0
  10. package/dist/lib/providers/amazonBedrock/index.js +4 -0
  11. package/dist/lib/providers/amazonBedrock/utils.d.ts +1 -0
  12. package/dist/lib/providers/amazonBedrock/utils.js +4 -0
  13. package/dist/{providers/anthropic.d.ts → lib/providers/anthropic/client.d.ts} +6 -21
  14. package/dist/{providers/anthropic.js → lib/providers/anthropic/client.js} +28 -45
  15. package/dist/lib/providers/anthropic/constants.d.ts +4 -0
  16. package/dist/lib/providers/anthropic/constants.js +9 -0
  17. package/dist/lib/providers/anthropic/index.d.ts +3 -0
  18. package/dist/lib/providers/anthropic/index.js +4 -0
  19. package/dist/lib/providers/anthropic/utils.d.ts +7 -0
  20. package/dist/lib/providers/anthropic/utils.js +150 -0
  21. package/dist/lib/providers/{googleAiStudio.d.ts → googleAiStudio/client.d.ts} +4 -4
  22. package/dist/{providers/googleAiStudio.js → lib/providers/googleAiStudio/client.js} +16 -15
  23. package/dist/lib/providers/googleAiStudio/index.d.ts +2 -0
  24. package/dist/lib/providers/googleAiStudio/index.js +3 -0
  25. package/dist/lib/providers/googleAiStudio/utils.d.ts +2 -0
  26. package/dist/lib/providers/googleAiStudio/utils.js +19 -0
  27. package/dist/lib/providers/googleNativeGemini3/constants.d.ts +1 -0
  28. package/dist/lib/providers/googleNativeGemini3/constants.js +2 -0
  29. package/dist/lib/providers/googleNativeGemini3/index.d.ts +2 -0
  30. package/dist/lib/providers/googleNativeGemini3/index.js +3 -0
  31. package/dist/lib/providers/{googleNativeGemini3.d.ts → googleNativeGemini3/utils.d.ts} +2 -2
  32. package/dist/lib/providers/{googleNativeGemini3.js → googleNativeGemini3/utils.js} +8 -8
  33. package/dist/{providers/googleVertex.d.ts → lib/providers/googleVertex/client.d.ts} +4 -4
  34. package/dist/lib/providers/{googleVertex.js → googleVertex/client.js} +32 -32
  35. package/dist/lib/providers/googleVertex/constants.d.ts +5 -0
  36. package/dist/lib/providers/googleVertex/constants.js +27 -0
  37. package/dist/lib/providers/googleVertex/index.d.ts +3 -0
  38. package/dist/lib/providers/googleVertex/index.js +4 -0
  39. package/dist/lib/providers/googleVertex/utils.d.ts +12 -0
  40. package/dist/lib/providers/googleVertex/utils.js +287 -0
  41. package/dist/lib/providers/{huggingFace.d.ts → huggingFace/client.d.ts} +3 -3
  42. package/dist/lib/providers/{huggingFace.js → huggingFace/client.js} +7 -7
  43. package/dist/lib/providers/huggingFace/index.d.ts +2 -0
  44. package/dist/lib/providers/huggingFace/index.js +3 -0
  45. package/dist/lib/providers/huggingFace/utils.d.ts +2 -0
  46. package/dist/lib/providers/huggingFace/utils.js +8 -0
  47. package/dist/lib/providers/index.d.ts +10 -10
  48. package/dist/lib/providers/index.js +10 -10
  49. package/dist/{providers/litellm.d.ts → lib/providers/litellm/client.d.ts} +3 -3
  50. package/dist/lib/providers/{litellm.js → litellm/client.js} +13 -13
  51. package/dist/lib/providers/litellm/constants.d.ts +1 -0
  52. package/dist/lib/providers/litellm/constants.js +3 -0
  53. package/dist/lib/providers/litellm/index.d.ts +3 -0
  54. package/dist/lib/providers/litellm/index.js +4 -0
  55. package/dist/lib/providers/litellm/utils.d.ts +5 -0
  56. package/dist/lib/providers/litellm/utils.js +11 -0
  57. package/dist/{providers/nvidiaNim.d.ts → lib/providers/nvidiaNim/client.d.ts} +3 -3
  58. package/dist/lib/providers/{nvidiaNim.js → nvidiaNim/client.js} +8 -8
  59. package/dist/lib/providers/nvidiaNim/constants.d.ts +1 -0
  60. package/dist/lib/providers/nvidiaNim/constants.js +2 -0
  61. package/dist/lib/providers/nvidiaNim/index.d.ts +3 -0
  62. package/dist/lib/providers/nvidiaNim/index.js +4 -0
  63. package/dist/lib/providers/nvidiaNim/utils.d.ts +9 -0
  64. package/dist/lib/providers/nvidiaNim/utils.js +101 -0
  65. package/dist/{providers/ollama.d.ts → lib/providers/ollama/client.d.ts} +3 -3
  66. package/dist/{providers/ollama.js → lib/providers/ollama/client.js} +10 -13
  67. package/dist/lib/providers/ollama/constants.d.ts +4 -0
  68. package/dist/lib/providers/ollama/constants.js +6 -0
  69. package/dist/lib/providers/ollama/index.d.ts +3 -0
  70. package/dist/lib/providers/ollama/index.js +4 -0
  71. package/dist/lib/providers/ollama/utils.d.ts +8 -0
  72. package/dist/lib/providers/ollama/utils.js +43 -0
  73. package/dist/lib/providers/{openAI.d.ts → openAI/client.d.ts} +3 -3
  74. package/dist/lib/providers/{openAI.js → openAI/client.js} +13 -13
  75. package/dist/lib/providers/openAI/constants.d.ts +1 -0
  76. package/dist/lib/providers/openAI/constants.js +3 -0
  77. package/dist/lib/providers/openAI/index.d.ts +3 -0
  78. package/dist/lib/providers/openAI/index.js +4 -0
  79. package/dist/lib/providers/openAI/utils.d.ts +2 -0
  80. package/dist/lib/providers/openAI/utils.js +8 -0
  81. package/dist/lib/providers/{openRouter.d.ts → openRouter/client.d.ts} +3 -3
  82. package/dist/{providers/openRouter.js → lib/providers/openRouter/client.js} +13 -29
  83. package/dist/lib/providers/openRouter/constants.d.ts +1 -0
  84. package/dist/lib/providers/openRouter/constants.js +2 -0
  85. package/dist/lib/providers/openRouter/index.d.ts +3 -0
  86. package/dist/lib/providers/openRouter/index.js +4 -0
  87. package/dist/lib/providers/openRouter/utils.d.ts +3 -0
  88. package/dist/lib/providers/openRouter/utils.js +18 -0
  89. package/dist/lib/providers/{openaiCompatible.d.ts → openaiCompatible/client.d.ts} +2 -2
  90. package/dist/{providers/openaiCompatible.js → lib/providers/openaiCompatible/client.js} +8 -22
  91. package/dist/lib/providers/openaiCompatible/constants.d.ts +1 -0
  92. package/dist/lib/providers/openaiCompatible/constants.js +2 -0
  93. package/dist/lib/providers/openaiCompatible/index.d.ts +3 -0
  94. package/dist/lib/providers/openaiCompatible/index.js +4 -0
  95. package/dist/lib/providers/openaiCompatible/utils.d.ts +5 -0
  96. package/dist/lib/providers/openaiCompatible/utils.js +17 -0
  97. package/dist/lib/proxy/modelRouter.d.ts +10 -0
  98. package/dist/lib/proxy/modelRouter.js +17 -0
  99. package/dist/lib/proxy/proxyConfig.js +46 -0
  100. package/dist/lib/proxy/routingPolicy.d.ts +4 -2
  101. package/dist/lib/proxy/routingPolicy.js +8 -5
  102. package/dist/lib/proxy/runtimeConfig.js +2 -0
  103. package/dist/lib/server/routes/claudeProxyRoutes.d.ts +52 -1
  104. package/dist/lib/server/routes/claudeProxyRoutes.js +467 -221
  105. package/dist/lib/server/routes/openaiProxyRoutes.js +1 -1
  106. package/dist/lib/types/errors.d.ts +5 -0
  107. package/dist/lib/types/proxy.d.ts +24 -0
  108. package/dist/lib/types/subscription.d.ts +4 -0
  109. package/dist/lib/utils/providerHealth.js +2 -1
  110. package/dist/lib/utils/providerUtils.js +2 -1
  111. package/dist/providers/{amazonBedrock.d.ts → amazonBedrock/client.d.ts} +4 -4
  112. package/dist/{lib/providers/amazonBedrock.js → providers/amazonBedrock/client.js} +14 -19
  113. package/dist/providers/amazonBedrock/constants.d.ts +1 -0
  114. package/dist/providers/amazonBedrock/constants.js +2 -0
  115. package/dist/providers/amazonBedrock/index.d.ts +3 -0
  116. package/dist/providers/amazonBedrock/index.js +3 -0
  117. package/dist/providers/amazonBedrock/utils.d.ts +1 -0
  118. package/dist/providers/amazonBedrock/utils.js +3 -0
  119. package/dist/{lib/providers/anthropic.d.ts → providers/anthropic/client.d.ts} +6 -21
  120. package/dist/{lib/providers/anthropic.js → providers/anthropic/client.js} +27 -46
  121. package/dist/providers/anthropic/constants.d.ts +4 -0
  122. package/dist/providers/anthropic/constants.js +8 -0
  123. package/dist/providers/anthropic/index.d.ts +3 -0
  124. package/dist/providers/anthropic/index.js +3 -0
  125. package/dist/providers/anthropic/utils.d.ts +7 -0
  126. package/dist/providers/anthropic/utils.js +149 -0
  127. package/dist/providers/{googleAiStudio.d.ts → googleAiStudio/client.d.ts} +4 -4
  128. package/dist/{lib/providers/googleAiStudio.js → providers/googleAiStudio/client.js} +15 -16
  129. package/dist/providers/googleAiStudio/index.d.ts +2 -0
  130. package/dist/providers/googleAiStudio/index.js +2 -0
  131. package/dist/providers/googleAiStudio/utils.d.ts +2 -0
  132. package/dist/providers/googleAiStudio/utils.js +18 -0
  133. package/dist/providers/googleNativeGemini3/constants.d.ts +1 -0
  134. package/dist/providers/googleNativeGemini3/constants.js +1 -0
  135. package/dist/providers/googleNativeGemini3/index.d.ts +2 -0
  136. package/dist/providers/googleNativeGemini3/index.js +2 -0
  137. package/dist/providers/{googleNativeGemini3.d.ts → googleNativeGemini3/utils.d.ts} +2 -2
  138. package/dist/providers/{googleNativeGemini3.js → googleNativeGemini3/utils.js} +7 -7
  139. package/dist/{lib/providers/googleVertex.d.ts → providers/googleVertex/client.d.ts} +4 -4
  140. package/dist/providers/{googleVertex.js → googleVertex/client.js} +31 -31
  141. package/dist/providers/googleVertex/constants.d.ts +5 -0
  142. package/dist/providers/googleVertex/constants.js +26 -0
  143. package/dist/providers/googleVertex/index.d.ts +3 -0
  144. package/dist/providers/googleVertex/index.js +3 -0
  145. package/dist/providers/googleVertex/utils.d.ts +12 -0
  146. package/dist/providers/googleVertex/utils.js +286 -0
  147. package/dist/providers/{huggingFace.d.ts → huggingFace/client.d.ts} +3 -3
  148. package/dist/providers/{huggingFace.js → huggingFace/client.js} +6 -6
  149. package/dist/providers/huggingFace/index.d.ts +2 -0
  150. package/dist/providers/huggingFace/index.js +2 -0
  151. package/dist/providers/huggingFace/utils.d.ts +2 -0
  152. package/dist/providers/huggingFace/utils.js +7 -0
  153. package/dist/providers/index.d.ts +10 -10
  154. package/dist/providers/index.js +10 -10
  155. package/dist/{lib/providers/litellm.d.ts → providers/litellm/client.d.ts} +3 -3
  156. package/dist/providers/{litellm.js → litellm/client.js} +12 -12
  157. package/dist/providers/litellm/constants.d.ts +1 -0
  158. package/dist/providers/litellm/constants.js +2 -0
  159. package/dist/providers/litellm/index.d.ts +3 -0
  160. package/dist/providers/litellm/index.js +3 -0
  161. package/dist/providers/litellm/utils.d.ts +5 -0
  162. package/dist/providers/litellm/utils.js +10 -0
  163. package/dist/{lib/providers/nvidiaNim.d.ts → providers/nvidiaNim/client.d.ts} +3 -3
  164. package/dist/providers/{nvidiaNim.js → nvidiaNim/client.js} +7 -7
  165. package/dist/providers/nvidiaNim/constants.d.ts +1 -0
  166. package/dist/providers/nvidiaNim/constants.js +1 -0
  167. package/dist/providers/nvidiaNim/index.d.ts +3 -0
  168. package/dist/providers/nvidiaNim/index.js +3 -0
  169. package/dist/providers/nvidiaNim/utils.d.ts +9 -0
  170. package/dist/providers/nvidiaNim/utils.js +100 -0
  171. package/dist/{lib/providers/ollama.d.ts → providers/ollama/client.d.ts} +3 -3
  172. package/dist/{lib/providers/ollama.js → providers/ollama/client.js} +9 -14
  173. package/dist/providers/ollama/constants.d.ts +4 -0
  174. package/dist/providers/ollama/constants.js +5 -0
  175. package/dist/providers/ollama/index.d.ts +3 -0
  176. package/dist/providers/ollama/index.js +3 -0
  177. package/dist/providers/ollama/utils.d.ts +8 -0
  178. package/dist/providers/ollama/utils.js +42 -0
  179. package/dist/providers/{openAI.d.ts → openAI/client.d.ts} +3 -3
  180. package/dist/providers/{openAI.js → openAI/client.js} +12 -12
  181. package/dist/providers/openAI/constants.d.ts +1 -0
  182. package/dist/providers/openAI/constants.js +2 -0
  183. package/dist/providers/openAI/index.d.ts +3 -0
  184. package/dist/providers/openAI/index.js +3 -0
  185. package/dist/providers/openAI/utils.d.ts +2 -0
  186. package/dist/providers/openAI/utils.js +7 -0
  187. package/dist/providers/{openRouter.d.ts → openRouter/client.d.ts} +3 -3
  188. package/dist/{lib/providers/openRouter.js → providers/openRouter/client.js} +12 -30
  189. package/dist/providers/openRouter/constants.d.ts +1 -0
  190. package/dist/providers/openRouter/constants.js +1 -0
  191. package/dist/providers/openRouter/index.d.ts +3 -0
  192. package/dist/providers/openRouter/index.js +3 -0
  193. package/dist/providers/openRouter/utils.d.ts +3 -0
  194. package/dist/providers/openRouter/utils.js +17 -0
  195. package/dist/providers/{openaiCompatible.d.ts → openaiCompatible/client.d.ts} +2 -2
  196. package/dist/{lib/providers/openaiCompatible.js → providers/openaiCompatible/client.js} +7 -23
  197. package/dist/providers/openaiCompatible/constants.d.ts +1 -0
  198. package/dist/providers/openaiCompatible/constants.js +1 -0
  199. package/dist/providers/openaiCompatible/index.d.ts +3 -0
  200. package/dist/providers/openaiCompatible/index.js +3 -0
  201. package/dist/providers/openaiCompatible/utils.d.ts +5 -0
  202. package/dist/providers/openaiCompatible/utils.js +16 -0
  203. package/dist/proxy/modelRouter.d.ts +10 -0
  204. package/dist/proxy/modelRouter.js +17 -0
  205. package/dist/proxy/proxyConfig.js +46 -0
  206. package/dist/proxy/routingPolicy.d.ts +4 -2
  207. package/dist/proxy/routingPolicy.js +8 -5
  208. package/dist/proxy/runtimeConfig.js +2 -0
  209. package/dist/server/routes/claudeProxyRoutes.d.ts +52 -1
  210. package/dist/server/routes/claudeProxyRoutes.js +467 -221
  211. package/dist/server/routes/openaiProxyRoutes.js +1 -1
  212. package/dist/types/errors.d.ts +5 -0
  213. package/dist/types/proxy.d.ts +24 -0
  214. package/dist/types/subscription.d.ts +4 -0
  215. package/dist/utils/providerHealth.js +2 -1
  216. package/dist/utils/providerUtils.js +2 -1
  217. package/package.json +3 -1
@@ -0,0 +1,4 @@
1
+ export * from "./client.js";
2
+ export * from "./constants.js";
3
+ export * from "./utils.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ import type { OpenRouterConfig } from "../../types/index.js";
2
+ export declare const getOpenRouterConfig: () => OpenRouterConfig;
3
+ export declare const getDefaultOpenRouterModel: () => string;
@@ -0,0 +1,18 @@
1
+ import { OpenRouterModels } from "../../constants/enums.js";
2
+ import { getProviderModel } from "../../utils/providerConfig.js";
3
+ export const getOpenRouterConfig = () => {
4
+ const apiKey = process.env.OPENROUTER_API_KEY;
5
+ if (!apiKey) {
6
+ throw new Error("OPENROUTER_API_KEY environment variable is required. " +
7
+ "Get your API key at https://openrouter.ai/keys");
8
+ }
9
+ return {
10
+ apiKey,
11
+ referer: process.env.OPENROUTER_REFERER,
12
+ appName: process.env.OPENROUTER_APP_NAME,
13
+ };
14
+ };
15
+ export const getDefaultOpenRouterModel = () => {
16
+ return getProviderModel("OPENROUTER_MODEL", OpenRouterModels.CLAUDE_SONNET_4_5);
17
+ };
18
+ //# sourceMappingURL=utils.js.map
@@ -1,5 +1,5 @@
1
- import type { AIProviderName } from "../constants/enums.js";
2
- import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
1
+ import type { AIProviderName } from "../../constants/enums.js";
2
+ import { OpenAIChatCompletionsProvider } from "../openaiChatCompletionsBase.js";
3
3
  /**
4
4
  * OpenAI Compatible Provider — direct HTTP, no AI SDK.
5
5
  *
@@ -1,25 +1,10 @@
1
- import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
2
- import { logger } from "../utils/logger.js";
3
- import { redactUrlCredentials } from "../utils/logSanitize.js";
4
- import { TimeoutError } from "../utils/timeout.js";
5
- import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
6
- const FALLBACK_OPENAI_COMPATIBLE_MODEL = "gpt-3.5-turbo";
7
- const getOpenAICompatibleConfig = () => {
8
- const baseURL = process.env.OPENAI_COMPATIBLE_BASE_URL;
9
- const apiKey = process.env.OPENAI_COMPATIBLE_API_KEY;
10
- if (!baseURL) {
11
- throw new Error("OPENAI_COMPATIBLE_BASE_URL environment variable is required. " +
12
- "Please set it to your OpenAI-compatible endpoint (e.g., https://api.openrouter.ai/api/v1)");
13
- }
14
- if (!apiKey) {
15
- throw new Error("OPENAI_COMPATIBLE_API_KEY environment variable is required. " +
16
- "Please set it to your API key for the OpenAI-compatible service.");
17
- }
18
- return { baseURL, apiKey };
19
- };
20
- const getDefaultOpenAICompatibleModel = () => {
21
- return process.env.OPENAI_COMPATIBLE_MODEL || undefined;
22
- };
1
+ import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../../types/index.js";
2
+ import { logger } from "../../utils/logger.js";
3
+ import { redactUrlCredentials } from "../../utils/logSanitize.js";
4
+ import { TimeoutError } from "../../utils/timeout.js";
5
+ import { OpenAIChatCompletionsProvider } from "../openaiChatCompletionsBase.js";
6
+ import { FALLBACK_OPENAI_COMPATIBLE_MODEL } from "./constants.js";
7
+ import { getDefaultOpenAICompatibleModel, getOpenAICompatibleConfig, } from "./utils.js";
23
8
  /**
24
9
  * OpenAI Compatible Provider — direct HTTP, no AI SDK.
25
10
  *
@@ -99,3 +84,4 @@ export class OpenAICompatibleProvider extends OpenAIChatCompletionsProvider {
99
84
  return new ProviderError(`OpenAI Compatible error: ${errorRecord?.message || "Unknown error"}`, "openai-compatible");
100
85
  }
101
86
  }
87
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ export declare const FALLBACK_OPENAI_COMPATIBLE_MODEL = "gpt-3.5-turbo";
@@ -0,0 +1,2 @@
1
+ export const FALLBACK_OPENAI_COMPATIBLE_MODEL = "gpt-3.5-turbo";
2
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,3 @@
1
+ export * from "./client.js";
2
+ export * from "./constants.js";
3
+ export * from "./utils.js";
@@ -0,0 +1,4 @@
1
+ export * from "./client.js";
2
+ export * from "./constants.js";
3
+ export * from "./utils.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,5 @@
1
+ export declare const getOpenAICompatibleConfig: () => {
2
+ baseURL: string;
3
+ apiKey: string;
4
+ };
5
+ export declare const getDefaultOpenAICompatibleModel: () => string | undefined;
@@ -0,0 +1,17 @@
1
+ export const getOpenAICompatibleConfig = () => {
2
+ const baseURL = process.env.OPENAI_COMPATIBLE_BASE_URL;
3
+ const apiKey = process.env.OPENAI_COMPATIBLE_API_KEY;
4
+ if (!baseURL) {
5
+ throw new Error("OPENAI_COMPATIBLE_BASE_URL environment variable is required. " +
6
+ "Please set it to your OpenAI-compatible endpoint (e.g., https://api.openrouter.ai/api/v1)");
7
+ }
8
+ if (!apiKey) {
9
+ throw new Error("OPENAI_COMPATIBLE_API_KEY environment variable is required. " +
10
+ "Please set it to your API key for the OpenAI-compatible service.");
11
+ }
12
+ return { baseURL, apiKey };
13
+ };
14
+ export const getDefaultOpenAICompatibleModel = () => {
15
+ return process.env.OPENAI_COMPATIBLE_MODEL || undefined;
16
+ };
17
+ //# sourceMappingURL=utils.js.map
@@ -1,12 +1,22 @@
1
1
  import type { FallbackEntry, ModelMapping, ProxyRoutingConfig, RouteResult } from "../types/index.js";
2
+ /** Default and accepted range for concurrent upstream requests per OAuth account. */
3
+ export declare const MIN_MAX_INFLIGHT_PER_ACCOUNT = 1;
4
+ export declare const MAX_MAX_INFLIGHT_PER_ACCOUNT = 20;
5
+ export declare const DEFAULT_MAX_INFLIGHT_PER_ACCOUNT = 2;
2
6
  export declare class ModelRouter {
3
7
  private readonly mappings;
4
8
  private readonly passthrough;
5
9
  private readonly fallback;
10
+ private readonly autoFallback;
11
+ private readonly maxInflightPerAccount;
6
12
  constructor(config: ProxyRoutingConfig);
7
13
  resolve(requestedModel: string): RouteResult;
8
14
  isClaudeTarget(requestedModel: string): boolean;
9
15
  getFallbackChain(): FallbackEntry[];
16
+ /** Whether translation-layer auto-provider fallback is explicitly enabled. */
17
+ isAutoFallbackEnabled(): boolean;
18
+ /** Maximum concurrent upstream requests admitted for each OAuth account. */
19
+ getMaxInflightPerAccount(): number;
10
20
  /** Return the raw model mapping entries (used by /v1/models). */
11
21
  getModelMappings(): ModelMapping[];
12
22
  /** Return models configured for passthrough (used by /v1/models). */
@@ -1,11 +1,20 @@
1
+ /** Default and accepted range for concurrent upstream requests per OAuth account. */
2
+ export const MIN_MAX_INFLIGHT_PER_ACCOUNT = 1;
3
+ export const MAX_MAX_INFLIGHT_PER_ACCOUNT = 20;
4
+ export const DEFAULT_MAX_INFLIGHT_PER_ACCOUNT = 2;
1
5
  export class ModelRouter {
2
6
  mappings;
3
7
  passthrough;
4
8
  fallback;
9
+ autoFallback;
10
+ maxInflightPerAccount;
5
11
  constructor(config) {
6
12
  this.mappings = new Map(config.modelMappings.map((m) => [m.from, m]));
7
13
  this.passthrough = new Set(config.passthroughModels ?? []);
8
14
  this.fallback = config.fallbackChain;
15
+ this.autoFallback = config.autoFallback === true;
16
+ this.maxInflightPerAccount =
17
+ config.maxInflightPerAccount ?? DEFAULT_MAX_INFLIGHT_PER_ACCOUNT;
9
18
  }
10
19
  resolve(requestedModel) {
11
20
  const mapping = this.mappings.get(requestedModel);
@@ -29,6 +38,14 @@ export class ModelRouter {
29
38
  getFallbackChain() {
30
39
  return this.fallback;
31
40
  }
41
+ /** Whether translation-layer auto-provider fallback is explicitly enabled. */
42
+ isAutoFallbackEnabled() {
43
+ return this.autoFallback;
44
+ }
45
+ /** Maximum concurrent upstream requests admitted for each OAuth account. */
46
+ getMaxInflightPerAccount() {
47
+ return this.maxInflightPerAccount;
48
+ }
32
49
  /** Return the raw model mapping entries (used by /v1/models). */
33
50
  getModelMappings() {
34
51
  return Array.from(this.mappings.values());
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import { readFile } from "node:fs/promises";
14
14
  import { extname } from "node:path";
15
+ import { MAX_MAX_INFLIGHT_PER_ACCOUNT, MIN_MAX_INFLIGHT_PER_ACCOUNT, } from "./modelRouter.js";
15
16
  import { logger } from "../utils/logger.js";
16
17
  // ---------------------------------------------------------------------------
17
18
  // Environment variable resolution
@@ -237,6 +238,24 @@ export function validateProxyConfig(config) {
237
238
  normalizedQuotaRouting !== "false") {
238
239
  errors.push("routing.quota-routing must be a boolean");
239
240
  }
241
+ const rawAutoFallback = routing["auto-fallback"] ?? routing.autoFallback;
242
+ const normalizedAutoFallback = typeof rawAutoFallback === "string"
243
+ ? rawAutoFallback.trim().toLowerCase()
244
+ : undefined;
245
+ if (rawAutoFallback !== undefined &&
246
+ typeof rawAutoFallback !== "boolean" &&
247
+ normalizedAutoFallback !== "true" &&
248
+ normalizedAutoFallback !== "false") {
249
+ errors.push("routing.auto-fallback must be a boolean");
250
+ }
251
+ const rawMaxInflight = routing["max-inflight-per-account"] ?? routing.maxInflightPerAccount;
252
+ if (rawMaxInflight !== undefined &&
253
+ (typeof rawMaxInflight !== "number" ||
254
+ !Number.isInteger(rawMaxInflight) ||
255
+ rawMaxInflight < MIN_MAX_INFLIGHT_PER_ACCOUNT ||
256
+ rawMaxInflight > MAX_MAX_INFLIGHT_PER_ACCOUNT)) {
257
+ errors.push("routing.max-inflight-per-account must be an integer between 1 and 20");
258
+ }
240
259
  const rawSessionSoftLimit = routing["session-soft-limit"] ?? routing.sessionSoftLimit;
241
260
  if (rawSessionSoftLimit !== undefined) {
242
261
  const sessionSoftLimit = Number(rawSessionSoftLimit);
@@ -322,6 +341,8 @@ function warnPlaintextApiKeys(accounts) {
322
341
  * - `strategy` ("round-robin" | "fill-first")
323
342
  * - `model-mappings` / `modelMappings` — array of {from, to, provider}
324
343
  * - `fallback-chain` / `fallbackChain` — array of {provider, model}
344
+ * - `auto-fallback` / `autoFallback` — opt in to an unspecified provider
345
+ * - `max-inflight-per-account` / `maxInflightPerAccount` — concurrency cap
325
346
  * - `passthroughModels` / `passthrough-models` — array of model IDs
326
347
  * - `quota-routing` / `quotaRouting` — quota-aware fill-first ordering
327
348
  * - `session-soft-limit` / `sessionSoftLimit` — proactive handoff threshold
@@ -396,6 +417,31 @@ function parseRoutingConfig(raw) {
396
417
  logger.warn(`[proxy-config] Ignoring routing.quotaRouting: expected boolean, got ${typeof rawQuotaRouting}`);
397
418
  }
398
419
  }
420
+ const rawAutoFallback = raw["auto-fallback"] ?? raw.autoFallback;
421
+ if (rawAutoFallback !== undefined) {
422
+ if (typeof rawAutoFallback === "boolean") {
423
+ result.autoFallback = rawAutoFallback;
424
+ }
425
+ else if (typeof rawAutoFallback === "string" &&
426
+ ["true", "false"].includes(rawAutoFallback.trim().toLowerCase())) {
427
+ result.autoFallback = rawAutoFallback.trim().toLowerCase() === "true";
428
+ }
429
+ else {
430
+ logger.warn(`[proxy-config] Ignoring routing.autoFallback: expected boolean, got ${typeof rawAutoFallback}`);
431
+ }
432
+ }
433
+ const rawMaxInflight = raw["max-inflight-per-account"] ?? raw.maxInflightPerAccount;
434
+ if (rawMaxInflight !== undefined) {
435
+ if (typeof rawMaxInflight === "number" &&
436
+ Number.isInteger(rawMaxInflight) &&
437
+ rawMaxInflight >= MIN_MAX_INFLIGHT_PER_ACCOUNT &&
438
+ rawMaxInflight <= MAX_MAX_INFLIGHT_PER_ACCOUNT) {
439
+ result.maxInflightPerAccount = rawMaxInflight;
440
+ }
441
+ else {
442
+ logger.warn(`[proxy-config] Ignoring routing.maxInflightPerAccount: expected integer between 1 and 20, got ${String(rawMaxInflight)}`);
443
+ }
444
+ }
399
445
  const rawSessionSoftLimit = raw["session-soft-limit"] ?? raw.sessionSoftLimit;
400
446
  if (rawSessionSoftLimit !== undefined) {
401
447
  const sessionSoftLimit = Number(rawSessionSoftLimit);
@@ -4,12 +4,14 @@ export declare function inferClaudeProxyModelTier(modelName: string): ClaudeProx
4
4
  * Build a translation plan for a Claude-compatible proxy request.
5
5
  * The plan lists the primary provider followed by eligible fallback targets.
6
6
  * All configured fallback entries are always eligible — no contract-based gating.
7
- * When no fallback chain is configured, an "auto-provider" entry is appended.
7
+ * An "auto-provider" entry is appended only when explicitly enabled by the
8
+ * caller. This keeps an empty fallback chain from silently escaping to an
9
+ * unrelated provider.
8
10
  */
9
11
  export declare function buildProxyTranslationPlan(primary: {
10
12
  provider: string;
11
13
  model?: string;
12
- }, fallbackChain: FallbackEntry[], requestedModel: string, _parsed: ParsedClaudeRequest): ProxyTranslationPlan;
14
+ }, fallbackChain: FallbackEntry[], requestedModel: string, _parsed: ParsedClaudeRequest, allowAutoFallback?: boolean): ProxyTranslationPlan;
13
15
  /**
14
16
  * Parse the retry-after header from an upstream 429 response.
15
17
  * Returns milliseconds to wait, or 0 if no valid header present.
@@ -15,9 +15,11 @@ export function inferClaudeProxyModelTier(modelName) {
15
15
  * Build a translation plan for a Claude-compatible proxy request.
16
16
  * The plan lists the primary provider followed by eligible fallback targets.
17
17
  * All configured fallback entries are always eligible — no contract-based gating.
18
- * When no fallback chain is configured, an "auto-provider" entry is appended.
18
+ * An "auto-provider" entry is appended only when explicitly enabled by the
19
+ * caller. This keeps an empty fallback chain from silently escaping to an
20
+ * unrelated provider.
19
21
  */
20
- export function buildProxyTranslationPlan(primary, fallbackChain, requestedModel, _parsed) {
22
+ export function buildProxyTranslationPlan(primary, fallbackChain, requestedModel, _parsed, allowAutoFallback = false) {
21
23
  const attempts = [
22
24
  {
23
25
  provider: primary.provider,
@@ -36,9 +38,10 @@ export function buildProxyTranslationPlan(primary, fallbackChain, requestedModel
36
38
  label: `${fallback.provider}/${fallback.model}`,
37
39
  });
38
40
  }
39
- // Append auto-provider when no configured fallback chain exists,
40
- // or when all configured entries were deduped (same as primary).
41
- if (fallbackChain.length === 0 || attempts.length === 1) {
41
+ // A provider chosen by the translation layer is an explicit opt-in. It is
42
+ // intentionally not a default when configured entries are absent or deduped.
43
+ if (allowAutoFallback &&
44
+ (fallbackChain.length === 0 || attempts.length === 1)) {
42
45
  attempts.push({ label: "auto-provider" });
43
46
  }
44
47
  return {
@@ -212,6 +212,8 @@ async function buildCandidate(options, generation, allowMissingConfig, allowMiss
212
212
  strategy,
213
213
  modelMappings: routing.modelMappings ?? [],
214
214
  fallbackChain: routing.fallbackChain ?? [],
215
+ autoFallback: routing.autoFallback,
216
+ maxInflightPerAccount: routing.maxInflightPerAccount,
215
217
  passthroughModels: routing.passthroughModels,
216
218
  quotaRouting: routing.quotaRouting,
217
219
  sessionSoftLimit: routing.sessionSoftLimit,
@@ -12,7 +12,13 @@
12
12
  import { buildTranslationOptions } from "../../proxy/proxyTranslationEngine.js";
13
13
  import { ProxyTracer } from "../../proxy/proxyTracer.js";
14
14
  import { isPermanentRefreshFailure } from "../../proxy/tokenRefresh.js";
15
- import type { AccountAllowlist, AccountCooldownPlan, AccountQuota, AnthropicAttemptLogger, AnthropicAuthRetryResult, AnthropicLoopState, AnthropicSuccessResult, AnthropicUpstreamFetchResult, ClaudeFinalRequestLogger, ClaudeLoggedErrorBuilder, ClaudeRequest, ClaudeProxyRouteRuntimeOptions, ModelRouterInterface, ParsedClaudeError, ProxyAccountRoutingDecision, ProxyAccountSortMetrics, ProxyBodyCaptureLogger, ProxyPassthroughAccount, RouteGroup, RuntimeAccountState, ServerContext, StreamTerminalOutcome } from "../../types/index.js";
15
+ import type { AccountAllowlist, AccountAdmissionLease, AccountCooldownPlan, AccountQuota, AnthropicAttemptLogger, AnthropicAuthRetryResult, AnthropicLoopState, AnthropicNonOkResult, AnthropicSuccessResult, AnthropicUpstreamFetchResult, ClaudeFinalRequestLogger, ClaudeLoggedErrorBuilder, ClaudeRequest, ClaudeProxyRouteRuntimeOptions, ModelRouterInterface, ParsedClaudeError, ProxyAccountRoutingDecision, ProxyAccountSortMetrics, ProxyBodyCaptureLogger, ProxyPassthroughAccount, RouteGroup, RuntimeAccountState, ServerContext, StreamTerminalOutcome } from "../../types/index.js";
16
+ declare function tryAcquireAccountAdmission(accountKey: string, capacity: number): AccountAdmissionLease | undefined;
17
+ declare function acquireAccountAdmission(accountKey: string, capacity: number, abortSignal?: AbortSignal, timeoutMs?: number): Promise<AccountAdmissionLease | undefined>;
18
+ declare function acquireFirstAvailableAccountAdmission(accountKeys: string[], capacity: number, abortSignal?: AbortSignal, timeoutMs?: number): Promise<{
19
+ accountKey: string;
20
+ lease: AccountAdmissionLease;
21
+ } | undefined>;
16
22
  /** Resolve the configured primary's stable key to its current index in the
17
23
  * request's enabledAccounts list. Returns 0 (insertion-order fallback) when
18
24
  * no key is configured or the key cannot be matched (account disabled/
@@ -158,6 +164,7 @@ declare function handleAnthropicStreamingSuccessResponse(args: {
158
164
  upstreamSpan?: import("@opentelemetry/api").Span;
159
165
  logAttempt: AnthropicAttemptLogger;
160
166
  logProxyBody: ProxyBodyCaptureLogger;
167
+ onStreamTerminal?: () => void;
161
168
  logFinalRequest: (status: number, accountLabel: string, accountType: string, errorType?: string, errorMessage?: string, extra?: {
162
169
  inputTokens?: number;
163
170
  outputTokens?: number;
@@ -189,6 +196,7 @@ declare function handleAnthropicAuthRetry(args: {
189
196
  upstreamSpan?: import("@opentelemetry/api").Span;
190
197
  logAttempt: AnthropicAttemptLogger;
191
198
  logProxyBody: ProxyBodyCaptureLogger;
199
+ onStreamTerminal?: () => void;
192
200
  logFinalRequest: (status: number, accountLabel: string, accountType: string, errorType?: string, errorMessage?: string, extra?: {
193
201
  inputTokens?: number;
194
202
  outputTokens?: number;
@@ -210,6 +218,33 @@ declare function finalizeAnthropicTerminalFetchError(args: {
210
218
  logProxyBody: ProxyBodyCaptureLogger;
211
219
  logFinalRequest: ClaudeFinalRequestLogger;
212
220
  }): Response | unknown;
221
+ declare function handleAnthropicNonOkResponse(args: {
222
+ response: Response;
223
+ account: ProxyPassthroughAccount;
224
+ accountState: RuntimeAccountState;
225
+ enabledAccounts: ProxyPassthroughAccount[];
226
+ orderedAccounts: ProxyPassthroughAccount[];
227
+ tracer?: ProxyTracer;
228
+ requestStartTime: number;
229
+ fetchStartMs: number;
230
+ attemptNumber: number;
231
+ logAttempt: AnthropicAttemptLogger;
232
+ logProxyBody: ProxyBodyCaptureLogger;
233
+ logFinalRequest: (status: number, accountLabel: string, accountType: string, errorType?: string, errorMessage?: string, extra?: {
234
+ inputTokens?: number;
235
+ outputTokens?: number;
236
+ cacheCreationTokens?: number;
237
+ cacheReadTokens?: number;
238
+ }) => void;
239
+ lastError: unknown;
240
+ authFailureMessage: string | null;
241
+ sawTransientFailure: boolean;
242
+ invalidRequestFailure: {
243
+ status: number;
244
+ body: string;
245
+ contentType?: string;
246
+ } | null;
247
+ }): Promise<AnthropicNonOkResult>;
213
248
  /**
214
249
  * Detect Anthropic's anti-abuse / request-construction 429.
215
250
  *
@@ -284,6 +319,12 @@ export declare const buildProxyFallbackOptions: typeof buildTranslationOptions;
284
319
  * carry transient HTML responses (e.g. 520 pages) inside `error.message`.
285
320
  */
286
321
  export declare function isTransientHttpFailure(status: number, errBody: string): boolean;
322
+ /**
323
+ * An upstream overload is already a capacity signal. Retrying it on the same
324
+ * OAuth account only consumes its remaining concurrency and delays rotation.
325
+ */
326
+ export declare function isUpstreamOverload(status: number, errBody: string): boolean;
327
+ export declare function redactProviderErrorMessage(message: string): string;
287
328
  export declare const __testHooks: {
288
329
  resolveHomeIndex: typeof resolveHomeIndex;
289
330
  maybeResetPrimaryToHome: typeof maybeResetPrimaryToHome;
@@ -309,12 +350,22 @@ export declare const __testHooks: {
309
350
  isAntiAbuseConstruction429: typeof isAntiAbuseConstruction429;
310
351
  fetchAnthropicAccountResponse: typeof fetchAnthropicAccountResponse;
311
352
  finalizeAnthropicTerminalFetchError: typeof finalizeAnthropicTerminalFetchError;
353
+ handleAnthropicNonOkResponse: typeof handleAnthropicNonOkResponse;
312
354
  handleAnthropicAuthRetry: typeof handleAnthropicAuthRetry;
313
355
  handleAnthropicStreamingSuccessResponse: typeof handleAnthropicStreamingSuccessResponse;
314
356
  claimTransientRateLimitRetry: typeof claimTransientRateLimitRetry;
315
357
  claimTransientCooldownAdmission: typeof claimTransientCooldownAdmission;
316
358
  waitForTransientAccountAvailability: typeof waitForTransientAccountAvailability;
359
+ acquireAccountAdmission: typeof acquireAccountAdmission;
360
+ acquireFirstAvailableAccountAdmission: typeof acquireFirstAvailableAccountAdmission;
361
+ tryAcquireAccountAdmission: typeof tryAcquireAccountAdmission;
362
+ getAccountAdmissionSnapshot: (accountKey: string) => {
363
+ active: number;
364
+ waiting: number;
365
+ };
317
366
  describeTransportError: typeof describeTransportError;
367
+ redactProviderErrorMessage: typeof redactProviderErrorMessage;
368
+ isUpstreamOverload: typeof isUpstreamOverload;
318
369
  shouldAttemptClaudeFallback: typeof shouldAttemptClaudeFallback;
319
370
  executeClaudeFallbackWithRetry: typeof executeClaudeFallbackWithRetry;
320
371
  buildClaudeAnthropicFailureResponse: typeof buildClaudeAnthropicFailureResponse;