@decartai/sdk 0.1.7 → 0.1.9

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.
@@ -15,6 +15,7 @@ declare const realTimeClientInitialStateSchema: z.ZodObject<{
15
15
  enhance: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
16
16
  }, z.core.$strip>>;
17
17
  image: z.ZodOptional<z.ZodUnion<readonly [z.ZodCustom<Blob, Blob>, z.ZodCustom<File, File>, z.ZodString]>>;
18
+ passthrough: z.ZodOptional<z.ZodBoolean>;
18
19
  }, z.core.$strip>;
19
20
  type OnRemoteStreamFn = (stream: MediaStream) => void;
20
21
  type OnConnectionChangeFn = (state: ConnectionState) => void;
@@ -46,6 +47,7 @@ declare const realTimeClientConnectOptionsSchema: z.ZodObject<{
46
47
  enhance: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
47
48
  }, z.core.$strip>>;
48
49
  image: z.ZodOptional<z.ZodUnion<readonly [z.ZodCustom<Blob, Blob>, z.ZodCustom<File, File>, z.ZodString]>>;
50
+ passthrough: z.ZodOptional<z.ZodBoolean>;
49
51
  }, z.core.$strip>>;
50
52
  queryParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
51
53
  mirror: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"auto">, z.ZodBoolean]>>;
@@ -96,6 +98,7 @@ type RealTimeClient = {
96
98
  * - `null`: clear the current image.
97
99
  */
98
100
  setImage: (image: Blob | File | string | null, options?: ImageSetOptions) => Promise<void>;
101
+ replaceVideoTrack: (track: MediaStreamTrack) => Promise<void>;
99
102
  };
100
103
  //#endregion
101
104
  export { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState };
@@ -89,6 +89,7 @@ const createRealTimeClient = (opts) => {
89
89
  initialImage,
90
90
  initialImageRef,
91
91
  initialPrompt,
92
+ initialPassthrough: initialState?.passthrough,
92
93
  logger,
93
94
  videoCodec: publishCodec
94
95
  });
@@ -64,6 +64,13 @@ var MediaChannel = class {
64
64
  await this.publishTracks(this.config.localStream);
65
65
  this.config.observability?.endPhase("publish-local-track", { success: true });
66
66
  }
67
+ async replaceVideoTrack(track) {
68
+ const room = this.room;
69
+ if (!room) throw new Error("Cannot replace video track: media channel is not connected");
70
+ const videoTrack = [...room.localParticipant.videoTrackPublications.values()][0]?.videoTrack;
71
+ if (!videoTrack) throw new Error("Cannot replace video track: no published video track");
72
+ await videoTrack.replaceTrack(track);
73
+ }
67
74
  disconnect() {
68
75
  const room = this.room;
69
76
  this.room = null;
@@ -50,9 +50,13 @@ const realtimeMethods = (session, imageToBase64) => {
50
50
  timeout: REALTIME_CONFIG.methods.promptTimeoutMs
51
51
  });
52
52
  };
53
+ const replaceVideoTrack = async (track) => {
54
+ await session.replaceVideoTrack(track);
55
+ };
53
56
  return {
54
57
  set,
55
- setPrompt
58
+ setPrompt,
59
+ replaceVideoTrack
56
60
  };
57
61
  };
58
62
  //#endregion
