@juspay/neurolink 9.62.0 → 9.63.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.
- package/CHANGELOG.md +6 -0
- package/README.md +132 -109
- package/dist/browser/neurolink.min.js +257 -257
- package/dist/cli/commands/auth.d.ts +19 -0
- package/dist/cli/commands/auth.js +266 -0
- package/dist/cli/commands/proxy.js +77 -2
- package/dist/cli/factories/authCommandFactory.d.ts +8 -0
- package/dist/cli/factories/authCommandFactory.js +41 -0
- package/dist/lib/proxy/proxyConfig.js +14 -0
- package/dist/lib/server/routes/claudeProxyRoutes.d.ts +24 -2
- package/dist/lib/server/routes/claudeProxyRoutes.js +61 -9
- package/dist/lib/types/cli.d.ts +4 -0
- package/dist/lib/types/proxy.d.ts +23 -1
- package/dist/lib/types/subscription.d.ts +5 -0
- package/dist/proxy/proxyConfig.js +14 -0
- package/dist/server/routes/claudeProxyRoutes.d.ts +24 -2
- package/dist/server/routes/claudeProxyRoutes.js +61 -9
- package/dist/types/cli.d.ts +4 -0
- package/dist/types/proxy.d.ts +23 -1
- package/dist/types/subscription.d.ts +5 -0
- package/package.json +21 -2
|
@@ -47,6 +47,11 @@ const BLOCKED_UPSTREAM_HEADERS = new Set([
|
|
|
47
47
|
let primaryAccountIndex = 0;
|
|
48
48
|
/** Track account count so we can reset primaryAccountIndex when it changes. */
|
|
49
49
|
let lastKnownAccountCount = 0;
|
|
50
|
+
/** Stable account key (e.g. "anthropic:user@example.com") of the configured
|
|
51
|
+
* home/primary account. Set once at proxy boot from routing.primaryAccount.
|
|
52
|
+
* When undefined, home semantics fall back to enabledAccounts[0] (insertion
|
|
53
|
+
* order) — preserves pre-existing behavior. */
|
|
54
|
+
let configuredPrimaryAccountKey;
|
|
50
55
|
const MAX_AUTH_RETRIES = 5;
|
|
51
56
|
const MAX_CONSECUTIVE_REFRESH_FAILURES = 15;
|
|
52
57
|
const MAX_TRANSIENT_SAME_ACCOUNT_RETRIES = 2;
|
|
@@ -82,22 +87,40 @@ function advancePrimaryIfCurrent(accountKey, enabledCount, primaryAccountKey) {
|
|
|
82
87
|
}
|
|
83
88
|
primaryAccountIndex = (primaryAccountIndex + 1) % enabledCount;
|
|
84
89
|
}
|
|
85
|
-
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
90
|
+
/** Resolve the configured primary's stable key to its current index in the
|
|
91
|
+
* request's enabledAccounts list. Returns 0 (insertion-order fallback) when
|
|
92
|
+
* no key is configured or the key cannot be matched (account disabled/
|
|
93
|
+
* removed). The resolution is per-request because enabledAccounts membership
|
|
94
|
+
* can shift between requests. */
|
|
95
|
+
function resolveHomeIndex(enabledAccounts) {
|
|
96
|
+
if (!configuredPrimaryAccountKey) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
const idx = enabledAccounts.findIndex((a) => a.key === configuredPrimaryAccountKey);
|
|
100
|
+
return idx >= 0 ? idx : 0;
|
|
101
|
+
}
|
|
102
|
+
/** If the configured home primary is no longer cooling, reset
|
|
103
|
+
* primaryAccountIndex back to its index so traffic returns to the preferred
|
|
104
|
+
* account once its rate limit window expires. Called at the start of each
|
|
105
|
+
* request. Home is resolved fresh per call via resolveHomeIndex. */
|
|
88
106
|
function maybeResetPrimaryToHome(enabledAccounts) {
|
|
89
|
-
if (enabledAccounts.length <= 1
|
|
107
|
+
if (enabledAccounts.length <= 1) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const homeIndex = resolveHomeIndex(enabledAccounts);
|
|
111
|
+
if (primaryAccountIndex === homeIndex) {
|
|
90
112
|
return;
|
|
91
113
|
}
|
|
92
|
-
const
|
|
114
|
+
const homeAccount = enabledAccounts[homeIndex];
|
|
115
|
+
const homeState = accountRuntimeState.get(homeAccount.key);
|
|
93
116
|
if (!homeState ||
|
|
94
117
|
!homeState.coolingUntil ||
|
|
95
118
|
Date.now() >= homeState.coolingUntil) {
|
|
96
119
|
// Home account is no longer cooling — reset to it
|
|
97
|
-
primaryAccountIndex =
|
|
120
|
+
primaryAccountIndex = homeIndex;
|
|
98
121
|
if (homeState?.coolingUntil) {
|
|
99
122
|
homeState.coolingUntil = undefined;
|
|
100
|
-
logger.always(`[proxy] home primary account=${
|
|
123
|
+
logger.always(`[proxy] home primary account=${homeAccount.label} cooling expired, resetting primaryAccountIndex to ${homeIndex}`);
|
|
101
124
|
}
|
|
102
125
|
}
|
|
103
126
|
}
|
|
@@ -1239,7 +1262,7 @@ async function loadClaudeProxyAccounts(args) {
|
|
|
1239
1262
|
const orderedAccounts = [...enabledAccounts];
|
|
1240
1263
|
if (accountStrategy === "round-robin" &&
|
|
1241
1264
|
orderedAccounts.length !== lastKnownAccountCount) {
|
|
1242
|
-
primaryAccountIndex =
|
|
1265
|
+
primaryAccountIndex = resolveHomeIndex(orderedAccounts);
|
|
1243
1266
|
lastKnownAccountCount = orderedAccounts.length;
|
|
1244
1267
|
}
|
|
1245
1268
|
if (orderedAccounts.length > 1) {
|
|
@@ -3232,7 +3255,8 @@ async function handleAnthropicRoutedClaudeRequest(args) {
|
|
|
3232
3255
|
* @param basePath - Base path prefix (default: "" since Claude API uses /v1/...).
|
|
3233
3256
|
* @returns RouteGroup with Claude-compatible endpoints.
|
|
3234
3257
|
*/
|
|
3235
|
-
export function createClaudeProxyRoutes(modelRouter, basePath = "", accountStrategy = "fill-first", passthroughMode = false) {
|
|
3258
|
+
export function createClaudeProxyRoutes(modelRouter, basePath = "", accountStrategy = "fill-first", passthroughMode = false, primaryAccountKey) {
|
|
3259
|
+
configuredPrimaryAccountKey = primaryAccountKey;
|
|
3236
3260
|
return {
|
|
3237
3261
|
prefix: `${basePath}/v1`,
|
|
3238
3262
|
routes: [
|
|
@@ -3691,4 +3715,32 @@ export function isTransientHttpFailure(status, errBody) {
|
|
|
3691
3715
|
normalized.includes("cloudflare") ||
|
|
3692
3716
|
normalized.includes("internal server error"));
|
|
3693
3717
|
}
|
|
3718
|
+
// ---------------------------------------------------------------------------
|
|
3719
|
+
// Test hooks (not part of the public SDK API). Only consumed by the proxy
|
|
3720
|
+
// continuous-test-suite to drive the in-process resolver/reset logic without
|
|
3721
|
+
// spinning up a full proxy. Keep this surface small.
|
|
3722
|
+
// ---------------------------------------------------------------------------
|
|
3723
|
+
export const __testHooks = {
|
|
3724
|
+
resolveHomeIndex,
|
|
3725
|
+
maybeResetPrimaryToHome,
|
|
3726
|
+
setConfiguredPrimaryAccountKey: (key) => {
|
|
3727
|
+
configuredPrimaryAccountKey = key;
|
|
3728
|
+
},
|
|
3729
|
+
getConfiguredPrimaryAccountKey: () => configuredPrimaryAccountKey,
|
|
3730
|
+
setPrimaryAccountIndex: (index) => {
|
|
3731
|
+
primaryAccountIndex = index;
|
|
3732
|
+
},
|
|
3733
|
+
getPrimaryAccountIndex: () => primaryAccountIndex,
|
|
3734
|
+
setAccountRuntimeState: (key, state) => {
|
|
3735
|
+
const existing = accountRuntimeState.get(key) ?? getOrCreateRuntimeState(key);
|
|
3736
|
+
Object.assign(existing, state);
|
|
3737
|
+
accountRuntimeState.set(key, existing);
|
|
3738
|
+
},
|
|
3739
|
+
resetAllRuntimeState: () => {
|
|
3740
|
+
accountRuntimeState.clear();
|
|
3741
|
+
primaryAccountIndex = 0;
|
|
3742
|
+
lastKnownAccountCount = 0;
|
|
3743
|
+
configuredPrimaryAccountKey = undefined;
|
|
3744
|
+
},
|
|
3745
|
+
};
|
|
3694
3746
|
//# sourceMappingURL=claudeProxyRoutes.js.map
|
package/dist/lib/types/cli.d.ts
CHANGED
|
@@ -859,6 +859,10 @@ export type AuthCommandArgs = BaseCommandArgs & {
|
|
|
859
859
|
label?: string;
|
|
860
860
|
account?: string;
|
|
861
861
|
force?: boolean;
|
|
862
|
+
/** Path to the proxy config YAML, used by set-/get-/clear-primary */
|
|
863
|
+
config?: string;
|
|
864
|
+
/** Email passed to `auth set-primary <email>` */
|
|
865
|
+
email?: string;
|
|
862
866
|
/** Yargs positional arguments */
|
|
863
867
|
_?: (string | number)[];
|
|
864
868
|
};
|
|
@@ -981,13 +981,35 @@ export type UpdateState = {
|
|
|
981
981
|
lastUpdateAt: string | null;
|
|
982
982
|
lastUpdateVersion: string | null;
|
|
983
983
|
};
|
|
984
|
-
/** Shape of the dynamically-imported js-yaml module.
|
|
984
|
+
/** Shape of the dynamically-imported js-yaml module. `dump` is optional —
|
|
985
|
+
* read-only consumers (proxy config loader) only need `load`; writers
|
|
986
|
+
* (CLI primary-account commands) check `dump` before calling. */
|
|
985
987
|
export type YamlModule = {
|
|
986
988
|
load(content: string): unknown;
|
|
989
|
+
dump?: (obj: unknown, opts?: Record<string, unknown>) => string;
|
|
987
990
|
default?: {
|
|
988
991
|
load(content: string): unknown;
|
|
992
|
+
dump?: (obj: unknown, opts?: Record<string, unknown>) => string;
|
|
989
993
|
};
|
|
990
994
|
};
|
|
995
|
+
/** Snapshot of a parsed proxy config file used by CLI primary-account
|
|
996
|
+
* read/edit/write helpers. Tracks the original format and whether comments
|
|
997
|
+
* were present (so the CLI can warn that comments will not round-trip). */
|
|
998
|
+
export type CliProxyConfigDoc = {
|
|
999
|
+
data: Record<string, unknown>;
|
|
1000
|
+
format: "yaml" | "json";
|
|
1001
|
+
hadComments: boolean;
|
|
1002
|
+
};
|
|
1003
|
+
/** Primary-account info exposed by the proxy `/status` endpoint.
|
|
1004
|
+
* `source` is "configured" when the operator's `routing.primaryAccount` is
|
|
1005
|
+
* authenticated and enabled, otherwise "fallback" — either no primary set
|
|
1006
|
+
* or the configured one is missing/disabled. */
|
|
1007
|
+
export type ProxyStatusPrimaryAccount = {
|
|
1008
|
+
configured: string | null;
|
|
1009
|
+
key: string | null;
|
|
1010
|
+
label: string | null;
|
|
1011
|
+
source: "configured" | "fallback";
|
|
1012
|
+
};
|
|
991
1013
|
/** Parsed fields captured from a Claude Code client request body. */
|
|
992
1014
|
export type ClaudeSnapshotBody = {
|
|
993
1015
|
metadataUserId?: string;
|
|
@@ -909,6 +909,11 @@ export type ProxyRoutingConfig = {
|
|
|
909
909
|
modelMappings: ModelMapping[];
|
|
910
910
|
fallbackChain: FallbackEntry[];
|
|
911
911
|
passthroughModels?: string[];
|
|
912
|
+
/** Email/label of the Anthropic account that should be tried first
|
|
913
|
+
* ("home"). When absent, falls back to insertion-order index 0.
|
|
914
|
+
* Resolved per-request to a stable key (anthropic:<email>); does not
|
|
915
|
+
* encode an index. */
|
|
916
|
+
primaryAccount?: string;
|
|
912
917
|
};
|
|
913
918
|
/** Cloaking plugin config */
|
|
914
919
|
export type CloakingConfig = {
|
|
@@ -336,6 +336,20 @@ function parseRoutingConfig(raw) {
|
|
|
336
336
|
if (Array.isArray(rawPassthrough)) {
|
|
337
337
|
result.passthroughModels = rawPassthrough.map(String);
|
|
338
338
|
}
|
|
339
|
+
// Primary account (accept kebab-case or camelCase). Email or label of the
|
|
340
|
+
// Anthropic account that should be tried first ("home"). Resolved to a
|
|
341
|
+
// stable key (anthropic:<email>) at proxy boot; absence preserves the
|
|
342
|
+
// pre-existing insertion-order behavior.
|
|
343
|
+
const rawPrimary = (raw["primary-account"] ?? raw.primaryAccount);
|
|
344
|
+
if (rawPrimary !== undefined) {
|
|
345
|
+
if (typeof rawPrimary === "string" && rawPrimary.trim() !== "") {
|
|
346
|
+
result.primaryAccount = rawPrimary.trim();
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
logger.warn(`[proxy-config] Ignoring routing.primaryAccount: expected non-empty ` +
|
|
350
|
+
`string, got ${typeof rawPrimary}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
339
353
|
return result;
|
|
340
354
|
}
|
|
341
355
|
// ---------------------------------------------------------------------------
|
|
@@ -10,7 +10,18 @@
|
|
|
10
10
|
* Without a router, models are passed through to the Anthropic provider.
|
|
11
11
|
*/
|
|
12
12
|
import type { ModelRouter } from "../../proxy/modelRouter.js";
|
|
13
|
-
import type { ParsedClaudeError, ParsedClaudeRequest, RouteGroup } from "../../types/index.js";
|
|
13
|
+
import type { ParsedClaudeError, ParsedClaudeRequest, ProxyPassthroughAccount, RouteGroup, RuntimeAccountState } from "../../types/index.js";
|
|
14
|
+
/** Resolve the configured primary's stable key to its current index in the
|
|
15
|
+
* request's enabledAccounts list. Returns 0 (insertion-order fallback) when
|
|
16
|
+
* no key is configured or the key cannot be matched (account disabled/
|
|
17
|
+
* removed). The resolution is per-request because enabledAccounts membership
|
|
18
|
+
* can shift between requests. */
|
|
19
|
+
declare function resolveHomeIndex(enabledAccounts: ProxyPassthroughAccount[]): number;
|
|
20
|
+
/** If the configured home primary is no longer cooling, reset
|
|
21
|
+
* primaryAccountIndex back to its index so traffic returns to the preferred
|
|
22
|
+
* account once its rate limit window expires. Called at the start of each
|
|
23
|
+
* request. Home is resolved fresh per call via resolveHomeIndex. */
|
|
24
|
+
declare function maybeResetPrimaryToHome(enabledAccounts: ProxyPassthroughAccount[]): void;
|
|
14
25
|
/**
|
|
15
26
|
* Create Claude-compatible proxy routes.
|
|
16
27
|
*
|
|
@@ -21,7 +32,7 @@ import type { ParsedClaudeError, ParsedClaudeRequest, RouteGroup } from "../../t
|
|
|
21
32
|
* @param basePath - Base path prefix (default: "" since Claude API uses /v1/...).
|
|
22
33
|
* @returns RouteGroup with Claude-compatible endpoints.
|
|
23
34
|
*/
|
|
24
|
-
export declare function createClaudeProxyRoutes(modelRouter?: ModelRouter, basePath?: string, accountStrategy?: "round-robin" | "fill-first", passthroughMode?: boolean): RouteGroup;
|
|
35
|
+
export declare function createClaudeProxyRoutes(modelRouter?: ModelRouter, basePath?: string, accountStrategy?: "round-robin" | "fill-first", passthroughMode?: boolean, primaryAccountKey?: string): RouteGroup;
|
|
25
36
|
export declare function getTransientSameAccountRetryDelayMs(retryNumber: number): number;
|
|
26
37
|
/**
|
|
27
38
|
* Parse a Claude error payload when available.
|
|
@@ -42,3 +53,14 @@ export declare function buildProxyFallbackOptions(parsed: ParsedClaudeRequest, o
|
|
|
42
53
|
* carry transient HTML responses (e.g. 520 pages) inside `error.message`.
|
|
43
54
|
*/
|
|
44
55
|
export declare function isTransientHttpFailure(status: number, errBody: string): boolean;
|
|
56
|
+
export declare const __testHooks: {
|
|
57
|
+
resolveHomeIndex: typeof resolveHomeIndex;
|
|
58
|
+
maybeResetPrimaryToHome: typeof maybeResetPrimaryToHome;
|
|
59
|
+
setConfiguredPrimaryAccountKey: (key: string | undefined) => void;
|
|
60
|
+
getConfiguredPrimaryAccountKey: () => string | undefined;
|
|
61
|
+
setPrimaryAccountIndex: (index: number) => void;
|
|
62
|
+
getPrimaryAccountIndex: () => number;
|
|
63
|
+
setAccountRuntimeState: (key: string, state: Partial<RuntimeAccountState>) => void;
|
|
64
|
+
resetAllRuntimeState: () => void;
|
|
65
|
+
};
|
|
66
|
+
export {};
|
|
@@ -47,6 +47,11 @@ const BLOCKED_UPSTREAM_HEADERS = new Set([
|
|
|
47
47
|
let primaryAccountIndex = 0;
|
|
48
48
|
/** Track account count so we can reset primaryAccountIndex when it changes. */
|
|
49
49
|
let lastKnownAccountCount = 0;
|
|
50
|
+
/** Stable account key (e.g. "anthropic:user@example.com") of the configured
|
|
51
|
+
* home/primary account. Set once at proxy boot from routing.primaryAccount.
|
|
52
|
+
* When undefined, home semantics fall back to enabledAccounts[0] (insertion
|
|
53
|
+
* order) — preserves pre-existing behavior. */
|
|
54
|
+
let configuredPrimaryAccountKey;
|
|
50
55
|
const MAX_AUTH_RETRIES = 5;
|
|
51
56
|
const MAX_CONSECUTIVE_REFRESH_FAILURES = 15;
|
|
52
57
|
const MAX_TRANSIENT_SAME_ACCOUNT_RETRIES = 2;
|
|
@@ -82,22 +87,40 @@ function advancePrimaryIfCurrent(accountKey, enabledCount, primaryAccountKey) {
|
|
|
82
87
|
}
|
|
83
88
|
primaryAccountIndex = (primaryAccountIndex + 1) % enabledCount;
|
|
84
89
|
}
|
|
85
|
-
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
90
|
+
/** Resolve the configured primary's stable key to its current index in the
|
|
91
|
+
* request's enabledAccounts list. Returns 0 (insertion-order fallback) when
|
|
92
|
+
* no key is configured or the key cannot be matched (account disabled/
|
|
93
|
+
* removed). The resolution is per-request because enabledAccounts membership
|
|
94
|
+
* can shift between requests. */
|
|
95
|
+
function resolveHomeIndex(enabledAccounts) {
|
|
96
|
+
if (!configuredPrimaryAccountKey) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
const idx = enabledAccounts.findIndex((a) => a.key === configuredPrimaryAccountKey);
|
|
100
|
+
return idx >= 0 ? idx : 0;
|
|
101
|
+
}
|
|
102
|
+
/** If the configured home primary is no longer cooling, reset
|
|
103
|
+
* primaryAccountIndex back to its index so traffic returns to the preferred
|
|
104
|
+
* account once its rate limit window expires. Called at the start of each
|
|
105
|
+
* request. Home is resolved fresh per call via resolveHomeIndex. */
|
|
88
106
|
function maybeResetPrimaryToHome(enabledAccounts) {
|
|
89
|
-
if (enabledAccounts.length <= 1
|
|
107
|
+
if (enabledAccounts.length <= 1) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const homeIndex = resolveHomeIndex(enabledAccounts);
|
|
111
|
+
if (primaryAccountIndex === homeIndex) {
|
|
90
112
|
return;
|
|
91
113
|
}
|
|
92
|
-
const
|
|
114
|
+
const homeAccount = enabledAccounts[homeIndex];
|
|
115
|
+
const homeState = accountRuntimeState.get(homeAccount.key);
|
|
93
116
|
if (!homeState ||
|
|
94
117
|
!homeState.coolingUntil ||
|
|
95
118
|
Date.now() >= homeState.coolingUntil) {
|
|
96
119
|
// Home account is no longer cooling — reset to it
|
|
97
|
-
primaryAccountIndex =
|
|
120
|
+
primaryAccountIndex = homeIndex;
|
|
98
121
|
if (homeState?.coolingUntil) {
|
|
99
122
|
homeState.coolingUntil = undefined;
|
|
100
|
-
logger.always(`[proxy] home primary account=${
|
|
123
|
+
logger.always(`[proxy] home primary account=${homeAccount.label} cooling expired, resetting primaryAccountIndex to ${homeIndex}`);
|
|
101
124
|
}
|
|
102
125
|
}
|
|
103
126
|
}
|
|
@@ -1239,7 +1262,7 @@ async function loadClaudeProxyAccounts(args) {
|
|
|
1239
1262
|
const orderedAccounts = [...enabledAccounts];
|
|
1240
1263
|
if (accountStrategy === "round-robin" &&
|
|
1241
1264
|
orderedAccounts.length !== lastKnownAccountCount) {
|
|
1242
|
-
primaryAccountIndex =
|
|
1265
|
+
primaryAccountIndex = resolveHomeIndex(orderedAccounts);
|
|
1243
1266
|
lastKnownAccountCount = orderedAccounts.length;
|
|
1244
1267
|
}
|
|
1245
1268
|
if (orderedAccounts.length > 1) {
|
|
@@ -3232,7 +3255,8 @@ async function handleAnthropicRoutedClaudeRequest(args) {
|
|
|
3232
3255
|
* @param basePath - Base path prefix (default: "" since Claude API uses /v1/...).
|
|
3233
3256
|
* @returns RouteGroup with Claude-compatible endpoints.
|
|
3234
3257
|
*/
|
|
3235
|
-
export function createClaudeProxyRoutes(modelRouter, basePath = "", accountStrategy = "fill-first", passthroughMode = false) {
|
|
3258
|
+
export function createClaudeProxyRoutes(modelRouter, basePath = "", accountStrategy = "fill-first", passthroughMode = false, primaryAccountKey) {
|
|
3259
|
+
configuredPrimaryAccountKey = primaryAccountKey;
|
|
3236
3260
|
return {
|
|
3237
3261
|
prefix: `${basePath}/v1`,
|
|
3238
3262
|
routes: [
|
|
@@ -3691,3 +3715,31 @@ export function isTransientHttpFailure(status, errBody) {
|
|
|
3691
3715
|
normalized.includes("cloudflare") ||
|
|
3692
3716
|
normalized.includes("internal server error"));
|
|
3693
3717
|
}
|
|
3718
|
+
// ---------------------------------------------------------------------------
|
|
3719
|
+
// Test hooks (not part of the public SDK API). Only consumed by the proxy
|
|
3720
|
+
// continuous-test-suite to drive the in-process resolver/reset logic without
|
|
3721
|
+
// spinning up a full proxy. Keep this surface small.
|
|
3722
|
+
// ---------------------------------------------------------------------------
|
|
3723
|
+
export const __testHooks = {
|
|
3724
|
+
resolveHomeIndex,
|
|
3725
|
+
maybeResetPrimaryToHome,
|
|
3726
|
+
setConfiguredPrimaryAccountKey: (key) => {
|
|
3727
|
+
configuredPrimaryAccountKey = key;
|
|
3728
|
+
},
|
|
3729
|
+
getConfiguredPrimaryAccountKey: () => configuredPrimaryAccountKey,
|
|
3730
|
+
setPrimaryAccountIndex: (index) => {
|
|
3731
|
+
primaryAccountIndex = index;
|
|
3732
|
+
},
|
|
3733
|
+
getPrimaryAccountIndex: () => primaryAccountIndex,
|
|
3734
|
+
setAccountRuntimeState: (key, state) => {
|
|
3735
|
+
const existing = accountRuntimeState.get(key) ?? getOrCreateRuntimeState(key);
|
|
3736
|
+
Object.assign(existing, state);
|
|
3737
|
+
accountRuntimeState.set(key, existing);
|
|
3738
|
+
},
|
|
3739
|
+
resetAllRuntimeState: () => {
|
|
3740
|
+
accountRuntimeState.clear();
|
|
3741
|
+
primaryAccountIndex = 0;
|
|
3742
|
+
lastKnownAccountCount = 0;
|
|
3743
|
+
configuredPrimaryAccountKey = undefined;
|
|
3744
|
+
},
|
|
3745
|
+
};
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -859,6 +859,10 @@ export type AuthCommandArgs = BaseCommandArgs & {
|
|
|
859
859
|
label?: string;
|
|
860
860
|
account?: string;
|
|
861
861
|
force?: boolean;
|
|
862
|
+
/** Path to the proxy config YAML, used by set-/get-/clear-primary */
|
|
863
|
+
config?: string;
|
|
864
|
+
/** Email passed to `auth set-primary <email>` */
|
|
865
|
+
email?: string;
|
|
862
866
|
/** Yargs positional arguments */
|
|
863
867
|
_?: (string | number)[];
|
|
864
868
|
};
|
package/dist/types/proxy.d.ts
CHANGED
|
@@ -981,13 +981,35 @@ export type UpdateState = {
|
|
|
981
981
|
lastUpdateAt: string | null;
|
|
982
982
|
lastUpdateVersion: string | null;
|
|
983
983
|
};
|
|
984
|
-
/** Shape of the dynamically-imported js-yaml module.
|
|
984
|
+
/** Shape of the dynamically-imported js-yaml module. `dump` is optional —
|
|
985
|
+
* read-only consumers (proxy config loader) only need `load`; writers
|
|
986
|
+
* (CLI primary-account commands) check `dump` before calling. */
|
|
985
987
|
export type YamlModule = {
|
|
986
988
|
load(content: string): unknown;
|
|
989
|
+
dump?: (obj: unknown, opts?: Record<string, unknown>) => string;
|
|
987
990
|
default?: {
|
|
988
991
|
load(content: string): unknown;
|
|
992
|
+
dump?: (obj: unknown, opts?: Record<string, unknown>) => string;
|
|
989
993
|
};
|
|
990
994
|
};
|
|
995
|
+
/** Snapshot of a parsed proxy config file used by CLI primary-account
|
|
996
|
+
* read/edit/write helpers. Tracks the original format and whether comments
|
|
997
|
+
* were present (so the CLI can warn that comments will not round-trip). */
|
|
998
|
+
export type CliProxyConfigDoc = {
|
|
999
|
+
data: Record<string, unknown>;
|
|
1000
|
+
format: "yaml" | "json";
|
|
1001
|
+
hadComments: boolean;
|
|
1002
|
+
};
|
|
1003
|
+
/** Primary-account info exposed by the proxy `/status` endpoint.
|
|
1004
|
+
* `source` is "configured" when the operator's `routing.primaryAccount` is
|
|
1005
|
+
* authenticated and enabled, otherwise "fallback" — either no primary set
|
|
1006
|
+
* or the configured one is missing/disabled. */
|
|
1007
|
+
export type ProxyStatusPrimaryAccount = {
|
|
1008
|
+
configured: string | null;
|
|
1009
|
+
key: string | null;
|
|
1010
|
+
label: string | null;
|
|
1011
|
+
source: "configured" | "fallback";
|
|
1012
|
+
};
|
|
991
1013
|
/** Parsed fields captured from a Claude Code client request body. */
|
|
992
1014
|
export type ClaudeSnapshotBody = {
|
|
993
1015
|
metadataUserId?: string;
|
|
@@ -909,6 +909,11 @@ export type ProxyRoutingConfig = {
|
|
|
909
909
|
modelMappings: ModelMapping[];
|
|
910
910
|
fallbackChain: FallbackEntry[];
|
|
911
911
|
passthroughModels?: string[];
|
|
912
|
+
/** Email/label of the Anthropic account that should be tried first
|
|
913
|
+
* ("home"). When absent, falls back to insertion-order index 0.
|
|
914
|
+
* Resolved per-request to a stable key (anthropic:<email>); does not
|
|
915
|
+
* encode an index. */
|
|
916
|
+
primaryAccount?: string;
|
|
912
917
|
};
|
|
913
918
|
/** Cloaking plugin config */
|
|
914
919
|
export type CloakingConfig = {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.63.0",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
|
-
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI.
|
|
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": {
|
|
7
7
|
"name": "Juspay Technologies",
|
|
8
8
|
"email": "support@juspay.in",
|
|
@@ -378,6 +378,25 @@
|
|
|
378
378
|
"google",
|
|
379
379
|
"bedrock",
|
|
380
380
|
"vertex",
|
|
381
|
+
"azure",
|
|
382
|
+
"mistral",
|
|
383
|
+
"ollama",
|
|
384
|
+
"huggingface",
|
|
385
|
+
"litellm",
|
|
386
|
+
"openrouter",
|
|
387
|
+
"deepseek",
|
|
388
|
+
"nvidia-nim",
|
|
389
|
+
"lm-studio",
|
|
390
|
+
"llama-cpp",
|
|
391
|
+
"tts",
|
|
392
|
+
"stt",
|
|
393
|
+
"voice",
|
|
394
|
+
"realtime",
|
|
395
|
+
"elevenlabs",
|
|
396
|
+
"deepgram",
|
|
397
|
+
"whisper",
|
|
398
|
+
"azure-speech",
|
|
399
|
+
"rag",
|
|
381
400
|
"streaming",
|
|
382
401
|
"tools",
|
|
383
402
|
"neurolink",
|