@juspay/neurolink 9.93.0 → 9.93.2

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 (53) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/browser/neurolink.min.js +379 -382
  3. package/dist/cli/commands/proxy.d.ts +3 -2
  4. package/dist/cli/commands/proxy.js +224 -66
  5. package/dist/cli/commands/proxyAnalyze.d.ts +3 -0
  6. package/dist/cli/commands/proxyAnalyze.js +147 -0
  7. package/dist/cli/parser.js +3 -1
  8. package/dist/cli/utils/serverUtils.js +4 -1
  9. package/dist/lib/proxy/globalInstaller.js +1 -1
  10. package/dist/lib/proxy/openaiFormat.js +1 -0
  11. package/dist/lib/proxy/proxyAnalysis.d.ts +3 -0
  12. package/dist/lib/proxy/proxyAnalysis.js +454 -0
  13. package/dist/lib/proxy/proxyHealth.d.ts +4 -0
  14. package/dist/lib/proxy/proxyHealth.js +21 -0
  15. package/dist/lib/proxy/sseInterceptor.d.ts +9 -1
  16. package/dist/lib/proxy/sseInterceptor.js +7 -6
  17. package/dist/lib/proxy/streamOutcome.d.ts +3 -1
  18. package/dist/lib/proxy/streamOutcome.js +77 -0
  19. package/dist/lib/proxy/updateCoordinator.d.ts +7 -0
  20. package/dist/lib/proxy/updateCoordinator.js +60 -0
  21. package/dist/lib/proxy/updateState.d.ts +4 -0
  22. package/dist/lib/proxy/updateState.js +51 -0
  23. package/dist/lib/proxy/workerLog.d.ts +6 -0
  24. package/dist/lib/proxy/workerLog.js +42 -0
  25. package/dist/lib/server/routes/claudeProxyRoutes.d.ts +1 -0
  26. package/dist/lib/server/routes/claudeProxyRoutes.js +114 -17
  27. package/dist/lib/server/routes/openaiProxyRoutes.d.ts +9 -0
  28. package/dist/lib/server/routes/openaiProxyRoutes.js +16 -1
  29. package/dist/lib/types/cli.d.ts +7 -0
  30. package/dist/lib/types/proxy.d.ts +187 -0
  31. package/dist/proxy/globalInstaller.js +1 -1
  32. package/dist/proxy/openaiFormat.js +1 -0
  33. package/dist/proxy/proxyAnalysis.d.ts +3 -0
  34. package/dist/proxy/proxyAnalysis.js +453 -0
  35. package/dist/proxy/proxyHealth.d.ts +4 -0
  36. package/dist/proxy/proxyHealth.js +21 -0
  37. package/dist/proxy/sseInterceptor.d.ts +9 -1
  38. package/dist/proxy/sseInterceptor.js +7 -6
  39. package/dist/proxy/streamOutcome.d.ts +3 -1
  40. package/dist/proxy/streamOutcome.js +77 -0
  41. package/dist/proxy/updateCoordinator.d.ts +7 -0
  42. package/dist/proxy/updateCoordinator.js +59 -0
  43. package/dist/proxy/updateState.d.ts +4 -0
  44. package/dist/proxy/updateState.js +51 -0
  45. package/dist/proxy/workerLog.d.ts +6 -0
  46. package/dist/proxy/workerLog.js +41 -0
  47. package/dist/server/routes/claudeProxyRoutes.d.ts +1 -0
  48. package/dist/server/routes/claudeProxyRoutes.js +114 -17
  49. package/dist/server/routes/openaiProxyRoutes.d.ts +9 -0
  50. package/dist/server/routes/openaiProxyRoutes.js +16 -1
  51. package/dist/types/cli.d.ts +7 -0
  52. package/dist/types/proxy.d.ts +187 -0
  53. package/package.json +4 -1
