@decartai/sdk 0.0.32 → 0.0.34

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.
@@ -49,6 +49,27 @@ interface VideoModelInputs {
49
49
  */
50
50
  data?: FileInput;
51
51
  }
52
+ /**
53
+ * Model-specific input documentation for lucy-pro-v2v.
54
+ */
55
+ interface VideoEditInputs {
56
+ /**
57
+ * Text description to use for the video editing.
58
+ *
59
+ * See our [Prompt Engineering](https://docs.platform.decart.ai/models/video/video-generation#prompt-engineering) guide for how to write prompt for Decart video models effectively.
60
+ */
61
+ prompt: string;
62
+ /**
63
+ * Video file to process.
64
+ * Can be a File, Blob, ReadableStream, URL, or string URL.
65
+ */
66
+ data: FileInput;
67
+ /**
68
+ * Optional reference image to guide what to add to the video.
69
+ * Can be a File, Blob, ReadableStream, URL, or string URL.
70
+ */
71
+ reference_image?: FileInput;
72
+ }
52
73
  /**
53
74
  * Model-specific input documentation for lucy-restyle-v2v.
54
75
  * Allows either prompt or reference_image (mutually exclusive).
@@ -85,7 +106,7 @@ interface PromptInput {
85
106
  * This allows different models to have field-specific documentation while maintaining type safety.
86
107
  * Specific models are checked first, then falls back to category-based selection.
87
108
  */
