@juspay/neurolink 9.86.5 → 9.87.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 +12 -0
- package/dist/adapters/video/replicateVideoHandler.js +27 -17
- package/dist/browser/neurolink.min.js +2 -2
- package/dist/lib/adapters/video/replicateVideoHandler.js +27 -17
- package/dist/lib/types/multimodal.d.ts +12 -0
- package/dist/lib/utils/safeFetch.js +11 -1
- package/dist/types/multimodal.d.ts +12 -0
- package/dist/utils/safeFetch.js +11 -1
- package/package.json +1 -1
|
@@ -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
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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 });
|
|
@@ -190,6 +190,18 @@ export type VideoOutputOptions = {
|
|
|
190
190
|
* `image` Buffer argument passed to `generate()`.
|
|
191
191
|
*/
|
|
192
192
|
imageUrl?: string;
|
|
193
|
+
/**
|
|
194
|
+
* Replicate only: the input-schema key the model expects the image under.
|
|
195
|
+
* Replicate image-to-video models disagree on this — e.g.
|
|
196
|
+
* `minimax/hailuo-2.3-fast` requires `first_frame_image`,
|
|
197
|
+
* `wan-video/wan-2.7-i2v` requires `first_frame` — and a model whose
|
|
198
|
+
* required image key is missing fails the prediction on submit. Setting
|
|
199
|
+
* this also switches the payload to the modern `duration`/`resolution`
|
|
200
|
+
* field shape those models expect (instead of the legacy
|
|
201
|
+
* `num_frames`/`fps`/`aspect_ratio` shape). Omit for models that accept
|
|
202
|
+
* the default `image` key.
|
|
203
|
+
*/
|
|
204
|
+
imageInputKey?: string;
|
|
193
205
|
/**
|
|
194
206
|
* Per-call provider credentials. Takes precedence over instance-level
|
|
195
207
|
* credentials set at construction time, which in turn override env vars.
|
|
@@ -28,13 +28,23 @@ const DEFAULT_TIMEOUT_MS = 60_000;
|
|
|
28
28
|
function buildPinnedAgent(hostname, ip, family) {
|
|
29
29
|
return new Agent({
|
|
30
30
|
connect: {
|
|
31
|
-
lookup: (host,
|
|
31
|
+
lookup: (host, options, callback) => {
|
|
32
32
|
if (host.toLowerCase() !== hostname.toLowerCase()) {
|
|
33
33
|
// The host the connect layer asks for differs from the URL host —
|
|
34
34
|
// this happens for absolute Host headers etc. Reject defensively.
|
|
35
35
|
callback(new Error(`safeFetch: refusing to resolve "${host}" — expected "${hostname}"`), "", 0);
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
+
// Node ≥20 enables autoSelectFamily (Happy Eyeballs) by default, and
|
|
39
|
+
// its lookup contract passes `all: true` expecting an address ARRAY.
|
|
40
|
+
// Answering with the string form there fails the connection with
|
|
41
|
+
// "Invalid IP address: undefined" — which broke every safeDownload
|
|
42
|
+
// (Replicate / Runway / Kling asset fetches) on modern Node while
|
|
43
|
+
// plain curl of the same URL succeeded.
|
|
44
|
+
if (options?.all) {
|
|
45
|
+
callback(null, [{ address: ip, family }]);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
38
48
|
callback(null, ip, family);
|
|
39
49
|
},
|
|
40
50
|
},
|
|
@@ -190,6 +190,18 @@ export type VideoOutputOptions = {
|
|
|
190
190
|
* `image` Buffer argument passed to `generate()`.
|
|
191
191
|
*/
|
|
192
192
|
imageUrl?: string;
|
|
193
|
+
/**
|
|
194
|
+
* Replicate only: the input-schema key the model expects the image under.
|
|
195
|
+
* Replicate image-to-video models disagree on this — e.g.
|
|
196
|
+
* `minimax/hailuo-2.3-fast` requires `first_frame_image`,
|
|
197
|
+
* `wan-video/wan-2.7-i2v` requires `first_frame` — and a model whose
|
|
198
|
+
* required image key is missing fails the prediction on submit. Setting
|
|
199
|
+
* this also switches the payload to the modern `duration`/`resolution`
|
|
200
|
+
* field shape those models expect (instead of the legacy
|
|
201
|
+
* `num_frames`/`fps`/`aspect_ratio` shape). Omit for models that accept
|
|
202
|
+
* the default `image` key.
|
|
203
|
+
*/
|
|
204
|
+
imageInputKey?: string;
|
|
193
205
|
/**
|
|
194
206
|
* Per-call provider credentials. Takes precedence over instance-level
|
|
195
207
|
* credentials set at construction time, which in turn override env vars.
|
package/dist/utils/safeFetch.js
CHANGED
|
@@ -28,13 +28,23 @@ const DEFAULT_TIMEOUT_MS = 60_000;
|
|
|
28
28
|
function buildPinnedAgent(hostname, ip, family) {
|
|
29
29
|
return new Agent({
|
|
30
30
|
connect: {
|
|
31
|
-
lookup: (host,
|
|
31
|
+
lookup: (host, options, callback) => {
|
|
32
32
|
if (host.toLowerCase() !== hostname.toLowerCase()) {
|
|
33
33
|
// The host the connect layer asks for differs from the URL host —
|
|
34
34
|
// this happens for absolute Host headers etc. Reject defensively.
|
|
35
35
|
callback(new Error(`safeFetch: refusing to resolve "${host}" — expected "${hostname}"`), "", 0);
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
+
// Node ≥20 enables autoSelectFamily (Happy Eyeballs) by default, and
|
|
39
|
+
// its lookup contract passes `all: true` expecting an address ARRAY.
|
|
40
|
+
// Answering with the string form there fails the connection with
|
|
41
|
+
// "Invalid IP address: undefined" — which broke every safeDownload
|
|
42
|
+
// (Replicate / Runway / Kling asset fetches) on modern Node while
|
|
43
|
+
// plain curl of the same URL succeeded.
|
|
44
|
+
if (options?.all) {
|
|
45
|
+
callback(null, [{ address: ip, family }]);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
38
48
|
callback(null, ip, family);
|
|
39
49
|
},
|
|
40
50
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.87.1",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (58+ servers), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
|
|
6
6
|
"author": {
|