@decartai/sdk 0.0.1

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.
@@ -0,0 +1,62 @@
1
+ import { createWebrtcError } from "../utils/errors.js";
2
+ import { modelDefinitionSchema } from "../shared/model.js";
3
+ import { modelStateSchema } from "../shared/types.js";
4
+ import { realtimeMethods } from "./methods.js";
5
+ import { WebRTCManager } from "./webrtc-manager.js";
6
+ import { z } from "zod";
7
+ import mitt from "mitt";
8
+ import { v4 } from "uuid";
9
+
10
+ //#region src/realtime/client.ts
11
+ const realTimeClientInitialStateSchema = modelStateSchema;
12
+ const createAsyncFunctionSchema = (schema) => z.custom((fn) => schema.implementAsync(fn));
13
+ const realTimeClientConnectOptionsSchema = z.object({
14
+ model: modelDefinitionSchema,
15
+ onRemoteStream: z.custom((val) => typeof val === "function", { message: "onRemoteStream must be a function" }),
16
+ initialState: realTimeClientInitialStateSchema.optional(),
17
+ customizeOffer: createAsyncFunctionSchema(z.function()).optional()
18
+ });
19
+ const createRealTimeClient = (opts) => {
20
+ const { baseUrl, apiKey } = opts;
21
+ const connect = async (stream, options) => {
22
+ const eventEmitter = mitt();
23
+ const parsedOptions = realTimeClientConnectOptionsSchema.safeParse(options);
24
+ if (!parsedOptions.success) throw parsedOptions.error;
25
+ const sessionId = v4();
26
+ const { onRemoteStream, initialState } = parsedOptions.data;
27
+ const url = `${baseUrl}${options.model.urlPath}`;
28
+ const webrtcManager = new WebRTCManager({
29
+ webrtcUrl: `${url}?api_key=${apiKey}&model=${options.model.name}`,
30
+ apiKey,
31
+ sessionId,
32
+ fps: options.model.fps,
33
+ initialState,
34
+ onRemoteStream,
35
+ onConnectionStateChange: (state) => {
36
+ eventEmitter.emit("connectionChange", state);
37
+ },
38
+ onError: (error) => {
39
+ console.error("WebRTC error:", error);
40
+ eventEmitter.emit("error", createWebrtcError(error));
41
+ },
42
+ customizeOffer: options.customizeOffer
43
+ });
44
+ await webrtcManager.connect(stream);
45
+ const methods = realtimeMethods(webrtcManager);
46
+ return {
47
+ enrichPrompt: methods.enrichPrompt,
48
+ setPrompt: methods.setPrompt,
49
+ setMirror: methods.setMirror,
50
+ isConnected: () => webrtcManager.isConnected(),
51
+ getConnectionState: () => webrtcManager.getConnectionState(),
52
+ disconnect: () => webrtcManager.cleanup(),
53
+ on: eventEmitter.on,
54
+ off: eventEmitter.off,
55
+ sessionId
56
+ };
57
+ };
58
+ return { connect };
59
+ };
60
+
61
+ //#endregion
62
+ export { createRealTimeClient };
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/realtime/methods.ts
4
+ const realtimeMethods = (webrtcManager) => {
5
+ const enrichPrompt = (_prompt) => {
6
+ throw new Error("Not implemented");
7
+ };
8
+ const setPrompt = (prompt, { enrich } = {}) => {
9
+ const parsedInput = z.object({
10
+ prompt: z.string().min(1),
11
+ enrich: z.boolean().optional().default(true)
12
+ }).safeParse({
13
+ prompt,
14
+ enrich
15
+ });
16
+ if (!parsedInput.success) throw parsedInput.error;
17
+ webrtcManager.sendMessage({
18
+ type: "prompt",
19
+ prompt: parsedInput.data.prompt
20
+ });
21
+ };
22
+ const setMirror = (enabled) => {
23
+ const parsedInput = z.object({ enabled: z.boolean() }).safeParse({ enabled });
24
+ if (!parsedInput.success) throw parsedInput.error;
25
+ webrtcManager.sendMessage({
26
+ type: "switch_camera",
27
+ rotateY: parsedInput.data.enabled ? 2 : 0
28
+ });
29
+ };
30
+ return {
31
+ enrichPrompt,
32
+ setPrompt,
33
+ setMirror
34
+ };
35
+ };
36
+
37
+ //#endregion
38
+ export { realtimeMethods };
@@ -0,0 +1,144 @@
1
+ //#region src/realtime/webrtc-connection.ts
2
+ const ICE_SERVERS = [{ urls: "stun:stun.l.google.com:19302" }];
3
+ var WebRTCConnection = class {
4
+ pc = null;
5
+ ws = null;
6
+ state = "disconnected";
7
+ constructor(callbacks = {}) {
8
+ this.callbacks = callbacks;
9
+ }
10
+ async connect(url, localStream, timeout = 15e3) {
11
+ const deadline = Date.now() + timeout;
12
+ await new Promise((resolve, reject) => {
13
+ const timer = setTimeout(() => reject(/* @__PURE__ */ new Error("WebSocket timeout")), timeout);
14
+ this.ws = new WebSocket(url);
15
+ this.ws.onopen = () => {
16
+ clearTimeout(timer);
17
+ resolve();
18
+ };
19
+ this.ws.onmessage = (e) => {
20
+ try {
21
+ this.handleSignalingMessage(JSON.parse(e.data));
22
+ } catch (err) {
23
+ console.error("[WebRTC] Parse error:", err);
24
+ }
25
+ };
26
+ this.ws.onerror = () => {
27
+ clearTimeout(timer);
28
+ };
29
+ this.ws.onclose = () => this.setState("disconnected");
30
+ });
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");
54
+ }
55
+ async handleSignalingMessage(msg) {
56
+ if (!this.pc) return;
57
+ try {
58
+ switch (msg.type) {
59
+ case "ready": {
60
+ await this.applyCodecPreference("video/VP8");
61
+ const offer = await this.pc.createOffer();
62
+ await this.callbacks.customizeOffer?.(offer);
63
+ await this.pc.setLocalDescription(offer);
64
+ this.send({
65
+ type: "offer",
66
+ sdp: offer.sdp || ""
67
+ });
68
+ break;
69
+ }
70
+ case "offer": {
71
+ await this.pc.setRemoteDescription({
72
+ type: "offer",
73
+ sdp: msg.sdp
74
+ });
75
+ const answer = await this.pc.createAnswer();
76
+ await this.pc.setLocalDescription(answer);
77
+ this.send({
78
+ type: "answer",
79
+ sdp: answer.sdp || ""
80
+ });
81
+ break;
82
+ }
83
+ case "answer":
84
+ await this.pc.setRemoteDescription({
85
+ type: "answer",
86
+ sdp: msg.sdp
87
+ });
88
+ break;
89
+ case "ice-candidate":
90
+ if (msg.candidate) await this.pc.addIceCandidate(msg.candidate);
91
+ break;
92
+ }
93
+ } catch (error) {
94
+ console.error("[WebRTC] Error:", error);
95
+ this.callbacks.onError?.(error);
96
+ }
97
+ }
98
+ send(message) {
99
+ if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(message));
100
+ }
101
+ setState(state) {
102
+ if (this.state !== state) {
103
+ this.state = state;
104
+ console.log(`[WebRTC] State: ${state}`);
105
+ this.callbacks.onStateChange?.(state);
106
+ }
107
+ }
108
+ cleanup() {
109
+ this.pc?.getSenders().forEach((s) => s.track?.stop());
110
+ this.pc?.close();
111
+ this.pc = null;
112
+ this.ws?.close();
113
+ this.ws = null;
114
+ this.setState("disconnected");
115
+ }
116
+ async applyCodecPreference(preferredCodecName) {
117
+ if (!this.pc) return;
118
+ const videoTransceiver = this.pc.getTransceivers().find((r) => r.sender.track?.kind === "video");
119
+ if (!videoTransceiver) {
120
+ console.error("Could not find video transceiver. Ensure track is added to peer connection.");
121
+ return;
122
+ }
123
+ const capabilities = RTCRtpSender.getCapabilities("video");
124
+ if (!capabilities) {
125
+ console.error("Could not get video sender capabilities.");
126
+ return;
127
+ }
128
+ const preferredCodecs = [];
129
+ const otherCodecs = [];
130
+ capabilities.codecs.forEach((codec) => {
131
+ if (codec.mimeType.toLowerCase() === preferredCodecName.toLowerCase()) preferredCodecs.push(codec);
132
+ else otherCodecs.push(codec);
133
+ });
134
+ const orderedCodecs = [...preferredCodecs, ...otherCodecs];
135
+ if (orderedCodecs.length === 0) {
136
+ console.warn("No video codecs found to set preferences for.");
137
+ return;
138
+ }
139
+ await videoTransceiver.setCodecPreferences(orderedCodecs);
140
+ }
141
+ };
142
+
143
+ //#endregion
144
+ export { WebRTCConnection };
@@ -0,0 +1,56 @@
1
+ import { WebRTCConnection } from "./webrtc-connection.js";
2
+ import pRetry from "p-retry";
3
+
4
+ //#region src/realtime/webrtc-manager.ts
5
+ const PERMANENT_ERRORS = [
6
+ "permission denied",
7
+ "not allowed",
8
+ "invalid session"
9
+ ];
10
+ var WebRTCManager = class {
11
+ connection;
12
+ config;
13
+ constructor(config) {
14
+ this.config = config;
15
+ this.connection = new WebRTCConnection({
16
+ onRemoteStream: config.onRemoteStream,
17
+ onStateChange: config.onConnectionStateChange,
18
+ onError: config.onError,
19
+ customizeOffer: config.customizeOffer
20
+ });
21
+ }
22
+ async connect(localStream) {
23
+ return pRetry(async () => {
24
+ await this.connection.connect(this.config.webrtcUrl, localStream);
25
+ return true;
26
+ }, {
27
+ retries: 5,
28
+ factor: 2,
29
+ minTimeout: 1e3,
30
+ maxTimeout: 1e4,
31
+ onFailedAttempt: (error) => {
32
+ console.log(`[WebRTC] Retry ${error.attemptNumber} failed: ${error.message}`);
33
+ this.connection.cleanup();
34
+ },
35
+ shouldRetry: (error) => {
36
+ const msg = error.message.toLowerCase();
37
+ return !PERMANENT_ERRORS.some((err) => msg.includes(err));
38
+ }
39
+ });
40
+ }
41
+ sendMessage(message) {
42
+ this.connection.send(message);
43
+ }
44
+ cleanup() {
45
+ this.connection.cleanup();
46
+ }
47
+ isConnected() {
48
+ return this.connection.state === "connected";
49
+ }
50
+ getConnectionState() {
51
+ return this.connection.state;
52
+ }
53
+ };
54
+
55
+ //#endregion
56
+ export { WebRTCManager };
@@ -0,0 +1,82 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/shared/model.d.ts
4
+ declare const realtimeModels: z.ZodUnion<readonly [z.ZodLiteral<"mirage">, z.ZodLiteral<"lucy_v2v_720p_rt">]>;
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
+ 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">]>]>;
8
+ type Model = z.infer<typeof modelSchema>;
9
+ type RealTimeModels = z.infer<typeof realtimeModels>;
10
+ type VideoModels = z.infer<typeof videoModels>;
11
+ type ImageModels = z.infer<typeof imageModels>;
12
+ declare const modelInputSchemas: {
13
+ readonly "lucy-pro-t2v": z.ZodObject<{
14
+ prompt: z.ZodString;
15
+ seed: z.ZodOptional<z.ZodNumber>;
16
+ resolution: z.ZodOptional<z.ZodString>;
17
+ orientation: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strip>;
19
+ readonly "lucy-pro-t2i": z.ZodObject<{
20
+ prompt: z.ZodString;
21
+ seed: z.ZodOptional<z.ZodNumber>;
22
+ resolution: z.ZodOptional<z.ZodString>;
23
+ orientation: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strip>;
25
+ readonly "lucy-pro-i2v": z.ZodObject<{
26
+ prompt: z.ZodString;
27
+ data: z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>;
28
+ seed: z.ZodOptional<z.ZodNumber>;
29
+ resolution: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strip>;
31
+ readonly "lucy-dev-i2v": z.ZodObject<{
32
+ prompt: z.ZodString;
33
+ data: z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>;
34
+ seed: z.ZodOptional<z.ZodNumber>;
35
+ resolution: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strip>;
37
+ readonly "lucy-pro-v2v": z.ZodObject<{
38
+ prompt: z.ZodString;
39
+ data: z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>;
40
+ seed: z.ZodOptional<z.ZodNumber>;
41
+ resolution: z.ZodOptional<z.ZodString>;
42
+ enhance_prompt: z.ZodOptional<z.ZodBoolean>;
43
+ num_inference_steps: z.ZodOptional<z.ZodNumber>;
44
+ }, z.core.$strip>;
45
+ readonly "lucy-dev-v2v": z.ZodObject<{
46
+ prompt: z.ZodString;
47
+ data: z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>;
48
+ seed: z.ZodOptional<z.ZodNumber>;
49
+ resolution: z.ZodOptional<z.ZodString>;
50
+ enhance_prompt: z.ZodOptional<z.ZodBoolean>;
51
+ }, z.core.$strip>;
52
+ readonly "lucy-pro-flf2v": z.ZodObject<{
53
+ prompt: z.ZodString;
54
+ start: z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>;
55
+ end: z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>;
56
+ seed: z.ZodOptional<z.ZodNumber>;
57
+ resolution: z.ZodOptional<z.ZodString>;
58
+ }, z.core.$strip>;
59
+ readonly "lucy-pro-i2i": z.ZodObject<{
60
+ prompt: z.ZodString;
61
+ data: z.ZodUnion<readonly [z.ZodCustom<File, File>, z.ZodCustom<Blob, Blob>, z.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>, z.ZodCustom<URL, URL>, z.ZodURL]>;
62
+ seed: z.ZodOptional<z.ZodNumber>;
63
+ resolution: z.ZodOptional<z.ZodString>;
64
+ enhance_prompt: z.ZodOptional<z.ZodBoolean>;
65
+ }, z.core.$strip>;
66
+ };
67
+ type ModelInputSchemas = typeof modelInputSchemas;
68
+ type ModelDefinition<T extends Model = Model> = {
69
+ name: T;
70
+ urlPath: string;
71
+ fps: number;
72
+ width: number;
73
+ height: number;
74
+ inputSchema: T extends keyof ModelInputSchemas ? ModelInputSchemas[T] : z.ZodObject<any>;
75
+ };
76
+ declare const models: {
77
+ realtime: <T extends RealTimeModels>(model: T) => ModelDefinition<T>;
78
+ video: <T extends VideoModels>(model: T) => ModelDefinition<T>;
79
+ image: <T extends ImageModels>(model: T) => ModelDefinition<T>;
80
+ };
81
+ //#endregion
82
+ export { Model, ModelDefinition, ModelInputSchemas, models };
@@ -0,0 +1,197 @@
1
+ import { createModelNotFoundError } from "../utils/errors.js";
2
+ import { z } from "zod";
3
+
4
+ //#region src/shared/model.ts
5
+ const realtimeModels = z.union([z.literal("mirage"), z.literal("lucy_v2v_720p_rt")]);
6
+ const videoModels = z.union([
7
+ z.literal("lucy-dev-i2v"),
8
+ z.literal("lucy-dev-v2v"),
9
+ z.literal("lucy-pro-t2v"),
10
+ z.literal("lucy-pro-i2v"),
11
+ z.literal("lucy-pro-v2v"),
12
+ z.literal("lucy-pro-flf2v")
13
+ ]);
14
+ const imageModels = z.union([z.literal("lucy-pro-t2i"), z.literal("lucy-pro-i2i")]);
15
+ const modelSchema = z.union([
16
+ realtimeModels,
17
+ videoModels,
18
+ imageModels
19
+ ]);
20
+ const fileInputSchema = z.union([
21
+ z.instanceof(File),
22
+ z.instanceof(Blob),
23
+ z.instanceof(ReadableStream),
24
+ z.instanceof(URL),
25
+ z.url()
26
+ ]);
27
+ const modelInputSchemas = {
28
+ "lucy-pro-t2v": z.object({
29
+ prompt: z.string(),
30
+ seed: z.number().optional(),
31
+ resolution: z.string().optional(),
32
+ orientation: z.string().optional()
33
+ }),
34
+ "lucy-pro-t2i": z.object({
35
+ prompt: z.string(),
36
+ seed: z.number().optional(),
37
+ resolution: z.string().optional(),
38
+ orientation: z.string().optional()
39
+ }),
40
+ "lucy-pro-i2v": z.object({
41
+ prompt: z.string(),
42
+ data: fileInputSchema,
43
+ seed: z.number().optional(),
44
+ resolution: z.string().optional()
45
+ }),
46
+ "lucy-dev-i2v": z.object({
47
+ prompt: z.string(),
48
+ data: fileInputSchema,
49
+ seed: z.number().optional(),
50
+ resolution: z.string().optional()
51
+ }),
52
+ "lucy-pro-v2v": z.object({
53
+ prompt: z.string(),
54
+ data: fileInputSchema,
55
+ seed: z.number().optional(),
56
+ resolution: z.string().optional(),
57
+ enhance_prompt: z.boolean().optional(),
58
+ num_inference_steps: z.number().optional()
59
+ }),
60
+ "lucy-dev-v2v": z.object({
61
+ prompt: z.string(),
62
+ data: fileInputSchema,
63
+ seed: z.number().optional(),
64
+ resolution: z.string().optional(),
65
+ enhance_prompt: z.boolean().optional()
66
+ }),
67
+ "lucy-pro-flf2v": z.object({
68
+ prompt: z.string(),
69
+ start: fileInputSchema,
70
+ end: fileInputSchema,
71
+ seed: z.number().optional(),
72
+ resolution: z.string().optional()
73
+ }),
74
+ "lucy-pro-i2i": z.object({
75
+ prompt: z.string(),
76
+ data: fileInputSchema,
77
+ seed: z.number().optional(),
78
+ resolution: z.string().optional(),
79
+ enhance_prompt: z.boolean().optional()
80
+ })
81
+ };
82
+ const modelDefinitionSchema = z.object({
83
+ name: modelSchema,
84
+ urlPath: z.string(),
85
+ fps: z.number().min(1),
86
+ width: z.number().min(1),
87
+ height: z.number().min(1),
88
+ inputSchema: z.any()
89
+ });
90
+ const _models = {
91
+ realtime: {
92
+ mirage: {
93
+ urlPath: "/v1/stream",
94
+ name: "mirage",
95
+ fps: 25,
96
+ width: 1280,
97
+ height: 704,
98
+ inputSchema: z.object({})
99
+ },
100
+ lucy_v2v_720p_rt: {
101
+ urlPath: "/v1/stream",
102
+ name: "lucy_v2v_720p_rt",
103
+ fps: 25,
104
+ width: 1280,
105
+ height: 704,
106
+ inputSchema: z.object({})
107
+ }
108
+ },
109
+ image: {
110
+ "lucy-pro-t2i": {
111
+ urlPath: "/v1/generate/lucy-pro-t2i",
112
+ name: "lucy-pro-t2i",
113
+ fps: 25,
114
+ width: 1280,
115
+ height: 704,
116
+ inputSchema: modelInputSchemas["lucy-pro-t2i"]
117
+ },
118
+ "lucy-pro-i2i": {
119
+ urlPath: "/v1/generate/lucy-pro-i2i",
120
+ name: "lucy-pro-i2i",
121
+ fps: 25,
122
+ width: 1280,
123
+ height: 704,
124
+ inputSchema: modelInputSchemas["lucy-pro-i2i"]
125
+ }
126
+ },
127
+ video: {
128
+ "lucy-dev-i2v": {
129
+ urlPath: "/v1/generate/lucy-dev-i2v",
130
+ name: "lucy-dev-i2v",
131
+ fps: 25,
132
+ width: 1280,
133
+ height: 704,
134
+ inputSchema: modelInputSchemas["lucy-dev-i2v"]
135
+ },
136
+ "lucy-dev-v2v": {
137
+ urlPath: "/v1/generate/lucy-dev-v2v",
138
+ name: "lucy-dev-v2v",
139
+ fps: 25,
140
+ width: 1280,
141
+ height: 704,
142
+ inputSchema: modelInputSchemas["lucy-dev-v2v"]
143
+ },
144
+ "lucy-pro-t2v": {
145
+ urlPath: "/v1/generate/lucy-pro-t2v",
146
+ name: "lucy-pro-t2v",
147
+ fps: 25,
148
+ width: 1280,
149
+ height: 704,
150
+ inputSchema: modelInputSchemas["lucy-pro-t2v"]
151
+ },
152
+ "lucy-pro-i2v": {
153
+ urlPath: "/v1/generate/lucy-pro-i2v",
154
+ name: "lucy-pro-i2v",
155
+ fps: 25,
156
+ width: 1280,
157
+ height: 704,
158
+ inputSchema: modelInputSchemas["lucy-pro-i2v"]
159
+ },
160
+ "lucy-pro-v2v": {
161
+ urlPath: "/v1/generate/lucy-pro-v2v",
162
+ name: "lucy-pro-v2v",
163
+ fps: 25,
164
+ width: 1280,
165
+ height: 704,
166
+ inputSchema: modelInputSchemas["lucy-pro-v2v"]
167
+ },
168
+ "lucy-pro-flf2v": {
169
+ urlPath: "/v1/generate/lucy-pro-flf2v",
170
+ name: "lucy-pro-flf2v",
171
+ fps: 25,
172
+ width: 1280,
173
+ height: 704,
174
+ inputSchema: modelInputSchemas["lucy-pro-flf2v"]
175
+ }
176
+ }
177
+ };
178
+ const models = {
179
+ realtime: (model) => {
180
+ const modelDefinition = _models.realtime[model];
181
+ if (!modelDefinition) throw createModelNotFoundError(model);
182
+ return modelDefinition;
183
+ },
184
+ video: (model) => {
185
+ const modelDefinition = _models.video[model];
186
+ if (!modelDefinition) throw createModelNotFoundError(model);
187
+ return modelDefinition;
188
+ },
189
+ image: (model) => {
190
+ const modelDefinition = _models.image[model];
191
+ if (!modelDefinition) throw createModelNotFoundError(model);
192
+ return modelDefinition;
193
+ }
194
+ };
195
+
196
+ //#endregion
197
+ export { modelDefinitionSchema, models };
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/shared/types.d.ts
4
+ declare const modelStateSchema: z.ZodObject<{
5
+ prompt: z.ZodOptional<z.ZodObject<{
6
+ text: z.ZodString;
7
+ enrich: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
8
+ }, z.core.$strip>>;
9
+ mirror: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
10
+ }, z.core.$strip>;
11
+ type ModelState = z.infer<typeof modelStateSchema>;
12
+ //#endregion
13
+ export { ModelState };
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/shared/types.ts
4
+ const modelStateSchema = z.object({
5
+ prompt: z.object({
6
+ text: z.string().min(1),
7
+ enrich: z.boolean().optional().default(true)
8
+ }).optional(),
9
+ mirror: z.boolean().optional().default(false)
10
+ });
11
+
12
+ //#endregion
13
+ export { modelStateSchema };
@@ -0,0 +1,18 @@
1
+ //#region src/utils/errors.d.ts
2
+ type DecartSDKError = {
3
+ code: string;
4
+ message: string;
5
+ data?: Record<string, unknown>;
6
+ cause?: Error;
7
+ };
8
+ declare const ERROR_CODES: {
9
+ readonly INVALID_API_KEY: "INVALID_API_KEY";
10
+ readonly INVALID_BASE_URL: "INVALID_BASE_URL";
11
+ readonly WEB_RTC_ERROR: "WEB_RTC_ERROR";
12
+ readonly PROCESSING_ERROR: "PROCESSING_ERROR";
13
+ readonly INVALID_INPUT: "INVALID_INPUT";
14
+ readonly INVALID_OPTIONS: "INVALID_OPTIONS";
15
+ readonly MODEL_NOT_FOUND: "MODEL_NOT_FOUND";
16
+ };
17
+ //#endregion
18
+ export { DecartSDKError, ERROR_CODES };
@@ -0,0 +1,36 @@
1
+ //#region src/utils/errors.ts
2
+ const ERROR_CODES = {
3
+ INVALID_API_KEY: "INVALID_API_KEY",
4
+ INVALID_BASE_URL: "INVALID_BASE_URL",
5
+ WEB_RTC_ERROR: "WEB_RTC_ERROR",
6
+ PROCESSING_ERROR: "PROCESSING_ERROR",
7
+ INVALID_INPUT: "INVALID_INPUT",
8
+ INVALID_OPTIONS: "INVALID_OPTIONS",
9
+ MODEL_NOT_FOUND: "MODEL_NOT_FOUND"
10
+ };
11
+ function createSDKError(code, message, data, cause) {
12
+ return {
13
+ code,
14
+ message,
15
+ data,
16
+ cause
17
+ };
18
+ }
19
+ function createInvalidApiKeyError() {
20
+ return createSDKError(ERROR_CODES.INVALID_API_KEY, "API key is required and must be a non-empty string");
21
+ }
22
+ function createInvalidBaseUrlError(url) {
23
+ return createSDKError(ERROR_CODES.INVALID_BASE_URL, `Invalid base URL${url ? `: ${url}` : ""}`);
24
+ }
25
+ function createWebrtcError(error) {
26
+ return createSDKError(ERROR_CODES.WEB_RTC_ERROR, "WebRTC error", { cause: error });
27
+ }
28
+ function createInvalidInputError(message) {
29
+ return createSDKError(ERROR_CODES.INVALID_INPUT, message);
30
+ }
31
+ function createModelNotFoundError(model) {
32
+ return createSDKError(ERROR_CODES.MODEL_NOT_FOUND, `Model ${model} not found`);
33
+ }
34
+
35
+ //#endregion
36
+ export { ERROR_CODES, createInvalidApiKeyError, createInvalidBaseUrlError, createInvalidInputError, createModelNotFoundError, createSDKError, createWebrtcError };