@@ -63,14 +63,19 @@ var SignalingChannel = class {
63
63
  this.config.observability?.startPhase("room-join");
64
64
  const roomInfoWait = this.waitForRoomInfo(handshakeTimeout);
65
65
  const initialStateRequest = buildInitialStateRequest(opts.initialState);
66
+ const userSetInitialState = opts.initialState != null && (opts.initialState.image != null || opts.initialState.imageRef != null || opts.initialState.prompt != null);
66
67
  const joinMessage = {
67
68
  type: "livekit_join",
68
- initial_state: initialStateRequest ? initialStateRequest.message : null
69
+ passthrough: opts.passthrough ?? !userSetInitialState
69
70
  };
70
71
  if (!this.writeMessage(joinMessage)) {
71
72
  roomInfoWait.cancel();
72
73
  throw new Error("WebSocket is not open");
73
74
  }
75
+ if (initialStateRequest && !this.writeMessage(initialStateRequest.message)) {
76
+ roomInfoWait.cancel();
77
+ throw new Error("WebSocket is not open");
78
+ }
74
79
  let roomInfo;
75
80
  try {
76
81
  roomInfo = await roomInfoWait.promise;
@@ -71,6 +71,12 @@ var StreamSession = class {
71
71
  this.assertConnected();
72
72
  return this.signaling.setImage(payload, opts);
73
73
  }
74
+ async replaceVideoTrack(track) {
75
+ this.assertConnected();
76
+ await this.media.replaceVideoTrack(track);
77
+ const previous = this.config.localStream;
78
+ this.config.localStream = new MediaStream(previous ? [track, ...previous.getAudioTracks()] : [track]);
79
+ }
74
80
  disconnect() {
75
81
  this.disposed = true;
76
82
  this.tearDown();
@@ -103,7 +109,8 @@ var StreamSession = class {
103
109
  this.config.observability?.markGlassToGlassStart();
104
110
  const { roomInfo, initialStateAck } = await this.signaling.openAndJoin({
105
111
  connectTimeout: REALTIME_CONFIG.session.connectionTimeoutMs,
106
- initialState
112
+ initialState,
113
+ passthrough: this.config.initialPassthrough
107
114
  });
108
115
  this.watchInitialStateAck(initialStateAck, attempt);
109
116
  if (this.disposed || this.currentAttempt !== attempt) {
@@ -161,10 +168,6 @@ var StreamSession = class {
161
168
  prompt: this.config.initialPrompt.text,
162
169
  enhance: this.config.initialPrompt.enhance
163
170
  };
164
- if (this.config.localStream) return {
165
- image: null,
166
- prompt: null
167
- };
168
171
  }
169
172
  wireSignalingEvents() {
170
173
  this.signaling.on("queuePosition", (qp) => {
@@ -7,6 +7,7 @@ declare const modelStateSchema: z.ZodObject<{
7
7
  enhance: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
8
8
  }, z.core.$strip>>;
9
9
  image: z.ZodOptional<z.ZodUnion<readonly [z.ZodCustom<Blob, Blob>, z.ZodCustom<File, File>, z.ZodString]>>;
10
+ passthrough: z.ZodOptional<z.ZodBoolean>;
10
11
  }, z.core.$strip>;
11
12
  type ModelState = z.infer<typeof modelStateSchema>;
12
13
  //#endregion
@@ -9,7 +9,8 @@ const modelStateSchema = z.object({
9
9
  z.instanceof(Blob),
10
10
  z.instanceof(File),
11
11
  z.string()
12
- ]).optional()
12
+ ]).optional(),
13
+ passthrough: z.boolean().optional()
13
14
  });
14
15
  //#endregion
15
16
  export { modelStateSchema };
@@ -25,6 +25,8 @@ type CreateTokenOptions = {
25
25
  };
26
26
  type CreateTokenResponse = {
27
27
  apiKey: string;
28
+ /** Signed JWT mirroring `apiKey`, verifiable offline via the public JWKS. */
29
+ token?: string;
28
30
  expiresAt: string;
29
31
  /** Present when `allowedModels` and/or `allowedOrigins` were set on the request. */
30
32
  permissions?: {
@@ -48,7 +50,7 @@ type TokensClient = {
48
50
  * ```ts
49
51
  * const client = createDecartClient({ apiKey: process.env.DECART_API_KEY });
50
52
  * const token = await client.tokens.create();
51
- * // Returns: { apiKey: "ek_...", expiresAt: "2024-12-15T12:10:00Z" }
53
+ * // Returns: { apiKey: "ek_...", token: "eyJhbGciOiJFZERTQS...", expiresAt: "2024-12-15T12:10:00Z" }
52
54
  *
53
55
  * // With metadata:
54
56
  * const token = await client.tokens.create({ metadata: { role: "viewer" } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decartai/sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Decart's JavaScript SDK",
5
5
  "type": "module",
6
6
  "license": "MIT",