@vibeframe/cli 0.109.1 → 0.110.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/dist/index.js +107 -3
- package/dist/tools/_shared/elicit.d.ts +31 -0
- package/dist/tools/_shared/elicit.test.d.ts +1 -0
- package/dist/tools/adapters/mcp.d.ts +25 -0
- package/dist/tools/adapters/mcp.js +2 -1
- package/dist/tools/define-tool.d.ts +17 -0
- package/dist/tools/manifest/index.js +99 -2
- package/dist/tools/manifest/scene.d.ts +2 -2
- package/dist/tools/manifest/storyboard.d.ts +2 -2
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -29613,6 +29613,7 @@ function isComposerProvider(value) {
|
|
|
29613
29613
|
return value === "claude" || value === "openai" || value === "gemini";
|
|
29614
29614
|
}
|
|
29615
29615
|
function resolveComposer(explicit) {
|
|
29616
|
+
loadEnv();
|
|
29616
29617
|
if (explicit) {
|
|
29617
29618
|
const key = readKey(explicit);
|
|
29618
29619
|
if (!key) {
|
|
@@ -29637,6 +29638,7 @@ var ENV_VAR, PROVIDER_LABEL, ComposerResolveError;
|
|
|
29637
29638
|
var init_composer_resolve = __esm({
|
|
29638
29639
|
"src/commands/_shared/composer-resolve.ts"() {
|
|
29639
29640
|
"use strict";
|
|
29641
|
+
init_api_key();
|
|
29640
29642
|
ENV_VAR = {
|
|
29641
29643
|
claude: "ANTHROPIC_API_KEY",
|
|
29642
29644
|
openai: "OPENAI_API_KEY",
|
|
@@ -67836,6 +67838,82 @@ var init_long_poll = __esm({
|
|
|
67836
67838
|
}
|
|
67837
67839
|
});
|
|
67838
67840
|
|
|
67841
|
+
// src/tools/_shared/elicit.ts
|
|
67842
|
+
function planBuildElicitation(args) {
|
|
67843
|
+
const assetsWillRun = args.stage === void 0 || args.stage === "all" || args.stage === "assets";
|
|
67844
|
+
if (!assetsWillRun) return null;
|
|
67845
|
+
const properties = {};
|
|
67846
|
+
const required = [];
|
|
67847
|
+
const narrationUndecided = !args.skipNarration && (args.ttsProvider === void 0 || args.ttsProvider === "auto");
|
|
67848
|
+
if (narrationUndecided) {
|
|
67849
|
+
properties.narration = {
|
|
67850
|
+
type: "string",
|
|
67851
|
+
title: "Narration voice-over",
|
|
67852
|
+
description: "Which TTS engine narrates the video?",
|
|
67853
|
+
enum: [...NARRATION_CHOICES],
|
|
67854
|
+
enumNames: [
|
|
67855
|
+
"Kokoro \u2014 free, runs locally on this machine",
|
|
67856
|
+
"ElevenLabs \u2014 cloud TTS, uses your ElevenLabs credits"
|
|
67857
|
+
]
|
|
67858
|
+
};
|
|
67859
|
+
required.push("narration");
|
|
67860
|
+
}
|
|
67861
|
+
if (args.skipBackdrop === void 0 && args.imageProvider === void 0) {
|
|
67862
|
+
properties.backdrop_images = {
|
|
67863
|
+
type: "string",
|
|
67864
|
+
title: "Backdrop images",
|
|
67865
|
+
description: "Generate AI background images for each scene?",
|
|
67866
|
+
enum: [...BACKDROP_CHOICES],
|
|
67867
|
+
enumNames: [
|
|
67868
|
+
"Skip \u2014 free, pure typographic scenes",
|
|
67869
|
+
"OpenAI \u2014 paid image generation (roughly $1-3 per video)"
|
|
67870
|
+
]
|
|
67871
|
+
};
|
|
67872
|
+
required.push("backdrop_images");
|
|
67873
|
+
}
|
|
67874
|
+
if (args.maxCostUsd === void 0) {
|
|
67875
|
+
properties.max_cost_usd = {
|
|
67876
|
+
type: "number",
|
|
67877
|
+
title: "Max provider spend (USD)",
|
|
67878
|
+
description: "Abort before any paid provider call when the estimate exceeds this cap. Leave empty for no cap.",
|
|
67879
|
+
minimum: 0
|
|
67880
|
+
};
|
|
67881
|
+
}
|
|
67882
|
+
if (Object.keys(properties).length === 0) return null;
|
|
67883
|
+
return {
|
|
67884
|
+
message: "VibeFrame is about to build this video. Choose how the assets are generated:",
|
|
67885
|
+
requestedSchema: { type: "object", properties, required }
|
|
67886
|
+
};
|
|
67887
|
+
}
|
|
67888
|
+
function applyElicitationAnswers(args, content) {
|
|
67889
|
+
if (!content) return args;
|
|
67890
|
+
const next = { ...args };
|
|
67891
|
+
const narration = content.narration;
|
|
67892
|
+
if (typeof narration === "string" && NARRATION_CHOICES.includes(narration)) {
|
|
67893
|
+
next.ttsProvider = narration;
|
|
67894
|
+
}
|
|
67895
|
+
const backdrop = content.backdrop_images;
|
|
67896
|
+
if (backdrop === "skip") {
|
|
67897
|
+
next.skipBackdrop = true;
|
|
67898
|
+
} else if (backdrop === "openai") {
|
|
67899
|
+
next.skipBackdrop = false;
|
|
67900
|
+
next.imageProvider = "openai";
|
|
67901
|
+
}
|
|
67902
|
+
const cap = content.max_cost_usd;
|
|
67903
|
+
if (typeof cap === "number" && Number.isFinite(cap) && cap >= 0) {
|
|
67904
|
+
next.maxCostUsd = cap;
|
|
67905
|
+
}
|
|
67906
|
+
return next;
|
|
67907
|
+
}
|
|
67908
|
+
var NARRATION_CHOICES, BACKDROP_CHOICES;
|
|
67909
|
+
var init_elicit = __esm({
|
|
67910
|
+
"src/tools/_shared/elicit.ts"() {
|
|
67911
|
+
"use strict";
|
|
67912
|
+
NARRATION_CHOICES = ["kokoro", "elevenlabs"];
|
|
67913
|
+
BACKDROP_CHOICES = ["skip", "openai"];
|
|
67914
|
+
}
|
|
67915
|
+
});
|
|
67916
|
+
|
|
67839
67917
|
// src/tools/manifest/scene.ts
|
|
67840
67918
|
import { resolve as resolve75, relative as relative12 } from "node:path";
|
|
67841
67919
|
function summariseLint(result) {
|
|
@@ -67974,6 +68052,7 @@ var init_scene2 = __esm({
|
|
|
67974
68052
|
init_zod();
|
|
67975
68053
|
init_define_tool();
|
|
67976
68054
|
init_long_poll();
|
|
68055
|
+
init_elicit();
|
|
67977
68056
|
init_visual_styles();
|
|
67978
68057
|
init_scene_project();
|
|
67979
68058
|
init_scene();
|
|
@@ -68307,9 +68386,32 @@ var init_scene2 = __esm({
|
|
|
68307
68386
|
name: "build",
|
|
68308
68387
|
category: "scene",
|
|
68309
68388
|
cost: "high",
|
|
68310
|
-
description: "v0.60 one-shot orchestrator: read STORYBOARD.md per-beat YAML cues (narration / backdrop / duration), dispatch TTS + image generation per beat, compose scene HTML via the compose-scenes-with-skills pipeline, then render to MP4. Use this instead of chaining init + scene_add + render manually. Caches by SHA256 of (DESIGN.md + cue body) so re-runs are idempotent and cheap. Long runs: over MCP, calls exceeding ~45s return immediately with { promoted: true, jobId, status: 'running' } \u2014 poll status_job every 15-30s until completed/failed instead of re-invoking build. Emits MCP progress notifications when the client supplies a progressToken.",
|
|
68389
|
+
description: "v0.60 one-shot orchestrator: read STORYBOARD.md per-beat YAML cues (narration / backdrop / duration), dispatch TTS + image generation per beat, compose scene HTML via the compose-scenes-with-skills pipeline, then render to MP4. Use this instead of chaining init + scene_add + render manually. Caches by SHA256 of (DESIGN.md + cue body) so re-runs are idempotent and cheap. Long runs: over MCP, calls exceeding ~45s return immediately with { promoted: true, jobId, status: 'running' } \u2014 poll status_job every 15-30s until completed/failed instead of re-invoking build. Emits MCP progress notifications when the client supplies a progressToken. When the MCP host supports elicitation, unspecified asset choices (narration provider, backdrop images, cost cap) are confirmed with the user via a form before the build starts.",
|
|
68311
68390
|
schema: sceneBuildSchema,
|
|
68312
68391
|
async execute(args, ctx) {
|
|
68392
|
+
let warnings;
|
|
68393
|
+
if (ctx.surface === "mcp" && ctx.elicit) {
|
|
68394
|
+
const form = planBuildElicitation(args);
|
|
68395
|
+
if (form) {
|
|
68396
|
+
const outcome = await ctx.elicit(form).catch(() => null);
|
|
68397
|
+
if (outcome === null) {
|
|
68398
|
+
warnings = ["Asset-choice elicitation failed or timed out; proceeding with defaults."];
|
|
68399
|
+
} else if (outcome.action === "accept") {
|
|
68400
|
+
args = applyElicitationAnswers(args, outcome.content);
|
|
68401
|
+
} else {
|
|
68402
|
+
return {
|
|
68403
|
+
success: false,
|
|
68404
|
+
error: "Build cancelled \u2014 the user declined the asset choices.",
|
|
68405
|
+
data: {
|
|
68406
|
+
cancelled: true,
|
|
68407
|
+
retryWith: [
|
|
68408
|
+
`build { projectDir: "${args.projectDir ?? "."}", ttsProvider: "kokoro", skipBackdrop: true }`
|
|
68409
|
+
]
|
|
68410
|
+
}
|
|
68411
|
+
};
|
|
68412
|
+
}
|
|
68413
|
+
}
|
|
68414
|
+
}
|
|
68313
68415
|
const projectDir = args.projectDir ? resolve75(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
68314
68416
|
const runBuild = (report) => executeSceneBuild({
|
|
68315
68417
|
projectDir,
|
|
@@ -68337,7 +68439,9 @@ var init_scene2 = __esm({
|
|
|
68337
68439
|
ctx.onProgress?.({ message: update.message ?? update.stage });
|
|
68338
68440
|
report(update);
|
|
68339
68441
|
}
|
|
68340
|
-
}).then(mapBuildResultToToolResult)
|
|
68442
|
+
}).then(mapBuildResultToToolResult).then(
|
|
68443
|
+
(result) => warnings === void 0 ? result : { ...result, data: { ...result.data, elicitationWarnings: warnings } }
|
|
68444
|
+
);
|
|
68341
68445
|
if (ctx.surface !== "mcp") {
|
|
68342
68446
|
return runBuild(() => void 0);
|
|
68343
68447
|
}
|
|
@@ -72909,7 +73013,7 @@ init_source();
|
|
|
72909
73013
|
// package.json
|
|
72910
73014
|
var package_default = {
|
|
72911
73015
|
name: "@vibeframe/cli",
|
|
72912
|
-
version: "0.
|
|
73016
|
+
version: "0.110.0",
|
|
72913
73017
|
description: "VibeFrame CLI - agentic video workflow runtime",
|
|
72914
73018
|
private: false,
|
|
72915
73019
|
license: "MIT",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ElicitForm } from "../adapters/mcp.js";
|
|
2
|
+
/**
|
|
3
|
+
* @module tools/_shared/elicit
|
|
4
|
+
*
|
|
5
|
+
* Pre-flight elicitation for the `build` tool: when an MCP client supports
|
|
6
|
+
* elicitation, ask the user the choices the host agent would otherwise pick
|
|
7
|
+
* silently (narration provider, paid backdrop generation, cost ceiling).
|
|
8
|
+
* Pure functions — the MCP wiring lives in the tool's execute and the
|
|
9
|
+
* server's makeElicitFn; CLI/Agent surfaces never reach this code path.
|
|
10
|
+
*/
|
|
11
|
+
/** The subset of build args that drive the question set. */
|
|
12
|
+
export interface BuildChoiceArgs {
|
|
13
|
+
stage?: "assets" | "compose" | "sync" | "render" | "all";
|
|
14
|
+
ttsProvider?: "auto" | "elevenlabs" | "kokoro";
|
|
15
|
+
skipNarration?: boolean;
|
|
16
|
+
skipBackdrop?: boolean;
|
|
17
|
+
imageProvider?: string;
|
|
18
|
+
maxCostUsd?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Builds the elicitation form for a build call, asking ONLY about choices the
|
|
22
|
+
* caller left unspecified. Returns null when there is nothing to ask — every
|
|
23
|
+
* choice explicit, or the requested stage doesn't generate assets.
|
|
24
|
+
*/
|
|
25
|
+
export declare function planBuildElicitation(args: BuildChoiceArgs): ElicitForm | null;
|
|
26
|
+
/**
|
|
27
|
+
* Maps accepted form answers back onto build args. Unknown or invalid values
|
|
28
|
+
* are ignored so a misbehaving client can never produce a worse state than
|
|
29
|
+
* the defaults the user would have gotten without elicitation.
|
|
30
|
+
*/
|
|
31
|
+
export declare function applyElicitationAnswers<T extends BuildChoiceArgs>(args: T, content: Record<string, string | number | boolean | string[]> | undefined): T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -22,6 +22,25 @@ export interface McpTool {
|
|
|
22
22
|
description: string;
|
|
23
23
|
inputSchema: McpInputSchema;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Structural mirror of the MCP elicitation form request/result (the CLI
|
|
27
|
+
* package deliberately has no dependency on @modelcontextprotocol/sdk).
|
|
28
|
+
* `requestedSchema.properties` values follow the spec's flat primitive
|
|
29
|
+
* schema: string (optionally with enum/enumNames), number, boolean.
|
|
30
|
+
*/
|
|
31
|
+
export interface ElicitForm {
|
|
32
|
+
message: string;
|
|
33
|
+
requestedSchema: {
|
|
34
|
+
type: "object";
|
|
35
|
+
properties: Record<string, unknown>;
|
|
36
|
+
required?: string[];
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface ElicitOutcome {
|
|
40
|
+
action: "accept" | "decline" | "cancel";
|
|
41
|
+
content?: Record<string, string | number | boolean | string[]>;
|
|
42
|
+
}
|
|
43
|
+
export type ElicitFn = (form: ElicitForm) => Promise<ElicitOutcome>;
|
|
25
44
|
/** Per-call extras forwarded by the MCP server request handler. */
|
|
26
45
|
export interface McpCallExtra {
|
|
27
46
|
/**
|
|
@@ -34,6 +53,12 @@ export interface McpCallExtra {
|
|
|
34
53
|
total?: number;
|
|
35
54
|
message?: string;
|
|
36
55
|
}) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Sends an `elicitation/create` form to the client and resolves with the
|
|
58
|
+
* user's answer. Only present when the connected client advertises the
|
|
59
|
+
* elicitation capability.
|
|
60
|
+
*/
|
|
61
|
+
elicit?: ElicitFn;
|
|
37
62
|
}
|
|
38
63
|
export type McpDispatcher = (name: string, args: Record<string, unknown>, extra?: McpCallExtra) => Promise<{
|
|
39
64
|
content: Array<{
|
|
@@ -245,7 +245,8 @@ function buildMcpDispatcher(manifest) {
|
|
|
245
245
|
() => tool.execute(parsed.data, {
|
|
246
246
|
workingDirectory: process.cwd(),
|
|
247
247
|
surface: "mcp",
|
|
248
|
-
...extra?.onProgress ? { onProgress: sink.send } : {}
|
|
248
|
+
...extra?.onProgress ? { onProgress: sink.send } : {},
|
|
249
|
+
...extra?.elicit ? { elicit: extra.elicit } : {}
|
|
249
250
|
})
|
|
250
251
|
);
|
|
251
252
|
const text = result.success ? JSON.stringify({ success: true, ...result.data }) : result.data ? JSON.stringify({
|
|
@@ -49,6 +49,23 @@ export interface ExecuteContext {
|
|
|
49
49
|
total?: number;
|
|
50
50
|
message?: string;
|
|
51
51
|
}) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Optional MCP elicitation channel. Present only when the connected MCP
|
|
54
|
+
* client advertises the elicitation capability; CLI/Agent surfaces leave
|
|
55
|
+
* it undefined, so CLI behavior never changes. See adapters/mcp.ts for
|
|
56
|
+
* the structural types.
|
|
57
|
+
*/
|
|
58
|
+
elicit?: (form: {
|
|
59
|
+
message: string;
|
|
60
|
+
requestedSchema: {
|
|
61
|
+
type: "object";
|
|
62
|
+
properties: Record<string, unknown>;
|
|
63
|
+
required?: string[];
|
|
64
|
+
};
|
|
65
|
+
}) => Promise<{
|
|
66
|
+
action: "accept" | "decline" | "cancel";
|
|
67
|
+
content?: Record<string, string | number | boolean | string[]>;
|
|
68
|
+
}>;
|
|
52
69
|
}
|
|
53
70
|
export interface ToolExecuteResult {
|
|
54
71
|
success: boolean;
|
|
@@ -30319,6 +30319,7 @@ function isComposerProvider(value) {
|
|
|
30319
30319
|
return value === "claude" || value === "openai" || value === "gemini";
|
|
30320
30320
|
}
|
|
30321
30321
|
function resolveComposer(explicit) {
|
|
30322
|
+
loadEnv();
|
|
30322
30323
|
if (explicit) {
|
|
30323
30324
|
const key = readKey(explicit);
|
|
30324
30325
|
if (!key) {
|
|
@@ -30343,6 +30344,7 @@ var ENV_VAR, PROVIDER_LABEL, ComposerResolveError;
|
|
|
30343
30344
|
var init_composer_resolve = __esm({
|
|
30344
30345
|
"src/commands/_shared/composer-resolve.ts"() {
|
|
30345
30346
|
"use strict";
|
|
30347
|
+
init_api_key();
|
|
30346
30348
|
ENV_VAR = {
|
|
30347
30349
|
claude: "ANTHROPIC_API_KEY",
|
|
30348
30350
|
openai: "OPENAI_API_KEY",
|
|
@@ -51298,6 +51300,76 @@ function pickOutputPath(data) {
|
|
|
51298
51300
|
return typeof candidate === "string" ? candidate : void 0;
|
|
51299
51301
|
}
|
|
51300
51302
|
|
|
51303
|
+
// src/tools/_shared/elicit.ts
|
|
51304
|
+
var NARRATION_CHOICES = ["kokoro", "elevenlabs"];
|
|
51305
|
+
var BACKDROP_CHOICES = ["skip", "openai"];
|
|
51306
|
+
function planBuildElicitation(args) {
|
|
51307
|
+
const assetsWillRun = args.stage === void 0 || args.stage === "all" || args.stage === "assets";
|
|
51308
|
+
if (!assetsWillRun) return null;
|
|
51309
|
+
const properties = {};
|
|
51310
|
+
const required = [];
|
|
51311
|
+
const narrationUndecided = !args.skipNarration && (args.ttsProvider === void 0 || args.ttsProvider === "auto");
|
|
51312
|
+
if (narrationUndecided) {
|
|
51313
|
+
properties.narration = {
|
|
51314
|
+
type: "string",
|
|
51315
|
+
title: "Narration voice-over",
|
|
51316
|
+
description: "Which TTS engine narrates the video?",
|
|
51317
|
+
enum: [...NARRATION_CHOICES],
|
|
51318
|
+
enumNames: [
|
|
51319
|
+
"Kokoro \u2014 free, runs locally on this machine",
|
|
51320
|
+
"ElevenLabs \u2014 cloud TTS, uses your ElevenLabs credits"
|
|
51321
|
+
]
|
|
51322
|
+
};
|
|
51323
|
+
required.push("narration");
|
|
51324
|
+
}
|
|
51325
|
+
if (args.skipBackdrop === void 0 && args.imageProvider === void 0) {
|
|
51326
|
+
properties.backdrop_images = {
|
|
51327
|
+
type: "string",
|
|
51328
|
+
title: "Backdrop images",
|
|
51329
|
+
description: "Generate AI background images for each scene?",
|
|
51330
|
+
enum: [...BACKDROP_CHOICES],
|
|
51331
|
+
enumNames: [
|
|
51332
|
+
"Skip \u2014 free, pure typographic scenes",
|
|
51333
|
+
"OpenAI \u2014 paid image generation (roughly $1-3 per video)"
|
|
51334
|
+
]
|
|
51335
|
+
};
|
|
51336
|
+
required.push("backdrop_images");
|
|
51337
|
+
}
|
|
51338
|
+
if (args.maxCostUsd === void 0) {
|
|
51339
|
+
properties.max_cost_usd = {
|
|
51340
|
+
type: "number",
|
|
51341
|
+
title: "Max provider spend (USD)",
|
|
51342
|
+
description: "Abort before any paid provider call when the estimate exceeds this cap. Leave empty for no cap.",
|
|
51343
|
+
minimum: 0
|
|
51344
|
+
};
|
|
51345
|
+
}
|
|
51346
|
+
if (Object.keys(properties).length === 0) return null;
|
|
51347
|
+
return {
|
|
51348
|
+
message: "VibeFrame is about to build this video. Choose how the assets are generated:",
|
|
51349
|
+
requestedSchema: { type: "object", properties, required }
|
|
51350
|
+
};
|
|
51351
|
+
}
|
|
51352
|
+
function applyElicitationAnswers(args, content) {
|
|
51353
|
+
if (!content) return args;
|
|
51354
|
+
const next = { ...args };
|
|
51355
|
+
const narration = content.narration;
|
|
51356
|
+
if (typeof narration === "string" && NARRATION_CHOICES.includes(narration)) {
|
|
51357
|
+
next.ttsProvider = narration;
|
|
51358
|
+
}
|
|
51359
|
+
const backdrop = content.backdrop_images;
|
|
51360
|
+
if (backdrop === "skip") {
|
|
51361
|
+
next.skipBackdrop = true;
|
|
51362
|
+
} else if (backdrop === "openai") {
|
|
51363
|
+
next.skipBackdrop = false;
|
|
51364
|
+
next.imageProvider = "openai";
|
|
51365
|
+
}
|
|
51366
|
+
const cap = content.max_cost_usd;
|
|
51367
|
+
if (typeof cap === "number" && Number.isFinite(cap) && cap >= 0) {
|
|
51368
|
+
next.maxCostUsd = cap;
|
|
51369
|
+
}
|
|
51370
|
+
return next;
|
|
51371
|
+
}
|
|
51372
|
+
|
|
51301
51373
|
// src/commands/_shared/visual-styles.ts
|
|
51302
51374
|
var STYLES = [
|
|
51303
51375
|
{
|
|
@@ -53536,9 +53608,32 @@ var sceneBuildTool = defineTool({
|
|
|
53536
53608
|
name: "build",
|
|
53537
53609
|
category: "scene",
|
|
53538
53610
|
cost: "high",
|
|
53539
|
-
description: "v0.60 one-shot orchestrator: read STORYBOARD.md per-beat YAML cues (narration / backdrop / duration), dispatch TTS + image generation per beat, compose scene HTML via the compose-scenes-with-skills pipeline, then render to MP4. Use this instead of chaining init + scene_add + render manually. Caches by SHA256 of (DESIGN.md + cue body) so re-runs are idempotent and cheap. Long runs: over MCP, calls exceeding ~45s return immediately with { promoted: true, jobId, status: 'running' } \u2014 poll status_job every 15-30s until completed/failed instead of re-invoking build. Emits MCP progress notifications when the client supplies a progressToken.",
|
|
53611
|
+
description: "v0.60 one-shot orchestrator: read STORYBOARD.md per-beat YAML cues (narration / backdrop / duration), dispatch TTS + image generation per beat, compose scene HTML via the compose-scenes-with-skills pipeline, then render to MP4. Use this instead of chaining init + scene_add + render manually. Caches by SHA256 of (DESIGN.md + cue body) so re-runs are idempotent and cheap. Long runs: over MCP, calls exceeding ~45s return immediately with { promoted: true, jobId, status: 'running' } \u2014 poll status_job every 15-30s until completed/failed instead of re-invoking build. Emits MCP progress notifications when the client supplies a progressToken. When the MCP host supports elicitation, unspecified asset choices (narration provider, backdrop images, cost cap) are confirmed with the user via a form before the build starts.",
|
|
53540
53612
|
schema: sceneBuildSchema,
|
|
53541
53613
|
async execute(args, ctx) {
|
|
53614
|
+
let warnings;
|
|
53615
|
+
if (ctx.surface === "mcp" && ctx.elicit) {
|
|
53616
|
+
const form = planBuildElicitation(args);
|
|
53617
|
+
if (form) {
|
|
53618
|
+
const outcome = await ctx.elicit(form).catch(() => null);
|
|
53619
|
+
if (outcome === null) {
|
|
53620
|
+
warnings = ["Asset-choice elicitation failed or timed out; proceeding with defaults."];
|
|
53621
|
+
} else if (outcome.action === "accept") {
|
|
53622
|
+
args = applyElicitationAnswers(args, outcome.content);
|
|
53623
|
+
} else {
|
|
53624
|
+
return {
|
|
53625
|
+
success: false,
|
|
53626
|
+
error: "Build cancelled \u2014 the user declined the asset choices.",
|
|
53627
|
+
data: {
|
|
53628
|
+
cancelled: true,
|
|
53629
|
+
retryWith: [
|
|
53630
|
+
`build { projectDir: "${args.projectDir ?? "."}", ttsProvider: "kokoro", skipBackdrop: true }`
|
|
53631
|
+
]
|
|
53632
|
+
}
|
|
53633
|
+
};
|
|
53634
|
+
}
|
|
53635
|
+
}
|
|
53636
|
+
}
|
|
53542
53637
|
const projectDir = args.projectDir ? resolve26(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
|
|
53543
53638
|
const runBuild = (report) => executeSceneBuild({
|
|
53544
53639
|
projectDir,
|
|
@@ -53566,7 +53661,9 @@ var sceneBuildTool = defineTool({
|
|
|
53566
53661
|
ctx.onProgress?.({ message: update.message ?? update.stage });
|
|
53567
53662
|
report(update);
|
|
53568
53663
|
}
|
|
53569
|
-
}).then(mapBuildResultToToolResult)
|
|
53664
|
+
}).then(mapBuildResultToToolResult).then(
|
|
53665
|
+
(result) => warnings === void 0 ? result : { ...result, data: { ...result.data, elicitationWarnings: warnings } }
|
|
53666
|
+
);
|
|
53570
53667
|
if (ctx.surface !== "mcp") {
|
|
53571
53668
|
return runBuild(() => void 0);
|
|
53572
53669
|
}
|
|
@@ -167,9 +167,9 @@ export declare const sceneBuildTool: import("../define-tool.js").ToolDefinition<
|
|
|
167
167
|
skipBackdrop?: boolean | undefined;
|
|
168
168
|
skipRender?: boolean | undefined;
|
|
169
169
|
imageProvider?: "openai" | undefined;
|
|
170
|
+
ttsProvider?: "elevenlabs" | "auto" | "kokoro" | undefined;
|
|
170
171
|
skipVideo?: boolean | undefined;
|
|
171
172
|
skipMusic?: boolean | undefined;
|
|
172
|
-
ttsProvider?: "elevenlabs" | "auto" | "kokoro" | undefined;
|
|
173
173
|
videoProvider?: "grok" | "seedance" | "kling" | "runway" | "veo" | undefined;
|
|
174
174
|
musicProvider?: "elevenlabs" | "replicate" | undefined;
|
|
175
175
|
imageQuality?: "standard" | "hd" | undefined;
|
|
@@ -188,9 +188,9 @@ export declare const sceneBuildTool: import("../define-tool.js").ToolDefinition<
|
|
|
188
188
|
skipBackdrop?: boolean | undefined;
|
|
189
189
|
skipRender?: boolean | undefined;
|
|
190
190
|
imageProvider?: "openai" | undefined;
|
|
191
|
+
ttsProvider?: "elevenlabs" | "auto" | "kokoro" | undefined;
|
|
191
192
|
skipVideo?: boolean | undefined;
|
|
192
193
|
skipMusic?: boolean | undefined;
|
|
193
|
-
ttsProvider?: "elevenlabs" | "auto" | "kokoro" | undefined;
|
|
194
194
|
videoProvider?: "grok" | "seedance" | "kling" | "runway" | "veo" | undefined;
|
|
195
195
|
musicProvider?: "elevenlabs" | "replicate" | undefined;
|
|
196
196
|
imageQuality?: "standard" | "hd" | undefined;
|
|
@@ -107,9 +107,9 @@ export declare const planTool: import("../define-tool.js").ToolDefinition<z.ZodO
|
|
|
107
107
|
skipNarration?: boolean | undefined;
|
|
108
108
|
skipBackdrop?: boolean | undefined;
|
|
109
109
|
imageProvider?: string | undefined;
|
|
110
|
+
ttsProvider?: "elevenlabs" | "auto" | "kokoro" | undefined;
|
|
110
111
|
skipVideo?: boolean | undefined;
|
|
111
112
|
skipMusic?: boolean | undefined;
|
|
112
|
-
ttsProvider?: "elevenlabs" | "auto" | "kokoro" | undefined;
|
|
113
113
|
videoProvider?: "grok" | "seedance" | "kling" | "runway" | "veo" | undefined;
|
|
114
114
|
musicProvider?: "elevenlabs" | "replicate" | undefined;
|
|
115
115
|
imageQuality?: "standard" | "hd" | undefined;
|
|
@@ -125,9 +125,9 @@ export declare const planTool: import("../define-tool.js").ToolDefinition<z.ZodO
|
|
|
125
125
|
skipNarration?: boolean | undefined;
|
|
126
126
|
skipBackdrop?: boolean | undefined;
|
|
127
127
|
imageProvider?: string | undefined;
|
|
128
|
+
ttsProvider?: "elevenlabs" | "auto" | "kokoro" | undefined;
|
|
128
129
|
skipVideo?: boolean | undefined;
|
|
129
130
|
skipMusic?: boolean | undefined;
|
|
130
|
-
ttsProvider?: "elevenlabs" | "auto" | "kokoro" | undefined;
|
|
131
131
|
videoProvider?: "grok" | "seedance" | "kling" | "runway" | "veo" | undefined;
|
|
132
132
|
musicProvider?: "elevenlabs" | "replicate" | undefined;
|
|
133
133
|
imageQuality?: "standard" | "hd" | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.110.0",
|
|
4
4
|
"description": "VibeFrame CLI - agentic video workflow runtime",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
"tsx": "^4.21.0",
|
|
84
84
|
"typescript": "^5.3.3",
|
|
85
85
|
"vitest": "^1.2.2",
|
|
86
|
-
"@vibeframe/ai-providers": "0.
|
|
87
|
-
"@vibeframe/core": "0.
|
|
86
|
+
"@vibeframe/ai-providers": "0.110.0",
|
|
87
|
+
"@vibeframe/core": "0.110.0"
|
|
88
88
|
},
|
|
89
89
|
"engines": {
|
|
90
90
|
"node": ">=20"
|