@brotu/ai 0.1.0 → 0.2.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/CATALOG.md +154 -2
- package/LICENSE +1 -1
- package/README.md +202 -58
- package/dist/adapters/google.adapter.d.ts +4 -2
- package/dist/adapters/google.adapter.d.ts.map +1 -1
- package/dist/adapters/openai.adapter.d.ts +2 -1
- package/dist/adapters/openai.adapter.d.ts.map +1 -1
- package/dist/catalog.cjs +114 -17
- package/dist/catalog.js +1 -1
- package/dist/{chunk-GKLTQ55S.js → chunk-PL534BFN.js} +118 -17
- package/dist/index.cjs +356 -32
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +243 -16
- package/dist/providers/google.models.d.ts +23 -0
- package/dist/providers/google.models.d.ts.map +1 -1
- package/dist/providers/openai.models.d.ts +7 -0
- package/dist/providers/openai.models.d.ts.map +1 -1
- package/package.json +6 -2
package/CATALOG.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- Generated by scripts/generate-catalog-doc.ts. Do not edit by hand. -->
|
|
2
2
|
# Supported catalog
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
97 models: 37 video, 29 image, 12 speech, 19 text.
|
|
5
5
|
|
|
6
6
|
Every model is served by its vendor's own API — no aggregator sits in between, so
|
|
7
7
|
the key you configure is the account that runs the work and bills it.
|
|
@@ -347,7 +347,159 @@ resolutions, aspect ratios and capabilities.
|
|
|
347
347
|
|---|---|---|---|---|
|
|
348
348
|
| `z-image-turbo` | — | — | image_optional | qwen |
|
|
349
349
|
|
|
350
|
-
##
|
|
350
|
+
## Speech (12)
|
|
351
|
+
|
|
352
|
+
### cosyvoice-v3-flash
|
|
353
|
+
|
|
354
|
+
| id | resolutions | aspect | input | served by |
|
|
355
|
+
|---|---|---|---|---|
|
|
356
|
+
| `cosyvoice-v3-flash` | — | — | text_only | qwen |
|
|
357
|
+
|
|
358
|
+
### eleven_flash_v2_5
|
|
359
|
+
|
|
360
|
+
| id | resolutions | aspect | input | served by |
|
|
361
|
+
|---|---|---|---|---|
|
|
362
|
+
| `eleven_flash_v2_5` | — | — | text_only | elevenlabs |
|
|
363
|
+
|
|
364
|
+
### eleven_multilingual_v2
|
|
365
|
+
|
|
366
|
+
| id | resolutions | aspect | input | served by |
|
|
367
|
+
|---|---|---|---|---|
|
|
368
|
+
| `eleven_multilingual_v2` | — | — | text_only | elevenlabs |
|
|
369
|
+
|
|
370
|
+
### eleven_v3
|
|
371
|
+
|
|
372
|
+
| id | resolutions | aspect | input | served by |
|
|
373
|
+
|---|---|---|---|---|
|
|
374
|
+
| `eleven_v3` | — | — | text_only | elevenlabs |
|
|
375
|
+
|
|
376
|
+
### gemini-2.5-flash-preview-tts
|
|
377
|
+
|
|
378
|
+
| id | resolutions | aspect | input | served by |
|
|
379
|
+
|---|---|---|---|---|
|
|
380
|
+
| `gemini-2.5-flash-preview-tts` | — | — | text_only | google |
|
|
381
|
+
|
|
382
|
+
### gemini-2.5-pro-preview-tts
|
|
383
|
+
|
|
384
|
+
| id | resolutions | aspect | input | served by |
|
|
385
|
+
|---|---|---|---|---|
|
|
386
|
+
| `gemini-2.5-pro-preview-tts` | — | — | text_only | google |
|
|
387
|
+
|
|
388
|
+
### gemini-3.1-flash-tts-preview
|
|
389
|
+
|
|
390
|
+
| id | resolutions | aspect | input | served by |
|
|
391
|
+
|---|---|---|---|---|
|
|
392
|
+
| `gemini-3.1-flash-tts-preview` | — | — | text_only | google |
|
|
393
|
+
|
|
394
|
+
### kling
|
|
395
|
+
|
|
396
|
+
| id | resolutions | aspect | input | served by |
|
|
397
|
+
|---|---|---|---|---|
|
|
398
|
+
| `kling/tts` | — | — | text_only | kling |
|
|
399
|
+
|
|
400
|
+
### qwen-audio-3.0-tts-flash
|
|
401
|
+
|
|
402
|
+
| id | resolutions | aspect | input | served by |
|
|
403
|
+
|---|---|---|---|---|
|
|
404
|
+
| `qwen-audio-3.0-tts-flash` | — | — | text_only | qwen |
|
|
405
|
+
|
|
406
|
+
### qwen-audio-3.0-tts-plus
|
|
407
|
+
|
|
408
|
+
| id | resolutions | aspect | input | served by |
|
|
409
|
+
|---|---|---|---|---|
|
|
410
|
+
| `qwen-audio-3.0-tts-plus` | — | — | text_only | qwen |
|
|
411
|
+
|
|
412
|
+
### qwen3-tts-flash
|
|
413
|
+
|
|
414
|
+
| id | resolutions | aspect | input | served by |
|
|
415
|
+
|---|---|---|---|---|
|
|
416
|
+
| `qwen3-tts-flash` | — | — | text_only | qwen |
|
|
417
|
+
|
|
418
|
+
### qwen3-tts-instruct-flash
|
|
419
|
+
|
|
420
|
+
| id | resolutions | aspect | input | served by |
|
|
421
|
+
|---|---|---|---|---|
|
|
422
|
+
| `qwen3-tts-instruct-flash` | — | — | text_only | qwen |
|
|
423
|
+
|
|
424
|
+
## Text (19)
|
|
425
|
+
|
|
426
|
+
### gemini-2.5-flash
|
|
427
|
+
|
|
428
|
+
| id | resolutions | aspect | input | served by |
|
|
429
|
+
|---|---|---|---|---|
|
|
430
|
+
| `gemini-2.5-flash` | — | — | image_optional | google |
|
|
431
|
+
|
|
432
|
+
### gemini-2.5-flash-lite
|
|
433
|
+
|
|
434
|
+
| id | resolutions | aspect | input | served by |
|
|
435
|
+
|---|---|---|---|---|
|
|
436
|
+
| `gemini-2.5-flash-lite` | — | — | image_optional | google |
|
|
437
|
+
|
|
438
|
+
### gemini-2.5-pro
|
|
439
|
+
|
|
440
|
+
| id | resolutions | aspect | input | served by |
|
|
441
|
+
|---|---|---|---|---|
|
|
442
|
+
| `gemini-2.5-pro` | — | — | image_optional | google |
|
|
443
|
+
|
|
444
|
+
### gemini-3-flash-preview
|
|
445
|
+
|
|
446
|
+
| id | resolutions | aspect | input | served by |
|
|
447
|
+
|---|---|---|---|---|
|
|
448
|
+
| `gemini-3-flash-preview` | — | — | image_optional | google |
|
|
449
|
+
|
|
450
|
+
### gemini-3.1-flash-lite
|
|
451
|
+
|
|
452
|
+
| id | resolutions | aspect | input | served by |
|
|
453
|
+
|---|---|---|---|---|
|
|
454
|
+
| `gemini-3.1-flash-lite` | — | — | image_optional | google |
|
|
455
|
+
|
|
456
|
+
### gemini-3.1-pro-preview
|
|
457
|
+
|
|
458
|
+
| id | resolutions | aspect | input | served by |
|
|
459
|
+
|---|---|---|---|---|
|
|
460
|
+
| `gemini-3.1-pro-preview` | — | — | image_optional | google |
|
|
461
|
+
|
|
462
|
+
### gemini-3.5-flash
|
|
463
|
+
|
|
464
|
+
| id | resolutions | aspect | input | served by |
|
|
465
|
+
|---|---|---|---|---|
|
|
466
|
+
| `gemini-3.5-flash` | — | — | image_optional | google |
|
|
467
|
+
|
|
468
|
+
### gemini-3.5-flash-lite
|
|
469
|
+
|
|
470
|
+
| id | resolutions | aspect | input | served by |
|
|
471
|
+
|---|---|---|---|---|
|
|
472
|
+
| `gemini-3.5-flash-lite` | — | — | image_optional | google |
|
|
473
|
+
|
|
474
|
+
### gemini-3.6-flash
|
|
475
|
+
|
|
476
|
+
| id | resolutions | aspect | input | served by |
|
|
477
|
+
|---|---|---|---|---|
|
|
478
|
+
| `gemini-3.6-flash` | — | — | image_optional | google |
|
|
479
|
+
|
|
480
|
+
### gemini-3.7-flash
|
|
481
|
+
|
|
482
|
+
| id | resolutions | aspect | input | served by |
|
|
483
|
+
|---|---|---|---|---|
|
|
484
|
+
| `gemini-3.7-flash` | — | — | image_optional | google |
|
|
485
|
+
|
|
486
|
+
### gpt-5.6-luna
|
|
487
|
+
|
|
488
|
+
| id | resolutions | aspect | input | served by |
|
|
489
|
+
|---|---|---|---|---|
|
|
490
|
+
| `gpt-5.6-luna` | — | — | image_optional | openai |
|
|
491
|
+
|
|
492
|
+
### gpt-5.6-sol
|
|
493
|
+
|
|
494
|
+
| id | resolutions | aspect | input | served by |
|
|
495
|
+
|---|---|---|---|---|
|
|
496
|
+
| `gpt-5.6-sol` | — | — | image_optional | openai |
|
|
497
|
+
|
|
498
|
+
### gpt-5.6-terra
|
|
499
|
+
|
|
500
|
+
| id | resolutions | aspect | input | served by |
|
|
501
|
+
|---|---|---|---|---|
|
|
502
|
+
| `gpt-5.6-terra` | — | — | image_optional | openai |
|
|
351
503
|
|
|
352
504
|
### qwen-max
|
|
353
505
|
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,13 +1,47 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Zorbi-Tech/brotu-sdk/main/docs/assets/logo.svg">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/Zorbi-Tech/brotu-sdk/main/docs/assets/logo-black.svg" alt="Brotu" width="280">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
8
|
+
<p align="center">
|
|
9
|
+
<strong>One TypeScript client for video, image, speech, text and vendor extras.</strong><br>
|
|
10
|
+
You bring the keys. Each call hits the vendor's own API.
|
|
11
|
+
</p>
|
|
5
12
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://www.npmjs.com/package/@brotu/ai"><img alt="npm version" src="https://img.shields.io/npm/v/@brotu/ai?color=ef5e28"></a>
|
|
15
|
+
<a href="https://www.npmjs.com/package/@brotu/ai"><img alt="npm downloads" src="https://img.shields.io/npm/dm/@brotu/ai?color=ef5e28&label=downloads"></a>
|
|
16
|
+
<a href="https://www.npmjs.com/package/@brotu/ai"><img alt="npm totals" src="https://img.shields.io/npm/dt/@brotu/ai?color=111&label=total"></a>
|
|
17
|
+
<a href="https://github.com/Zorbi-Tech/brotu-sdk/blob/main/LICENSE"><img alt="MIT" src="https://img.shields.io/npm/l/@brotu/ai?color=111"></a>
|
|
18
|
+
</p>
|
|
9
19
|
|
|
10
|
-
|
|
20
|
+
<p align="center">
|
|
21
|
+
Built by <a href="https://x.com/andersonbrdev">@andersonbrdev</a>
|
|
22
|
+
·
|
|
23
|
+
<a href="https://x.com/brotuApp">@brotuApp</a>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
Kling, Seedance, Wan, Veo, Gemini, gpt-image and ElevenLabs all speak different HTTP. This package is one `brotuClient` in front of them. No proxy.
|
|
27
|
+
|
|
28
|
+
97 models: 37 video, 29 image, 12 speech, 19 text. Full table in [CATALOG.md](./CATALOG.md). That file is generated from the catalog, so it cannot drift from what the code supports.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bun add @brotu/ai
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm i @brotu/ai
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pnpm add @brotu/ai
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Client
|
|
11
45
|
|
|
12
46
|
```ts
|
|
13
47
|
import { brotuClient } from "@brotu/ai";
|
|
@@ -15,9 +49,37 @@ import { brotuClient } from "@brotu/ai";
|
|
|
15
49
|
const ai = brotuClient({
|
|
16
50
|
providers: {
|
|
17
51
|
kling: { apiKey: process.env.KLING_API_KEY! },
|
|
52
|
+
byteplus: { apiKey: process.env.ARK_API_KEY! },
|
|
53
|
+
google: { apiKey: process.env.GEMINI_API_KEY! },
|
|
54
|
+
openai: { apiKey: process.env.OPENAI_API_KEY! },
|
|
55
|
+
qwen: { apiKey: process.env.QWEN_API_KEY! },
|
|
56
|
+
elevenlabs: { apiKey: process.env.ELEVENLABS_API_KEY! },
|
|
18
57
|
},
|
|
19
58
|
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Only configured providers appear in `ai.models()`.
|
|
62
|
+
|
|
63
|
+
Every public call returns `{ data, error }`. `data` is unusable until you narrow on `error`.
|
|
64
|
+
|
|
65
|
+
| Surface | Methods |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `ai.video` | `submit` / `generate` |
|
|
68
|
+
| `ai.image` | `submit` / `generate` |
|
|
69
|
+
| `ai.text` | `submit` / `generate` |
|
|
70
|
+
| `ai.audio` | `submit` / `generate` |
|
|
71
|
+
| `ai.jobs` | `poll` / `wait` |
|
|
72
|
+
| `ai.estimateCost` | units, and USD when verified |
|
|
73
|
+
| `ai.kling` | `motionControl`, `omniVideo`, `avatar`, `outpainting`, `imageOmni` |
|
|
74
|
+
| `ai.google` | `omniVideo` (conversational refine) |
|
|
75
|
+
|
|
76
|
+
`ai.kling` and `ai.google` exist only when that key is set.
|
|
77
|
+
|
|
78
|
+
## Video
|
|
79
|
+
|
|
80
|
+
`submit` returns a job handle. `generate` waits. Video takes minutes, so do not `generate` inside a request handler.
|
|
20
81
|
|
|
82
|
+
```ts
|
|
21
83
|
const { data: job, error } = await ai.video.submit({
|
|
22
84
|
model: "kling/v2-6",
|
|
23
85
|
prompt: "a cat wearing sunglasses, cinematic",
|
|
@@ -26,69 +88,161 @@ const { data: job, error } = await ai.video.submit({
|
|
|
26
88
|
});
|
|
27
89
|
|
|
28
90
|
if (error) return console.error(error.code, error.message);
|
|
29
|
-
await db.jobs.insert(job);
|
|
91
|
+
await db.jobs.insert(job);
|
|
92
|
+
|
|
93
|
+
const { data } = await ai.jobs.wait(job);
|
|
94
|
+
data.outputs[0].url;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Image-to-video is the same shape with `imageUrl`.
|
|
98
|
+
|
|
99
|
+
## Image
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
const { data, error } = await ai.image.generate({
|
|
103
|
+
model: "gpt-image-2",
|
|
104
|
+
prompt: "a ginger cat on a windowsill, soft light",
|
|
105
|
+
quality: "medium",
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
OpenAI and Gemini return a data URI. Give the client `storage` if you want a real URL.
|
|
110
|
+
|
|
111
|
+
## Text
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
const { data, error } = await ai.text.generate({
|
|
115
|
+
model: "gpt-5.6-luna",
|
|
116
|
+
prompt: "summarize this in two sentences",
|
|
117
|
+
systemPrompt: "be brief",
|
|
118
|
+
maxTokens: 200,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
data?.outputs[0].raw?.text;
|
|
30
122
|
```
|
|
31
123
|
|
|
32
|
-
|
|
124
|
+
OpenAI: `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` on the Responses API.
|
|
125
|
+
Gemini: `gemini-3.7-flash` and the current ladder on the Interactions API.
|
|
126
|
+
Qwen: `qwen3.8-max`, `qwen-plus`, `qwen-turbo`, and the rest.
|
|
33
127
|
|
|
34
|
-
|
|
35
|
-
|
|
128
|
+
Pass `referenceImages` for vision. The output is `data:text/plain` plus `raw.text`. Token totals are only known after the call, so `estimateCost` reports the rate and leaves `usd` null.
|
|
129
|
+
|
|
130
|
+
## Audio
|
|
131
|
+
|
|
132
|
+
`prompt` is the spoken text.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
const { data, error } = await ai.audio.generate({
|
|
136
|
+
model: "gemini-3.1-flash-tts-preview",
|
|
137
|
+
prompt: "Say cheerfully: good morning",
|
|
138
|
+
voice: "Puck",
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Gemini TTS: 30 official voices, default `Kore`.
|
|
143
|
+
Qwen: `Cherry`, `Ethan`, and the rest on `qwen3-tts-flash`.
|
|
144
|
+
ElevenLabs: you must pass `voice`. There is no default.
|
|
145
|
+
|
|
146
|
+
Realtime / Live WebSocket models are not on this surface.
|
|
147
|
+
|
|
148
|
+
## Jobs
|
|
36
149
|
|
|
37
150
|
```ts
|
|
38
|
-
const { data
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
151
|
+
const { data: snapshot } = await ai.jobs.poll(job);
|
|
152
|
+
const { data: result } = await ai.jobs.wait(job, { timeoutMs: 420_000 });
|
|
153
|
+
|
|
154
|
+
if (result === undefined && snapshot?.status === "pending") {
|
|
155
|
+
// still running
|
|
42
156
|
}
|
|
43
|
-
data.outputs[0].url;
|
|
44
157
|
```
|
|
45
158
|
|
|
46
|
-
Error codes: `unknown_model`, `missing_key`, `unsupported_provider`,
|
|
47
|
-
`invalid_request`, `provider_error`, `timeout`.
|
|
159
|
+
Error codes: `unknown_model`, `missing_key`, `unsupported_provider`, `invalid_request`, `provider_error`, `timeout`.
|
|
48
160
|
|
|
49
|
-
##
|
|
161
|
+
## Motion control, avatars, omni
|
|
50
162
|
|
|
51
|
-
|
|
52
|
-
handle is plain JSON: store it, and any later process can pick it up.
|
|
163
|
+
Not on `ai.video`. A shared signature would be a lie.
|
|
53
164
|
|
|
54
165
|
```ts
|
|
55
|
-
|
|
166
|
+
if (!ai.kling) throw new Error("needs a kling key");
|
|
167
|
+
|
|
168
|
+
const { data: motion } = await ai.kling.motionControl({
|
|
169
|
+
model: "kling-2.6",
|
|
170
|
+
imageUrl: "https://example.com/character.png",
|
|
171
|
+
videoUrl: "https://example.com/dance.mp4",
|
|
172
|
+
characterOrientation: "video",
|
|
173
|
+
resolution: "1080p",
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const { data: talking } = await ai.kling.avatar({
|
|
177
|
+
imageUrl: "https://example.com/portrait.png",
|
|
178
|
+
soundFileUrl: "https://example.com/voice.mp3",
|
|
179
|
+
prompt: "warm, speaking to camera",
|
|
180
|
+
mode: "pro",
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const { data: omni } = await ai.kling.omniVideo({
|
|
184
|
+
model: "kling-3.0-omni",
|
|
185
|
+
prompt: "@hero walks through @backdrop",
|
|
186
|
+
references: [
|
|
187
|
+
{ type: "refer_image", url: "https://example.com/hero.png", id: "hero" },
|
|
188
|
+
{ type: "refer_image", url: "https://example.com/street.png", id: "backdrop" },
|
|
189
|
+
],
|
|
190
|
+
duration: 10,
|
|
191
|
+
aspectRatio: "9:16",
|
|
192
|
+
});
|
|
56
193
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
194
|
+
await ai.kling.outpainting({
|
|
195
|
+
imageUrl: "https://example.com/square.png",
|
|
196
|
+
up: 0,
|
|
197
|
+
down: 0,
|
|
198
|
+
left: 0.5,
|
|
199
|
+
right: 0.5,
|
|
200
|
+
prompt: "continue the street",
|
|
201
|
+
});
|
|
60
202
|
```
|
|
61
203
|
|
|
62
|
-
|
|
63
|
-
|
|
204
|
+
Google Omni is the one model you refine by talking to the previous result:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
if (!ai.google) throw new Error("needs a google key");
|
|
208
|
+
|
|
209
|
+
const first = await ai.google.omniVideo({
|
|
210
|
+
model: "gemini-omni-flash-preview",
|
|
211
|
+
prompt: "a cat walks through rain at night",
|
|
212
|
+
});
|
|
64
213
|
|
|
65
|
-
|
|
214
|
+
await ai.google.omniVideo({
|
|
215
|
+
model: "gemini-omni-flash-preview",
|
|
216
|
+
prompt: "make it dawn, keep the camera",
|
|
217
|
+
previousInteractionId: first.data?.interactionId,
|
|
218
|
+
});
|
|
219
|
+
```
|
|
66
220
|
|
|
67
|
-
|
|
68
|
-
copied into it, with `data.outputs[].url` pointing at your copy and the original
|
|
69
|
-
kept in `sourceUrl`.
|
|
221
|
+
## Cost and storage
|
|
70
222
|
|
|
71
223
|
```ts
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
accessKeyId: process.env.S3_KEY!,
|
|
78
|
-
secretAccessKey: process.env.S3_SECRET!,
|
|
79
|
-
endpoint: "https://….r2.cloudflarestorage.com", // R2, MinIO, any S3 API
|
|
80
|
-
publicUrl: "https://cdn.example.com", // set it, and nothing is signed
|
|
81
|
-
},
|
|
224
|
+
const { data } = await ai.estimateCost("video", {
|
|
225
|
+
model: "kling/v3",
|
|
226
|
+
prompt: "x",
|
|
227
|
+
duration: 5,
|
|
228
|
+
resolution: "720p",
|
|
82
229
|
});
|
|
83
230
|
```
|
|
84
231
|
|
|
85
|
-
|
|
86
|
-
whole generation. `@aws-sdk/client-s3` is an optional peer dependency, loaded
|
|
87
|
-
only when you configure storage.
|
|
232
|
+
Provider URLs expire. Pass `storage` (any S3 API) and outputs land in your bucket. `outputs[].url` is your copy; `sourceUrl` is the original. `@aws-sdk/client-s3` is an optional peer.
|
|
88
233
|
|
|
89
|
-
|
|
234
|
+
```ts
|
|
235
|
+
storage: {
|
|
236
|
+
bucket: "my-bucket",
|
|
237
|
+
region: "us-east-2",
|
|
238
|
+
accessKeyId: process.env.S3_KEY!,
|
|
239
|
+
secretAccessKey: process.env.S3_SECRET!,
|
|
240
|
+
endpoint: "https://....r2.cloudflarestorage.com",
|
|
241
|
+
publicUrl: "https://cdn.example.com",
|
|
242
|
+
}
|
|
243
|
+
```
|
|
90
244
|
|
|
91
|
-
|
|
245
|
+
## Regions and extra models
|
|
92
246
|
|
|
93
247
|
```ts
|
|
94
248
|
providers: {
|
|
@@ -96,20 +250,10 @@ providers: {
|
|
|
96
250
|
}
|
|
97
251
|
```
|
|
98
252
|
|
|
99
|
-
## Adding a model
|
|
100
|
-
|
|
101
|
-
Models are data. Register your own, or patch a built-in one:
|
|
102
|
-
|
|
103
253
|
```ts
|
|
104
254
|
import { registerModels } from "@brotu/ai";
|
|
105
255
|
|
|
106
|
-
registerModels([
|
|
107
|
-
{ id: "kling/v3", provider: "kling", /* … */ },
|
|
108
|
-
]);
|
|
256
|
+
registerModels([{ id: "kling/v3", provider: "kling" /* ... */ }]);
|
|
109
257
|
```
|
|
110
258
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Credits, quotas, accounts and job persistence are product concerns, not client
|
|
114
|
-
concerns. Metering belongs on a server, where it can be trusted — not in an SDK
|
|
115
|
-
running on the caller's machine.
|
|
259
|
+
Credits, quotas, accounts and job persistence stay on your server. This package maps params, polls if needed, and hands back URLs.
|
|
@@ -39,8 +39,10 @@ export declare class GoogleAdapter implements ContentGeneratorPort {
|
|
|
39
39
|
/** Resume a Veo operation submitted earlier, possibly by another process. */
|
|
40
40
|
completeJob(job: Job): Promise<JobSnapshot>;
|
|
41
41
|
generateVideo(params: VideoGenerationParams): Promise<GenerationResult>;
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
private textBody;
|
|
43
|
+
private speechBody;
|
|
44
|
+
generateText(params: TextGenerationParams): Promise<GenerationResult>;
|
|
45
|
+
generateAudio(params: AudioGenerationParams): Promise<GenerationResult>;
|
|
44
46
|
estimateCost(type: GenerationType, params: GenerationParams): Promise<CostEstimate>;
|
|
45
47
|
supportsModel(model: string): boolean;
|
|
46
48
|
getAvailableModels(): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/google.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,GAAG,EACR,KAAK,WAAW,EAEhB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EAEjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"google.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/google.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,GAAG,EACR,KAAK,WAAW,EAEhB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EAEjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,MAAM,iCAAiC,CAAC;AAUzC,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAqCD;;;;;;;GAOG;AACH,qBAAa,aAAc,YAAW,oBAAoB;IACzD,QAAQ,CAAC,YAAY,YAAY;IACjC,QAAQ,CAAC,cAAc,EAAE,cAAc,EAAE,CAKvC;IAEF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAE5C,YAAY,IAAI,EAAE,oBAAoB,EAErC;IAED,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,KAAK,OAAO,GAKlB;YAEa,OAAO;IAwBf,aAAa,CAClB,MAAM,EAAE,qBAAqB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAyF3B;IAID,OAAO,CAAC,OAAO;IAoCf;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAoDhB,4EAA4E;IACtE,SAAS,CACd,MAAM,EAAE,qBAAqB,GAAG;QAAE,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAAE,GAChE,OAAO,CAAC;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,gBAAgB,EAAE,CAAA;KAAE,CAAC,CAkClE;YAEa,QAAQ;IA4FtB,6EAA6E;IACvE,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CA+ChD;IAED,aAAa,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEtE;IAED,OAAO,CAAC,QAAQ;IA+BhB,OAAO,CAAC,UAAU;IAgBZ,YAAY,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsD1E;IAEK,aAAa,CAClB,MAAM,EAAE,qBAAqB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAyD3B;IAEK,YAAY,CACjB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,GACtB,OAAO,CAAC,YAAY,CAAC,CAEvB;IAED,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAOpC;IAED,kBAAkB;;;cAKE,cAAc;QAkBjC;CACD"}
|
|
@@ -26,7 +26,8 @@ export declare class OpenAIAdapter implements ContentGeneratorPort {
|
|
|
26
26
|
generateImage(params: ImageGenerationParams): Promise<GenerationResult>;
|
|
27
27
|
generateVideo(_params: VideoGenerationParams): Promise<GenerationResult>;
|
|
28
28
|
generateAudio(_params: AudioGenerationParams): Promise<GenerationResult>;
|
|
29
|
-
|
|
29
|
+
private textBody;
|
|
30
|
+
generateText(params: TextGenerationParams): Promise<GenerationResult>;
|
|
30
31
|
/** Synchronous provider: there is never a queued job to come back to. */
|
|
31
32
|
completeJob(job: Job): Promise<JobSnapshot>;
|
|
32
33
|
estimateCost(type: GenerationType, params: GenerationParams): Promise<CostEstimate>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EACX,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EAEZ,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"openai.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EACX,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EAEZ,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,MAAM,iCAAiC,CAAC;AAQzC,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAUD;;;;;;;;GAQG;AACH,qBAAa,aAAc,YAAW,oBAAoB;IACzD,QAAQ,CAAC,YAAY,YAAY;IAEjC,QAAQ,CAAC,cAAc,EAAE,cAAc,EAAE,CAAqB;IAE9D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAE5C,YAAY,IAAI,EAAE,oBAAoB,EAErC;IAED,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,SAAS;IA6CX,aAAa,CAClB,MAAM,EAAE,qBAAqB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAmE3B;IAED,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAIvE;IAED,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEvE;IAED,OAAO,CAAC,QAAQ;IA6BV,YAAY,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuE1E;IAED,yEAAyE;IACnE,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAKhD;IAEK,YAAY,CACjB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,GACtB,OAAO,CAAC,YAAY,CAAC,CAgBvB;IAED,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpC;IAED,kBAAkB;;;cAKE,cAAc;QAQjC;CACD"}
|