@decartai/sdk 0.1.12 → 0.1.14
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 +85 -1
- package/dist/create-client.d.ts +46 -0
- package/dist/create-client.js +106 -0
- package/dist/index.d.ts +8 -150
- package/dist/index.js +6 -116
- package/dist/index.react-native.d.ts +36 -0
- package/dist/index.react-native.js +9 -0
- package/dist/realtime/browser/glass-to-glass-diagnostics.js +27 -0
- package/dist/realtime/{observability → browser}/glass-to-glass.js +2 -19
- package/dist/realtime/browser/index.js +32 -0
- package/dist/realtime/{mirror-stream.js → browser/mirror-stream.js} +1 -1
- package/dist/realtime/{observability → browser}/pixel-marker.js +1 -1
- package/dist/realtime/{preflight.js → browser/preflight.js} +14 -108
- package/dist/realtime/browser/prepare-connection.js +39 -0
- package/dist/realtime/client.d.ts +11 -4
- package/dist/realtime/client.js +33 -37
- package/dist/realtime/livekit.js +26 -0
- package/dist/realtime/media-channel.js +17 -10
- package/dist/realtime/methods.d.ts +1 -1
- package/dist/realtime/methods.js +3 -2
- package/dist/realtime/observability/g2g.d.ts +14 -0
- package/dist/realtime/observability/realtime-observability.js +8 -18
- package/dist/realtime/observability/webrtc-stats.d.ts +1 -1
- package/dist/realtime/preflight-connectivity.js +102 -0
- package/dist/realtime/preflight-types.d.ts +30 -0
- package/dist/realtime/react-native/index.js +36 -0
- package/dist/realtime/react-native/preflight.js +10 -0
- package/dist/realtime/react-native/prepare-connection.js +26 -0
- package/dist/realtime/stream-session.js +1 -2
- package/dist/realtime/subscribe-client.js +10 -9
- package/dist/shared/model.d.ts +36 -36
- package/dist/shared/model.js +13 -22
- package/dist/shared/request.js +5 -4
- package/dist/shared/types.d.ts +1 -1
- package/dist/shared/types.js +3 -2
- package/dist/utils/errors.d.ts +3 -0
- package/dist/utils/errors.js +16 -1
- package/dist/utils/platform.js +17 -1
- package/dist/utils/runtime.js +13 -0
- package/package.json +10 -3
- package/dist/realtime/observability/glass-to-glass.d.ts +0 -41
- package/dist/realtime/preflight.d.ts +0 -59
package/README.md
CHANGED
|
@@ -243,6 +243,90 @@ if (status.status === "completed") {
|
|
|
243
243
|
}
|
|
244
244
|
```
|
|
245
245
|
|
|
246
|
+
### React Native / Expo
|
|
247
|
+
|
|
248
|
+
React Native realtime requires [LiveKit's React Native packages](https://github.com/livekit/client-sdk-react-native)
|
|
249
|
+
and an early `registerGlobals()` call. Plain `react-native-webrtc` is not
|
|
250
|
+
supported. SDK imports and `createDecartClient(...)` usage stay the same.
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
npm install @decartai/sdk livekit-client@2.20.1 \
|
|
254
|
+
@livekit/react-native@2.11.1 \
|
|
255
|
+
@livekit/react-native-webrtc@144.1.1
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Call LiveKit setup from a side-effect module that runs before your router or app
|
|
259
|
+
entrypoint:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
// livekit-bootstrap.ts
|
|
263
|
+
import { registerGlobals } from "@livekit/react-native";
|
|
264
|
+
|
|
265
|
+
registerGlobals();
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
// index.ts
|
|
270
|
+
import "./livekit-bootstrap";
|
|
271
|
+
import "expo-router/entry"; // or import your root App component
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
With the globals registered, realtime usage is the same as on the web. Use the
|
|
275
|
+
model's numeric FPS when configuring native camera capture, then pass that
|
|
276
|
+
`MediaStream` to the SDK:
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
import { createDecartClient, models, resolveFpsNumber } from "@decartai/sdk";
|
|
280
|
+
import { mediaDevices } from "@livekit/react-native-webrtc";
|
|
281
|
+
|
|
282
|
+
const client = createDecartClient({ apiKey: "your-api-key-here" });
|
|
283
|
+
const model = models.realtime("lucy-2.5");
|
|
284
|
+
const captureFps = resolveFpsNumber(model.fps);
|
|
285
|
+
|
|
286
|
+
const cameraStream = await mediaDevices.getUserMedia({
|
|
287
|
+
audio: false,
|
|
288
|
+
video: {
|
|
289
|
+
facingMode: "user",
|
|
290
|
+
frameRate: captureFps,
|
|
291
|
+
width: model.width,
|
|
292
|
+
height: model.height,
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
const realtimeClient = await client.realtime.connect(cameraStream, {
|
|
297
|
+
model,
|
|
298
|
+
preferredVideoCodec: "vp8",
|
|
299
|
+
onRemoteStream,
|
|
300
|
+
});
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
For Expo, install the config plugins:
|
|
304
|
+
|
|
305
|
+
```sh
|
|
306
|
+
npm install @livekit/react-native-expo-plugin@1.0.2 \
|
|
307
|
+
@config-plugins/react-native-webrtc
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Add them to `app.json`:
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"expo": {
|
|
315
|
+
"plugins": [
|
|
316
|
+
"@livekit/react-native-expo-plugin",
|
|
317
|
+
"@config-plugins/react-native-webrtc"
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Run `npx expo prebuild` and rebuild the native app. LiveKit does not run in Expo
|
|
324
|
+
Go. Bare React Native apps must follow LiveKit's native setup instructions.
|
|
325
|
+
|
|
326
|
+
Outgoing `mirror`, `debugQuality`, and deep connectivity preflight are browser-only
|
|
327
|
+
and fail with `UNSUPPORTED_PLATFORM_FEATURE` on React Native. Mirror the local
|
|
328
|
+
preview with your native video view instead.
|
|
329
|
+
|
|
246
330
|
## Development
|
|
247
331
|
|
|
248
332
|
### Setup
|
|
@@ -273,4 +357,4 @@ The package is published to npm as `@decartai/sdk`.
|
|
|
273
357
|
|
|
274
358
|
## License
|
|
275
359
|
|
|
276
|
-
MIT
|
|
360
|
+
MIT
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Logger } from "./utils/logger.js";
|
|
2
|
+
|
|
3
|
+
//#region src/create-client.d.ts
|
|
4
|
+
type DecartClientOptions = {
|
|
5
|
+
proxy: string;
|
|
6
|
+
apiKey?: never;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
realtimeBaseUrl?: string;
|
|
9
|
+
integration?: string;
|
|
10
|
+
logger?: Logger;
|
|
11
|
+
telemetry?: boolean;
|
|
12
|
+
} | {
|
|
13
|
+
proxy?: never;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
realtimeBaseUrl?: string;
|
|
17
|
+
integration?: string;
|
|
18
|
+
logger?: Logger;
|
|
19
|
+
telemetry?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Create a Decart API client.
|
|
23
|
+
*
|
|
24
|
+
* @param options - Configuration options
|
|
25
|
+
* @param options.proxy - URL of the proxy server. When set, the client will use the proxy instead of direct API access and apiKey is not required.
|
|
26
|
+
* @param options.apiKey - API key for authentication.
|
|
27
|
+
* @param options.baseUrl - Override the default API base URL.
|
|
28
|
+
* @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
|
|
29
|
+
* @param options.integration - Optional integration identifier.
|
|
30
|
+
*
|
|
31
|
+
* Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* // Option 1: Explicit API key (direct API access)
|
|
36
|
+
* const client = createDecartClient({ apiKey: "your-api-key" });
|
|
37
|
+
*
|
|
38
|
+
* // Option 2: Using DECART_API_KEY environment variable
|
|
39
|
+
* const client = createDecartClient();
|
|
40
|
+
*
|
|
41
|
+
* // Option 3: Using proxy (client-side, no API key needed)
|
|
42
|
+
* const client = createDecartClient({ proxy: "https://your-server.com/api/decart" });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
//#endregion
|
|
46
|
+
export { DecartClientOptions };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createInvalidApiKeyError, createInvalidBaseUrlError } from "./utils/errors.js";
|
|
2
|
+
import { createFilesClient } from "./files/client.js";
|
|
3
|
+
import { createProcessClient } from "./process/client.js";
|
|
4
|
+
import { createQueueClient } from "./queue/client.js";
|
|
5
|
+
import { createTokensClient } from "./tokens/client.js";
|
|
6
|
+
import { readEnv } from "./utils/env.js";
|
|
7
|
+
import { createConsoleLogger } from "./utils/logger.js";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
//#region src/create-client.ts
|
|
10
|
+
const proxySchema = z.union([z.string().url(), z.string().startsWith("/")]);
|
|
11
|
+
const decartClientOptionsSchema = z.object({
|
|
12
|
+
apiKey: z.string().min(1).optional(),
|
|
13
|
+
baseUrl: z.url().optional(),
|
|
14
|
+
proxy: proxySchema.optional(),
|
|
15
|
+
integration: z.string().optional(),
|
|
16
|
+
realtimeBaseUrl: z.url().optional()
|
|
17
|
+
}).refine((data) => {
|
|
18
|
+
const hasProxy = !!data.proxy;
|
|
19
|
+
const hasApiKey = !!data.apiKey;
|
|
20
|
+
return !(hasProxy && hasApiKey);
|
|
21
|
+
}, { message: "Cannot provide both 'proxy' and 'apiKey'. Use 'proxy' for proxy mode or 'apiKey' for direct API access." });
|
|
22
|
+
/**
|
|
23
|
+
* Create a Decart API client.
|
|
24
|
+
*
|
|
25
|
+
* @param options - Configuration options
|
|
26
|
+
* @param options.proxy - URL of the proxy server. When set, the client will use the proxy instead of direct API access and apiKey is not required.
|
|
27
|
+
* @param options.apiKey - API key for authentication.
|
|
28
|
+
* @param options.baseUrl - Override the default API base URL.
|
|
29
|
+
* @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
|
|
30
|
+
* @param options.integration - Optional integration identifier.
|
|
31
|
+
*
|
|
32
|
+
* Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* // Option 1: Explicit API key (direct API access)
|
|
37
|
+
* const client = createDecartClient({ apiKey: "your-api-key" });
|
|
38
|
+
*
|
|
39
|
+
* // Option 2: Using DECART_API_KEY environment variable
|
|
40
|
+
* const client = createDecartClient();
|
|
41
|
+
*
|
|
42
|
+
* // Option 3: Using proxy (client-side, no API key needed)
|
|
43
|
+
* const client = createDecartClient({ proxy: "https://your-server.com/api/decart" });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
const createDecartClientForPlatform = (createRealtime, options = {}) => {
|
|
47
|
+
const parsedOptions = decartClientOptionsSchema.safeParse(options);
|
|
48
|
+
if (!parsedOptions.success) {
|
|
49
|
+
const issue = parsedOptions.error.issues[0];
|
|
50
|
+
if (issue.path.includes("apiKey")) throw createInvalidApiKeyError();
|
|
51
|
+
if (issue.path.includes("baseUrl") || issue.path.includes("realtimeBaseUrl")) throw createInvalidBaseUrlError(options[issue.path.includes("realtimeBaseUrl") ? "realtimeBaseUrl" : "baseUrl"]);
|
|
52
|
+
if (issue.path.includes("proxy")) throw createInvalidBaseUrlError(issue.path.includes("proxy") ? options.proxy : void 0);
|
|
53
|
+
throw parsedOptions.error;
|
|
54
|
+
}
|
|
55
|
+
const isProxyMode = "proxy" in parsedOptions.data && !!parsedOptions.data.proxy;
|
|
56
|
+
const apiKey = isProxyMode ? void 0 : ("apiKey" in parsedOptions.data ? parsedOptions.data.apiKey : void 0) ?? readEnv("DECART_API_KEY");
|
|
57
|
+
if (!isProxyMode && !apiKey) throw createInvalidApiKeyError();
|
|
58
|
+
let baseUrl;
|
|
59
|
+
if (isProxyMode && "proxy" in parsedOptions.data && parsedOptions.data.proxy) baseUrl = parsedOptions.data.proxy;
|
|
60
|
+
else baseUrl = parsedOptions.data.baseUrl || "https://api.decart.ai";
|
|
61
|
+
const { integration } = parsedOptions.data;
|
|
62
|
+
const logger = "logger" in options && options.logger ? options.logger : createConsoleLogger("info");
|
|
63
|
+
const telemetryEnabled = !("telemetry" in options && options.telemetry === false);
|
|
64
|
+
const wsBaseUrl = parsedOptions.data.realtimeBaseUrl || "wss://api3.decart.ai";
|
|
65
|
+
const realtime = createRealtime({
|
|
66
|
+
publishBaseUrl: wsBaseUrl,
|
|
67
|
+
subscribeBaseUrl: isProxyMode || parsedOptions.data.baseUrl !== void 0 ? baseUrl : wsBaseUrl.replace(/^wss?:\/\//i, "https://"),
|
|
68
|
+
apiKey: apiKey || "",
|
|
69
|
+
integration,
|
|
70
|
+
logger,
|
|
71
|
+
telemetryEnabled
|
|
72
|
+
});
|
|
73
|
+
const process = createProcessClient({
|
|
74
|
+
baseUrl,
|
|
75
|
+
apiKey: apiKey || "",
|
|
76
|
+
integration
|
|
77
|
+
});
|
|
78
|
+
const queue = createQueueClient({
|
|
79
|
+
baseUrl,
|
|
80
|
+
apiKey: apiKey || "",
|
|
81
|
+
integration
|
|
82
|
+
});
|
|
83
|
+
const tokens = createTokensClient({
|
|
84
|
+
baseUrl,
|
|
85
|
+
apiKey: apiKey || "",
|
|
86
|
+
integration
|
|
87
|
+
});
|
|
88
|
+
const files = createFilesClient({
|
|
89
|
+
baseUrl,
|
|
90
|
+
apiKey: apiKey || "",
|
|
91
|
+
integration
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
realtime: {
|
|
95
|
+
connect: realtime.connect,
|
|
96
|
+
subscribe: realtime.subscribe,
|
|
97
|
+
checkConnectivity: realtime.checkConnectivity
|
|
98
|
+
},
|
|
99
|
+
process,
|
|
100
|
+
queue,
|
|
101
|
+
tokens,
|
|
102
|
+
files
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
//#endregion
|
|
106
|
+
export { createDecartClientForPlatform };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CanonicalModel, CustomModelDefinition, ImageModelDefinition, ImageModels, ListedModelDefinition, Model, ModelDefinition, ModelKind, RealTimeModels, VideoModelDefinition, VideoModels, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveModelAlias } from "./shared/model.js";
|
|
1
|
+
import { CanonicalModel, CustomModelDefinition, ImageModelDefinition, ImageModels, ListedModelDefinition, Model, ModelDefinition, ModelFps, ModelKind, RealTimeModels, VideoModelDefinition, VideoModels, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias } from "./shared/model.js";
|
|
3
2
|
import { FileInput, ProcessOptions, ReactNativeFile } from "./process/types.js";
|
|
4
3
|
import { FileReference, FileUploadInput } from "./files/types.js";
|
|
5
4
|
import { FilesClient, UploadFileOptions } from "./files/client.js";
|
|
@@ -7,172 +6,31 @@ import { ProcessClient } from "./process/client.js";
|
|
|
7
6
|
import { JobStatus, JobStatusResponse, JobSubmitResponse, QueueJobResult, QueueSubmitAndPollOptions, QueueSubmitOptions } from "./queue/types.js";
|
|
8
7
|
import { QueueClient } from "./queue/client.js";
|
|
9
8
|
import { DecartSDKError, ERROR_CODES } from "./utils/errors.js";
|
|
10
|
-
import {
|
|
9
|
+
import { LogLevel, Logger, createConsoleLogger, noopLogger } from "./utils/logger.js";
|
|
10
|
+
import { G2GMetrics } from "./realtime/observability/g2g.js";
|
|
11
11
|
import { WebRTCStats } from "./realtime/observability/webrtc-stats.js";
|
|
12
12
|
import { ConnectionQuality, ConnectionQualityLimitingFactor, ConnectionQualityMetrics, ConnectionQualityReport } from "./realtime/observability/connection-quality.js";
|
|
13
13
|
import { ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ReconnectEvent, VideoStallEvent } from "./realtime/observability/diagnostics.js";
|
|
14
14
|
import { ConnectionState, GenerationEndedMessage, QueuePosition, QueuePositionMessage } from "./realtime/types.js";
|
|
15
15
|
import { SetInput } from "./realtime/methods.js";
|
|
16
|
-
import { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState } from "./realtime/client.js";
|
|
17
|
-
import { CheckConnectivityOptions, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport } from "./realtime/preflight.js";
|
|
16
|
+
import { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState, RealtimeMediaStream } from "./realtime/client.js";
|
|
17
|
+
import { CheckConnectivityOptions, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport } from "./realtime/preflight-types.js";
|
|
18
18
|
import { RealTimeSubscribeClient, SubscribeEvents, SubscribeOptions } from "./realtime/subscribe-client.js";
|
|
19
19
|
import { ModelState } from "./shared/types.js";
|
|
20
20
|
import { CreateTokenOptions, CreateTokenResponse, TokensClient } from "./tokens/client.js";
|
|
21
|
+
import { DecartClientOptions } from "./create-client.js";
|
|
21
22
|
|
|
22
23
|
//#region src/index.d.ts
|
|
23
|
-
type DecartClientOptions = {
|
|
24
|
-
proxy: string;
|
|
25
|
-
apiKey?: never;
|
|
26
|
-
baseUrl?: string;
|
|
27
|
-
realtimeBaseUrl?: string;
|
|
28
|
-
integration?: string;
|
|
29
|
-
logger?: Logger;
|
|
30
|
-
telemetry?: boolean;
|
|
31
|
-
} | {
|
|
32
|
-
proxy?: never;
|
|
33
|
-
apiKey?: string;
|
|
34
|
-
baseUrl?: string;
|
|
35
|
-
realtimeBaseUrl?: string;
|
|
36
|
-
integration?: string;
|
|
37
|
-
logger?: Logger;
|
|
38
|
-
telemetry?: boolean;
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Create a Decart API client.
|
|
42
|
-
*
|
|
43
|
-
* @param options - Configuration options
|
|
44
|
-
* @param options.proxy - URL of the proxy server. When set, the client will use the proxy instead of direct API access and apiKey is not required.
|
|
45
|
-
* @param options.apiKey - API key for authentication.
|
|
46
|
-
* @param options.baseUrl - Override the default API base URL.
|
|
47
|
-
* @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
|
|
48
|
-
* @param options.integration - Optional integration identifier.
|
|
49
|
-
*
|
|
50
|
-
* Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```ts
|
|
54
|
-
* // (direct API access)Option 1: Explicit API key
|
|
55
|
-
* const client = createDecartClient({ apiKey: "your-api-key" });
|
|
56
|
-
*
|
|
57
|
-
* // Option 2: Using DECART_API_KEY environment variable
|
|
58
|
-
* const client = createDecartClient();
|
|
59
|
-
*
|
|
60
|
-
* // Option 3: Using proxy (client-side, no API key needed)
|
|
61
|
-
* const client = createDecartClient({ proxy: "https://your-server.com/api/decart" });
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
24
|
declare const createDecartClient: (options?: DecartClientOptions) => {
|
|
65
25
|
realtime: {
|
|
66
|
-
connect: (stream:
|
|
26
|
+
connect: <TStream extends RealtimeMediaStream = MediaStream>(stream: TStream | null, options: RealTimeClientConnectOptions<TStream>) => Promise<RealTimeClient>;
|
|
67
27
|
subscribe: (options: SubscribeOptions) => Promise<RealTimeSubscribeClient>;
|
|
68
|
-
/**
|
|
69
|
-
* Check whether the user's network can support a real-time session
|
|
70
|
-
* *before* connecting — so you can gate showing the integration.
|
|
71
|
-
*
|
|
72
|
-
* Default (STUN-only): validates WebRTC reachability (UDP egress / TURN
|
|
73
|
-
* need) and approximate latency via a throwaway peer connection — no
|
|
74
|
-
* session, instant. Opt-in deep probe (`{ deep: true, model }`): briefly
|
|
75
|
-
* opens a real session with a synthetic source and measures *true*
|
|
76
|
-
* glass-to-glass latency (and end-to-end drops / upstream loss+jitter),
|
|
77
|
-
* then tears it down — accurate, but costs a short GPU session.
|
|
78
|
-
*
|
|
79
|
-
* @example
|
|
80
|
-
* ```ts
|
|
81
|
-
* // Fast, pre-session reachability check
|
|
82
|
-
* const { quality, reasons } = await client.realtime.checkConnectivity();
|
|
83
|
-
* if (quality === "critical") showFallbackUI(reasons);
|
|
84
|
-
*
|
|
85
|
-
* // Accurate, measured glass-to-glass verdict
|
|
86
|
-
* const probe = await client.realtime.checkConnectivity({ deep: true, model: models.realtime("mirage") });
|
|
87
|
-
* console.log(probe.metrics.g2gMs);
|
|
88
|
-
* ```
|
|
89
|
-
*/
|
|
90
28
|
checkConnectivity: (options?: CheckConnectivityOptions) => Promise<ConnectivityReport>;
|
|
91
29
|
};
|
|
92
|
-
/**
|
|
93
|
-
* Client for synchronous image generation.
|
|
94
|
-
* Only image models support the sync/process API.
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* ```ts
|
|
98
|
-
* const client = createDecartClient({ apiKey: "your-api-key" });
|
|
99
|
-
* const result = await client.process({
|
|
100
|
-
* model: models.image("lucy-pro-i2i"),
|
|
101
|
-
* prompt: "Transform into anime style",
|
|
102
|
-
* data: imageBlob
|
|
103
|
-
* });
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
30
|
process: ProcessClient;
|
|
107
|
-
/**
|
|
108
|
-
* Client for queue-based async video generation.
|
|
109
|
-
* Only video models support the queue API.
|
|
110
|
-
* Jobs are submitted and processed asynchronously.
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* ```ts
|
|
114
|
-
* const client = createDecartClient({ apiKey: "your-api-key" });
|
|
115
|
-
*
|
|
116
|
-
* // Option 1: Submit and poll automatically
|
|
117
|
-
* const result = await client.queue.submitAndPoll({
|
|
118
|
-
* model: models.video("lucy-pro-v2v"),
|
|
119
|
-
* prompt: "Transform into anime style",
|
|
120
|
-
* data: videoBlob,
|
|
121
|
-
* onStatusChange: (job) => console.log(`Job ${job.job_id}: ${job.status}`)
|
|
122
|
-
* });
|
|
123
|
-
*
|
|
124
|
-
* // Option 2: Submit and poll manually
|
|
125
|
-
* const job = await client.queue.submit({
|
|
126
|
-
* model: models.video("lucy-pro-v2v"),
|
|
127
|
-
* prompt: "Transform into anime style",
|
|
128
|
-
* data: videoBlob
|
|
129
|
-
* });
|
|
130
|
-
*
|
|
131
|
-
* // Poll until completion
|
|
132
|
-
* while (true) {
|
|
133
|
-
* const status = await client.queue.status(job.job_id);
|
|
134
|
-
* console.log(`Job ${status.job_id}: ${status.status}`);
|
|
135
|
-
*
|
|
136
|
-
* if (status.status === "completed") {
|
|
137
|
-
* const blob = await client.queue.result(job.job_id);
|
|
138
|
-
* break;
|
|
139
|
-
* }
|
|
140
|
-
* if (status.status === "failed") {
|
|
141
|
-
* throw new Error("Job failed");
|
|
142
|
-
* }
|
|
143
|
-
* await new Promise(resolve => setTimeout(resolve, 1500));
|
|
144
|
-
* }
|
|
145
|
-
* ```
|
|
146
|
-
*/
|
|
147
31
|
queue: QueueClient;
|
|
148
|
-
/**
|
|
149
|
-
* Client for creating client tokens.
|
|
150
|
-
* Client tokens are short-lived API keys safe for client-side use.
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```ts
|
|
154
|
-
* // Server-side: Create a client token
|
|
155
|
-
* const serverClient = createDecartClient({ apiKey: process.env.DECART_API_KEY });
|
|
156
|
-
* const token = await serverClient.tokens.create();
|
|
157
|
-
* // Returns: { apiKey: "ek_...", expiresAt: "2024-12-15T12:10:00Z" }
|
|
158
|
-
*
|
|
159
|
-
* // Client-side: Use the client token
|
|
160
|
-
* const client = createDecartClient({ apiKey: token.apiKey });
|
|
161
|
-
* const realtimeClient = await client.realtime.connect(stream, options);
|
|
162
|
-
* ```
|
|
163
|
-
*/
|
|
164
32
|
tokens: TokensClient;
|
|
165
|
-
/**
|
|
166
|
-
* Upload files once and reuse them across generations.
|
|
167
|
-
*
|
|
168
|
-
* @example
|
|
169
|
-
* ```ts
|
|
170
|
-
* const ref = await client.files.upload(blob);
|
|
171
|
-
* await rt.set({ image: ref.id, prompt: "make it cinematic" });
|
|
172
|
-
* await rt.set({ image: ref.id, prompt: "now in noir" });
|
|
173
|
-
* ```
|
|
174
|
-
*/
|
|
175
33
|
files: FilesClient;
|
|
176
34
|
};
|
|
177
35
|
//#endregion
|
|
178
|
-
export {
|
|
36
|
+
export { CanonicalModel, CheckConnectivityOptions, ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, ConnectionQuality, ConnectionQualityLimitingFactor, ConnectionQualityMetrics, ConnectionQualityReport, ConnectionState, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport, CreateTokenOptions, CreateTokenResponse, CustomModelDefinition, type DecartClientOptions, DecartSDKError, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ERROR_CODES, FileInput, FileReference, FileUploadInput, FilesClient, G2GMetrics, GenerationEndedMessage, ImageModelDefinition, ImageModels, JobStatus, JobStatusResponse, JobSubmitResponse, ListedModelDefinition, LogLevel, Logger, Model, ModelDefinition, ModelFps, ModelKind, ModelState, ProcessClient, ProcessOptions, QueueClient, QueueJobResult, QueuePosition, QueuePositionMessage, QueueSubmitAndPollOptions, QueueSubmitOptions, ReactNativeFile, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState, Events as RealTimeEvents, RealTimeModels, RealTimeSubscribeClient, RealtimeMediaStream, ReconnectEvent, SetInput, SubscribeEvents, SubscribeOptions, TokensClient, UploadFileOptions, VideoModelDefinition, VideoModels, VideoStallEvent, WebRTCStats, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
|
package/dist/index.js
CHANGED
|
@@ -1,119 +1,9 @@
|
|
|
1
|
-
import { ERROR_CODES
|
|
2
|
-
import { createFilesClient } from "./files/client.js";
|
|
3
|
-
import { createProcessClient } from "./process/client.js";
|
|
4
|
-
import { createQueueClient } from "./queue/client.js";
|
|
5
|
-
import { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveModelAlias } from "./shared/model.js";
|
|
1
|
+
import { ERROR_CODES } from "./utils/errors.js";
|
|
6
2
|
import { createConsoleLogger, noopLogger } from "./utils/logger.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { createTokensClient } from "./tokens/client.js";
|
|
11
|
-
import { readEnv } from "./utils/env.js";
|
|
12
|
-
import { z } from "zod";
|
|
3
|
+
import { createDecartClientForPlatform } from "./create-client.js";
|
|
4
|
+
import { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias } from "./shared/model.js";
|
|
5
|
+
import { createBrowserRealtime } from "./realtime/browser/index.js";
|
|
13
6
|
//#region src/index.ts
|
|
14
|
-
const
|
|
15
|
-
const decartClientOptionsSchema = z.object({
|
|
16
|
-
apiKey: z.string().min(1).optional(),
|
|
17
|
-
baseUrl: z.url().optional(),
|
|
18
|
-
proxy: proxySchema.optional(),
|
|
19
|
-
integration: z.string().optional(),
|
|
20
|
-
realtimeBaseUrl: z.url().optional()
|
|
21
|
-
}).refine((data) => {
|
|
22
|
-
const hasProxy = !!data.proxy;
|
|
23
|
-
const hasApiKey = !!data.apiKey;
|
|
24
|
-
return !(hasProxy && hasApiKey);
|
|
25
|
-
}, { message: "Cannot provide both 'proxy' and 'apiKey'. Use 'proxy' for proxy mode or 'apiKey' for direct API access." });
|
|
26
|
-
/**
|
|
27
|
-
* Create a Decart API client.
|
|
28
|
-
*
|
|
29
|
-
* @param options - Configuration options
|
|
30
|
-
* @param options.proxy - URL of the proxy server. When set, the client will use the proxy instead of direct API access and apiKey is not required.
|
|
31
|
-
* @param options.apiKey - API key for authentication.
|
|
32
|
-
* @param options.baseUrl - Override the default API base URL.
|
|
33
|
-
* @param options.realtimeBaseUrl - Override the default WebSocket base URL for realtime connections.
|
|
34
|
-
* @param options.integration - Optional integration identifier.
|
|
35
|
-
*
|
|
36
|
-
* Realtime media uses LiveKit only (inference must enable it in `TRANSPORTS_ENABLED`).
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```ts
|
|
40
|
-
* // (direct API access)Option 1: Explicit API key
|
|
41
|
-
* const client = createDecartClient({ apiKey: "your-api-key" });
|
|
42
|
-
*
|
|
43
|
-
* // Option 2: Using DECART_API_KEY environment variable
|
|
44
|
-
* const client = createDecartClient();
|
|
45
|
-
*
|
|
46
|
-
* // Option 3: Using proxy (client-side, no API key needed)
|
|
47
|
-
* const client = createDecartClient({ proxy: "https://your-server.com/api/decart" });
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
const createDecartClient = (options = {}) => {
|
|
51
|
-
const parsedOptions = decartClientOptionsSchema.safeParse(options);
|
|
52
|
-
if (!parsedOptions.success) {
|
|
53
|
-
const issue = parsedOptions.error.issues[0];
|
|
54
|
-
if (issue.path.includes("apiKey")) throw createInvalidApiKeyError();
|
|
55
|
-
if (issue.path.includes("baseUrl") || issue.path.includes("realtimeBaseUrl")) throw createInvalidBaseUrlError(options[issue.path.includes("realtimeBaseUrl") ? "realtimeBaseUrl" : "baseUrl"]);
|
|
56
|
-
if (issue.path.includes("proxy")) throw createInvalidBaseUrlError(issue.path.includes("proxy") ? options.proxy : void 0);
|
|
57
|
-
throw parsedOptions.error;
|
|
58
|
-
}
|
|
59
|
-
const isProxyMode = "proxy" in parsedOptions.data && !!parsedOptions.data.proxy;
|
|
60
|
-
const apiKey = isProxyMode ? void 0 : ("apiKey" in parsedOptions.data ? parsedOptions.data.apiKey : void 0) ?? readEnv("DECART_API_KEY");
|
|
61
|
-
if (!isProxyMode && !apiKey) throw createInvalidApiKeyError();
|
|
62
|
-
let baseUrl;
|
|
63
|
-
if (isProxyMode && "proxy" in parsedOptions.data && parsedOptions.data.proxy) baseUrl = parsedOptions.data.proxy;
|
|
64
|
-
else baseUrl = parsedOptions.data.baseUrl || "https://api.decart.ai";
|
|
65
|
-
const { integration } = parsedOptions.data;
|
|
66
|
-
const logger = "logger" in options && options.logger ? options.logger : createConsoleLogger("info");
|
|
67
|
-
const telemetryEnabled = !("telemetry" in options && options.telemetry === false);
|
|
68
|
-
const wsBaseUrl = parsedOptions.data.realtimeBaseUrl || "wss://api3.decart.ai";
|
|
69
|
-
const realtimePublish = createRealTimeClient({
|
|
70
|
-
baseUrl: wsBaseUrl,
|
|
71
|
-
apiKey: apiKey || "",
|
|
72
|
-
integration,
|
|
73
|
-
logger,
|
|
74
|
-
telemetryEnabled
|
|
75
|
-
});
|
|
76
|
-
const realtimeSubscribe = createRealTimeSubscribeClient({
|
|
77
|
-
baseUrl: isProxyMode || parsedOptions.data.baseUrl !== void 0 ? baseUrl : wsBaseUrl.replace(/^wss?:\/\//i, "https://"),
|
|
78
|
-
apiKey: apiKey || "",
|
|
79
|
-
integration,
|
|
80
|
-
logger
|
|
81
|
-
});
|
|
82
|
-
const preflight = createPreflight({
|
|
83
|
-
logger,
|
|
84
|
-
connect: realtimePublish.connect
|
|
85
|
-
});
|
|
86
|
-
const process = createProcessClient({
|
|
87
|
-
baseUrl,
|
|
88
|
-
apiKey: apiKey || "",
|
|
89
|
-
integration
|
|
90
|
-
});
|
|
91
|
-
const queue = createQueueClient({
|
|
92
|
-
baseUrl,
|
|
93
|
-
apiKey: apiKey || "",
|
|
94
|
-
integration
|
|
95
|
-
});
|
|
96
|
-
const tokens = createTokensClient({
|
|
97
|
-
baseUrl,
|
|
98
|
-
apiKey: apiKey || "",
|
|
99
|
-
integration
|
|
100
|
-
});
|
|
101
|
-
const files = createFilesClient({
|
|
102
|
-
baseUrl,
|
|
103
|
-
apiKey: apiKey || "",
|
|
104
|
-
integration
|
|
105
|
-
});
|
|
106
|
-
return {
|
|
107
|
-
realtime: {
|
|
108
|
-
connect: realtimePublish.connect,
|
|
109
|
-
subscribe: realtimeSubscribe.subscribe,
|
|
110
|
-
checkConnectivity: preflight.checkConnectivity
|
|
111
|
-
},
|
|
112
|
-
process,
|
|
113
|
-
queue,
|
|
114
|
-
tokens,
|
|
115
|
-
files
|
|
116
|
-
};
|
|
117
|
-
};
|
|
7
|
+
const createDecartClient = (options = {}) => createDecartClientForPlatform(createBrowserRealtime, options);
|
|
118
8
|
//#endregion
|
|
119
|
-
export { ERROR_CODES, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveModelAlias };
|
|
9
|
+
export { ERROR_CODES, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CanonicalModel, CustomModelDefinition, ImageModelDefinition, ImageModels, ListedModelDefinition, Model, ModelDefinition, ModelFps, ModelKind, RealTimeModels, VideoModelDefinition, VideoModels, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias } from "./shared/model.js";
|
|
2
|
+
import { FileInput, ProcessOptions, ReactNativeFile } from "./process/types.js";
|
|
3
|
+
import { FileReference, FileUploadInput } from "./files/types.js";
|
|
4
|
+
import { FilesClient, UploadFileOptions } from "./files/client.js";
|
|
5
|
+
import { ProcessClient } from "./process/client.js";
|
|
6
|
+
import { JobStatus, JobStatusResponse, JobSubmitResponse, QueueJobResult, QueueSubmitAndPollOptions, QueueSubmitOptions } from "./queue/types.js";
|
|
7
|
+
import { QueueClient } from "./queue/client.js";
|
|
8
|
+
import { DecartSDKError, ERROR_CODES } from "./utils/errors.js";
|
|
9
|
+
import { LogLevel, Logger, createConsoleLogger, noopLogger } from "./utils/logger.js";
|
|
10
|
+
import { G2GMetrics } from "./realtime/observability/g2g.js";
|
|
11
|
+
import { WebRTCStats } from "./realtime/observability/webrtc-stats.js";
|
|
12
|
+
import { ConnectionQuality, ConnectionQualityLimitingFactor, ConnectionQualityMetrics, ConnectionQualityReport } from "./realtime/observability/connection-quality.js";
|
|
13
|
+
import { ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ReconnectEvent, VideoStallEvent } from "./realtime/observability/diagnostics.js";
|
|
14
|
+
import { ConnectionState, GenerationEndedMessage, QueuePosition, QueuePositionMessage } from "./realtime/types.js";
|
|
15
|
+
import { SetInput } from "./realtime/methods.js";
|
|
16
|
+
import { Events, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState, RealtimeMediaStream } from "./realtime/client.js";
|
|
17
|
+
import { CheckConnectivityOptions, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport } from "./realtime/preflight-types.js";
|
|
18
|
+
import { RealTimeSubscribeClient, SubscribeEvents, SubscribeOptions } from "./realtime/subscribe-client.js";
|
|
19
|
+
import { ModelState } from "./shared/types.js";
|
|
20
|
+
import { CreateTokenOptions, CreateTokenResponse, TokensClient } from "./tokens/client.js";
|
|
21
|
+
import { DecartClientOptions } from "./create-client.js";
|
|
22
|
+
|
|
23
|
+
//#region src/index.react-native.d.ts
|
|
24
|
+
declare const createDecartClient: (options?: DecartClientOptions) => {
|
|
25
|
+
realtime: {
|
|
26
|
+
connect: <TStream extends RealtimeMediaStream = MediaStream>(stream: TStream | null, options: RealTimeClientConnectOptions<TStream>) => Promise<RealTimeClient>;
|
|
27
|
+
subscribe: (options: SubscribeOptions) => Promise<RealTimeSubscribeClient>;
|
|
28
|
+
checkConnectivity: (options?: CheckConnectivityOptions) => Promise<ConnectivityReport>;
|
|
29
|
+
};
|
|
30
|
+
process: ProcessClient;
|
|
31
|
+
queue: QueueClient;
|
|
32
|
+
tokens: TokensClient;
|
|
33
|
+
files: FilesClient;
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { CanonicalModel, CheckConnectivityOptions, ClientSessionConnectionBreakdownEvent, ClientSessionConnectionBreakdownPhase, ConnectionQuality, ConnectionQualityLimitingFactor, ConnectionQualityMetrics, ConnectionQualityReport, ConnectionState, ConnectivityMetrics, ConnectivityReport, ConnectivityTransport, CreateTokenOptions, CreateTokenResponse, CustomModelDefinition, type DecartClientOptions, DecartSDKError, DiagnosticEvent, DiagnosticEventName, DiagnosticEvents, ERROR_CODES, FileInput, FileReference, FileUploadInput, FilesClient, G2GMetrics, GenerationEndedMessage, ImageModelDefinition, ImageModels, JobStatus, JobStatusResponse, JobSubmitResponse, ListedModelDefinition, LogLevel, Logger, Model, ModelDefinition, ModelFps, ModelKind, ModelState, ProcessClient, ProcessOptions, QueueClient, QueueJobResult, QueuePosition, QueuePositionMessage, QueueSubmitAndPollOptions, QueueSubmitOptions, ReactNativeFile, RealTimeClient, RealTimeClientConnectOptions, RealTimeClientInitialState, Events as RealTimeEvents, RealTimeModels, RealTimeSubscribeClient, RealtimeMediaStream, ReconnectEvent, SetInput, SubscribeEvents, SubscribeOptions, TokensClient, UploadFileOptions, VideoModelDefinition, VideoModels, VideoStallEvent, WebRTCStats, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ERROR_CODES } from "./utils/errors.js";
|
|
2
|
+
import { createConsoleLogger, noopLogger } from "./utils/logger.js";
|
|
3
|
+
import { createDecartClientForPlatform } from "./create-client.js";
|
|
4
|
+
import { isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias } from "./shared/model.js";
|
|
5
|
+
import { createReactNativeRealtime } from "./realtime/react-native/index.js";
|
|
6
|
+
//#region src/index.react-native.ts
|
|
7
|
+
const createDecartClient = (options = {}) => createDecartClientForPlatform(createReactNativeRealtime, options);
|
|
8
|
+
//#endregion
|
|
9
|
+
export { ERROR_CODES, createConsoleLogger, createDecartClient, isCanonicalModel, isImageModel, isModel, isRealtimeModel, isVideoModel, listModels, modelAliases, models, noopLogger, resolveCanonicalModelAlias, resolveFpsNumber, resolveModelAlias };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SeqTracker, createMarkerReader, createStampPump } from "./glass-to-glass.js";
|
|
2
|
+
//#region src/realtime/browser/glass-to-glass-diagnostics.ts
|
|
3
|
+
function createBrowserGlassToGlassDiagnostics() {
|
|
4
|
+
const tracker = new SeqTracker();
|
|
5
|
+
const reader = createMarkerReader(tracker);
|
|
6
|
+
let pump;
|
|
7
|
+
return {
|
|
8
|
+
attachOutgoingStream: (stream, fps) => {
|
|
9
|
+
pump?.dispose();
|
|
10
|
+
pump = createStampPump(stream, {
|
|
11
|
+
tracker,
|
|
12
|
+
fps
|
|
13
|
+
});
|
|
14
|
+
return pump.stream;
|
|
15
|
+
},
|
|
16
|
+
attachRemoteVideoTrack: (track) => reader.attach(track),
|
|
17
|
+
markStart: () => tracker.markStart(performance.now()),
|
|
18
|
+
snapshot: () => tracker.snapshot(),
|
|
19
|
+
dispose: () => {
|
|
20
|
+
pump?.dispose();
|
|
21
|
+
pump = void 0;
|
|
22
|
+
reader.dispose();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { createBrowserGlassToGlassDiagnostics };
|