egaki 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/README.md +17 -5
- package/dist/cli.js +12 -4
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +5 -0
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +70 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +47 -7
- package/dist/video-model-catalog.d.ts.map +1 -1
- package/dist/video-model-catalog.js +61 -0
- package/package.json +3 -1
- package/skills/egaki/SKILL.md +100 -0
- package/src/cli.ts +13 -4
- package/src/credentials.ts +5 -0
- package/src/model-catalog.ts +74 -0
- package/src/models.ts +48 -7
- package/src/video-model-catalog.ts +61 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,68 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.3.0
|
|
6
|
+
|
|
7
|
+
1. **Google Vertex AI provider** — use Google Cloud billing instead of AI Studio by
|
|
8
|
+
prefixing model IDs with `vertex/`:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
egaki login --provider vertex --key AIza...
|
|
12
|
+
egaki image "product shot on marble" -m vertex/imagen-4.0-generate-001 -o product.png
|
|
13
|
+
egaki image "editorial portrait" -m vertex/gemini-3.1-flash-image-preview --aspect-ratio 4:5
|
|
14
|
+
egaki video "storm over mountains" -m vertex/veo-3.1-fast-generate-001 --duration 6 -o storm.mp4
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Bare model IDs (e.g. `imagen-4.0-generate-001`) continue to route through Google AI
|
|
18
|
+
Studio as before. `vertex/` prefix routes through `@ai-sdk/google-vertex` using your
|
|
19
|
+
`GOOGLE_VERTEX_API_KEY`. The two providers are fully independent — having one key does
|
|
20
|
+
not affect the other.
|
|
21
|
+
|
|
22
|
+
Supported Vertex models:
|
|
23
|
+
- `vertex/imagen-4.0-generate-001`, `vertex/imagen-4.0-ultra-generate-001`, `vertex/imagen-4.0-fast-generate-001`
|
|
24
|
+
- `vertex/gemini-2.5-flash-image`, `vertex/gemini-3-pro-image-preview`, `vertex/gemini-3.1-flash-image-preview`
|
|
25
|
+
- `vertex/veo-3.1-generate-001`, `vertex/veo-3.1-fast-generate-001`
|
|
26
|
+
|
|
27
|
+
2. **`egaki models --provider vertex`** — list only Vertex models:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
egaki models --provider vertex
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
3. **Fixed confusing error for Vertex without a key** — if you attempt a `vertex/` model
|
|
34
|
+
without a `GOOGLE_VERTEX_API_KEY` configured, you now get a clear error pointing you
|
|
35
|
+
to set one up instead of a cryptic upstream failure.
|
|
36
|
+
|
|
37
|
+
## 0.2.0
|
|
38
|
+
|
|
39
|
+
1. **New `egaki video` command** — generate videos from text prompts or still images.
|
|
40
|
+
Full support for all AI Gateway video providers:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
egaki video "a paper boat drifting on a calm lake at sunrise" -o boat.mp4
|
|
44
|
+
egaki video "timelapse of a stormy sea" -m google/veo-3.1-generate-001 --duration 8 -o storm.mp4
|
|
45
|
+
egaki video "animate the clouds slowly" --input photo.jpg -m klingai/kling-v2.6-i2v -o animated.mp4
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Supported models: Google Veo 3.0/3.1, Kling v2.5/v2.6/v3.0, Bytedance Seedance,
|
|
49
|
+
Alibaba Wan, xAI Grok video.
|
|
50
|
+
|
|
51
|
+
2. **Full video options** — `--duration`, `--resolution`, `--aspect-ratio`, `--fps`,
|
|
52
|
+
`--seed`, `--count`, `--input` (image-to-video), `--stdout`, `--json`.
|
|
53
|
+
|
|
54
|
+
3. **`egaki models --type` filter** — filter model listing by modality:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
egaki models --type video
|
|
58
|
+
egaki models --type image
|
|
59
|
+
egaki models --type all # default
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Video models show duration range, capabilities (t2v, i2v, r2v), and resolution tiers.
|
|
63
|
+
|
|
64
|
+
4. **Egaki subscription covers video** — all gateway video models work with your
|
|
65
|
+
`egaki_...` key; usage is billed per-second based on model, resolution, and duration.
|
|
66
|
+
|
|
5
67
|
## 0.1.0
|
|
6
68
|
|
|
7
69
|
1. **New `egaki video` command** — generate videos from text prompts using AI models
|
package/README.md
CHANGED
|
@@ -55,6 +55,14 @@ egaki image "cyberpunk alley at night" --aspect-ratio 16:9
|
|
|
55
55
|
egaki image "polaroid-style travel photo" --aspect-ratio 4:5
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
### Use Google Cloud billing via Vertex AI
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
egaki login --provider vertex --key AIza...
|
|
62
|
+
egaki image "editorial sneaker photo on white seamless" -m vertex/imagen-4.0-generate-001 -o sneaker.png
|
|
63
|
+
egaki video "storm over mountains" -m vertex/veo-3.1-fast-generate-001 --duration 6 -o storm.mp4
|
|
64
|
+
```
|
|
65
|
+
|
|
58
66
|
### Pipe image output to other tools
|
|
59
67
|
|
|
60
68
|
```bash
|
|
@@ -67,7 +75,7 @@ egaki image "flat icon of a fox" --stdout | magick - -resize 512x512 fox-icon.pn
|
|
|
67
75
|
|
|
68
76
|
```bash
|
|
69
77
|
egaki video "a paper boat drifting on a calm lake at sunrise" -o boat.mp4
|
|
70
|
-
egaki video "timelapse of a stormy sea, cinematic" -m
|
|
78
|
+
egaki video "timelapse of a stormy sea, cinematic" -m veo-3.1-generate-001 --duration 8 -o storm.mp4
|
|
71
79
|
```
|
|
72
80
|
|
|
73
81
|
### Generate with a cheap model
|
|
@@ -88,7 +96,7 @@ egaki video "slowly animate the clouds" --input photo.jpg -m klingai/kling-v2.6-
|
|
|
88
96
|
|
|
89
97
|
```bash
|
|
90
98
|
egaki video "aerial drone shot over a city grid" \
|
|
91
|
-
-m
|
|
99
|
+
-m veo-3.1-fast-generate-001 \
|
|
92
100
|
--aspect-ratio 16:9 \
|
|
93
101
|
--resolution 1080p \
|
|
94
102
|
--duration 6 \
|
|
@@ -175,8 +183,9 @@ egaki image "mascot variations, flat vector look" \
|
|
|
175
183
|
|
|
176
184
|
| Model ID | Best for | Example command |
|
|
177
185
|
| --- | --- | --- |
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
186
|
+
| `veo-3.1-generate-001` | Highest quality video with audio, up to 4K | `egaki video "rainy Tokyo street at night" -m veo-3.1-generate-001 --duration 8 -o tokyo.mp4` |
|
|
187
|
+
| `veo-3.1-fast-generate-001` | Fast Veo with 720p–4K, good for iteration | `egaki video "abstract paint patterns" -m veo-3.1-fast-generate-001 --duration 5 -o paint.mp4` |
|
|
188
|
+
| `vertex/veo-3.1-generate-001` | Same as above, routed through Vertex AI | `egaki video "rainy Tokyo street" -m vertex/veo-3.1-generate-001 --duration 8 -o tokyo.mp4` |
|
|
180
189
|
| `klingai/kling-v2.5-turbo-t2v` | Cheap, fast Kling text-to-video | `egaki video "a paper boat on a pond" -m klingai/kling-v2.5-turbo-t2v --duration 5 -o boat.mp4` |
|
|
181
190
|
| `bytedance/seedance-v1.5-pro` | Bytedance, audio support, three resolutions | `egaki video "timelapse of clouds above mountains" -m bytedance/seedance-v1.5-pro -o clouds.mp4` |
|
|
182
191
|
| `xai/grok-imagine-video` | xAI video generation, cheap for short clips | `egaki video "a dog catching a frisbee" -m xai/grok-imagine-video --duration 3 -o dog.mp4` |
|
|
@@ -189,6 +198,7 @@ egaki image "mascot variations, flat vector look" \
|
|
|
189
198
|
- **BFL image models (`flux-*`)**: Kontext/Pro variants via AI Gateway subscription
|
|
190
199
|
- **Recraft models (`recraft-*`)**: v2/v3/v4 families available via AI Gateway subscription
|
|
191
200
|
- **xAI image models (`grok-imagine-*`)**: Grok image generation via AI Gateway subscription
|
|
201
|
+
- **Vertex models (`vertex/*`)**: same models as Google AI Studio, routed through Vertex AI / Google Cloud billing
|
|
192
202
|
- **Google Veo video models**: up to 4K, audio optional, duration 4–8s
|
|
193
203
|
- **Kling video models**: mode (std/pro), audio on v2.6+, image-to-video support
|
|
194
204
|
- **Bytedance Seedance**: 480p–1080p, audio support on v1.5-pro
|
|
@@ -200,6 +210,7 @@ egaki supports **both** authentication modes:
|
|
|
200
210
|
|
|
201
211
|
- **BYOK (bring your own keys):** add provider keys with `egaki login` per provider.
|
|
202
212
|
- **Egaki subscription:** use one `egaki_...` key to access all supported models without managing keys for each provider.
|
|
213
|
+
- **Google vs Vertex:** bare model IDs (e.g. `imagen-4.0-generate-001`) use Google AI Studio. Prefix with `vertex/` (e.g. `vertex/imagen-4.0-generate-001`) to route through Vertex AI / Google Cloud billing.
|
|
203
214
|
|
|
204
215
|
```bash
|
|
205
216
|
# Subscribe and get a checkout URL
|
|
@@ -211,8 +222,9 @@ egaki subscribe --plan pro
|
|
|
211
222
|
# Save your Egaki key after checkout
|
|
212
223
|
egaki login --provider egaki --key egaki_...
|
|
213
224
|
|
|
214
|
-
# BYOK
|
|
225
|
+
# BYOK examples (direct provider keys)
|
|
215
226
|
egaki login --provider google --key AIza...
|
|
227
|
+
egaki login --provider vertex --key AIza...
|
|
216
228
|
|
|
217
229
|
# Check subscription usage / cancel
|
|
218
230
|
egaki usage
|
package/dist/cli.js
CHANGED
|
@@ -55,6 +55,7 @@ cli
|
|
|
55
55
|
.example('egaki login')
|
|
56
56
|
.example('# Non-interactive login with flags')
|
|
57
57
|
.example('egaki login --provider google --key AIza...')
|
|
58
|
+
.example('egaki login --provider vertex --key AIza...')
|
|
58
59
|
.example('# Pipe key from stdin (useful in CI/scripts)')
|
|
59
60
|
.example('echo "AIza..." | egaki login --provider google')
|
|
60
61
|
.example('# Show configured providers')
|
|
@@ -170,6 +171,8 @@ cli
|
|
|
170
171
|
.example('egaki image "fill with flowers" --input photo.jpg --mask mask.png')
|
|
171
172
|
.example('# Generate with Gemini multimodal at 4K')
|
|
172
173
|
.example('egaki image "dreamy landscape" -m gemini-2.5-flash-image --image-size 4K')
|
|
174
|
+
.example('# Route through Vertex AI (Google Cloud billing)')
|
|
175
|
+
.example('egaki image "product photo on marble" -m vertex/imagen-4.0-generate-001')
|
|
173
176
|
.example('# Generate multiple images')
|
|
174
177
|
.example('egaki image "abstract art" -n 4 -o art.png')
|
|
175
178
|
.example('# Pipe to another tool')
|
|
@@ -250,6 +253,8 @@ cli
|
|
|
250
253
|
.example('egaki video "A paper airplane gliding through clouds" -o airplane.mp4')
|
|
251
254
|
.example('# Generate with Veo model + duration')
|
|
252
255
|
.example('egaki video "cinematic rainy street at night" -m veo-3.1-fast-generate-001 --duration 6')
|
|
256
|
+
.example('# Route through Vertex AI (Google Cloud billing)')
|
|
257
|
+
.example('egaki video "storm over mountains" -m vertex/veo-3.1-fast-generate-001 --duration 6')
|
|
253
258
|
.example('# Image-to-video (model support required)')
|
|
254
259
|
.example('egaki video "animate subtle camera pan" --model luma-ray-2 --input frame.png -o animated.mp4')
|
|
255
260
|
.example('# Generate multiple videos')
|
|
@@ -385,7 +390,10 @@ async function generateWithImageModel({ prompt, model, outputPath, count, aspect
|
|
|
385
390
|
const imagePrompt = inputImages.length > 0
|
|
386
391
|
? { text: prompt, images: inputImages, ...(maskImage ? { mask: maskImage } : {}) }
|
|
387
392
|
: prompt;
|
|
393
|
+
const config = getModelConfig(model);
|
|
388
394
|
const imageModel = await createImageModel(model);
|
|
395
|
+
// Use the correct providerOptions key based on provider (google vs vertex)
|
|
396
|
+
const providerOptionsKey = config.provider === 'vertex' ? 'vertex' : 'google';
|
|
389
397
|
if (!stdout) {
|
|
390
398
|
console.error(pc.cyan('Generating...'));
|
|
391
399
|
}
|
|
@@ -396,7 +404,7 @@ async function generateWithImageModel({ prompt, model, outputPath, count, aspect
|
|
|
396
404
|
...(aspectRatio ? { aspectRatio } : {}),
|
|
397
405
|
...(seed !== undefined ? { seed } : {}),
|
|
398
406
|
providerOptions: {
|
|
399
|
-
|
|
407
|
+
[providerOptionsKey]: {
|
|
400
408
|
...(allowPeople ? { personGeneration: 'allow_all' } : {}),
|
|
401
409
|
...(aspectRatio ? { aspectRatio } : {}),
|
|
402
410
|
},
|
|
@@ -421,7 +429,6 @@ async function generateWithImageModel({ prompt, model, outputPath, count, aspect
|
|
|
421
429
|
console.error(pc.green(`Saved: ${filePath}`));
|
|
422
430
|
savedFiles.push(filePath);
|
|
423
431
|
}
|
|
424
|
-
const config = getModelConfig(model);
|
|
425
432
|
const cost = calculateCost(config.cost, result.usage, result.images.length);
|
|
426
433
|
if (cost != null) {
|
|
427
434
|
console.error(pc.dim(`Cost: ${formatCost(cost)}`));
|
|
@@ -441,6 +448,8 @@ async function generateWithImageModel({ prompt, model, outputPath, count, aspect
|
|
|
441
448
|
// Generate using generateText with responseModalities (Gemini multimodal models)
|
|
442
449
|
async function generateWithTextModel({ prompt, model, outputPath, inputImages, imageSize, aspectRatio, json, stdout, }) {
|
|
443
450
|
const textModel = await createTextModel(model);
|
|
451
|
+
const config = getModelConfig(model);
|
|
452
|
+
const providerOptionsKey = config.provider === 'vertex' ? 'vertex' : 'google';
|
|
444
453
|
if (!stdout) {
|
|
445
454
|
console.error(pc.cyan('Generating...'));
|
|
446
455
|
}
|
|
@@ -463,7 +472,7 @@ async function generateWithTextModel({ prompt, model, outputPath, inputImages, i
|
|
|
463
472
|
model: textModel,
|
|
464
473
|
...(messages ? { messages } : { prompt }),
|
|
465
474
|
providerOptions: {
|
|
466
|
-
|
|
475
|
+
[providerOptionsKey]: {
|
|
467
476
|
responseModalities: ['TEXT', 'IMAGE'],
|
|
468
477
|
...(imageSize || aspectRatio
|
|
469
478
|
? {
|
|
@@ -501,7 +510,6 @@ async function generateWithTextModel({ prompt, model, outputPath, inputImages, i
|
|
|
501
510
|
console.error(pc.green(`Saved: ${filePath}`));
|
|
502
511
|
savedFiles.push(filePath);
|
|
503
512
|
}
|
|
504
|
-
const config = getModelConfig(model);
|
|
505
513
|
const cost = calculateCost(config.cost, result.usage, imageFiles.length);
|
|
506
514
|
if (cost != null) {
|
|
507
515
|
console.error(pc.dim(`Cost: ${formatCost(cost)}`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,SAAS,EAAE,MAAM,CAC5B,MAAM,EACN;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,SAAS,EAAE,MAAM,CAC5B,MAAM,EACN;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAgChD,CAAA;AAED,eAAO,MAAM,iBAAiB,4BAA4B,CAAA;AAa1D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAEhD,wBAAgB,eAAe,IAAI,WAAW,CAO7C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAOzD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAInE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIxD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGnE;AAKD,wBAAgB,sBAAsB,IAAI,IAAI,CAW7C;AAID,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG;IAC9C,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;CAClC,CAaA"}
|
package/dist/credentials.js
CHANGED
|
@@ -18,6 +18,11 @@ export const PROVIDERS = {
|
|
|
18
18
|
label: 'Google AI (Gemini, Imagen)',
|
|
19
19
|
hint: 'Get your key at https://aistudio.google.com/apikey',
|
|
20
20
|
},
|
|
21
|
+
vertex: {
|
|
22
|
+
envVar: 'GOOGLE_VERTEX_API_KEY',
|
|
23
|
+
label: 'Google Vertex AI (Gemini, Imagen, Veo via Google Cloud)',
|
|
24
|
+
hint: 'Get an API key at https://console.cloud.google.com/apis/credentials',
|
|
25
|
+
},
|
|
21
26
|
openai: {
|
|
22
27
|
envVar: 'OPENAI_API_KEY',
|
|
23
28
|
label: 'OpenAI (DALL-E)',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../src/model-catalog.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,CAAA;IACjB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,CAAA;IACjB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,YAAY,CAAA;AAEnD,MAAM,MAAM,aAAa,GAAG;IAC1B,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB,mCAAmC;IACnC,UAAU,EAAE,OAAO,CAAA;IACnB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAA;IACb,uCAAuC;IACvC,cAAc,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,EAAE,aAAa,CAAA;CACxB,CAAA;AA+
|
|
1
|
+
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../src/model-catalog.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,CAAA;IACjB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,CAAA;IACjB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,YAAY,CAAA;AAEnD,MAAM,MAAM,aAAa,GAAG;IAC1B,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB,mCAAmC;IACnC,UAAU,EAAE,OAAO,CAAA;IACnB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAA;IACb,uCAAuC;IACvC,cAAc,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAA;IAC1B,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,EAAE,aAAa,CAAA;CACxB,CAAA;AA+ED,eAAO,MAAM,OAAO,EAAE,UAAU,EAs4B/B,CAAA;AAMD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE5D"}
|
package/dist/model-catalog.js
CHANGED
|
@@ -53,6 +53,20 @@ const xaiImage = {
|
|
|
53
53
|
provider: 'xai',
|
|
54
54
|
strategy: 'image',
|
|
55
55
|
};
|
|
56
|
+
const vertexImagen = {
|
|
57
|
+
provider: 'vertex',
|
|
58
|
+
strategy: 'image',
|
|
59
|
+
features: {
|
|
60
|
+
...googleImagen.features,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
const vertexText = {
|
|
64
|
+
provider: 'vertex',
|
|
65
|
+
strategy: 'text',
|
|
66
|
+
features: {
|
|
67
|
+
...googleText.features,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
56
70
|
const fluxAspectRatios = ['1:1', '3:4', '4:3', '9:16', '16:9', '9:21', '21:9'];
|
|
57
71
|
// ─── catalog ─────────────────────────────────────────────────────────────────
|
|
58
72
|
export const CATALOG = [
|
|
@@ -134,6 +148,62 @@ export const CATALOG = [
|
|
|
134
148
|
},
|
|
135
149
|
cost: { type: 'per-token', inputPerM: 0.5, outputPerM: 3.0 },
|
|
136
150
|
},
|
|
151
|
+
// ── Vertex: Imagen ──────────────────────────────────────────────────────
|
|
152
|
+
// Same models as Google AI Studio but routed through Vertex AI / Google Cloud billing.
|
|
153
|
+
// Use `egaki login --provider vertex --key <key>` to configure.
|
|
154
|
+
{
|
|
155
|
+
id: 'vertex/imagen-4.0-generate-001',
|
|
156
|
+
name: 'Imagen 4 (Vertex)',
|
|
157
|
+
released: '2025-08-15',
|
|
158
|
+
...vertexImagen,
|
|
159
|
+
cost: { type: 'per-image', perImage: 0.04 },
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: 'vertex/imagen-4.0-ultra-generate-001',
|
|
163
|
+
name: 'Imagen 4 Ultra (Vertex)',
|
|
164
|
+
released: '2025-08-15',
|
|
165
|
+
...vertexImagen,
|
|
166
|
+
cost: { type: 'per-image', perImage: 0.06 },
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: 'vertex/imagen-4.0-fast-generate-001',
|
|
170
|
+
name: 'Imagen 4 Fast (Vertex)',
|
|
171
|
+
released: '2025-08-15',
|
|
172
|
+
...vertexImagen,
|
|
173
|
+
cost: { type: 'per-image', perImage: 0.02 },
|
|
174
|
+
},
|
|
175
|
+
// ── Vertex: Gemini text+image ─────────────────────────────────────────
|
|
176
|
+
{
|
|
177
|
+
id: 'vertex/gemini-2.5-flash-image',
|
|
178
|
+
name: 'Gemini 2.5 Flash Image (Vertex)',
|
|
179
|
+
released: '2025-08-26',
|
|
180
|
+
...vertexText,
|
|
181
|
+
cost: { type: 'per-token', inputPerM: 0.3, outputPerM: 30 },
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: 'vertex/gemini-3-pro-image-preview',
|
|
185
|
+
name: 'Gemini 3 Pro Image (Vertex)',
|
|
186
|
+
released: '2025-11-20',
|
|
187
|
+
...vertexText,
|
|
188
|
+
cost: { type: 'per-token', inputPerM: 1.25, outputPerM: 10 },
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: 'vertex/gemini-3.1-flash-image-preview',
|
|
192
|
+
name: 'Gemini 3.1 Flash Image (Vertex)',
|
|
193
|
+
released: '2026-02-26',
|
|
194
|
+
...vertexText,
|
|
195
|
+
features: {
|
|
196
|
+
...vertexText.features,
|
|
197
|
+
aspectRatios: [
|
|
198
|
+
...vertexText.features.aspectRatios,
|
|
199
|
+
'4:1',
|
|
200
|
+
'1:4',
|
|
201
|
+
'8:1',
|
|
202
|
+
'1:8',
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
cost: { type: 'per-token', inputPerM: 0.5, outputPerM: 3.0 },
|
|
206
|
+
},
|
|
137
207
|
// ── BFL (AI Gateway) ───────────────────────────────────────────────────
|
|
138
208
|
{
|
|
139
209
|
id: 'flux-kontext-max',
|
package/dist/models.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AAInD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE/D,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,eAAe,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,CAAA;AAE3C,eAAO,MAAM,YAAY,EAA+B,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;AAC7E,eAAO,MAAM,YAAY,EAAqC,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AAInD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE/D,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,eAAe,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,CAAA;AAE3C,eAAO,MAAM,YAAY,EAA+B,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;AAC7E,eAAO,MAAM,YAAY,EAAqC,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;AAYnF,eAAO,MAAM,aAAa,4BAA4B,CAAA;AACtD,eAAO,MAAM,mBAAmB,8BAA8B,CAAA;AAE9D,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAO7D;AAuBD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAiD5D;AAqDD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAsC3E;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,CAAC,CAqCxB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAyCpE"}
|
package/dist/models.js
CHANGED
|
@@ -4,6 +4,16 @@ import { CATALOG, findModel } from './model-catalog.js';
|
|
|
4
4
|
import { VIDEO_CATALOG, findVideoModel } from './video-model-catalog.js';
|
|
5
5
|
export const IMAGE_MODELS = CATALOG.map((m) => m.id);
|
|
6
6
|
export const VIDEO_MODELS = VIDEO_CATALOG.map((m) => m.id);
|
|
7
|
+
/**
|
|
8
|
+
* Strip provider prefix from a model ID (e.g. "vertex/imagen-4.0-generate-001" → "imagen-4.0-generate-001").
|
|
9
|
+
* Provider SDKs expect bare model IDs, but the catalog uses prefixed IDs for routing.
|
|
10
|
+
*/
|
|
11
|
+
function stripProviderPrefix(modelId) {
|
|
12
|
+
const slash = modelId.indexOf('/');
|
|
13
|
+
if (slash === -1)
|
|
14
|
+
return modelId;
|
|
15
|
+
return modelId.slice(slash + 1);
|
|
16
|
+
}
|
|
7
17
|
export const DEFAULT_MODEL = 'nano-banana-pro-preview';
|
|
8
18
|
export const DEFAULT_VIDEO_MODEL = 'veo-3.1-fast-generate-001';
|
|
9
19
|
export function getModelConfig(modelId) {
|
|
@@ -39,6 +49,19 @@ export function ensureProviderKey(providerName) {
|
|
|
39
49
|
// If direct provider key exists, we're good
|
|
40
50
|
if (hasDirectProviderKey(providerName))
|
|
41
51
|
return;
|
|
52
|
+
// Vertex models require a direct key — the upstream Vercel AI Gateway
|
|
53
|
+
// does not support vertex/ routing, so egaki gateway can't proxy them.
|
|
54
|
+
if (providerName === 'vertex') {
|
|
55
|
+
console.error('');
|
|
56
|
+
console.error(pc.red(pc.bold('Vertex models require a direct Google Cloud API key')));
|
|
57
|
+
console.error('');
|
|
58
|
+
console.error(` ${pc.cyan('egaki login --provider vertex --key <key>')}`);
|
|
59
|
+
console.error('');
|
|
60
|
+
console.error(pc.dim('Get a key at https://console.cloud.google.com/apis/credentials'));
|
|
61
|
+
console.error(pc.dim('Egaki subscription does not cover Vertex routing yet.'));
|
|
62
|
+
console.error('');
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
42
65
|
// If egaki key exists, we'll route through the gateway
|
|
43
66
|
if (hasEgakiKey())
|
|
44
67
|
return;
|
|
@@ -72,8 +95,11 @@ async function createGatewayImageModel(modelId, provider) {
|
|
|
72
95
|
apiKey: process.env['EGAKI_API_KEY'],
|
|
73
96
|
baseURL: EGAKI_GATEWAY_URL,
|
|
74
97
|
});
|
|
75
|
-
// Gateway expects provider/model format for routing
|
|
76
|
-
|
|
98
|
+
// Gateway expects provider/model format for routing.
|
|
99
|
+
// For models that already have a prefix (e.g. vertex/imagen-4.0), strip it
|
|
100
|
+
// and use the catalog provider. For bare IDs, prepend the provider.
|
|
101
|
+
const bareId = stripProviderPrefix(modelId);
|
|
102
|
+
const gatewayModelId = `${provider}/${bareId}`;
|
|
77
103
|
return gateway.image(gatewayModelId);
|
|
78
104
|
}
|
|
79
105
|
/**
|
|
@@ -85,7 +111,8 @@ async function createGatewayTextModel(modelId, provider) {
|
|
|
85
111
|
apiKey: process.env['EGAKI_API_KEY'],
|
|
86
112
|
baseURL: EGAKI_GATEWAY_URL,
|
|
87
113
|
});
|
|
88
|
-
const
|
|
114
|
+
const bareId = stripProviderPrefix(modelId);
|
|
115
|
+
const gatewayModelId = `${provider}/${bareId}`;
|
|
89
116
|
return gateway(gatewayModelId);
|
|
90
117
|
}
|
|
91
118
|
/**
|
|
@@ -97,7 +124,8 @@ async function createGatewayVideoModel(modelId, provider) {
|
|
|
97
124
|
apiKey: process.env['EGAKI_API_KEY'],
|
|
98
125
|
baseURL: EGAKI_GATEWAY_URL,
|
|
99
126
|
});
|
|
100
|
-
const
|
|
127
|
+
const bareId = stripProviderPrefix(modelId);
|
|
128
|
+
const gatewayModelId = `${provider}/${bareId}`;
|
|
101
129
|
return gateway.video(gatewayModelId);
|
|
102
130
|
}
|
|
103
131
|
// Lazily import the provider and create the right model instance.
|
|
@@ -115,6 +143,10 @@ export async function createImageModel(modelId) {
|
|
|
115
143
|
const { google } = await import('@ai-sdk/google');
|
|
116
144
|
return google.image(modelId);
|
|
117
145
|
}
|
|
146
|
+
case 'vertex': {
|
|
147
|
+
const { vertex } = await import('@ai-sdk/google-vertex');
|
|
148
|
+
return vertex.image(stripProviderPrefix(modelId));
|
|
149
|
+
}
|
|
118
150
|
case 'openai': {
|
|
119
151
|
const { openai } = await import('@ai-sdk/openai');
|
|
120
152
|
return openai.image(modelId);
|
|
@@ -151,9 +183,13 @@ export async function createTextModel(modelId) {
|
|
|
151
183
|
const { google } = await import('@ai-sdk/google');
|
|
152
184
|
return google(modelId);
|
|
153
185
|
}
|
|
186
|
+
case 'vertex': {
|
|
187
|
+
const { vertex } = await import('@ai-sdk/google-vertex');
|
|
188
|
+
return vertex(stripProviderPrefix(modelId));
|
|
189
|
+
}
|
|
154
190
|
default:
|
|
155
|
-
// Only Google
|
|
156
|
-
console.error(pc.red(`Text+image generation is only supported for Google models, got provider: ${config.provider}`));
|
|
191
|
+
// Only Google/Vertex support generateText with responseModalities for images
|
|
192
|
+
console.error(pc.red(`Text+image generation is only supported for Google/Vertex models, got provider: ${config.provider}`));
|
|
157
193
|
process.exit(1);
|
|
158
194
|
}
|
|
159
195
|
}
|
|
@@ -178,12 +214,16 @@ export async function createVideoModel(modelId) {
|
|
|
178
214
|
const { google } = await import('@ai-sdk/google');
|
|
179
215
|
return google.video(modelId);
|
|
180
216
|
}
|
|
217
|
+
case 'vertex': {
|
|
218
|
+
const { vertex } = await import('@ai-sdk/google-vertex');
|
|
219
|
+
return vertex.video(stripProviderPrefix(modelId));
|
|
220
|
+
}
|
|
181
221
|
case 'fal': {
|
|
182
222
|
const { fal } = await import('@ai-sdk/fal');
|
|
183
223
|
return fal.video(modelId);
|
|
184
224
|
}
|
|
185
225
|
default:
|
|
186
|
-
console.error(pc.red(`Direct video generation is only supported for Google and Fal keys, got provider: ${config.provider}`));
|
|
226
|
+
console.error(pc.red(`Direct video generation is only supported for Google, Vertex, and Fal keys, got provider: ${config.provider}`));
|
|
187
227
|
process.exit(1);
|
|
188
228
|
}
|
|
189
229
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video-model-catalog.d.ts","sourceRoot":"","sources":["../src/video-model-catalog.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,wBAAwB,GAAG;IACrC,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAA;IACrB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mCAAmC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,kBAAkB,CAAA;IACxB,oEAAoE;IACpE,kBAAkB,EAAE,MAAM,CAAA;IAC1B,KAAK,EAAE,wBAAwB,EAAE,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,gBAAgB,CAAA;AAElE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+CAA+C;IAC/C,WAAW,EAAE,OAAO,CAAA;IACpB,8DAA8D;IAC9D,YAAY,EAAE,OAAO,CAAA;IACrB,gDAAgD;IAChD,YAAY,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,gBAAgB,GAAG,SAAS,CAAC,CAAA;IACzE,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,yCAAyC;IACzC,gBAAgB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/C,IAAI,EAAE,OAAO,CAAA;IACb,cAAc,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,cAAc,CAAA;IACpB,QAAQ,EAAE,kBAAkB,CAAA;CAC7B,CAAA;AAID,eAAO,MAAM,aAAa,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"video-model-catalog.d.ts","sourceRoot":"","sources":["../src/video-model-catalog.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,wBAAwB,GAAG;IACrC,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAA;IACrB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mCAAmC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,kBAAkB,CAAA;IACxB,oEAAoE;IACpE,kBAAkB,EAAE,MAAM,CAAA;IAC1B,KAAK,EAAE,wBAAwB,EAAE,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,gBAAgB,CAAA;AAElE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+CAA+C;IAC/C,WAAW,EAAE,OAAO,CAAA;IACpB,8DAA8D;IAC9D,YAAY,EAAE,OAAO,CAAA;IACrB,gDAAgD;IAChD,YAAY,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,gBAAgB,GAAG,SAAS,CAAC,CAAA;IACzE,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,yCAAyC;IACzC,gBAAgB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/C,IAAI,EAAE,OAAO,CAAA;IACb,cAAc,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,cAAc,CAAA;IACpB,QAAQ,EAAE,kBAAkB,CAAA;CAC7B,CAAA;AAID,eAAO,MAAM,aAAa,EAAE,eAAe,EA0S1C,CAAA;AAID,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEtE"}
|
|
@@ -115,6 +115,67 @@ export const VIDEO_CATALOG = [
|
|
|
115
115
|
multipleVideos: true,
|
|
116
116
|
},
|
|
117
117
|
},
|
|
118
|
+
// ── Vertex: Veo ──────────────────────────────────────────────────────
|
|
119
|
+
// Same Veo models routed through Vertex AI / Google Cloud billing.
|
|
120
|
+
// Use `egaki login --provider vertex --key <key>` to configure.
|
|
121
|
+
{
|
|
122
|
+
id: 'vertex/veo-3.1-generate-001',
|
|
123
|
+
name: 'Veo 3.1 (Vertex)',
|
|
124
|
+
provider: 'vertex',
|
|
125
|
+
strategy: 'video',
|
|
126
|
+
released: '2026-01',
|
|
127
|
+
cost: {
|
|
128
|
+
type: 'per-video-second',
|
|
129
|
+
defaultDurationSec: 8,
|
|
130
|
+
tiers: [
|
|
131
|
+
{ resolution: '720p', audio: false, costPerSecond: 0.2 },
|
|
132
|
+
{ resolution: '720p', audio: true, costPerSecond: 0.4 },
|
|
133
|
+
{ resolution: '1080p', audio: false, costPerSecond: 0.2 },
|
|
134
|
+
{ resolution: '1080p', audio: true, costPerSecond: 0.4 },
|
|
135
|
+
{ resolution: '4k', audio: false, costPerSecond: 0.4 },
|
|
136
|
+
{ resolution: '4k', audio: true, costPerSecond: 0.6 },
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
features: {
|
|
140
|
+
textToVideo: true,
|
|
141
|
+
imageToVideo: false,
|
|
142
|
+
capabilities: ['t2v'],
|
|
143
|
+
aspectRatios: ['16:9', '9:16'],
|
|
144
|
+
resolutions: ['720p', '1080p', '4k'],
|
|
145
|
+
durationRangeSec: { min: 4, max: 8 },
|
|
146
|
+
seed: true,
|
|
147
|
+
multipleVideos: true,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: 'vertex/veo-3.1-fast-generate-001',
|
|
152
|
+
name: 'Veo 3.1 Fast (Vertex)',
|
|
153
|
+
provider: 'vertex',
|
|
154
|
+
strategy: 'video',
|
|
155
|
+
released: '2026-01',
|
|
156
|
+
cost: {
|
|
157
|
+
type: 'per-video-second',
|
|
158
|
+
defaultDurationSec: 8,
|
|
159
|
+
tiers: [
|
|
160
|
+
{ resolution: '720p', audio: false, costPerSecond: 0.1 },
|
|
161
|
+
{ resolution: '720p', audio: true, costPerSecond: 0.15 },
|
|
162
|
+
{ resolution: '1080p', audio: false, costPerSecond: 0.1 },
|
|
163
|
+
{ resolution: '1080p', audio: true, costPerSecond: 0.15 },
|
|
164
|
+
{ resolution: '4k', audio: false, costPerSecond: 0.3 },
|
|
165
|
+
{ resolution: '4k', audio: true, costPerSecond: 0.35 },
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
features: {
|
|
169
|
+
textToVideo: true,
|
|
170
|
+
imageToVideo: false,
|
|
171
|
+
capabilities: ['t2v'],
|
|
172
|
+
aspectRatios: ['16:9', '9:16'],
|
|
173
|
+
resolutions: ['720p', '1080p', '4k'],
|
|
174
|
+
durationRangeSec: { min: 4, max: 8 },
|
|
175
|
+
seed: true,
|
|
176
|
+
multipleVideos: true,
|
|
177
|
+
},
|
|
178
|
+
},
|
|
118
179
|
{
|
|
119
180
|
id: 'grok-imagine-video',
|
|
120
181
|
name: 'Grok Imagine Video',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "egaki",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/cli.js",
|
|
6
6
|
"types": "./dist/cli.d.ts",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"files": [
|
|
34
34
|
"src",
|
|
35
35
|
"dist",
|
|
36
|
+
"skills",
|
|
36
37
|
"README.md",
|
|
37
38
|
"CHANGELOG.md"
|
|
38
39
|
],
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"dependencies": {
|
|
49
50
|
"@ai-sdk/fal": "2.0.21",
|
|
50
51
|
"@ai-sdk/google": "3.0.33",
|
|
52
|
+
"@ai-sdk/google-vertex": "^4.0.95",
|
|
51
53
|
"@ai-sdk/openai": "3.0.36",
|
|
52
54
|
"@ai-sdk/replicate": "2.0.20",
|
|
53
55
|
"@clack/prompts": "^1.0.1",
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: egaki
|
|
3
|
+
description: >
|
|
4
|
+
AI image and video generation CLI. Use this skill to install egaki, configure
|
|
5
|
+
auth, run help commands, and generate images or videos with provider keys or
|
|
6
|
+
an Egaki subscription.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# egaki
|
|
10
|
+
|
|
11
|
+
Generate AI images and videos from the terminal.
|
|
12
|
+
Use this for text-to-image, image editing, mask-based edits, text-to-video,
|
|
13
|
+
image-to-video, and model discovery.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add -g egaki
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Always check help first
|
|
22
|
+
|
|
23
|
+
Run the full help output before using commands:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
egaki --help
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Do not truncate help output with `head`.
|
|
30
|
+
|
|
31
|
+
For subcommand details: `egaki <command> --help` (e.g. `egaki image --help`, `egaki video --help`, `egaki login --help`)
|
|
32
|
+
|
|
33
|
+
## Auth options
|
|
34
|
+
|
|
35
|
+
You can authenticate in two ways:
|
|
36
|
+
|
|
37
|
+
1. Egaki subscription key (recommended — all models, one key)
|
|
38
|
+
2. Provider API keys (Google, OpenAI, Fal, Replicate) via `egaki login`
|
|
39
|
+
|
|
40
|
+
If using Egaki subscription, set it up first with `egaki subscribe`, then store
|
|
41
|
+
the key with `egaki login --provider egaki --key egaki_...`.
|
|
42
|
+
|
|
43
|
+
## Login behavior for remote agents
|
|
44
|
+
|
|
45
|
+
When login requires a URL flow, run login in the background and send the login URL
|
|
46
|
+
to the user so they can complete auth interactively.
|
|
47
|
+
|
|
48
|
+
## Example commands
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# configure key interactively
|
|
52
|
+
egaki login
|
|
53
|
+
|
|
54
|
+
# show login status
|
|
55
|
+
egaki login --show
|
|
56
|
+
|
|
57
|
+
# subscribe to Egaki for all supported models
|
|
58
|
+
egaki subscribe
|
|
59
|
+
|
|
60
|
+
# check subscription usage
|
|
61
|
+
egaki usage
|
|
62
|
+
|
|
63
|
+
# generate an image
|
|
64
|
+
egaki image "a watercolor fox reading a map" -o fox.png
|
|
65
|
+
|
|
66
|
+
# select a model explicitly
|
|
67
|
+
egaki image "isometric floating city, soft colors" -m imagen-4.0-generate-001 -o city.png
|
|
68
|
+
|
|
69
|
+
# edit an existing image (local file or URL)
|
|
70
|
+
egaki image "add a red scarf and make it winter" --input portrait.jpg -o portrait-winter.png
|
|
71
|
+
egaki image "turn this into a manga panel" --input https://example.com/photo.jpg -o manga.png
|
|
72
|
+
|
|
73
|
+
# inpainting with a mask
|
|
74
|
+
egaki image "replace the sky with a dramatic sunset" --input scene.png --mask mask.png -o scene-sunset.png
|
|
75
|
+
|
|
76
|
+
# generate a video — use a 5 minute timeout, video generation is slow
|
|
77
|
+
egaki video "a paper boat drifting on a calm lake at sunrise" -o boat.mp4
|
|
78
|
+
|
|
79
|
+
# generate a video with a specific model
|
|
80
|
+
egaki video "timelapse of a stormy sea, cinematic" -m google/veo-3.1-fast-generate-001 --duration 6 -o storm.mp4
|
|
81
|
+
|
|
82
|
+
# cheap video model
|
|
83
|
+
egaki video "a cat walking on a rooftop at night" -m klingai/kling-v2.5-turbo-t2v --duration 5 -o cat.mp4
|
|
84
|
+
|
|
85
|
+
# image-to-video (model must support i2v)
|
|
86
|
+
egaki video "slowly animate the clouds" --input photo.jpg -m klingai/kling-v2.6-i2v -o animated.mp4
|
|
87
|
+
|
|
88
|
+
# discover all models (image + video)
|
|
89
|
+
egaki models
|
|
90
|
+
|
|
91
|
+
# filter by type
|
|
92
|
+
egaki models --type video
|
|
93
|
+
egaki models --type image
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Video generation note for agents
|
|
97
|
+
|
|
98
|
+
Video generation can be very slow — some models take 1–3 minutes per request.
|
|
99
|
+
Always use a command timeout of **at least 5 minutes** when invoking `egaki video`
|
|
100
|
+
from automation or agent workflows.
|
package/src/cli.ts
CHANGED
|
@@ -98,6 +98,7 @@ cli
|
|
|
98
98
|
.example('egaki login')
|
|
99
99
|
.example('# Non-interactive login with flags')
|
|
100
100
|
.example('egaki login --provider google --key AIza...')
|
|
101
|
+
.example('egaki login --provider vertex --key AIza...')
|
|
101
102
|
.example('# Pipe key from stdin (useful in CI/scripts)')
|
|
102
103
|
.example('echo "AIza..." | egaki login --provider google')
|
|
103
104
|
.example('# Show configured providers')
|
|
@@ -283,6 +284,8 @@ cli
|
|
|
283
284
|
.example('egaki image "fill with flowers" --input photo.jpg --mask mask.png')
|
|
284
285
|
.example('# Generate with Gemini multimodal at 4K')
|
|
285
286
|
.example('egaki image "dreamy landscape" -m gemini-2.5-flash-image --image-size 4K')
|
|
287
|
+
.example('# Route through Vertex AI (Google Cloud billing)')
|
|
288
|
+
.example('egaki image "product photo on marble" -m vertex/imagen-4.0-generate-001')
|
|
286
289
|
.example('# Generate multiple images')
|
|
287
290
|
.example('egaki image "abstract art" -n 4 -o art.png')
|
|
288
291
|
.example('# Pipe to another tool')
|
|
@@ -410,6 +413,8 @@ cli
|
|
|
410
413
|
.example('egaki video "A paper airplane gliding through clouds" -o airplane.mp4')
|
|
411
414
|
.example('# Generate with Veo model + duration')
|
|
412
415
|
.example('egaki video "cinematic rainy street at night" -m veo-3.1-fast-generate-001 --duration 6')
|
|
416
|
+
.example('# Route through Vertex AI (Google Cloud billing)')
|
|
417
|
+
.example('egaki video "storm over mountains" -m vertex/veo-3.1-fast-generate-001 --duration 6')
|
|
413
418
|
.example('# Image-to-video (model support required)')
|
|
414
419
|
.example('egaki video "animate subtle camera pan" --model luma-ray-2 --input frame.png -o animated.mp4')
|
|
415
420
|
.example('# Generate multiple videos')
|
|
@@ -597,8 +602,12 @@ async function generateWithImageModel({
|
|
|
597
602
|
? { text: prompt, images: inputImages, ...(maskImage ? { mask: maskImage } : {}) }
|
|
598
603
|
: prompt
|
|
599
604
|
|
|
605
|
+
const config = getModelConfig(model)
|
|
600
606
|
const imageModel = await createImageModel(model)
|
|
601
607
|
|
|
608
|
+
// Use the correct providerOptions key based on provider (google vs vertex)
|
|
609
|
+
const providerOptionsKey = config.provider === 'vertex' ? 'vertex' : 'google'
|
|
610
|
+
|
|
602
611
|
if (!stdout) {
|
|
603
612
|
console.error(pc.cyan('Generating...'))
|
|
604
613
|
}
|
|
@@ -610,7 +619,7 @@ async function generateWithImageModel({
|
|
|
610
619
|
...(aspectRatio ? { aspectRatio } : {}),
|
|
611
620
|
...(seed !== undefined ? { seed } : {}),
|
|
612
621
|
providerOptions: {
|
|
613
|
-
|
|
622
|
+
[providerOptionsKey]: {
|
|
614
623
|
...(allowPeople ? { personGeneration: 'allow_all' } : {}),
|
|
615
624
|
...(aspectRatio ? { aspectRatio } : {}),
|
|
616
625
|
},
|
|
@@ -640,7 +649,6 @@ async function generateWithImageModel({
|
|
|
640
649
|
savedFiles.push(filePath)
|
|
641
650
|
}
|
|
642
651
|
|
|
643
|
-
const config = getModelConfig(model)
|
|
644
652
|
const cost = calculateCost(config.cost, result.usage, result.images.length)
|
|
645
653
|
if (cost != null) {
|
|
646
654
|
console.error(pc.dim(`Cost: ${formatCost(cost)}`))
|
|
@@ -680,6 +688,8 @@ async function generateWithTextModel({
|
|
|
680
688
|
stdout: boolean
|
|
681
689
|
}) {
|
|
682
690
|
const textModel = await createTextModel(model)
|
|
691
|
+
const config = getModelConfig(model)
|
|
692
|
+
const providerOptionsKey = config.provider === 'vertex' ? 'vertex' : 'google'
|
|
683
693
|
|
|
684
694
|
if (!stdout) {
|
|
685
695
|
console.error(pc.cyan('Generating...'))
|
|
@@ -705,7 +715,7 @@ async function generateWithTextModel({
|
|
|
705
715
|
model: textModel,
|
|
706
716
|
...(messages ? { messages } : { prompt }),
|
|
707
717
|
providerOptions: {
|
|
708
|
-
|
|
718
|
+
[providerOptionsKey]: {
|
|
709
719
|
responseModalities: ['TEXT', 'IMAGE'],
|
|
710
720
|
...(imageSize || aspectRatio
|
|
711
721
|
? {
|
|
@@ -750,7 +760,6 @@ async function generateWithTextModel({
|
|
|
750
760
|
savedFiles.push(filePath)
|
|
751
761
|
}
|
|
752
762
|
|
|
753
|
-
const config = getModelConfig(model)
|
|
754
763
|
const cost = calculateCost(config.cost, result.usage, imageFiles.length)
|
|
755
764
|
if (cost != null) {
|
|
756
765
|
console.error(pc.dim(`Cost: ${formatCost(cost)}`))
|
package/src/credentials.ts
CHANGED
|
@@ -22,6 +22,11 @@ export const PROVIDERS: Record<
|
|
|
22
22
|
label: 'Google AI (Gemini, Imagen)',
|
|
23
23
|
hint: 'Get your key at https://aistudio.google.com/apikey',
|
|
24
24
|
},
|
|
25
|
+
vertex: {
|
|
26
|
+
envVar: 'GOOGLE_VERTEX_API_KEY',
|
|
27
|
+
label: 'Google Vertex AI (Gemini, Imagen, Veo via Google Cloud)',
|
|
28
|
+
hint: 'Get an API key at https://console.cloud.google.com/apis/credentials',
|
|
29
|
+
},
|
|
25
30
|
openai: {
|
|
26
31
|
envVar: 'OPENAI_API_KEY',
|
|
27
32
|
label: 'OpenAI (DALL-E)',
|
package/src/model-catalog.ts
CHANGED
|
@@ -109,6 +109,22 @@ const xaiImage = {
|
|
|
109
109
|
strategy: 'image' as const,
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
const vertexImagen = {
|
|
113
|
+
provider: 'vertex',
|
|
114
|
+
strategy: 'image' as const,
|
|
115
|
+
features: {
|
|
116
|
+
...googleImagen.features,
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const vertexText = {
|
|
121
|
+
provider: 'vertex',
|
|
122
|
+
strategy: 'text' as const,
|
|
123
|
+
features: {
|
|
124
|
+
...googleText.features,
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
|
|
112
128
|
const fluxAspectRatios = ['1:1', '3:4', '4:3', '9:16', '16:9', '9:21', '21:9']
|
|
113
129
|
|
|
114
130
|
// ─── catalog ─────────────────────────────────────────────────────────────────
|
|
@@ -196,6 +212,64 @@ export const CATALOG: ModelEntry[] = [
|
|
|
196
212
|
cost: { type: 'per-token', inputPerM: 0.5, outputPerM: 3.0 },
|
|
197
213
|
},
|
|
198
214
|
|
|
215
|
+
// ── Vertex: Imagen ──────────────────────────────────────────────────────
|
|
216
|
+
// Same models as Google AI Studio but routed through Vertex AI / Google Cloud billing.
|
|
217
|
+
// Use `egaki login --provider vertex --key <key>` to configure.
|
|
218
|
+
{
|
|
219
|
+
id: 'vertex/imagen-4.0-generate-001',
|
|
220
|
+
name: 'Imagen 4 (Vertex)',
|
|
221
|
+
released: '2025-08-15',
|
|
222
|
+
...vertexImagen,
|
|
223
|
+
cost: { type: 'per-image', perImage: 0.04 },
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
id: 'vertex/imagen-4.0-ultra-generate-001',
|
|
227
|
+
name: 'Imagen 4 Ultra (Vertex)',
|
|
228
|
+
released: '2025-08-15',
|
|
229
|
+
...vertexImagen,
|
|
230
|
+
cost: { type: 'per-image', perImage: 0.06 },
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
id: 'vertex/imagen-4.0-fast-generate-001',
|
|
234
|
+
name: 'Imagen 4 Fast (Vertex)',
|
|
235
|
+
released: '2025-08-15',
|
|
236
|
+
...vertexImagen,
|
|
237
|
+
cost: { type: 'per-image', perImage: 0.02 },
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
// ── Vertex: Gemini text+image ─────────────────────────────────────────
|
|
241
|
+
{
|
|
242
|
+
id: 'vertex/gemini-2.5-flash-image',
|
|
243
|
+
name: 'Gemini 2.5 Flash Image (Vertex)',
|
|
244
|
+
released: '2025-08-26',
|
|
245
|
+
...vertexText,
|
|
246
|
+
cost: { type: 'per-token', inputPerM: 0.3, outputPerM: 30 },
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
id: 'vertex/gemini-3-pro-image-preview',
|
|
250
|
+
name: 'Gemini 3 Pro Image (Vertex)',
|
|
251
|
+
released: '2025-11-20',
|
|
252
|
+
...vertexText,
|
|
253
|
+
cost: { type: 'per-token', inputPerM: 1.25, outputPerM: 10 },
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
id: 'vertex/gemini-3.1-flash-image-preview',
|
|
257
|
+
name: 'Gemini 3.1 Flash Image (Vertex)',
|
|
258
|
+
released: '2026-02-26',
|
|
259
|
+
...vertexText,
|
|
260
|
+
features: {
|
|
261
|
+
...vertexText.features,
|
|
262
|
+
aspectRatios: [
|
|
263
|
+
...vertexText.features.aspectRatios,
|
|
264
|
+
'4:1',
|
|
265
|
+
'1:4',
|
|
266
|
+
'8:1',
|
|
267
|
+
'1:8',
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
cost: { type: 'per-token', inputPerM: 0.5, outputPerM: 3.0 },
|
|
271
|
+
},
|
|
272
|
+
|
|
199
273
|
// ── BFL (AI Gateway) ───────────────────────────────────────────────────
|
|
200
274
|
{
|
|
201
275
|
id: 'flux-kontext-max',
|
package/src/models.ts
CHANGED
|
@@ -29,6 +29,16 @@ export type { ModelEntry, VideoModelEntry }
|
|
|
29
29
|
export const IMAGE_MODELS = CATALOG.map((m) => m.id) as [string, ...string[]]
|
|
30
30
|
export const VIDEO_MODELS = VIDEO_CATALOG.map((m) => m.id) as [string, ...string[]]
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Strip provider prefix from a model ID (e.g. "vertex/imagen-4.0-generate-001" → "imagen-4.0-generate-001").
|
|
34
|
+
* Provider SDKs expect bare model IDs, but the catalog uses prefixed IDs for routing.
|
|
35
|
+
*/
|
|
36
|
+
function stripProviderPrefix(modelId: string): string {
|
|
37
|
+
const slash = modelId.indexOf('/')
|
|
38
|
+
if (slash === -1) return modelId
|
|
39
|
+
return modelId.slice(slash + 1)
|
|
40
|
+
}
|
|
41
|
+
|
|
32
42
|
export const DEFAULT_MODEL = 'nano-banana-pro-preview'
|
|
33
43
|
export const DEFAULT_VIDEO_MODEL = 'veo-3.1-fast-generate-001'
|
|
34
44
|
|
|
@@ -66,6 +76,20 @@ export function ensureProviderKey(providerName: string): void {
|
|
|
66
76
|
// If direct provider key exists, we're good
|
|
67
77
|
if (hasDirectProviderKey(providerName)) return
|
|
68
78
|
|
|
79
|
+
// Vertex models require a direct key — the upstream Vercel AI Gateway
|
|
80
|
+
// does not support vertex/ routing, so egaki gateway can't proxy them.
|
|
81
|
+
if (providerName === 'vertex') {
|
|
82
|
+
console.error('')
|
|
83
|
+
console.error(pc.red(pc.bold('Vertex models require a direct Google Cloud API key')))
|
|
84
|
+
console.error('')
|
|
85
|
+
console.error(` ${pc.cyan('egaki login --provider vertex --key <key>')}`)
|
|
86
|
+
console.error('')
|
|
87
|
+
console.error(pc.dim('Get a key at https://console.cloud.google.com/apis/credentials'))
|
|
88
|
+
console.error(pc.dim('Egaki subscription does not cover Vertex routing yet.'))
|
|
89
|
+
console.error('')
|
|
90
|
+
process.exit(1)
|
|
91
|
+
}
|
|
92
|
+
|
|
69
93
|
// If egaki key exists, we'll route through the gateway
|
|
70
94
|
if (hasEgakiKey()) return
|
|
71
95
|
|
|
@@ -109,8 +133,11 @@ async function createGatewayImageModel(modelId: string, provider: string): Promi
|
|
|
109
133
|
apiKey: process.env['EGAKI_API_KEY']!,
|
|
110
134
|
baseURL: EGAKI_GATEWAY_URL,
|
|
111
135
|
})
|
|
112
|
-
// Gateway expects provider/model format for routing
|
|
113
|
-
|
|
136
|
+
// Gateway expects provider/model format for routing.
|
|
137
|
+
// For models that already have a prefix (e.g. vertex/imagen-4.0), strip it
|
|
138
|
+
// and use the catalog provider. For bare IDs, prepend the provider.
|
|
139
|
+
const bareId = stripProviderPrefix(modelId)
|
|
140
|
+
const gatewayModelId = `${provider}/${bareId}`
|
|
114
141
|
return gateway.image(gatewayModelId)
|
|
115
142
|
}
|
|
116
143
|
|
|
@@ -123,7 +150,8 @@ async function createGatewayTextModel(modelId: string, provider: string): Promis
|
|
|
123
150
|
apiKey: process.env['EGAKI_API_KEY']!,
|
|
124
151
|
baseURL: EGAKI_GATEWAY_URL,
|
|
125
152
|
})
|
|
126
|
-
const
|
|
153
|
+
const bareId = stripProviderPrefix(modelId)
|
|
154
|
+
const gatewayModelId = `${provider}/${bareId}`
|
|
127
155
|
return gateway(gatewayModelId)
|
|
128
156
|
}
|
|
129
157
|
|
|
@@ -136,7 +164,8 @@ async function createGatewayVideoModel(modelId: string, provider: string) {
|
|
|
136
164
|
apiKey: process.env['EGAKI_API_KEY']!,
|
|
137
165
|
baseURL: EGAKI_GATEWAY_URL,
|
|
138
166
|
})
|
|
139
|
-
const
|
|
167
|
+
const bareId = stripProviderPrefix(modelId)
|
|
168
|
+
const gatewayModelId = `${provider}/${bareId}`
|
|
140
169
|
return gateway.video(gatewayModelId)
|
|
141
170
|
}
|
|
142
171
|
|
|
@@ -156,6 +185,10 @@ export async function createImageModel(modelId: string): Promise<ImageModel> {
|
|
|
156
185
|
const { google } = await import('@ai-sdk/google')
|
|
157
186
|
return google.image(modelId)
|
|
158
187
|
}
|
|
188
|
+
case 'vertex': {
|
|
189
|
+
const { vertex } = await import('@ai-sdk/google-vertex')
|
|
190
|
+
return vertex.image(stripProviderPrefix(modelId))
|
|
191
|
+
}
|
|
159
192
|
case 'openai': {
|
|
160
193
|
const { openai } = await import('@ai-sdk/openai')
|
|
161
194
|
return openai.image(modelId)
|
|
@@ -198,11 +231,15 @@ export async function createTextModel(
|
|
|
198
231
|
const { google } = await import('@ai-sdk/google')
|
|
199
232
|
return google(modelId)
|
|
200
233
|
}
|
|
234
|
+
case 'vertex': {
|
|
235
|
+
const { vertex } = await import('@ai-sdk/google-vertex')
|
|
236
|
+
return vertex(stripProviderPrefix(modelId))
|
|
237
|
+
}
|
|
201
238
|
default:
|
|
202
|
-
// Only Google
|
|
239
|
+
// Only Google/Vertex support generateText with responseModalities for images
|
|
203
240
|
console.error(
|
|
204
241
|
pc.red(
|
|
205
|
-
`Text+image generation is only supported for Google models, got provider: ${config.provider}`,
|
|
242
|
+
`Text+image generation is only supported for Google/Vertex models, got provider: ${config.provider}`,
|
|
206
243
|
),
|
|
207
244
|
)
|
|
208
245
|
process.exit(1)
|
|
@@ -234,6 +271,10 @@ export async function createVideoModel(modelId: string): Promise<any> {
|
|
|
234
271
|
const { google } = await import('@ai-sdk/google')
|
|
235
272
|
return google.video(modelId)
|
|
236
273
|
}
|
|
274
|
+
case 'vertex': {
|
|
275
|
+
const { vertex } = await import('@ai-sdk/google-vertex')
|
|
276
|
+
return vertex.video(stripProviderPrefix(modelId))
|
|
277
|
+
}
|
|
237
278
|
case 'fal': {
|
|
238
279
|
const { fal } = await import('@ai-sdk/fal')
|
|
239
280
|
return fal.video(modelId)
|
|
@@ -241,7 +282,7 @@ export async function createVideoModel(modelId: string): Promise<any> {
|
|
|
241
282
|
default:
|
|
242
283
|
console.error(
|
|
243
284
|
pc.red(
|
|
244
|
-
`Direct video generation is only supported for Google and Fal keys, got provider: ${config.provider}`,
|
|
285
|
+
`Direct video generation is only supported for Google, Vertex, and Fal keys, got provider: ${config.provider}`,
|
|
245
286
|
),
|
|
246
287
|
)
|
|
247
288
|
process.exit(1)
|
|
@@ -169,6 +169,67 @@ export const VIDEO_CATALOG: VideoModelEntry[] = [
|
|
|
169
169
|
multipleVideos: true,
|
|
170
170
|
},
|
|
171
171
|
},
|
|
172
|
+
// ── Vertex: Veo ──────────────────────────────────────────────────────
|
|
173
|
+
// Same Veo models routed through Vertex AI / Google Cloud billing.
|
|
174
|
+
// Use `egaki login --provider vertex --key <key>` to configure.
|
|
175
|
+
{
|
|
176
|
+
id: 'vertex/veo-3.1-generate-001',
|
|
177
|
+
name: 'Veo 3.1 (Vertex)',
|
|
178
|
+
provider: 'vertex',
|
|
179
|
+
strategy: 'video',
|
|
180
|
+
released: '2026-01',
|
|
181
|
+
cost: {
|
|
182
|
+
type: 'per-video-second',
|
|
183
|
+
defaultDurationSec: 8,
|
|
184
|
+
tiers: [
|
|
185
|
+
{ resolution: '720p', audio: false, costPerSecond: 0.2 },
|
|
186
|
+
{ resolution: '720p', audio: true, costPerSecond: 0.4 },
|
|
187
|
+
{ resolution: '1080p', audio: false, costPerSecond: 0.2 },
|
|
188
|
+
{ resolution: '1080p', audio: true, costPerSecond: 0.4 },
|
|
189
|
+
{ resolution: '4k', audio: false, costPerSecond: 0.4 },
|
|
190
|
+
{ resolution: '4k', audio: true, costPerSecond: 0.6 },
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
features: {
|
|
194
|
+
textToVideo: true,
|
|
195
|
+
imageToVideo: false,
|
|
196
|
+
capabilities: ['t2v'],
|
|
197
|
+
aspectRatios: ['16:9', '9:16'],
|
|
198
|
+
resolutions: ['720p', '1080p', '4k'],
|
|
199
|
+
durationRangeSec: { min: 4, max: 8 },
|
|
200
|
+
seed: true,
|
|
201
|
+
multipleVideos: true,
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: 'vertex/veo-3.1-fast-generate-001',
|
|
206
|
+
name: 'Veo 3.1 Fast (Vertex)',
|
|
207
|
+
provider: 'vertex',
|
|
208
|
+
strategy: 'video',
|
|
209
|
+
released: '2026-01',
|
|
210
|
+
cost: {
|
|
211
|
+
type: 'per-video-second',
|
|
212
|
+
defaultDurationSec: 8,
|
|
213
|
+
tiers: [
|
|
214
|
+
{ resolution: '720p', audio: false, costPerSecond: 0.1 },
|
|
215
|
+
{ resolution: '720p', audio: true, costPerSecond: 0.15 },
|
|
216
|
+
{ resolution: '1080p', audio: false, costPerSecond: 0.1 },
|
|
217
|
+
{ resolution: '1080p', audio: true, costPerSecond: 0.15 },
|
|
218
|
+
{ resolution: '4k', audio: false, costPerSecond: 0.3 },
|
|
219
|
+
{ resolution: '4k', audio: true, costPerSecond: 0.35 },
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
features: {
|
|
223
|
+
textToVideo: true,
|
|
224
|
+
imageToVideo: false,
|
|
225
|
+
capabilities: ['t2v'],
|
|
226
|
+
aspectRatios: ['16:9', '9:16'],
|
|
227
|
+
resolutions: ['720p', '1080p', '4k'],
|
|
228
|
+
durationRangeSec: { min: 4, max: 8 },
|
|
229
|
+
seed: true,
|
|
230
|
+
multipleVideos: true,
|
|
231
|
+
},
|
|
232
|
+
},
|
|
172
233
|
{
|
|
173
234
|
id: 'grok-imagine-video',
|
|
174
235
|
name: 'Grok Imagine Video',
|