@@ -460,7 +460,10 @@ export type RequestAttemptLogEntry = {
460
460
  account: string;
461
461
  accountType: string;
462
462
  responseStatus: number;
463
+ /** End-to-end request age when this attempt completed. */
463
464
  responseTimeMs: number;
465
+ /** Time spent in this specific account attempt. */
466
+ attemptDurationMs?: number;
464
467
  errorType?: string;
465
468
  errorMessage?: string;
466
469
  /** Low-level transport code such as ETIMEDOUT or EADDRNOTAVAIL. */
@@ -522,6 +525,8 @@ export type AnthropicAttemptLogger = (status: number, errorType?: string, errorM
522
525
  errorCode?: string;
523
526
  rateLimitKind?: "transient" | "quota";
524
527
  cooldownReason?: "transient" | "session" | "weekly" | "unified";
528
+ /** Override for nested retries whose attempt starts after this logger. */
529
+ attemptDurationMs?: number;
525
530
  /** Override used when one account selection performs an OAuth retry fetch. */
526
531
  attempt?: number;
527
532
  }) => void;
@@ -558,9 +563,40 @@ export type LoadedClaudeAccountContext = {
558
563
  };
559
564
  export type AnthropicSuccessResult = {
560
565
  retryNextAccount: true;
566
+ failure?: {
567
+ message: string;
568
+ rateLimit: boolean;
569
+ };
561
570
  } | {
562
571
  response: Response | unknown;
563
572
  };
