vargai 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.
Files changed (154) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.env.example +27 -0
  3. package/.github/workflows/ci.yml +23 -0
  4. package/.husky/README.md +102 -0
  5. package/.husky/commit-msg +6 -0
  6. package/.husky/pre-commit +9 -0
  7. package/.husky/pre-push +6 -0
  8. package/.size-limit.json +8 -0
  9. package/.test-hooks.ts +5 -0
  10. package/CLAUDE.md +125 -0
  11. package/CONTRIBUTING.md +150 -0
  12. package/LICENSE.md +53 -0
  13. package/README.md +78 -0
  14. package/SKILLS.md +173 -0
  15. package/STRUCTURE.md +92 -0
  16. package/biome.json +34 -0
  17. package/bun.lock +1254 -0
  18. package/commitlint.config.js +22 -0
  19. package/docs/plan.md +66 -0
  20. package/docs/todo.md +14 -0
  21. package/docs/varg-sdk.md +812 -0
  22. package/ffmpeg/CLAUDE.md +68 -0
  23. package/package.json +69 -0
  24. package/pipeline/cookbooks/SKILL.md +285 -0
  25. package/pipeline/cookbooks/remotion-video.md +585 -0
  26. package/pipeline/cookbooks/round-video-character.md +337 -0
  27. package/pipeline/cookbooks/scripts/animate-frames-parallel.ts +84 -0
  28. package/pipeline/cookbooks/scripts/combine-scenes.sh +53 -0
  29. package/pipeline/cookbooks/scripts/generate-frames-parallel.ts +99 -0
  30. package/pipeline/cookbooks/scripts/still-to-video.sh +37 -0
  31. package/pipeline/cookbooks/talking-character.md +59 -0
  32. package/pipeline/cookbooks/text-to-tiktok.md +669 -0
  33. package/pipeline/cookbooks/trendwatching.md +156 -0
  34. package/plan.md +281 -0
  35. package/scripts/.gitkeep +0 -0
  36. package/src/ai-sdk/cache.ts +142 -0
  37. package/src/ai-sdk/examples/cached-generation.ts +53 -0
  38. package/src/ai-sdk/examples/duet-scene-4.ts +53 -0
  39. package/src/ai-sdk/examples/duet-scene-5-audio.ts +32 -0
  40. package/src/ai-sdk/examples/duet-video.ts +56 -0
  41. package/src/ai-sdk/examples/editly-composition.ts +63 -0
  42. package/src/ai-sdk/examples/editly-test.ts +57 -0
  43. package/src/ai-sdk/examples/editly-video-test.ts +52 -0
  44. package/src/ai-sdk/examples/fal-lipsync.ts +43 -0
  45. package/src/ai-sdk/examples/higgsfield-image.ts +61 -0
  46. package/src/ai-sdk/examples/music-generation.ts +19 -0
  47. package/src/ai-sdk/examples/openai-sora.ts +34 -0
  48. package/src/ai-sdk/examples/replicate-bg-removal.ts +52 -0
  49. package/src/ai-sdk/examples/simpsons-scene.ts +61 -0
  50. package/src/ai-sdk/examples/talking-lion.ts +55 -0
  51. package/src/ai-sdk/examples/video-generation.ts +39 -0
  52. package/src/ai-sdk/examples/workflow-animated-girl.ts +104 -0
  53. package/src/ai-sdk/examples/workflow-before-after.ts +114 -0
  54. package/src/ai-sdk/examples/workflow-character-grid.ts +112 -0
  55. package/src/ai-sdk/examples/workflow-slideshow.ts +161 -0
  56. package/src/ai-sdk/file-cache.ts +112 -0
  57. package/src/ai-sdk/file.ts +238 -0
  58. package/src/ai-sdk/generate-element.ts +92 -0
  59. package/src/ai-sdk/generate-music.ts +46 -0
  60. package/src/ai-sdk/generate-video.ts +165 -0
  61. package/src/ai-sdk/index.ts +72 -0
  62. package/src/ai-sdk/music-model.ts +110 -0
  63. package/src/ai-sdk/providers/editly/editly.test.ts +1108 -0
  64. package/src/ai-sdk/providers/editly/ffmpeg.ts +60 -0
  65. package/src/ai-sdk/providers/editly/index.ts +817 -0
  66. package/src/ai-sdk/providers/editly/layers.ts +772 -0
  67. package/src/ai-sdk/providers/editly/plan.md +144 -0
  68. package/src/ai-sdk/providers/editly/types.ts +328 -0
  69. package/src/ai-sdk/providers/elevenlabs-provider.ts +255 -0
  70. package/src/ai-sdk/providers/fal-provider.ts +512 -0
  71. package/src/ai-sdk/providers/higgsfield.ts +379 -0
  72. package/src/ai-sdk/providers/openai.ts +251 -0
  73. package/src/ai-sdk/providers/replicate.ts +16 -0
  74. package/src/ai-sdk/video-model.ts +185 -0
  75. package/src/cli/commands/find.tsx +137 -0
  76. package/src/cli/commands/help.tsx +85 -0
  77. package/src/cli/commands/index.ts +9 -0
  78. package/src/cli/commands/list.tsx +238 -0
  79. package/src/cli/commands/run.tsx +511 -0
  80. package/src/cli/commands/which.tsx +253 -0
  81. package/src/cli/index.ts +112 -0
  82. package/src/cli/quiet.ts +44 -0
  83. package/src/cli/types.ts +32 -0
  84. package/src/cli/ui/components/Badge.tsx +29 -0
  85. package/src/cli/ui/components/DataTable.tsx +51 -0
  86. package/src/cli/ui/components/Header.tsx +23 -0
  87. package/src/cli/ui/components/HelpBlock.tsx +44 -0
  88. package/src/cli/ui/components/KeyValue.tsx +33 -0
  89. package/src/cli/ui/components/OptionRow.tsx +81 -0
  90. package/src/cli/ui/components/Separator.tsx +23 -0
  91. package/src/cli/ui/components/StatusBox.tsx +108 -0
  92. package/src/cli/ui/components/VargBox.tsx +51 -0
  93. package/src/cli/ui/components/VargProgress.tsx +36 -0
  94. package/src/cli/ui/components/VargSpinner.tsx +34 -0
  95. package/src/cli/ui/components/VargText.tsx +56 -0
  96. package/src/cli/ui/components/index.ts +19 -0
  97. package/src/cli/ui/index.ts +12 -0
  98. package/src/cli/ui/render.ts +35 -0
  99. package/src/cli/ui/theme.ts +63 -0
  100. package/src/cli/utils.ts +78 -0
  101. package/src/core/executor/executor.ts +201 -0
  102. package/src/core/executor/index.ts +13 -0
  103. package/src/core/executor/job.ts +214 -0
  104. package/src/core/executor/pipeline.ts +222 -0
  105. package/src/core/index.ts +11 -0
  106. package/src/core/registry/index.ts +9 -0
  107. package/src/core/registry/loader.ts +149 -0
  108. package/src/core/registry/registry.ts +221 -0
  109. package/src/core/registry/resolver.ts +206 -0
  110. package/src/core/schema/helpers.ts +134 -0
  111. package/src/core/schema/index.ts +8 -0
  112. package/src/core/schema/shared.ts +102 -0
  113. package/src/core/schema/types.ts +279 -0
  114. package/src/core/schema/validator.ts +92 -0
  115. package/src/definitions/actions/captions.ts +261 -0
  116. package/src/definitions/actions/edit.ts +298 -0
  117. package/src/definitions/actions/image.ts +125 -0
  118. package/src/definitions/actions/index.ts +114 -0
  119. package/src/definitions/actions/music.ts +205 -0
  120. package/src/definitions/actions/sync.ts +128 -0
  121. package/src/definitions/actions/transcribe.ts +200 -0
  122. package/src/definitions/actions/upload.ts +111 -0
  123. package/src/definitions/actions/video.ts +163 -0
  124. package/src/definitions/actions/voice.ts +119 -0
  125. package/src/definitions/index.ts +23 -0
  126. package/src/definitions/models/elevenlabs.ts +50 -0
  127. package/src/definitions/models/flux.ts +56 -0
  128. package/src/definitions/models/index.ts +36 -0
  129. package/src/definitions/models/kling.ts +56 -0
  130. package/src/definitions/models/llama.ts +54 -0
  131. package/src/definitions/models/nano-banana-pro.ts +102 -0
  132. package/src/definitions/models/sonauto.ts +68 -0
  133. package/src/definitions/models/soul.ts +65 -0
  134. package/src/definitions/models/wan.ts +54 -0
  135. package/src/definitions/models/whisper.ts +44 -0
  136. package/src/definitions/skills/index.ts +12 -0
  137. package/src/definitions/skills/talking-character.ts +87 -0
  138. package/src/definitions/skills/text-to-tiktok.ts +97 -0
  139. package/src/index.ts +118 -0
  140. package/src/providers/apify.ts +269 -0
  141. package/src/providers/base.ts +264 -0
  142. package/src/providers/elevenlabs.ts +217 -0
  143. package/src/providers/fal.ts +392 -0
  144. package/src/providers/ffmpeg.ts +544 -0
  145. package/src/providers/fireworks.ts +193 -0
  146. package/src/providers/groq.ts +149 -0
  147. package/src/providers/higgsfield.ts +145 -0
  148. package/src/providers/index.ts +143 -0
  149. package/src/providers/replicate.ts +147 -0
  150. package/src/providers/storage.ts +206 -0
  151. package/src/tests/all.test.ts +509 -0
  152. package/src/tests/index.ts +33 -0
  153. package/src/tests/unit.test.ts +403 -0
  154. package/tsconfig.json +45 -0
