@curvet/sdk 0.1.0 → 0.2.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.
- package/README.md +53 -1
- package/dist/index.cjs +188 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +159 -24
- package/dist/index.d.ts +159 -24
- package/dist/index.js +180 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -83,11 +83,41 @@ if (job.status !== "completed") {
|
|
|
83
83
|
const status = await curvet.jobs.retrieve(job.jobId!);
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
###
|
|
86
|
+
### Audio & 3D (async, same as video)
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const audio = await curvet.audio.generate({ model: "fish-audio", prompt: "Hello there" });
|
|
90
|
+
const mesh = await curvet.threeD.generate({ model: "meshy-3d", prompt: "a ceramic mug" });
|
|
91
|
+
console.log(audio.mediaUrl, mesh.mediaUrl);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Models, balance & analytics
|
|
87
95
|
|
|
88
96
|
```ts
|
|
89
97
|
const chatModels = await curvet.models.list({ type: "chat" });
|
|
90
98
|
const balance = await curvet.balance.get();
|
|
99
|
+
const analytics = await curvet.analytics.get({ startDate: "2026-01-01", endDate: "2026-02-01" });
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Workflows
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
// JSON inputs:
|
|
106
|
+
const out = await curvet.workflows.run("workflowId", { inputs: { topic: "ai" } });
|
|
107
|
+
|
|
108
|
+
// With file inputs (multipart, handled for you):
|
|
109
|
+
await curvet.workflows.run("workflowId", {
|
|
110
|
+
inputs: { caption: "hello" },
|
|
111
|
+
files: { image: new Blob([bytes], { type: "image/png" }) },
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Food & speech-to-text
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
const dishes = await curvet.food.search("paneer", { limit: 5 });
|
|
119
|
+
const stt = await curvet.voice.stt({ audio: audioBytes, filename: "clip.wav" });
|
|
120
|
+
console.log(stt.text);
|
|
91
121
|
```
|
|
92
122
|
|
|
93
123
|
## Errors
|
|
@@ -155,6 +185,28 @@ npm run build # ESM + CJS + d.ts via tsup
|
|
|
155
185
|
CURVET_TEST_APP_KEY=cvt_app_xxx npm test
|
|
156
186
|
```
|
|
157
187
|
|
|
188
|
+
## Releasing
|
|
189
|
+
|
|
190
|
+
Publishing happens locally with the release script — no npm token, no CI.
|
|
191
|
+
`npm publish` prompts for your passkey/2FA, which you approve in the browser.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
./scripts/release.sh # publish the current package.json version
|
|
195
|
+
./scripts/release.sh patch # bump patch, then publish (0.2.0 -> 0.2.1)
|
|
196
|
+
./scripts/release.sh minor # bump minor, then publish
|
|
197
|
+
./scripts/release.sh major # bump major, then publish
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The script validates (typecheck + tests + build) before bumping, tags the
|
|
201
|
+
version, publishes (you approve the passkey prompt), then pushes the tag and
|
|
202
|
+
commit to GitHub. The order is deliberate — if the publish is cancelled,
|
|
203
|
+
nothing is pushed; just re-run `npm publish && git push --follow-tags origin main`
|
|
204
|
+
to finish.
|
|
205
|
+
|
|
206
|
+
> A tokenless CI alternative using npm Trusted Publishing (OIDC) is also included
|
|
207
|
+
> at [`.github/workflows/publish.yml`](.github/workflows/publish.yml) for when
|
|
208
|
+
> GitHub Actions is available.
|
|
209
|
+
|
|
158
210
|
## License
|
|
159
211
|
|
|
160
212
|
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
APIError: () => APIError,
|
|
24
|
+
Analytics: () => Analytics,
|
|
25
|
+
Audio: () => Audio,
|
|
24
26
|
AuthError: () => AuthError,
|
|
25
27
|
BadRequestError: () => BadRequestError,
|
|
26
28
|
Balance: () => Balance,
|
|
@@ -29,17 +31,22 @@ __export(index_exports, {
|
|
|
29
31
|
Curvet: () => Curvet,
|
|
30
32
|
CurvetError: () => CurvetError,
|
|
31
33
|
DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
|
|
34
|
+
Food: () => Food,
|
|
32
35
|
Images: () => Images,
|
|
33
36
|
InsufficientBalanceError: () => InsufficientBalanceError,
|
|
34
37
|
Job: () => Job,
|
|
35
38
|
JobFailedError: () => JobFailedError,
|
|
36
39
|
JobTimeoutError: () => JobTimeoutError,
|
|
37
40
|
Jobs: () => Jobs,
|
|
41
|
+
MediaResource: () => MediaResource,
|
|
38
42
|
Models: () => Models,
|
|
39
43
|
NotFoundError: () => NotFoundError,
|
|
40
44
|
PermissionError: () => PermissionError,
|
|
41
45
|
RateLimitError: () => RateLimitError,
|
|
42
|
-
|
|
46
|
+
ThreeD: () => ThreeD,
|
|
47
|
+
Video: () => Video,
|
|
48
|
+
Voice: () => Voice,
|
|
49
|
+
Workflows: () => Workflows
|
|
43
50
|
});
|
|
44
51
|
module.exports = __toCommonJS(index_exports);
|
|
45
52
|
|
|
@@ -170,8 +177,12 @@ var HttpClient = class {
|
|
|
170
177
|
};
|
|
171
178
|
let payload;
|
|
172
179
|
if (body !== void 0) {
|
|
173
|
-
|
|
174
|
-
|
|
180
|
+
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
181
|
+
payload = body;
|
|
182
|
+
} else {
|
|
183
|
+
headers["content-type"] = "application/json";
|
|
184
|
+
payload = JSON.stringify(body);
|
|
185
|
+
}
|
|
175
186
|
}
|
|
176
187
|
let attempt = 0;
|
|
177
188
|
for (; ; ) {
|
|
@@ -405,20 +416,17 @@ var Job = class {
|
|
|
405
416
|
}
|
|
406
417
|
};
|
|
407
418
|
|
|
408
|
-
// src/resources/
|
|
409
|
-
var
|
|
410
|
-
constructor(client, defaults, path
|
|
419
|
+
// src/resources/media.ts
|
|
420
|
+
var MediaResource = class {
|
|
421
|
+
constructor(client, defaults, path) {
|
|
411
422
|
this.client = client;
|
|
412
423
|
this.defaults = defaults;
|
|
413
424
|
this.path = path;
|
|
414
425
|
}
|
|
415
426
|
/**
|
|
416
|
-
* Submit
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
* The media POST long-polls server-side and can block well past a normal
|
|
420
|
-
* request timeout, so we default its timeout to the poll budget and disable
|
|
421
|
-
* auto-retry (a retried POST would enqueue a duplicate, double-charged job).
|
|
427
|
+
* Submit WITHOUT polling. The media POST long-polls server-side and can block
|
|
428
|
+
* well past a normal request timeout, so we default its timeout to the poll
|
|
429
|
+
* budget and disable auto-retry (a retried POST would enqueue a duplicate job).
|
|
422
430
|
*/
|
|
423
431
|
async submit(params, options) {
|
|
424
432
|
const reqOptions = {
|
|
@@ -434,10 +442,7 @@ var Video = class {
|
|
|
434
442
|
});
|
|
435
443
|
return normalizeMediaPost(body);
|
|
436
444
|
}
|
|
437
|
-
/**
|
|
438
|
-
* Submit and resolve to the finished media. Handles the 200-vs-202 split and
|
|
439
|
-
* polls `/jobs/:id` internally. Throws JobFailedError / JobTimeoutError.
|
|
440
|
-
*/
|
|
445
|
+
/** Submit and resolve to the finished media (auto-polls /jobs/:id). */
|
|
441
446
|
async generate(params, options) {
|
|
442
447
|
const submitted = await this.submit(params, options);
|
|
443
448
|
if (submitted.status === "completed" || submitted.status === "failed") {
|
|
@@ -458,6 +463,27 @@ var Video = class {
|
|
|
458
463
|
}
|
|
459
464
|
};
|
|
460
465
|
|
|
466
|
+
// src/resources/video.ts
|
|
467
|
+
var Video = class extends MediaResource {
|
|
468
|
+
constructor(client, defaults) {
|
|
469
|
+
super(client, defaults, "/video");
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
// src/resources/audio.ts
|
|
474
|
+
var Audio = class extends MediaResource {
|
|
475
|
+
constructor(client, defaults) {
|
|
476
|
+
super(client, defaults, "/audio");
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
// src/resources/threeD.ts
|
|
481
|
+
var ThreeD = class extends MediaResource {
|
|
482
|
+
constructor(client, defaults) {
|
|
483
|
+
super(client, defaults, "/3d");
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
|
|
461
487
|
// src/resources/models.ts
|
|
462
488
|
var Models = class {
|
|
463
489
|
constructor(client, cacheTtlMs = 6e4) {
|
|
@@ -510,6 +536,132 @@ var Balance = class {
|
|
|
510
536
|
}
|
|
511
537
|
};
|
|
512
538
|
|
|
539
|
+
// src/resources/analytics.ts
|
|
540
|
+
var Analytics = class {
|
|
541
|
+
constructor(client) {
|
|
542
|
+
this.client = client;
|
|
543
|
+
}
|
|
544
|
+
/** Usage analytics for the app, optionally bounded by a date range. */
|
|
545
|
+
async get(params = {}) {
|
|
546
|
+
const { startDate, endDate, ...options } = params;
|
|
547
|
+
const body = await this.client.request({
|
|
548
|
+
method: "GET",
|
|
549
|
+
path: "/analytics",
|
|
550
|
+
query: { startDate, endDate },
|
|
551
|
+
options
|
|
552
|
+
});
|
|
553
|
+
return body.analytics;
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
// src/resources/workflows.ts
|
|
558
|
+
var Workflows = class {
|
|
559
|
+
constructor(client) {
|
|
560
|
+
this.client = client;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Execute a visual-builder workflow by id. Sends JSON when there are no file
|
|
564
|
+
* inputs, multipart/form-data when files are provided. Not auto-retried (a
|
|
565
|
+
* workflow run executes and may consume credits).
|
|
566
|
+
*/
|
|
567
|
+
async run(id, params = {}, options) {
|
|
568
|
+
const reqOptions = { ...options, maxRetries: options?.maxRetries ?? 0 };
|
|
569
|
+
const hasFiles = params.files && Object.keys(params.files).length > 0;
|
|
570
|
+
let body;
|
|
571
|
+
if (hasFiles) {
|
|
572
|
+
const form = new FormData();
|
|
573
|
+
form.append("inputs", JSON.stringify(params.inputs ?? {}));
|
|
574
|
+
if (params.includeFullState !== void 0) {
|
|
575
|
+
form.append("includeFullState", String(params.includeFullState));
|
|
576
|
+
}
|
|
577
|
+
for (const [field, file] of Object.entries(params.files)) {
|
|
578
|
+
form.append(field, file);
|
|
579
|
+
}
|
|
580
|
+
body = form;
|
|
581
|
+
} else {
|
|
582
|
+
body = { inputs: params.inputs ?? {}, includeFullState: params.includeFullState };
|
|
583
|
+
}
|
|
584
|
+
return this.client.request({
|
|
585
|
+
method: "POST",
|
|
586
|
+
path: `/workflows/${encodeURIComponent(id)}/run`,
|
|
587
|
+
body,
|
|
588
|
+
options: reqOptions
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
// src/resources/food.ts
|
|
594
|
+
var Food = class {
|
|
595
|
+
constructor(client) {
|
|
596
|
+
this.client = client;
|
|
597
|
+
}
|
|
598
|
+
/** List dishes (default limit 20). */
|
|
599
|
+
async list(opts) {
|
|
600
|
+
const { limit, ...options } = opts ?? {};
|
|
601
|
+
const body = await this.client.request({
|
|
602
|
+
method: "GET",
|
|
603
|
+
path: "/food",
|
|
604
|
+
query: { limit },
|
|
605
|
+
options
|
|
606
|
+
});
|
|
607
|
+
return body.data;
|
|
608
|
+
}
|
|
609
|
+
/** Full-text search for dishes. */
|
|
610
|
+
async search(query, opts) {
|
|
611
|
+
const { limit, ...options } = opts ?? {};
|
|
612
|
+
const body = await this.client.request({
|
|
613
|
+
method: "GET",
|
|
614
|
+
path: "/food/search",
|
|
615
|
+
query: { q: query, limit },
|
|
616
|
+
options
|
|
617
|
+
});
|
|
618
|
+
return body.data;
|
|
619
|
+
}
|
|
620
|
+
/** Natural-language dish recommendations. */
|
|
621
|
+
async recommendations(prompt, options) {
|
|
622
|
+
const body = await this.client.request({
|
|
623
|
+
method: "POST",
|
|
624
|
+
path: "/food/recommendations",
|
|
625
|
+
body: { prompt },
|
|
626
|
+
options
|
|
627
|
+
});
|
|
628
|
+
return body.data;
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
// src/resources/voice.ts
|
|
633
|
+
var Voice = class {
|
|
634
|
+
constructor(client) {
|
|
635
|
+
this.client = client;
|
|
636
|
+
}
|
|
637
|
+
async stt(params, options) {
|
|
638
|
+
const form = new FormData();
|
|
639
|
+
form.append("audio", toBlob(params.audio), params.filename ?? "audio");
|
|
640
|
+
if (params.provider) form.append("provider", params.provider);
|
|
641
|
+
if (params.model) form.append("model", params.model);
|
|
642
|
+
if (params.prompt) form.append("prompt", params.prompt);
|
|
643
|
+
if (params.languageCode) form.append("languageCode", params.languageCode);
|
|
644
|
+
if (params.allowFallback !== void 0) {
|
|
645
|
+
form.append("allowFallback", String(params.allowFallback));
|
|
646
|
+
}
|
|
647
|
+
const reqOptions = {
|
|
648
|
+
...options,
|
|
649
|
+
timeout: options?.timeout ?? 12e4,
|
|
650
|
+
maxRetries: options?.maxRetries ?? 0
|
|
651
|
+
};
|
|
652
|
+
return this.client.request({
|
|
653
|
+
method: "POST",
|
|
654
|
+
path: "/voice/stt/public",
|
|
655
|
+
body: form,
|
|
656
|
+
options: reqOptions
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
function toBlob(audio) {
|
|
661
|
+
if (typeof Blob !== "undefined" && audio instanceof Blob) return audio;
|
|
662
|
+
return new Blob([audio]);
|
|
663
|
+
}
|
|
664
|
+
|
|
513
665
|
// src/client.ts
|
|
514
666
|
var DEFAULT_BASE_URL = "https://curvet.ai/api/v1/playground";
|
|
515
667
|
var Curvet = class {
|
|
@@ -526,13 +678,16 @@ var Curvet = class {
|
|
|
526
678
|
"No fetch implementation available. Use Node 18+ or pass { fetch }."
|
|
527
679
|
);
|
|
528
680
|
}
|
|
529
|
-
const
|
|
681
|
+
const playgroundBase = options.baseURL ?? DEFAULT_BASE_URL;
|
|
682
|
+
const v1Base = playgroundBase.replace(/\/playground\/?$/, "");
|
|
683
|
+
const shared = {
|
|
530
684
|
appKey,
|
|
531
|
-
baseURL: options.baseURL ?? DEFAULT_BASE_URL,
|
|
532
685
|
timeout: options.timeout ?? 6e4,
|
|
533
686
|
maxRetries: options.maxRetries ?? 2,
|
|
534
687
|
fetch: fetchImpl
|
|
535
|
-
}
|
|
688
|
+
};
|
|
689
|
+
const client = new HttpClient({ ...shared, baseURL: playgroundBase });
|
|
690
|
+
const v1Client = new HttpClient({ ...shared, baseURL: v1Base });
|
|
536
691
|
const jobDefaults = {
|
|
537
692
|
pollIntervalMs: options.defaultPollIntervalMs ?? 2500,
|
|
538
693
|
pollTimeoutMs: options.defaultPollTimeoutMs ?? 18e4
|
|
@@ -541,8 +696,14 @@ var Curvet = class {
|
|
|
541
696
|
this.image = new Images(client);
|
|
542
697
|
this.jobs = new Jobs(client, jobDefaults);
|
|
543
698
|
this.video = new Video(client, jobDefaults);
|
|
699
|
+
this.audio = new Audio(client, jobDefaults);
|
|
700
|
+
this.threeD = new ThreeD(client, jobDefaults);
|
|
544
701
|
this.models = new Models(client);
|
|
545
702
|
this.balance = new Balance(client);
|
|
703
|
+
this.analytics = new Analytics(client);
|
|
704
|
+
this.workflows = new Workflows(client);
|
|
705
|
+
this.food = new Food(v1Client);
|
|
706
|
+
this.voice = new Voice(v1Client);
|
|
546
707
|
}
|
|
547
708
|
};
|
|
548
709
|
function envKey() {
|
|
@@ -555,6 +716,8 @@ function defaultFetch() {
|
|
|
555
716
|
// Annotate the CommonJS export names for ESM import in node:
|
|
556
717
|
0 && (module.exports = {
|
|
557
718
|
APIError,
|
|
719
|
+
Analytics,
|
|
720
|
+
Audio,
|
|
558
721
|
AuthError,
|
|
559
722
|
BadRequestError,
|
|
560
723
|
Balance,
|
|
@@ -563,16 +726,21 @@ function defaultFetch() {
|
|
|
563
726
|
Curvet,
|
|
564
727
|
CurvetError,
|
|
565
728
|
DEFAULT_BASE_URL,
|
|
729
|
+
Food,
|
|
566
730
|
Images,
|
|
567
731
|
InsufficientBalanceError,
|
|
568
732
|
Job,
|
|
569
733
|
JobFailedError,
|
|
570
734
|
JobTimeoutError,
|
|
571
735
|
Jobs,
|
|
736
|
+
MediaResource,
|
|
572
737
|
Models,
|
|
573
738
|
NotFoundError,
|
|
574
739
|
PermissionError,
|
|
575
740
|
RateLimitError,
|
|
576
|
-
|
|
741
|
+
ThreeD,
|
|
742
|
+
Video,
|
|
743
|
+
Voice,
|
|
744
|
+
Workflows
|
|
577
745
|
});
|
|
578
746
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/retry.ts","../src/core/http.ts","../src/resources/chat.ts","../src/resources/image.ts","../src/core/normalize.ts","../src/core/poll.ts","../src/resources/jobs.ts","../src/resources/video.ts","../src/resources/models.ts","../src/resources/balance.ts","../src/client.ts"],"sourcesContent":["export { Curvet, DEFAULT_BASE_URL } from \"./client\";\nexport type { CurvetOptions } from \"./client\";\n\n// Errors\nexport {\n CurvetError,\n AuthError,\n PermissionError,\n BadRequestError,\n NotFoundError,\n APIError,\n ConnectionError,\n InsufficientBalanceError,\n RateLimitError,\n JobFailedError,\n JobTimeoutError,\n} from \"./core/errors\";\nexport type { CurvetErrorOptions } from \"./core/errors\";\n\n// Resources\nexport { Chat } from \"./resources/chat\";\nexport { Images } from \"./resources/image\";\nexport { Video } from \"./resources/video\";\nexport { Jobs, Job } from \"./resources/jobs\";\nexport type { JobDefaults } from \"./resources/jobs\";\nexport { Models } from \"./resources/models\";\nexport type { ModelsListOptions } from \"./resources/models\";\nexport { Balance } from \"./resources/balance\";\nexport type { BalanceInfo } from \"./resources/balance\";\n\n// Types\nexport type { Usage, RequestOptions, FetchLike } from \"./types/common\";\nexport type { ChatRole, ChatMessage, ChatCreateParams, ChatResponse } from \"./types/chat\";\nexport type { ImageGenerateParams, ImageResponse } from \"./types/image\";\nexport type {\n JobStatus,\n MediaKind,\n MediaJob,\n VideoGenerateParams,\n PollOptions,\n} from \"./types/job\";\nexport type { ModelType, ModelInfo, RateLimits, KnownModelId, ModelId } from \"./types/models\";\n","export interface CurvetErrorOptions {\n status?: number;\n requestId?: string;\n raw?: unknown;\n}\n\n/** Base class for every error thrown by the SDK. */\nexport class CurvetError extends Error {\n readonly status?: number;\n readonly requestId?: string;\n readonly raw?: unknown;\n\n constructor(message: string, opts: CurvetErrorOptions = {}) {\n super(message);\n this.name = new.target.name;\n this.status = opts.status;\n this.requestId = opts.requestId;\n this.raw = opts.raw;\n // Restore prototype chain so `instanceof` works after transpilation.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** 401 — missing or invalid `x-app-key`. */\nexport class AuthError extends CurvetError {}\n/** 403 — app not active, playground not enabled, or model/category not allowed. */\nexport class PermissionError extends CurvetError {}\n/** 400 — invalid/unknown model or malformed payload. */\nexport class BadRequestError extends CurvetError {}\n/** 404 — job or workflow not found. */\nexport class NotFoundError extends CurvetError {}\n/** 5xx — upstream/server error (retried automatically). */\nexport class APIError extends CurvetError {}\n/** Network failure or timeout before a response was received. */\nexport class ConnectionError extends CurvetError {}\n\n/** 402 — not enough credits to complete the request. */\nexport class InsufficientBalanceError extends CurvetError {\n required?: number;\n available?: number;\n}\n\n/** 429 — hourly request limit or daily cost cap exceeded. */\nexport class RateLimitError extends CurvetError {\n kind?: \"rate\" | \"cost\";\n limit?: number;\n used?: number;\n resetsAt?: Date;\n retryAfterMs?: number;\n}\n\n/** An async media job finished with status \"failed\". */\nexport class JobFailedError extends CurvetError {\n readonly jobId: string;\n constructor(message: string, jobId: string, opts: CurvetErrorOptions = {}) {\n super(message, opts);\n this.jobId = jobId;\n }\n}\n\n/** An async media job did not finish within the poll timeout. */\nexport class JobTimeoutError extends CurvetError {\n readonly jobId: string;\n constructor(message: string, jobId: string, opts: CurvetErrorOptions = {}) {\n super(message, opts);\n this.jobId = jobId;\n }\n}\n\ninterface HeaderBag {\n get(name: string): string | null;\n}\n\n/** Map an HTTP status + JSON error body to the right typed error. */\nexport function errorFromResponse(\n status: number,\n body: unknown,\n requestId?: string,\n headers?: HeaderBag,\n): CurvetError {\n const b = (body ?? {}) as Record<string, any>;\n const message =\n typeof b.error === \"string\" ? b.error : `HTTP ${status}`;\n const base: CurvetErrorOptions = { status, requestId, raw: body };\n\n switch (status) {\n case 400:\n return new BadRequestError(message, base);\n case 401:\n return new AuthError(message, base);\n case 402: {\n const e = new InsufficientBalanceError(message, base);\n e.required = b.required;\n e.available = b.available;\n return e;\n }\n case 403:\n return new PermissionError(message, base);\n case 404:\n return new NotFoundError(message, base);\n case 429: {\n const e = new RateLimitError(message, base);\n const info = b.rateLimitInfo ?? b.costCapInfo;\n e.kind = b.costCapInfo ? \"cost\" : \"rate\";\n if (info) {\n e.limit = info.limit;\n e.used = info.used;\n if (info.resetsAt) e.resetsAt = new Date(info.resetsAt);\n }\n const retryAfter = headers?.get?.(\"retry-after\");\n if (info?.resetsIn != null) e.retryAfterMs = Number(info.resetsIn) * 1000;\n else if (retryAfter) e.retryAfterMs = Number(retryAfter) * 1000;\n else if (e.resetsAt) e.retryAfterMs = Math.max(0, e.resetsAt.getTime() - Date.now());\n return e;\n }\n default:\n return new APIError(message, base);\n }\n}\n","/** Exponential backoff with full jitter. */\nexport function fullJitterBackoff(attempt: number, baseMs = 500, capMs = 8000): number {\n const exp = Math.min(capMs, baseMs * 2 ** attempt);\n return Math.random() * exp;\n}\n\n/** Sleep that rejects with an AbortError if the signal fires. */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) return reject(abortError());\n const onAbort = () => {\n cleanup();\n reject(abortError());\n };\n const cleanup = () => {\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", onAbort);\n };\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nexport function abortError(): Error {\n const e = new Error(\"The operation was aborted.\");\n e.name = \"AbortError\";\n return e;\n}\n\n/** Only 429 and 5xx are safe to retry. */\nexport function isRetryableStatus(status: number): boolean {\n return status === 429 || status >= 500;\n}\n","import type { FetchLike, RequestOptions } from \"../types/common\";\nimport {\n CurvetError,\n ConnectionError,\n RateLimitError,\n errorFromResponse,\n} from \"./errors\";\nimport { fullJitterBackoff, isRetryableStatus, sleep } from \"./retry\";\n\nexport interface HttpClientOptions {\n appKey: string;\n baseURL: string;\n timeout: number;\n maxRetries: number;\n fetch: FetchLike;\n}\n\nexport interface RequestArgs {\n method: string;\n path: string;\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n options?: RequestOptions;\n}\n\n/**\n * The single place that knows about fetch, headers, base URL, error mapping,\n * and retries. Resources call `request()`; everything else stays mockable.\n */\nexport class HttpClient {\n constructor(private opts: HttpClientOptions) {}\n\n async request<T = any>(args: RequestArgs): Promise<T> {\n const { method, path, body, query, options } = args;\n const url = this.buildUrl(path, query);\n const maxRetries = options?.maxRetries ?? this.opts.maxRetries;\n const timeout = options?.timeout ?? this.opts.timeout;\n\n const headers: Record<string, string> = {\n \"x-app-key\": this.opts.appKey,\n accept: \"application/json\",\n ...(options?.headers ?? {}),\n };\n let payload: string | undefined;\n if (body !== undefined) {\n headers[\"content-type\"] = \"application/json\";\n payload = JSON.stringify(body);\n }\n\n let attempt = 0;\n for (;;) {\n const { signal, done } = this.makeSignal(timeout, options?.signal);\n try {\n const res = await this.opts.fetch(url, { method, headers, body: payload, signal });\n const text = await res.text();\n const parsed = text ? safeJson(text) : undefined;\n\n if (res.ok) return parsed as T;\n\n const requestId =\n res.headers.get(\"x-request-id\") ??\n (parsed as any)?.metadata?.requestId ??\n undefined;\n const err = errorFromResponse(res.status, parsed, requestId, res.headers);\n\n if (isRetryableStatus(res.status) && attempt < maxRetries) {\n await this.backoff(err, attempt, options?.signal);\n attempt++;\n continue;\n }\n throw err;\n } catch (e: any) {\n if (e instanceof CurvetError) throw e;\n // AbortError: distinguish user-abort (rethrow) from our timeout (retry/ConnectionError).\n if (e?.name === \"AbortError\") {\n if (options?.signal?.aborted) throw e;\n if (attempt < maxRetries) {\n await this.backoff(undefined, attempt, options?.signal);\n attempt++;\n continue;\n }\n throw new ConnectionError(\"Request timed out\", { raw: e });\n }\n // Network error before any response — safe to retry.\n if (attempt < maxRetries) {\n await this.backoff(undefined, attempt, options?.signal);\n attempt++;\n continue;\n }\n throw new ConnectionError(e?.message ?? \"Network request failed\", { raw: e });\n } finally {\n done();\n }\n }\n }\n\n private async backoff(err: CurvetError | undefined, attempt: number, signal?: AbortSignal) {\n let delay = fullJitterBackoff(attempt);\n if (err instanceof RateLimitError && err.retryAfterMs != null) {\n delay = Math.min(err.retryAfterMs, 30000);\n }\n await sleep(delay, signal);\n }\n\n private buildUrl(path: string, query?: Record<string, string | number | undefined>) {\n const base = this.opts.baseURL.replace(/\\/$/, \"\");\n let url = base + (path.startsWith(\"/\") ? path : \"/\" + path);\n if (query) {\n const qs = Object.entries(query)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join(\"&\");\n if (qs) url += \"?\" + qs;\n }\n return url;\n }\n\n /** Combine a per-request timeout with an optional user AbortSignal. */\n private makeSignal(timeout: number, userSignal?: AbortSignal) {\n const controller = new AbortController();\n const onUserAbort = () => controller.abort();\n if (userSignal) {\n if (userSignal.aborted) controller.abort();\n else userSignal.addEventListener(\"abort\", onUserAbort, { once: true });\n }\n const timer = setTimeout(() => controller.abort(), timeout);\n return {\n signal: controller.signal,\n done: () => {\n clearTimeout(timer);\n userSignal?.removeEventListener(\"abort\", onUserAbort);\n },\n };\n }\n}\n\nfunction safeJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { ChatCreateParams, ChatResponse } from \"../types/chat\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport class Chat {\n constructor(private client: HttpClient) {}\n\n /** Create a chat completion. Synchronous — resolves with the model's reply. */\n create(params: ChatCreateParams, options?: RequestOptions): Promise<ChatResponse> {\n return this.client.request<ChatResponse>({\n method: \"POST\",\n path: \"/chat\",\n body: params,\n options,\n });\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { ImageGenerateParams, ImageResponse } from \"../types/image\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport class Images {\n constructor(private client: HttpClient) {}\n\n /** Generate an image from a prompt. Synchronous — resolves with `imageUrl`. */\n generate(params: ImageGenerateParams, options?: RequestOptions): Promise<ImageResponse> {\n return this.client.request<ImageResponse>({\n method: \"POST\",\n path: \"/image\",\n body: params,\n options,\n });\n }\n}\n","import type { MediaJob, JobStatus } from \"../types/job\";\n\n/**\n * The API returns the output URL under three different keys depending on the\n * endpoint: `videoUrl` (/video), `audioUrl` (/audio), `modelUrl` (/3d), and\n * `output.mediaUrl` (GET /jobs/:id). Unify them.\n */\nfunction pickMediaUrl(body: Record<string, any>): string | undefined {\n return (\n body?.videoUrl ??\n body?.audioUrl ??\n body?.modelUrl ??\n body?.output?.mediaUrl ??\n body?.mediaUrl ??\n undefined\n );\n}\n\n/**\n * Normalize a POST /video|/audio|/3d response, which is EITHER a 200 with the\n * final media URL (job already done) OR a 202 with just a `jobId` to poll.\n */\nexport function normalizeMediaPost(body: unknown): MediaJob {\n const b = (body ?? {}) as Record<string, any>;\n const mediaUrl = pickMediaUrl(b);\n const jobId = b.jobId ?? b.metadata?.jobId;\n const status: JobStatus = mediaUrl\n ? \"completed\"\n : b.status === \"failed\"\n ? \"failed\"\n : \"processing\";\n return {\n jobId,\n status,\n mediaUrl,\n usage: b.usage,\n metadata: b.metadata,\n error: b.error ?? null,\n raw: body,\n };\n}\n\n/** Normalize a GET /jobs/:id response. */\nexport function normalizeJob(body: unknown): MediaJob {\n const b = (body ?? {}) as Record<string, any>;\n const mediaUrl = pickMediaUrl(b);\n const status: JobStatus = (b.status as JobStatus) ?? (mediaUrl ? \"completed\" : \"processing\");\n return {\n jobId: b.jobId,\n status,\n progress: b.progress,\n mediaUrl,\n metadata: b.output?.metadata ?? b.metadata,\n error: b.error ?? null,\n cost: b.cost,\n eta: b.eta,\n raw: body,\n };\n}\n","import { sleep } from \"./retry\";\n\n/** Thrown internally when a poll loop exceeds its timeout. */\nexport class PollTimeoutError extends Error {\n constructor(message = \"Polling timed out\") {\n super(message);\n this.name = \"PollTimeoutError\";\n }\n}\n\nexport interface PollConfig<T> {\n isTerminal: (result: T) => boolean;\n intervalMs: number;\n timeoutMs: number;\n signal?: AbortSignal;\n onTick?: (result: T) => void;\n}\n\n/**\n * Repeatedly call `fn` until `isTerminal` is true (resolves the result) or the\n * timeout elapses (throws PollTimeoutError). Polls immediately, then every\n * `intervalMs`. Honors an AbortSignal between ticks.\n */\nexport async function pollUntil<T>(fn: () => Promise<T>, cfg: PollConfig<T>): Promise<T> {\n const start = Date.now();\n for (;;) {\n const result = await fn();\n cfg.onTick?.(result);\n if (cfg.isTerminal(result)) return result;\n const elapsed = Date.now() - start;\n if (elapsed >= cfg.timeoutMs) throw new PollTimeoutError();\n const remaining = cfg.timeoutMs - elapsed;\n await sleep(Math.min(cfg.intervalMs, Math.max(0, remaining)), cfg.signal);\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { MediaJob, PollOptions } from \"../types/job\";\nimport type { RequestOptions } from \"../types/common\";\nimport { normalizeJob } from \"../core/normalize\";\nimport { pollUntil, PollTimeoutError } from \"../core/poll\";\nimport { JobFailedError, JobTimeoutError } from \"../core/errors\";\n\nexport interface JobDefaults {\n pollIntervalMs: number;\n pollTimeoutMs: number;\n}\n\nexport class Jobs {\n constructor(\n private client: HttpClient,\n private defaults: JobDefaults,\n ) {}\n\n /** Fetch the current status of an async job once (no polling). */\n async retrieve(jobId: string, options?: RequestOptions): Promise<MediaJob> {\n const body = await this.client.request({\n method: \"GET\",\n path: `/jobs/${encodeURIComponent(jobId)}`,\n options,\n });\n return normalizeJob(body);\n }\n\n /** Get a {@link Job} handle to poll/await an existing job by id. */\n handle(jobId: string): Job {\n return new Job(jobId, this.client, this.defaults);\n }\n}\n\n/** A handle to a single async media job. */\nexport class Job {\n constructor(\n readonly id: string,\n private client: HttpClient,\n private defaults: JobDefaults,\n ) {}\n\n /** One status fetch (no polling). */\n retrieve(options?: RequestOptions): Promise<MediaJob> {\n return new Jobs(this.client, this.defaults).retrieve(this.id, options);\n }\n\n /**\n * Poll until the job reaches a terminal state.\n * Resolves with the completed job, or throws JobFailedError / JobTimeoutError.\n */\n async wait(opts: PollOptions = {}): Promise<MediaJob> {\n const intervalMs = opts.pollIntervalMs ?? this.defaults.pollIntervalMs;\n const timeoutMs = opts.pollTimeoutMs ?? this.defaults.pollTimeoutMs;\n\n let result: MediaJob;\n try {\n result = await pollUntil(() => this.retrieve({ signal: opts.signal }), {\n intervalMs,\n timeoutMs,\n signal: opts.signal,\n isTerminal: (r) => r.status === \"completed\" || r.status === \"failed\",\n onTick: (r) => opts.onProgress?.(r.progress ?? 0, r.eta),\n });\n } catch (e) {\n if (e instanceof PollTimeoutError) {\n throw new JobTimeoutError(\n `Job ${this.id} did not complete within ${timeoutMs}ms`,\n this.id,\n );\n }\n throw e;\n }\n\n if (result.status === \"failed\") {\n throw new JobFailedError(result.error || `Job ${this.id} failed`, this.id, {\n raw: result.raw,\n });\n }\n return result;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { MediaJob, VideoGenerateParams, PollOptions } from \"../types/job\";\nimport type { RequestOptions } from \"../types/common\";\nimport { normalizeMediaPost } from \"../core/normalize\";\nimport { Job, type JobDefaults } from \"./jobs\";\nimport { CurvetError } from \"../core/errors\";\n\n/**\n * Video generation. Backed by an async job queue: `generate()` submits and\n * polls to completion (the common case); `submit()` fires and returns the job\n * handle for manual polling.\n *\n * The same implementation backs audio and 3D (v1.1) via the `path` arg.\n */\nexport class Video {\n constructor(\n private client: HttpClient,\n private defaults: JobDefaults,\n private path: string = \"/video\",\n ) {}\n\n /**\n * Submit a job WITHOUT polling. Returns once the server responds — either the\n * 200 fast-path (already done) or a 202 with a jobId.\n *\n * The media POST long-polls server-side and can block well past a normal\n * request timeout, so we default its timeout to the poll budget and disable\n * auto-retry (a retried POST would enqueue a duplicate, double-charged job).\n */\n async submit(params: VideoGenerateParams, options?: RequestOptions): Promise<MediaJob> {\n const reqOptions: RequestOptions = {\n ...options,\n timeout: options?.timeout ?? this.defaults.pollTimeoutMs,\n maxRetries: options?.maxRetries ?? 0,\n };\n const body = await this.client.request({\n method: \"POST\",\n path: this.path,\n body: params,\n options: reqOptions,\n });\n return normalizeMediaPost(body);\n }\n\n /**\n * Submit and resolve to the finished media. Handles the 200-vs-202 split and\n * polls `/jobs/:id` internally. Throws JobFailedError / JobTimeoutError.\n */\n async generate(\n params: VideoGenerateParams,\n options?: RequestOptions & PollOptions,\n ): Promise<MediaJob> {\n const submitted = await this.submit(params, options);\n if (submitted.status === \"completed\" || submitted.status === \"failed\") {\n return submitted;\n }\n if (!submitted.jobId) {\n throw new CurvetError(\"Async job did not return a jobId to poll\", {\n raw: submitted.raw,\n });\n }\n const job = new Job(submitted.jobId, this.client, this.defaults);\n return job.wait({\n pollIntervalMs: options?.pollIntervalMs,\n pollTimeoutMs: options?.pollTimeoutMs,\n signal: options?.signal,\n onProgress: options?.onProgress,\n });\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { ModelInfo, RateLimits } from \"../types/models\";\nimport type { RequestOptions } from \"../types/common\";\n\ninterface ModelsListResponse {\n success: boolean;\n models: ModelInfo[];\n rateLimits: RateLimits;\n}\n\nexport interface ModelsListOptions extends RequestOptions {\n /** Filter to a single model type (e.g. \"chat\", \"image\", \"video\"). */\n type?: string;\n /** Bypass the in-memory cache and fetch fresh. */\n refresh?: boolean;\n}\n\n/**\n * Live model catalog. The list is dynamic and per-app filtered server-side, so\n * it is always fetched (with a short in-memory cache), never hardcoded.\n */\nexport class Models {\n private cache?: { at: number; data: ModelsListResponse };\n\n constructor(\n private client: HttpClient,\n private cacheTtlMs = 60_000,\n ) {}\n\n private async load(options?: RequestOptions): Promise<ModelsListResponse> {\n return this.client.request<ModelsListResponse>({\n method: \"GET\",\n path: \"/models\",\n options,\n });\n }\n\n private async ensure(options?: ModelsListOptions): Promise<ModelsListResponse> {\n const stale = !this.cache || Date.now() - this.cache.at > this.cacheTtlMs;\n if (options?.refresh || stale) {\n this.cache = { at: Date.now(), data: await this.load(options) };\n }\n return this.cache!.data;\n }\n\n /** List available models, optionally filtered by `type`. */\n async list(options?: ModelsListOptions): Promise<ModelInfo[]> {\n const data = await this.ensure(options);\n const models = data.models ?? [];\n return options?.type ? models.filter((m) => m.type === options.type) : models;\n }\n\n /** Find a single model by id (or undefined). */\n async get(id: string, options?: ModelsListOptions): Promise<ModelInfo | undefined> {\n return (await this.list(options)).find((m) => m.id === id);\n }\n\n /** The app's rate limits as reported by GET /models. */\n async rateLimits(options?: ModelsListOptions): Promise<RateLimits | undefined> {\n return (await this.ensure(options)).rateLimits;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport interface BalanceInfo {\n walletBalance?: number;\n totalAvailableUSD: number;\n totalPoints?: number;\n breakdown?: {\n walletCredits?: number;\n totalCredits?: number;\n organizationLimit?: number;\n monthlyUsed?: number;\n isEnterprise?: boolean;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\nexport class Balance {\n constructor(private client: HttpClient) {}\n\n /** Get the current credit balance for the app owner. */\n async get(options?: RequestOptions): Promise<BalanceInfo> {\n const body = await this.client.request<{ success: boolean; balance: BalanceInfo }>({\n method: \"GET\",\n path: \"/balance\",\n options,\n });\n return body.balance;\n }\n}\n","import { HttpClient } from \"./core/http\";\nimport { CurvetError } from \"./core/errors\";\nimport type { FetchLike } from \"./types/common\";\nimport { Chat } from \"./resources/chat\";\nimport { Images } from \"./resources/image\";\nimport { Video } from \"./resources/video\";\nimport { Jobs } from \"./resources/jobs\";\nimport { Models } from \"./resources/models\";\nimport { Balance } from \"./resources/balance\";\n\nexport const DEFAULT_BASE_URL = \"https://curvet.ai/api/v1/playground\";\n\nexport interface CurvetOptions {\n /** Your app key. Falls back to the CURVET_APP_KEY env var. */\n appKey?: string;\n /** Override the gateway base URL (defaults to production). */\n baseURL?: string;\n /** Per-request timeout in ms (default 60000). */\n timeout?: number;\n /** Max automatic retries for 429/5xx and network errors (default 2). */\n maxRetries?: number;\n /** Inject a fetch implementation (defaults to global fetch on Node 18+). */\n fetch?: FetchLike;\n /** Default poll interval for async media jobs, in ms (default 2500). */\n defaultPollIntervalMs?: number;\n /** Default poll timeout for async media jobs, in ms (default 180000). */\n defaultPollTimeoutMs?: number;\n}\n\n/**\n * The Curvet client. One instance per app key.\n *\n * ```ts\n * const curvet = new Curvet({ appKey: process.env.CURVET_APP_KEY });\n * const { response } = await curvet.chat.create({\n * model: \"gpt-4o-mini\",\n * messages: [{ role: \"user\", content: \"hi\" }],\n * });\n * ```\n */\nexport class Curvet {\n readonly chat: Chat;\n readonly image: Images;\n readonly video: Video;\n readonly jobs: Jobs;\n readonly models: Models;\n readonly balance: Balance;\n\n constructor(options: CurvetOptions = {}) {\n const appKey = options.appKey ?? envKey();\n if (!appKey) {\n throw new CurvetError(\n \"Missing Curvet app key. Pass { appKey } or set the CURVET_APP_KEY environment variable.\",\n );\n }\n const fetchImpl = options.fetch ?? defaultFetch();\n if (!fetchImpl) {\n throw new CurvetError(\n \"No fetch implementation available. Use Node 18+ or pass { fetch }.\",\n );\n }\n\n const client = new HttpClient({\n appKey,\n baseURL: options.baseURL ?? DEFAULT_BASE_URL,\n timeout: options.timeout ?? 60_000,\n maxRetries: options.maxRetries ?? 2,\n fetch: fetchImpl,\n });\n\n const jobDefaults = {\n pollIntervalMs: options.defaultPollIntervalMs ?? 2500,\n pollTimeoutMs: options.defaultPollTimeoutMs ?? 180_000,\n };\n\n this.chat = new Chat(client);\n this.image = new Images(client);\n this.jobs = new Jobs(client, jobDefaults);\n this.video = new Video(client, jobDefaults);\n this.models = new Models(client);\n this.balance = new Balance(client);\n }\n}\n\nfunction envKey(): string | undefined {\n return typeof process !== \"undefined\" ? process.env?.CURVET_APP_KEY : undefined;\n}\n\nfunction defaultFetch(): FetchLike | undefined {\n const f = (globalThis as { fetch?: unknown }).fetch;\n return typeof f === \"function\" ? (f.bind(globalThis) as FetchLike) : undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/retry.ts","../src/core/http.ts","../src/resources/chat.ts","../src/resources/image.ts","../src/core/normalize.ts","../src/core/poll.ts","../src/resources/jobs.ts","../src/resources/media.ts","../src/resources/video.ts","../src/resources/audio.ts","../src/resources/threeD.ts","../src/resources/models.ts","../src/resources/balance.ts","../src/resources/analytics.ts","../src/resources/workflows.ts","../src/resources/food.ts","../src/resources/voice.ts","../src/client.ts"],"sourcesContent":["export { Curvet, DEFAULT_BASE_URL } from \"./client\";\nexport type { CurvetOptions } from \"./client\";\n\n// Errors\nexport {\n CurvetError,\n AuthError,\n PermissionError,\n BadRequestError,\n NotFoundError,\n APIError,\n ConnectionError,\n InsufficientBalanceError,\n RateLimitError,\n JobFailedError,\n JobTimeoutError,\n} from \"./core/errors\";\nexport type { CurvetErrorOptions } from \"./core/errors\";\n\n// Resources\nexport { Chat } from \"./resources/chat\";\nexport { Images } from \"./resources/image\";\nexport { MediaResource } from \"./resources/media\";\nexport type { MediaParamsBase } from \"./resources/media\";\nexport { Video } from \"./resources/video\";\nexport { Audio } from \"./resources/audio\";\nexport { ThreeD } from \"./resources/threeD\";\nexport { Jobs, Job } from \"./resources/jobs\";\nexport type { JobDefaults } from \"./resources/jobs\";\nexport { Models } from \"./resources/models\";\nexport type { ModelsListOptions } from \"./resources/models\";\nexport { Balance } from \"./resources/balance\";\nexport type { BalanceInfo } from \"./resources/balance\";\nexport { Analytics } from \"./resources/analytics\";\nexport type { AnalyticsParams, AnalyticsResult } from \"./resources/analytics\";\nexport { Workflows } from \"./resources/workflows\";\nexport type { WorkflowRunParams, WorkflowRunResult } from \"./resources/workflows\";\nexport { Food } from \"./resources/food\";\nexport type { FoodItem } from \"./resources/food\";\nexport { Voice } from \"./resources/voice\";\nexport type { SttParams, SttResult } from \"./resources/voice\";\n\n// Types\nexport type { Usage, RequestOptions, FetchLike } from \"./types/common\";\nexport type { ChatRole, ChatMessage, ChatCreateParams, ChatResponse } from \"./types/chat\";\nexport type { ImageGenerateParams, ImageResponse } from \"./types/image\";\nexport type {\n JobStatus,\n MediaKind,\n MediaJob,\n VideoGenerateParams,\n AudioGenerateParams,\n ThreeDGenerateParams,\n PollOptions,\n} from \"./types/job\";\nexport type { ModelType, ModelInfo, RateLimits, KnownModelId, ModelId } from \"./types/models\";\n","export interface CurvetErrorOptions {\n status?: number;\n requestId?: string;\n raw?: unknown;\n}\n\n/** Base class for every error thrown by the SDK. */\nexport class CurvetError extends Error {\n readonly status?: number;\n readonly requestId?: string;\n readonly raw?: unknown;\n\n constructor(message: string, opts: CurvetErrorOptions = {}) {\n super(message);\n this.name = new.target.name;\n this.status = opts.status;\n this.requestId = opts.requestId;\n this.raw = opts.raw;\n // Restore prototype chain so `instanceof` works after transpilation.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** 401 — missing or invalid `x-app-key`. */\nexport class AuthError extends CurvetError {}\n/** 403 — app not active, playground not enabled, or model/category not allowed. */\nexport class PermissionError extends CurvetError {}\n/** 400 — invalid/unknown model or malformed payload. */\nexport class BadRequestError extends CurvetError {}\n/** 404 — job or workflow not found. */\nexport class NotFoundError extends CurvetError {}\n/** 5xx — upstream/server error (retried automatically). */\nexport class APIError extends CurvetError {}\n/** Network failure or timeout before a response was received. */\nexport class ConnectionError extends CurvetError {}\n\n/** 402 — not enough credits to complete the request. */\nexport class InsufficientBalanceError extends CurvetError {\n required?: number;\n available?: number;\n}\n\n/** 429 — hourly request limit or daily cost cap exceeded. */\nexport class RateLimitError extends CurvetError {\n kind?: \"rate\" | \"cost\";\n limit?: number;\n used?: number;\n resetsAt?: Date;\n retryAfterMs?: number;\n}\n\n/** An async media job finished with status \"failed\". */\nexport class JobFailedError extends CurvetError {\n readonly jobId: string;\n constructor(message: string, jobId: string, opts: CurvetErrorOptions = {}) {\n super(message, opts);\n this.jobId = jobId;\n }\n}\n\n/** An async media job did not finish within the poll timeout. */\nexport class JobTimeoutError extends CurvetError {\n readonly jobId: string;\n constructor(message: string, jobId: string, opts: CurvetErrorOptions = {}) {\n super(message, opts);\n this.jobId = jobId;\n }\n}\n\ninterface HeaderBag {\n get(name: string): string | null;\n}\n\n/** Map an HTTP status + JSON error body to the right typed error. */\nexport function errorFromResponse(\n status: number,\n body: unknown,\n requestId?: string,\n headers?: HeaderBag,\n): CurvetError {\n const b = (body ?? {}) as Record<string, any>;\n const message =\n typeof b.error === \"string\" ? b.error : `HTTP ${status}`;\n const base: CurvetErrorOptions = { status, requestId, raw: body };\n\n switch (status) {\n case 400:\n return new BadRequestError(message, base);\n case 401:\n return new AuthError(message, base);\n case 402: {\n const e = new InsufficientBalanceError(message, base);\n e.required = b.required;\n e.available = b.available;\n return e;\n }\n case 403:\n return new PermissionError(message, base);\n case 404:\n return new NotFoundError(message, base);\n case 429: {\n const e = new RateLimitError(message, base);\n const info = b.rateLimitInfo ?? b.costCapInfo;\n e.kind = b.costCapInfo ? \"cost\" : \"rate\";\n if (info) {\n e.limit = info.limit;\n e.used = info.used;\n if (info.resetsAt) e.resetsAt = new Date(info.resetsAt);\n }\n const retryAfter = headers?.get?.(\"retry-after\");\n if (info?.resetsIn != null) e.retryAfterMs = Number(info.resetsIn) * 1000;\n else if (retryAfter) e.retryAfterMs = Number(retryAfter) * 1000;\n else if (e.resetsAt) e.retryAfterMs = Math.max(0, e.resetsAt.getTime() - Date.now());\n return e;\n }\n default:\n return new APIError(message, base);\n }\n}\n","/** Exponential backoff with full jitter. */\nexport function fullJitterBackoff(attempt: number, baseMs = 500, capMs = 8000): number {\n const exp = Math.min(capMs, baseMs * 2 ** attempt);\n return Math.random() * exp;\n}\n\n/** Sleep that rejects with an AbortError if the signal fires. */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) return reject(abortError());\n const onAbort = () => {\n cleanup();\n reject(abortError());\n };\n const cleanup = () => {\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", onAbort);\n };\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nexport function abortError(): Error {\n const e = new Error(\"The operation was aborted.\");\n e.name = \"AbortError\";\n return e;\n}\n\n/** Only 429 and 5xx are safe to retry. */\nexport function isRetryableStatus(status: number): boolean {\n return status === 429 || status >= 500;\n}\n","import type { FetchLike, RequestOptions } from \"../types/common\";\nimport {\n CurvetError,\n ConnectionError,\n RateLimitError,\n errorFromResponse,\n} from \"./errors\";\nimport { fullJitterBackoff, isRetryableStatus, sleep } from \"./retry\";\n\nexport interface HttpClientOptions {\n appKey: string;\n baseURL: string;\n timeout: number;\n maxRetries: number;\n fetch: FetchLike;\n}\n\nexport interface RequestArgs {\n method: string;\n path: string;\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n options?: RequestOptions;\n}\n\n/**\n * The single place that knows about fetch, headers, base URL, error mapping,\n * and retries. Resources call `request()`; everything else stays mockable.\n */\nexport class HttpClient {\n constructor(private opts: HttpClientOptions) {}\n\n async request<T = any>(args: RequestArgs): Promise<T> {\n const { method, path, body, query, options } = args;\n const url = this.buildUrl(path, query);\n const maxRetries = options?.maxRetries ?? this.opts.maxRetries;\n const timeout = options?.timeout ?? this.opts.timeout;\n\n const headers: Record<string, string> = {\n \"x-app-key\": this.opts.appKey,\n accept: \"application/json\",\n ...(options?.headers ?? {}),\n };\n let payload: string | FormData | undefined;\n if (body !== undefined) {\n if (typeof FormData !== \"undefined\" && body instanceof FormData) {\n // Multipart — let fetch set the content-type (with boundary).\n payload = body;\n } else {\n headers[\"content-type\"] = \"application/json\";\n payload = JSON.stringify(body);\n }\n }\n\n let attempt = 0;\n for (;;) {\n const { signal, done } = this.makeSignal(timeout, options?.signal);\n try {\n const res = await this.opts.fetch(url, { method, headers, body: payload, signal });\n const text = await res.text();\n const parsed = text ? safeJson(text) : undefined;\n\n if (res.ok) return parsed as T;\n\n const requestId =\n res.headers.get(\"x-request-id\") ??\n (parsed as any)?.metadata?.requestId ??\n undefined;\n const err = errorFromResponse(res.status, parsed, requestId, res.headers);\n\n if (isRetryableStatus(res.status) && attempt < maxRetries) {\n await this.backoff(err, attempt, options?.signal);\n attempt++;\n continue;\n }\n throw err;\n } catch (e: any) {\n if (e instanceof CurvetError) throw e;\n // AbortError: distinguish user-abort (rethrow) from our timeout (retry/ConnectionError).\n if (e?.name === \"AbortError\") {\n if (options?.signal?.aborted) throw e;\n if (attempt < maxRetries) {\n await this.backoff(undefined, attempt, options?.signal);\n attempt++;\n continue;\n }\n throw new ConnectionError(\"Request timed out\", { raw: e });\n }\n // Network error before any response — safe to retry.\n if (attempt < maxRetries) {\n await this.backoff(undefined, attempt, options?.signal);\n attempt++;\n continue;\n }\n throw new ConnectionError(e?.message ?? \"Network request failed\", { raw: e });\n } finally {\n done();\n }\n }\n }\n\n private async backoff(err: CurvetError | undefined, attempt: number, signal?: AbortSignal) {\n let delay = fullJitterBackoff(attempt);\n if (err instanceof RateLimitError && err.retryAfterMs != null) {\n delay = Math.min(err.retryAfterMs, 30000);\n }\n await sleep(delay, signal);\n }\n\n private buildUrl(path: string, query?: Record<string, string | number | undefined>) {\n const base = this.opts.baseURL.replace(/\\/$/, \"\");\n let url = base + (path.startsWith(\"/\") ? path : \"/\" + path);\n if (query) {\n const qs = Object.entries(query)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join(\"&\");\n if (qs) url += \"?\" + qs;\n }\n return url;\n }\n\n /** Combine a per-request timeout with an optional user AbortSignal. */\n private makeSignal(timeout: number, userSignal?: AbortSignal) {\n const controller = new AbortController();\n const onUserAbort = () => controller.abort();\n if (userSignal) {\n if (userSignal.aborted) controller.abort();\n else userSignal.addEventListener(\"abort\", onUserAbort, { once: true });\n }\n const timer = setTimeout(() => controller.abort(), timeout);\n return {\n signal: controller.signal,\n done: () => {\n clearTimeout(timer);\n userSignal?.removeEventListener(\"abort\", onUserAbort);\n },\n };\n }\n}\n\nfunction safeJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { ChatCreateParams, ChatResponse } from \"../types/chat\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport class Chat {\n constructor(private client: HttpClient) {}\n\n /** Create a chat completion. Synchronous — resolves with the model's reply. */\n create(params: ChatCreateParams, options?: RequestOptions): Promise<ChatResponse> {\n return this.client.request<ChatResponse>({\n method: \"POST\",\n path: \"/chat\",\n body: params,\n options,\n });\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { ImageGenerateParams, ImageResponse } from \"../types/image\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport class Images {\n constructor(private client: HttpClient) {}\n\n /** Generate an image from a prompt. Synchronous — resolves with `imageUrl`. */\n generate(params: ImageGenerateParams, options?: RequestOptions): Promise<ImageResponse> {\n return this.client.request<ImageResponse>({\n method: \"POST\",\n path: \"/image\",\n body: params,\n options,\n });\n }\n}\n","import type { MediaJob, JobStatus } from \"../types/job\";\n\n/**\n * The API returns the output URL under three different keys depending on the\n * endpoint: `videoUrl` (/video), `audioUrl` (/audio), `modelUrl` (/3d), and\n * `output.mediaUrl` (GET /jobs/:id). Unify them.\n */\nfunction pickMediaUrl(body: Record<string, any>): string | undefined {\n return (\n body?.videoUrl ??\n body?.audioUrl ??\n body?.modelUrl ??\n body?.output?.mediaUrl ??\n body?.mediaUrl ??\n undefined\n );\n}\n\n/**\n * Normalize a POST /video|/audio|/3d response, which is EITHER a 200 with the\n * final media URL (job already done) OR a 202 with just a `jobId` to poll.\n */\nexport function normalizeMediaPost(body: unknown): MediaJob {\n const b = (body ?? {}) as Record<string, any>;\n const mediaUrl = pickMediaUrl(b);\n const jobId = b.jobId ?? b.metadata?.jobId;\n const status: JobStatus = mediaUrl\n ? \"completed\"\n : b.status === \"failed\"\n ? \"failed\"\n : \"processing\";\n return {\n jobId,\n status,\n mediaUrl,\n usage: b.usage,\n metadata: b.metadata,\n error: b.error ?? null,\n raw: body,\n };\n}\n\n/** Normalize a GET /jobs/:id response. */\nexport function normalizeJob(body: unknown): MediaJob {\n const b = (body ?? {}) as Record<string, any>;\n const mediaUrl = pickMediaUrl(b);\n const status: JobStatus = (b.status as JobStatus) ?? (mediaUrl ? \"completed\" : \"processing\");\n return {\n jobId: b.jobId,\n status,\n progress: b.progress,\n mediaUrl,\n metadata: b.output?.metadata ?? b.metadata,\n error: b.error ?? null,\n cost: b.cost,\n eta: b.eta,\n raw: body,\n };\n}\n","import { sleep } from \"./retry\";\n\n/** Thrown internally when a poll loop exceeds its timeout. */\nexport class PollTimeoutError extends Error {\n constructor(message = \"Polling timed out\") {\n super(message);\n this.name = \"PollTimeoutError\";\n }\n}\n\nexport interface PollConfig<T> {\n isTerminal: (result: T) => boolean;\n intervalMs: number;\n timeoutMs: number;\n signal?: AbortSignal;\n onTick?: (result: T) => void;\n}\n\n/**\n * Repeatedly call `fn` until `isTerminal` is true (resolves the result) or the\n * timeout elapses (throws PollTimeoutError). Polls immediately, then every\n * `intervalMs`. Honors an AbortSignal between ticks.\n */\nexport async function pollUntil<T>(fn: () => Promise<T>, cfg: PollConfig<T>): Promise<T> {\n const start = Date.now();\n for (;;) {\n const result = await fn();\n cfg.onTick?.(result);\n if (cfg.isTerminal(result)) return result;\n const elapsed = Date.now() - start;\n if (elapsed >= cfg.timeoutMs) throw new PollTimeoutError();\n const remaining = cfg.timeoutMs - elapsed;\n await sleep(Math.min(cfg.intervalMs, Math.max(0, remaining)), cfg.signal);\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { MediaJob, PollOptions } from \"../types/job\";\nimport type { RequestOptions } from \"../types/common\";\nimport { normalizeJob } from \"../core/normalize\";\nimport { pollUntil, PollTimeoutError } from \"../core/poll\";\nimport { JobFailedError, JobTimeoutError } from \"../core/errors\";\n\nexport interface JobDefaults {\n pollIntervalMs: number;\n pollTimeoutMs: number;\n}\n\nexport class Jobs {\n constructor(\n private client: HttpClient,\n private defaults: JobDefaults,\n ) {}\n\n /** Fetch the current status of an async job once (no polling). */\n async retrieve(jobId: string, options?: RequestOptions): Promise<MediaJob> {\n const body = await this.client.request({\n method: \"GET\",\n path: `/jobs/${encodeURIComponent(jobId)}`,\n options,\n });\n return normalizeJob(body);\n }\n\n /** Get a {@link Job} handle to poll/await an existing job by id. */\n handle(jobId: string): Job {\n return new Job(jobId, this.client, this.defaults);\n }\n}\n\n/** A handle to a single async media job. */\nexport class Job {\n constructor(\n readonly id: string,\n private client: HttpClient,\n private defaults: JobDefaults,\n ) {}\n\n /** One status fetch (no polling). */\n retrieve(options?: RequestOptions): Promise<MediaJob> {\n return new Jobs(this.client, this.defaults).retrieve(this.id, options);\n }\n\n /**\n * Poll until the job reaches a terminal state.\n * Resolves with the completed job, or throws JobFailedError / JobTimeoutError.\n */\n async wait(opts: PollOptions = {}): Promise<MediaJob> {\n const intervalMs = opts.pollIntervalMs ?? this.defaults.pollIntervalMs;\n const timeoutMs = opts.pollTimeoutMs ?? this.defaults.pollTimeoutMs;\n\n let result: MediaJob;\n try {\n result = await pollUntil(() => this.retrieve({ signal: opts.signal }), {\n intervalMs,\n timeoutMs,\n signal: opts.signal,\n isTerminal: (r) => r.status === \"completed\" || r.status === \"failed\",\n onTick: (r) => opts.onProgress?.(r.progress ?? 0, r.eta),\n });\n } catch (e) {\n if (e instanceof PollTimeoutError) {\n throw new JobTimeoutError(\n `Job ${this.id} did not complete within ${timeoutMs}ms`,\n this.id,\n );\n }\n throw e;\n }\n\n if (result.status === \"failed\") {\n throw new JobFailedError(result.error || `Job ${this.id} failed`, this.id, {\n raw: result.raw,\n });\n }\n return result;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { MediaJob, PollOptions } from \"../types/job\";\nimport type { RequestOptions } from \"../types/common\";\nimport { normalizeMediaPost } from \"../core/normalize\";\nimport { Job, type JobDefaults } from \"./jobs\";\nimport { CurvetError } from \"../core/errors\";\n\nexport interface MediaParamsBase {\n model: string;\n prompt: string;\n [key: string]: unknown;\n}\n\n/**\n * Generic engine for the async media endpoints (video / audio / 3d). They all\n * enqueue the same server-side job queue, so they share one implementation\n * parameterized by `path` and request param type.\n *\n * `generate()` submits and polls to completion; `submit()` fires without polling.\n */\nexport class MediaResource<P extends MediaParamsBase> {\n constructor(\n protected client: HttpClient,\n protected defaults: JobDefaults,\n protected path: string,\n ) {}\n\n /**\n * Submit WITHOUT polling. The media POST long-polls server-side and can block\n * well past a normal request timeout, so we default its timeout to the poll\n * budget and disable auto-retry (a retried POST would enqueue a duplicate job).\n */\n async submit(params: P, options?: RequestOptions): Promise<MediaJob> {\n const reqOptions: RequestOptions = {\n ...options,\n timeout: options?.timeout ?? this.defaults.pollTimeoutMs,\n maxRetries: options?.maxRetries ?? 0,\n };\n const body = await this.client.request({\n method: \"POST\",\n path: this.path,\n body: params,\n options: reqOptions,\n });\n return normalizeMediaPost(body);\n }\n\n /** Submit and resolve to the finished media (auto-polls /jobs/:id). */\n async generate(params: P, options?: RequestOptions & PollOptions): Promise<MediaJob> {\n const submitted = await this.submit(params, options);\n if (submitted.status === \"completed\" || submitted.status === \"failed\") {\n return submitted;\n }\n if (!submitted.jobId) {\n throw new CurvetError(\"Async job did not return a jobId to poll\", {\n raw: submitted.raw,\n });\n }\n const job = new Job(submitted.jobId, this.client, this.defaults);\n return job.wait({\n pollIntervalMs: options?.pollIntervalMs,\n pollTimeoutMs: options?.pollTimeoutMs,\n signal: options?.signal,\n onProgress: options?.onProgress,\n });\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { JobDefaults } from \"./jobs\";\nimport type { VideoGenerateParams } from \"../types/job\";\nimport { MediaResource } from \"./media\";\n\n/** Video generation (async). `curvet.video.generate(...)` auto-polls to completion. */\nexport class Video extends MediaResource<VideoGenerateParams> {\n constructor(client: HttpClient, defaults: JobDefaults) {\n super(client, defaults, \"/video\");\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { JobDefaults } from \"./jobs\";\nimport type { AudioGenerateParams } from \"../types/job\";\nimport { MediaResource } from \"./media\";\n\n/** Audio generation (async). `curvet.audio.generate(...)` auto-polls to completion. */\nexport class Audio extends MediaResource<AudioGenerateParams> {\n constructor(client: HttpClient, defaults: JobDefaults) {\n super(client, defaults, \"/audio\");\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { JobDefaults } from \"./jobs\";\nimport type { ThreeDGenerateParams } from \"../types/job\";\nimport { MediaResource } from \"./media\";\n\n/** 3D model generation (async). `curvet.threeD.generate(...)` auto-polls to completion. */\nexport class ThreeD extends MediaResource<ThreeDGenerateParams> {\n constructor(client: HttpClient, defaults: JobDefaults) {\n super(client, defaults, \"/3d\");\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { ModelInfo, RateLimits } from \"../types/models\";\nimport type { RequestOptions } from \"../types/common\";\n\ninterface ModelsListResponse {\n success: boolean;\n models: ModelInfo[];\n rateLimits: RateLimits;\n}\n\nexport interface ModelsListOptions extends RequestOptions {\n /** Filter to a single model type (e.g. \"chat\", \"image\", \"video\"). */\n type?: string;\n /** Bypass the in-memory cache and fetch fresh. */\n refresh?: boolean;\n}\n\n/**\n * Live model catalog. The list is dynamic and per-app filtered server-side, so\n * it is always fetched (with a short in-memory cache), never hardcoded.\n */\nexport class Models {\n private cache?: { at: number; data: ModelsListResponse };\n\n constructor(\n private client: HttpClient,\n private cacheTtlMs = 60_000,\n ) {}\n\n private async load(options?: RequestOptions): Promise<ModelsListResponse> {\n return this.client.request<ModelsListResponse>({\n method: \"GET\",\n path: \"/models\",\n options,\n });\n }\n\n private async ensure(options?: ModelsListOptions): Promise<ModelsListResponse> {\n const stale = !this.cache || Date.now() - this.cache.at > this.cacheTtlMs;\n if (options?.refresh || stale) {\n this.cache = { at: Date.now(), data: await this.load(options) };\n }\n return this.cache!.data;\n }\n\n /** List available models, optionally filtered by `type`. */\n async list(options?: ModelsListOptions): Promise<ModelInfo[]> {\n const data = await this.ensure(options);\n const models = data.models ?? [];\n return options?.type ? models.filter((m) => m.type === options.type) : models;\n }\n\n /** Find a single model by id (or undefined). */\n async get(id: string, options?: ModelsListOptions): Promise<ModelInfo | undefined> {\n return (await this.list(options)).find((m) => m.id === id);\n }\n\n /** The app's rate limits as reported by GET /models. */\n async rateLimits(options?: ModelsListOptions): Promise<RateLimits | undefined> {\n return (await this.ensure(options)).rateLimits;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport interface BalanceInfo {\n walletBalance?: number;\n totalAvailableUSD: number;\n totalPoints?: number;\n breakdown?: {\n walletCredits?: number;\n totalCredits?: number;\n organizationLimit?: number;\n monthlyUsed?: number;\n isEnterprise?: boolean;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\nexport class Balance {\n constructor(private client: HttpClient) {}\n\n /** Get the current credit balance for the app owner. */\n async get(options?: RequestOptions): Promise<BalanceInfo> {\n const body = await this.client.request<{ success: boolean; balance: BalanceInfo }>({\n method: \"GET\",\n path: \"/balance\",\n options,\n });\n return body.balance;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport interface AnalyticsParams extends RequestOptions {\n /** ISO 8601 start date. */\n startDate?: string;\n /** ISO 8601 end date. */\n endDate?: string;\n}\n\nexport interface AnalyticsResult {\n totalRequests?: number;\n totalCost?: number;\n requestsByModel?: Record<string, number>;\n requestsByCategory?: Record<string, number>;\n [key: string]: unknown;\n}\n\nexport class Analytics {\n constructor(private client: HttpClient) {}\n\n /** Usage analytics for the app, optionally bounded by a date range. */\n async get(params: AnalyticsParams = {}): Promise<AnalyticsResult> {\n const { startDate, endDate, ...options } = params;\n const body = await this.client.request<{ success: boolean; analytics: AnalyticsResult }>({\n method: \"GET\",\n path: \"/analytics\",\n query: { startDate, endDate },\n options,\n });\n return body.analytics;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport interface WorkflowRunParams {\n /** Input values for the workflow. */\n inputs?: Record<string, unknown>;\n /** Optional file inputs, keyed by the workflow's file field name. */\n files?: Record<string, Blob>;\n /** Include the full execution state in the response (default true server-side). */\n includeFullState?: boolean;\n}\n\nexport interface WorkflowRunResult {\n success: boolean;\n [key: string]: unknown;\n}\n\nexport class Workflows {\n constructor(private client: HttpClient) {}\n\n /**\n * Execute a visual-builder workflow by id. Sends JSON when there are no file\n * inputs, multipart/form-data when files are provided. Not auto-retried (a\n * workflow run executes and may consume credits).\n */\n async run(\n id: string,\n params: WorkflowRunParams = {},\n options?: RequestOptions,\n ): Promise<WorkflowRunResult> {\n const reqOptions: RequestOptions = { ...options, maxRetries: options?.maxRetries ?? 0 };\n const hasFiles = params.files && Object.keys(params.files).length > 0;\n\n let body: unknown;\n if (hasFiles) {\n const form = new FormData();\n form.append(\"inputs\", JSON.stringify(params.inputs ?? {}));\n if (params.includeFullState !== undefined) {\n form.append(\"includeFullState\", String(params.includeFullState));\n }\n for (const [field, file] of Object.entries(params.files!)) {\n form.append(field, file);\n }\n body = form;\n } else {\n body = { inputs: params.inputs ?? {}, includeFullState: params.includeFullState };\n }\n\n return this.client.request<WorkflowRunResult>({\n method: \"POST\",\n path: `/workflows/${encodeURIComponent(id)}/run`,\n body,\n options: reqOptions,\n });\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport interface FoodItem {\n [key: string]: unknown;\n}\n\n/**\n * Indian Food Dataset API. Mounted as a sibling of the playground under\n * `/api/v1/food`, so it uses the v1-root HTTP client. Requires the app to have\n * Food API access enabled.\n */\nexport class Food {\n constructor(private client: HttpClient) {}\n\n /** List dishes (default limit 20). */\n async list(opts?: { limit?: number } & RequestOptions): Promise<FoodItem[]> {\n const { limit, ...options } = opts ?? {};\n const body = await this.client.request<{ success: boolean; data: FoodItem[]; count: number }>({\n method: \"GET\",\n path: \"/food\",\n query: { limit },\n options,\n });\n return body.data;\n }\n\n /** Full-text search for dishes. */\n async search(query: string, opts?: { limit?: number } & RequestOptions): Promise<FoodItem[]> {\n const { limit, ...options } = opts ?? {};\n const body = await this.client.request<{ success: boolean; data: FoodItem[] }>({\n method: \"GET\",\n path: \"/food/search\",\n query: { q: query, limit },\n options,\n });\n return body.data;\n }\n\n /** Natural-language dish recommendations. */\n async recommendations(prompt: string, options?: RequestOptions): Promise<FoodItem[]> {\n const body = await this.client.request<{ success: boolean; data: FoodItem[] }>({\n method: \"POST\",\n path: \"/food/recommendations\",\n body: { prompt },\n options,\n });\n return body.data;\n }\n}\n","import type { HttpClient } from \"../core/http\";\nimport type { RequestOptions } from \"../types/common\";\n\nexport interface SttParams {\n /** The audio to transcribe. */\n audio: Blob | Uint8Array | ArrayBuffer;\n /** File name for the upload (default \"audio\"). */\n filename?: string;\n provider?: \"elevenlabs\" | \"deepinfra\" | (string & {});\n /** ASR model id (provider-specific; optional). */\n model?: string;\n prompt?: string;\n /** ISO 639-1 language hint. */\n languageCode?: string;\n allowFallback?: boolean;\n}\n\nexport interface SttResult {\n success: boolean;\n text: string;\n languageCode?: string;\n segments?: Array<{ start: number; end: number; text: string }>;\n provider?: string;\n creditsCharged?: number;\n creditsRemaining?: number;\n [key: string]: unknown;\n}\n\n/**\n * Public speech-to-text. Mounted as a sibling of the playground under\n * `/api/v1/voice`, so it uses the v1-root HTTP client. Multipart upload; not\n * auto-retried (it consumes credits).\n */\nexport class Voice {\n constructor(private client: HttpClient) {}\n\n async stt(params: SttParams, options?: RequestOptions): Promise<SttResult> {\n const form = new FormData();\n form.append(\"audio\", toBlob(params.audio), params.filename ?? \"audio\");\n if (params.provider) form.append(\"provider\", params.provider);\n if (params.model) form.append(\"model\", params.model);\n if (params.prompt) form.append(\"prompt\", params.prompt);\n if (params.languageCode) form.append(\"languageCode\", params.languageCode);\n if (params.allowFallback !== undefined) {\n form.append(\"allowFallback\", String(params.allowFallback));\n }\n\n const reqOptions: RequestOptions = {\n ...options,\n timeout: options?.timeout ?? 120_000,\n maxRetries: options?.maxRetries ?? 0,\n };\n return this.client.request<SttResult>({\n method: \"POST\",\n path: \"/voice/stt/public\",\n body: form,\n options: reqOptions,\n });\n }\n}\n\nfunction toBlob(audio: Blob | Uint8Array | ArrayBuffer): Blob {\n if (typeof Blob !== \"undefined\" && audio instanceof Blob) return audio;\n return new Blob([audio] as ConstructorParameters<typeof Blob>[0]);\n}\n","import { HttpClient } from \"./core/http\";\nimport { CurvetError } from \"./core/errors\";\nimport type { FetchLike } from \"./types/common\";\nimport { Chat } from \"./resources/chat\";\nimport { Images } from \"./resources/image\";\nimport { Video } from \"./resources/video\";\nimport { Audio } from \"./resources/audio\";\nimport { ThreeD } from \"./resources/threeD\";\nimport { Jobs } from \"./resources/jobs\";\nimport { Models } from \"./resources/models\";\nimport { Balance } from \"./resources/balance\";\nimport { Analytics } from \"./resources/analytics\";\nimport { Workflows } from \"./resources/workflows\";\nimport { Food } from \"./resources/food\";\nimport { Voice } from \"./resources/voice\";\n\nexport const DEFAULT_BASE_URL = \"https://curvet.ai/api/v1/playground\";\n\nexport interface CurvetOptions {\n /** Your app key. Falls back to the CURVET_APP_KEY env var. */\n appKey?: string;\n /** Override the playground base URL (defaults to production). */\n baseURL?: string;\n /** Per-request timeout in ms (default 60000). */\n timeout?: number;\n /** Max automatic retries for 429/5xx and network errors (default 2). */\n maxRetries?: number;\n /** Inject a fetch implementation (defaults to global fetch on Node 18+). */\n fetch?: FetchLike;\n /** Default poll interval for async media jobs, in ms (default 2500). */\n defaultPollIntervalMs?: number;\n /** Default poll timeout for async media jobs, in ms (default 180000). */\n defaultPollTimeoutMs?: number;\n}\n\n/**\n * The Curvet client. One instance per app key.\n *\n * ```ts\n * const curvet = new Curvet({ appKey: process.env.CURVET_APP_KEY });\n * const { response } = await curvet.chat.create({\n * model: \"gpt-4o-mini\",\n * messages: [{ role: \"user\", content: \"hi\" }],\n * });\n * ```\n */\nexport class Curvet {\n readonly chat: Chat;\n readonly image: Images;\n readonly video: Video;\n readonly audio: Audio;\n readonly threeD: ThreeD;\n readonly jobs: Jobs;\n readonly models: Models;\n readonly balance: Balance;\n readonly analytics: Analytics;\n readonly workflows: Workflows;\n readonly food: Food;\n readonly voice: Voice;\n\n constructor(options: CurvetOptions = {}) {\n const appKey = options.appKey ?? envKey();\n if (!appKey) {\n throw new CurvetError(\n \"Missing Curvet app key. Pass { appKey } or set the CURVET_APP_KEY environment variable.\",\n );\n }\n const fetchImpl = options.fetch ?? defaultFetch();\n if (!fetchImpl) {\n throw new CurvetError(\n \"No fetch implementation available. Use Node 18+ or pass { fetch }.\",\n );\n }\n\n const playgroundBase = options.baseURL ?? DEFAULT_BASE_URL;\n // Sibling routes (food, voice) live one level up at /api/v1/*.\n const v1Base = playgroundBase.replace(/\\/playground\\/?$/, \"\");\n\n const shared = {\n appKey,\n timeout: options.timeout ?? 60_000,\n maxRetries: options.maxRetries ?? 2,\n fetch: fetchImpl,\n };\n const client = new HttpClient({ ...shared, baseURL: playgroundBase });\n const v1Client = new HttpClient({ ...shared, baseURL: v1Base });\n\n const jobDefaults = {\n pollIntervalMs: options.defaultPollIntervalMs ?? 2500,\n pollTimeoutMs: options.defaultPollTimeoutMs ?? 180_000,\n };\n\n this.chat = new Chat(client);\n this.image = new Images(client);\n this.jobs = new Jobs(client, jobDefaults);\n this.video = new Video(client, jobDefaults);\n this.audio = new Audio(client, jobDefaults);\n this.threeD = new ThreeD(client, jobDefaults);\n this.models = new Models(client);\n this.balance = new Balance(client);\n this.analytics = new Analytics(client);\n this.workflows = new Workflows(client);\n this.food = new Food(v1Client);\n this.voice = new Voice(v1Client);\n }\n}\n\nfunction envKey(): string | undefined {\n return typeof process !== \"undefined\" ? process.env?.CURVET_APP_KEY : undefined;\n}\n\nfunction defaultFetch(): FetchLike | undefined {\n const f = (globalThis as { fetch?: unknown }).fetch;\n return typeof f === \"function\" ? (f.bind(globalThis) as FetchLike) : undefined;\n}\n"],"mappings":"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","names":[]}
|