vargai 0.4.0-alpha83 → 0.4.0-alpha85
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/.claude/settings.local.json +7 -0
- package/.env.example +33 -0
- package/.github/workflows/ci.yml +23 -0
- package/.husky/README.md +102 -0
- package/.husky/commit-msg +6 -0
- package/.husky/pre-commit +9 -0
- package/.husky/pre-push +6 -0
- package/package.json +1 -1
- package/src/cli/commands/render.tsx +1 -1
- package/src/ai-sdk/examples/garry-tan-varg.ts +0 -61
- package/src/react/examples/omnihuman15-react-test.tsx +0 -58
package/.env.example
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# fal.ai api key
|
|
2
|
+
FAL_API_KEY=fal_xxx
|
|
3
|
+
|
|
4
|
+
# higgsfield credentials
|
|
5
|
+
HIGGSFIELD_API_KEY=hf_xxx
|
|
6
|
+
HIGGSFIELD_SECRET=secret_xxx
|
|
7
|
+
|
|
8
|
+
# elevenlabs api key
|
|
9
|
+
ELEVENLABS_API_KEY=el_xxx
|
|
10
|
+
|
|
11
|
+
# groq api key (ultra-fast whisper transcription)
|
|
12
|
+
GROQ_API_KEY=gsk_xxx
|
|
13
|
+
|
|
14
|
+
# fireworks api key (word-level transcription with timestamps)
|
|
15
|
+
FIREWORKS_API_KEY=fw_xxx
|
|
16
|
+
|
|
17
|
+
# cloudflare r2 / s3 storage
|
|
18
|
+
CLOUDFLARE_R2_API_URL=https://xxx.r2.cloudflarestorage.com
|
|
19
|
+
CLOUDFLARE_ACCESS_KEY_ID=xxx
|
|
20
|
+
CLOUDFLARE_ACCESS_SECRET=xxx
|
|
21
|
+
CLOUDFLARE_R2_BUCKET=m
|
|
22
|
+
|
|
23
|
+
# replicate (optional)
|
|
24
|
+
REPLICATE_API_TOKEN=r8_xxx
|
|
25
|
+
|
|
26
|
+
# apify (web scraping actors)
|
|
27
|
+
APIFY_TOKEN=apify_api_xxx
|
|
28
|
+
|
|
29
|
+
# decart ai (real-time & batch video/image)
|
|
30
|
+
DECART_API_KEY=decart_xxx
|
|
31
|
+
|
|
32
|
+
# together ai (fast flux-schnell, no queue)
|
|
33
|
+
TOGETHER_API_KEY=together_xxx
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-format:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- uses: oven-sh/setup-bun@v2
|
|
16
|
+
with:
|
|
17
|
+
bun-version: latest
|
|
18
|
+
|
|
19
|
+
- name: Install dependencies
|
|
20
|
+
run: bun install
|
|
21
|
+
|
|
22
|
+
- name: Check
|
|
23
|
+
run: bun run check
|
package/.husky/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Git Hooks Configuration
|
|
2
|
+
|
|
3
|
+
This project uses [Husky](https://typicode.github.io/husky/) to manage Git hooks for maintaining code quality and security.
|
|
4
|
+
|
|
5
|
+
## Installed Hooks
|
|
6
|
+
|
|
7
|
+
### `pre-commit`
|
|
8
|
+
Runs before each commit:
|
|
9
|
+
- **Gitleaks** - Scans staged files for secrets and credentials
|
|
10
|
+
- **Lint-staged** - Runs Biome linter/formatter on staged files
|
|
11
|
+
|
|
12
|
+
### `commit-msg`
|
|
13
|
+
Validates commit messages:
|
|
14
|
+
- **Commitlint** - Enforces [Conventional Commits](https://www.conventionalcommits.org/) format
|
|
15
|
+
|
|
16
|
+
### `pre-push`
|
|
17
|
+
Runs before pushing to remote:
|
|
18
|
+
- **TypeScript type checking** - Ensures no type errors before push
|
|
19
|
+
|
|
20
|
+
## Commit Message Format
|
|
21
|
+
|
|
22
|
+
Follow the Conventional Commits specification:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
<type>(<scope>): <subject>
|
|
26
|
+
|
|
27
|
+
<body>
|
|
28
|
+
|
|
29
|
+
<footer>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Types
|
|
33
|
+
- `feat`: New feature
|
|
34
|
+
- `fix`: Bug fix
|
|
35
|
+
- `docs`: Documentation changes
|
|
36
|
+
- `style`: Code style changes (formatting, etc)
|
|
37
|
+
- `refactor`: Code refactoring
|
|
38
|
+
- `perf`: Performance improvements
|
|
39
|
+
- `test`: Test changes
|
|
40
|
+
- `build`: Build system changes
|
|
41
|
+
- `ci`: CI/CD changes
|
|
42
|
+
- `chore`: Other changes
|
|
43
|
+
- `revert`: Revert previous commit
|
|
44
|
+
|
|
45
|
+
### Examples
|
|
46
|
+
```bash
|
|
47
|
+
feat: add video generation API
|
|
48
|
+
fix(transcribe): handle empty audio files
|
|
49
|
+
docs: update installation guide
|
|
50
|
+
refactor: simplify audio processing pipeline
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Available Scripts
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Run linter
|
|
57
|
+
bun run lint
|
|
58
|
+
|
|
59
|
+
# Format code
|
|
60
|
+
bun run format
|
|
61
|
+
|
|
62
|
+
# Type check
|
|
63
|
+
bun run type-check
|
|
64
|
+
|
|
65
|
+
# Check bundle size
|
|
66
|
+
bun run size
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Bypassing Hooks
|
|
70
|
+
|
|
71
|
+
⚠️ **Not recommended** - Only use when absolutely necessary:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Skip all hooks
|
|
75
|
+
git commit --no-verify -m "emergency fix"
|
|
76
|
+
|
|
77
|
+
# Skip specific checks by setting env vars
|
|
78
|
+
HUSKY=0 git commit -m "skip all hooks"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Troubleshooting
|
|
82
|
+
|
|
83
|
+
If hooks aren't running:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Reinstall hooks
|
|
87
|
+
rm -rf .husky/_
|
|
88
|
+
bun run prepare
|
|
89
|
+
chmod +x .husky/pre-commit .husky/commit-msg .husky/pre-push
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Size Limits
|
|
93
|
+
|
|
94
|
+
Bundle size limits are defined in `.size-limit.json`. Check size before publishing:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
bun run size
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
package/.husky/pre-push
ADDED
package/package.json
CHANGED
|
@@ -83,7 +83,7 @@ async function loadComponent(filePath: string): Promise<VargElement> {
|
|
|
83
83
|
|
|
84
84
|
if (hasVargaiImport) {
|
|
85
85
|
const tmpFile = `${tmpDir}/${Date.now()}.tsx`;
|
|
86
|
-
// Resolve
|
|
86
|
+
// Resolve JSX pragma to absolute path so it works from the cache dir
|
|
87
87
|
const runtimeDir = resolve(pkgDir, "src/react/runtime");
|
|
88
88
|
const resolvedSource = source.replace(
|
|
89
89
|
/@jsxImportSource\s+vargai/,
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Garry Tan Talking Head Video
|
|
3
|
-
* Generate a video of Garry Tan saying "varg.ai is cool!"
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
generateImage,
|
|
8
|
-
experimental_generateSpeech as generateSpeech,
|
|
9
|
-
} from "ai";
|
|
10
|
-
import { elevenlabs, File, fal, generateVideo } from "../index";
|
|
11
|
-
|
|
12
|
-
async function main() {
|
|
13
|
-
const script = `varg.ai is cool!`;
|
|
14
|
-
|
|
15
|
-
console.log("generating Garry Tan image and voice in parallel...");
|
|
16
|
-
const [imageResult, speechResult] = await Promise.all([
|
|
17
|
-
generateImage({
|
|
18
|
-
model: fal.imageModel("flux-schnell"),
|
|
19
|
-
prompt:
|
|
20
|
-
"Garry Tan, Y Combinator CEO, Asian American man, short dark hair, glasses, friendly smile, professional headshot, studio lighting, clean background, looking at camera",
|
|
21
|
-
n: 1,
|
|
22
|
-
}),
|
|
23
|
-
generateSpeech({
|
|
24
|
-
model: elevenlabs.speechModel("turbo"),
|
|
25
|
-
text: script,
|
|
26
|
-
voice: "adam",
|
|
27
|
-
}),
|
|
28
|
-
]);
|
|
29
|
-
|
|
30
|
-
const firstImage = imageResult.images[0];
|
|
31
|
-
if (!firstImage) throw new Error("No image generated");
|
|
32
|
-
const image = File.from(firstImage);
|
|
33
|
-
const audio = File.from(speechResult.audio);
|
|
34
|
-
|
|
35
|
-
console.log(`image: ${(await image.data()).byteLength} bytes`);
|
|
36
|
-
console.log(`audio: ${(await audio.data()).byteLength} bytes`);
|
|
37
|
-
|
|
38
|
-
await Bun.write("output/garry-tan-image.png", await image.data());
|
|
39
|
-
await Bun.write("output/garry-tan-voice.mp3", await audio.data());
|
|
40
|
-
|
|
41
|
-
console.log("\nanimating Garry Tan (5 seconds)...");
|
|
42
|
-
const { video } = await generateVideo({
|
|
43
|
-
model: fal.videoModel("wan-2.5"),
|
|
44
|
-
prompt: {
|
|
45
|
-
text: "man talking naturally, moving mouth while speaking, subtle head movements, professional demeanor, blinking naturally",
|
|
46
|
-
images: [await image.data()],
|
|
47
|
-
},
|
|
48
|
-
duration: 5,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const output = File.from(video);
|
|
52
|
-
console.log(`video: ${(await output.data()).byteLength} bytes`);
|
|
53
|
-
await Bun.write("output/garry-tan-varg.mp4", await output.data());
|
|
54
|
-
|
|
55
|
-
console.log("\ndone! files saved to output/");
|
|
56
|
-
console.log("- output/garry-tan-image.png");
|
|
57
|
-
console.log("- output/garry-tan-voice.mp3");
|
|
58
|
-
console.log("- output/garry-tan-varg.mp4");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
main().catch(console.error);
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OmniHuman v1.5 React syntax test
|
|
3
|
-
*
|
|
4
|
-
* Uses a local image + local audio file to generate a talking video.
|
|
5
|
-
*
|
|
6
|
-
* Run: bun run src/react/examples/omnihuman15-react-test.tsx
|
|
7
|
-
* Output: output/omnihuman15-react-test.mp4
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { fal } from "../../ai-sdk/providers/fal";
|
|
11
|
-
import { Clip, Render, render, Video } from "..";
|
|
12
|
-
|
|
13
|
-
const IMAGE_PATH = "output/garry-tan-image.png";
|
|
14
|
-
const AUDIO_PATH = "output/garry-tan-voice.mp3";
|
|
15
|
-
|
|
16
|
-
const video = (
|
|
17
|
-
<Render width={720} height={1280}>
|
|
18
|
-
<Clip duration={5}>
|
|
19
|
-
<Video
|
|
20
|
-
model={fal.videoModel("omnihuman-v1.5")}
|
|
21
|
-
prompt={{
|
|
22
|
-
text: "friendly professional talking head, natural blinking, subtle head movement",
|
|
23
|
-
images: [IMAGE_PATH],
|
|
24
|
-
audio: AUDIO_PATH,
|
|
25
|
-
}}
|
|
26
|
-
providerOptions={{
|
|
27
|
-
fal: {
|
|
28
|
-
resolution: "720p",
|
|
29
|
-
turbo_mode: true,
|
|
30
|
-
},
|
|
31
|
-
}}
|
|
32
|
-
/>
|
|
33
|
-
</Clip>
|
|
34
|
-
</Render>
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
async function main() {
|
|
38
|
-
if (!process.env.FAL_API_KEY && !process.env.FAL_KEY) {
|
|
39
|
-
console.error("ERROR: FAL_API_KEY/FAL_KEY not found in environment");
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const result = await render(video, {
|
|
44
|
-
output: "output/omnihuman15-react-test.mp4",
|
|
45
|
-
cache: ".cache/ai",
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
console.log(
|
|
49
|
-
`ok: output/omnihuman15-react-test.mp4 (${(result.video.byteLength / 1024 / 1024).toFixed(2)} MB)`,
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (import.meta.main) {
|
|
54
|
-
main().catch((err) => {
|
|
55
|
-
console.error(err);
|
|
56
|
-
process.exit(1);
|
|
57
|
-
});
|
|
58
|
-
}
|