vargai 0.4.0-alpha12 → 0.4.0-alpha14

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/package.json CHANGED
@@ -64,7 +64,7 @@
64
64
  "replicate": "^1.4.0",
65
65
  "zod": "^4.2.1"
66
66
  },
67
- "version": "0.4.0-alpha12",
67
+ "version": "0.4.0-alpha14",
68
68
  "exports": {
69
69
  ".": "./src/index.ts",
70
70
  "./ai": "./src/ai-sdk/index.ts",
@@ -1,14 +1,32 @@
1
1
  import { existsSync, mkdirSync } from "node:fs";
2
- import { dirname, resolve } from "node:path";
2
+ import { resolve } from "node:path";
3
3
  import { defineCommand } from "citty";
4
4
  import { render } from "../../react/render";
5
- import type { RenderMode, VargElement } from "../../react/types";
5
+ import type { DefaultModels, RenderMode, VargElement } from "../../react/types";
6
6
 
7
7
  const AUTO_IMPORTS = `/** @jsxImportSource vargai */
8
8
  import { Animate, Captions, Clip, Image, Music, Overlay, Packshot, Render, Slider, Speech, Split, Subtitle, Swipe, TalkingHead, Title, Video, Grid, SplitLayout } from "vargai/react";
9
9
  import { fal, elevenlabs, replicate } from "vargai/ai";
10
10
  `;
11
11
 
12
+ async function detectDefaultModels(): Promise<DefaultModels | undefined> {
13
+ const defaults: DefaultModels = {};
14
+
15
+ if (process.env.FAL_KEY) {
16
+ const { fal } = await import("../../ai-sdk/providers/fal");
17
+ defaults.image = fal.imageModel("flux-schnell");
18
+ defaults.video = fal.videoModel("wan-2.5");
19
+ }
20
+
21
+ if (process.env.ELEVENLABS_API_KEY) {
22
+ const { elevenlabs } = await import("../../ai-sdk/providers/elevenlabs");
23
+ defaults.speech = elevenlabs.speechModel("eleven_multilingual_v2");
24
+ defaults.music = elevenlabs.musicModel("music_v1");
25
+ }
26
+
27
+ return Object.keys(defaults).length > 0 ? defaults : undefined;
28
+ }
29
+
12
30
  async function loadComponent(filePath: string): Promise<VargElement> {
13
31
  const resolvedPath = resolve(filePath);
14
32
  const source = await Bun.file(resolvedPath).text();
@@ -130,10 +148,13 @@ export const renderCmd = defineCommand({
130
148
 
131
149
  const useCache = !args["no-cache"] && mode !== "preview";
132
150
 
151
+ const defaults = await detectDefaultModels();
152
+
133
153
  const buffer = await render(component, {
134
154
  output: outputPath,
135
155
  cache: useCache ? args.cache : undefined,
136
156
  mode,
157
+ defaults,
137
158
  });
138
159
 
139
160
  if (!args.quiet) {
@@ -1,6 +1,7 @@
1
1
  import type { generateImage } from "ai";
2
2
  import type { fileCache } from "../../ai-sdk/file-cache";
3
3
  import type { generateVideo } from "../../ai-sdk/generate-video";
4
+ import type { DefaultModels } from "../types";
4
5
  import type { ProgressTracker } from "./progress";
5
6
 
6
7
  export interface RenderContext {
@@ -14,4 +15,6 @@ export interface RenderContext {
14
15
  progress?: ProgressTracker;
15
16
  /** In-memory deduplication for concurrent renders of the same element */
16
17
  pending: Map<string, Promise<string>>;
18
+ /** Default models for elements that don't specify one */
19
+ defaults?: DefaultModels;
17
20
  }
@@ -54,9 +54,11 @@ export async function renderImage(
54
54
  throw new Error("Image element requires either 'prompt' or 'src'");
55
55
  }
56
56
 
57
- const model = props.model;
57
+ const model = props.model ?? ctx.defaults?.image;
58
58
  if (!model) {
59
- throw new Error("Image element requires 'model' prop when using prompt");
59
+ throw new Error(
60
+ "Image element requires 'model' prop (or set defaults.image in render options)",
61
+ );
60
62
  }
61
63
 
62
64
  // Compute cache key for deduplication
@@ -10,9 +10,9 @@ export async function renderMusic(
10
10
  const props = element.props as MusicProps;
11
11
 
12
12
  const prompt = props.prompt;
13
- const model = props.model;
13
+ const model = props.model ?? ctx.defaults?.music;
14
14
  if (!prompt || !model) {
15
- throw new Error("Music generation requires both prompt and model");
15
+ throw new Error("Music requires prompt and model (or set defaults.music)");
16
16
  }
17
17
 
18
18
  const cacheKey = JSON.stringify({
@@ -126,6 +126,7 @@ export async function renderRoot(
126
126
  tempFiles: [],
127
127
  progress,
128
128
  pending: new Map(),
129
+ defaults: options.defaults,
129
130
  };
130
131
 
131
132
  const clipElements: VargElement<"clip">[] = [];
@@ -21,9 +21,9 @@ export async function renderSpeech(
21
21
  throw new Error("Speech element requires text content");
22
22
  }
23
23
 
24
- const model = props.model;
24
+ const model = props.model ?? ctx.defaults?.speech;
25
25
  if (!model) {
26
- throw new Error("Speech element requires 'model' prop");
26
+ throw new Error("Speech requires 'model' prop (or set defaults.speech)");
27
27
  }
28
28
 
29
29
  const cacheKey = computeCacheKey(element);
@@ -81,9 +81,11 @@ export async function renderVideo(
81
81
  throw new Error("Video element requires either 'prompt' or 'src'");
82
82
  }
83
83
 
84
- const model = props.model;
84
+ const model = props.model ?? ctx.defaults?.video;
85
85
  if (!model) {
86
- throw new Error("Video element requires 'model' prop when using prompt");
86
+ throw new Error(
87
+ "Video element requires 'model' prop (or set defaults.video in render options)",
88
+ );
87
89
  }
88
90
 
89
91
  // Compute cache key for deduplication
@@ -212,11 +212,19 @@ export interface PackshotProps extends BaseProps {
212
212
 
213
213
  export type RenderMode = "strict" | "default" | "preview";
214
214
 
215
+ export interface DefaultModels {
216
+ image?: ImageModelV3;
217
+ video?: VideoModelV3;
218
+ speech?: SpeechModelV3;
219
+ music?: MusicModelV3;
220
+ }
221
+
215
222
  export interface RenderOptions {
216
223
  output?: string;
217
224
  cache?: string;
218
225
  quiet?: boolean;
219
226
  mode?: RenderMode;
227
+ defaults?: DefaultModels;
220
228
  }
221
229
 
222
230
  export interface ElementPropsMap {