@decartai/sdk 0.0.26 → 0.0.28

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/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { ImageModelDefinition, ImageModels, Model, ModelDefinition, RealTimeModels, VideoModelDefinition, VideoModels, models } from "./shared/model.js";
1
+ import { ImageModelDefinition, ImageModels, Model, ModelDefinition, RealTimeModels, VideoModelDefinition, VideoModels, isImageModel, isRealtimeModel, isVideoModel, models } from "./shared/model.js";
2
2
  import { FileInput, ProcessOptions } from "./process/types.js";
3
3
  import { ProcessClient } from "./process/client.js";
4
4
  import { JobStatus, JobStatusResponse, JobSubmitResponse, QueueJobResult, QueueSubmitAndPollOptions, QueueSubmitOptions } from "./queue/types.js";
5
5
  import { QueueClient } from "./queue/client.js";
6
6
  import { DecartSDKError, ERROR_CODES } from "./utils/errors.js";
7
- import { RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState } from "./realtime/client.js";
7
+ import { AvatarOptions, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState } from "./realtime/client.js";
8
8
  import { ModelState } from "./shared/types.js";
9
9
  import { CreateTokenResponse, TokensClient } from "./tokens/client.js";
10
10
  import { z } from "zod";
@@ -35,7 +35,7 @@ type DecartClientOptions = z.infer<typeof decartClientOptionsSchema>;
35
35
  */
