@juspay/neurolink 12.12.3 → 12.12.5

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.
@@ -134,18 +134,18 @@ function buildCodexErrorResponse(status, message) {
134
134
  * tokens and hydrating cooldown + quota state from disk.
135
135
  */
136
136
  async function loadCodexProxyAccounts() {
137
- const keys = await tokenStore.listByPrefix(CODEX_ACCOUNT_PREFIX);
138
- const [cooldowns, quotas] = await Promise.all([
137
+ const [inventory, cooldowns, quotas] = await Promise.all([
138
+ tokenStore.getProviderSnapshot(),
139
139
  loadAccountCooldowns(),
140
140
  loadAccountQuotas(),
141
141
  ]);
142
142
  const now = Date.now();
143
143
  const accounts = [];
144
- for (const key of keys) {
145
- if (await tokenStore.isDisabled(key)) {
144
+ for (const [key, entry] of Object.entries(inventory)) {
145
+ if (!key.startsWith(CODEX_ACCOUNT_PREFIX) || entry.disabled) {
146
146
  continue;
147
147
  }
148
- const tokens = await tokenStore.loadTokens(key);
148
+ const tokens = entry.tokens;
149
149
  if (!tokens || tokens.tokenType !== "Bearer") {
150
150
  // Only OAuth (Bearer) accounts can serve the ChatGPT backend.
151
151
  continue;
@@ -346,6 +346,17 @@ export async function handleCodexResponsesRequest(ctx) {
346
346
  }).catch(() => undefined);
347
347
  };
348
348
  const accounts = await loadCodexProxyAccounts();
349
+ const cancelRequest = async (account) => {
350
+ await recordFinalOutcome(account, 499, {
351
+ errorType: "client_cancelled",
352
+ errorMessage: "Client cancelled Codex request",
353
+ terminalOutcome: "client_cancelled",
354
+ });
355
+ return buildCodexErrorResponse(499, "Client cancelled Codex request");
356
+ };
357
+ if (ctx.abortSignal?.aborted) {
358
+ return cancelRequest();
359
+ }
349
360
  if (accounts.length === 0) {
350
361
  await recordFinalOutcome(undefined, 401, {
351
362
  errorType: "no_accounts",
@@ -392,6 +403,9 @@ export async function handleCodexResponsesRequest(ctx) {
392
403
  let authRetried = false;
393
404
  // Same-account loop only re-runs once, for a post-401 token refresh.
394
405
  for (;;) {
406
+ if (ctx.abortSignal?.aborted) {
407
+ return cancelRequest(lastAttemptedAccount);
408
+ }
395
409
  attempt += 1;
396
410
  const attemptStartedAt = Date.now();
397
411
  lastAttemptedAccount = account;
@@ -402,10 +416,23 @@ export async function handleCodexResponsesRequest(ctx) {
402
416
  method: "POST",
403
417
  headers: buildCodexUpstreamHeaders(ctx.headers, account),
404
418
  body: bodyStr,
405
- signal: AbortSignal.timeout(CODEX_UPSTREAM_TIMEOUT_MS),
419
+ signal: ctx.abortSignal
420
+ ? AbortSignal.any([
421
+ ctx.abortSignal,
422
+ AbortSignal.timeout(CODEX_UPSTREAM_TIMEOUT_MS),
423
+ ])
424
+ : AbortSignal.timeout(CODEX_UPSTREAM_TIMEOUT_MS),
406
425
  });
407
426
  }
408
427
  catch (error) {
428
+ if (ctx.abortSignal?.aborted) {
429
+ writeAttempt(account, attempt, attemptStartedAt, 499, {
430
+ errorType: "client_cancelled",
431
+ errorMessage: "Client cancelled Codex request",
432
+ retryable: false,
433
+ });
434
+ return cancelRequest(account);
435
+ }
409
436
  // A transport failure message is derived from local state — resolved
410
437
  // hostnames, socket paths, Node internals — and says nothing the caller
411
438
  // can act on. Keep the detail in the log and return a fixed string, so
@@ -860,6 +860,7 @@ export type ProxyRollingState = {
860
860
  generation: number;
861
861
  }>;
862
862
  queuedSockets: number;
863
+ pendingTransfers?: number;
863
864
  rejectedSockets: number;
864
865
  failedTransfers: number;
865
866
  lastFailure: {
@@ -871,7 +872,7 @@ export type ProxyRollingState = {
871
872
  workerPid?: number;
872
873
  workerExitCode?: number | null;
873
874
  workerExitSignal?: string | null;
874
- supervisorAction?: "none" | "sigkill_after_transfer_failure";
875
+ supervisorAction?: "none" | "sigkill_after_transfer_failure" | "cancel_uncommitted_socket";
875
876
  } | null;
876
877
  };
877
878
  export type ProxySupervisorState = {
@@ -138,12 +138,17 @@ export type CodexResponsesInputItem = {
138
138
  call_id: string;
139
139
  output: string;
140
140
  };
141
+ /** Codex reasoning settings; supported levels depend on the selected model. */
142
+ export type CodexReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
141
143
  /** Request shape used to bridge Anthropic Messages traffic to Codex Responses. */
142
144
  export type CodexResponsesRequest = {
143
145
  model: string;
144
146
  input: CodexResponsesInputItem[];
145
147
  stream: true;
146
148
  store: false;
149
+ reasoning?: {
150
+ effort: CodexReasoningEffort;
151
+ };
147
152
  instructions?: string;
148
153
  tools?: Array<{
149
154
  type: "function";
@@ -163,3 +168,8 @@ export type CodexFallbackResult = {
163
168
  usage?: NonNullable<InternalResult["usage"]>;
164
169
  finishReason: "end_turn" | "tool_use";
165
170
  };
171
+ /** Incremental Claude frames and explicit upstream cancellation. */
172
+ export type CodexFallbackStream = {
173
+ frames: AsyncGenerator<string, CodexFallbackResult>;
174
+ cancel: (reason?: unknown) => Promise<void>;
175
+ };
@@ -192,6 +192,9 @@ export type SSEMessageDelta = {
192
192
  };
193
193
  usage: {
194
194
  output_tokens: number;
195
+ input_tokens?: number;
196
+ cache_read_input_tokens?: number;
197
+ cache_creation_input_tokens?: number;
195
198
  };
196
199
  };
197
200
  export type SSEMessageStop = {
@@ -1392,6 +1395,7 @@ export type ClaudeProxyModelTier = "opus" | "sonnet" | "haiku" | "other";
1392
1395
  export type ProxyTranslationAttempt = {
1393
1396
  provider?: string;
1394
1397
  model?: string;
1398
+ reasoningEffort?: FallbackEntry["reasoningEffort"];
1395
1399
  label: string;
1396
1400
  };
1397
1401
  /** Ordered plan of provider attempts for a proxy request. */
@@ -2360,7 +2364,7 @@ export type RollingWorkerFailureDetails = {
2360
2364
  workerPid?: number;
2361
2365
  workerExitCode?: number | null;
2362
2366
  workerExitSignal?: string | null;
2363
- supervisorAction?: "none" | "sigkill_after_transfer_failure";
2367
+ supervisorAction?: "none" | "sigkill_after_transfer_failure" | "cancel_uncommitted_socket";
2364
2368
  };
2365
2369
  export type RollingWorkerSupervisorEvent = {
2366
2370
  at: string;
@@ -2388,6 +2392,8 @@ export type RollingWorkerSupervisorSnapshot = {
2388
2392
  generation: number;
2389
2393
  }>;
2390
2394
  queuedSockets: number;
2395
+ /** Offered sockets awaiting acknowledgement or commit, across all workers. */
2396
+ pendingTransfers?: number;
2391
2397
  rejectedSockets: number;
2392
2398
  failedTransfers: number;
2393
2399
  /** Bounded generation-scoped evidence for attributing lifetime counters. */
@@ -2404,13 +2410,15 @@ export type RollingWorkerSupervisorOptions = {
2404
2410
  spawnWorker: (generation: number, expectedVersion: string) => RollingWorkerHandle;
2405
2411
  readyTimeoutMs?: number;
2406
2412
  socketQueueLimit?: number;
2413
+ /** Bound IPC socket offers independently of active HTTP requests. */
2414
+ maxPendingTransfers?: number;
2407
2415
  socketQueueTimeoutMs?: number;
2408
2416
  shutdownTimeoutMs?: number;
2409
2417
  onStateChange?: (snapshot: RollingWorkerSupervisorSnapshot) => void;
2410
2418
  onReplacementRequested?: (request: {
2411
2419
  generation: number;
2412
2420
  pid: number;
2413
- reason: "environment";
2421
+ reason: "environment" | "socket_offer_timeout";
2414
2422
  }) => void;
2415
2423
  log?: (message: string) => void;
2416
2424
  };
@@ -2421,6 +2429,7 @@ export type RollingProxyServerOptions = {
2421
2429
  spawnWorker: (generation: number, expectedVersion: string) => RollingWorkerHandle;
2422
2430
  readyTimeoutMs?: number;
2423
2431
  socketQueueLimit?: number;
2432
+ maxPendingTransfers?: number;
2424
2433
  socketQueueTimeoutMs?: number;
2425
2434
  shutdownTimeoutMs?: number;
2426
2435
  recoveryDelayMs?: number;
@@ -5,6 +5,7 @@
5
5
  * and usage tracking for Anthropic API access.
6
6
  */
7
7
  import type { StoredOAuthTokens } from "./auth.js";
8
+ import type { CodexReasoningEffort } from "./codex.js";
8
9
  export type { StoredOAuthTokens, TokenRefresher, TokenStorageData, StoredProviderTokens, } from "./auth.js";
9
10
  /**
10
11
  * Claude subscription tier levels
@@ -979,6 +980,8 @@ export type ModelMapping = {
979
980
  export type FallbackEntry = {
980
981
  provider: string;
981
982
  model: string;
983
+ /** Explicit Codex fallback effort. Omit to use the upstream default. */
984
+ reasoningEffort?: CodexReasoningEffort;
982
985
  };
983
986
  /** Full proxy routing config */
984
987
  export type ProxyRoutingConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "12.12.3",
3
+ "version": "12.12.5",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (connect any MCP server), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
6
6
  "author": {