@decartai/sdk 0.0.68 → 0.1.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 (42) hide show
  1. package/README.md +49 -9
  2. package/dist/index.d.ts +6 -4
  3. package/dist/index.js +43 -28
  4. package/dist/process/client.js +1 -3
  5. package/dist/process/request.js +1 -3
  6. package/dist/queue/client.js +1 -3
  7. package/dist/queue/polling.js +1 -2
  8. package/dist/queue/request.js +1 -3
  9. package/dist/realtime/client.d.ts +17 -11
  10. package/dist/realtime/client.js +71 -155
  11. package/dist/realtime/config-realtime.js +49 -0
  12. package/dist/realtime/event-buffer.js +1 -3
  13. package/dist/realtime/initial-state-gate.js +21 -0
  14. package/dist/realtime/media-channel.js +82 -0
  15. package/dist/realtime/methods.js +12 -42
  16. package/dist/realtime/mirror-stream.js +1 -2
  17. package/dist/realtime/observability/diagnostics.d.ts +14 -53
  18. package/dist/realtime/observability/livekit-stats-provider.js +25 -0
  19. package/dist/realtime/observability/realtime-observability.js +70 -6
  20. package/dist/realtime/observability/telemetry-reporter.js +9 -28
  21. package/dist/realtime/observability/webrtc-stats.d.ts +5 -4
  22. package/dist/realtime/observability/webrtc-stats.js +3 -5
  23. package/dist/realtime/signaling-channel.js +286 -0
  24. package/dist/realtime/stream-session.js +252 -0
  25. package/dist/realtime/subscribe-client.d.ts +2 -3
  26. package/dist/realtime/subscribe-client.js +115 -11
  27. package/dist/realtime/types.d.ts +25 -1
  28. package/dist/shared/model.d.ts +11 -1
  29. package/dist/shared/model.js +51 -14
  30. package/dist/shared/request.js +1 -3
  31. package/dist/shared/types.js +1 -3
  32. package/dist/tokens/client.js +1 -3
  33. package/dist/utils/env.js +1 -2
  34. package/dist/utils/errors.js +1 -2
  35. package/dist/utils/logger.js +1 -2
  36. package/dist/utils/media.js +43 -0
  37. package/dist/utils/platform.js +13 -0
  38. package/dist/utils/user-agent.js +1 -3
  39. package/dist/version.js +1 -2
  40. package/package.json +2 -1
  41. package/dist/realtime/webrtc-connection.js +0 -500
  42. package/dist/realtime/webrtc-manager.js +0 -210
@@ -1,5 +1,29 @@
1
1
  //#region src/realtime/types.d.ts
2
2
 
3
+ type GenerationEndedMessage = GenerationEnded & {
4
+ type: "generation_ended";
5
+ };
6
+ type QueuePositionMessage = {
7
+ type: "queue_position";
8
+ position: number;
9
+ queue_size: number;
10
+ };
11
+ type QueuePosition = {
12
+ position: number;
13
+ queueSize: number;
14
+ };
3
15
  type ConnectionState = "connecting" | "connected" | "generating" | "disconnected" | "reconnecting";
16
+ type GenerationTick = {
17
+ seconds: number;
18
+ };
19
+ type GenerationEnded = {
20
+ seconds: number;
21
+ reason: string;
22
+ };
23
+ type ImageSetOptions = {
24
+ prompt?: string | null;
25
+ enhance?: boolean;
26
+ timeout?: number;
27
+ };
4
28
  //#endregion
5
- export { ConnectionState };
29
+ export { ConnectionState, GenerationEnded, GenerationEndedMessage, GenerationTick, ImageSetOptions, QueuePosition, QueuePositionMessage };
@@ -318,11 +318,17 @@ declare const modelInputSchemas: {
318
318
  }, z.core.$strip>;
319
319
  };
320
320
  type ModelInputSchemas = typeof modelInputSchemas;
