@juspay/neurolink 12.24.1 → 12.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/dist/adapters/providerImageAdapter.js +2 -4
- package/dist/browser/neurolink.min.js +410 -410
- package/dist/cli/commands/proxy.js +30 -0
- package/dist/cli/utils/interactiveSetup.js +1 -1
- package/dist/constants/contextWindows.js +0 -5
- package/dist/constants/enums.d.ts +3 -1
- package/dist/constants/enums.js +2 -0
- package/dist/models/manifests/deepseek.js +3 -3
- package/dist/providers/catalog/deepseek.json +28 -14
- package/dist/providers/catalog/huggingface.json +85 -85
- package/dist/proxy/accountRanking.d.ts +67 -4
- package/dist/proxy/accountRanking.js +188 -8
- package/dist/proxy/proxyAnalysis.js +76 -0
- package/dist/proxy/proxyConfig.d.ts +24 -1
- package/dist/proxy/proxyConfig.js +131 -3
- package/dist/proxy/routingEvidence.d.ts +1 -1
- package/dist/proxy/routingEvidence.js +5 -0
- package/dist/proxy/runtimeConfig.js +15 -0
- package/dist/proxy/sessionAffinity.d.ts +23 -0
- package/dist/proxy/sessionAffinity.js +62 -0
- package/dist/server/routes/claudeProxyRoutes.d.ts +48 -3
- package/dist/server/routes/claudeProxyRoutes.js +324 -29
- package/dist/types/proxy.d.ts +48 -0
- package/dist/types/subscription.d.ts +16 -4
- package/docs-site/static/search-index.json +25 -24
- package/package.json +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Bind a session to the account that just served it, refreshing its idle clock. */
|
|
2
|
+
export declare function bind(sessionId: string, accountKey: string, now: number): void;
|
|
3
|
+
/**
|
|
4
|
+
* The account a session is bound to, or undefined if unbound or idle-expired.
|
|
5
|
+
* A read never refreshes the binding — only a served request (bind) does,
|
|
6
|
+
* since the idle TTL counts from the session's last served request.
|
|
7
|
+
*/
|
|
8
|
+
export declare function get(sessionId: string, now: number, idleTtlMs: number): string | undefined;
|
|
9
|
+
export declare function clear(): void;
|
|
10
|
+
export declare function size(): number;
|
|
11
|
+
/**
|
|
12
|
+
* Sessions whose binding has not idle-expired. Expired entries are dropped
|
|
13
|
+
* here as on read, since otherwise they would linger until the cap evicted
|
|
14
|
+
* them.
|
|
15
|
+
*/
|
|
16
|
+
export declare function countActive(now: number, idleTtlMs: number): number;
|
|
17
|
+
export declare const sessionAffinity: Readonly<{
|
|
18
|
+
bind: typeof bind;
|
|
19
|
+
get: typeof get;
|
|
20
|
+
clear: typeof clear;
|
|
21
|
+
size: typeof size;
|
|
22
|
+
countActive: typeof countActive;
|
|
23
|
+
}>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const MAX_BOUND_SESSIONS = 5_000;
|
|
2
|
+
// Per-record shape is an inline type on the Map's generic parameter rather
|
|
3
|
+
// than a named `type` alias: it is a private, single-use implementation
|
|
4
|
+
// detail with no external consumer, so it does not belong in
|
|
5
|
+
// src/lib/types/ (CLAUDE.md rule 2 targets shared type definitions).
|
|
6
|
+
const bindings = new Map();
|
|
7
|
+
/** Bind a session to the account that just served it, refreshing its idle clock. */
|
|
8
|
+
export function bind(sessionId, accountKey, now) {
|
|
9
|
+
// Delete-then-set moves the entry to the end of Map iteration order, which
|
|
10
|
+
// is what makes that order double as least-recently-bound-first for the
|
|
11
|
+
// cap eviction below.
|
|
12
|
+
bindings.delete(sessionId);
|
|
13
|
+
bindings.set(sessionId, { accountKey, lastServedAt: now });
|
|
14
|
+
if (bindings.size > MAX_BOUND_SESSIONS) {
|
|
15
|
+
const oldestKey = bindings.keys().next().value;
|
|
16
|
+
if (oldestKey !== undefined) {
|
|
17
|
+
bindings.delete(oldestKey);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The account a session is bound to, or undefined if unbound or idle-expired.
|
|
23
|
+
* A read never refreshes the binding — only a served request (bind) does,
|
|
24
|
+
* since the idle TTL counts from the session's last served request.
|
|
25
|
+
*/
|
|
26
|
+
export function get(sessionId, now, idleTtlMs) {
|
|
27
|
+
const record = bindings.get(sessionId);
|
|
28
|
+
if (!record) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
if (now - record.lastServedAt > idleTtlMs) {
|
|
32
|
+
bindings.delete(sessionId);
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return record.accountKey;
|
|
36
|
+
}
|
|
37
|
+
export function clear() {
|
|
38
|
+
bindings.clear();
|
|
39
|
+
}
|
|
40
|
+
export function size() {
|
|
41
|
+
return bindings.size;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Sessions whose binding has not idle-expired. Expired entries are dropped
|
|
45
|
+
* here as on read, since otherwise they would linger until the cap evicted
|
|
46
|
+
* them.
|
|
47
|
+
*/
|
|
48
|
+
export function countActive(now, idleTtlMs) {
|
|
49
|
+
for (const [sessionId, record] of bindings) {
|
|
50
|
+
if (now - record.lastServedAt > idleTtlMs) {
|
|
51
|
+
bindings.delete(sessionId);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return bindings.size;
|
|
55
|
+
}
|
|
56
|
+
export const sessionAffinity = Object.freeze({
|
|
57
|
+
bind,
|
|
58
|
+
get,
|
|
59
|
+
clear,
|
|
60
|
+
size,
|
|
61
|
+
countActive,
|
|
62
|
+
});
|
|
@@ -2,7 +2,7 @@ import { buildTranslationOptions } from "../../proxy/proxyTranslationEngine.js";
|
|
|
2
2
|
import { ProxyTracer } from "../../proxy/proxyTracer.js";
|
|
3
3
|
import { isPermanentRefreshFailure } from "../../proxy/tokenRefresh.js";
|
|
4
4
|
import type { ProxyAccountDirectoryOverride } from "../../types/index.js";
|
|
5
|
-
import type { AccountAllowlist, AccountAdmissionLease, JsonObject, AccountCooldownPlan, AccountQuota, AccountQuotaWindow, AccountUsageFetchResult, AnthropicAttemptLogger, AnthropicAuthRetryResult, AnthropicEntitlementFailure, AnthropicInvalidRequestFailure, AnthropicLoopState, AnthropicScopedExhaustion, AnthropicNonOkResult, AnthropicSuccessResult, AnthropicUpstreamBody, AnthropicUpstreamBodyBuilder, AnthropicUpstreamFetchResult, ClaudeFinalRequestLogger, ClaudeLoggedErrorBuilder, ClaudeRequest, ClaudeProxyRouteRuntimeOptions, ModelRouterInterface, ParsedClaudeError, ProxyAccountRoutingDecision, ProxyAccountSortMetrics, ProxyBodyCaptureLogger, ProxyLimitsRefreshResponse, ProxyQuotaCooldownUpdate, ProxyOveragePolicy, ProxyPassthroughAccount, QueuedAccountAdmission, RouteGroup, RuntimeAccountState, ServerContext, StreamTerminalOutcome } from "../../types/index.js";
|
|
5
|
+
import type { AccountAllowlist, AccountAdmissionLease, JsonObject, AccountCooldownPlan, AccountQuota, AccountQuotaWindow, AccountUsageFetchResult, AnthropicAttemptLogger, AnthropicAuthRetryResult, AnthropicEntitlementFailure, AnthropicInvalidRequestFailure, AnthropicLoopState, AnthropicScopedExhaustion, AnthropicNonOkResult, AnthropicSuccessResult, AnthropicUpstreamBody, AnthropicUpstreamBodyBuilder, AnthropicUpstreamFetchResult, ClaudeFinalRequestLogger, ClaudeLoggedErrorBuilder, ClaudeRequest, ClaudeProxyRouteRuntimeOptions, ModelRouterInterface, ParsedClaudeError, ProxyAccountRankingPolicy, ProxyAccountRoutingAffinityEvidence, ProxyAccountRoutingDecision, ProxyAccountRoutingReason, ProxyAccountRoutingSpillEvidence, ProxyAccountSortMetrics, ProxyAffinityPrecedenceSkipReason, ProxyBodyCaptureLogger, ProxyLimitsRefreshResponse, ProxyQuotaCooldownUpdate, ProxyOveragePolicy, ProxyPassthroughAccount, ProxyRoutingPolicySnapshot, QueuedAccountAdmission, RouteGroup, RuntimeAccountState, ServerContext, StreamTerminalOutcome } from "../../types/index.js";
|
|
6
6
|
declare function tryAcquireAccountAdmission(accountKey: string, capacity: number | undefined, generation?: number): AccountAdmissionLease | undefined;
|
|
7
7
|
/** Current in-flight request count for one account, unlimited or capped. */
|
|
8
8
|
declare function getAccountInflight(accountKey: string): number;
|
|
@@ -121,9 +121,18 @@ declare function evaluateScopedExhaustion(accounts: ProxyPassthroughAccount[], r
|
|
|
121
121
|
eligible: ProxyPassthroughAccount[];
|
|
122
122
|
exhaustion: AnthropicScopedExhaustion | null;
|
|
123
123
|
};
|
|
124
|
-
declare function orderAccountsByQuotaWithMetrics(accounts: ProxyPassthroughAccount[], now: number, primaryKey: string | undefined, sessionSoftLimit: number, sessionResetToleranceMs: number,
|
|
124
|
+
declare function orderAccountsByQuotaWithMetrics(accounts: ProxyPassthroughAccount[], now: number, primaryKey: string | undefined, sessionSoftLimit: number, sessionResetToleranceMs: number, options?: {
|
|
125
|
+
requestedModel?: string;
|
|
126
|
+
policy?: {
|
|
127
|
+
ranking?: ProxyAccountRankingPolicy;
|
|
128
|
+
affinityKey?: string;
|
|
129
|
+
preferPrimary?: boolean;
|
|
130
|
+
};
|
|
131
|
+
}): {
|
|
125
132
|
orderedAccounts: ProxyPassthroughAccount[];
|
|
126
133
|
metricsByKey: Map<string, ProxyAccountSortMetrics>;
|
|
134
|
+
reason: ProxyAccountRoutingReason;
|
|
135
|
+
affinitySkippedReason: ProxyAffinityPrecedenceSkipReason | null;
|
|
127
136
|
};
|
|
128
137
|
/**
|
|
129
138
|
* Order accounts to MAXIMIZE quota utilization (fill-first, smart order):
|
|
@@ -164,7 +173,30 @@ declare function buildRoutingDecision(args: {
|
|
|
164
173
|
sessionSoftLimit: number;
|
|
165
174
|
sessionResetToleranceMs: number;
|
|
166
175
|
rotationOffset: number;
|
|
176
|
+
policySelectionReason?: ProxyAccountRoutingReason;
|
|
177
|
+
policy?: ProxyRoutingPolicySnapshot;
|
|
178
|
+
affinity?: ProxyAccountRoutingAffinityEvidence;
|
|
179
|
+
spill?: ProxyAccountRoutingSpillEvidence;
|
|
167
180
|
}): ProxyAccountRoutingDecision | undefined;
|
|
181
|
+
declare function selectClaudeProxyAccountOrder(args: {
|
|
182
|
+
enabledAccounts: ProxyPassthroughAccount[];
|
|
183
|
+
accountStrategy: "round-robin" | "fill-first";
|
|
184
|
+
primaryAccountKey: string | undefined;
|
|
185
|
+
quotaRoutingEnabled: boolean;
|
|
186
|
+
sessionSoftLimit: number;
|
|
187
|
+
sessionResetToleranceMs: number;
|
|
188
|
+
requestedModel?: string;
|
|
189
|
+
sessionId?: string;
|
|
190
|
+
ranking: ProxyAccountRankingPolicy;
|
|
191
|
+
preferPrimary: boolean;
|
|
192
|
+
sessionAffinityEnabled: boolean;
|
|
193
|
+
sessionAffinityIdleTtlMs: number;
|
|
194
|
+
spillInflight: number;
|
|
195
|
+
setRoutingDecision: (decision: ProxyAccountRoutingDecision) => void;
|
|
196
|
+
}): {
|
|
197
|
+
orderedAccounts: ProxyPassthroughAccount[];
|
|
198
|
+
metricsByKey: Map<string, ProxyAccountSortMetrics>;
|
|
199
|
+
};
|
|
168
200
|
declare function trackUpstreamReadableStream(source: ReadableStream<Uint8Array>): {
|
|
169
201
|
stream: ReadableStream<Uint8Array>;
|
|
170
202
|
outcome: Promise<StreamTerminalOutcome>;
|
|
@@ -314,6 +346,7 @@ declare function handleAnthropicAuthRetry(args: {
|
|
|
314
346
|
sawRateLimit: boolean;
|
|
315
347
|
sawTransientFailure: boolean;
|
|
316
348
|
sawNetworkError: boolean;
|
|
349
|
+
bindServedSession?: (servingAccountKey: string) => void;
|
|
317
350
|
}): Promise<AnthropicAuthRetryResult>;
|
|
318
351
|
declare function finalizeAnthropicTerminalFetchError(args: {
|
|
319
352
|
terminalError: NonNullable<AnthropicUpstreamFetchResult["terminalError"]>;
|
|
@@ -506,7 +539,14 @@ export declare const __testHooks: {
|
|
|
506
539
|
scheduleAdaptiveQuotaRefreshes: typeof scheduleAdaptiveQuotaRefreshes;
|
|
507
540
|
scheduleHandoffQuotaRefresh: typeof scheduleHandoffQuotaRefresh;
|
|
508
541
|
getQuotaRefreshState: (key: string) => import("../../index.js").ProxyQuotaRefreshRuntimeState;
|
|
509
|
-
buildQuotaRoutingDecision: (accounts: ProxyPassthroughAccount[], now: number, primaryKey: string | undefined, sessionSoftLimit?: number, sessionResetToleranceMs?: number,
|
|
542
|
+
buildQuotaRoutingDecision: (accounts: ProxyPassthroughAccount[], now: number, primaryKey: string | undefined, sessionSoftLimit?: number, sessionResetToleranceMs?: number, options?: {
|
|
543
|
+
requestedModel?: string;
|
|
544
|
+
policy?: {
|
|
545
|
+
ranking?: ProxyAccountRankingPolicy;
|
|
546
|
+
affinityKey?: string;
|
|
547
|
+
preferPrimary?: boolean;
|
|
548
|
+
};
|
|
549
|
+
}) => ProxyAccountRoutingDecision | undefined;
|
|
510
550
|
buildRoutingDecision: typeof buildRoutingDecision;
|
|
511
551
|
resetEpochToMs: typeof resetEpochToMs;
|
|
512
552
|
seedRuntimeQuotasFromDisk: typeof seedRuntimeQuotasFromDisk;
|
|
@@ -520,6 +560,11 @@ export declare const __testHooks: {
|
|
|
520
560
|
bodyStr: string;
|
|
521
561
|
sessionId?: string;
|
|
522
562
|
};
|
|
563
|
+
extractSnapshotBodySessionIdForTests: (body: unknown) => string | undefined;
|
|
564
|
+
selectClaudeProxyAccountOrderForTests: typeof selectClaudeProxyAccountOrder;
|
|
565
|
+
setForceSpillThrowForTests: (value: boolean) => void;
|
|
566
|
+
setForceAffinityLookupThrowForTests: (value: boolean) => void;
|
|
567
|
+
setForceBindRecheckThrowForTests: (value: boolean) => void;
|
|
523
568
|
isAntiAbuseConstruction429: typeof isAntiAbuseConstruction429;
|
|
524
569
|
fetchAnthropicAccountResponse: typeof fetchAnthropicAccountResponse;
|
|
525
570
|
finalizeAnthropicTerminalFetchError: typeof finalizeAnthropicTerminalFetchError;
|