venice-video-harness 2.4.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 +28 -0
- package/LICENSE +21 -0
- package/README.md +598 -0
- package/dist/assembly/manifest-builder.d.ts +8 -0
- package/dist/assembly/manifest-builder.d.ts.map +1 -0
- package/dist/assembly/manifest-builder.js +196 -0
- package/dist/assembly/manifest-builder.js.map +1 -0
- package/dist/assembly/remotion-scaffold.d.ts +14 -0
- package/dist/assembly/remotion-scaffold.d.ts.map +1 -0
- package/dist/assembly/remotion-scaffold.js +292 -0
- package/dist/assembly/remotion-scaffold.js.map +1 -0
- package/dist/assembly/types.d.ts +67 -0
- package/dist/assembly/types.d.ts.map +1 -0
- package/dist/assembly/types.js +5 -0
- package/dist/assembly/types.js.map +1 -0
- package/dist/characters/describer.d.ts +32 -0
- package/dist/characters/describer.d.ts.map +1 -0
- package/dist/characters/describer.js +309 -0
- package/dist/characters/describer.js.map +1 -0
- package/dist/characters/extractor.d.ts +27 -0
- package/dist/characters/extractor.d.ts.map +1 -0
- package/dist/characters/extractor.js +274 -0
- package/dist/characters/extractor.js.map +1 -0
- package/dist/characters/reference-manager.d.ts +95 -0
- package/dist/characters/reference-manager.d.ts.map +1 -0
- package/dist/characters/reference-manager.js +346 -0
- package/dist/characters/reference-manager.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +310 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +66 -0
- package/dist/config.js.map +1 -0
- package/dist/editing/aligner.d.ts +44 -0
- package/dist/editing/aligner.d.ts.map +1 -0
- package/dist/editing/aligner.js +201 -0
- package/dist/editing/aligner.js.map +1 -0
- package/dist/editing/edl.d.ts +45 -0
- package/dist/editing/edl.d.ts.map +1 -0
- package/dist/editing/edl.js +133 -0
- package/dist/editing/edl.js.map +1 -0
- package/dist/editing/overlays.d.ts +97 -0
- package/dist/editing/overlays.d.ts.map +1 -0
- package/dist/editing/overlays.js +41 -0
- package/dist/editing/overlays.js.map +1 -0
- package/dist/editing/packer.d.ts +52 -0
- package/dist/editing/packer.d.ts.map +1 -0
- package/dist/editing/packer.js +170 -0
- package/dist/editing/packer.js.map +1 -0
- package/dist/editing/providers/whisper-cpp.d.ts +32 -0
- package/dist/editing/providers/whisper-cpp.d.ts.map +1 -0
- package/dist/editing/providers/whisper-cpp.js +239 -0
- package/dist/editing/providers/whisper-cpp.js.map +1 -0
- package/dist/editing/render.d.ts +36 -0
- package/dist/editing/render.d.ts.map +1 -0
- package/dist/editing/render.js +227 -0
- package/dist/editing/render.js.map +1 -0
- package/dist/editing/self-eval.d.ts +48 -0
- package/dist/editing/self-eval.d.ts.map +1 -0
- package/dist/editing/self-eval.js +293 -0
- package/dist/editing/self-eval.js.map +1 -0
- package/dist/editing/silence.d.ts +76 -0
- package/dist/editing/silence.d.ts.map +1 -0
- package/dist/editing/silence.js +189 -0
- package/dist/editing/silence.js.map +1 -0
- package/dist/editing/types.d.ts +178 -0
- package/dist/editing/types.d.ts.map +1 -0
- package/dist/editing/types.js +13 -0
- package/dist/editing/types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive.d.ts +12 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +78 -0
- package/dist/interactive.js.map +1 -0
- package/dist/mini-drama/assembler.d.ts +61 -0
- package/dist/mini-drama/assembler.d.ts.map +1 -0
- package/dist/mini-drama/assembler.js +466 -0
- package/dist/mini-drama/assembler.js.map +1 -0
- package/dist/mini-drama/audio-mix.d.ts +65 -0
- package/dist/mini-drama/audio-mix.d.ts.map +1 -0
- package/dist/mini-drama/audio-mix.js +118 -0
- package/dist/mini-drama/audio-mix.js.map +1 -0
- package/dist/mini-drama/cli.d.ts +3 -0
- package/dist/mini-drama/cli.d.ts.map +1 -0
- package/dist/mini-drama/cli.js +2869 -0
- package/dist/mini-drama/cli.js.map +1 -0
- package/dist/mini-drama/fcpxml-export.d.ts +2 -0
- package/dist/mini-drama/fcpxml-export.d.ts.map +1 -0
- package/dist/mini-drama/fcpxml-export.js +5 -0
- package/dist/mini-drama/fcpxml-export.js.map +1 -0
- package/dist/mini-drama/generation-planner.d.ts +24 -0
- package/dist/mini-drama/generation-planner.d.ts.map +1 -0
- package/dist/mini-drama/generation-planner.js +304 -0
- package/dist/mini-drama/generation-planner.js.map +1 -0
- package/dist/mini-drama/location-generator.d.ts +23 -0
- package/dist/mini-drama/location-generator.d.ts.map +1 -0
- package/dist/mini-drama/location-generator.js +144 -0
- package/dist/mini-drama/location-generator.js.map +1 -0
- package/dist/mini-drama/music-cues.d.ts +96 -0
- package/dist/mini-drama/music-cues.d.ts.map +1 -0
- package/dist/mini-drama/music-cues.js +332 -0
- package/dist/mini-drama/music-cues.js.map +1 -0
- package/dist/mini-drama/panel-fixer.d.ts +12 -0
- package/dist/mini-drama/panel-fixer.d.ts.map +1 -0
- package/dist/mini-drama/panel-fixer.js +319 -0
- package/dist/mini-drama/panel-fixer.js.map +1 -0
- package/dist/mini-drama/prompt-builder.d.ts +149 -0
- package/dist/mini-drama/prompt-builder.d.ts.map +1 -0
- package/dist/mini-drama/prompt-builder.js +722 -0
- package/dist/mini-drama/prompt-builder.js.map +1 -0
- package/dist/mini-drama/reference-slots.d.ts +31 -0
- package/dist/mini-drama/reference-slots.d.ts.map +1 -0
- package/dist/mini-drama/reference-slots.js +161 -0
- package/dist/mini-drama/reference-slots.js.map +1 -0
- package/dist/mini-drama/shot-paths.d.ts +77 -0
- package/dist/mini-drama/shot-paths.d.ts.map +1 -0
- package/dist/mini-drama/shot-paths.js +101 -0
- package/dist/mini-drama/shot-paths.js.map +1 -0
- package/dist/mini-drama/storyboard-reference-generator.d.ts +47 -0
- package/dist/mini-drama/storyboard-reference-generator.d.ts.map +1 -0
- package/dist/mini-drama/storyboard-reference-generator.js +293 -0
- package/dist/mini-drama/storyboard-reference-generator.js.map +1 -0
- package/dist/mini-drama/subtitle-generator.d.ts +12 -0
- package/dist/mini-drama/subtitle-generator.d.ts.map +1 -0
- package/dist/mini-drama/subtitle-generator.js +139 -0
- package/dist/mini-drama/subtitle-generator.js.map +1 -0
- package/dist/mini-drama/timeline-export/davinci-fcpxml.d.ts +3 -0
- package/dist/mini-drama/timeline-export/davinci-fcpxml.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/davinci-fcpxml.js +150 -0
- package/dist/mini-drama/timeline-export/davinci-fcpxml.js.map +1 -0
- package/dist/mini-drama/timeline-export/fcpxml.d.ts +11 -0
- package/dist/mini-drama/timeline-export/fcpxml.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/fcpxml.js +140 -0
- package/dist/mini-drama/timeline-export/fcpxml.js.map +1 -0
- package/dist/mini-drama/timeline-export/index.d.ts +13 -0
- package/dist/mini-drama/timeline-export/index.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/index.js +26 -0
- package/dist/mini-drama/timeline-export/index.js.map +1 -0
- package/dist/mini-drama/timeline-export/premiere-xmeml.d.ts +3 -0
- package/dist/mini-drama/timeline-export/premiere-xmeml.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/premiere-xmeml.js +211 -0
- package/dist/mini-drama/timeline-export/premiere-xmeml.js.map +1 -0
- package/dist/mini-drama/timeline-export/probe.d.ts +53 -0
- package/dist/mini-drama/timeline-export/probe.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/probe.js +89 -0
- package/dist/mini-drama/timeline-export/probe.js.map +1 -0
- package/dist/mini-drama/timeline-export/types.d.ts +57 -0
- package/dist/mini-drama/timeline-export/types.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/types.js +14 -0
- package/dist/mini-drama/timeline-export/types.js.map +1 -0
- package/dist/mini-drama/video-generator.d.ts +22 -0
- package/dist/mini-drama/video-generator.d.ts.map +1 -0
- package/dist/mini-drama/video-generator.js +1305 -0
- package/dist/mini-drama/video-generator.js.map +1 -0
- package/dist/mini-drama/voice-reference.d.ts +42 -0
- package/dist/mini-drama/voice-reference.d.ts.map +1 -0
- package/dist/mini-drama/voice-reference.js +170 -0
- package/dist/mini-drama/voice-reference.js.map +1 -0
- package/dist/output/html-renderer.d.ts +2 -0
- package/dist/output/html-renderer.d.ts.map +1 -0
- package/dist/output/html-renderer.js +37 -0
- package/dist/output/html-renderer.js.map +1 -0
- package/dist/parsers/fountain-parser.d.ts +34 -0
- package/dist/parsers/fountain-parser.d.ts.map +1 -0
- package/dist/parsers/fountain-parser.js +71 -0
- package/dist/parsers/fountain-parser.js.map +1 -0
- package/dist/parsers/pdf-parser.d.ts +24 -0
- package/dist/parsers/pdf-parser.d.ts.map +1 -0
- package/dist/parsers/pdf-parser.js +237 -0
- package/dist/parsers/pdf-parser.js.map +1 -0
- package/dist/parsers/scene-extractor.d.ts +41 -0
- package/dist/parsers/scene-extractor.d.ts.map +1 -0
- package/dist/parsers/scene-extractor.js +400 -0
- package/dist/parsers/scene-extractor.js.map +1 -0
- package/dist/series/manager.d.ts +64 -0
- package/dist/series/manager.d.ts.map +1 -0
- package/dist/series/manager.js +282 -0
- package/dist/series/manager.js.map +1 -0
- package/dist/series/types.d.ts +641 -0
- package/dist/series/types.d.ts.map +1 -0
- package/dist/series/types.js +304 -0
- package/dist/series/types.js.map +1 -0
- package/dist/storyboard/assembler.d.ts +134 -0
- package/dist/storyboard/assembler.d.ts.map +1 -0
- package/dist/storyboard/assembler.js +319 -0
- package/dist/storyboard/assembler.js.map +1 -0
- package/dist/storyboard/prompt-builder.d.ts +113 -0
- package/dist/storyboard/prompt-builder.d.ts.map +1 -0
- package/dist/storyboard/prompt-builder.js +578 -0
- package/dist/storyboard/prompt-builder.js.map +1 -0
- package/dist/storyboard/shot-planner.d.ts +34 -0
- package/dist/storyboard/shot-planner.d.ts.map +1 -0
- package/dist/storyboard/shot-planner.js +446 -0
- package/dist/storyboard/shot-planner.js.map +1 -0
- package/dist/user-config.d.ts +15 -0
- package/dist/user-config.d.ts.map +1 -0
- package/dist/user-config.js +103 -0
- package/dist/user-config.js.map +1 -0
- package/dist/venice/audio-preflight.d.ts +80 -0
- package/dist/venice/audio-preflight.d.ts.map +1 -0
- package/dist/venice/audio-preflight.js +142 -0
- package/dist/venice/audio-preflight.js.map +1 -0
- package/dist/venice/audio.d.ts +88 -0
- package/dist/venice/audio.d.ts.map +1 -0
- package/dist/venice/audio.js +234 -0
- package/dist/venice/audio.js.map +1 -0
- package/dist/venice/client.d.ts +86 -0
- package/dist/venice/client.d.ts.map +1 -0
- package/dist/venice/client.js +375 -0
- package/dist/venice/client.js.map +1 -0
- package/dist/venice/edit.d.ts +57 -0
- package/dist/venice/edit.d.ts.map +1 -0
- package/dist/venice/edit.js +100 -0
- package/dist/venice/edit.js.map +1 -0
- package/dist/venice/generate.d.ts +47 -0
- package/dist/venice/generate.d.ts.map +1 -0
- package/dist/venice/generate.js +150 -0
- package/dist/venice/generate.js.map +1 -0
- package/dist/venice/image-bytes.d.ts +26 -0
- package/dist/venice/image-bytes.d.ts.map +1 -0
- package/dist/venice/image-bytes.js +101 -0
- package/dist/venice/image-bytes.js.map +1 -0
- package/dist/venice/models.d.ts +143 -0
- package/dist/venice/models.d.ts.map +1 -0
- package/dist/venice/models.js +984 -0
- package/dist/venice/models.js.map +1 -0
- package/dist/venice/multi-edit.d.ts +40 -0
- package/dist/venice/multi-edit.d.ts.map +1 -0
- package/dist/venice/multi-edit.js +97 -0
- package/dist/venice/multi-edit.js.map +1 -0
- package/dist/venice/provenance.d.ts +66 -0
- package/dist/venice/provenance.d.ts.map +1 -0
- package/dist/venice/provenance.js +151 -0
- package/dist/venice/provenance.js.map +1 -0
- package/dist/venice/recipe.d.ts +69 -0
- package/dist/venice/recipe.d.ts.map +1 -0
- package/dist/venice/recipe.js +103 -0
- package/dist/venice/recipe.js.map +1 -0
- package/dist/venice/rejection.d.ts +63 -0
- package/dist/venice/rejection.d.ts.map +1 -0
- package/dist/venice/rejection.js +111 -0
- package/dist/venice/rejection.js.map +1 -0
- package/dist/venice/seedance-preflight.d.ts +38 -0
- package/dist/venice/seedance-preflight.d.ts.map +1 -0
- package/dist/venice/seedance-preflight.js +29 -0
- package/dist/venice/seedance-preflight.js.map +1 -0
- package/dist/venice/types.d.ts +212 -0
- package/dist/venice/types.d.ts.map +1 -0
- package/dist/venice/types.js +9 -0
- package/dist/venice/types.js.map +1 -0
- package/dist/venice/video.d.ts +77 -0
- package/dist/venice/video.d.ts.map +1 -0
- package/dist/venice/video.js +163 -0
- package/dist/venice/video.js.map +1 -0
- package/dist/venice/voices.d.ts +40 -0
- package/dist/venice/voices.d.ts.map +1 -0
- package/dist/venice/voices.js +194 -0
- package/dist/venice/voices.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-preflight.d.ts","sourceRoot":"","sources":["../../src/venice/audio-preflight.ts"],"names":[],"mappings":"AA4BA,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAY5F;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAY9E;AAED;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBxE;AAED,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBvE;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAahB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Audio pre-flight helpers for Wan 2.7 (and any future model that constrains
|
|
3
|
+
// `audio_url` input duration).
|
|
4
|
+
//
|
|
5
|
+
// Wan 2.7's `audio_url` rejects clips shorter than 3 seconds with HTTP 400:
|
|
6
|
+
// "audio_url: Audio duration is too short. Minimum is 3 seconds."
|
|
7
|
+
//
|
|
8
|
+
// POST /video/quote does NOT validate audio duration, so the error only
|
|
9
|
+
// surfaces at queue time. This module:
|
|
10
|
+
//
|
|
11
|
+
// - probes audio duration via `ffprobe`
|
|
12
|
+
// - throws `WanAudioTooShortError` when below a model's `minAudioInputSec`
|
|
13
|
+
// - pads short clips with TRAILING silence via `ffmpeg apad`
|
|
14
|
+
//
|
|
15
|
+
// Trailing (not leading) silence is the right call:
|
|
16
|
+
// leading silence wastes the most-interesting visual portion on a held pose
|
|
17
|
+
// before the mouth moves. Trailing silence lets the model finish speech and
|
|
18
|
+
// idle (blinks, micro-motion) naturally.
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
import { execFile } from 'node:child_process';
|
|
21
|
+
import { mkdir } from 'node:fs/promises';
|
|
22
|
+
import { basename, dirname, join } from 'node:path';
|
|
23
|
+
import { promisify } from 'node:util';
|
|
24
|
+
import { getVideoModel } from './models.js';
|
|
25
|
+
const execFileAsync = promisify(execFile);
|
|
26
|
+
export class WanAudioTooShortError extends Error {
|
|
27
|
+
model;
|
|
28
|
+
audioPath;
|
|
29
|
+
durationSec;
|
|
30
|
+
minSec;
|
|
31
|
+
constructor(info) {
|
|
32
|
+
super(`[WanAudioTooShort] ${info.model} requires audio_url >= ${info.minSec}s, ` +
|
|
33
|
+
`got ${info.durationSec.toFixed(3)}s (${info.audioPath}). ` +
|
|
34
|
+
`Pad with trailing silence via padAudioForModel().`);
|
|
35
|
+
this.name = 'WanAudioTooShortError';
|
|
36
|
+
this.model = info.model;
|
|
37
|
+
this.audioPath = info.audioPath;
|
|
38
|
+
this.durationSec = info.durationSec;
|
|
39
|
+
this.minSec = info.minSec;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Probe an audio file's duration in seconds via ffprobe.
|
|
44
|
+
*
|
|
45
|
+
* Throws if ffprobe is not on PATH or the file cannot be read.
|
|
46
|
+
*/
|
|
47
|
+
export async function probeAudioDurationSec(audioPath) {
|
|
48
|
+
const { stdout } = await execFileAsync('ffprobe', [
|
|
49
|
+
'-v', 'error',
|
|
50
|
+
'-show_entries', 'format=duration',
|
|
51
|
+
'-of', 'default=noprint_wrappers=1:nokey=1',
|
|
52
|
+
audioPath,
|
|
53
|
+
]);
|
|
54
|
+
const seconds = parseFloat(stdout.trim());
|
|
55
|
+
if (!Number.isFinite(seconds)) {
|
|
56
|
+
throw new Error(`Could not parse ffprobe duration for ${audioPath} (got "${stdout.trim()}")`);
|
|
57
|
+
}
|
|
58
|
+
return seconds;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Pad an audio file with TRAILING silence to exactly `targetSec` seconds.
|
|
62
|
+
*
|
|
63
|
+
* Writes the padded variant to `outPath`, leaving the source file untouched.
|
|
64
|
+
* The caller decides where to put it — convention is `audio/dialogue-padded/`
|
|
65
|
+
* so the original short clip remains usable for non-Wan placements.
|
|
66
|
+
*
|
|
67
|
+
* Pads to exactly `targetSec` (no slack). Less padding = less held-pose
|
|
68
|
+
* visual time after the speech ends.
|
|
69
|
+
*/
|
|
70
|
+
export async function padAudioWithTrailingSilence(opts) {
|
|
71
|
+
const fromSec = await probeAudioDurationSec(opts.inputPath);
|
|
72
|
+
if (fromSec >= opts.targetSec) {
|
|
73
|
+
return { outputPath: opts.inputPath, paddedFromSec: fromSec, toSec: fromSec };
|
|
74
|
+
}
|
|
75
|
+
await mkdir(dirname(opts.outputPath), { recursive: true });
|
|
76
|
+
// `apad=pad_dur=<delta>` appends `<delta>` seconds of silence; `-t targetSec`
|
|
77
|
+
// is a belt-and-braces cap in case ffmpeg's apad rounding overshoots.
|
|
78
|
+
const padDur = (opts.targetSec - fromSec).toFixed(3);
|
|
79
|
+
await execFileAsync('ffmpeg', [
|
|
80
|
+
'-y',
|
|
81
|
+
'-i', opts.inputPath,
|
|
82
|
+
'-af', `apad=pad_dur=${padDur}`,
|
|
83
|
+
'-t', String(opts.targetSec),
|
|
84
|
+
opts.outputPath,
|
|
85
|
+
]);
|
|
86
|
+
return { outputPath: opts.outputPath, paddedFromSec: fromSec, toSec: opts.targetSec };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Ensure an audio file meets a model's minimum-duration requirement.
|
|
90
|
+
*
|
|
91
|
+
* - If the model has no `minAudioInputSec` or the clip already qualifies,
|
|
92
|
+
* returns the original path unmodified.
|
|
93
|
+
* - Otherwise, pads with trailing silence and returns the padded path.
|
|
94
|
+
*
|
|
95
|
+
* Throws `WanAudioTooShortError` only if the model declares a minimum AND
|
|
96
|
+
* padding is explicitly disabled (`paddedDir: null` is reserved for that
|
|
97
|
+
* future variant; today we always pad rather than throw, because callers
|
|
98
|
+
* have already paid for the TTS and want the render).
|
|
99
|
+
*/
|
|
100
|
+
export async function padAudioForModel(opts) {
|
|
101
|
+
const spec = getVideoModel(opts.model);
|
|
102
|
+
const minSec = opts.targetSec ?? spec?.minAudioInputSec;
|
|
103
|
+
if (!minSec) {
|
|
104
|
+
const durationSec = await probeAudioDurationSec(opts.audioPath);
|
|
105
|
+
return { outputPath: opts.audioPath, padded: false, durationSec };
|
|
106
|
+
}
|
|
107
|
+
const fromSec = await probeAudioDurationSec(opts.audioPath);
|
|
108
|
+
if (fromSec >= minSec) {
|
|
109
|
+
return { outputPath: opts.audioPath, padded: false, durationSec: fromSec };
|
|
110
|
+
}
|
|
111
|
+
const dir = opts.paddedDir ?? join(dirname(opts.audioPath), 'padded');
|
|
112
|
+
const baseName = basename(opts.audioPath);
|
|
113
|
+
const outPath = join(dir, baseName);
|
|
114
|
+
const { toSec } = await padAudioWithTrailingSilence({
|
|
115
|
+
inputPath: opts.audioPath,
|
|
116
|
+
outputPath: outPath,
|
|
117
|
+
targetSec: minSec,
|
|
118
|
+
});
|
|
119
|
+
return { outputPath: outPath, padded: true, durationSec: toSec };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Assert an audio file is long enough for a given model.
|
|
123
|
+
*
|
|
124
|
+
* Use this when callers want to reject short audio explicitly rather than
|
|
125
|
+
* silently padding it.
|
|
126
|
+
*/
|
|
127
|
+
export async function assertAudioMeetsModelMin(opts) {
|
|
128
|
+
const spec = getVideoModel(opts.model);
|
|
129
|
+
const minSec = spec?.minAudioInputSec;
|
|
130
|
+
if (!minSec)
|
|
131
|
+
return;
|
|
132
|
+
const durationSec = await probeAudioDurationSec(opts.audioPath);
|
|
133
|
+
if (durationSec < minSec) {
|
|
134
|
+
throw new WanAudioTooShortError({
|
|
135
|
+
model: opts.model,
|
|
136
|
+
audioPath: opts.audioPath,
|
|
137
|
+
durationSec,
|
|
138
|
+
minSec,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=audio-preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-preflight.js","sourceRoot":"","sources":["../../src/venice/audio-preflight.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { VeniceClient } from './client.js';
|
|
2
|
+
export declare const DEFAULT_VENICE_TTS_MODEL = "tts-kokoro";
|
|
3
|
+
export declare const DEFAULT_VENICE_MUSIC_MODEL = "elevenlabs-music";
|
|
4
|
+
export declare const DEFAULT_VENICE_SFX_MODEL = "elevenlabs-sound-effects-v2";
|
|
5
|
+
/** BytePlus Seed Audio 1.0 — expressive prompt-driven speech/audio via the audio queue. */
|
|
6
|
+
export declare const DEFAULT_VENICE_SEED_AUDIO_MODEL = "seed-audio-1-0";
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Use DEFAULT_VENICE_MUSIC_MODEL or DEFAULT_VENICE_SFX_MODEL.
|
|
9
|
+
* Kept for backward compatibility with existing scripts.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_VENICE_AUDIO_MODEL = "stable-audio-25";
|
|
12
|
+
export interface TTSOptions {
|
|
13
|
+
voiceId: string;
|
|
14
|
+
text: string;
|
|
15
|
+
modelId?: string;
|
|
16
|
+
/** Qwen3 TTS style prompt (e.g. "Very happy.", "Sad and slow.") */
|
|
17
|
+
prompt?: string;
|
|
18
|
+
speed?: number;
|
|
19
|
+
responseFormat?: 'mp3' | 'wav' | 'flac' | 'aac' | 'opus' | 'pcm';
|
|
20
|
+
streaming?: boolean;
|
|
21
|
+
/** Qwen3 TTS only */
|
|
22
|
+
language?: string;
|
|
23
|
+
/** Qwen3 TTS only: sampling temperature (0-2) */
|
|
24
|
+
temperature?: number;
|
|
25
|
+
/** Qwen3 TTS only: nucleus sampling (0-1) */
|
|
26
|
+
top_p?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface DialogueLine {
|
|
29
|
+
shotNumber: number;
|
|
30
|
+
character: string;
|
|
31
|
+
voiceId: string;
|
|
32
|
+
text: string;
|
|
33
|
+
voicePrompt?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function generateSpeech(client: VeniceClient, options: TTSOptions, outputPath: string): Promise<string>;
|
|
36
|
+
export declare function generateDialogueForShots(client: VeniceClient, lines: DialogueLine[], outputDir: string): Promise<{
|
|
37
|
+
shotNumber: number;
|
|
38
|
+
character: string;
|
|
39
|
+
text: string;
|
|
40
|
+
path: string;
|
|
41
|
+
}[]>;
|
|
42
|
+
export interface SFXOptions {
|
|
43
|
+
text: string;
|
|
44
|
+
durationSeconds?: number;
|
|
45
|
+
modelId?: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function generateSoundEffect(client: VeniceClient, options: SFXOptions, outputPath: string): Promise<string>;
|
|
48
|
+
export interface MusicOptions {
|
|
49
|
+
prompt: string;
|
|
50
|
+
durationSeconds?: number;
|
|
51
|
+
modelId?: string;
|
|
52
|
+
lyricsPrompt?: string;
|
|
53
|
+
forceInstrumental?: boolean;
|
|
54
|
+
voice?: string;
|
|
55
|
+
/** Playback speed for speed-enabled models (e.g. seed-audio-1-0: 0.5–2). */
|
|
56
|
+
speed?: number;
|
|
57
|
+
/** ISO 639-1 language code for models with supports_language_code. */
|
|
58
|
+
languageCode?: string;
|
|
59
|
+
}
|
|
60
|
+
export declare function generateMusic(client: VeniceClient, options: MusicOptions, outputPath: string): Promise<string>;
|
|
61
|
+
export interface SeedAudioOptions {
|
|
62
|
+
/** The text/script to speak, or an audio description. Up to 2048 chars. */
|
|
63
|
+
prompt: string;
|
|
64
|
+
/** A voice from the model's roster, or "Describe in prompt" to steer via text. */
|
|
65
|
+
voice?: string;
|
|
66
|
+
/** Playback speed, 0.5–2 (default 1). */
|
|
67
|
+
speed?: number;
|
|
68
|
+
/** Generation length in seconds (default 120). */
|
|
69
|
+
durationSeconds?: number;
|
|
70
|
+
/** Override the model id (defaults to seed-audio-1-0). */
|
|
71
|
+
modelId?: string;
|
|
72
|
+
}
|
|
73
|
+
export declare function generateSeedAudio(client: VeniceClient, options: SeedAudioOptions, outputPath: string): Promise<string>;
|
|
74
|
+
interface QueuedAudioOptions {
|
|
75
|
+
prompt: string;
|
|
76
|
+
modelId?: string;
|
|
77
|
+
durationSeconds?: number;
|
|
78
|
+
forceInstrumental?: boolean;
|
|
79
|
+
voice?: string;
|
|
80
|
+
languageCode?: string;
|
|
81
|
+
speed?: number;
|
|
82
|
+
lyricsPrompt?: string;
|
|
83
|
+
pollIntervalMs?: number;
|
|
84
|
+
maxPollAttempts?: number;
|
|
85
|
+
}
|
|
86
|
+
export declare function generateQueuedAudio(client: VeniceClient, options: QueuedAudioOptions, outputPath: string): Promise<string>;
|
|
87
|
+
export {};
|
|
88
|
+
//# sourceMappingURL=audio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/venice/audio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Venice Audio API -- TTS, music, sound effects, queued audio generation
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
import { dirname, extname, join } from 'node:path';
|
|
8
|
+
import { promisify } from 'node:util';
|
|
9
|
+
import { getMusicModel } from './models.js';
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
// ---- Default Models -------------------------------------------------------
|
|
12
|
+
export const DEFAULT_VENICE_TTS_MODEL = 'tts-kokoro';
|
|
13
|
+
export const DEFAULT_VENICE_MUSIC_MODEL = 'elevenlabs-music';
|
|
14
|
+
export const DEFAULT_VENICE_SFX_MODEL = 'elevenlabs-sound-effects-v2';
|
|
15
|
+
/** BytePlus Seed Audio 1.0 — expressive prompt-driven speech/audio via the audio queue. */
|
|
16
|
+
export const DEFAULT_VENICE_SEED_AUDIO_MODEL = 'seed-audio-1-0';
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use DEFAULT_VENICE_MUSIC_MODEL or DEFAULT_VENICE_SFX_MODEL.
|
|
19
|
+
* Kept for backward compatibility with existing scripts.
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_VENICE_AUDIO_MODEL = 'stable-audio-25';
|
|
22
|
+
export async function generateSpeech(client, options, outputPath) {
|
|
23
|
+
const { voiceId, text, modelId = DEFAULT_VENICE_TTS_MODEL, prompt, speed = 1, responseFormat = 'mp3', streaming = false, language, temperature, top_p, } = options;
|
|
24
|
+
const body = {
|
|
25
|
+
input: text,
|
|
26
|
+
model: modelId,
|
|
27
|
+
voice: voiceId,
|
|
28
|
+
response_format: responseFormat,
|
|
29
|
+
speed,
|
|
30
|
+
streaming,
|
|
31
|
+
};
|
|
32
|
+
if (prompt && (modelId.startsWith('tts-qwen3') || modelId.startsWith('elevenlabs'))) {
|
|
33
|
+
body.prompt = prompt;
|
|
34
|
+
}
|
|
35
|
+
if (language && modelId.startsWith('tts-qwen3')) {
|
|
36
|
+
body.language = language;
|
|
37
|
+
}
|
|
38
|
+
if (temperature !== undefined && modelId.startsWith('tts-qwen3')) {
|
|
39
|
+
body.temperature = temperature;
|
|
40
|
+
}
|
|
41
|
+
if (top_p !== undefined && modelId.startsWith('tts-qwen3')) {
|
|
42
|
+
body.top_p = top_p;
|
|
43
|
+
}
|
|
44
|
+
const audioBuffer = await client.postBinary('/api/v1/audio/speech', body);
|
|
45
|
+
await mkdir(dirname(outputPath), { recursive: true });
|
|
46
|
+
await writeFile(outputPath, audioBuffer);
|
|
47
|
+
return outputPath;
|
|
48
|
+
}
|
|
49
|
+
export async function generateDialogueForShots(client, lines, outputDir) {
|
|
50
|
+
await mkdir(outputDir, { recursive: true });
|
|
51
|
+
const results = [];
|
|
52
|
+
for (const line of lines) {
|
|
53
|
+
const shotNum = String(line.shotNumber).padStart(3, '0');
|
|
54
|
+
const filename = `dialogue-shot-${shotNum}.mp3`;
|
|
55
|
+
const outputPath = `${outputDir}/${filename}`;
|
|
56
|
+
await generateSpeech(client, {
|
|
57
|
+
voiceId: line.voiceId,
|
|
58
|
+
text: line.text,
|
|
59
|
+
prompt: line.voicePrompt,
|
|
60
|
+
}, outputPath);
|
|
61
|
+
results.push({
|
|
62
|
+
shotNumber: line.shotNumber,
|
|
63
|
+
character: line.character,
|
|
64
|
+
text: line.text,
|
|
65
|
+
path: outputPath,
|
|
66
|
+
});
|
|
67
|
+
console.log(` TTS [${line.character}] shot ${shotNum}: "${line.text.slice(0, 40)}..." -> ${filename}`);
|
|
68
|
+
}
|
|
69
|
+
return results;
|
|
70
|
+
}
|
|
71
|
+
export async function generateSoundEffect(client, options, outputPath) {
|
|
72
|
+
const { text, durationSeconds = 5, modelId = DEFAULT_VENICE_SFX_MODEL, } = options;
|
|
73
|
+
return generateQueuedAudio(client, {
|
|
74
|
+
prompt: text,
|
|
75
|
+
modelId,
|
|
76
|
+
durationSeconds: clamp(durationSeconds, 1, 190),
|
|
77
|
+
}, outputPath);
|
|
78
|
+
}
|
|
79
|
+
export async function generateMusic(client, options, outputPath) {
|
|
80
|
+
const { prompt, durationSeconds = 60, modelId = DEFAULT_VENICE_MUSIC_MODEL, lyricsPrompt, forceInstrumental, voice, speed, languageCode, } = options;
|
|
81
|
+
return generateQueuedAudio(client, {
|
|
82
|
+
prompt,
|
|
83
|
+
modelId,
|
|
84
|
+
durationSeconds: clamp(durationSeconds, 1, 190),
|
|
85
|
+
lyricsPrompt,
|
|
86
|
+
forceInstrumental,
|
|
87
|
+
voice,
|
|
88
|
+
speed,
|
|
89
|
+
languageCode,
|
|
90
|
+
}, outputPath);
|
|
91
|
+
}
|
|
92
|
+
export async function generateSeedAudio(client, options, outputPath) {
|
|
93
|
+
const modelId = options.modelId ?? DEFAULT_VENICE_SEED_AUDIO_MODEL;
|
|
94
|
+
const spec = getMusicModel(modelId);
|
|
95
|
+
const prompt = options.prompt?.trim() ?? '';
|
|
96
|
+
const minLen = spec?.minPromptLength ?? 1;
|
|
97
|
+
const maxLen = spec?.promptCharacterLimit ?? 2048;
|
|
98
|
+
if (prompt.length < minLen) {
|
|
99
|
+
throw new Error(`${modelId}: prompt is required (min ${minLen} char).`);
|
|
100
|
+
}
|
|
101
|
+
if (prompt.length > maxLen) {
|
|
102
|
+
throw new Error(`${modelId}: prompt is ${prompt.length} chars, exceeds the ${maxLen}-char limit. ` +
|
|
103
|
+
`Split into multiple calls and concatenate the audio.`);
|
|
104
|
+
}
|
|
105
|
+
// Only send a voice the model actually offers; otherwise let the model use
|
|
106
|
+
// its default ("Describe in prompt" for seed-audio) so voice steering can
|
|
107
|
+
// live in the prompt text.
|
|
108
|
+
let voice = options.voice;
|
|
109
|
+
if (voice && spec?.voices && !spec.voices.includes(voice)) {
|
|
110
|
+
throw new Error(`${modelId}: unknown voice "${voice}". Valid voices: ${spec.voices.join(', ')}.`);
|
|
111
|
+
}
|
|
112
|
+
if (!voice && spec?.defaultVoice)
|
|
113
|
+
voice = spec.defaultVoice;
|
|
114
|
+
let speed = options.speed;
|
|
115
|
+
if (speed !== undefined && spec?.supportsSpeed) {
|
|
116
|
+
speed = clamp(speed, spec.minSpeed ?? 0.5, spec.maxSpeed ?? 2);
|
|
117
|
+
}
|
|
118
|
+
else if (speed !== undefined && spec && !spec.supportsSpeed) {
|
|
119
|
+
speed = undefined; // model ignores speed; drop it to keep the request clean
|
|
120
|
+
}
|
|
121
|
+
const durationSeconds = options.durationSeconds ?? spec?.defaultDurationSec ?? 120;
|
|
122
|
+
return generateQueuedAudio(client, {
|
|
123
|
+
prompt,
|
|
124
|
+
modelId,
|
|
125
|
+
durationSeconds,
|
|
126
|
+
voice,
|
|
127
|
+
speed,
|
|
128
|
+
}, outputPath);
|
|
129
|
+
}
|
|
130
|
+
export async function generateQueuedAudio(client, options, outputPath) {
|
|
131
|
+
const { prompt, modelId = DEFAULT_VENICE_MUSIC_MODEL, durationSeconds, forceInstrumental, voice, languageCode, speed, lyricsPrompt, pollIntervalMs = 5_000, maxPollAttempts = 120, } = options;
|
|
132
|
+
const queueBody = {
|
|
133
|
+
model: modelId,
|
|
134
|
+
prompt,
|
|
135
|
+
};
|
|
136
|
+
if (durationSeconds !== undefined) {
|
|
137
|
+
queueBody.duration_seconds = durationSeconds;
|
|
138
|
+
}
|
|
139
|
+
if (forceInstrumental !== undefined) {
|
|
140
|
+
queueBody.force_instrumental = forceInstrumental;
|
|
141
|
+
}
|
|
142
|
+
if (voice) {
|
|
143
|
+
queueBody.voice = voice;
|
|
144
|
+
}
|
|
145
|
+
if (languageCode) {
|
|
146
|
+
queueBody.language_code = languageCode;
|
|
147
|
+
}
|
|
148
|
+
if (speed !== undefined) {
|
|
149
|
+
queueBody.speed = speed;
|
|
150
|
+
}
|
|
151
|
+
if (lyricsPrompt) {
|
|
152
|
+
queueBody.lyrics_prompt = lyricsPrompt;
|
|
153
|
+
}
|
|
154
|
+
const queued = await client.post('/api/v1/audio/queue', queueBody);
|
|
155
|
+
for (let attempt = 0; attempt < maxPollAttempts; attempt++) {
|
|
156
|
+
if (attempt > 0) {
|
|
157
|
+
await sleep(pollIntervalMs);
|
|
158
|
+
}
|
|
159
|
+
const response = await client.postBinaryOrJson('/api/v1/audio/retrieve', {
|
|
160
|
+
model: queued.model,
|
|
161
|
+
queue_id: queued.queue_id,
|
|
162
|
+
delete_media_on_completion: false,
|
|
163
|
+
});
|
|
164
|
+
if (Buffer.isBuffer(response.value)) {
|
|
165
|
+
await writeAudioBuffer(response.value, response.contentType, outputPath);
|
|
166
|
+
await client.post('/api/v1/audio/complete', {
|
|
167
|
+
model: queued.model,
|
|
168
|
+
queue_id: queued.queue_id,
|
|
169
|
+
});
|
|
170
|
+
return outputPath;
|
|
171
|
+
}
|
|
172
|
+
const status = response.value;
|
|
173
|
+
if (status.status === 'PROCESSING') {
|
|
174
|
+
console.log(` Audio still processing (${Math.round(status.execution_duration / 1000)}s / ~${Math.round(status.average_execution_time / 1000)}s)`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
throw new Error(`Timed out waiting for Venice audio generation: ${queued.model} (${queued.queue_id})`);
|
|
178
|
+
}
|
|
179
|
+
// ---- Internals ------------------------------------------------------------
|
|
180
|
+
async function writeAudioBuffer(buffer, contentType, outputPath) {
|
|
181
|
+
await mkdir(dirname(outputPath), { recursive: true });
|
|
182
|
+
const inputExt = extensionFromContentType(contentType);
|
|
183
|
+
const outputExt = extname(outputPath).toLowerCase();
|
|
184
|
+
if (!inputExt || inputExt === outputExt) {
|
|
185
|
+
await writeFile(outputPath, buffer);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'venice-audio-'));
|
|
189
|
+
const tempInput = join(tempDir, `source${inputExt}`);
|
|
190
|
+
try {
|
|
191
|
+
await writeFile(tempInput, buffer);
|
|
192
|
+
const ffmpegArgs = ffmpegTranscodeArgs(tempInput, outputPath, outputExt);
|
|
193
|
+
await execFileAsync('ffmpeg', ffmpegArgs);
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function extensionFromContentType(contentType) {
|
|
200
|
+
if (contentType.includes('audio/mpeg'))
|
|
201
|
+
return '.mp3';
|
|
202
|
+
if (contentType.includes('audio/wav'))
|
|
203
|
+
return '.wav';
|
|
204
|
+
if (contentType.includes('audio/flac'))
|
|
205
|
+
return '.flac';
|
|
206
|
+
if (contentType.includes('audio/aac'))
|
|
207
|
+
return '.aac';
|
|
208
|
+
if (contentType.includes('audio/opus'))
|
|
209
|
+
return '.opus';
|
|
210
|
+
if (contentType.includes('audio/pcm'))
|
|
211
|
+
return '.pcm';
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
function ffmpegTranscodeArgs(inputPath, outputPath, outputExt) {
|
|
215
|
+
switch (outputExt) {
|
|
216
|
+
case '.mp3':
|
|
217
|
+
return ['-y', '-i', inputPath, '-vn', '-codec:a', 'libmp3lame', '-q:a', '2', outputPath];
|
|
218
|
+
case '.wav':
|
|
219
|
+
return ['-y', '-i', inputPath, '-vn', '-codec:a', 'pcm_s16le', outputPath];
|
|
220
|
+
case '.flac':
|
|
221
|
+
return ['-y', '-i', inputPath, '-vn', '-codec:a', 'flac', outputPath];
|
|
222
|
+
case '.aac':
|
|
223
|
+
return ['-y', '-i', inputPath, '-vn', '-codec:a', 'aac', outputPath];
|
|
224
|
+
default:
|
|
225
|
+
return ['-y', '-i', inputPath, outputPath];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function clamp(value, min, max) {
|
|
229
|
+
return Math.min(Math.max(value, min), max);
|
|
230
|
+
}
|
|
231
|
+
function sleep(ms) {
|
|
232
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=audio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio.js","sourceRoot":"","sources":["../../src/venice/audio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export declare class VeniceRequestError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly body: unknown;
|
|
4
|
+
constructor(message: string, status: number, body: unknown);
|
|
5
|
+
}
|
|
6
|
+
export interface VeniceDeprecationNotice {
|
|
7
|
+
modelId: string | null;
|
|
8
|
+
modelName: string | null;
|
|
9
|
+
warning: string;
|
|
10
|
+
date: string | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Inspect a Response's headers for Venice deprecation notices and emit
|
|
14
|
+
* a structured stderr warning the first time each unique notice is seen
|
|
15
|
+
* in this process. Returns the parsed notice when present (mostly for
|
|
16
|
+
* testing), otherwise null.
|
|
17
|
+
*
|
|
18
|
+
* Exported for tests; callers in this file invoke it from each request
|
|
19
|
+
* path so every response shape (json, binary, json-or-binary) is covered.
|
|
20
|
+
*/
|
|
21
|
+
export declare function reportVeniceDeprecation(headers: Headers, requestPath: string): VeniceDeprecationNotice | null;
|
|
22
|
+
/**
|
|
23
|
+
* Test-only: reset the per-process deduplication state so unit tests can
|
|
24
|
+
* exercise the warn-once behavior across multiple invocations.
|
|
25
|
+
*/
|
|
26
|
+
export declare function _resetDeprecationDedupeForTests(): void;
|
|
27
|
+
export declare class VeniceClient {
|
|
28
|
+
private readonly apiKey;
|
|
29
|
+
private readonly baseUrl;
|
|
30
|
+
/**
|
|
31
|
+
* Timestamp (epoch ms) of the last request that completed. Used by the
|
|
32
|
+
* simple rate-limiter to ensure a minimum gap between consecutive calls.
|
|
33
|
+
*/
|
|
34
|
+
private lastRequestAt;
|
|
35
|
+
/**
|
|
36
|
+
* @param apiKey Bearer token for the Venice API. Falls back to the
|
|
37
|
+
* `VENICE_API_KEY` environment variable when omitted.
|
|
38
|
+
* @param baseUrl Root URL for the API (no trailing slash).
|
|
39
|
+
*/
|
|
40
|
+
constructor(apiKey?: string, baseUrl?: string);
|
|
41
|
+
/** Send a GET request and return parsed JSON. Used by setup/doctor checks. */
|
|
42
|
+
get<T = unknown>(path: string): Promise<T>;
|
|
43
|
+
/**
|
|
44
|
+
* Send a POST request to `path` with a JSON body and return the parsed
|
|
45
|
+
* response.
|
|
46
|
+
*
|
|
47
|
+
* Automatically retries on transient failures (HTTP 429 / 5xx) up to
|
|
48
|
+
* {@link MAX_RETRIES} times using exponential back-off. A small delay is
|
|
49
|
+
* inserted between consecutive requests to stay within rate limits.
|
|
50
|
+
*
|
|
51
|
+
* @typeParam T Expected shape of the parsed JSON response.
|
|
52
|
+
* @param path API path **including** the leading slash (e.g. `/api/v1/image/generate`).
|
|
53
|
+
* @param body Request payload -- will be JSON-stringified.
|
|
54
|
+
* @returns Parsed JSON response body.
|
|
55
|
+
* @throws {VeniceRequestError} On non-retryable HTTP errors (4xx other than 429).
|
|
56
|
+
* @throws {Error} When all retry attempts are exhausted.
|
|
57
|
+
*/
|
|
58
|
+
post<T = unknown>(path: string, body: Record<string, unknown>): Promise<T>;
|
|
59
|
+
/**
|
|
60
|
+
* POST with JSON body, receive raw binary (e.g. image/png from multi-edit).
|
|
61
|
+
* Same retry/rate-limit logic as {@link post}.
|
|
62
|
+
*/
|
|
63
|
+
postBinary(path: string, body: Record<string, unknown>): Promise<Buffer>;
|
|
64
|
+
/**
|
|
65
|
+
* POST with JSON body, receive either JSON status data or raw binary media.
|
|
66
|
+
* Useful for async retrieval endpoints that return JSON while processing and
|
|
67
|
+
* switch to binary once the asset is ready for download.
|
|
68
|
+
*/
|
|
69
|
+
postBinaryOrJson<T = unknown>(path: string, body: Record<string, unknown>): Promise<{
|
|
70
|
+
contentType: string;
|
|
71
|
+
value: T | Buffer;
|
|
72
|
+
}>;
|
|
73
|
+
/**
|
|
74
|
+
* Send a chat completion request with multimodal content (text + images).
|
|
75
|
+
* Uses the OpenAI-compatible chat completions endpoint.
|
|
76
|
+
*/
|
|
77
|
+
chatWithVision(model: string, systemPrompt: string, imageDataUris: string[], userPrompt: string): Promise<string>;
|
|
78
|
+
/**
|
|
79
|
+
* Ensure at least {@link RATE_LIMIT_DELAY_MS} ms have elapsed since the
|
|
80
|
+
* previous request completed.
|
|
81
|
+
*/
|
|
82
|
+
private applyRateLimit;
|
|
83
|
+
/** Promise-based sleep helper. */
|
|
84
|
+
private static sleep;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/venice/client.ts"],"names":[],"mappings":"AAkBA,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,EAAE,OAAO,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;CAM3D;AA6BD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM,GAClB,uBAAuB,GAAG,IAAI,CA2BhC;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAK;IAE1B;;;;OAIG;gBACS,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAa7C,8EAA8E;IACxE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAuBhD;;;;;;;;;;;;;;OAcG;IACG,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAmFhF;;;OAGG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IA+D9E;;;;OAIG;IACG,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAA;KAAE,CAAC;IAyEtD;;;OAGG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EAAE,EACvB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC;IA0BlB;;;OAGG;YACW,cAAc;IAO5B,kCAAkC;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK;CAGrB"}
|