573
+ /** Result of buffering only enough upstream SSE to make a retry-safe decision. */
574
+ export type AnthropicStreamPreflightResult = {
575
+ kind: "ready";
576
+ chunks: Uint8Array[];
577
+ } | {
578
+ kind: "empty";
579
+ chunks: Uint8Array[];
580
+ } | {
581
+ kind: "transport_error";
582
+ chunks: Uint8Array[];
583
+ error: unknown;
584
+ } | {
585
+ kind: "sse_error";
586
+ chunks: Uint8Array[];
587
+ errorType: string;
588
+ message: string;
589
+ };
590
+ /** One complete Server-Sent Event extracted from an incremental buffer. */
591
+ export type ParsedSSEEvent = {
592
+ event: string;
593
+ data: string;
594
+ };
595
+ /** Complete SSE events plus the trailing partial frame. */
596
+ export type ParsedSSEBuffer = {
597
+ events: ParsedSSEEvent[];
598
+ remainder: string;
599
+ };
564
600
  export type AnthropicAuthRetryResult = {
565
601
  response?: Response | unknown;
566
602
  continueLoop: boolean;
@@ -810,6 +846,8 @@ export type ProxyReadinessState = {
810
846
  startTimeMs: number;
811
847
  acceptingConnections: boolean;
812
848
  ready: boolean;
849
+ /** True only while the updater is draining inference traffic. */
850
+ drainingForUpdate: boolean;
813
851
  readyAtMs?: number;
814
852
  };
815
853
  /** Structured response returned by the proxy /health endpoint. */
@@ -817,6 +855,7 @@ export type ProxyHealthResponse = {
817
855
  status: "ok" | "starting";
818
856
  ready: boolean;
819
857
  acceptingConnections: boolean;
858
+ drainingForUpdate: boolean;
820
859
  strategy: string;
821
860
  passthrough: boolean;
822
861
  version: string;
@@ -1025,6 +1064,124 @@ export type QueuedProxyLifecycleEvent = {
1025
1064
  date: string;
1026
1065
  record: Record<string, unknown>;
1027
1066
  };
1067
+ /** Percentile summary used by offline proxy log analysis. */
1068
+ export type ProxyLatencySummary = {
1069
+ count: number;
1070
+ p50: number | null;
1071
+ p95: number | null;
1072
+ p99: number | null;
1073
+ max: number | null;
1074
+ };
1075
+ /** Per-account request and rate-limit totals reconstructed from JSONL logs. */
1076
+ export type ProxyAnalysisAccount = {
1077
+ account: string;
1078
+ accountType: string;
1079
+ attempts: number;
1080
+ attemptErrors: number;
1081
+ finalRequests: number;
1082
+ finalErrors: number;
1083
+ transientRateLimits: number;
1084
+ quotaRateLimits: number;
1085
+ unclassifiedRateLimits: number;
1086
+ };
1087
+ /** Offline report generated from proxy request, attempt, and lifecycle logs. */
1088
+ export type ProxyAnalysisReport = {
1089
+ generatedAt: string;
1090
+ since: string;
1091
+ logsDir: string;
1092
+ files: {
1093
+ lifecycle: number;
1094
+ requests: number;
1095
+ attempts: number;
1096
+ };
1097
+ coverage: {
1098
+ lifecycle: boolean;
1099
+ finalRequests: boolean;
1100
+ attempts: boolean;
1101
+ attemptLatency: boolean;
1102
+ cacheUsage: boolean;
1103
+ };
1104
+ dataQuality: {
1105
+ linesRead: number;
1106
+ malformedLines: number;
1107
+ unsupportedLifecycleLines: number;
1108
+ lifecycleSequenceGaps: number;
1109
+ lifecycleSequenceDuplicates: number;
1110
+ };
1111
+ lifecycle: {
1112
+ accepted: number;
1113
+ headers: number;
1114
+ firstChunks: number;
1115
+ terminal: number;
1116
+ unsettled: number;
1117
+ terminalOutcomes: Record<string, number>;
1118
+ errorTypes: Record<string, number>;
1119
+ errorCodes: Record<string, number>;
1120
+ };
1121
+ requests: {
1122
+ completed: number;
1123
+ success: number;
1124
+ errors: number;
1125
+ finalRateLimits: number;
1126
+ recoveredAfterRetry: number;
1127
+ errorTypes: Record<string, number>;
1128
+ errorCodes: Record<string, number>;
1129
+ };
1130
+ attempts: {
1131
+ total: number;
1132
+ errors: number;
1133
+ errorTypes: Record<string, number>;
1134
+ errorCodes: Record<string, number>;
1135
+ };
1136
+ rateLimits: {
1137
+ attemptRateLimits: number;
1138
+ transient: number;
1139
+ quota: number;
1140
+ unclassified: number;
1141
+ };
1142
+ latencyMs: {
1143
+ headers: ProxyLatencySummary;
1144
+ firstChunk: ProxyLatencySummary;
1145
+ terminal: ProxyLatencySummary;
1146
+ finalRequest: ProxyLatencySummary;
1147
+ attempt: ProxyLatencySummary;
1148
+ singleAttemptDelta: ProxyLatencySummary;
1149
+ };
1150
+ cache: {
1151
+ requestsWithUsage: number;
1152
+ requestsWithCacheRead: number;
1153
+ cacheReadTokens: number;
1154
+ cacheCreationTokens: number;
1155
+ inputTokens: number;
1156
+ requestHitRate: number | null;
1157
+ };
1158
+ accounts: ProxyAnalysisAccount[];
1159
+ };
1160
+ /** Inputs for the offline proxy JSONL analyzer. */
1161
+ export type ProxyAnalysisOptions = {
1162
+ logsDir?: string;
1163
+ since?: string;
1164
+ nowMs?: number;
1165
+ };
1166
+ /** Attempt timing retained while joining offline proxy log records. */
1167
+ export type ProxyAnalysisAttemptRecord = {
1168
+ count: number;
1169
+ hadError: boolean;
1170
+ totalDurationMs: number;
1171
+ durationCount: number;
1172
+ };
1173
+ /** Final request fields retained while joining offline proxy log records. */
1174
+ export type ProxyAnalysisFinalRequestRecord = {
1175
+ status: number;
1176
+ durationMs: number | null;
1177
+ account: string;
1178
+ accountType: string;
1179
+ inputTokens: number | null;
1180
+ cacheReadTokens: number | null;
1181
+ cacheCreationTokens: number | null;
1182
+ errorType: string | null;
1183
+ errorCode: string | null;
1184
+ };
1028
1185
  /** Request metadata retained by the HTTP adapter for terminal error logging. */
1029
1186
  export type RuntimeRequestMetadata = {
1030
1187
  requestId: string;
@@ -1034,6 +1191,8 @@ export type RuntimeRequestMetadata = {
1034
1191
  model: string;
1035
1192
  stream: boolean;
1036
1193
  toolCount: number;
1194
+ /** Admission decision captured before an updater drain can race the route. */
1195
+ rejectForUpdate?: boolean;
1037
1196
  terminalErrorType?: string;
1038
1197
  terminalErrorCode?: string;
1039
1198
  };
@@ -1201,6 +1360,14 @@ export type UpdateState = {
1201
1360
  lastUpdateVersion: string | null;
1202
1361
  /** Installed by the updater but not yet confirmed as the running version. */
1203
1362
  pendingRestartVersion: string | null;
1363
+ /** Why an available update has not yet reached a safe install/restart boundary. */
1364
+ deferredUpdate: {
1365
+ version: string;
1366
+ since: string;
1367
+ updatedAt: string;
1368
+ reason: "waiting_for_quiet" | "draining" | "drain_timeout" | "drain_unavailable" | "activity_unavailable";
1369
+ activeRequests: number | null;
1370
+ } | null;
1204
1371
  /** Last updater failure, retained until a successful update or replacement. */
1205
1372
  lastFailure: {
1206
1373
  at: string;
@@ -1209,6 +1376,26 @@ export type UpdateState = {
1209
1376
  message: string;
1210
1377
  } | null;
1211
1378
  };
1379
+ /** Result from waiting for a non-disruptive updater execution window. */
1380
+ export type ProxyUpdateWindowResult = {
1381
+ ready: boolean;
1382
+ draining: boolean;
1383
+ reason?: "stopping" | "parent_stopped" | "drain_failed" | "drain_timeout";
1384
+ };
1385
+ /** Dependencies and timing controls for the updater's safe-window coordinator. */
1386
+ export type ProxyUpdateWindowOptions = {
1387
+ quietThresholdMs: number;
1388
+ quietWaitMs: number;
1389
+ drainWaitMs: number;
1390
+ pollIntervalMs: number;
1391
+ getActivity: () => Promise<ProxyRuntimeActivity | null>;
1392
+ setDraining: (draining: boolean) => Promise<boolean>;
1393
+ isStopping: () => boolean;
1394
+ isParentAlive: () => boolean;
1395
+ onPhase?: (phase: "waiting_for_quiet" | "draining" | "drain_timeout", activity: ProxyRuntimeActivity | null) => void;
1396
+ now?: () => number;
1397
+ sleep?: (ms: number) => Promise<void>;
1398
+ };
1212
1399
  /** Result of validating a newly installed CLI through the stable trampoline. */
1213
1400
  export type InstalledVersionValidation = {
1214
1401
  version?: string;
@@ -14,7 +14,7 @@ function writableDirectory(path) {
14
14
  if (!existsSync(path)) {
15
15
  return false;
16
16
  }
17
- accessSync(path, constants.W_OK);
17
+ accessSync(path, constants.W_OK | constants.X_OK);
18
18
  return true;
19
19
  }
20
20
  catch {
@@ -760,6 +760,7 @@ export function createClaudeToOpenAIStreamTransform(requestModel, options = {})
760
760
  finished = true;
761
761
  options.onError?.(message);
762
762
  emit(controller, serializer.emitError(message));
763
+ controller.terminate();
763
764
  return;
764
765
  }
765
766
  default:
@@ -0,0 +1,3 @@
1
+ import type { ProxyAnalysisOptions, ProxyAnalysisReport } from "../types/index.js";
2
+ /** Analyze local proxy logs without reading request or response body artifacts. */
3
+ export declare function analyzeProxyLogs(options?: ProxyAnalysisOptions): Promise<ProxyAnalysisReport>;