@@ -0,0 +1,238 @@
1
+ import type { ImageModelV3File } from "@ai-sdk/provider";
2
+
3
+ export class File {
4
+ private _data: Uint8Array | null = null;
5
+ private _url: string | null = null;
6
+ private _mediaType: string;
7
+ private _loader: (() => Promise<Uint8Array>) | null = null;
8
+
9
+ private constructor(
10
+ options:
11
+ | { data: Uint8Array; mediaType: string }
12
+ | { url: string; mediaType?: string }
13
+ | { loader: () => Promise<Uint8Array>; mediaType: string },
14
+ ) {
15
+ if ("data" in options) {
16
+ this._data = options.data;
17
+ this._mediaType = options.mediaType;
18
+ } else if ("url" in options) {
19
+ this._url = options.url;
20
+ this._mediaType = options.mediaType ?? inferMediaType(options.url);
21
+ } else {
22
+ this._loader = options.loader;
23
+ this._mediaType = options.mediaType;
24
+ }
25
+ }
26
+
27
+ static fromPath(path: string, mediaType?: string): File {
28
+ const resolvedMediaType = mediaType ?? inferMediaType(path);
29
+ return new File({
30
+ loader: async () => {
31
+ const file = Bun.file(path);
32
+ return new Uint8Array(await file.arrayBuffer());
33
+ },
34
+ mediaType: resolvedMediaType,
35
+ });
36
+ }
37
+
38
+ static fromUrl(url: string, mediaType?: string): File {
39
+ return new File({ url, mediaType });
40
+ }
41
+
42
+ static fromBuffer(data: Uint8Array, mediaType: string): File {
43
+ return new File({ data, mediaType });
44
+ }
45
+
46
+ static fromGenerated(generated: {
47
+ uint8Array: Uint8Array;
48
+ mediaType: string;
49
+ }): File {
50
+ return new File({
51
+ data: generated.uint8Array,
52
+ mediaType: generated.mediaType,
53
+ });
54
+ }
55
+
56
+ static fromArrayBuffer(buffer: ArrayBuffer, mediaType: string): File {
57
+ return new File({ data: new Uint8Array(buffer), mediaType });
58
+ }
59
+
60
+ static async fromBlob(blob: Blob, mediaType?: string): Promise<File> {
61
+ const data = new Uint8Array(await blob.arrayBuffer());
62
+ return new File({ data, mediaType: mediaType ?? blob.type });
63
+ }
64
+
65
+ static from(input: {
66
+ uint8Array: Uint8Array;
67
+ mimeType?: string;
68
+ mediaType?: string;
69
+ }): File;
70
+ static from(
71
+ input: string | Uint8Array | ArrayBuffer | Blob,
72
+ mediaType?: string,
73
+ ): File | Promise<File>;
74
+ static from(
75
+ input:
76
+ | string
77
+ | Uint8Array
78
+ | ArrayBuffer
79
+ | Blob
80
+ | { uint8Array: Uint8Array; mimeType?: string; mediaType?: string },
81
+ mediaType?: string,
82
+ ): File | Promise<File> {
83
+ if (typeof input === "object" && input !== null && "uint8Array" in input) {
84
+ const mime =
85
+ input.mimeType ?? input.mediaType ?? "application/octet-stream";
86
+ return File.fromBuffer(input.uint8Array, mime);
87
+ }
88
+ if (typeof input === "string" && /^https?:\/\//.test(input)) {
89
+ return File.fromUrl(input, mediaType);
90
+ }
91
+ if (typeof input === "string") {
92
+ return File.fromPath(input, mediaType);
93
+ }
94
+ if (input instanceof Blob) {
95
+ return File.fromBlob(input, mediaType);
96
+ }
97
+ if (input instanceof ArrayBuffer) {
98
+ return File.fromArrayBuffer(
99
+ input,
100
+ mediaType ?? "application/octet-stream",
101
+ );
102
+ }
103
+ return File.fromBuffer(input, mediaType ?? "application/octet-stream");
104
+ }
105
+
106
+ get mediaType(): string {
107
+ return this._mediaType;
108
+ }
109
+
110
+ isImage(): boolean {
111
+ return this._mediaType.startsWith("image/");
112
+ }
113
+
114
+ isAudio(): boolean {
115
+ return this._mediaType.startsWith("audio/");
116
+ }
117
+
118
+ isVideo(): boolean {
119
+ return this._mediaType.startsWith("video/");
120
+ }
121
+
122
+ async data(): Promise<Uint8Array> {
123
+ if (this._data) return this._data;
124
+ if (this._loader) {
125
+ this._data = await this._loader();
126
+ return this._data;
127
+ }
128
+ if (this._url) {
129
+ const response = await fetch(this._url);
130
+ this._data = new Uint8Array(await response.arrayBuffer());
131
+ return this._data;
132
+ }
133
+ throw new Error("File has no data source");
134
+ }
135
+
136
+ async arrayBuffer(): Promise<Uint8Array> {
137
+ return this.data();
138
+ }
139
+
140
+ async blob(): Promise<Blob> {
141
+ const data = await this.arrayBuffer();
142
+ return new Blob([data], { type: this._mediaType });
143
+ }
144
+
145
+ async url(uploader?: (blob: Blob) => Promise<string>): Promise<string> {
146
+ if (this._url && !this._data && !this._loader) {
147
+ return this._url;
148
+ }
149
+ const blob = await this.blob();
150
+ if (uploader) return uploader(blob);
151
+ try {
152
+ const { fal } = await import("@fal-ai/client");
153
+ return fal.storage.upload(blob);
154
+ } catch {
155
+ throw new Error("No uploader provided and @fal-ai/client not available.");
156
+ }
157
+ }
158
+
159
+ async base64(): Promise<string> {
160
+ const data = await this.arrayBuffer();
161
+ let binary = "";
162
+ for (let i = 0; i < data.byteLength; i++) {
163
+ binary += String.fromCharCode(data[i]!);
164
+ }
165
+ return btoa(binary);
166
+ }
167
+
168
+ async toInput(): Promise<ImageModelV3File> {
169
+ if (this._url && !this._data && !this._loader) {
170
+ return { type: "url", url: this._url };
171
+ }
172
+ const data = await this.arrayBuffer();
173
+ return { type: "file", mediaType: this._mediaType, data };
174
+ }
175
+
176
+ async toTemp(): Promise<string> {
177
+ const data = await this.data();
178
+ const ext = this.extensionFromMediaType();
179
+ const tmpDir = process.env.TMPDIR ?? "/tmp";
180
+ const filename = `varg-${Date.now()}-${Math.random().toString(36).slice(2)}${ext}`;
181
+ const path = `${tmpDir}/${filename}`;
182
+ await Bun.write(path, data);
183
+ return path;
184
+ }
185
+
186
+ static async toTemp(
187
+ file:
188
+ | { uint8Array: Uint8Array; mimeType?: string; mediaType?: string }
189
+ | File,
190
+ ): Promise<string> {
191
+ if (file instanceof File) {
192
+ return file.toTemp();
193
+ }
194
+ const f = File.from(file);
195
+ return f.toTemp();
196
+ }
197
+
198
+ private extensionFromMediaType(): string {
199
+ const extMap: Record<string, string> = {
200
+ "image/png": ".png",
201
+ "image/jpeg": ".jpg",
202
+ "image/gif": ".gif",
203
+ "image/webp": ".webp",
204
+ "audio/mpeg": ".mp3",
205
+ "audio/wav": ".wav",
206
+ "audio/mp4": ".m4a",
207
+ "video/mp4": ".mp4",
208
+ "video/webm": ".webm",
209
+ "video/quicktime": ".mov",
210
+ };
211
+ return extMap[this._mediaType] ?? "";
212
+ }
213
+ }
214
+
215
+ function inferMediaType(path: string): string {
216
+ const ext = path.split(".").pop()?.toLowerCase();
217
+ const mimeTypes: Record<string, string> = {
218
+ png: "image/png",
219
+ jpg: "image/jpeg",
220
+ jpeg: "image/jpeg",
221
+ gif: "image/gif",
222
+ webp: "image/webp",
223
+ svg: "image/svg+xml",
224
+ mp3: "audio/mpeg",
225
+ wav: "audio/wav",
226
+ ogg: "audio/ogg",
227
+ m4a: "audio/mp4",
228
+ aac: "audio/aac",
229
+ mp4: "video/mp4",
230
+ webm: "video/webm",
231
+ mov: "video/quicktime",
232
+ };
233
+ return mimeTypes[ext ?? ""] ?? "application/octet-stream";
234
+ }
235
+
236
+ export function files(...paths: string[]): File[] {
237
+ return paths.map((p) => File.fromPath(p));
238
+ }
@@ -0,0 +1,92 @@
1
+ import type { DataContent, ImageModel } from "ai";
2
+ import { generateImage } from "ai";
3
+
4
+ export type ElementType = "character" | "location" | "item";
5
+
6
+ export interface Element {
7
+ type: ElementType;
8
+ text: string;
9
+ images: Uint8Array[];
10
+ }
11
+
12
+ export interface PromptWithElements {
13
+ text: string;
14
+ images: Uint8Array[];
15
+ }
16
+
17
+ export function scene(
18
+ strings: TemplateStringsArray,
19
+ ...elements: Element[]
20
+ ): PromptWithElements {
21
+ let text = "";
22
+ const images: Uint8Array[] = [];
23
+ let imageIndex = 1;
24
+
25
+ for (let i = 0; i < strings.length; i++) {
26
+ text += strings[i];
27
+ if (i < elements.length) {
28
+ const el = elements[i]!;
29
+ const count = el.images.length;
30
+
31
+ if (count === 1) {
32
+ text += `[image ${imageIndex}: ${el.type} - ${el.text}]`;
33
+ } else if (count > 1) {
34
+ text += `[images ${imageIndex}-${imageIndex + count - 1}: ${el.type} - ${el.text}]`;
35
+ } else {
36
+ text += `[${el.type}: ${el.text}]`;
37
+ }
38
+
39
+ images.push(...el.images);
40
+ imageIndex += count;
41
+ }
42
+ }
43
+
44
+ return { text: text.trim(), images };
45
+ }
46
+
47
+ export type GenerateElementPrompt =
48
+ | string
49
+ | {
50
+ text: string;
51
+ images?: Array<DataContent>;
52
+ };
53
+
54
+ export interface GenerateElementOptions {
55
+ model: ImageModel;
56
+ type: ElementType;
57
+ prompt: GenerateElementPrompt;
58
+ n?: number;
59
+ size?: `${number}x${number}`;
60
+ aspectRatio?: `${number}:${number}`;
61
+ seed?: number;
62
+ }
63
+
64
+ export interface GenerateElementResult {
65
+ element: Element;
66
+ }
67
+
68
+ export async function generateElement(
69
+ options: GenerateElementOptions,
70
+ ): Promise<GenerateElementResult> {
71
+ const { model, type, prompt, n = 1, size, aspectRatio, seed } = options;
72
+
73
+ const text = typeof prompt === "string" ? prompt : prompt.text;
74
+ const images = typeof prompt === "string" ? undefined : prompt.images;
75
+
76
+ const { images: generatedImages } = await generateImage({
77
+ model,
78
+ prompt: images ? { text, images } : text,
79
+ n,
80
+ size,
81
+ aspectRatio,
82
+ seed,
83
+ });
84
+
85
+ return {
86
+ element: {
87
+ type,
88
+ text,
89
+ images: generatedImages.map((img) => img.uint8Array),
90
+ },
91
+ };
92
+ }
@@ -0,0 +1,46 @@
1
+ import type { SharedV3ProviderOptions } from "@ai-sdk/provider";
2
+ import type { MusicModelV3 } from "./music-model";
3
+
4
+ export interface GenerateMusicOptions {
5
+ model: MusicModelV3;
6
+ prompt: string;
7
+ duration?: number;
8
+ providerOptions?: SharedV3ProviderOptions;
9
+ abortSignal?: AbortSignal;
10
+ headers?: Record<string, string | undefined>;
11
+ }
12
+
13
+ export interface GenerateMusicResult {
14
+ audio: {
15
+ uint8Array: Uint8Array;
16
+ };
17
+ warnings: Array<{ type: string; feature?: string; details?: string }>;
18
+ response: {
19
+ timestamp: Date;
20
+ modelId: string;
21
+ headers: Record<string, string> | undefined;
22
+ };
23
+ }
24
+
25
+ export async function generateMusic(
26
+ options: GenerateMusicOptions,
27
+ ): Promise<GenerateMusicResult> {
28
+ const { model, prompt, duration, providerOptions, abortSignal, headers } =
29
+ options;
30
+
31
+ const result = await model.doGenerate({
32
+ prompt,
33
+ duration,
34
+ providerOptions: providerOptions ?? {},
35
+ abortSignal,
36
+ headers,
37
+ });
38
+
39
+ return {
40
+ audio: {
41
+ uint8Array: result.audio,
42
+ },
43
+ warnings: result.warnings,
44
+ response: result.response,
45
+ };
46
+ }
@@ -0,0 +1,165 @@
1
+ import type {
2
+ ImageModelV3File,
3
+ SharedV3ProviderOptions,
4
+ SharedV3Warning,
5
+ } from "@ai-sdk/provider";
6
+ import type { DataContent } from "ai";
7
+ import type { VideoModelV3 } from "./video-model";
8
+
9
+ export type GenerateVideoPrompt =
10
+ | string
11
+ | {
12
+ text?: string;
13
+ images?: Array<DataContent>;
14
+ audio?: DataContent;
15
+ video?: DataContent;
16
+ };
17
+
18
+ export interface GenerateVideoOptions {
19
+ model: VideoModelV3;
20
+ prompt: GenerateVideoPrompt;
21
+ n?: number;
22
+ resolution?: `${number}x${number}`;
23
+ aspectRatio?: `${number}:${number}`;
24
+ duration?: number;
25
+ fps?: number;
26
+ seed?: number;
27
+ providerOptions?: SharedV3ProviderOptions;
28
+ abortSignal?: AbortSignal;
29
+ headers?: Record<string, string>;
30
+ }
31
+
32
+ export interface GeneratedVideo {
33
+ readonly base64: string;
34
+ readonly uint8Array: Uint8Array;
35
+ readonly mimeType: string;
36
+ }
37
+
38
+ export interface GenerateVideoResult {
39
+ readonly video: GeneratedVideo;
40
+ readonly videos: GeneratedVideo[];
41
+ readonly warnings: SharedV3Warning[];
42
+ }
43
+
44
+ class DefaultGeneratedVideo implements GeneratedVideo {
45
+ private _data: Uint8Array;
46
+ readonly mimeType = "video/mp4";
47
+
48
+ constructor(data: Uint8Array | string) {
49
+ if (typeof data === "string") {
50
+ this._data = Uint8Array.from(atob(data), (c) => c.charCodeAt(0));
51
+ } else {
52
+ this._data = data;
53
+ }
54
+ }
55
+
56
+ get uint8Array(): Uint8Array {
57
+ return this._data;
58
+ }
59
+
60
+ get base64(): string {
61
+ let binary = "";
62
+ const bytes = this._data;
63
+ for (let i = 0; i < bytes.byteLength; i++) {
64
+ binary += String.fromCharCode(bytes[i]!);
65
+ }
66
+ return btoa(binary);
67
+ }
68
+ }
69
+
70
+ function toUint8Array(data: DataContent): Uint8Array {
71
+ if (typeof data === "string") {
72
+ return Uint8Array.from(atob(data), (c) => c.charCodeAt(0));
73
+ }
74
+ if (data instanceof ArrayBuffer) {
75
+ return new Uint8Array(data);
76
+ }
77
+ return data;
78
+ }
79
+
80
+ function normalizePrompt(prompt: GenerateVideoPrompt): {
81
+ prompt: string | undefined;
82
+ files: ImageModelV3File[] | undefined;
83
+ } {
84
+ if (typeof prompt === "string") {
85
+ return { prompt, files: undefined };
86
+ }
87
+
88
+ const files: ImageModelV3File[] = [];
89
+
90
+ for (const img of prompt.images ?? []) {
91
+ files.push({
92
+ type: "file",
93
+ mediaType: "image/png",
94
+ data: toUint8Array(img),
95
+ });
96
+ }
97
+
98
+ if (prompt.audio) {
99
+ files.push({
100
+ type: "file",
101
+ mediaType: "audio/mpeg",
102
+ data: toUint8Array(prompt.audio),
103
+ });
104
+ }
105
+
106
+ if (prompt.video) {
107
+ files.push({
108
+ type: "file",
109
+ mediaType: "video/mp4",
110
+ data: toUint8Array(prompt.video),
111
+ });
112
+ }
113
+
114
+ return {
115
+ prompt: prompt.text,
116
+ files: files.length > 0 ? files : undefined,
117
+ };
118
+ }
119
+
120
+ export async function generateVideo(
121
+ options: GenerateVideoOptions,
122
+ ): Promise<GenerateVideoResult> {
123
+ const {
124
+ model,
125
+ prompt: promptArg,
126
+ n = 1,
127
+ resolution,
128
+ aspectRatio,
129
+ duration,
130
+ fps,
131
+ seed,
132
+ providerOptions = {},
133
+ abortSignal,
134
+ headers,
135
+ } = options;
136
+
137
+ const { prompt, files } = normalizePrompt(promptArg);
138
+
139
+ const result = await model.doGenerate({
140
+ prompt: prompt ?? "",
141
+ n,
142
+ resolution,
143
+ aspectRatio,
144
+ duration,
145
+ fps,
146
+ seed,
147
+ files,
148
+ providerOptions,
149
+ abortSignal,
150
+ headers,
151
+ });
152
+
153
+ const videos = result.videos.map((v) => new DefaultGeneratedVideo(v));
154
+ const warnings = result.warnings;
155
+
156
+ if (videos.length === 0) {
157
+ throw new Error("No videos generated");
158
+ }
159
+
160
+ return {
161
+ video: videos[0]!,
162
+ videos,
163
+ warnings,
164
+ };
165
+ }
@@ -0,0 +1,72 @@
1
+ export {
2
+ type CacheStorage,
3
+ clearCache,
4
+ type WithCacheOptions,
5
+ withCache,
6
+ } from "./cache";
7
+ export { File, files } from "./file";
8
+ export { fileCache } from "./file-cache";
9
+ export {
10
+ type Element,
11
+ type ElementType,
12
+ type GenerateElementOptions,
13
+ type GenerateElementResult,
14
+ generateElement,
15
+ scene,
16
+ } from "./generate-element";
17
+ export {
18
+ type GenerateMusicOptions,
19
+ type GenerateMusicResult,
20
+ generateMusic,
21
+ } from "./generate-music";
22
+ export {
23
+ type GenerateVideoOptions,
24
+ type GenerateVideoPrompt,
25
+ type GenerateVideoResult,
26
+ generateVideo,
27
+ } from "./generate-video";
28
+ export type {
29
+ MusicModelV3,
30
+ MusicModelV3CallOptions,
31
+ MusicModelV3ProviderMetadata,
32
+ } from "./music-model";
33
+ export {
34
+ type AudioTrack,
35
+ type Clip as EditlyClip,
36
+ type EditlyConfig,
37
+ editly,
38
+ type Layer as EditlyLayer,
39
+ } from "./providers/editly";
40
+ export {
41
+ createElevenLabs,
42
+ type ElevenLabsProvider,
43
+ elevenlabs,
44
+ VOICES,
45
+ } from "./providers/elevenlabs-provider";
46
+ export { createFal, type FalProvider, fal } from "./providers/fal-provider";
47
+ export {
48
+ createHiggsfield,
49
+ type HiggsfieldImageModelSettings,
50
+ type HiggsfieldProvider,
51
+ type HiggsfieldProviderSettings,
52
+ higgsfield,
53
+ } from "./providers/higgsfield";
54
+ export {
55
+ createOpenAI,
56
+ type OpenAIProvider,
57
+ type OpenAIProviderSettings,
58
+ openai,
59
+ } from "./providers/openai";
60
+ export {
61
+ createReplicate,
62
+ type ReplicateProvider,
63
+ type ReplicateProviderSettings,
64
+ replicate,
65
+ } from "./providers/replicate";
66
+ export type {
67
+ VideoModelV3,
68
+ VideoModelV3CallOptions,
69
+ VideoModelV3File,
70
+ VideoModelV3ProviderMetadata,
71
+ VideoModelV3Usage,
72
+ } from "./video-model";