@curvet/sdk 0.1.0 → 0.3.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.
- package/CHANGELOG.md +45 -0
- package/README.md +73 -1
- package/dist/index.cjs +301 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +233 -24
- package/dist/index.d.ts +233 -24
- package/dist/index.js +290 -19
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ interface FetchResponse {
|
|
|
29
29
|
interface FetchInit {
|
|
30
30
|
method?: string;
|
|
31
31
|
headers?: Record<string, string>;
|
|
32
|
-
body?: string;
|
|
32
|
+
body?: string | FormData;
|
|
33
33
|
signal?: AbortSignal;
|
|
34
34
|
}
|
|
35
35
|
/** Injectable fetch implementation (defaults to global fetch on Node 18+). */
|
|
@@ -173,6 +173,17 @@ interface VideoGenerateParams {
|
|
|
173
173
|
resolution?: string;
|
|
174
174
|
[key: string]: unknown;
|
|
175
175
|
}
|
|
176
|
+
interface AudioGenerateParams {
|
|
177
|
+
model: ModelId;
|
|
178
|
+
prompt: string;
|
|
179
|
+
voice?: string;
|
|
180
|
+
[key: string]: unknown;
|
|
181
|
+
}
|
|
182
|
+
interface ThreeDGenerateParams {
|
|
183
|
+
model: ModelId;
|
|
184
|
+
prompt: string;
|
|
185
|
+
[key: string]: unknown;
|
|
186
|
+
}
|
|
176
187
|
interface PollOptions {
|
|
177
188
|
/** Poll interval in ms (default 2500). */
|
|
178
189
|
pollIntervalMs?: number;
|
|
@@ -211,32 +222,46 @@ declare class Job {
|
|
|
211
222
|
wait(opts?: PollOptions): Promise<MediaJob>;
|
|
212
223
|
}
|
|
213
224
|
|
|
225
|
+
interface MediaParamsBase {
|
|
226
|
+
model: string;
|
|
227
|
+
prompt: string;
|
|
228
|
+
[key: string]: unknown;
|
|
229
|
+
}
|
|
214
230
|
/**
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
231
|
+
* Generic engine for the async media endpoints (video / audio / 3d). They all
|
|
232
|
+
* enqueue the same server-side job queue, so they share one implementation
|
|
233
|
+
* parameterized by `path` and request param type.
|
|
218
234
|
*
|
|
219
|
-
*
|
|
235
|
+
* `generate()` submits and polls to completion; `submit()` fires without polling.
|
|
220
236
|
*/
|
|
221
|
-
declare class
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
constructor(client: HttpClient, defaults: JobDefaults, path
|
|
226
|
-
/**
|
|
227
|
-
* Submit a job WITHOUT polling. Returns once the server responds — either the
|
|
228
|
-
* 200 fast-path (already done) or a 202 with a jobId.
|
|
229
|
-
*
|
|
230
|
-
* The media POST long-polls server-side and can block well past a normal
|
|
231
|
-
* request timeout, so we default its timeout to the poll budget and disable
|
|
232
|
-
* auto-retry (a retried POST would enqueue a duplicate, double-charged job).
|
|
233
|
-
*/
|
|
234
|
-
submit(params: VideoGenerateParams, options?: RequestOptions): Promise<MediaJob>;
|
|
237
|
+
declare class MediaResource<P extends MediaParamsBase> {
|
|
238
|
+
protected client: HttpClient;
|
|
239
|
+
protected defaults: JobDefaults;
|
|
240
|
+
protected path: string;
|
|
241
|
+
constructor(client: HttpClient, defaults: JobDefaults, path: string);
|
|
235
242
|
/**
|
|
236
|
-
* Submit
|
|
237
|
-
*
|
|
243
|
+
* Submit WITHOUT polling. The media POST long-polls server-side and can block
|
|
244
|
+
* well past a normal request timeout, so we default its timeout to the poll
|
|
245
|
+
* budget and disable auto-retry (a retried POST would enqueue a duplicate job).
|
|
238
246
|
*/
|
|
239
|
-
|
|
247
|
+
submit(params: P, options?: RequestOptions): Promise<MediaJob>;
|
|
248
|
+
/** Submit and resolve to the finished media (auto-polls /jobs/:id). */
|
|
249
|
+
generate(params: P, options?: RequestOptions & PollOptions): Promise<MediaJob>;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Video generation (async). `curvet.video.generate(...)` auto-polls to completion. */
|
|
253
|
+
declare class Video extends MediaResource<VideoGenerateParams> {
|
|
254
|
+
constructor(client: HttpClient, defaults: JobDefaults);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** Audio generation (async). `curvet.audio.generate(...)` auto-polls to completion. */
|
|
258
|
+
declare class Audio extends MediaResource<AudioGenerateParams> {
|
|
259
|
+
constructor(client: HttpClient, defaults: JobDefaults);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** 3D model generation (async). `curvet.threeD.generate(...)` auto-polls to completion. */
|
|
263
|
+
declare class ThreeD extends MediaResource<ThreeDGenerateParams> {
|
|
264
|
+
constructor(client: HttpClient, defaults: JobDefaults);
|
|
240
265
|
}
|
|
241
266
|
|
|
242
267
|
interface ModelsListOptions extends RequestOptions {
|
|
@@ -285,11 +310,179 @@ declare class Balance {
|
|
|
285
310
|
get(options?: RequestOptions): Promise<BalanceInfo>;
|
|
286
311
|
}
|
|
287
312
|
|
|
313
|
+
interface AnalyticsParams extends RequestOptions {
|
|
314
|
+
/** ISO 8601 start date. */
|
|
315
|
+
startDate?: string;
|
|
316
|
+
/** ISO 8601 end date. */
|
|
317
|
+
endDate?: string;
|
|
318
|
+
}
|
|
319
|
+
interface AnalyticsResult {
|
|
320
|
+
totalRequests?: number;
|
|
321
|
+
totalCost?: number;
|
|
322
|
+
requestsByModel?: Record<string, number>;
|
|
323
|
+
requestsByCategory?: Record<string, number>;
|
|
324
|
+
[key: string]: unknown;
|
|
325
|
+
}
|
|
326
|
+
declare class Analytics {
|
|
327
|
+
private client;
|
|
328
|
+
constructor(client: HttpClient);
|
|
329
|
+
/** Usage analytics for the app, optionally bounded by a date range. */
|
|
330
|
+
get(params?: AnalyticsParams): Promise<AnalyticsResult>;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
interface WorkflowRunParams {
|
|
334
|
+
/** Input values for the workflow. */
|
|
335
|
+
inputs?: Record<string, unknown>;
|
|
336
|
+
/** Optional file inputs, keyed by the workflow's file field name. */
|
|
337
|
+
files?: Record<string, Blob>;
|
|
338
|
+
/** Include the full execution state in the response (default true server-side). */
|
|
339
|
+
includeFullState?: boolean;
|
|
340
|
+
}
|
|
341
|
+
/** Result of a synchronous `run()` call. */
|
|
342
|
+
interface WorkflowRunResult {
|
|
343
|
+
success: boolean;
|
|
344
|
+
[key: string]: unknown;
|
|
345
|
+
}
|
|
346
|
+
type WorkflowRunStatus = "queued" | "running" | "completed" | "failed" | "stopped";
|
|
347
|
+
interface WorkflowRunNode {
|
|
348
|
+
nodeId: string;
|
|
349
|
+
nodeLabel?: string;
|
|
350
|
+
nodeType?: string;
|
|
351
|
+
status?: string;
|
|
352
|
+
executionTime?: number;
|
|
353
|
+
}
|
|
354
|
+
/** Normalized status of an async (pollable) workflow run. */
|
|
355
|
+
interface WorkflowRun {
|
|
356
|
+
runId: string;
|
|
357
|
+
status: WorkflowRunStatus;
|
|
358
|
+
progress?: number;
|
|
359
|
+
totalNodes?: number;
|
|
360
|
+
completedNodeCount?: number;
|
|
361
|
+
/** The node currently executing (null when finished/queued). */
|
|
362
|
+
currentNode?: {
|
|
363
|
+
id: string;
|
|
364
|
+
label?: string;
|
|
365
|
+
type?: string;
|
|
366
|
+
} | null;
|
|
367
|
+
nodesExecuted?: WorkflowRunNode[];
|
|
368
|
+
/** Final outputs (present once completed). */
|
|
369
|
+
result?: unknown;
|
|
370
|
+
error?: string | null;
|
|
371
|
+
startTime?: string;
|
|
372
|
+
endTime?: string;
|
|
373
|
+
/** Raw, unnormalized response body. */
|
|
374
|
+
raw: unknown;
|
|
375
|
+
}
|
|
376
|
+
interface WorkflowSubmitResult {
|
|
377
|
+
runId: string;
|
|
378
|
+
status: WorkflowRunStatus;
|
|
379
|
+
raw: unknown;
|
|
380
|
+
}
|
|
381
|
+
interface WorkflowPollOptions {
|
|
382
|
+
/** Poll interval in ms (default 2500). */
|
|
383
|
+
pollIntervalMs?: number;
|
|
384
|
+
/** Total poll timeout in ms before throwing WorkflowRunTimeoutError (default 300000). */
|
|
385
|
+
pollTimeoutMs?: number;
|
|
386
|
+
signal?: AbortSignal;
|
|
387
|
+
/** Called on each poll tick with the latest run status (current node, progress). */
|
|
388
|
+
onProgress?: (run: WorkflowRun) => void;
|
|
389
|
+
}
|
|
390
|
+
/** Retrieve async workflow-run status. */
|
|
391
|
+
declare class WorkflowRuns {
|
|
392
|
+
private client;
|
|
393
|
+
constructor(client: HttpClient);
|
|
394
|
+
/** Fetch the current status of an async run once (no polling). */
|
|
395
|
+
retrieve(runId: string, options?: RequestOptions): Promise<WorkflowRun>;
|
|
396
|
+
}
|
|
397
|
+
declare class Workflows {
|
|
398
|
+
private client;
|
|
399
|
+
readonly runs: WorkflowRuns;
|
|
400
|
+
constructor(client: HttpClient);
|
|
401
|
+
/**
|
|
402
|
+
* Execute a workflow synchronously (blocks until it finishes). Best for short
|
|
403
|
+
* workflows; for long ones (video/audio/3D nodes) prefer `runAndPoll`.
|
|
404
|
+
* Sends JSON, or multipart/form-data when file inputs are provided.
|
|
405
|
+
*/
|
|
406
|
+
run(id: string, params?: WorkflowRunParams, options?: RequestOptions): Promise<WorkflowRunResult>;
|
|
407
|
+
/**
|
|
408
|
+
* Submit a workflow in async (pollable) mode — returns immediately with a
|
|
409
|
+
* runId. Poll `runs.retrieve(runId)` for status, or use `runAndPoll`.
|
|
410
|
+
*/
|
|
411
|
+
submit(id: string, params?: WorkflowRunParams, options?: RequestOptions): Promise<WorkflowSubmitResult>;
|
|
412
|
+
/**
|
|
413
|
+
* Submit and poll to completion. Resolves with the completed run (including
|
|
414
|
+
* `result`), reporting progress via `onProgress`. Throws WorkflowRunFailedError
|
|
415
|
+
* on failure, WorkflowRunTimeoutError on timeout.
|
|
416
|
+
*/
|
|
417
|
+
runAndPoll(id: string, params?: WorkflowRunParams, opts?: RequestOptions & WorkflowPollOptions): Promise<WorkflowRun>;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
interface FoodItem {
|
|
421
|
+
[key: string]: unknown;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Indian Food Dataset API. Mounted as a sibling of the playground under
|
|
425
|
+
* `/api/v1/food`, so it uses the v1-root HTTP client. Requires the app to have
|
|
426
|
+
* Food API access enabled.
|
|
427
|
+
*/
|
|
428
|
+
declare class Food {
|
|
429
|
+
private client;
|
|
430
|
+
constructor(client: HttpClient);
|
|
431
|
+
/** List dishes (default limit 20). */
|
|
432
|
+
list(opts?: {
|
|
433
|
+
limit?: number;
|
|
434
|
+
} & RequestOptions): Promise<FoodItem[]>;
|
|
435
|
+
/** Full-text search for dishes. */
|
|
436
|
+
search(query: string, opts?: {
|
|
437
|
+
limit?: number;
|
|
438
|
+
} & RequestOptions): Promise<FoodItem[]>;
|
|
439
|
+
/** Natural-language dish recommendations. */
|
|
440
|
+
recommendations(prompt: string, options?: RequestOptions): Promise<FoodItem[]>;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
interface SttParams {
|
|
444
|
+
/** The audio to transcribe. */
|
|
445
|
+
audio: Blob | Uint8Array | ArrayBuffer;
|
|
446
|
+
/** File name for the upload (default "audio"). */
|
|
447
|
+
filename?: string;
|
|
448
|
+
provider?: "elevenlabs" | "deepinfra" | (string & {});
|
|
449
|
+
/** ASR model id (provider-specific; optional). */
|
|
450
|
+
model?: string;
|
|
451
|
+
prompt?: string;
|
|
452
|
+
/** ISO 639-1 language hint. */
|
|
453
|
+
languageCode?: string;
|
|
454
|
+
allowFallback?: boolean;
|
|
455
|
+
}
|
|
456
|
+
interface SttResult {
|
|
457
|
+
success: boolean;
|
|
458
|
+
text: string;
|
|
459
|
+
languageCode?: string;
|
|
460
|
+
segments?: Array<{
|
|
461
|
+
start: number;
|
|
462
|
+
end: number;
|
|
463
|
+
text: string;
|
|
464
|
+
}>;
|
|
465
|
+
provider?: string;
|
|
466
|
+
creditsCharged?: number;
|
|
467
|
+
creditsRemaining?: number;
|
|
468
|
+
[key: string]: unknown;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Public speech-to-text. Mounted as a sibling of the playground under
|
|
472
|
+
* `/api/v1/voice`, so it uses the v1-root HTTP client. Multipart upload; not
|
|
473
|
+
* auto-retried (it consumes credits).
|
|
474
|
+
*/
|
|
475
|
+
declare class Voice {
|
|
476
|
+
private client;
|
|
477
|
+
constructor(client: HttpClient);
|
|
478
|
+
stt(params: SttParams, options?: RequestOptions): Promise<SttResult>;
|
|
479
|
+
}
|
|
480
|
+
|
|
288
481
|
declare const DEFAULT_BASE_URL = "https://curvet.ai/api/v1/playground";
|
|
289
482
|
interface CurvetOptions {
|
|
290
483
|
/** Your app key. Falls back to the CURVET_APP_KEY env var. */
|
|
291
484
|
appKey?: string;
|
|
292
|
-
/** Override the
|
|
485
|
+
/** Override the playground base URL (defaults to production). */
|
|
293
486
|
baseURL?: string;
|
|
294
487
|
/** Per-request timeout in ms (default 60000). */
|
|
295
488
|
timeout?: number;
|
|
@@ -317,9 +510,15 @@ declare class Curvet {
|
|
|
317
510
|
readonly chat: Chat;
|
|
318
511
|
readonly image: Images;
|
|
319
512
|
readonly video: Video;
|
|
513
|
+
readonly audio: Audio;
|
|
514
|
+
readonly threeD: ThreeD;
|
|
320
515
|
readonly jobs: Jobs;
|
|
321
516
|
readonly models: Models;
|
|
322
517
|
readonly balance: Balance;
|
|
518
|
+
readonly analytics: Analytics;
|
|
519
|
+
readonly workflows: Workflows;
|
|
520
|
+
readonly food: Food;
|
|
521
|
+
readonly voice: Voice;
|
|
323
522
|
constructor(options?: CurvetOptions);
|
|
324
523
|
}
|
|
325
524
|
|
|
@@ -376,5 +575,15 @@ declare class JobTimeoutError extends CurvetError {
|
|
|
376
575
|
readonly jobId: string;
|
|
377
576
|
constructor(message: string, jobId: string, opts?: CurvetErrorOptions);
|
|
378
577
|
}
|
|
578
|
+
/** An async workflow run finished with status "failed" (or "stopped"). */
|
|
579
|
+
declare class WorkflowRunFailedError extends CurvetError {
|
|
580
|
+
readonly runId: string;
|
|
581
|
+
constructor(message: string, runId: string, opts?: CurvetErrorOptions);
|
|
582
|
+
}
|
|
583
|
+
/** An async workflow run did not finish within the poll timeout. */
|
|
584
|
+
declare class WorkflowRunTimeoutError extends CurvetError {
|
|
585
|
+
readonly runId: string;
|
|
586
|
+
constructor(message: string, runId: string, opts?: CurvetErrorOptions);
|
|
587
|
+
}
|
|
379
588
|
|
|
380
|
-
export { APIError, AuthError, BadRequestError, Balance, type BalanceInfo, Chat, type ChatCreateParams, type ChatMessage, type ChatResponse, type ChatRole, ConnectionError, Curvet, CurvetError, type CurvetErrorOptions, type CurvetOptions, DEFAULT_BASE_URL, type FetchLike, type ImageGenerateParams, type ImageResponse, Images, InsufficientBalanceError, Job, type JobDefaults, JobFailedError, type JobStatus, JobTimeoutError, Jobs, type KnownModelId, type MediaJob, type MediaKind, type ModelId, type ModelInfo, type ModelType, Models, type ModelsListOptions, NotFoundError, PermissionError, type PollOptions, RateLimitError, type RateLimits, type RequestOptions, type Usage, Video, type VideoGenerateParams };
|
|
589
|
+
export { APIError, Analytics, type AnalyticsParams, type AnalyticsResult, Audio, type AudioGenerateParams, AuthError, BadRequestError, Balance, type BalanceInfo, Chat, type ChatCreateParams, type ChatMessage, type ChatResponse, type ChatRole, ConnectionError, Curvet, CurvetError, type CurvetErrorOptions, type CurvetOptions, DEFAULT_BASE_URL, type FetchLike, Food, type FoodItem, type ImageGenerateParams, type ImageResponse, Images, InsufficientBalanceError, Job, type JobDefaults, JobFailedError, type JobStatus, JobTimeoutError, Jobs, type KnownModelId, type MediaJob, type MediaKind, type MediaParamsBase, MediaResource, type ModelId, type ModelInfo, type ModelType, Models, type ModelsListOptions, NotFoundError, PermissionError, type PollOptions, RateLimitError, type RateLimits, type RequestOptions, type SttParams, type SttResult, ThreeD, type ThreeDGenerateParams, type Usage, Video, type VideoGenerateParams, Voice, type WorkflowPollOptions, type WorkflowRun, WorkflowRunFailedError, type WorkflowRunNode, type WorkflowRunParams, type WorkflowRunResult, type WorkflowRunStatus, WorkflowRunTimeoutError, WorkflowRuns, type WorkflowSubmitResult, Workflows };
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,18 @@ var JobTimeoutError = class extends CurvetError {
|
|
|
37
37
|
this.jobId = jobId;
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
|
+
var WorkflowRunFailedError = class extends CurvetError {
|
|
41
|
+
constructor(message, runId, opts = {}) {
|
|
42
|
+
super(message, opts);
|
|
43
|
+
this.runId = runId;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var WorkflowRunTimeoutError = class extends CurvetError {
|
|
47
|
+
constructor(message, runId, opts = {}) {
|
|
48
|
+
super(message, opts);
|
|
49
|
+
this.runId = runId;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
40
52
|
function errorFromResponse(status, body, requestId, headers) {
|
|
41
53
|
const b = body ?? {};
|
|
42
54
|
const message = typeof b.error === "string" ? b.error : `HTTP ${status}`;
|
|
@@ -125,8 +137,12 @@ var HttpClient = class {
|
|
|
125
137
|
};
|
|
126
138
|
let payload;
|
|
127
139
|
if (body !== void 0) {
|
|
128
|
-
|
|
129
|
-
|
|
140
|
+
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
141
|
+
payload = body;
|
|
142
|
+
} else {
|
|
143
|
+
headers["content-type"] = "application/json";
|
|
144
|
+
payload = JSON.stringify(body);
|
|
145
|
+
}
|
|
130
146
|
}
|
|
131
147
|
let attempt = 0;
|
|
132
148
|
for (; ; ) {
|
|
@@ -360,20 +376,17 @@ var Job = class {
|
|
|
360
376
|
}
|
|
361
377
|
};
|
|
362
378
|
|
|
363
|
-
// src/resources/
|
|
364
|
-
var
|
|
365
|
-
constructor(client, defaults, path
|
|
379
|
+
// src/resources/media.ts
|
|
380
|
+
var MediaResource = class {
|
|
381
|
+
constructor(client, defaults, path) {
|
|
366
382
|
this.client = client;
|
|
367
383
|
this.defaults = defaults;
|
|
368
384
|
this.path = path;
|
|
369
385
|
}
|
|
370
386
|
/**
|
|
371
|
-
* Submit
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
* The media POST long-polls server-side and can block well past a normal
|
|
375
|
-
* request timeout, so we default its timeout to the poll budget and disable
|
|
376
|
-
* auto-retry (a retried POST would enqueue a duplicate, double-charged job).
|
|
387
|
+
* Submit WITHOUT polling. The media POST long-polls server-side and can block
|
|
388
|
+
* well past a normal request timeout, so we default its timeout to the poll
|
|
389
|
+
* budget and disable auto-retry (a retried POST would enqueue a duplicate job).
|
|
377
390
|
*/
|
|
378
391
|
async submit(params, options) {
|
|
379
392
|
const reqOptions = {
|
|
@@ -389,10 +402,7 @@ var Video = class {
|
|
|
389
402
|
});
|
|
390
403
|
return normalizeMediaPost(body);
|
|
391
404
|
}
|
|
392
|
-
/**
|
|
393
|
-
* Submit and resolve to the finished media. Handles the 200-vs-202 split and
|
|
394
|
-
* polls `/jobs/:id` internally. Throws JobFailedError / JobTimeoutError.
|
|
395
|
-
*/
|
|
405
|
+
/** Submit and resolve to the finished media (auto-polls /jobs/:id). */
|
|
396
406
|
async generate(params, options) {
|
|
397
407
|
const submitted = await this.submit(params, options);
|
|
398
408
|
if (submitted.status === "completed" || submitted.status === "failed") {
|
|
@@ -413,6 +423,27 @@ var Video = class {
|
|
|
413
423
|
}
|
|
414
424
|
};
|
|
415
425
|
|
|
426
|
+
// src/resources/video.ts
|
|
427
|
+
var Video = class extends MediaResource {
|
|
428
|
+
constructor(client, defaults) {
|
|
429
|
+
super(client, defaults, "/video");
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
// src/resources/audio.ts
|
|
434
|
+
var Audio = class extends MediaResource {
|
|
435
|
+
constructor(client, defaults) {
|
|
436
|
+
super(client, defaults, "/audio");
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
// src/resources/threeD.ts
|
|
441
|
+
var ThreeD = class extends MediaResource {
|
|
442
|
+
constructor(client, defaults) {
|
|
443
|
+
super(client, defaults, "/3d");
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
|
|
416
447
|
// src/resources/models.ts
|
|
417
448
|
var Models = class {
|
|
418
449
|
constructor(client, cacheTtlMs = 6e4) {
|
|
@@ -465,6 +496,227 @@ var Balance = class {
|
|
|
465
496
|
}
|
|
466
497
|
};
|
|
467
498
|
|
|
499
|
+
// src/resources/analytics.ts
|
|
500
|
+
var Analytics = class {
|
|
501
|
+
constructor(client) {
|
|
502
|
+
this.client = client;
|
|
503
|
+
}
|
|
504
|
+
/** Usage analytics for the app, optionally bounded by a date range. */
|
|
505
|
+
async get(params = {}) {
|
|
506
|
+
const { startDate, endDate, ...options } = params;
|
|
507
|
+
const body = await this.client.request({
|
|
508
|
+
method: "GET",
|
|
509
|
+
path: "/analytics",
|
|
510
|
+
query: { startDate, endDate },
|
|
511
|
+
options
|
|
512
|
+
});
|
|
513
|
+
return body.analytics;
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
// src/resources/workflows.ts
|
|
518
|
+
function normalizeRun(body) {
|
|
519
|
+
const b = body ?? {};
|
|
520
|
+
return {
|
|
521
|
+
runId: b.runId,
|
|
522
|
+
status: b.status,
|
|
523
|
+
progress: b.progress,
|
|
524
|
+
totalNodes: b.totalNodes,
|
|
525
|
+
completedNodeCount: b.completedNodeCount,
|
|
526
|
+
currentNode: b.currentNode ?? null,
|
|
527
|
+
nodesExecuted: b.nodesExecuted,
|
|
528
|
+
result: b.result,
|
|
529
|
+
error: b.error ?? null,
|
|
530
|
+
startTime: b.startTime,
|
|
531
|
+
endTime: b.endTime,
|
|
532
|
+
raw: body
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
function buildBody(params, extra = {}) {
|
|
536
|
+
const hasFiles = params.files && Object.keys(params.files).length > 0;
|
|
537
|
+
if (hasFiles) {
|
|
538
|
+
const form = new FormData();
|
|
539
|
+
form.append("inputs", JSON.stringify(params.inputs ?? {}));
|
|
540
|
+
if (params.includeFullState !== void 0) {
|
|
541
|
+
form.append("includeFullState", String(params.includeFullState));
|
|
542
|
+
}
|
|
543
|
+
for (const [k, v] of Object.entries(extra)) form.append(k, String(v));
|
|
544
|
+
for (const [field, file] of Object.entries(params.files)) {
|
|
545
|
+
form.append(field, file);
|
|
546
|
+
}
|
|
547
|
+
return form;
|
|
548
|
+
}
|
|
549
|
+
return {
|
|
550
|
+
inputs: params.inputs ?? {},
|
|
551
|
+
includeFullState: params.includeFullState,
|
|
552
|
+
...extra
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
var WorkflowRuns = class {
|
|
556
|
+
constructor(client) {
|
|
557
|
+
this.client = client;
|
|
558
|
+
}
|
|
559
|
+
/** Fetch the current status of an async run once (no polling). */
|
|
560
|
+
async retrieve(runId, options) {
|
|
561
|
+
const body = await this.client.request({
|
|
562
|
+
method: "GET",
|
|
563
|
+
path: `/workflows/runs/${encodeURIComponent(runId)}`,
|
|
564
|
+
options
|
|
565
|
+
});
|
|
566
|
+
return normalizeRun(body);
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
var Workflows = class {
|
|
570
|
+
constructor(client) {
|
|
571
|
+
this.client = client;
|
|
572
|
+
this.runs = new WorkflowRuns(client);
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Execute a workflow synchronously (blocks until it finishes). Best for short
|
|
576
|
+
* workflows; for long ones (video/audio/3D nodes) prefer `runAndPoll`.
|
|
577
|
+
* Sends JSON, or multipart/form-data when file inputs are provided.
|
|
578
|
+
*/
|
|
579
|
+
async run(id, params = {}, options) {
|
|
580
|
+
const reqOptions = { ...options, maxRetries: options?.maxRetries ?? 0 };
|
|
581
|
+
return this.client.request({
|
|
582
|
+
method: "POST",
|
|
583
|
+
path: `/workflows/${encodeURIComponent(id)}/run`,
|
|
584
|
+
body: buildBody(params),
|
|
585
|
+
options: reqOptions
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Submit a workflow in async (pollable) mode — returns immediately with a
|
|
590
|
+
* runId. Poll `runs.retrieve(runId)` for status, or use `runAndPoll`.
|
|
591
|
+
*/
|
|
592
|
+
async submit(id, params = {}, options) {
|
|
593
|
+
const reqOptions = { ...options, maxRetries: options?.maxRetries ?? 0 };
|
|
594
|
+
const res = await this.client.request({
|
|
595
|
+
method: "POST",
|
|
596
|
+
path: `/workflows/${encodeURIComponent(id)}/run`,
|
|
597
|
+
body: buildBody(params, { async: true }),
|
|
598
|
+
options: reqOptions
|
|
599
|
+
});
|
|
600
|
+
return { runId: res?.runId, status: res?.status ?? "running", raw: res };
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Submit and poll to completion. Resolves with the completed run (including
|
|
604
|
+
* `result`), reporting progress via `onProgress`. Throws WorkflowRunFailedError
|
|
605
|
+
* on failure, WorkflowRunTimeoutError on timeout.
|
|
606
|
+
*/
|
|
607
|
+
async runAndPoll(id, params = {}, opts = {}) {
|
|
608
|
+
const submitted = await this.submit(id, params, opts);
|
|
609
|
+
if (!submitted.runId) {
|
|
610
|
+
throw new CurvetError("Workflow submit did not return a runId", {
|
|
611
|
+
raw: submitted.raw
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
const intervalMs = opts.pollIntervalMs ?? 2500;
|
|
615
|
+
const timeoutMs = opts.pollTimeoutMs ?? 3e5;
|
|
616
|
+
let run;
|
|
617
|
+
try {
|
|
618
|
+
run = await pollUntil(
|
|
619
|
+
() => this.runs.retrieve(submitted.runId, { signal: opts.signal }),
|
|
620
|
+
{
|
|
621
|
+
intervalMs,
|
|
622
|
+
timeoutMs,
|
|
623
|
+
signal: opts.signal,
|
|
624
|
+
isTerminal: (r) => r.status === "completed" || r.status === "failed" || r.status === "stopped",
|
|
625
|
+
onTick: (r) => opts.onProgress?.(r)
|
|
626
|
+
}
|
|
627
|
+
);
|
|
628
|
+
} catch (e) {
|
|
629
|
+
if (e instanceof PollTimeoutError) {
|
|
630
|
+
throw new WorkflowRunTimeoutError(
|
|
631
|
+
`Workflow run ${submitted.runId} did not finish within ${timeoutMs}ms`,
|
|
632
|
+
submitted.runId
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
throw e;
|
|
636
|
+
}
|
|
637
|
+
if (run.status === "failed" || run.status === "stopped") {
|
|
638
|
+
throw new WorkflowRunFailedError(
|
|
639
|
+
run.error || `Workflow run ${submitted.runId} ${run.status}`,
|
|
640
|
+
submitted.runId,
|
|
641
|
+
{ raw: run.raw }
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
return run;
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
// src/resources/food.ts
|
|
649
|
+
var Food = class {
|
|
650
|
+
constructor(client) {
|
|
651
|
+
this.client = client;
|
|
652
|
+
}
|
|
653
|
+
/** List dishes (default limit 20). */
|
|
654
|
+
async list(opts) {
|
|
655
|
+
const { limit, ...options } = opts ?? {};
|
|
656
|
+
const body = await this.client.request({
|
|
657
|
+
method: "GET",
|
|
658
|
+
path: "/food",
|
|
659
|
+
query: { limit },
|
|
660
|
+
options
|
|
661
|
+
});
|
|
662
|
+
return body.data;
|
|
663
|
+
}
|
|
664
|
+
/** Full-text search for dishes. */
|
|
665
|
+
async search(query, opts) {
|
|
666
|
+
const { limit, ...options } = opts ?? {};
|
|
667
|
+
const body = await this.client.request({
|
|
668
|
+
method: "GET",
|
|
669
|
+
path: "/food/search",
|
|
670
|
+
query: { q: query, limit },
|
|
671
|
+
options
|
|
672
|
+
});
|
|
673
|
+
return body.data;
|
|
674
|
+
}
|
|
675
|
+
/** Natural-language dish recommendations. */
|
|
676
|
+
async recommendations(prompt, options) {
|
|
677
|
+
const body = await this.client.request({
|
|
678
|
+
method: "POST",
|
|
679
|
+
path: "/food/recommendations",
|
|
680
|
+
body: { prompt },
|
|
681
|
+
options
|
|
682
|
+
});
|
|
683
|
+
return body.data;
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
// src/resources/voice.ts
|
|
688
|
+
var Voice = class {
|
|
689
|
+
constructor(client) {
|
|
690
|
+
this.client = client;
|
|
691
|
+
}
|
|
692
|
+
async stt(params, options) {
|
|
693
|
+
const form = new FormData();
|
|
694
|
+
form.append("audio", toBlob(params.audio), params.filename ?? "audio");
|
|
695
|
+
if (params.provider) form.append("provider", params.provider);
|
|
696
|
+
if (params.model) form.append("model", params.model);
|
|
697
|
+
if (params.prompt) form.append("prompt", params.prompt);
|
|
698
|
+
if (params.languageCode) form.append("languageCode", params.languageCode);
|
|
699
|
+
if (params.allowFallback !== void 0) {
|
|
700
|
+
form.append("allowFallback", String(params.allowFallback));
|
|
701
|
+
}
|
|
702
|
+
const reqOptions = {
|
|
703
|
+
...options,
|
|
704
|
+
timeout: options?.timeout ?? 12e4,
|
|
705
|
+
maxRetries: options?.maxRetries ?? 0
|
|
706
|
+
};
|
|
707
|
+
return this.client.request({
|
|
708
|
+
method: "POST",
|
|
709
|
+
path: "/voice/stt/public",
|
|
710
|
+
body: form,
|
|
711
|
+
options: reqOptions
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
function toBlob(audio) {
|
|
716
|
+
if (typeof Blob !== "undefined" && audio instanceof Blob) return audio;
|
|
717
|
+
return new Blob([audio]);
|
|
718
|
+
}
|
|
719
|
+
|
|
468
720
|
// src/client.ts
|
|
469
721
|
var DEFAULT_BASE_URL = "https://curvet.ai/api/v1/playground";
|
|
470
722
|
var Curvet = class {
|
|
@@ -481,13 +733,16 @@ var Curvet = class {
|
|
|
481
733
|
"No fetch implementation available. Use Node 18+ or pass { fetch }."
|
|
482
734
|
);
|
|
483
735
|
}
|
|
484
|
-
const
|
|
736
|
+
const playgroundBase = options.baseURL ?? DEFAULT_BASE_URL;
|
|
737
|
+
const v1Base = playgroundBase.replace(/\/playground\/?$/, "");
|
|
738
|
+
const shared = {
|
|
485
739
|
appKey,
|
|
486
|
-
baseURL: options.baseURL ?? DEFAULT_BASE_URL,
|
|
487
740
|
timeout: options.timeout ?? 6e4,
|
|
488
741
|
maxRetries: options.maxRetries ?? 2,
|
|
489
742
|
fetch: fetchImpl
|
|
490
|
-
}
|
|
743
|
+
};
|
|
744
|
+
const client = new HttpClient({ ...shared, baseURL: playgroundBase });
|
|
745
|
+
const v1Client = new HttpClient({ ...shared, baseURL: v1Base });
|
|
491
746
|
const jobDefaults = {
|
|
492
747
|
pollIntervalMs: options.defaultPollIntervalMs ?? 2500,
|
|
493
748
|
pollTimeoutMs: options.defaultPollTimeoutMs ?? 18e4
|
|
@@ -496,8 +751,14 @@ var Curvet = class {
|
|
|
496
751
|
this.image = new Images(client);
|
|
497
752
|
this.jobs = new Jobs(client, jobDefaults);
|
|
498
753
|
this.video = new Video(client, jobDefaults);
|
|
754
|
+
this.audio = new Audio(client, jobDefaults);
|
|
755
|
+
this.threeD = new ThreeD(client, jobDefaults);
|
|
499
756
|
this.models = new Models(client);
|
|
500
757
|
this.balance = new Balance(client);
|
|
758
|
+
this.analytics = new Analytics(client);
|
|
759
|
+
this.workflows = new Workflows(client);
|
|
760
|
+
this.food = new Food(v1Client);
|
|
761
|
+
this.voice = new Voice(v1Client);
|
|
501
762
|
}
|
|
502
763
|
};
|
|
503
764
|
function envKey() {
|
|
@@ -509,6 +770,8 @@ function defaultFetch() {
|
|
|
509
770
|
}
|
|
510
771
|
export {
|
|
511
772
|
APIError,
|
|
773
|
+
Analytics,
|
|
774
|
+
Audio,
|
|
512
775
|
AuthError,
|
|
513
776
|
BadRequestError,
|
|
514
777
|
Balance,
|
|
@@ -517,16 +780,24 @@ export {
|
|
|
517
780
|
Curvet,
|
|
518
781
|
CurvetError,
|
|
519
782
|
DEFAULT_BASE_URL,
|
|
783
|
+
Food,
|
|
520
784
|
Images,
|
|
521
785
|
InsufficientBalanceError,
|
|
522
786
|
Job,
|
|
523
787
|
JobFailedError,
|
|
524
788
|
JobTimeoutError,
|
|
525
789
|
Jobs,
|
|
790
|
+
MediaResource,
|
|
526
791
|
Models,
|
|
527
792
|
NotFoundError,
|
|
528
793
|
PermissionError,
|
|
529
794
|
RateLimitError,
|
|
530
|
-
|
|
795
|
+
ThreeD,
|
|
796
|
+
Video,
|
|
797
|
+
Voice,
|
|
798
|
+
WorkflowRunFailedError,
|
|
799
|
+
WorkflowRunTimeoutError,
|
|
800
|
+
WorkflowRuns,
|
|
801
|
+
Workflows
|
|
531
802
|
};
|
|
532
803
|
//# sourceMappingURL=index.js.map
|