36
36
  declare const createDecartClient: (options?: DecartClientOptions) => {
37
37
  realtime: {
38
- connect: (stream: MediaStream, options: RealTimeClientConnectOptions) => Promise<RealTimeClient>;
38
+ connect: (stream: MediaStream | null, options: RealTimeClientConnectOptions) => Promise<RealTimeClient>;
39
39
  };
40
40
  /**
41
41
  * Client for synchronous image generation.
@@ -109,4 +109,4 @@ declare const createDecartClient: (options?: DecartClientOptions) => {
109
109
  tokens: TokensClient;
110
110
  };
111
111
  //#endregion
112
- export { type CreateTokenResponse, DecartClientOptions, type DecartSDKError, ERROR_CODES, type FileInput, type ImageModelDefinition, type ImageModels, type JobStatus, type JobStatusResponse, type JobSubmitResponse, type Model, type ModelDefinition, type ModelState, type ProcessClient, type ProcessOptions, type QueueClient, type QueueJobResult, type QueueSubmitAndPollOptions, type QueueSubmitOptions, type RealTimeClient, type RealTimeClientConnectOptions, type RealTimeClientInitialState, type RealTimeModels, type TokensClient, type VideoModelDefinition, type VideoModels, createDecartClient, models };
112
+ export { type AvatarOptions, type CreateTokenResponse, DecartClientOptions, type DecartSDKError, ERROR_CODES, type FileInput, type ImageModelDefinition, type ImageModels, type JobStatus, type JobStatusResponse, type JobSubmitResponse, type Model, type ModelDefinition, type ModelState, type ProcessClient, type ProcessOptions, type QueueClient, type QueueJobResult, type QueueSubmitAndPollOptions, type QueueSubmitOptions, type RealTimeClient, type RealTimeClientConnectOptions, type RealTimeClientInitialState, type RealTimeModels, type TokensClient, type VideoModelDefinition, type VideoModels, createDecartClient, isImageModel, isRealtimeModel, isVideoModel, models };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ERROR_CODES, createInvalidApiKeyError, createInvalidBaseUrlError } from "./utils/errors.js";
2
2
  import { createProcessClient } from "./process/client.js";
3
3
  import { createQueueClient } from "./queue/client.js";
4
- import { models } from "./shared/model.js";
4
+ import { isImageModel, isRealtimeModel, isVideoModel, models } from "./shared/model.js";
5
5
  import { createRealTimeClient } from "./realtime/client.js";
6
6
  import { createTokensClient } from "./tokens/client.js";
7
7
  import { readEnv } from "./utils/env.js";
@@ -67,4 +67,4 @@ const createDecartClient = (options = {}) => {
67
67
  };
68
68
 
69
69
  //#endregion
70
- export { ERROR_CODES, createDecartClient, models };
70
+ export { ERROR_CODES, createDecartClient, isImageModel, isRealtimeModel, isVideoModel, models };
@@ -0,0 +1,90 @@
1
+ //#region src/realtime/audio-stream-manager.ts
2
+ /**
3
+ * Manages an audio stream for avatar-live mode.
4
+ * Creates a continuous audio stream that outputs silence by default,
5
+ * and allows playing audio files through the stream.
6
+ */
7
+ var AudioStreamManager = class {
8
+ audioContext;
9
+ destination;
10
+ silenceOscillator;
11
+ silenceGain;
12
+ currentSource = null;
13
+ _isPlaying = false;
14
+ constructor() {
15
+ this.audioContext = new AudioContext();
16
+ this.destination = this.audioContext.createMediaStreamDestination();
17
+ this.silenceOscillator = this.audioContext.createOscillator();
18
+ this.silenceGain = this.audioContext.createGain();
19
+ this.silenceGain.gain.value = 0;
20
+ this.silenceOscillator.connect(this.silenceGain);
21
+ this.silenceGain.connect(this.destination);
22
+ this.silenceOscillator.start();
23
+ }
24
+ /**
25
+ * Get the MediaStream to pass to WebRTC.
26
+ * This stream outputs silence when no audio is playing.
27
+ */
28
+ getStream() {
29
+ return this.destination.stream;
30
+ }
31
+ /**
32
+ * Check if audio is currently playing.
33
+ */
34
+ isPlaying() {
35
+ return this._isPlaying;
36
+ }
37
+ /**
38
+ * Play audio through the stream.
39
+ * When the audio ends, the stream automatically reverts to silence.
40
+ * @param audio - Audio data as Blob, File, or ArrayBuffer
41
+ * @returns Promise that resolves when audio finishes playing
42
+ */
43
+ async playAudio(audio) {
44
+ if (this.audioContext.state === "suspended") await this.audioContext.resume();
45
+ if (this._isPlaying) this.stopAudio();
46
+ let arrayBuffer;
47
+ if (audio instanceof ArrayBuffer) arrayBuffer = audio;
48
+ else arrayBuffer = await audio.arrayBuffer();
49
+ const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);
50
+ const source = this.audioContext.createBufferSource();
51
+ source.buffer = audioBuffer;
52
+ source.connect(this.destination);
53
+ this.currentSource = source;
54
+ this._isPlaying = true;
55
+ return new Promise((resolve) => {
56
+ source.onended = () => {
57
+ this._isPlaying = false;
58
+ this.currentSource = null;
59
+ resolve();
60
+ };
61
+ source.start();
62
+ });
63
+ }
64
+ /**
65
+ * Stop currently playing audio immediately.
66
+ * The stream will revert to silence.
67
+ */
68
+ stopAudio() {
69
+ if (this.currentSource) {
70
+ try {
71
+ this.currentSource.stop();
72
+ } catch {}
73
+ this.currentSource = null;
74
+ }
75
+ this._isPlaying = false;
76
+ }
77
+ /**
78
+ * Clean up resources.
79
+ */
80
+ cleanup() {
81
+ this.stopAudio();
82
+ try {
83
+ this.silenceOscillator.stop();
84
+ } catch {}
85
+ this.audioContext.close();
86
+ }
87
+ };
88
+
89
+ //#endregion
90
+ export { AudioStreamManager };
@@ -11,9 +11,13 @@ declare const realTimeClientInitialStateSchema: z.ZodObject<{
11
11
  }, z.core.$strip>;
12
12
  type OnRemoteStreamFn = (stream: MediaStream) => void;
13
13
  type RealTimeClientInitialState = z.infer<typeof realTimeClientInitialStateSchema>;
14
+ declare const avatarOptionsSchema: z.ZodObject<{
15
+ avatarImage: z.ZodUnion<readonly [z.ZodCustom<Blob, Blob>, z.ZodCustom<File, File>, z.ZodString]>;
16
+ }, z.core.$strip>;
17
+ type AvatarOptions = z.infer<typeof avatarOptionsSchema>;
14
18
  declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
15
19
  model: z.ZodObject<{
16
- name: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"mirage_v2">, z.ZodLiteral<"lucy_v2v_720p_rt">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-dev-i2v">, z.ZodLiteral<"lucy-fast-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">, z.ZodLiteral<"lucy-motion">, z.ZodLiteral<"lucy-restyle-v2v">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-pro-t2i">, z.ZodLiteral<"lucy-pro-i2i">]>]>;
20
+ name: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"mirage_v2">, z.ZodLiteral<"lucy_v2v_720p_rt">, z.ZodLiteral<"avatar-live">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-dev-i2v">, z.ZodLiteral<"lucy-fast-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">, z.ZodLiteral<"lucy-motion">, z.ZodLiteral<"lucy-restyle-v2v">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-pro-t2i">, z.ZodLiteral<"lucy-pro-i2i">]>]>;
17
21
  urlPath: z.ZodString;
