egaki 0.6.0 → 0.7.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 +140 -9
- package/dist/cli/cache-utils.d.ts +33 -0
- package/dist/cli/cache-utils.d.ts.map +1 -0
- package/dist/cli/cache-utils.js +157 -0
- package/dist/cli/cached-generate.d.ts +105 -0
- package/dist/cli/cached-generate.d.ts.map +1 -0
- package/dist/cli/cached-generate.js +208 -0
- package/dist/cli/cached-generate.test.d.ts +11 -0
- package/dist/cli/cached-generate.test.d.ts.map +1 -0
- package/dist/cli/cached-generate.test.js +431 -0
- package/dist/cli/cartesia-provider.d.ts +16 -0
- package/dist/cli/cartesia-provider.d.ts.map +1 -0
- package/dist/cli/cartesia-provider.js +184 -0
- package/dist/cli/chatgpt-auth.d.ts.map +1 -0
- package/dist/cli/cli.d.ts +4 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/{cli.js → cli/cli.js} +626 -600
- package/dist/cli/clone-generate.d.ts +26 -0
- package/dist/cli/clone-generate.d.ts.map +1 -0
- package/dist/cli/clone-generate.js +148 -0
- package/dist/cli/credentials.d.ts.map +1 -0
- package/dist/{credentials.js → cli/credentials.js} +20 -0
- package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
- package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
- package/dist/cli/elevenlabs-speech-provider.js +199 -0
- package/dist/cli/generate.d.ts +140 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +604 -0
- package/dist/cli/generate.test.d.ts +2 -0
- package/dist/cli/generate.test.d.ts.map +1 -0
- package/dist/cli/generate.test.js +131 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +7 -0
- package/dist/{model-catalog.d.ts → cli/model-catalog.d.ts} +6 -0
- package/dist/cli/model-catalog.d.ts.map +1 -0
- package/dist/{model-catalog.js → cli/model-catalog.js} +714 -4
- package/dist/{models.d.ts → cli/models.d.ts} +12 -5
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/{models.js → cli/models.js} +58 -57
- package/dist/cli/open-browser.d.ts.map +1 -0
- package/dist/cli/openai-speech-provider.d.ts +3 -0
- package/dist/cli/openai-speech-provider.d.ts.map +1 -0
- package/dist/cli/openai-speech-provider.js +28 -0
- package/dist/cli/separation-generate.d.ts +34 -0
- package/dist/cli/separation-generate.d.ts.map +1 -0
- package/dist/cli/separation-generate.js +117 -0
- package/dist/cli/speech-catalog.d.ts +35 -0
- package/dist/cli/speech-catalog.d.ts.map +1 -0
- package/dist/cli/speech-catalog.js +195 -0
- package/dist/cli/speech-generate.d.ts +86 -0
- package/dist/cli/speech-generate.d.ts.map +1 -0
- package/dist/cli/speech-generate.js +156 -0
- package/dist/cli/speech-models.d.ts +8 -0
- package/dist/cli/speech-models.d.ts.map +1 -0
- package/dist/cli/speech-models.js +109 -0
- package/dist/cli/speech-provider.test.d.ts +2 -0
- package/dist/cli/speech-provider.test.d.ts.map +1 -0
- package/dist/cli/speech-provider.test.js +197 -0
- package/dist/cli/subscription.d.ts.map +1 -0
- package/dist/cli/transcription-catalog.d.ts +35 -0
- package/dist/cli/transcription-catalog.d.ts.map +1 -0
- package/dist/cli/transcription-catalog.js +192 -0
- package/dist/cli/transcription-generate.d.ts +62 -0
- package/dist/cli/transcription-generate.d.ts.map +1 -0
- package/dist/cli/transcription-generate.js +144 -0
- package/dist/cli/transcription-models.d.ts +9 -0
- package/dist/cli/transcription-models.d.ts.map +1 -0
- package/dist/cli/transcription-models.js +100 -0
- package/dist/cli/transcription-providers.d.ts +22 -0
- package/dist/cli/transcription-providers.d.ts.map +1 -0
- package/dist/cli/transcription-providers.js +290 -0
- package/dist/cli/video-model-catalog.d.ts.map +1 -0
- package/dist/cli/xai-auth.d.ts.map +1 -0
- package/dist/{xai-auth.js → cli/xai-auth.js} +1 -1
- package/dist/vite/angled-screen.d.ts +57 -0
- package/dist/vite/angled-screen.d.ts.map +1 -0
- package/dist/vite/angled-screen.js +115 -0
- package/dist/vite/app.d.ts +51 -0
- package/dist/vite/app.d.ts.map +1 -0
- package/dist/vite/app.js +150 -0
- package/dist/vite/bands-shader.d.ts +47 -0
- package/dist/vite/bands-shader.d.ts.map +1 -0
- package/dist/vite/bands-shader.js +267 -0
- package/dist/vite/code-block.d.ts +107 -0
- package/dist/vite/code-block.d.ts.map +1 -0
- package/dist/vite/code-block.js +641 -0
- package/dist/vite/components.d.ts +36 -0
- package/dist/vite/components.d.ts.map +1 -0
- package/dist/vite/components.js +113 -0
- package/dist/vite/dispersion-rings-shader.d.ts +44 -0
- package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
- package/dist/vite/dispersion-rings-shader.js +282 -0
- package/dist/vite/easing-curves.d.ts +129 -0
- package/dist/vite/easing-curves.d.ts.map +1 -0
- package/dist/vite/easing-curves.js +584 -0
- package/dist/vite/easing-curves.test.d.ts +2 -0
- package/dist/vite/easing-curves.test.d.ts.map +1 -0
- package/dist/vite/easing-curves.test.js +200 -0
- package/dist/vite/generated-media-client.d.ts +35 -0
- package/dist/vite/generated-media-client.d.ts.map +1 -0
- package/dist/vite/generated-media-client.js +76 -0
- package/dist/vite/keyframes.d.ts +129 -0
- package/dist/vite/keyframes.d.ts.map +1 -0
- package/dist/vite/keyframes.js +194 -0
- package/dist/vite/layout-editor.d.ts +45 -0
- package/dist/vite/layout-editor.d.ts.map +1 -0
- package/dist/vite/layout-editor.js +587 -0
- package/dist/vite/layout-transition.d.ts +136 -0
- package/dist/vite/layout-transition.d.ts.map +1 -0
- package/dist/vite/layout-transition.js +581 -0
- package/dist/vite/liquid-gradient-shader.d.ts +62 -0
- package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
- package/dist/vite/liquid-gradient-shader.js +413 -0
- package/dist/vite/mdx-client.d.ts +15 -0
- package/dist/vite/mdx-client.d.ts.map +1 -0
- package/dist/vite/mdx-client.js +265 -0
- package/dist/vite/mdx-parse.d.ts +102 -0
- package/dist/vite/mdx-parse.d.ts.map +1 -0
- package/dist/vite/mdx-parse.js +251 -0
- package/dist/vite/mdx-provided-components.d.ts +18 -0
- package/dist/vite/mdx-provided-components.d.ts.map +1 -0
- package/dist/vite/mdx-provided-components.js +14 -0
- package/dist/vite/mdx-video.d.ts +327 -0
- package/dist/vite/mdx-video.d.ts.map +1 -0
- package/dist/vite/mdx-video.js +596 -0
- package/dist/vite/mdx-video.test.d.ts +9 -0
- package/dist/vite/mdx-video.test.d.ts.map +1 -0
- package/dist/vite/mdx-video.test.js +1945 -0
- package/dist/vite/media-components.d.ts +45 -0
- package/dist/vite/media-components.d.ts.map +1 -0
- package/dist/vite/media-components.js +355 -0
- package/dist/vite/media-duration-store.d.ts +66 -0
- package/dist/vite/media-duration-store.d.ts.map +1 -0
- package/dist/vite/media-duration-store.js +204 -0
- package/dist/vite/player-page.d.ts +35 -0
- package/dist/vite/player-page.d.ts.map +1 -0
- package/dist/vite/player-page.js +720 -0
- package/dist/vite/render-client.d.ts +18 -0
- package/dist/vite/render-client.d.ts.map +1 -0
- package/dist/vite/render-client.js +67 -0
- package/dist/vite/sdk.d.ts +221 -0
- package/dist/vite/sdk.d.ts.map +1 -0
- package/dist/vite/sdk.js +355 -0
- package/dist/vite/server-components.d.ts +55 -0
- package/dist/vite/server-components.d.ts.map +1 -0
- package/dist/vite/server-components.js +156 -0
- package/dist/vite/server-mdx.d.ts +74 -0
- package/dist/vite/server-mdx.d.ts.map +1 -0
- package/dist/vite/server-mdx.js +259 -0
- package/dist/vite/shader-renderer.d.ts +48 -0
- package/dist/vite/shader-renderer.d.ts.map +1 -0
- package/dist/vite/shader-renderer.js +411 -0
- package/dist/vite/store-hooks.d.ts +12 -0
- package/dist/vite/store-hooks.d.ts.map +1 -0
- package/dist/vite/store-hooks.js +93 -0
- package/dist/vite/store.d.ts +75 -0
- package/dist/vite/store.d.ts.map +1 -0
- package/dist/vite/store.js +52 -0
- package/dist/vite/store.test.d.ts +6 -0
- package/dist/vite/store.test.d.ts.map +1 -0
- package/dist/vite/store.test.js +172 -0
- package/dist/vite/tweakpane-hook.d.ts +94 -0
- package/dist/vite/tweakpane-hook.d.ts.map +1 -0
- package/dist/vite/tweakpane-hook.js +450 -0
- package/dist/vite/vite-plugin.d.ts +28 -0
- package/dist/vite/vite-plugin.d.ts.map +1 -0
- package/dist/vite/vite-plugin.js +538 -0
- package/dist/vite/wave-gradient-shader.d.ts +41 -0
- package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
- package/dist/vite/wave-gradient-shader.js +207 -0
- package/package.json +101 -24
- package/skills/egaki/SKILL.md +162 -1
- package/src/cli/cache-utils.ts +169 -0
- package/src/cli/cached-generate.test.ts +531 -0
- package/src/cli/cached-generate.ts +348 -0
- package/src/cli/cartesia-provider.ts +249 -0
- package/src/{cli.ts → cli/cli.ts} +836 -884
- package/src/cli/clone-generate.ts +202 -0
- package/src/{credentials.ts → cli/credentials.ts} +20 -0
- package/src/cli/elevenlabs-speech-provider.ts +243 -0
- package/src/cli/generate.test.ts +166 -0
- package/src/cli/generate.ts +912 -0
- package/src/cli/main.ts +8 -0
- package/src/{model-catalog.ts → cli/model-catalog.ts} +787 -58
- package/src/{models.ts → cli/models.ts} +65 -86
- package/src/cli/openai-speech-provider.ts +34 -0
- package/src/cli/separation-generate.ts +187 -0
- package/src/cli/speech-catalog.ts +253 -0
- package/src/cli/speech-generate.ts +275 -0
- package/src/cli/speech-models.ts +146 -0
- package/src/cli/speech-provider.test.ts +226 -0
- package/src/cli/transcription-catalog.ts +250 -0
- package/src/cli/transcription-generate.ts +214 -0
- package/src/cli/transcription-models.ts +136 -0
- package/src/cli/transcription-providers.ts +427 -0
- package/src/{xai-auth.ts → cli/xai-auth.ts} +1 -1
- package/src/vite/angled-screen.tsx +214 -0
- package/src/vite/app.tsx +197 -0
- package/src/vite/bands-shader.tsx +319 -0
- package/src/vite/code-block.tsx +939 -0
- package/src/vite/components.tsx +278 -0
- package/src/vite/dispersion-rings-shader.tsx +331 -0
- package/src/vite/easing-curves.test.ts +232 -0
- package/src/vite/easing-curves.ts +743 -0
- package/src/vite/generated-media-client.tsx +121 -0
- package/src/vite/keyframes.tsx +347 -0
- package/src/vite/layout-editor.tsx +709 -0
- package/src/vite/layout-transition.tsx +706 -0
- package/src/vite/liquid-gradient-shader.tsx +474 -0
- package/src/vite/mdx-client.tsx +420 -0
- package/src/vite/mdx-parse.ts +343 -0
- package/src/vite/mdx-provided-components.ts +19 -0
- package/src/vite/mdx-video.test.tsx +2219 -0
- package/src/vite/mdx-video.tsx +976 -0
- package/src/vite/media-components.tsx +473 -0
- package/src/vite/media-duration-store.ts +225 -0
- package/src/vite/motion-timing.ts +194 -0
- package/src/vite/player-page.tsx +1107 -0
- package/src/vite/render-client.ts +84 -0
- package/src/vite/sdk.ts +598 -0
- package/src/vite/server-components.tsx +241 -0
- package/src/vite/server-mdx.ts +285 -0
- package/src/vite/shader-renderer.tsx +535 -0
- package/src/vite/store-hooks.ts +117 -0
- package/src/vite/store.test.ts +202 -0
- package/src/vite/store.ts +115 -0
- package/src/vite/styles.css +21 -0
- package/src/vite/tweakpane-hook.tsx +593 -0
- package/src/vite/virtual-modules.d.ts +30 -0
- package/src/vite/vite-plugin.ts +584 -0
- package/src/vite/wave-gradient-shader.tsx +253 -0
- package/README.md +0 -370
- package/dist/antigravity-auth.d.ts +0 -15
- package/dist/antigravity-auth.d.ts.map +0 -1
- package/dist/antigravity-auth.js +0 -544
- package/dist/antigravity-image.d.ts +0 -11
- package/dist/antigravity-image.d.ts.map +0 -1
- package/dist/antigravity-image.js +0 -285
- package/dist/chatgpt-auth.d.ts.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/credentials.d.ts.map +0 -1
- package/dist/gateway-model-candidates.generated.d.ts +0 -11
- package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
- package/dist/gateway-model-candidates.generated.js +0 -64
- package/dist/login.d.ts.map +0 -1
- package/dist/model-catalog.d.ts.map +0 -1
- package/dist/models.d.ts.map +0 -1
- package/dist/open-browser.d.ts.map +0 -1
- package/dist/subscription.d.ts.map +0 -1
- package/dist/video-model-catalog.d.ts.map +0 -1
- package/dist/xai-auth.d.ts.map +0 -1
- /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
- /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
- /package/dist/{credentials.d.ts → cli/credentials.d.ts} +0 -0
- /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
- /package/dist/{login.js → cli/login.js} +0 -0
- /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
- /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
- /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
- /package/dist/{subscription.js → cli/subscription.js} +0 -0
- /package/dist/{video-model-catalog.d.ts → cli/video-model-catalog.d.ts} +0 -0
- /package/dist/{video-model-catalog.js → cli/video-model-catalog.js} +0 -0
- /package/dist/{xai-auth.d.ts → cli/xai-auth.d.ts} +0 -0
- /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
- /package/src/{login.ts → cli/login.ts} +0 -0
- /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
- /package/src/{subscription.ts → cli/subscription.ts} +0 -0
- /package/src/{video-model-catalog.ts → cli/video-model-catalog.ts} +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type CloneProvider = 'cartesia' | 'elevenlabs';
|
|
2
|
+
export interface CloneVoiceOptions {
|
|
3
|
+
/** Raw audio bytes of the clip to clone from. */
|
|
4
|
+
audio: Uint8Array;
|
|
5
|
+
/** Name for the cloned voice. */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Which provider to use. */
|
|
8
|
+
provider: CloneProvider;
|
|
9
|
+
/** Cartesia only: ISO 639-1 language code. Default: 'en'. Ignored by ElevenLabs. */
|
|
10
|
+
language?: string;
|
|
11
|
+
/** Optional description for the voice. */
|
|
12
|
+
description?: string;
|
|
13
|
+
/** Original filename for MIME type inference. */
|
|
14
|
+
filename?: string;
|
|
15
|
+
/** Cartesia: optional base voice ID to derive from. */
|
|
16
|
+
baseVoiceId?: string;
|
|
17
|
+
/** ElevenLabs: apply AI noise removal to the clip. */
|
|
18
|
+
removeBackgroundNoise?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface CloneVoiceResult {
|
|
21
|
+
voiceId: string;
|
|
22
|
+
name: string;
|
|
23
|
+
provider: CloneProvider;
|
|
24
|
+
}
|
|
25
|
+
export declare function cloneVoiceUncached(opts: CloneVoiceOptions): Promise<Error | CloneVoiceResult>;
|
|
26
|
+
//# sourceMappingURL=clone-generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-generate.d.ts","sourceRoot":"","sources":["../../src/cli/clone-generate.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,YAAY,CAAA;AAErD,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,KAAK,EAAE,UAAU,CAAA;IACjB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,6BAA6B;IAC7B,QAAQ,EAAE,aAAa,CAAA;IACvB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sDAAsD;IACtD,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,aAAa,CAAA;CACxB;AAoJD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAUnC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// Voice cloning via Cartesia and ElevenLabs APIs.
|
|
2
|
+
// Both are simple multipart/form-data HTTP calls, no SDK needed.
|
|
3
|
+
// Returns Error | Result (errore style) instead of throwing.
|
|
4
|
+
//
|
|
5
|
+
// Cartesia: POST https://api.cartesia.ai/voices/clone
|
|
6
|
+
// Instant clone, up to 10s of audio, free.
|
|
7
|
+
// Docs: https://docs.cartesia.ai/api-reference/voices/clone
|
|
8
|
+
// Best practices: https://docs.cartesia.ai/build-with-cartesia/capability-guides/clone-voices
|
|
9
|
+
//
|
|
10
|
+
// ElevenLabs: POST https://api.elevenlabs.io/v1/voices/add
|
|
11
|
+
// Instant voice clone (IVC), 1-3 min recommended.
|
|
12
|
+
// Docs: https://elevenlabs.io/docs/api-reference/voices/ivc/create
|
|
13
|
+
import { injectCredentialsToEnv } from './credentials.js';
|
|
14
|
+
// ─── validation ─────────────────────────────────────────────────────────────
|
|
15
|
+
const CARTESIA_LANGUAGES = new Set([
|
|
16
|
+
'en', 'fr', 'de', 'es', 'pt', 'zh', 'ja', 'hi', 'it', 'ko', 'nl', 'pl',
|
|
17
|
+
'ru', 'sv', 'tr', 'tl', 'bg', 'ro', 'ar', 'cs', 'el', 'fi', 'hr', 'ms',
|
|
18
|
+
'sk', 'da', 'ta', 'uk', 'hu', 'no', 'vi', 'bn', 'th', 'he', 'ka', 'id',
|
|
19
|
+
'te', 'gu', 'kn', 'ml', 'mr', 'pa',
|
|
20
|
+
]);
|
|
21
|
+
function validateOptions(opts) {
|
|
22
|
+
if (opts.audio.length === 0) {
|
|
23
|
+
return new Error('No audio data provided. Pass an audio file or use --stdin.');
|
|
24
|
+
}
|
|
25
|
+
if (!opts.name || opts.name.trim().length === 0) {
|
|
26
|
+
return new Error('Voice name is required. Use --name "My Voice".');
|
|
27
|
+
}
|
|
28
|
+
if (opts.provider === 'cartesia' && opts.language && !CARTESIA_LANGUAGES.has(opts.language)) {
|
|
29
|
+
return new Error(`Unsupported language "${opts.language}" for Cartesia. ` +
|
|
30
|
+
`Supported: ${[...CARTESIA_LANGUAGES].join(', ')}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// ─── MIME type helper ───────────────────────────────────────────────────────
|
|
34
|
+
function mimeTypeFromFilename(filename) {
|
|
35
|
+
if (!filename)
|
|
36
|
+
return 'audio/mpeg';
|
|
37
|
+
const ext = filename.split('.').pop()?.toLowerCase();
|
|
38
|
+
const map = {
|
|
39
|
+
mp3: 'audio/mpeg',
|
|
40
|
+
wav: 'audio/wav',
|
|
41
|
+
flac: 'audio/flac',
|
|
42
|
+
ogg: 'audio/ogg',
|
|
43
|
+
oga: 'audio/ogg',
|
|
44
|
+
webm: 'audio/webm',
|
|
45
|
+
mpga: 'audio/mpeg',
|
|
46
|
+
m4a: 'audio/mp4',
|
|
47
|
+
};
|
|
48
|
+
return map[ext ?? ''] ?? 'audio/mpeg';
|
|
49
|
+
}
|
|
50
|
+
// ─── Cartesia clone ─────────────────────────────────────────────────────────
|
|
51
|
+
const CARTESIA_API_BASE = 'https://api.cartesia.ai';
|
|
52
|
+
const CARTESIA_API_VERSION = '2026-03-01';
|
|
53
|
+
async function cloneVoiceCartesia(opts) {
|
|
54
|
+
const apiKey = process.env['CARTESIA_API_KEY'];
|
|
55
|
+
if (!apiKey) {
|
|
56
|
+
return new Error('CARTESIA_API_KEY not found. Run: egaki login --provider cartesia\n' +
|
|
57
|
+
'Get your key at https://play.cartesia.ai/keys');
|
|
58
|
+
}
|
|
59
|
+
const language = opts.language ?? 'en';
|
|
60
|
+
const mime = mimeTypeFromFilename(opts.filename);
|
|
61
|
+
const ext = opts.filename?.split('.').pop() ?? 'mp3';
|
|
62
|
+
const formData = new FormData();
|
|
63
|
+
const blob = new Blob([Buffer.from(opts.audio)], { type: mime });
|
|
64
|
+
formData.append('clip', new File([blob], `clip.${ext}`, { type: mime }));
|
|
65
|
+
formData.append('name', opts.name.trim());
|
|
66
|
+
formData.append('language', language);
|
|
67
|
+
if (opts.description)
|
|
68
|
+
formData.append('description', opts.description);
|
|
69
|
+
if (opts.baseVoiceId)
|
|
70
|
+
formData.append('base_voice_id', opts.baseVoiceId);
|
|
71
|
+
const response = await fetch(`${CARTESIA_API_BASE}/voices/clone`, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: {
|
|
74
|
+
'Cartesia-Version': CARTESIA_API_VERSION,
|
|
75
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
76
|
+
},
|
|
77
|
+
body: formData,
|
|
78
|
+
}).catch((cause) => new Error('Cartesia clone request failed', { cause }));
|
|
79
|
+
if (response instanceof Error)
|
|
80
|
+
return response;
|
|
81
|
+
if (!response.ok) {
|
|
82
|
+
const errorText = await response.text().catch(() => '');
|
|
83
|
+
return new Error(`Cartesia clone API error ${response.status}: ${errorText || response.statusText}`);
|
|
84
|
+
}
|
|
85
|
+
const json = await response.json().catch((cause) => new Error('Cartesia clone API returned invalid JSON', { cause }));
|
|
86
|
+
if (json instanceof Error)
|
|
87
|
+
return json;
|
|
88
|
+
if (!json.id)
|
|
89
|
+
return new Error('Cartesia clone API response did not include a voice id');
|
|
90
|
+
return {
|
|
91
|
+
voiceId: json.id,
|
|
92
|
+
name: json.name ?? opts.name.trim(),
|
|
93
|
+
provider: 'cartesia',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// ─── ElevenLabs clone ───────────────────────────────────────────────────────
|
|
97
|
+
const ELEVENLABS_API_BASE = 'https://api.elevenlabs.io';
|
|
98
|
+
async function cloneVoiceElevenLabs(opts) {
|
|
99
|
+
const apiKey = process.env['ELEVENLABS_API_KEY'];
|
|
100
|
+
if (!apiKey) {
|
|
101
|
+
return new Error('ELEVENLABS_API_KEY not found. Run: egaki login --provider elevenlabs\n' +
|
|
102
|
+
'Get your key at https://elevenlabs.io/app/settings/api-keys');
|
|
103
|
+
}
|
|
104
|
+
const mime = mimeTypeFromFilename(opts.filename);
|
|
105
|
+
const ext = opts.filename?.split('.').pop() ?? 'mp3';
|
|
106
|
+
const formData = new FormData();
|
|
107
|
+
formData.append('name', opts.name.trim());
|
|
108
|
+
const blob = new Blob([Buffer.from(opts.audio)], { type: mime });
|
|
109
|
+
formData.append('files', new File([blob], `clip.${ext}`, { type: mime }));
|
|
110
|
+
if (opts.description)
|
|
111
|
+
formData.append('description', opts.description);
|
|
112
|
+
if (opts.removeBackgroundNoise)
|
|
113
|
+
formData.append('remove_background_noise', 'true');
|
|
114
|
+
const response = await fetch(`${ELEVENLABS_API_BASE}/v1/voices/add`, {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers: {
|
|
117
|
+
'xi-api-key': apiKey,
|
|
118
|
+
},
|
|
119
|
+
body: formData,
|
|
120
|
+
}).catch((cause) => new Error('ElevenLabs clone request failed', { cause }));
|
|
121
|
+
if (response instanceof Error)
|
|
122
|
+
return response;
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
const errorText = await response.text().catch(() => '');
|
|
125
|
+
return new Error(`ElevenLabs clone API error ${response.status}: ${errorText || response.statusText}`);
|
|
126
|
+
}
|
|
127
|
+
const json = await response.json().catch((cause) => new Error('ElevenLabs clone API returned invalid JSON', { cause }));
|
|
128
|
+
if (json instanceof Error)
|
|
129
|
+
return json;
|
|
130
|
+
if (!json.voice_id)
|
|
131
|
+
return new Error('ElevenLabs clone API response did not include a voice_id');
|
|
132
|
+
return {
|
|
133
|
+
voiceId: json.voice_id,
|
|
134
|
+
name: opts.name.trim(),
|
|
135
|
+
provider: 'elevenlabs',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
// ─── main entry point ───────────────────────────────────────────────────────
|
|
139
|
+
export async function cloneVoiceUncached(opts) {
|
|
140
|
+
injectCredentialsToEnv();
|
|
141
|
+
const validationError = validateOptions(opts);
|
|
142
|
+
if (validationError)
|
|
143
|
+
return validationError;
|
|
144
|
+
if (opts.provider === 'elevenlabs') {
|
|
145
|
+
return cloneVoiceElevenLabs(opts);
|
|
146
|
+
}
|
|
147
|
+
return cloneVoiceCartesia(opts);
|
|
148
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/cli/credentials.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE5C,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAKD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAoElD,CAAA;AAED,eAAO,MAAM,iBAAiB,4BAA4B,CAAA;AAa1D,oGAAoG;AACpG,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAA;AAC5D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;AAEzD,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,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAIvD;AAED,wBAAgB,cAAc,IAAI,WAAW,GAAG,SAAS,CAOxD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAI/C;AAED,wBAAgB,UAAU,IAAI,OAAO,GAAG,SAAS,CAKhD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIxD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAInE;AASD,wBAAgB,sBAAsB,IAAI,IAAI,CAkB7C;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAID,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG;IAC9C,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;CAC5C,CA0CA"}
|
|
@@ -58,6 +58,26 @@ export const PROVIDERS = {
|
|
|
58
58
|
hint: 'Sign in with your xAI / Grok account via browser',
|
|
59
59
|
oauth: true,
|
|
60
60
|
},
|
|
61
|
+
elevenlabs: {
|
|
62
|
+
envVar: 'ELEVENLABS_API_KEY',
|
|
63
|
+
label: 'ElevenLabs (speech)',
|
|
64
|
+
hint: 'Get your key at https://elevenlabs.io/app/settings/api-keys',
|
|
65
|
+
},
|
|
66
|
+
cartesia: {
|
|
67
|
+
envVar: 'CARTESIA_API_KEY',
|
|
68
|
+
label: 'Cartesia (speech)',
|
|
69
|
+
hint: 'Get your key at https://play.cartesia.ai/keys',
|
|
70
|
+
},
|
|
71
|
+
deepgram: {
|
|
72
|
+
envVar: 'DEEPGRAM_API_KEY',
|
|
73
|
+
label: 'Deepgram (transcription)',
|
|
74
|
+
hint: 'Get your key at https://console.deepgram.com/api-keys',
|
|
75
|
+
},
|
|
76
|
+
groq: {
|
|
77
|
+
envVar: 'GROQ_API_KEY',
|
|
78
|
+
label: 'Groq (fast transcription)',
|
|
79
|
+
hint: 'Get your key at https://console.groq.com/keys',
|
|
80
|
+
},
|
|
61
81
|
};
|
|
62
82
|
export const EGAKI_GATEWAY_URL = 'https://egaki.org/v3/ai';
|
|
63
83
|
function getConfigDir() {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SpeechProvider } from './speech-generate.js';
|
|
2
|
+
import type { WordTimestamp } from './transcription-generate.js';
|
|
3
|
+
interface CharacterAlignment {
|
|
4
|
+
characters: string[];
|
|
5
|
+
character_start_times_seconds: number[];
|
|
6
|
+
character_end_times_seconds: number[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Group character-level timestamps into word-level timestamps.
|
|
10
|
+
* Characters are grouped by splitting on whitespace characters.
|
|
11
|
+
* Each word's start time is the start of its first character,
|
|
12
|
+
* and its end time is the end of its last character.
|
|
13
|
+
*/
|
|
14
|
+
export declare function groupCharactersToWords(alignment: CharacterAlignment): WordTimestamp[];
|
|
15
|
+
/**
|
|
16
|
+
* Parse an ElevenLabs NDJSON stream into audio chunks and character alignment.
|
|
17
|
+
* Each line is a JSON object with audio_base64 and optional alignment data.
|
|
18
|
+
* Alignment is typically only in the first chunk.
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseElevenLabsStream(body: ReadableStream<Uint8Array>): Promise<{
|
|
21
|
+
audioChunks: Uint8Array[];
|
|
22
|
+
alignment?: CharacterAlignment;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function createElevenLabsSpeechProvider(): SpeechProvider;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=elevenlabs-speech-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elevenlabs-speech-provider.d.ts","sourceRoot":"","sources":["../../src/cli/elevenlabs-speech-provider.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAA+C,MAAM,sBAAsB,CAAA;AACvG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAsChE,UAAU,kBAAkB;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,6BAA6B,EAAE,MAAM,EAAE,CAAA;IACvC,2BAA2B,EAAE,MAAM,EAAE,CAAA;CACtC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,kBAAkB,GAAG,aAAa,EAAE,CA+BrF;AAYD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,GAC/B,OAAO,CAAC;IAAE,WAAW,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAsDxE;AAgBD,wBAAgB,8BAA8B,IAAI,cAAc,CA2D/D"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// ElevenLabs speech provider for egaki.
|
|
2
|
+
// Uses the streaming endpoint /v1/text-to-speech/{voiceId}/stream/with-timestamps
|
|
3
|
+
// to get audio chunks + character timestamps in a single streamed response.
|
|
4
|
+
// Character-level alignment is grouped into word-level timestamps.
|
|
5
|
+
//
|
|
6
|
+
// API docs: https://elevenlabs.io/docs/api-reference/text-to-speech/stream-with-timestamps
|
|
7
|
+
//
|
|
8
|
+
// The streaming response is NDJSON (newline-delimited JSON), NOT SSE.
|
|
9
|
+
// Each line is a JSON object: { audio_base64, alignment?, normalized_alignment? }
|
|
10
|
+
// Alignment data (character-level timing) is included in the first chunk only.
|
|
11
|
+
// We use `normalized_alignment` (timing of what was actually spoken).
|
|
12
|
+
const ELEVENLABS_API_BASE = 'https://api.elevenlabs.io';
|
|
13
|
+
const DEFAULT_VOICE_ID = '21m00Tcm4TlvDq8ikWAM'; // Rachel
|
|
14
|
+
// ─── format mapping ──────────────────────────────────────────────────────────
|
|
15
|
+
const FORMAT_MAP = {
|
|
16
|
+
mp3: 'mp3_44100_128',
|
|
17
|
+
mp3_32: 'mp3_44100_32',
|
|
18
|
+
mp3_64: 'mp3_44100_64',
|
|
19
|
+
mp3_96: 'mp3_44100_96',
|
|
20
|
+
mp3_128: 'mp3_44100_128',
|
|
21
|
+
mp3_192: 'mp3_44100_192',
|
|
22
|
+
pcm: 'pcm_44100',
|
|
23
|
+
pcm_16000: 'pcm_16000',
|
|
24
|
+
pcm_22050: 'pcm_22050',
|
|
25
|
+
pcm_24000: 'pcm_24000',
|
|
26
|
+
pcm_44100: 'pcm_44100',
|
|
27
|
+
ulaw: 'ulaw_8000',
|
|
28
|
+
};
|
|
29
|
+
function resolveOutputFormat(format) {
|
|
30
|
+
if (!format)
|
|
31
|
+
return 'mp3_44100_128';
|
|
32
|
+
return FORMAT_MAP[format] || format;
|
|
33
|
+
}
|
|
34
|
+
function formatToMediaType(format) {
|
|
35
|
+
if (format.startsWith('mp3'))
|
|
36
|
+
return 'audio/mpeg';
|
|
37
|
+
if (format.startsWith('pcm'))
|
|
38
|
+
return 'audio/pcm';
|
|
39
|
+
if (format.startsWith('ulaw'))
|
|
40
|
+
return 'audio/basic';
|
|
41
|
+
if (format.startsWith('opus'))
|
|
42
|
+
return 'audio/opus';
|
|
43
|
+
if (format.startsWith('wav'))
|
|
44
|
+
return 'audio/wav';
|
|
45
|
+
return 'audio/mpeg';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Group character-level timestamps into word-level timestamps.
|
|
49
|
+
* Characters are grouped by splitting on whitespace characters.
|
|
50
|
+
* Each word's start time is the start of its first character,
|
|
51
|
+
* and its end time is the end of its last character.
|
|
52
|
+
*/
|
|
53
|
+
export function groupCharactersToWords(alignment) {
|
|
54
|
+
const words = [];
|
|
55
|
+
let currentWord = '';
|
|
56
|
+
let wordStart = -1;
|
|
57
|
+
let wordEnd = -1;
|
|
58
|
+
for (let i = 0; i < alignment.characters.length; i++) {
|
|
59
|
+
const char = alignment.characters[i];
|
|
60
|
+
const charStart = alignment.character_start_times_seconds[i];
|
|
61
|
+
const charEnd = alignment.character_end_times_seconds[i];
|
|
62
|
+
if (/\s/.test(char)) {
|
|
63
|
+
if (currentWord) {
|
|
64
|
+
words.push({ word: currentWord, startSecond: wordStart, endSecond: wordEnd });
|
|
65
|
+
currentWord = '';
|
|
66
|
+
wordStart = -1;
|
|
67
|
+
wordEnd = -1;
|
|
68
|
+
}
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
currentWord += char;
|
|
72
|
+
if (wordStart < 0)
|
|
73
|
+
wordStart = charStart;
|
|
74
|
+
wordEnd = charEnd;
|
|
75
|
+
}
|
|
76
|
+
if (currentWord) {
|
|
77
|
+
words.push({ word: currentWord, startSecond: wordStart, endSecond: wordEnd });
|
|
78
|
+
}
|
|
79
|
+
return words;
|
|
80
|
+
}
|
|
81
|
+
// ─── NDJSON stream parser ────────────────────────────────────────────────────
|
|
82
|
+
/**
|
|
83
|
+
* Parse an ElevenLabs NDJSON stream into audio chunks and character alignment.
|
|
84
|
+
* Each line is a JSON object with audio_base64 and optional alignment data.
|
|
85
|
+
* Alignment is typically only in the first chunk.
|
|
86
|
+
*/
|
|
87
|
+
export async function parseElevenLabsStream(body) {
|
|
88
|
+
const audioChunks = [];
|
|
89
|
+
let alignment;
|
|
90
|
+
const reader = body.pipeThrough(new TextDecoderStream()).getReader();
|
|
91
|
+
let buffer = '';
|
|
92
|
+
while (true) {
|
|
93
|
+
const { done, value } = await reader.read();
|
|
94
|
+
if (done)
|
|
95
|
+
break;
|
|
96
|
+
buffer += value;
|
|
97
|
+
// Process complete lines
|
|
98
|
+
let newlineIdx;
|
|
99
|
+
while ((newlineIdx = buffer.indexOf('\n')) >= 0) {
|
|
100
|
+
const line = buffer.slice(0, newlineIdx).trim();
|
|
101
|
+
buffer = buffer.slice(newlineIdx + 1);
|
|
102
|
+
if (!line)
|
|
103
|
+
continue;
|
|
104
|
+
let chunk;
|
|
105
|
+
try {
|
|
106
|
+
chunk = JSON.parse(line);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (chunk.audio_base64) {
|
|
112
|
+
audioChunks.push(new Uint8Array(Buffer.from(chunk.audio_base64, 'base64')));
|
|
113
|
+
}
|
|
114
|
+
// Capture alignment from first chunk that has it
|
|
115
|
+
if (!alignment) {
|
|
116
|
+
const align = chunk.normalized_alignment || chunk.alignment;
|
|
117
|
+
if (align)
|
|
118
|
+
alignment = align;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Process any remaining data in buffer (last line without trailing newline)
|
|
123
|
+
const remaining = buffer.trim();
|
|
124
|
+
if (remaining) {
|
|
125
|
+
try {
|
|
126
|
+
const chunk = JSON.parse(remaining);
|
|
127
|
+
if (chunk.audio_base64) {
|
|
128
|
+
audioChunks.push(new Uint8Array(Buffer.from(chunk.audio_base64, 'base64')));
|
|
129
|
+
}
|
|
130
|
+
if (!alignment) {
|
|
131
|
+
const align = chunk.normalized_alignment || chunk.alignment;
|
|
132
|
+
if (align)
|
|
133
|
+
alignment = align;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch { /* ignore malformed trailing data */ }
|
|
137
|
+
}
|
|
138
|
+
return { audioChunks, alignment };
|
|
139
|
+
}
|
|
140
|
+
/** Concatenate multiple Uint8Array chunks into one. */
|
|
141
|
+
function concatUint8Arrays(chunks) {
|
|
142
|
+
const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
|
|
143
|
+
const result = new Uint8Array(totalLength);
|
|
144
|
+
let offset = 0;
|
|
145
|
+
for (const chunk of chunks) {
|
|
146
|
+
result.set(chunk, offset);
|
|
147
|
+
offset += chunk.length;
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
// ─── provider ────────────────────────────────────────────────────────────────
|
|
152
|
+
export function createElevenLabsSpeechProvider() {
|
|
153
|
+
return {
|
|
154
|
+
async generate(options) {
|
|
155
|
+
const apiKey = process.env['ELEVENLABS_API_KEY'];
|
|
156
|
+
if (!apiKey) {
|
|
157
|
+
throw new Error('Missing ELEVENLABS_API_KEY. Run: egaki login --provider elevenlabs --key <key>');
|
|
158
|
+
}
|
|
159
|
+
const voiceId = options.voice || DEFAULT_VOICE_ID;
|
|
160
|
+
const outputFormat = resolveOutputFormat(options.outputFormat);
|
|
161
|
+
const body = {
|
|
162
|
+
text: options.text,
|
|
163
|
+
model_id: options.modelId,
|
|
164
|
+
};
|
|
165
|
+
if (options.language) {
|
|
166
|
+
body.language_code = options.language;
|
|
167
|
+
}
|
|
168
|
+
if (options.speed != null) {
|
|
169
|
+
body.voice_settings = { speed: options.speed };
|
|
170
|
+
}
|
|
171
|
+
const queryParams = new URLSearchParams({ output_format: outputFormat });
|
|
172
|
+
const url = `${ELEVENLABS_API_BASE}/v1/text-to-speech/${voiceId}/stream/with-timestamps?${queryParams}`;
|
|
173
|
+
const response = await fetch(url, {
|
|
174
|
+
method: 'POST',
|
|
175
|
+
headers: {
|
|
176
|
+
'Content-Type': 'application/json',
|
|
177
|
+
'xi-api-key': apiKey,
|
|
178
|
+
},
|
|
179
|
+
body: JSON.stringify(body),
|
|
180
|
+
signal: options.abortSignal,
|
|
181
|
+
});
|
|
182
|
+
if (!response.ok) {
|
|
183
|
+
const errorText = await response.text().catch(() => '');
|
|
184
|
+
throw new Error(`ElevenLabs TTS API error ${response.status}: ${errorText || response.statusText}`);
|
|
185
|
+
}
|
|
186
|
+
if (!response.body) {
|
|
187
|
+
throw new Error('ElevenLabs TTS stream response has no body');
|
|
188
|
+
}
|
|
189
|
+
const { audioChunks, alignment } = await parseElevenLabsStream(response.body);
|
|
190
|
+
const audio = concatUint8Arrays(audioChunks);
|
|
191
|
+
const timestamps = alignment ? groupCharactersToWords(alignment) : undefined;
|
|
192
|
+
return {
|
|
193
|
+
audio,
|
|
194
|
+
mediaType: formatToMediaType(outputFormat),
|
|
195
|
+
timestamps,
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { ValidationError } from './models.js';
|
|
2
|
+
export { ValidationError };
|
|
3
|
+
/** Image model IDs from the catalog. Accepts arbitrary strings too. */
|
|
4
|
+
export type ImageModelId = 'imagen-4.0-generate-001' | 'imagen-4.0-ultra-generate-001' | 'imagen-4.0-fast-generate-001' | 'gemini-2.0-flash-exp-image-generation' | 'gemini-2.5-flash-image' | 'gemini-3-pro-image-preview' | 'gemini-3.1-flash-image-preview' | 'vertex/imagen-4.0-generate-001' | 'vertex/imagen-4.0-ultra-generate-001' | 'vertex/imagen-4.0-fast-generate-001' | 'vertex/gemini-2.5-flash-image' | 'vertex/gemini-3-pro-image-preview' | 'vertex/gemini-3.1-flash-image-preview' | 'flux-kontext-max' | 'flux-kontext-pro' | 'flux-pro-1.0-fill' | 'flux-pro-1.1' | 'flux-pro-1.1-ultra' | 'flux-2-pro' | 'flux-2-max' | 'flux-2-flex' | 'flux-2-klein-9b' | 'flux-2-klein-4b' | 'recraft-v2' | 'recraft-v3' | 'recraft-v4' | 'recraft-v4-pro' | 'recraft-v4.1' | 'recraft-v4.1-pro' | 'recraft-v4.1-utility' | 'recraft-v4.1-utility-pro' | 'seedream-5.0-lite' | 'seedream-4.5' | 'seedream-4.0' | 'grok-imagine-image' | 'grok-imagine-image-quality' | 'dall-e-2' | 'dall-e-3' | 'gpt-image-1' | 'gpt-image-1-mini' | 'gpt-image-1.5' | 'gpt-image-2' | 'chatgpt-image-latest' | (string & {});
|
|
5
|
+
/** Video model IDs from the catalog. Accepts arbitrary strings too. */
|
|
6
|
+
export type VideoModelId = 'veo-3.1-generate-001' | 'veo-3.1-fast-generate-001' | 'veo-3.0-generate-001' | 'veo-3.0-fast-generate-001' | 'vertex/veo-3.1-generate-001' | 'vertex/veo-3.1-fast-generate-001' | 'grok-imagine-video' | 'grok-imagine-video-1.5' | 'kling-v3.0-t2v' | 'kling-v3.0-i2v' | 'kling-v3.0-motion-control' | 'kling-v2.6-t2v' | 'kling-v2.6-i2v' | 'kling-v2.6-motion-control' | 'kling-v2.5-turbo-t2v' | 'kling-v2.5-turbo-i2v' | 'wan-v2.6-t2v' | 'wan-v2.6-i2v' | 'wan-v2.6-i2v-flash' | 'wan-v2.6-r2v' | 'wan-v2.6-r2v-flash' | 'wan-v2.5-t2v-preview' | 'seedance-2.0' | 'seedance-2.0-fast' | 'seedance-v1.5-pro' | 'seedance-v1.0-pro' | 'seedance-v1.0-pro-fast' | 'seedance-v1.0-lite-t2v' | 'seedance-v1.0-lite-i2v' | 'luma-ray-2' | 'minimax-video' | 'hunyuan-video' | (string & {});
|
|
7
|
+
/** Common aspect ratios across providers. */
|
|
8
|
+
export type AspectRatio = '1:1' | '3:4' | '4:3' | '9:16' | '16:9' | '2:3' | '3:2' | '4:5' | '5:4' | '9:21' | '21:9' | (string & {});
|
|
9
|
+
/** Image quality presets (varies by provider). */
|
|
10
|
+
export type ImageQuality = 'auto' | 'low' | 'medium' | 'high' | 'standard' | (string & {});
|
|
11
|
+
/** Image output formats. */
|
|
12
|
+
export type ImageOutputFormat = 'png' | 'jpeg' | 'webp' | (string & {});
|
|
13
|
+
export type GeneratedFile = {
|
|
14
|
+
uint8Array: Uint8Array;
|
|
15
|
+
mediaType: string;
|
|
16
|
+
};
|
|
17
|
+
export interface GenerateImageOptions {
|
|
18
|
+
prompt: string;
|
|
19
|
+
/** Model ID. Defaults to DEFAULT_MODEL if omitted. */
|
|
20
|
+
model?: ImageModelId;
|
|
21
|
+
count?: number;
|
|
22
|
+
aspectRatio?: AspectRatio;
|
|
23
|
+
seed?: number;
|
|
24
|
+
inputImages?: Uint8Array[];
|
|
25
|
+
maskImage?: Uint8Array;
|
|
26
|
+
allowPeople?: boolean;
|
|
27
|
+
quality?: ImageQuality;
|
|
28
|
+
resolution?: string;
|
|
29
|
+
outputFormat?: ImageOutputFormat;
|
|
30
|
+
negativePrompt?: string;
|
|
31
|
+
/** Only for text-model image generation (Gemini). */
|
|
32
|
+
imageSize?: '1K' | '2K' | '4K';
|
|
33
|
+
}
|
|
34
|
+
export interface GenerateImageResult {
|
|
35
|
+
images: GeneratedFile[];
|
|
36
|
+
model: string;
|
|
37
|
+
cost: number | null;
|
|
38
|
+
usage?: {
|
|
39
|
+
inputTokens?: number;
|
|
40
|
+
outputTokens?: number;
|
|
41
|
+
};
|
|
42
|
+
warnings?: unknown[];
|
|
43
|
+
/** Text response from text-model path (Gemini). */
|
|
44
|
+
text?: string;
|
|
45
|
+
/** Revised prompt from ChatGPT Responses API path. */
|
|
46
|
+
revisedPrompt?: string | null;
|
|
47
|
+
}
|
|
48
|
+
export interface GenerateVideoOptions {
|
|
49
|
+
prompt: string;
|
|
50
|
+
/** Model ID. Defaults to DEFAULT_VIDEO_MODEL if omitted. */
|
|
51
|
+
model?: VideoModelId;
|
|
52
|
+
count?: number;
|
|
53
|
+
aspectRatio?: AspectRatio;
|
|
54
|
+
resolution?: string;
|
|
55
|
+
duration?: number;
|
|
56
|
+
fps?: number;
|
|
57
|
+
seed?: number;
|
|
58
|
+
inputImage?: Uint8Array;
|
|
59
|
+
mode?: 'edit-video' | 'extend-video' | 'reference-to-video';
|
|
60
|
+
/** URL for video editing/extension input. Must be a URL (not a local path). */
|
|
61
|
+
videoUrl?: string;
|
|
62
|
+
/** Reference image URLs for r2v generation. Must be URLs (not local paths). */
|
|
63
|
+
referenceImages?: string[];
|
|
64
|
+
negativePrompt?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface GenerateVideoResult {
|
|
67
|
+
videos: GeneratedFile[];
|
|
68
|
+
model: string;
|
|
69
|
+
cost: number | null;
|
|
70
|
+
warnings?: unknown[];
|
|
71
|
+
/** Raw responses from the AI SDK (provider-specific). */
|
|
72
|
+
responses?: unknown[];
|
|
73
|
+
}
|
|
74
|
+
type ProviderOptionsResult = Record<string, Record<string, string | number | boolean | string[] | null | undefined | Record<string, string | number | boolean | null | undefined>>>;
|
|
75
|
+
export declare function buildImageProviderOptions(provider: string, opts: {
|
|
76
|
+
aspectRatio?: `${number}:${number}`;
|
|
77
|
+
allowPeople: boolean;
|
|
78
|
+
quality?: string;
|
|
79
|
+
resolution?: string;
|
|
80
|
+
outputFormat?: string;
|
|
81
|
+
negativePrompt?: string;
|
|
82
|
+
}): ProviderOptionsResult;
|
|
83
|
+
export declare function buildVideoProviderOptions(provider: string, opts: {
|
|
84
|
+
resolution?: string;
|
|
85
|
+
mode?: string;
|
|
86
|
+
videoUrl?: string;
|
|
87
|
+
referenceImages?: string[];
|
|
88
|
+
negativePrompt?: string;
|
|
89
|
+
model: string;
|
|
90
|
+
}): ProviderOptionsResult | undefined;
|
|
91
|
+
export declare function calculateCost(cost: {
|
|
92
|
+
type: 'per-image';
|
|
93
|
+
perImage: number;
|
|
94
|
+
} | {
|
|
95
|
+
type: 'per-token';
|
|
96
|
+
inputPerM: number;
|
|
97
|
+
outputPerM: number;
|
|
98
|
+
} | {
|
|
99
|
+
type: 'per-video-second';
|
|
100
|
+
defaultDurationSec: number;
|
|
101
|
+
tiers: Array<{
|
|
102
|
+
resolution?: string;
|
|
103
|
+
costPerSecond: number;
|
|
104
|
+
hasVideoInput?: boolean;
|
|
105
|
+
}>;
|
|
106
|
+
} | {
|
|
107
|
+
type: 'unknown';
|
|
108
|
+
}, usage: {
|
|
109
|
+
inputTokens?: number;
|
|
110
|
+
outputTokens?: number;
|
|
111
|
+
imagesGenerated?: number;
|
|
112
|
+
videosGenerated?: number;
|
|
113
|
+
durationSeconds?: number;
|
|
114
|
+
resolution?: string;
|
|
115
|
+
hasVideoInput?: boolean;
|
|
116
|
+
}, count?: number): number | null;
|
|
117
|
+
/**
|
|
118
|
+
* Generate images from a text prompt. Auto-detects which generation strategy
|
|
119
|
+
* to use (image API, text model, or ChatGPT Responses API) based on model ID.
|
|
120
|
+
* Shares credentials and subscription with the CLI.
|
|
121
|
+
*/
|
|
122
|
+
export declare function generateImageUncached(opts: GenerateImageOptions): Promise<Error | GenerateImageResult>;
|
|
123
|
+
/**
|
|
124
|
+
* Generate videos from a text prompt (or image+text for i2v models).
|
|
125
|
+
* Shares credentials and subscription with the CLI.
|
|
126
|
+
*/
|
|
127
|
+
export declare function generateVideoUncached(opts: GenerateVideoOptions): Promise<Error | GenerateVideoResult>;
|
|
128
|
+
export interface CachedGenerateResult {
|
|
129
|
+
/** Public URL path (e.g. `/generated/image/sunset-a1b2c3d4.png`) */
|
|
130
|
+
src: string;
|
|
131
|
+
}
|
|
132
|
+
export declare const generateImage: import("./cached-generate.js").CachedGenerateFn<GenerateImageOptions & {
|
|
133
|
+
seed?: number;
|
|
134
|
+
}, CachedGenerateResult>;
|
|
135
|
+
export declare const generateVideo: import("./cached-generate.js").CachedGenerateFn<GenerateVideoOptions & {
|
|
136
|
+
seed?: number;
|
|
137
|
+
}, CachedGenerateResult>;
|
|
138
|
+
export { generateSpeech, generateSpeechUncached, calculateSpeechCost, type GenerateSpeechOptions, type GenerateSpeechResult, type CachedSpeechResult, type SpeechProvider, type SpeechProviderOptions, type SpeechProviderResult, } from './speech-generate.js';
|
|
139
|
+
export { transcribeAudio, transcribeAudioUncached, calculateTranscriptionCost, segmentsToWordTimestamps, wordTimestampsToCaptions, type TranscribeOptions, type TranscribeResult, type WordTimestamp, type TranscriptionSegment, } from './transcription-generate.js';
|
|
140
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"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"}
|