@decartai/sdk 0.0.4 → 0.0.6

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/README.md CHANGED
@@ -24,7 +24,7 @@ For complete documentation, guides, and examples, visit:
24
24
  ```typescript
25
25
  import { createDecartClient, models } from "@decartai/sdk";
26
26
 
27
- const model = models.realtime("mirage");
27
+ const model = models.realtime("mirage_v2");
28
28
 
29
29
  // Get user's camera stream
30
30
  const stream = await navigator.mediaDevices.getUserMedia({
@@ -50,7 +50,7 @@ const realtimeClient = await client.realtime.connect(stream, {
50
50
  initialState: {
51
51
  prompt: {
52
52
  text: "Anime",
53
- enrich: true
53
+ enhance: true
54
54
  }
55
55
  }
56
56
  });
@@ -6,7 +6,7 @@ import { z } from "zod";
6
6
  declare const realTimeClientInitialStateSchema: z.ZodObject<{
7
7
  prompt: z.ZodOptional<z.ZodObject<{
8
8
  text: z.ZodString;
9
- enrich: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
9
+ enhance: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
10
10
  }, z.core.$strip>>;
11
11
  mirror: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
12
12
  }, z.core.$strip>;
@@ -14,7 +14,7 @@ type OnRemoteStreamFn = (stream: MediaStream) => void;
14
14
  type RealTimeClientInitialState = z.infer<typeof realTimeClientInitialStateSchema>;
15
15
  declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
16
16
  model: z.ZodObject<{
17
- name: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"lucy_v2v_720p_rt">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-dev-i2v">, z.ZodLiteral<"lucy-dev-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-pro-t2i">, z.ZodLiteral<"lucy-pro-i2i">]>]>;
17
+ 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-dev-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-pro-t2i">, z.ZodLiteral<"lucy-pro-i2i">]>]>;
18
18
  urlPath: z.ZodString;
19
19
  fps: z.ZodNumber;
20
20
  width: z.ZodNumber;
@@ -25,7 +25,7 @@ declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
25
25
  initialState: z.ZodOptional<z.ZodObject<{
26
26
  prompt: z.ZodOptional<z.ZodObject<{
27
27
  text: z.ZodString;
28
- enrich: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
28
+ enhance: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
29
29
  }, z.core.$strip>>;
30
30
  mirror: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
31
31
  }, z.core.$strip>>;
@@ -37,11 +37,10 @@ type Events = {
37
37
  error: DecartSDKError;
38
38
  };
39
39
  type RealTimeClient = {
40
- enrichPrompt: (prompt: string) => Promise<string>;
41
40
  setPrompt: (prompt: string, {
42
- enrich
41
+ enhance
43
42
  }?: {
44
- enrich?: boolean;
43
+ enhance?: boolean;
45
44
  }) => void;
46
45
  setMirror: (enabled: boolean) => void;
47
46
  isConnected: () => boolean;
@@ -43,8 +43,14 @@ const createRealTimeClient = (opts) => {
43
43
  });
44
44
  await webrtcManager.connect(stream);
45
45
  const methods = realtimeMethods(webrtcManager);
46
+ if (options.initialState) {
47
+ if (options.initialState.prompt) {
48
+ const { text, enhance } = options.initialState.prompt;
49
+ methods.setPrompt(text, { enhance });
50
+ }
51
+ if (options.initialState.mirror) methods.setMirror(options.initialState.mirror);
52
+ }
46
53
  return {
47
- enrichPrompt: methods.enrichPrompt,
48
54
  setPrompt: methods.setPrompt,
49
55
  setMirror: methods.setMirror,
50
56
  isConnected: () => webrtcManager.isConnected(),
@@ -2,22 +2,19 @@ import { z } from "zod";
2
2
 
3
3
  //#region src/realtime/methods.ts
4
4
  const realtimeMethods = (webrtcManager) => {
5
- const enrichPrompt = (_prompt) => {
6
- throw new Error("Not implemented");
7
- };
8
- const setPrompt = (prompt, { enrich } = {}) => {
5
+ const setPrompt = (prompt, { enhance } = {}) => {
9
6
  const parsedInput = z.object({
10
7
  prompt: z.string().min(1),
11
- enrich: z.boolean().optional().default(true)
8
+ enhance: z.boolean().optional().default(true)
12
9
  }).safeParse({
13
10
  prompt,
14
- enrich
11
+ enhance
15
12
  });
16
13
  if (!parsedInput.success) throw parsedInput.error;
17
14
  webrtcManager.sendMessage({
18
15
  type: "prompt",
19
16
  prompt: parsedInput.data.prompt,
20
- enhance_prompt: parsedInput.data.enrich
17
+ enhance_prompt: parsedInput.data.enhance
21
18
  });
22
19
  };
23
20
  const setMirror = (enabled) => {
@@ -29,7 +26,6 @@ const realtimeMethods = (webrtcManager) => {
29
26
  });
30
27
  };
31
28
  return {
32
- enrichPrompt,
33
29
  setPrompt,
34
30
  setMirror
35
31
  };
@@ -3,13 +3,17 @@ const ICE_SERVERS = [{ urls: "stun:stun.l.google.com:19302" }];
3
3
  var WebRTCConnection = class {
4
4
  pc = null;
5
5
  ws = null;
6
+ localStream = null;
7
+ connectionReject = null;
6
8
  state = "disconnected";
7
9
  constructor(callbacks = {}) {
8
10
  this.callbacks = callbacks;
9
11
  }
10
- async connect(url, localStream, timeout = 15e3) {
12
+ async connect(url, localStream, timeout = 25e3) {
11
13
  const deadline = Date.now() + timeout;
14
+ this.localStream = localStream;
12
15
  await new Promise((resolve, reject) => {
16
+ this.connectionReject = reject;
13
17
  const timer = setTimeout(() => reject(/* @__PURE__ */ new Error("WebSocket timeout")), timeout);
14
18
  this.ws = new WebSocket(url);
15
19
  this.ws.onopen = () => {
@@ -28,34 +32,35 @@ var WebRTCConnection = class {
28
32
  };
29
33
  this.ws.onclose = () => this.setState("disconnected");
30
34
  });
31
- this.pc?.close();
32
- this.pc = new RTCPeerConnection({ iceServers: ICE_SERVERS });
33
- localStream.getTracks().forEach((track) => this.pc.addTrack(track, localStream));
34
- this.pc.ontrack = (e) => {
35
- if (e.streams?.[0]) this.callbacks.onRemoteStream?.(e.streams[0]);
36
- };
37
- this.pc.onicecandidate = (e) => {
38
- if (e.candidate) this.send({
39
- type: "ice-candidate",
40
- candidate: e.candidate
41
- });
42
- };
43
- this.pc.onconnectionstatechange = () => {
44
- if (!this.pc) return;
45
- const s = this.pc.connectionState;
46
- this.setState(s === "connected" ? "connected" : ["connecting", "new"].includes(s) ? "connecting" : "disconnected");
47
- };
48
- this.handleSignalingMessage({ type: "ready" });
49
- while (Date.now() < deadline) {
50
- if (this.state === "connected") return;
51
- await new Promise((r) => setTimeout(r, 100));
52
- }
53
- throw new Error("Connection timeout");
35
+ await this.setupNewPeerConnection();
36
+ return new Promise((resolve, reject) => {
37
+ this.connectionReject = reject;
38
+ const checkConnection = setInterval(() => {
39
+ if (this.state === "connected") {
40
+ clearInterval(checkConnection);
41
+ this.connectionReject = null;
42
+ resolve();
43
+ } else if (Date.now() >= deadline) {
44
+ clearInterval(checkConnection);
45
+ this.connectionReject = null;
46
+ reject(/* @__PURE__ */ new Error("Connection timeout"));
47
+ }
48
+ }, 100);
49
+ });
54
50
  }
55
51
  async handleSignalingMessage(msg) {
56
52
  if (!this.pc) return;
57
53
  try {
58
54
  switch (msg.type) {
55
+ case "error": {
56
+ const error = new Error(msg.error);
57
+ this.callbacks.onError?.(error);
58
+ if (this.connectionReject) {
59
+ this.connectionReject(error);
60
+ this.connectionReject = null;
61
+ }
62
+ break;
63
+ }
59
64
  case "ready": {
60
65
  await this.applyCodecPreference("video/VP8");
61
66
  const offer = await this.pc.createOffer();
@@ -89,6 +94,11 @@ var WebRTCConnection = class {
89
94
  case "ice-candidate":
90
95
  if (msg.candidate) await this.pc.addIceCandidate(msg.candidate);
91
96
  break;
97
+ case "ice-restart": {
98
+ const turnConfig = msg.turn_config;
99
+ if (turnConfig) await this.setupNewPeerConnection(turnConfig);
100
+ break;
101
+ }
92
102
  }
93
103
  } catch (error) {
94
104
  console.error("[WebRTC] Error:", error);
@@ -105,12 +115,46 @@ var WebRTCConnection = class {
105
115
  this.callbacks.onStateChange?.(state);
106
116
  }
107
117
  }
118
+ async setupNewPeerConnection(turnConfig) {
119
+ if (!this.localStream) throw new Error("No local stream found");
120
+ if (this.pc) {
121
+ this.pc.getSenders().forEach((sender) => {
122
+ if (sender.track) this.pc.removeTrack(sender);
123
+ });
124
+ this.pc.close();
125
+ }
126
+ const iceServers = ICE_SERVERS;
127
+ if (turnConfig) iceServers.push({
128
+ urls: turnConfig.server_url,
129
+ credential: turnConfig.credential,
130
+ username: turnConfig.username
131
+ });
132
+ this.pc = new RTCPeerConnection({ iceServers });
133
+ this.localStream.getTracks().forEach((track) => this.pc.addTrack(track, this.localStream));
134
+ this.pc.ontrack = (e) => {
135
+ if (e.streams?.[0]) this.callbacks.onRemoteStream?.(e.streams[0]);
136
+ };
137
+ this.pc.onicecandidate = (e) => {
138
+ this.send({
139
+ type: "ice-candidate",
140
+ candidate: e.candidate
141
+ });
142
+ };
143
+ this.pc.onconnectionstatechange = () => {
144
+ if (!this.pc) return;
145
+ const s = this.pc.connectionState;
146
+ this.setState(s === "connected" ? "connected" : ["connecting", "new"].includes(s) ? "connecting" : "disconnected");
147
+ };
148
+ this.pc.oniceconnectionstatechange = () => {};
149
+ this.handleSignalingMessage({ type: "ready" });
150
+ }
108
151
  cleanup() {
109
152
  this.pc?.getSenders().forEach((s) => s.track?.stop());
110
153
  this.pc?.close();
111
154
  this.pc = null;
112
155
  this.ws?.close();
113
156
  this.ws = null;
157
+ this.localStream = null;
114
158
  this.setState("disconnected");
115
159
  }
116
160
  async applyCodecPreference(preferredCodecName) {
@@ -5,7 +5,10 @@ import pRetry from "p-retry";
5
5
  const PERMANENT_ERRORS = [
6
6
  "permission denied",
7
7
  "not allowed",
8
- "invalid session"
8
+ "invalid session",
9
+ "401",
10
+ "invalid api key",
11
+ "unauthorized"
9
12
  ];
10
13
  var WebRTCManager = class {
11
14
  connection;
@@ -29,7 +32,7 @@ var WebRTCManager = class {
29
32
  minTimeout: 1e3,
30
33
  maxTimeout: 1e4,
31
34
  onFailedAttempt: (error) => {
32
- console.log(`[WebRTC] Retry ${error.attemptNumber} failed: ${error.message}`);
35
+ console.error(`[WebRTC] Failed to connect: ${error.message}`);
33
36
  this.connection.cleanup();
34
37
  },
35
38
  shouldRetry: (error) => {
@@ -1,10 +1,10 @@
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<"lucy_v2v_720p_rt">]>;
4
+ declare const realtimeModels: z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"mirage_v2">, z.ZodLiteral<"lucy_v2v_720p_rt">]>;
5
5
  declare const videoModels: z.ZodUnion<readonly [z.ZodLiteral<"lucy-dev-i2v">, z.ZodLiteral<"lucy-dev-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">]>;
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<"lucy_v2v_720p_rt">]>, z.ZodUnion<readonly [z.ZodLiteral<"lucy-dev-i2v">, z.ZodLiteral<"lucy-dev-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">]>, 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-dev-v2v">, z.ZodLiteral<"lucy-pro-t2v">, z.ZodLiteral<"lucy-pro-i2v">, z.ZodLiteral<"lucy-pro-v2v">, z.ZodLiteral<"lucy-pro-flf2v">]>, 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>;
@@ -2,7 +2,11 @@ import { createModelNotFoundError } from "../utils/errors.js";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/shared/model.ts
5
- const realtimeModels = z.union([z.literal("mirage"), z.literal("lucy_v2v_720p_rt")]);
5
+ const realtimeModels = z.union([
6
+ z.literal("mirage"),
7
+ z.literal("mirage_v2"),
8
+ z.literal("lucy_v2v_720p_rt")
9
+ ]);
6
10
  const videoModels = z.union([
7
11
  z.literal("lucy-dev-i2v"),
8
12
  z.literal("lucy-dev-v2v"),
@@ -97,6 +101,14 @@ const _models = {
97
101
  height: 704,
98
102
  inputSchema: z.object({})
99
103
  },
104
+ mirage_v2: {
105
+ urlPath: "/v1/stream",
106
+ name: "mirage_v2",
107
+ fps: 12,
108
+ width: 1280,
109
+ height: 704,
110
+ inputSchema: z.object({})
111
+ },
100
112
  lucy_v2v_720p_rt: {
101
113
  urlPath: "/v1/stream",
102
114
  name: "lucy_v2v_720p_rt",
@@ -4,7 +4,7 @@ import { z } from "zod";
4
4
  declare const modelStateSchema: z.ZodObject<{
5
5
  prompt: z.ZodOptional<z.ZodObject<{
6
6
  text: z.ZodString;
7
- enrich: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
7
+ enhance: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
8
8
  }, z.core.$strip>>;
9
9
  mirror: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
10
10
  }, z.core.$strip>;
@@ -4,7 +4,7 @@ import { z } from "zod";
4
4
  const modelStateSchema = z.object({
5
5
  prompt: z.object({
6
6
  text: z.string().min(1),
7
- enrich: z.boolean().optional().default(true)
7
+ enhance: z.boolean().optional().default(true)
8
8
  }).optional(),
9
9
  mirror: z.boolean().optional().default(false)
10
10
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decartai/sdk",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Decart's JavaScript SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",