18
22
  queueUrlPath: z.ZodOptional<z.ZodString>;
19
23
  fps: z.ZodNumber;
@@ -29,6 +33,9 @@ declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
29
33
  }, z.core.$strip>>;
30
34
  }, z.core.$strip>>;
31
35
  customizeOffer: z.ZodOptional<z.ZodCustom<z.core.$InferInnerFunctionTypeAsync<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>, z.core.$InferInnerFunctionTypeAsync<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>>;
36
+ avatar: z.ZodOptional<z.ZodObject<{
37
+ avatarImage: z.ZodUnion<readonly [z.ZodCustom<Blob, Blob>, z.ZodCustom<File, File>, z.ZodString]>;
38
+ }, z.core.$strip>>;
32
39
  }, z.core.$strip>;
33
40
  type RealTimeClientConnectOptions = z.infer<typeof realTimeClientConnectOptionsSchema>;
34
41
  type Events = {
@@ -47,6 +54,8 @@ type RealTimeClient = {
47
54
  on: <K extends keyof Events>(event: K, listener: (data: Events[K]) => void) => void;
48
55
  off: <K extends keyof Events>(event: K, listener: (data: Events[K]) => void) => void;
49
56
  sessionId: string;
57
+ setImage: (image: Blob | File | string) => Promise<void>;
58
+ playAudio?: (audio: Blob | File | ArrayBuffer) => Promise<void>;
50
59
  };
51
60
  //#endregion
52
- export { RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState };
61
+ export { AvatarOptions, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState };
@@ -1,6 +1,7 @@
1
1
  import { createWebrtcError } from "../utils/errors.js";
2
2
  import { modelDefinitionSchema } from "../shared/model.js";
3
3
  import { modelStateSchema } from "../shared/types.js";
4
+ import { AudioStreamManager } from "./audio-stream-manager.js";
4
5
  import { realtimeMethods } from "./methods.js";
5
6
  import { WebRTCManager } from "./webrtc-manager.js";
6
7
  import { z } from "zod";
@@ -8,13 +9,30 @@ import mitt from "mitt";
8
9
  import { v4 } from "uuid";
9
10
 
10
11
  //#region src/realtime/client.ts
12
+ async function blobToBase64(blob) {
13
+ return new Promise((resolve, reject) => {
14
+ const reader = new FileReader();
15
+ reader.onloadend = () => {
16
+ const base64 = reader.result.split(",")[1];
17
+ resolve(base64);
18
+ };
19
+ reader.onerror = reject;
20
+ reader.readAsDataURL(blob);
21
+ });
22
+ }
11
23
  const realTimeClientInitialStateSchema = modelStateSchema;
12
24
  const createAsyncFunctionSchema = (schema) => z.custom((fn) => schema.implementAsync(fn));
25
+ const avatarOptionsSchema = z.object({ avatarImage: z.union([
26
+ z.instanceof(Blob),
27
+ z.instanceof(File),
28
+ z.string()
29
+ ]) });
13
30
  const realTimeClientConnectOptionsSchema = z.object({
14
31
  model: modelDefinitionSchema,
15
32
  onRemoteStream: z.custom((val) => typeof val === "function", { message: "onRemoteStream must be a function" }),
16
33
  initialState: realTimeClientInitialStateSchema.optional(),
17
- customizeOffer: createAsyncFunctionSchema(z.function()).optional()
34
+ customizeOffer: createAsyncFunctionSchema(z.function()).optional(),
35
+ avatar: avatarOptionsSchema.optional()
18
36
  });
19
37
  const createRealTimeClient = (opts) => {
20
38
  const { baseUrl, apiKey, integration } = opts;
@@ -23,7 +41,21 @@ const createRealTimeClient = (opts) => {
23
41
  const parsedOptions = realTimeClientConnectOptionsSchema.safeParse(options);
24
42
  if (!parsedOptions.success) throw parsedOptions.error;
25
43
  const sessionId = v4();
26
- const { onRemoteStream, initialState } = parsedOptions.data;
44
+ const isAvatarLive = options.model.name === "avatar-live";
45
+ const { onRemoteStream, initialState, avatar } = parsedOptions.data;
46
+ let audioStreamManager;
47
+ let inputStream;
48
+ if (isAvatarLive && !stream) {
49
+ audioStreamManager = new AudioStreamManager();
50
+ inputStream = audioStreamManager.getStream();
51
+ } else inputStream = stream ?? new MediaStream();
52
+ let avatarImageBase64;
53
+ if (isAvatarLive && avatar?.avatarImage) {
54
+ let imageBlob;
55
+ if (typeof avatar.avatarImage === "string") imageBlob = await (await fetch(avatar.avatarImage)).blob();
56
+ else imageBlob = avatar.avatarImage;
57
+ avatarImageBase64 = await blobToBase64(imageBlob);
58
+ }
27
59
  const webrtcManager = new WebRTCManager({
28
60
  webrtcUrl: `${`${baseUrl}${options.model.urlPath}`}?api_key=${apiKey}&model=${options.model.name}`,
29
61
  apiKey,
@@ -41,9 +73,11 @@ const createRealTimeClient = (opts) => {
41
73
  },
42
74
  customizeOffer: options.customizeOffer,
43
75
  vp8MinBitrate: 300,
44
- vp8StartBitrate: 600
76
+ vp8StartBitrate: 600,
77
+ isAvatarLive,
78
+ avatarImageBase64
45
79
  });
46
- await webrtcManager.connect(stream);
80
+ await webrtcManager.connect(inputStream);
47
81
  const methods = realtimeMethods(webrtcManager);
48
82
  if (options.initialState) {
49
83
  if (options.initialState.prompt) {
@@ -51,15 +85,36 @@ const createRealTimeClient = (opts) => {
51
85
  methods.setPrompt(text, { enhance });
52
86
  }
53
87
  }
54
- return {
88
+ const client = {
55
89
  setPrompt: methods.setPrompt,
56
90
  isConnected: () => webrtcManager.isConnected(),
57
91
  getConnectionState: () => webrtcManager.getConnectionState(),
58
- disconnect: () => webrtcManager.cleanup(),
92
+ disconnect: () => {
93
+ webrtcManager.cleanup();
94
+ audioStreamManager?.cleanup();
95
+ },
59
96
  on: eventEmitter.on,
60
97
  off: eventEmitter.off,
61
- sessionId
98
+ sessionId,
99
+ setImage: async (image) => {
100
+ let imageBase64;
101
+ if (typeof image === "string") {
102
+ let url = null;
103
+ try {
104
+ url = new URL(image);
105
+ } catch {}
106
+ if (url?.protocol === "data:") imageBase64 = image.split(",")[1];
107
+ else if (url?.protocol === "http:" || url?.protocol === "https:") imageBase64 = await blobToBase64(await (await fetch(image)).blob());
108
+ else imageBase64 = image;
109
+ } else imageBase64 = await blobToBase64(image);
110
+ return webrtcManager.setImage(imageBase64);
111
+ }
62
112
  };
113
+ if (isAvatarLive && audioStreamManager) {
114
+ const manager = audioStreamManager;
115
+ client.playAudio = (audio) => manager.playAudio(audio);
116
+ }
117
+ return client;
63
118
  };
64
119
  return { connect };
65
120
  };
@@ -3,6 +3,7 @@ import mitt from "mitt";
3
3
 
4
4
  //#region src/realtime/webrtc-connection.ts
5
5
  const ICE_SERVERS = [{ urls: "stun:stun.l.google.com:19302" }];
6
+ const AVATAR_SETUP_TIMEOUT_MS = 15e3;
6
7
  var WebRTCConnection = class {
7
8
  pc = null;
8
9
  ws = null;
@@ -38,6 +39,7 @@ var WebRTCConnection = class {
38
39
  };
39
40
  this.ws.onclose = () => this.setState("disconnected");
40
41
  });
42
+ if (this.callbacks.avatarImageBase64) await this.sendAvatarImage(this.callbacks.avatarImageBase64);
41
43
  await this.setupNewPeerConnection();
42
44
  return new Promise((resolve, reject) => {
43
45
  this.connectionReject = reject;
@@ -55,18 +57,22 @@ var WebRTCConnection = class {
55
57
  });
56
58
  }
57
59
  async handleSignalingMessage(msg) {
58
- if (!this.pc) return;
59
60
  try {
60
- switch (msg.type) {
61
- case "error": {
62
- const error = new Error(msg.error);
63
- this.callbacks.onError?.(error);
64
- if (this.connectionReject) {
65
- this.connectionReject(error);
66
- this.connectionReject = null;
67
- }
68
- break;
61
+ if (msg.type === "error") {
62
+ const error = new Error(msg.error);
63
+ this.callbacks.onError?.(error);
64
+ if (this.connectionReject) {
65
+ this.connectionReject(error);
66
+ this.connectionReject = null;
69
67
  }
68
+ return;
69
+ }
70
+ if (msg.type === "image_set") {
71
+ this.websocketMessagesEmitter.emit("imageSet", msg);
72
+ return;
73
+ }
74
+ if (!this.pc) return;
75
+ switch (msg.type) {
70
76
  case "ready": {
71
77
  await this.applyCodecPreference("video/VP8");
72
78
  const offer = await this.pc.createOffer();
@@ -118,10 +124,35 @@ var WebRTCConnection = class {
118
124
  send(message) {
119
125
  if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(message));
120
126
  }
127
+ async sendAvatarImage(imageBase64) {
128
+ return this.setImageBase64(imageBase64);
129
+ }
130
+ /**
131
+ * Send an image to the server (e.g., as a reference for inference).
132
+ * Can be called after connection is established.
133
+ */
134
+ async setImageBase64(imageBase64) {
135
+ return new Promise((resolve, reject) => {
136
+ const timeoutId = setTimeout(() => {
137
+ this.websocketMessagesEmitter.off("imageSet", listener);
138
+ reject(/* @__PURE__ */ new Error("Image send timed out"));
139
+ }, AVATAR_SETUP_TIMEOUT_MS);
140
+ const listener = (msg) => {
141
+ clearTimeout(timeoutId);
142
+ this.websocketMessagesEmitter.off("imageSet", listener);
143
+ if (msg.status === "success") resolve();
144
+ else reject(/* @__PURE__ */ new Error(`Failed to send image: ${msg.status}`));
145
+ };
146
+ this.websocketMessagesEmitter.on("imageSet", listener);
147
+ this.send({
148
+ type: "set_image",
149
+ image_data: imageBase64
150
+ });
151
+ });
152
+ }
121
153
  setState(state) {
122
154
  if (this.state !== state) {
123
155
  this.state = state;
124
- console.log(`[WebRTC] State: ${state}`);
125
156
  this.callbacks.onStateChange?.(state);
126
157
  }
127
158
  }
@@ -140,6 +171,7 @@ var WebRTCConnection = class {
140
171
  username: turnConfig.username
141
172
  });
142
173
  this.pc = new RTCPeerConnection({ iceServers });
174
+ if (this.callbacks.isAvatarLive) this.pc.addTransceiver("video", { direction: "recvonly" });
143
175
  this.localStream.getTracks().forEach((track) => {
144
176
  if (this.pc && this.localStream) this.pc.addTrack(track, this.localStream);
145
177
  });
@@ -173,7 +205,7 @@ var WebRTCConnection = class {
173
205
  }
174
206
  async applyCodecPreference(preferredCodecName) {
175
207
  if (!this.pc) return;
176
- const videoTransceiver = this.pc.getTransceivers().find((r) => r.sender.track?.kind === "video");
208
+ const videoTransceiver = this.pc.getTransceivers().find((r) => r.sender.track?.kind === "video" || r.receiver.track?.kind === "video");
177
209
  if (!videoTransceiver) {
178
210
  console.error("Could not find video transceiver. Ensure track is added to peer connection.");
179
211
  return;
@@ -21,7 +21,9 @@ var WebRTCManager = class {
21
21
  onError: config.onError,
22
22
  customizeOffer: config.customizeOffer,
23
23
  vp8MinBitrate: config.vp8MinBitrate,
24
- vp8StartBitrate: config.vp8StartBitrate
24
+ vp8StartBitrate: config.vp8StartBitrate,
25
+ isAvatarLive: config.isAvatarLive,
26
+ avatarImageBase64: config.avatarImageBase64
25
27
  });
26
28
  }
27
29
  async connect(localStream) {
@@ -58,6 +60,9 @@ var WebRTCManager = class {
58
60
  getWebsocketMessageEmitter() {
59
61
  return this.connection.websocketMessagesEmitter;
60
62
  }
63
+ setImage(imageBase64) {
64
+ return this.connection.setImageBase64(imageBase64);
65
+ }
61
66
  };
62
67
 
63
68
  //#endregion
@@ -1,14 +1,17 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  //#region src/shared/model.d.ts
4
- declare const realtimeModels: z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"mirage_v2">, z.ZodLiteral<"lucy_v2v_720p_rt">]>;
4
+ declare const realtimeModels: z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"mirage_v2">, z.ZodLiteral<"lucy_v2v_720p_rt">, z.ZodLiteral<"avatar-live">]>;
5
5
  declare const videoModels: z.ZodUnion<readonly [z.ZodLiteral<"lucy-dev-i2v">, z.ZodLiteral<"lucy-fast-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">, z.ZodLiteral<"lucy-motion">, z.ZodLiteral<"lucy-restyle-v2v">]>;
6
6
  declare const imageModels: z.ZodUnion<readonly [z.ZodLiteral<"lucy-pro-t2i">, z.ZodLiteral<"lucy-pro-i2i">]>;
7
- declare const modelSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"mirage_v2">, z.ZodLiteral<"lucy_v2v_720p_rt">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-dev-i2v">, z.ZodLiteral<"lucy-fast-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">, z.ZodLiteral<"lucy-motion">, z.ZodLiteral<"lucy-restyle-v2v">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-pro-t2i">, z.ZodLiteral<"lucy-pro-i2i">]>]>;
7
+ declare const modelSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"mirage_v2">, z.ZodLiteral<"lucy_v2v_720p_rt">, z.ZodLiteral<"avatar-live">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-dev-i2v">, z.ZodLiteral<"lucy-fast-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">, z.ZodLiteral<"lucy-motion">, z.ZodLiteral<"lucy-restyle-v2v">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-pro-t2i">, z.ZodLiteral<"lucy-pro-i2i">]>]>;
8
8
  type Model = z.infer<typeof modelSchema>;
9
9
  type RealTimeModels = z.infer<typeof realtimeModels>;
10
10
  type VideoModels = z.infer<typeof videoModels>;
11
11
  type ImageModels = z.infer<typeof imageModels>;
12
+ declare function isRealtimeModel(model: string): model is RealTimeModels;
13
+ declare function isVideoModel(model: string): model is VideoModels;
14
+ declare function isImageModel(model: string): model is ImageModels;
12
15
  declare const modelInputSchemas: {
13
16
  readonly "lucy-pro-t2v": z.ZodObject<{
14
17
  prompt: z.ZodString;
@@ -141,4 +144,4 @@ declare const models: {
141
144
  image: <T extends ImageModels>(model: T) => ModelDefinition<T>;
142
145
  };
143
146
  //#endregion
144
- export { ImageModelDefinition, ImageModels, Model, ModelDefinition, ModelInputSchemas, RealTimeModels, VideoModelDefinition, VideoModels, models };
147
+ export { ImageModelDefinition, ImageModels, Model, ModelDefinition, ModelInputSchemas, RealTimeModels, VideoModelDefinition, VideoModels, isImageModel, isRealtimeModel, isVideoModel, models };
@@ -5,7 +5,8 @@ import { z } from "zod";
5
5
  const realtimeModels = z.union([
6
6
  z.literal("mirage"),
7
7
  z.literal("mirage_v2"),
8
- z.literal("lucy_v2v_720p_rt")
8
+ z.literal("lucy_v2v_720p_rt"),
9
+ z.literal("avatar-live")
9
10
  ]);
10
11
  const videoModels = z.union([
11
12
  z.literal("lucy-dev-i2v"),
@@ -23,6 +24,15 @@ const modelSchema = z.union([
23
24
  videoModels,
24
25
  imageModels
25
26
  ]);
27
+ function isRealtimeModel(model) {
28
+ return realtimeModels.safeParse(model).success;
29
+ }
30
+ function isVideoModel(model) {
31
+ return videoModels.safeParse(model).success;
32
+ }
33
+ function isImageModel(model) {
34
+ return imageModels.safeParse(model).success;
35
+ }
26
36
  const fileInputSchema = z.union([
27
37
  z.instanceof(File),
28
38
  z.instanceof(Blob),
@@ -155,6 +165,14 @@ const _models = {
155
165
  width: 1280,
156
166
  height: 704,
157
167
  inputSchema: z.object({})
168
+ },
169
+ "avatar-live": {
170
+ urlPath: "/v1/avatar-live/stream",
171
+ name: "avatar-live",
172
+ fps: 25,
173
+ width: 1280,
174
+ height: 720,
175
+ inputSchema: z.object({})
158
176
  }
159
177
  },
160
178
  image: {
@@ -271,4 +289,4 @@ const models = {
271
289
  };
272
290
 
273
291
  //#endregion
274
- export { modelDefinitionSchema, models };
292
+ export { isImageModel, isRealtimeModel, isVideoModel, modelDefinitionSchema, models };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decartai/sdk",
3
- "version": "0.0.26",
3
+ "version": "0.0.28",
4
4
  "description": "Decart's JavaScript SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",