88
- type ModelSpecificInputs<T extends ModelDefinition> = T["name"] extends "lucy-pro-i2i" ? ImageEditingInputs : T["name"] extends "lucy-restyle-v2v" ? VideoRestyleInputs : T["name"] extends ImageModels ? ImageGenerationInputs : T["name"] extends VideoModels ? VideoModelInputs : PromptInput;
109
+ type ModelSpecificInputs<T extends ModelDefinition> = T["name"] extends "lucy-pro-i2i" ? ImageEditingInputs : T["name"] extends "lucy-restyle-v2v" ? VideoRestyleInputs : T["name"] extends "lucy-pro-v2v" ? VideoEditInputs : T["name"] extends ImageModels ? ImageGenerationInputs : T["name"] extends VideoModels ? VideoModelInputs : PromptInput;
89
110
  interface ProcessInputs {
90
111
  /**
91
112
  * Random seed for reproducible results.
@@ -56,6 +56,10 @@ const createRealTimeClient = (opts) => {
56
56
  else imageBlob = avatar.avatarImage;
57
57
  avatarImageBase64 = await blobToBase64(imageBlob);
58
58
  }
59
+ const initialPrompt = isAvatarLive && options.initialState?.prompt ? {
60
+ text: options.initialState.prompt.text,
61
+ enhance: options.initialState.prompt.enhance
62
+ } : void 0;
59
63
  const webrtcManager = new WebRTCManager({
60
64
  webrtcUrl: `${`${baseUrl}${options.model.urlPath}`}?api_key=${apiKey}&model=${options.model.name}`,
61
65
  apiKey,
@@ -75,15 +79,14 @@ const createRealTimeClient = (opts) => {
75
79
  vp8MinBitrate: 300,
76
80
  vp8StartBitrate: 600,
77
81
  isAvatarLive,
78
- avatarImageBase64
82
+ avatarImageBase64,
83
+ initialPrompt
79
84
  });
80
85
  await webrtcManager.connect(inputStream);
81
86
  const methods = realtimeMethods(webrtcManager);
82
- if (options.initialState) {
83
- if (options.initialState.prompt) {
84
- const { text, enhance } = options.initialState.prompt;
85
- methods.setPrompt(text, { enhance });
86
- }
87
+ if (!isAvatarLive && options.initialState?.prompt) {
88
+ const { text, enhance } = options.initialState.prompt;
89
+ methods.setPrompt(text, { enhance });
87
90
  }
88
91
  const client = {
89
92
  setPrompt: methods.setPrompt,
@@ -40,6 +40,7 @@ var WebRTCConnection = class {
40
40
  this.ws.onclose = () => this.setState("disconnected");
41
41
  });
42
42
  if (this.callbacks.avatarImageBase64) await this.sendAvatarImage(this.callbacks.avatarImageBase64);
43
+ if (this.callbacks.initialPrompt) await this.sendInitialPrompt(this.callbacks.initialPrompt);
43
44
  await this.setupNewPeerConnection();
44
45
  return new Promise((resolve, reject) => {
45
46
  this.connectionReject = reject;
@@ -71,6 +72,10 @@ var WebRTCConnection = class {
71
72
  this.websocketMessagesEmitter.emit("setImageAck", msg);
72
73
  return;
73
74
  }
75
+ if (msg.type === "prompt_ack") {
76
+ this.websocketMessagesEmitter.emit("promptAck", msg);
77
+ return;
78
+ }
74
79
  if (!this.pc) return;
75
80
  switch (msg.type) {
76
81
  case "ready": {
@@ -112,9 +117,6 @@ var WebRTCConnection = class {
112
117
  if (turnConfig) await this.setupNewPeerConnection(turnConfig);
113
118
  break;
114
119
  }
115
- case "prompt_ack":
116
- this.websocketMessagesEmitter.emit("promptAck", msg);
117
- break;
118
120
  }
119
121
  } catch (error) {
120
122
  console.error("[WebRTC] Error:", error);
@@ -150,6 +152,31 @@ var WebRTCConnection = class {
150
152
  });
151
153
  });
152
154
  }
155
+ /**
156
+ * Send the initial prompt to the server before WebRTC handshake.
157
+ */
158
+ async sendInitialPrompt(prompt) {
159
+ return new Promise((resolve, reject) => {
160
+ const timeoutId = setTimeout(() => {
161
+ this.websocketMessagesEmitter.off("promptAck", listener);
162
+ reject(/* @__PURE__ */ new Error("Prompt send timed out"));
163
+ }, AVATAR_SETUP_TIMEOUT_MS);
164
+ const listener = (msg) => {
165
+ if (msg.prompt === prompt.text) {
166
+ clearTimeout(timeoutId);
167
+ this.websocketMessagesEmitter.off("promptAck", listener);
168
+ if (msg.success) resolve();
169
+ else reject(new Error(msg.error ?? "Failed to send prompt"));
170
+ }
171
+ };
172
+ this.websocketMessagesEmitter.on("promptAck", listener);
173
+ this.send({
174
+ type: "prompt",
175
+ prompt: prompt.text,
176
+ enhance_prompt: prompt.enhance ?? true
177
+ });
178
+ });
179
+ }
153
180
  setState(state) {
154
181
  if (this.state !== state) {
155
182
  this.state = state;
@@ -23,7 +23,8 @@ var WebRTCManager = class {
23
23
  vp8MinBitrate: config.vp8MinBitrate,
24
24
  vp8StartBitrate: config.vp8StartBitrate,
25
25
  isAvatarLive: config.isAvatarLive,
26
- avatarImageBase64: config.avatarImageBase64
26
+ avatarImageBase64: config.avatarImageBase64,
27
+ initialPrompt: config.initialPrompt
27
28
  });
28
29
  }
29
30
  async connect(localStream) {
@@ -49,6 +49,7 @@ declare const modelInputSchemas: {
49
49
  readonly "lucy-pro-v2v": z.ZodObject<{
50
50
  prompt: z.ZodString;
51
51
  data: z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>;
52
+ reference_image: z.ZodOptional<z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>>;
52
53
  seed: z.ZodOptional<z.ZodNumber>;
53
54
  resolution: z.ZodDefault<z.ZodOptional<z.ZodLiteral<"720p">>>;
54
55
  enhance_prompt: z.ZodOptional<z.ZodBoolean>;
@@ -87,6 +87,7 @@ const modelInputSchemas = {
87
87
  "lucy-pro-v2v": z.object({
88
88
  prompt: z.string().min(1).max(1e3).describe("The prompt to use for the generation"),
89
89
  data: fileInputSchema.describe("The video data to use for generation (File, Blob, ReadableStream, URL, or string URL). Output video is limited to 5 seconds."),
90
+ reference_image: fileInputSchema.optional().describe("Optional reference image to guide what to add to the video (File, Blob, ReadableStream, URL, or string URL)"),
90
91
  seed: z.number().optional().describe("The seed to use for the generation"),
91
92
  resolution: proV2vResolutionSchema,
92
93
  enhance_prompt: z.boolean().optional().describe("Whether to enhance the prompt"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decartai/sdk",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "description": "Decart's JavaScript SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",