321
+ type ModelFps = number | {
322
+ max?: number;
323
+ min?: number;
324
+ ideal?: number;
325
+ exact?: number;
326
+ };
321
327
  type ModelDefinition<T extends Model = Model> = {
322
328
  name: T;
323
329
  urlPath: string;
324
330
  queueUrlPath?: string;
325
- fps: number;
331
+ fps: ModelFps;
326
332
  width: number;
327
333
  height: number;
328
334
  inputSchema: T extends keyof ModelInputSchemas ? ModelInputSchemas[T] : z.ZodTypeAny;
@@ -341,6 +347,7 @@ type CustomModelDefinition = Omit<ModelDefinition, "name" | "inputSchema"> & {
341
347
  * Requires `queueUrlPath` to distinguish from realtime definitions of the same model name.
342
348
  */
343
349
  type ImageModelDefinition = ModelDefinition<ImageModels> & {
350
+ fps: number;
344
351
  queueUrlPath: string;
345
352
  };
346
353
  /**
@@ -349,6 +356,7 @@ type ImageModelDefinition = ModelDefinition<ImageModels> & {
349
356
  * Requires `queueUrlPath` to distinguish from realtime definitions of the same model name.
350
357
  */
351
358
  type VideoModelDefinition = ModelDefinition<VideoModels> & {
359
+ fps: number;
352
360
  queueUrlPath: string;
353
361
  };
354
362
  type ModelKind = "realtime" | "video" | "image";
@@ -386,6 +394,7 @@ declare const models: {
386
394
  * - `"lucy-restyle-2"` - Video restyling
387
395
  */
388
396
  video: <T extends VideoModels>(model: T) => ModelDefinition<T> & {
397
+ fps: number;
389
398
  queueUrlPath: string;
390
399
  };
391
400
  /**
@@ -395,6 +404,7 @@ declare const models: {
395
404
  * - `"lucy-image-2"` - Image-to-image editing
396
405
  */
397
406
  image: <T extends ImageModels>(model: T) => ModelDefinition<T> & {
407
+ fps: number;
398
408
  queueUrlPath: string;
399
409
  };
400
410
  };
@@ -1,6 +1,5 @@
1
1
  import { createModelNotFoundError } from "../utils/errors.js";
2
2
  import { z } from "zod";
3
-
4
3
  //#region src/shared/model.ts
5
4
  const CANONICAL_MODEL_NAMES = [
6
5
  "lucy-2.1",
@@ -195,11 +194,20 @@ const modelInputSchemas = {
195
194
  "lucy-pro-i2i": imageEditSchema,
196
195
  "lucy-restyle-v2v": restyleSchema
197
196
  };
197
+ function resolveFpsNumber(fps, fallback = 30) {
198
+ if (typeof fps === "number") return fps;
199
+ return fps.ideal ?? fps.max ?? fps.exact ?? fps.min ?? fallback;
200
+ }
198
201
  const modelDefinitionSchema = z.object({
199
202
  name: z.string(),
200
203
  urlPath: z.string(),
201
204
  queueUrlPath: z.string().optional(),
202
- fps: z.number().min(1),
205
+ fps: z.union([z.number().min(1), z.object({
206
+ max: z.number().min(1).optional(),
207
+ min: z.number().min(1).optional(),
208
+ ideal: z.number().min(1).optional(),
209
+ exact: z.number().min(1).optional()
210
+ })]),
203
211
  width: z.number().min(1),
204
212
  height: z.number().min(1),
205
213
  inputSchema: z.any().optional()
@@ -209,7 +217,10 @@ const _models = {
209
217
  "lucy-2.1": {
210
218
  urlPath: "/v1/stream",
211
219
  name: "lucy-2.1",
212
- fps: 20,
220
+ fps: {
221
+ ideal: 30,
222
+ max: 30
223
+ },
213
224
  width: 1088,
214
225
  height: 624,
215
226
  inputSchema: z.object({})
@@ -217,7 +228,10 @@ const _models = {
217
228
  "lucy-2.1-vton": {
218
229
  urlPath: "/v1/stream",
219
230
  name: "lucy-2.1-vton",
220
- fps: 20,
231
+ fps: {
232
+ ideal: 30,
233
+ max: 30
234
+ },
221
235
  width: 1088,
222
236
  height: 624,
223
237
  inputSchema: z.object({})
@@ -225,7 +239,10 @@ const _models = {
225
239
  "lucy-vton-2": {
226
240
  urlPath: "/v1/stream",
227
241
  name: "lucy-vton-2",
228
- fps: 20,
242
+ fps: {
243
+ ideal: 30,
244
+ max: 30
245
+ },
229
246
  width: 1088,
230
247
  height: 624,
231
248
  inputSchema: z.object({})
@@ -233,7 +250,10 @@ const _models = {
233
250
  "lucy-restyle-2": {
234
251
  urlPath: "/v1/stream",
235
252
  name: "lucy-restyle-2",
236
- fps: 22,
253
+ fps: {
254
+ ideal: 30,
255
+ max: 30
256
+ },
237
257
  width: 1280,
238
258
  height: 704,
239
259
  inputSchema: z.object({})
@@ -241,7 +261,10 @@ const _models = {
241
261
  "lucy-latest": {
242
262
  urlPath: "/v1/stream",
243
263
  name: "lucy-latest",
244
- fps: 20,
264
+ fps: {
265
+ ideal: 30,
266
+ max: 30
267
+ },
245
268
  width: 1088,
246
269
  height: 624,
247
270
  inputSchema: z.object({})
@@ -249,7 +272,10 @@ const _models = {
249
272
  "lucy-vton-latest": {
250
273
  urlPath: "/v1/stream",
251
274
  name: "lucy-vton-latest",
252
- fps: 20,
275
+ fps: {
276
+ ideal: 30,
277
+ max: 30
278
+ },
253
279
  width: 1088,
254
280
  height: 624,
255
281
  inputSchema: z.object({})
@@ -257,7 +283,10 @@ const _models = {
257
283
  "lucy-restyle-latest": {
258
284
  urlPath: "/v1/stream",
259
285
  name: "lucy-restyle-latest",
260
- fps: 22,
286
+ fps: {
287
+ ideal: 30,
288
+ max: 30
289
+ },
261
290
  width: 1280,
262
291
  height: 704,
263
292
  inputSchema: z.object({})
@@ -265,7 +294,10 @@ const _models = {
265
294
  mirage_v2: {
266
295
  urlPath: "/v1/stream",
267
296
  name: "mirage_v2",
268
- fps: 22,
297
+ fps: {
298
+ ideal: 30,
299
+ max: 30
300
+ },
269
301
  width: 1280,
270
302
  height: 704,
271
303
  inputSchema: z.object({})
@@ -273,7 +305,10 @@ const _models = {
273
305
  "lucy-vton": {
274
306
  urlPath: "/v1/stream",
275
307
  name: "lucy-vton",
276
- fps: 20,
308
+ fps: {
309
+ ideal: 30,
310
+ max: 30
311
+ },
277
312
  width: 1088,
278
313
  height: 624,
279
314
  inputSchema: z.object({})
@@ -281,7 +316,10 @@ const _models = {
281
316
  "lucy-2.1-vton-2": {
282
317
  urlPath: "/v1/stream",
283
318
  name: "lucy-2.1-vton-2",
284
- fps: 20,
319
+ fps: {
320
+ ideal: 30,
321
+ max: 30
322
+ },
285
323
  width: 1088,
286
324
  height: 624,
287
325
  inputSchema: z.object({})
@@ -479,6 +517,5 @@ const models = {
479
517
  return modelDefinition;
480
518
  }
481
519
  };
482
-
483
520
  //#endregion
484
- export { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, modelDefinitionSchema, models, resolveCanonicalModelAlias, resolveModelAlias };
521
+ export { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, modelDefinitionSchema, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
@@ -1,6 +1,5 @@
1
1
  import { createInvalidInputError } from "../utils/errors.js";
2
2
  import { buildUserAgent } from "../utils/user-agent.js";
3
-
4
3
  //#region src/shared/request.ts
5
4
  /**
6
5
  * Type guard to check if a value is a React Native file object.
@@ -46,6 +45,5 @@ function buildFormData(inputs) {
46
45
  else formData.append(key, String(value));
47
46
  return formData;
48
47
  }
49
-
50
48
  //#endregion
51
- export { buildAuthHeaders, buildFormData, fileInputToBlob };
49
+ export { buildAuthHeaders, buildFormData, fileInputToBlob };
@@ -1,5 +1,4 @@
1
1
  import { z } from "zod";
2
-
3
2
  //#region src/shared/types.ts
4
3
  const modelStateSchema = z.object({
5
4
  prompt: z.object({
@@ -12,6 +11,5 @@ const modelStateSchema = z.object({
12
11
  z.string()
13
12
  ]).optional()
14
13
  });
15
-
16
14
  //#endregion
17
- export { modelStateSchema };
15
+ export { modelStateSchema };
@@ -1,6 +1,5 @@
1
1
  import { createSDKError } from "../utils/errors.js";
2
2
  import { buildAuthHeaders } from "../shared/request.js";
3
-
4
3
  //#region src/tokens/client.ts
5
4
  const createTokensClient = (opts) => {
6
5
  const { baseUrl, apiKey, integration } = opts;
@@ -25,6 +24,5 @@ const createTokensClient = (opts) => {
25
24
  };
26
25
  return { create };
27
26
  };
28
-
29
27
  //#endregion
30
- export { createTokensClient };
28
+ export { createTokensClient };
package/dist/utils/env.js CHANGED
@@ -4,6 +4,5 @@ const readEnv = (env) => {
4
4
  if (typeof globalThisAny.process !== "undefined") return globalThisAny.process.env?.[env]?.trim();
5
5
  if (typeof globalThisAny.Deno !== "undefined") return globalThisAny.Deno.env?.get?.(env)?.trim();
6
6
  };
7
-
8
7
  //#endregion
9
- export { readEnv };
8
+ export { readEnv };
@@ -79,6 +79,5 @@ function createQueueStatusError(message, status) {
79
79
  function createQueueResultError(message, status) {
80
80
  return createSDKError(ERROR_CODES.QUEUE_RESULT_ERROR, message, { status });
81
81
  }
82
-
83
82
  //#endregion
84
- export { ERROR_CODES, classifyWebrtcError, createInvalidApiKeyError, createInvalidBaseUrlError, createInvalidInputError, createModelNotFoundError, createQueueResultError, createQueueStatusError, createQueueSubmitError, createSDKError };
83
+ export { ERROR_CODES, classifyWebrtcError, createInvalidApiKeyError, createInvalidBaseUrlError, createInvalidInputError, createModelNotFoundError, createQueueResultError, createQueueStatusError, createQueueSubmitError, createSDKError };
@@ -32,6 +32,5 @@ function createConsoleLogger(minLevel = "warn") {
32
32
  error: (msg, data) => log("error", msg, data)
33
33
  };
34
34
  }
35
-
36
35
  //#endregion
37
- export { createConsoleLogger, noopLogger };
36
+ export { createConsoleLogger, noopLogger };
@@ -0,0 +1,43 @@
1
+ //#region src/utils/media.ts
2
+ async function blobToBase64(blob) {
3
+ return new Promise((resolve, reject) => {
4
+ const reader = new FileReader();
5
+ reader.onloadend = () => {
6
+ const result = reader.result;
7
+ if (typeof result !== "string") {
8
+ reject(/* @__PURE__ */ new Error("FileReader did not return a string"));
9
+ return;
10
+ }
11
+ const base64 = result.split(",")[1];
12
+ if (!base64) {
13
+ reject(/* @__PURE__ */ new Error("Invalid data URL format"));
14
+ return;
15
+ }
16
+ resolve(base64);
17
+ };
18
+ reader.onerror = reject;
19
+ reader.readAsDataURL(blob);
20
+ });
21
+ }
22
+ async function imageToBase64(image) {
23
+ if (typeof image === "string") {
24
+ let url = null;
25
+ try {
26
+ url = new URL(image);
27
+ } catch {}
28
+ if (url?.protocol === "data:") {
29
+ const [, base64] = image.split(",", 2);
30
+ if (!base64) throw new Error("Invalid data URL image");
31
+ return base64;
32
+ }
33
+ if (url?.protocol === "http:" || url?.protocol === "https:") {
34
+ const response = await fetch(image);
35
+ if (!response.ok) throw new Error(`Failed to fetch image: ${response.status} ${response.statusText}`);
36
+ return blobToBase64(await response.blob());
37
+ }
38
+ return image;
39
+ }
40
+ return blobToBase64(image);
41
+ }
42
+ //#endregion
43
+ export { imageToBase64 };
@@ -0,0 +1,13 @@
1
+ //#region src/utils/platform.ts
2
+ function isDesktopSafari() {
3
+ const g = globalThis;
4
+ const ua = g?.navigator?.userAgent ?? "";
5
+ const platform = g?.navigator?.platform ?? "";
6
+ const maxTouchPoints = g?.navigator?.maxTouchPoints ?? 0;
7
+ if (!/^((?!chrome|chromium|crios|fxios|edg|firefox|opr|opera|android).)*safari/i.test(ua)) return false;
8
+ if (/iPad|iPhone|iPod/.test(ua)) return false;
9
+ if (platform === "MacIntel" && maxTouchPoints > 1) return false;
10
+ return true;
11
+ }
12
+ //#endregion
13
+ export { isDesktopSafari };
@@ -1,5 +1,4 @@
1
1
  import { VERSION } from "../version.js";
2
-
3
2
  //#region src/utils/user-agent.ts
4
3
  function getRuntimeEnvironment(globalThisAny = globalThis) {
5
4
  if (globalThisAny.window) return "runtime/browser";
@@ -27,6 +26,5 @@ function buildUserAgent(integration, globalThisAny = globalThis) {
27
26
  getRuntimeEnvironment(globalThisAny)
28
27
  ].join(" ");
29
28
  }
30
-
31
29
  //#endregion
32
- export { buildUserAgent };
30
+ export { buildUserAgent };
package/dist/version.js CHANGED
@@ -5,6 +5,5 @@
5
5
  * Falls back to '0.0.0-dev' in development.
6
6
  */
7
7
  const VERSION = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "0.0.0-dev";
8
-
9
8
  //#endregion
10
- export { VERSION };
9
+ export { VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decartai/sdk",
3
- "version": "0.0.68",
3
+ "version": "0.1.0",
4
4
  "description": "Decart's JavaScript SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,6 +43,7 @@
43
43
  "vitest": "^4.0.18"
44
44
  },
45
45
  "dependencies": {
46
+ "livekit-client": "^2.0.0",
46
47
  "mitt": "^3.0.1",
47
48
  "p-retry": "^6.2.1",
48
49
  "zod": "^4.0.17"