@juspay/neurolink 9.86.4 → 9.87.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/adapters/video/replicateVideoHandler.js +27 -17
  3. package/dist/auth/tokenStore.d.ts +6 -0
  4. package/dist/auth/tokenStore.js +36 -4
  5. package/dist/browser/neurolink.min.js +417 -417
  6. package/dist/cli/commands/auth.js +3 -0
  7. package/dist/cli/commands/proxy.js +310 -107
  8. package/dist/lib/adapters/video/replicateVideoHandler.js +27 -17
  9. package/dist/lib/auth/tokenStore.d.ts +6 -0
  10. package/dist/lib/auth/tokenStore.js +36 -4
  11. package/dist/lib/proxy/accountCooldown.d.ts +5 -0
  12. package/dist/lib/proxy/accountCooldown.js +93 -0
  13. package/dist/lib/proxy/accountQuota.d.ts +3 -4
  14. package/dist/lib/proxy/accountQuota.js +75 -44
  15. package/dist/lib/proxy/accountSelection.d.ts +8 -0
  16. package/dist/lib/proxy/accountSelection.js +26 -0
  17. package/dist/lib/proxy/proxyConfig.js +24 -0
  18. package/dist/lib/proxy/proxyPaths.js +2 -0
  19. package/dist/lib/proxy/requestLogger.js +2 -0
  20. package/dist/lib/proxy/snapshotPersistence.js +1 -1
  21. package/dist/lib/proxy/sseInterceptor.js +16 -0
  22. package/dist/lib/proxy/streamOutcome.d.ts +3 -0
  23. package/dist/lib/proxy/streamOutcome.js +27 -0
  24. package/dist/lib/proxy/tokenRefresh.d.ts +8 -0
  25. package/dist/lib/proxy/tokenRefresh.js +92 -15
  26. package/dist/lib/proxy/updateState.js +17 -4
  27. package/dist/lib/server/routes/claudeProxyRoutes.d.ts +18 -3
  28. package/dist/lib/server/routes/claudeProxyRoutes.js +624 -223
  29. package/dist/lib/types/auth.d.ts +1 -1
  30. package/dist/lib/types/cli.d.ts +2 -0
  31. package/dist/lib/types/multimodal.d.ts +12 -0
  32. package/dist/lib/types/proxy.d.ts +49 -8
  33. package/dist/lib/types/subscription.d.ts +5 -0
  34. package/dist/proxy/accountCooldown.d.ts +5 -0
  35. package/dist/proxy/accountCooldown.js +92 -0
  36. package/dist/proxy/accountQuota.d.ts +3 -4
  37. package/dist/proxy/accountQuota.js +75 -44
  38. package/dist/proxy/accountSelection.d.ts +8 -0
  39. package/dist/proxy/accountSelection.js +25 -0
  40. package/dist/proxy/proxyConfig.js +24 -0
  41. package/dist/proxy/proxyPaths.js +2 -0
  42. package/dist/proxy/requestLogger.js +2 -0
  43. package/dist/proxy/snapshotPersistence.js +1 -1
  44. package/dist/proxy/sseInterceptor.js +16 -0
  45. package/dist/proxy/streamOutcome.d.ts +3 -0
  46. package/dist/proxy/streamOutcome.js +26 -0
  47. package/dist/proxy/tokenRefresh.d.ts +8 -0
  48. package/dist/proxy/tokenRefresh.js +92 -15
  49. package/dist/proxy/updateState.js +17 -4
  50. package/dist/server/routes/claudeProxyRoutes.d.ts +18 -3
  51. package/dist/server/routes/claudeProxyRoutes.js +624 -223
  52. package/dist/types/auth.d.ts +1 -1
  53. package/dist/types/cli.d.ts +2 -0
  54. package/dist/types/multimodal.d.ts +12 -0
  55. package/dist/types/proxy.d.ts +49 -8
  56. package/dist/types/subscription.d.ts +5 -0
  57. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [9.87.0](https://github.com/juspay/neurolink/compare/v9.86.5...v9.87.0) (2026-07-14)
2
+
3
+ ### Features
4
+
5
+ - **(video):** imageInputKey option for Replicate image-to-video models ([a66cab9](https://github.com/juspay/neurolink/commit/a66cab95749ad664d5e14824e0ee731ba9c3de8a))
6
+
7
+ ## [9.86.5](https://github.com/juspay/neurolink/compare/v9.86.4...v9.86.5) (2026-07-14)
8
+
9
+ ### Bug Fixes
10
+
11
+ - **(proxy):** harden routing and process reliability ([be7487c](https://github.com/juspay/neurolink/commit/be7487cec6870176dfbcac3ed8b547a36bcc887a))
12
+
1
13
  ## [9.86.4](https://github.com/juspay/neurolink/compare/v9.86.3...v9.86.4) (2026-07-11)
2
14
 
3
15
  ### Bug Fixes
@@ -51,27 +51,37 @@ export class ReplicateVideoHandler {
51
51
  const startTime = Date.now();
52
52
  const model = options.model ?? DEFAULT_MODEL;
53
53
  const dataUri = `data:image/${this.detectImageType(image)};base64,${image.toString("base64")}`;
54
- // Wan-Alpha + most image-to-video models accept this shape; specific
55
- // models may require provider-specific extras passed through
56
- // VideoOutputOptions.[unknown key].
54
+ // Replicate image-to-video models do not share an input schema. The
55
+ // legacy shape below (`image` + `num_frames`/`fps`/`aspect_ratio`) fits
56
+ // Wan-Alpha-era models; current models (minimax/hailuo-2.3-*,
57
+ // wan-video/wan-2.7-i2v) key the image as `first_frame_image` /
58
+ // `first_frame` and take `duration` instead of frame counts — a missing
59
+ // required image key fails the prediction on submit. `imageInputKey`
60
+ // selects the image key AND the modern `duration`/`resolution` shape;
61
+ // omitting it preserves the legacy payload exactly.
57
62
  //
58
- // `resolution` is forwarded as the `resolution` input parameter.
59
- // Wan-Alpha and several other Replicate image-to-video models accept it
60
- // (e.g. "720p", "1080p"). Models that do not recognise it will silently
61
- // ignore the field — the Replicate API does not reject unknown input keys.
62
63
  // `calculateDimensions` still populates the metadata `dimensions` field
63
64
  // so downstream consumers always receive correct width/height regardless
64
65
  // of whether the model honoured the resolution hint.
65
- const inputPayload = {
66
- image: dataUri,
67
- prompt,
68
- num_frames: (options.length ?? 4) * 24, // Assume 24 fps
69
- fps: 24,
70
- aspect_ratio: options.aspectRatio,
71
- ...(options.resolution !== undefined
72
- ? { resolution: options.resolution }
73
- : {}),
74
- };
66
+ const inputPayload = options.imageInputKey !== undefined
67
+ ? {
68
+ [options.imageInputKey]: dataUri,
69
+ prompt,
70
+ duration: options.length ?? 4,
71
+ ...(options.resolution !== undefined
72
+ ? { resolution: options.resolution }
73
+ : {}),
74
+ }
75
+ : {
76
+ image: dataUri,
77
+ prompt,
78
+ num_frames: (options.length ?? 4) * 24, // Assume 24 fps
79
+ fps: 24,
80
+ aspect_ratio: options.aspectRatio,
81
+ ...(options.resolution !== undefined
82
+ ? { resolution: options.resolution }
83
+ : {}),
84
+ };
75
85
  let prediction;
76
86
  try {
77
87
  prediction = await predict(auth, { model, input: inputPayload }, { abortSignal: options.abortSignal });
@@ -171,6 +171,10 @@ export declare class TokenStore {
171
171
  * round-trips. The state survives proxy restarts because it is stored
172
172
  * alongside the tokens in the JSON file.
173
173
  *
174
+ * This operation and saveTokens() share the instance mutex. A concurrent
175
+ * save cannot erase a disable: a later disable wins, while a later save
176
+ * preserves the existing disabled metadata.
177
+ *
174
178
  * @param provider - The provider key (e.g., "anthropic:user@example.com")
175
179
  * @param reason - Optional human-readable reason (e.g., "refresh_failed")
176
180
  */
@@ -194,6 +198,8 @@ export declare class TokenStore {
194
198
  * @returns true if the provider entry exists and is disabled
195
199
  */
196
200
  isDisabled(provider: string): Promise<boolean>;
201
+ /** Return the persisted disable reason, if the provider is disabled. */
202
+ getDisabledReason(provider: string): Promise<string | undefined>;
197
203
  /**
198
204
  * Lists all provider keys that are currently disabled.
199
205
  *
@@ -146,13 +146,23 @@ export class TokenStore {
146
146
  throw error;
147
147
  }
148
148
  }
149
- // Update provider tokens
149
+ const existingProvider = storageData.providers[provider];
150
+ const now = Date.now();
151
+ // Token rotation must not silently clear an operator-disabled account.
152
+ // Explicit login calls markEnabled() after saving fresh credentials.
150
153
  storageData.providers[provider] = {
151
154
  tokens,
152
- createdAt: Date.now(),
153
- lastAccessed: Date.now(),
155
+ createdAt: existingProvider?.createdAt ?? now,
156
+ lastAccessed: now,
157
+ ...(existingProvider?.disabled === true
158
+ ? {
159
+ disabled: true,
160
+ disabledAt: existingProvider.disabledAt,
161
+ disabledReason: existingProvider.disabledReason,
162
+ }
163
+ : {}),
154
164
  };
155
- storageData.lastModified = Date.now();
165
+ storageData.lastModified = now;
156
166
  try {
157
167
  const content = this.encryptionEnabled
158
168
  ? this.obfuscate(JSON.stringify(storageData))
@@ -489,6 +499,10 @@ export class TokenStore {
489
499
  * round-trips. The state survives proxy restarts because it is stored
490
500
  * alongside the tokens in the JSON file.
491
501
  *
502
+ * This operation and saveTokens() share the instance mutex. A concurrent
503
+ * save cannot erase a disable: a later disable wins, while a later save
504
+ * preserves the existing disabled metadata.
505
+ *
492
506
  * @param provider - The provider key (e.g., "anthropic:user@example.com")
493
507
  * @param reason - Optional human-readable reason (e.g., "refresh_failed")
494
508
  */
@@ -587,6 +601,24 @@ export class TokenStore {
587
601
  }
588
602
  });
589
603
  }
604
+ /** Return the persisted disable reason, if the provider is disabled. */
605
+ async getDisabledReason(provider) {
606
+ return this._mutex.runExclusive(async () => {
607
+ try {
608
+ const storageData = await this.loadStorageData();
609
+ const providerData = storageData.providers[provider];
610
+ return providerData?.disabled === true
611
+ ? providerData.disabledReason
612
+ : undefined;
613
+ }
614
+ catch (error) {
615
+ if (error instanceof TokenStoreError && error.code === "NOT_FOUND") {
616
+ return undefined;
617
+ }
618
+ throw error;
619
+ }
620
+ });
621
+ }
590
622
  /**
591
623
  * Lists all provider keys that are currently disabled.
592
624
  *