@nodetool-ai/agents 0.8.1 → 0.8.3
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/.nodetool-build-stamp +1 -1
- package/dist/analysis/audio-dsp.d.ts +3 -2
- package/dist/analysis/audio-dsp.d.ts.map +1 -1
- package/dist/analysis/audio-dsp.js +11 -8
- package/dist/analysis/audio-dsp.js.map +1 -1
- package/dist/analysis/media-decode.d.ts +13 -0
- package/dist/analysis/media-decode.d.ts.map +1 -1
- package/dist/analysis/media-decode.js +33 -6
- package/dist/analysis/media-decode.js.map +1 -1
- package/dist/apify/assets.d.ts.map +1 -1
- package/dist/apify/assets.js +4 -0
- package/dist/apify/assets.js.map +1 -1
- package/dist/author-graph.d.ts +2 -3
- package/dist/author-graph.d.ts.map +1 -1
- package/dist/author-graph.js +3 -5
- package/dist/author-graph.js.map +1 -1
- package/dist/browser-gate.d.ts +2 -2
- package/dist/browser-gate.js +2 -2
- package/dist/capabilities/GamePublishRequest.d.ts +14 -0
- package/dist/capabilities/GamePublishRequest.d.ts.map +1 -0
- package/dist/capabilities/GamePublishRequest.js +2 -0
- package/dist/capabilities/GamePublishRequest.js.map +1 -0
- package/dist/capabilities/adapters.d.ts +4 -13
- package/dist/capabilities/adapters.d.ts.map +1 -1
- package/dist/capabilities/adapters.js +9 -14
- package/dist/capabilities/adapters.js.map +1 -1
- package/dist/capabilities/agent-activity.d.ts +27 -0
- package/dist/capabilities/agent-activity.d.ts.map +1 -0
- package/dist/capabilities/agent-activity.js +103 -0
- package/dist/capabilities/agent-activity.js.map +1 -0
- package/dist/capabilities/agentic-storyboard-finish.d.ts +67 -0
- package/dist/capabilities/agentic-storyboard-finish.d.ts.map +1 -0
- package/dist/capabilities/agentic-storyboard-finish.js +1321 -0
- package/dist/capabilities/agentic-storyboard-finish.js.map +1 -0
- package/dist/capabilities/agents.d.ts +5 -2
- package/dist/capabilities/agents.d.ts.map +1 -1
- package/dist/capabilities/agents.js +14 -4
- package/dist/capabilities/agents.js.map +1 -1
- package/dist/capabilities/agents.specs.d.ts +3 -0
- package/dist/capabilities/agents.specs.d.ts.map +1 -1
- package/dist/capabilities/agents.specs.js +71 -1
- package/dist/capabilities/agents.specs.js.map +1 -1
- package/dist/capabilities/analysis.d.ts.map +1 -1
- package/dist/capabilities/analysis.js +33 -22
- package/dist/capabilities/analysis.js.map +1 -1
- package/dist/capabilities/analysis.specs.js +2 -2
- package/dist/capabilities/analysis.specs.js.map +1 -1
- package/dist/capabilities/apps.d.ts.map +1 -1
- package/dist/capabilities/apps.js +5 -3
- package/dist/capabilities/apps.js.map +1 -1
- package/dist/capabilities/args.d.ts +2 -5
- package/dist/capabilities/args.d.ts.map +1 -1
- package/dist/capabilities/args.js +2 -5
- package/dist/capabilities/args.js.map +1 -1
- package/dist/capabilities/assets.d.ts.map +1 -1
- package/dist/capabilities/assets.js +40 -10
- package/dist/capabilities/assets.js.map +1 -1
- package/dist/capabilities/browser.d.ts +1 -1
- package/dist/capabilities/browser.js +1 -1
- package/dist/capabilities/browser.specs.d.ts +1 -1
- package/dist/capabilities/browser.specs.js +1 -1
- package/dist/capabilities/code.d.ts +5 -0
- package/dist/capabilities/code.d.ts.map +1 -1
- package/dist/capabilities/code.js +128 -89
- package/dist/capabilities/code.js.map +1 -1
- package/dist/capabilities/collections.d.ts +4 -6
- package/dist/capabilities/collections.d.ts.map +1 -1
- package/dist/capabilities/collections.js +16 -11
- package/dist/capabilities/collections.js.map +1 -1
- package/dist/capabilities/derive-shot.d.ts +45 -0
- package/dist/capabilities/derive-shot.d.ts.map +1 -0
- package/dist/capabilities/derive-shot.js +82 -0
- package/dist/capabilities/derive-shot.js.map +1 -0
- package/dist/capabilities/documents.d.ts +2 -1
- package/dist/capabilities/documents.d.ts.map +1 -1
- package/dist/capabilities/documents.js +12 -6
- package/dist/capabilities/documents.js.map +1 -1
- package/dist/capabilities/email.d.ts +2 -1
- package/dist/capabilities/email.d.ts.map +1 -1
- package/dist/capabilities/email.js +5 -3
- package/dist/capabilities/email.js.map +1 -1
- package/dist/capabilities/errors.d.ts +19 -0
- package/dist/capabilities/errors.d.ts.map +1 -0
- package/dist/capabilities/errors.js +109 -0
- package/dist/capabilities/errors.js.map +1 -0
- package/dist/capabilities/errors.specs.d.ts +11 -0
- package/dist/capabilities/errors.specs.d.ts.map +1 -0
- package/dist/capabilities/errors.specs.js +100 -0
- package/dist/capabilities/errors.specs.js.map +1 -0
- package/dist/capabilities/example-timelines.d.ts.map +1 -1
- package/dist/capabilities/example-timelines.js +52 -10
- package/dist/capabilities/example-timelines.js.map +1 -1
- package/dist/capabilities/example-timelines.specs.d.ts +1 -0
- package/dist/capabilities/example-timelines.specs.d.ts.map +1 -1
- package/dist/capabilities/example-timelines.specs.js +21 -3
- package/dist/capabilities/example-timelines.specs.js.map +1 -1
- package/dist/capabilities/finish-storyboard.d.ts +5 -0
- package/dist/capabilities/finish-storyboard.d.ts.map +1 -0
- package/dist/capabilities/finish-storyboard.js +278 -0
- package/dist/capabilities/finish-storyboard.js.map +1 -0
- package/dist/capabilities/game-asset-browser.d.ts +11 -0
- package/dist/capabilities/game-asset-browser.d.ts.map +1 -0
- package/dist/capabilities/game-asset-browser.js +152 -0
- package/dist/capabilities/game-asset-browser.js.map +1 -0
- package/dist/capabilities/game-asset-source.js +1 -1
- package/dist/capabilities/game-asset-source.js.map +1 -1
- package/dist/capabilities/game.d.ts +44 -2
- package/dist/capabilities/game.d.ts.map +1 -1
- package/dist/capabilities/game.js +408 -160
- package/dist/capabilities/game.js.map +1 -1
- package/dist/capabilities/game.specs.d.ts +4 -0
- package/dist/capabilities/game.specs.d.ts.map +1 -1
- package/dist/capabilities/game.specs.js +42 -13
- package/dist/capabilities/game.specs.js.map +1 -1
- package/dist/capabilities/game3d.d.ts +17 -0
- package/dist/capabilities/game3d.d.ts.map +1 -0
- package/dist/capabilities/game3d.js +434 -0
- package/dist/capabilities/game3d.js.map +1 -0
- package/dist/capabilities/gate-from-context.d.ts +1 -1
- package/dist/capabilities/gate-from-context.js +1 -1
- package/dist/capabilities/generations.d.ts +2 -0
- package/dist/capabilities/generations.d.ts.map +1 -1
- package/dist/capabilities/generations.js +14 -23
- package/dist/capabilities/generations.js.map +1 -1
- package/dist/capabilities/index.d.ts +2 -2
- package/dist/capabilities/index.d.ts.map +1 -1
- package/dist/capabilities/index.js +2 -2
- package/dist/capabilities/index.js.map +1 -1
- package/dist/capabilities/invoke.d.ts +14 -25
- package/dist/capabilities/invoke.d.ts.map +1 -1
- package/dist/capabilities/invoke.js +72 -35
- package/dist/capabilities/invoke.js.map +1 -1
- package/dist/capabilities/jobs.d.ts.map +1 -1
- package/dist/capabilities/jobs.js +47 -3
- package/dist/capabilities/jobs.js.map +1 -1
- package/dist/capabilities/jobs.specs.d.ts.map +1 -1
- package/dist/capabilities/jobs.specs.js +3 -1
- package/dist/capabilities/jobs.specs.js.map +1 -1
- package/dist/capabilities/js-scripts.d.ts +19 -1
- package/dist/capabilities/js-scripts.d.ts.map +1 -1
- package/dist/capabilities/js-scripts.js +109 -2
- package/dist/capabilities/js-scripts.js.map +1 -1
- package/dist/capabilities/js-scripts.specs.d.ts +2 -0
- package/dist/capabilities/js-scripts.specs.d.ts.map +1 -1
- package/dist/capabilities/js-scripts.specs.js +50 -0
- package/dist/capabilities/js-scripts.specs.js.map +1 -1
- package/dist/capabilities/lazy-tool-core.d.ts +23 -0
- package/dist/capabilities/lazy-tool-core.d.ts.map +1 -0
- package/dist/capabilities/lazy-tool-core.js +56 -0
- package/dist/capabilities/lazy-tool-core.js.map +1 -0
- package/dist/capabilities/lazy-tool.d.ts +3 -23
- package/dist/capabilities/lazy-tool.d.ts.map +1 -1
- package/dist/capabilities/lazy-tool.js +6 -64
- package/dist/capabilities/lazy-tool.js.map +1 -1
- package/dist/capabilities/legacy-tools.d.ts +15 -0
- package/dist/capabilities/legacy-tools.d.ts.map +1 -0
- package/dist/capabilities/legacy-tools.js +98 -0
- package/dist/capabilities/legacy-tools.js.map +1 -0
- package/dist/capabilities/media.d.ts +0 -9
- package/dist/capabilities/media.d.ts.map +1 -1
- package/dist/capabilities/media.js +314 -261
- package/dist/capabilities/media.js.map +1 -1
- package/dist/capabilities/media.specs.d.ts.map +1 -1
- package/dist/capabilities/media.specs.js +17 -0
- package/dist/capabilities/media.specs.js.map +1 -1
- package/dist/capabilities/metadata.d.ts +62 -0
- package/dist/capabilities/metadata.d.ts.map +1 -0
- package/dist/capabilities/metadata.js +114 -0
- package/dist/capabilities/metadata.js.map +1 -0
- package/dist/capabilities/model3d.d.ts.map +1 -1
- package/dist/capabilities/model3d.js +4 -0
- package/dist/capabilities/model3d.js.map +1 -1
- package/dist/capabilities/models.d.ts +2 -2
- package/dist/capabilities/models.d.ts.map +1 -1
- package/dist/capabilities/models.js +5 -3
- package/dist/capabilities/models.js.map +1 -1
- package/dist/capabilities/registry.d.ts +6 -19
- package/dist/capabilities/registry.d.ts.map +1 -1
- package/dist/capabilities/registry.js +72 -113
- package/dist/capabilities/registry.js.map +1 -1
- package/dist/capabilities/run-agent.d.ts +19 -0
- package/dist/capabilities/run-agent.d.ts.map +1 -0
- package/dist/capabilities/run-agent.js +183 -0
- package/dist/capabilities/run-agent.js.map +1 -0
- package/dist/capabilities/runs.d.ts +9 -0
- package/dist/capabilities/runs.d.ts.map +1 -0
- package/dist/capabilities/runs.js +46 -0
- package/dist/capabilities/runs.js.map +1 -0
- package/dist/capabilities/runs.specs.d.ts +39 -0
- package/dist/capabilities/runs.specs.d.ts.map +1 -0
- package/dist/capabilities/runs.specs.js +52 -0
- package/dist/capabilities/runs.specs.js.map +1 -0
- package/dist/capabilities/scripts.d.ts.map +1 -1
- package/dist/capabilities/scripts.js +11 -5
- package/dist/capabilities/scripts.js.map +1 -1
- package/dist/capabilities/settings.d.ts.map +1 -1
- package/dist/capabilities/settings.js +4 -2
- package/dist/capabilities/settings.js.map +1 -1
- package/dist/capabilities/sketches.d.ts.map +1 -1
- package/dist/capabilities/sketches.js +4 -2
- package/dist/capabilities/sketches.js.map +1 -1
- package/dist/capabilities/skills.d.ts.map +1 -1
- package/dist/capabilities/skills.js +22 -2
- package/dist/capabilities/skills.js.map +1 -1
- package/dist/capabilities/storyboard-layout-check.d.ts +33 -0
- package/dist/capabilities/storyboard-layout-check.d.ts.map +1 -0
- package/dist/capabilities/storyboard-layout-check.js +229 -0
- package/dist/capabilities/storyboard-layout-check.js.map +1 -0
- package/dist/capabilities/storyboard-measured-sources.d.ts +10 -0
- package/dist/capabilities/storyboard-measured-sources.d.ts.map +1 -0
- package/dist/capabilities/storyboard-measured-sources.js +67 -0
- package/dist/capabilities/storyboard-measured-sources.js.map +1 -0
- package/dist/capabilities/storyboard-review-times.d.ts +4 -0
- package/dist/capabilities/storyboard-review-times.d.ts.map +1 -0
- package/dist/capabilities/storyboard-review-times.js +39 -0
- package/dist/capabilities/storyboard-review-times.js.map +1 -0
- package/dist/capabilities/storyboards.d.ts +12 -18
- package/dist/capabilities/storyboards.d.ts.map +1 -1
- package/dist/capabilities/storyboards.js +779 -96
- package/dist/capabilities/storyboards.js.map +1 -1
- package/dist/capabilities/storyboards.specs.d.ts +9 -0
- package/dist/capabilities/storyboards.specs.d.ts.map +1 -1
- package/dist/capabilities/storyboards.specs.js +173 -5
- package/dist/capabilities/storyboards.specs.js.map +1 -1
- package/dist/capabilities/threads.js +1 -1
- package/dist/capabilities/threads.js.map +1 -1
- package/dist/capabilities/timeline-bridge.d.ts +368 -0
- package/dist/capabilities/timeline-bridge.d.ts.map +1 -0
- package/dist/capabilities/timeline-bridge.js +1008 -0
- package/dist/capabilities/timeline-bridge.js.map +1 -0
- package/dist/capabilities/timeline-clip-frames.d.ts +17 -0
- package/dist/capabilities/timeline-clip-frames.d.ts.map +1 -0
- package/dist/capabilities/timeline-clip-frames.js +84 -0
- package/dist/capabilities/timeline-clip-frames.js.map +1 -0
- package/dist/capabilities/timeline-media-edit.d.ts +8 -0
- package/dist/capabilities/timeline-media-edit.d.ts.map +1 -0
- package/dist/capabilities/timeline-media-edit.js +94 -0
- package/dist/capabilities/timeline-media-edit.js.map +1 -0
- package/dist/capabilities/timeline-native-media.d.ts.map +1 -1
- package/dist/capabilities/timeline-native-media.js +40 -0
- package/dist/capabilities/timeline-native-media.js.map +1 -1
- package/dist/capabilities/timeline-operations.d.ts +52 -0
- package/dist/capabilities/timeline-operations.d.ts.map +1 -0
- package/dist/capabilities/timeline-operations.js +413 -0
- package/dist/capabilities/timeline-operations.js.map +1 -0
- package/dist/capabilities/timelines.d.ts +28 -3
- package/dist/capabilities/timelines.d.ts.map +1 -1
- package/dist/capabilities/timelines.js +410 -294
- package/dist/capabilities/timelines.js.map +1 -1
- package/dist/capabilities/timelines.specs.d.ts +8 -0
- package/dist/capabilities/timelines.specs.d.ts.map +1 -1
- package/dist/capabilities/timelines.specs.js +178 -9
- package/dist/capabilities/timelines.specs.js.map +1 -1
- package/dist/capabilities/types.d.ts +3 -1
- package/dist/capabilities/types.d.ts.map +1 -1
- package/dist/capabilities/types.js.map +1 -1
- package/dist/capabilities/ui.d.ts.map +1 -1
- package/dist/capabilities/ui.js +24 -2
- package/dist/capabilities/ui.js.map +1 -1
- package/dist/capabilities/web.d.ts.map +1 -1
- package/dist/capabilities/web.js +4 -0
- package/dist/capabilities/web.js.map +1 -1
- package/dist/capabilities/workflows.d.ts +3 -1
- package/dist/capabilities/workflows.d.ts.map +1 -1
- package/dist/capabilities/workflows.js +244 -39
- package/dist/capabilities/workflows.js.map +1 -1
- package/dist/capabilities/workflows.specs.d.ts +2 -0
- package/dist/capabilities/workflows.specs.d.ts.map +1 -1
- package/dist/capabilities/workflows.specs.js +72 -2
- package/dist/capabilities/workflows.specs.js.map +1 -1
- package/dist/codeact/action-diagnostics.d.ts.map +1 -1
- package/dist/codeact/action-diagnostics.js +51 -1
- package/dist/codeact/action-diagnostics.js.map +1 -1
- package/dist/codeact/codeact-executor.d.ts.map +1 -1
- package/dist/codeact/codeact-executor.js +16 -8
- package/dist/codeact/codeact-executor.js.map +1 -1
- package/dist/codeact/compact-ids.d.ts.map +1 -1
- package/dist/codeact/compact-ids.js +5 -1
- package/dist/codeact/compact-ids.js.map +1 -1
- package/dist/codeact/graph-model.d.ts +1 -1
- package/dist/codeact/graph-model.d.ts.map +1 -1
- package/dist/codeact/graph-model.js +2 -3
- package/dist/codeact/graph-model.js.map +1 -1
- package/dist/codeact/nodetool-api.d.ts +1 -1
- package/dist/codeact/nodetool-api.d.ts.map +1 -1
- package/dist/codeact/nodetool-api.js +202 -284
- package/dist/codeact/nodetool-api.js.map +1 -1
- package/dist/codeact/sandbox-packages.d.ts +0 -7
- package/dist/codeact/sandbox-packages.d.ts.map +1 -1
- package/dist/codeact/sandbox-packages.js +1 -10
- package/dist/codeact/sandbox-packages.js.map +1 -1
- package/dist/codeact/tool-api.d.ts +6 -3
- package/dist/codeact/tool-api.d.ts.map +1 -1
- package/dist/codeact/tool-api.js +22 -15
- package/dist/codeact/tool-api.js.map +1 -1
- package/dist/evals/codeact-api-cases.d.ts.map +1 -1
- package/dist/evals/codeact-api-cases.js +2 -0
- package/dist/evals/codeact-api-cases.js.map +1 -1
- package/dist/evals/codeact-api-runs.d.ts +3 -0
- package/dist/evals/codeact-api-runs.d.ts.map +1 -0
- package/dist/evals/codeact-api-runs.js +33 -0
- package/dist/evals/codeact-api-runs.js.map +1 -0
- package/dist/evals/surfaces/game.d.ts +8 -2
- package/dist/evals/surfaces/game.d.ts.map +1 -1
- package/dist/evals/surfaces/game.js +460 -2
- package/dist/evals/surfaces/game.js.map +1 -1
- package/dist/evals/surfaces/sketch.d.ts +2 -0
- package/dist/evals/surfaces/sketch.d.ts.map +1 -1
- package/dist/evals/surfaces/sketch.js +11 -3
- package/dist/evals/surfaces/sketch.js.map +1 -1
- package/dist/evals/surfaces/timeline.d.ts +4 -357
- package/dist/evals/surfaces/timeline.d.ts.map +1 -1
- package/dist/evals/surfaces/timeline.js +9 -2621
- package/dist/evals/surfaces/timeline.js.map +1 -1
- package/dist/evals/tool-loop-bridge.d.ts +4 -0
- package/dist/evals/tool-loop-bridge.d.ts.map +1 -1
- package/dist/evals/tool-loop-bridge.js.map +1 -1
- package/dist/evals/tool-loop-eval.d.ts +2 -0
- package/dist/evals/tool-loop-eval.d.ts.map +1 -1
- package/dist/evals/tool-loop-eval.js +6 -1
- package/dist/evals/tool-loop-eval.js.map +1 -1
- package/dist/evals/tool-loop-permission.d.ts +1 -15
- package/dist/evals/tool-loop-permission.d.ts.map +1 -1
- package/dist/evals/tool-loop-permission.js +23 -41
- package/dist/evals/tool-loop-permission.js.map +1 -1
- package/dist/game-authoring.d.ts +9573 -0
- package/dist/game-authoring.d.ts.map +1 -0
- package/dist/game-authoring.js +146 -0
- package/dist/game-authoring.js.map +1 -0
- package/dist/game-build.d.ts +3 -0
- package/dist/game-build.d.ts.map +1 -0
- package/dist/game-build.js +3 -0
- package/dist/game-build.js.map +1 -0
- package/dist/game-code-bake.d.ts +26 -0
- package/dist/game-code-bake.d.ts.map +1 -0
- package/dist/game-code-bake.js +98 -0
- package/dist/game-code-bake.js.map +1 -0
- package/dist/game-examples.d.ts +2227 -18
- package/dist/game-examples.d.ts.map +1 -1
- package/dist/game-examples.js +5 -4
- package/dist/game-examples.js.map +1 -1
- package/dist/generation-cancel.d.ts +31 -0
- package/dist/generation-cancel.d.ts.map +1 -0
- package/dist/generation-cancel.js +28 -0
- package/dist/generation-cancel.js.map +1 -0
- package/dist/host-access-gate.d.ts +29 -0
- package/dist/host-access-gate.d.ts.map +1 -0
- package/dist/host-access-gate.js +39 -0
- package/dist/host-access-gate.js.map +1 -0
- package/dist/host-modules/dispatcher.d.ts +7 -1
- package/dist/host-modules/dispatcher.d.ts.map +1 -1
- package/dist/host-modules/dispatcher.js +13 -2
- package/dist/host-modules/dispatcher.js.map +1 -1
- package/dist/host-modules/docx.d.ts.map +1 -1
- package/dist/host-modules/docx.js +2 -2
- package/dist/host-modules/docx.js.map +1 -1
- package/dist/host-modules/epub.d.ts.map +1 -1
- package/dist/host-modules/epub.js +2 -2
- package/dist/host-modules/epub.js.map +1 -1
- package/dist/host-modules/fabric.d.ts.map +1 -1
- package/dist/host-modules/fabric.js +1 -1
- package/dist/host-modules/fabric.js.map +1 -1
- package/dist/host-modules/limits.d.ts +10 -8
- package/dist/host-modules/limits.d.ts.map +1 -1
- package/dist/host-modules/limits.js +14 -9
- package/dist/host-modules/limits.js.map +1 -1
- package/dist/host-modules/mammoth.d.ts.map +1 -1
- package/dist/host-modules/mammoth.js +2 -2
- package/dist/host-modules/mammoth.js.map +1 -1
- package/dist/host-modules/ocr.d.ts.map +1 -1
- package/dist/host-modules/ocr.js +1 -1
- package/dist/host-modules/ocr.js.map +1 -1
- package/dist/host-modules/pdf.d.ts.map +1 -1
- package/dist/host-modules/pdf.js +2 -2
- package/dist/host-modules/pdf.js.map +1 -1
- package/dist/host-modules/pdflib.d.ts.map +1 -1
- package/dist/host-modules/pdflib.js +2 -2
- package/dist/host-modules/pdflib.js.map +1 -1
- package/dist/host-modules/pptx.d.ts.map +1 -1
- package/dist/host-modules/pptx.js +2 -2
- package/dist/host-modules/pptx.js.map +1 -1
- package/dist/host-modules/pptxgen.d.ts.map +1 -1
- package/dist/host-modules/pptxgen.js +2 -2
- package/dist/host-modules/pptxgen.js.map +1 -1
- package/dist/host-modules/tfjs.d.ts.map +1 -1
- package/dist/host-modules/tfjs.js +4 -4
- package/dist/host-modules/tfjs.js.map +1 -1
- package/dist/host-modules/xlsx.d.ts.map +1 -1
- package/dist/host-modules/xlsx.js +2 -2
- package/dist/host-modules/xlsx.js.map +1 -1
- package/dist/index.d.ts +18 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -3
- package/dist/index.js.map +1 -1
- package/dist/js-sandbox-worker/engine.d.ts +4 -0
- package/dist/js-sandbox-worker/engine.d.ts.map +1 -0
- package/dist/js-sandbox-worker/engine.js +45 -0
- package/dist/js-sandbox-worker/engine.js.map +1 -0
- package/dist/js-sandbox-worker/host.js +1 -1
- package/dist/js-sandbox-worker/host.js.map +1 -1
- package/dist/js-sandbox-worker/interpreter.d.ts +1 -1
- package/dist/js-sandbox-worker/interpreter.d.ts.map +1 -1
- package/dist/js-sandbox-worker/interpreter.js +94 -2
- package/dist/js-sandbox-worker/interpreter.js.map +1 -1
- package/dist/js-sandbox-worker/worker-entry.d.ts.map +1 -1
- package/dist/js-sandbox-worker/worker-entry.js +3 -2
- package/dist/js-sandbox-worker/worker-entry.js.map +1 -1
- package/dist/js-sandbox.d.ts +9 -1
- package/dist/js-sandbox.d.ts.map +1 -1
- package/dist/js-sandbox.js +76 -15
- package/dist/js-sandbox.js.map +1 -1
- package/dist/js-script-app-runner.d.ts +2 -0
- package/dist/js-script-app-runner.d.ts.map +1 -1
- package/dist/js-script-app-runner.js +8 -3
- package/dist/js-script-app-runner.js.map +1 -1
- package/dist/js-script-sandbox.d.ts +12 -18
- package/dist/js-script-sandbox.d.ts.map +1 -1
- package/dist/js-script-sandbox.js +3 -49
- package/dist/js-script-sandbox.js.map +1 -1
- package/dist/prompts/product-knowledge.d.ts +1 -1
- package/dist/prompts/product-knowledge.d.ts.map +1 -1
- package/dist/prompts/product-knowledge.js +82 -41
- package/dist/prompts/product-knowledge.js.map +1 -1
- package/dist/sandbox-pack-resolution.d.ts +21 -0
- package/dist/sandbox-pack-resolution.d.ts.map +1 -0
- package/dist/sandbox-pack-resolution.js +42 -0
- package/dist/sandbox-pack-resolution.js.map +1 -0
- package/dist/sandbox-toolbelt.d.ts +3 -1
- package/dist/sandbox-toolbelt.d.ts.map +1 -1
- package/dist/sandbox-toolbelt.js +8 -2
- package/dist/sandbox-toolbelt.js.map +1 -1
- package/dist/skill-prompt.d.ts +11 -1
- package/dist/skill-prompt.d.ts.map +1 -1
- package/dist/skill-prompt.js +17 -6
- package/dist/skill-prompt.js.map +1 -1
- package/dist/system-skills.d.ts +7 -1
- package/dist/system-skills.d.ts.map +1 -1
- package/dist/system-skills.js +2 -2
- package/dist/system-skills.js.map +1 -1
- package/dist/timeline-capture.d.ts +21 -0
- package/dist/timeline-capture.d.ts.map +1 -0
- package/dist/timeline-capture.js +564 -0
- package/dist/timeline-capture.js.map +1 -0
- package/dist/timeline-code-bake.d.ts +75 -0
- package/dist/timeline-code-bake.d.ts.map +1 -0
- package/dist/timeline-code-bake.js +327 -0
- package/dist/timeline-code-bake.js.map +1 -0
- package/dist/timeline-preview/frames.d.ts +26 -0
- package/dist/timeline-preview/frames.d.ts.map +1 -1
- package/dist/timeline-preview/frames.js +155 -70
- package/dist/timeline-preview/frames.js.map +1 -1
- package/dist/tools/base-tool.d.ts +1 -0
- package/dist/tools/base-tool.d.ts.map +1 -1
- package/dist/tools/base-tool.js +1 -1
- package/dist/tools/base-tool.js.map +1 -1
- package/dist/tools/builtin-tools.d.ts +4 -3
- package/dist/tools/builtin-tools.d.ts.map +1 -1
- package/dist/tools/builtin-tools.js +24 -3
- package/dist/tools/builtin-tools.js.map +1 -1
- package/dist/tools/external-capability-tools.d.ts +1 -1
- package/dist/tools/external-capability-tools.js +1 -1
- package/dist/tools/mcp-tool-support.d.ts +10 -9
- package/dist/tools/mcp-tool-support.d.ts.map +1 -1
- package/dist/tools/mcp-tool-support.js +14 -13
- package/dist/tools/mcp-tool-support.js.map +1 -1
- package/dist/tools/mcp-tools.d.ts +6 -4
- package/dist/tools/mcp-tools.d.ts.map +1 -1
- package/dist/tools/mcp-tools.js +65 -62
- package/dist/tools/mcp-tools.js.map +1 -1
- package/dist/tools/tool-permissions.d.ts +1 -1
- package/dist/tools/tool-permissions.js +1 -1
- package/package.json +124 -41
- package/dist/capabilities/gate-tools.d.ts +0 -18
- package/dist/capabilities/gate-tools.d.ts.map +0 -1
- package/dist/capabilities/gate-tools.js +0 -66
- package/dist/capabilities/gate-tools.js.map +0 -1
- package/dist/tsconfig.tests.tmp.tsbuildinfo +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { finishStoryboard, layoutStoryboard, previewStoryboardDesign } from "./finish-storyboard.js";
|
|
1
2
|
/**
|
|
2
3
|
* The `storyboards` capability module.
|
|
3
4
|
*
|
|
@@ -15,10 +16,15 @@
|
|
|
15
16
|
*
|
|
16
17
|
* Design: docs/tool-class-retirement-design.md § "Migration".
|
|
17
18
|
*/
|
|
18
|
-
import {
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
21
|
+
import { mp4DurationSeconds, withSpan } from "@nodetool-ai/runtime";
|
|
22
|
+
import { storyboardMotionDesign, storyboardShotGraphics } from "@nodetool-ai/protocol/api-schemas/storyboards.js";
|
|
23
|
+
import { assertProductionGenerationAllowed, compileOneTake, isFullResourceId, isShortResourceId, productionRequirement } from "@nodetool-ai/protocol";
|
|
19
24
|
import { stampScriptStoryboardId } from "./script-link.js";
|
|
20
|
-
import { listStoryboardsSpec, createStoryboardSpec, getStoryboardSpec, renderStoryboardStillsSpec, renderStoryboardClipsSpec, reviseStoryboardClipSpec, assembleStoryboardTimelineSpec, editStoryboardSpec, directStoryboardSpec, extractScriptFromStoryboardSpec, deleteStoryboardSpec } from "./storyboards.specs.js";
|
|
21
|
-
import {
|
|
25
|
+
import { listStoryboardsSpec, createStoryboardSpec, getStoryboardSpec, renderStoryboardStillsSpec, renderStoryboardClipsSpec, reviseStoryboardClipSpec, assembleStoryboardTimelineSpec, deriveShotFromClipSpec, editStoryboardSpec, directStoryboardSpec, extractScriptFromStoryboardSpec, deleteStoryboardSpec, getStoryboardOneTakeSpec, updateStoryboardOneTakeSpec } from "./storyboards.specs.js";
|
|
26
|
+
import { measureStoryboardSources } from "./storyboard-measured-sources.js";
|
|
27
|
+
import { clampConcurrency } from "./concurrency.js";
|
|
22
28
|
import { isNonBlankString, isNumber, isRecord, isString } from "../utils/type-guards.js";
|
|
23
29
|
import { resolveProjectId } from "./project-scope.js";
|
|
24
30
|
/** Shots one call may render, so a stray `targets: "all"` cannot bankrupt a run. */
|
|
@@ -323,7 +329,8 @@ const listStoryboards = {
|
|
|
323
329
|
with_keyframe: doc.shots.filter((s) => !!s.keyframe).length,
|
|
324
330
|
with_clip: doc.shots.filter((s) => !!s.clip).length,
|
|
325
331
|
timeline_id: row.timeline_id ?? undefined,
|
|
326
|
-
updated_at: row.updated_at
|
|
332
|
+
updated_at: row.updated_at,
|
|
333
|
+
revision: row.revision
|
|
327
334
|
};
|
|
328
335
|
})
|
|
329
336
|
};
|
|
@@ -342,7 +349,8 @@ function createdBoardSummary(row) {
|
|
|
342
349
|
name: row.name,
|
|
343
350
|
project_id: row.project_id,
|
|
344
351
|
shots: doc.shots.length,
|
|
345
|
-
updated_at: row.updated_at
|
|
352
|
+
updated_at: row.updated_at,
|
|
353
|
+
revision: row.revision
|
|
346
354
|
};
|
|
347
355
|
}
|
|
348
356
|
const createStoryboard = {
|
|
@@ -408,6 +416,7 @@ const getStoryboard = {
|
|
|
408
416
|
const drifted = new Set(link.drifted_shot_ids);
|
|
409
417
|
return {
|
|
410
418
|
id: row.id,
|
|
419
|
+
revision: row.revision,
|
|
411
420
|
name: row.name,
|
|
412
421
|
brief: doc.brief,
|
|
413
422
|
style: doc.style,
|
|
@@ -418,6 +427,7 @@ const getStoryboard = {
|
|
|
418
427
|
timeline_id: row.timeline_id ?? undefined,
|
|
419
428
|
narration: doc.screenplay?.narration ?? undefined,
|
|
420
429
|
music_prompt: doc.screenplay?.music_prompt ?? undefined,
|
|
430
|
+
motion_design: doc.screenplay?.motion_design ?? null,
|
|
421
431
|
script_id: link.script_id,
|
|
422
432
|
script_link: link,
|
|
423
433
|
shots: [...doc.shots]
|
|
@@ -429,6 +439,10 @@ const getStoryboard = {
|
|
|
429
439
|
action: shot.action,
|
|
430
440
|
camera: shot.camera,
|
|
431
441
|
motion: shot.motion,
|
|
442
|
+
end_state: shot.end_state,
|
|
443
|
+
sound: shot.sound,
|
|
444
|
+
graphics: shot.graphics,
|
|
445
|
+
production: shot.production,
|
|
432
446
|
duration_seconds: shot.duration_seconds,
|
|
433
447
|
status: shot.status,
|
|
434
448
|
has_keyframe: !!shot.keyframe,
|
|
@@ -531,6 +545,71 @@ async function filterStale(selected, params, doc, entities, kind) {
|
|
|
531
545
|
.map((shot) => shot.id)
|
|
532
546
|
};
|
|
533
547
|
}
|
|
548
|
+
function modelOverrides(params) {
|
|
549
|
+
const options = {};
|
|
550
|
+
if (isNonBlankString(params["provider"])) {
|
|
551
|
+
options.provider = params["provider"];
|
|
552
|
+
}
|
|
553
|
+
if (isNonBlankString(params["model"])) {
|
|
554
|
+
options.model = params["model"];
|
|
555
|
+
}
|
|
556
|
+
return options;
|
|
557
|
+
}
|
|
558
|
+
function missingPlanModel(plan) {
|
|
559
|
+
if (plan.model.provider && plan.model.model) {
|
|
560
|
+
return undefined;
|
|
561
|
+
}
|
|
562
|
+
return {
|
|
563
|
+
error: `No ${plan.kind === "keyframe" ? "still" : "clip"} model is set for shot ${plan.shotId}. Pass provider + model (use find_model), or set one on the shot or board.`
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
async function clipModelError(context, plans) {
|
|
567
|
+
const groups = new Map();
|
|
568
|
+
for (const plan of plans) {
|
|
569
|
+
const error = missingPlanModel(plan);
|
|
570
|
+
if (error) {
|
|
571
|
+
return error;
|
|
572
|
+
}
|
|
573
|
+
if (plan.preflightError) {
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
const key = JSON.stringify([plan.model.provider, plan.model.model]);
|
|
577
|
+
const group = groups.get(key) ?? [];
|
|
578
|
+
group.push(plan);
|
|
579
|
+
groups.set(key, group);
|
|
580
|
+
}
|
|
581
|
+
for (const group of groups.values()) {
|
|
582
|
+
const model = group[0].model;
|
|
583
|
+
let supportedTasks = model.supportedTasks;
|
|
584
|
+
try {
|
|
585
|
+
const provider = await context.getProvider(model.provider);
|
|
586
|
+
const models = await provider.getAvailableVideoModels();
|
|
587
|
+
supportedTasks =
|
|
588
|
+
models.find((entry) => entry.id === model.model)?.supportedTasks ??
|
|
589
|
+
supportedTasks;
|
|
590
|
+
}
|
|
591
|
+
catch {
|
|
592
|
+
// Legacy providers can lack discovery, so their persisted task declarations apply.
|
|
593
|
+
}
|
|
594
|
+
const unsupported = group.find((plan) => {
|
|
595
|
+
const task = plan.mode === "direct" ? "text_to_video" : plan.mode === "reference" ? "reference_to_video" : "image_to_video";
|
|
596
|
+
return supportedTasks?.length && !supportedTasks.includes(task);
|
|
597
|
+
});
|
|
598
|
+
if (unsupported) {
|
|
599
|
+
const task = unsupported.mode === "direct" ? "text_to_video" : unsupported.mode === "reference" ? "reference_to_video" : "image_to_video";
|
|
600
|
+
return {
|
|
601
|
+
error: `The selected clip model ${model.provider}/${model.model} does not support ${task}; choose a model that supports the selected shot mode.`
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return undefined;
|
|
606
|
+
}
|
|
607
|
+
function uniformModel(plans) {
|
|
608
|
+
const model = plans[0]?.model;
|
|
609
|
+
return model && plans.every((plan) => plan.model.provider === model.provider && plan.model.model === model.model)
|
|
610
|
+
? { provider: model.provider, model: model.model }
|
|
611
|
+
: {};
|
|
612
|
+
}
|
|
534
613
|
const renderStoryboardStills = {
|
|
535
614
|
spec: renderStoryboardStillsSpec,
|
|
536
615
|
impl: async (run, params) => {
|
|
@@ -539,14 +618,11 @@ const renderStoryboardStills = {
|
|
|
539
618
|
if (isError(board))
|
|
540
619
|
return board;
|
|
541
620
|
const { row, doc } = board;
|
|
542
|
-
const model = resolveModel(params, doc.imageModel, "still", "text_to_image");
|
|
543
|
-
if (isError(model))
|
|
544
|
-
return model;
|
|
545
621
|
const { shotRenderMode } = await import("@nodetool-ai/protocol");
|
|
546
622
|
// A direct shot renders its clip from the prompt, so it needs no still.
|
|
547
623
|
// Naming it in `targets` still renders one — a board frame to look at is
|
|
548
624
|
// worth having even when the clip does not come from it.
|
|
549
|
-
const selected = selectShots(doc.shots, params["targets"], (s) => !s.keyframe &&
|
|
625
|
+
const selected = selectShots(doc.shots, params["targets"], (s) => (params["stale_only"] === true ? !!s.keyframe : !s.keyframe) &&
|
|
550
626
|
shotRenderMode(s) !== "direct" &&
|
|
551
627
|
!shotHasPicture(s, doc.shots));
|
|
552
628
|
if (isError(selected))
|
|
@@ -565,6 +641,10 @@ const renderStoryboardStills = {
|
|
|
565
641
|
: "No shot needs a still: each already has one, or renders its clip directly."
|
|
566
642
|
};
|
|
567
643
|
}
|
|
644
|
+
const protectedStill = chosen.find((shot) => shot.production?.protected_inputs?.some((input) => input.asset_id));
|
|
645
|
+
if (protectedStill) {
|
|
646
|
+
return { error: `Shot ${protectedStill.id} protects source assets; the current still renderer cannot prove source fidelity. Use those assets directly in Timeline materialization or a policy-aware finishing path.` };
|
|
647
|
+
}
|
|
568
648
|
if (chosen.length > MAX_SHOTS_PER_CALL) {
|
|
569
649
|
return {
|
|
570
650
|
error: `${chosen.length} shots selected, over the ${MAX_SHOTS_PER_CALL}-shot per-call limit. Pass targets in batches.`
|
|
@@ -575,22 +655,34 @@ const renderStoryboardStills = {
|
|
|
575
655
|
// says: `style` and `model` can be overridden per call. Recording the
|
|
576
656
|
// override is the point — a version rendered against something other than
|
|
577
657
|
// the board's settings reads stale against the board, correctly.
|
|
578
|
-
const planOptions =
|
|
579
|
-
provider: model.provider,
|
|
580
|
-
model: model.model
|
|
581
|
-
};
|
|
658
|
+
const planOptions = modelOverrides(params);
|
|
582
659
|
if (isString(params["style"])) {
|
|
583
660
|
planOptions.style = params["style"];
|
|
584
661
|
}
|
|
585
662
|
const plans = planShotRenders(doc, entities, "keyframe", chosen.map((shot) => shot.id), planOptions);
|
|
586
|
-
const
|
|
587
|
-
|
|
663
|
+
const { imageModelSupportsTask } = await import("@nodetool-ai/runtime");
|
|
664
|
+
for (const plan of plans) {
|
|
665
|
+
const modelError = missingPlanModel(plan);
|
|
666
|
+
if (modelError) {
|
|
667
|
+
return modelError;
|
|
668
|
+
}
|
|
669
|
+
plan.stillModelTakesImages = await imageModelSupportsTask(context, plan.model, "image_to_image", plan.model.supportedTasks);
|
|
670
|
+
}
|
|
671
|
+
const outcomes = await withSpan("render", {
|
|
672
|
+
"document.id": row.id,
|
|
673
|
+
"render.kind": "keyframe",
|
|
674
|
+
"render.shot_count": plans.length
|
|
675
|
+
}, async (span) => {
|
|
676
|
+
const rendered = await renderShots(renderHost(context), { id: row.id }, plans, { concurrency: clampConcurrency(params["concurrency"]) });
|
|
677
|
+
if (rendered.some((outcome) => !outcome.ok)) {
|
|
678
|
+
span?.setStatus({ code: SpanStatusCode.ERROR });
|
|
679
|
+
}
|
|
680
|
+
return rendered;
|
|
588
681
|
});
|
|
589
682
|
const results = outcomes.map((outcome) => outcomeRow(outcome, false));
|
|
590
683
|
return {
|
|
591
684
|
storyboard_id: row.id,
|
|
592
|
-
|
|
593
|
-
model: model.model,
|
|
685
|
+
...uniformModel(plans),
|
|
594
686
|
rendered: results.filter((r) => r.ok).length,
|
|
595
687
|
failed: results.filter((r) => !r.ok).length,
|
|
596
688
|
skipped,
|
|
@@ -613,43 +705,23 @@ const renderStoryboardClips = {
|
|
|
613
705
|
override !== "reference") {
|
|
614
706
|
return { error: 'mode must be "keyframe", "direct", or "reference".' };
|
|
615
707
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
override === "reference"
|
|
621
|
-
? override
|
|
622
|
-
: shotRenderMode(shot);
|
|
623
|
-
const selected = selectShots(doc.shots, params["targets"], (s) => !shotHasPicture(s, doc.shots) &&
|
|
624
|
-
(modeOf(s) === "direct" || modeOf(s) === "reference" || !!s.keyframe));
|
|
625
|
-
if (isError(selected))
|
|
626
|
-
return selected;
|
|
627
|
-
const requiredCapabilities = new Set(selected.map((shot) => modeOf(shot) === "direct"
|
|
628
|
-
? "text_to_video"
|
|
629
|
-
: modeOf(shot) === "reference"
|
|
630
|
-
? "reference_to_video"
|
|
631
|
-
: "image_to_video"));
|
|
632
|
-
const capability = requiredCapabilities.has("reference_to_video")
|
|
633
|
-
? "reference_to_video"
|
|
634
|
-
: requiredCapabilities.has("image_to_video")
|
|
635
|
-
? "image_to_video"
|
|
636
|
-
: "text_to_video";
|
|
637
|
-
const model = resolveModel(params, doc.videoModel, "clip", capability);
|
|
638
|
-
if (isError(model))
|
|
639
|
-
return model;
|
|
640
|
-
const declaredTasks = doc.videoModel?.supported_tasks;
|
|
641
|
-
if (Array.isArray(declaredTasks) &&
|
|
642
|
-
declaredTasks.length > 0 &&
|
|
643
|
-
model.model === doc.videoModel?.id &&
|
|
644
|
-
model.provider === doc.videoModel?.provider) {
|
|
645
|
-
const unsupported = [...requiredCapabilities].find((task) => !declaredTasks.includes(task));
|
|
646
|
-
if (unsupported) {
|
|
647
|
-
return {
|
|
648
|
-
error: `The selected clip model does not support ${unsupported}; choose a model that supports every selected shot mode.`
|
|
649
|
-
};
|
|
650
|
-
}
|
|
708
|
+
const candidates = selectShots(doc.shots, params["targets"], (shot) => (params["stale_only"] === true ? !!shot.clip : !shotHasPicture(shot, doc.shots)) &&
|
|
709
|
+
!shot.covered_by?.shot_id);
|
|
710
|
+
if (isError(candidates)) {
|
|
711
|
+
return candidates;
|
|
651
712
|
}
|
|
652
713
|
const entities = await loadBoardEntities(context, doc);
|
|
714
|
+
const { planShotRenders, renderShots } = await import("@nodetool-ai/storyboard");
|
|
715
|
+
const readinessOptions = modelOverrides(params);
|
|
716
|
+
if (override !== undefined) {
|
|
717
|
+
readinessOptions.mode = override;
|
|
718
|
+
}
|
|
719
|
+
const ready = new Set(planShotRenders(doc, entities, "clip", candidates.map((shot) => shot.id), readinessOptions)
|
|
720
|
+
.filter((plan) => plan.mode !== "keyframe" || !!plan.sourceKeyframe)
|
|
721
|
+
.map((plan) => plan.shotId));
|
|
722
|
+
const selected = params["targets"] === undefined || params["targets"] === null
|
|
723
|
+
? candidates.filter((shot) => ready.has(shot.id))
|
|
724
|
+
: candidates;
|
|
653
725
|
const fresh = await filterStale(selected, params, doc, entities, "clip");
|
|
654
726
|
const skipped = fresh.skipped;
|
|
655
727
|
const chosen = fresh.shots;
|
|
@@ -663,13 +735,16 @@ const renderStoryboardClips = {
|
|
|
663
735
|
: 'No shot is ready for a clip. A keyframe-mode shot needs a still first (render_storyboard_stills), or set its render_mode to "direct" — or pass mode: "direct" here — to render straight from the prompt. Name shots explicitly with `targets` to override the selection.'
|
|
664
736
|
};
|
|
665
737
|
}
|
|
738
|
+
const forbiddenClip = chosen.find((shot) => shot.production?.media_strategy === "still_motion_graphics");
|
|
739
|
+
if (forbiddenClip) {
|
|
740
|
+
return { error: `Shot ${forbiddenClip.id} is still_motion_graphics; video generation is forbidden. Materialize its still/assets as Timeline layers instead.` };
|
|
741
|
+
}
|
|
666
742
|
if (chosen.length > MAX_SHOTS_PER_CALL) {
|
|
667
743
|
return {
|
|
668
744
|
error: `${chosen.length} shots selected, over the ${MAX_SHOTS_PER_CALL}-shot per-call limit. Pass targets in batches.`
|
|
669
745
|
};
|
|
670
746
|
}
|
|
671
747
|
const { scriptLinesById } = await import("@nodetool-ai/timeline");
|
|
672
|
-
const { planShotRenders, renderShots } = await import("@nodetool-ai/storyboard");
|
|
673
748
|
// A linked board times its shots from the words they cover, so a clip is
|
|
674
749
|
// rendered long enough to hold its voiceover (design §2.3). A shot pinned
|
|
675
750
|
// to `manual`, an unvoiced line, or an unlinked board keeps
|
|
@@ -678,8 +753,7 @@ const renderStoryboardClips = {
|
|
|
678
753
|
// As in the stills path: the record says what this call rendered with, so
|
|
679
754
|
// a per-call model or style override reads stale against the board.
|
|
680
755
|
const planOptions = {
|
|
681
|
-
|
|
682
|
-
model: model.model,
|
|
756
|
+
...modelOverrides(params),
|
|
683
757
|
style: isString(params["style"]) ? params["style"] : doc.style || "",
|
|
684
758
|
scriptLines: scriptLinesById(scriptDoc?.sections ?? [])
|
|
685
759
|
};
|
|
@@ -687,18 +761,31 @@ const renderStoryboardClips = {
|
|
|
687
761
|
planOptions.mode = override;
|
|
688
762
|
}
|
|
689
763
|
const plans = planShotRenders(doc, entities, "clip", chosen.map((shot) => shot.id), planOptions);
|
|
764
|
+
const modelError = await clipModelError(context, plans);
|
|
765
|
+
if (modelError) {
|
|
766
|
+
return modelError;
|
|
767
|
+
}
|
|
690
768
|
const renderOptions = {
|
|
691
769
|
concurrency: clampConcurrency(params["concurrency"])
|
|
692
770
|
};
|
|
693
771
|
if (isString(params["resolution"])) {
|
|
694
772
|
renderOptions.resolution = params["resolution"];
|
|
695
773
|
}
|
|
696
|
-
const outcomes = await
|
|
774
|
+
const outcomes = await withSpan("render", {
|
|
775
|
+
"document.id": row.id,
|
|
776
|
+
"render.kind": "clip",
|
|
777
|
+
"render.shot_count": plans.length
|
|
778
|
+
}, async (span) => {
|
|
779
|
+
const rendered = await renderShots(renderHost(context), { id: row.id }, plans, renderOptions);
|
|
780
|
+
if (rendered.some((outcome) => !outcome.ok)) {
|
|
781
|
+
span?.setStatus({ code: SpanStatusCode.ERROR });
|
|
782
|
+
}
|
|
783
|
+
return rendered;
|
|
784
|
+
});
|
|
697
785
|
const results = outcomes.map((outcome) => outcomeRow(outcome, true));
|
|
698
786
|
return {
|
|
699
787
|
storyboard_id: row.id,
|
|
700
|
-
|
|
701
|
-
model: model.model,
|
|
788
|
+
...uniformModel(plans),
|
|
702
789
|
rendered: results.filter((r) => r.ok).length,
|
|
703
790
|
failed: results.filter((r) => !r.ok).length,
|
|
704
791
|
skipped,
|
|
@@ -723,6 +810,15 @@ const reviseStoryboardClip = {
|
|
|
723
810
|
error: `No shot matches "${String(params["target"])}". Call get_storyboard to list shot ids.`
|
|
724
811
|
};
|
|
725
812
|
}
|
|
813
|
+
if (shot.production?.media_strategy === "still_motion_graphics") {
|
|
814
|
+
return { error: `Shot ${shot.id} is still_motion_graphics; video revision is forbidden.` };
|
|
815
|
+
}
|
|
816
|
+
try {
|
|
817
|
+
assertProductionGenerationAllowed(shot.production, "video_to_video");
|
|
818
|
+
}
|
|
819
|
+
catch (error) {
|
|
820
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
821
|
+
}
|
|
726
822
|
if (!shot.clip) {
|
|
727
823
|
return {
|
|
728
824
|
error: "Shot has no clip to revise. Run render_storyboard_clips first."
|
|
@@ -739,6 +835,13 @@ const reviseStoryboardClip = {
|
|
|
739
835
|
error: "The shot's clip could not be read back from storage."
|
|
740
836
|
};
|
|
741
837
|
}
|
|
838
|
+
const current = await loadBoard(run, row.id);
|
|
839
|
+
if (isError(current))
|
|
840
|
+
return current;
|
|
841
|
+
const currentShot = current.doc.shots.find((value) => value.id === shot.id);
|
|
842
|
+
if (!currentShot)
|
|
843
|
+
return { error: `Shot ${shot.id} no longer exists.` };
|
|
844
|
+
assertProductionGenerationAllowed(currentShot.production, "video_to_video");
|
|
742
845
|
const saved = await renderMedia(context, {
|
|
743
846
|
provider: model.provider,
|
|
744
847
|
capability: "video_to_video",
|
|
@@ -786,7 +889,7 @@ const assembleStoryboardTimeline = {
|
|
|
786
889
|
return board;
|
|
787
890
|
const { row, doc } = board;
|
|
788
891
|
const { Storyboard, TimelineSequence } = await import("@nodetool-ai/models");
|
|
789
|
-
const { buildLinkedTimeline, buildStoryboardTimeline, foreignTimelineParts, frameSizeForAspect } = await import("@nodetool-ai/timeline");
|
|
892
|
+
const { buildLinkedTimeline, buildStoryboardTimeline, foreignTimelineParts, assertStoryboardReassemblyAllowed, frameSizeForAspect } = await import("@nodetool-ai/timeline");
|
|
790
893
|
// A board that links a script is cut against the words: shot lengths come
|
|
791
894
|
// from the takes and every voiced line gets its own clip. A link pointing
|
|
792
895
|
// at a script that is gone is a warning, not a failure — the board still
|
|
@@ -799,33 +902,7 @@ const assembleStoryboardTimeline = {
|
|
|
799
902
|
if (scriptId && !script) {
|
|
800
903
|
warnings.push(`Script ${scriptId} is linked but could not be loaded, so the board was assembled on its own.`);
|
|
801
904
|
}
|
|
802
|
-
const
|
|
803
|
-
const { applyMeasuredShotClipDurations } = await import("@nodetool-ai/timeline");
|
|
804
|
-
const signal = context.signal ?? new AbortController().signal;
|
|
805
|
-
const measurements = await mapWithConcurrency(doc.shots, clampConcurrency(undefined), async (shot) => {
|
|
806
|
-
const clip = shot.clip;
|
|
807
|
-
const assetId = clip?.asset_id;
|
|
808
|
-
if (shot.status !== "rendered" || !assetId)
|
|
809
|
-
return null;
|
|
810
|
-
try {
|
|
811
|
-
const bytes = await loadMediaRefBytes(clip, context);
|
|
812
|
-
const seconds = bytes?.length
|
|
813
|
-
? await probeVideoDurationSeconds(bytes, signal)
|
|
814
|
-
: null;
|
|
815
|
-
return seconds === null ? null : [assetId, seconds];
|
|
816
|
-
}
|
|
817
|
-
catch (error) {
|
|
818
|
-
if (signal.aborted)
|
|
819
|
-
throw error;
|
|
820
|
-
return null;
|
|
821
|
-
}
|
|
822
|
-
});
|
|
823
|
-
const durations = new Map();
|
|
824
|
-
for (const measurement of measurements) {
|
|
825
|
-
if (measurement)
|
|
826
|
-
durations.set(...measurement);
|
|
827
|
-
}
|
|
828
|
-
const measuredShots = applyMeasuredShotClipDurations(doc.shots, durations);
|
|
905
|
+
const measuredShots = await measureStoryboardSources(doc.shots, context);
|
|
829
906
|
const assembled = script
|
|
830
907
|
? buildLinkedTimeline({
|
|
831
908
|
boardId: row.id,
|
|
@@ -865,9 +942,9 @@ const assembleStoryboardTimeline = {
|
|
|
865
942
|
`(${worst.usedMs}ms in the cut, ${worst.sourceMs}ms rendered). ` +
|
|
866
943
|
`Re-render those shots at the length their lines need.`);
|
|
867
944
|
}
|
|
868
|
-
if (assembled.
|
|
945
|
+
if (assembled.durationMs === 0) {
|
|
869
946
|
return {
|
|
870
|
-
error: "No shot has
|
|
947
|
+
error: "No shot has an allowed still, video, or graphics source. Add graphics intent or use render_storyboard_stills / render_storyboard_clips where allowed by the shot production policy.",
|
|
871
948
|
skipped_shot_ids: assembled.skippedShotIds,
|
|
872
949
|
skipped_line_ids: skippedLineIds
|
|
873
950
|
};
|
|
@@ -934,11 +1011,12 @@ const assembleStoryboardTimeline = {
|
|
|
934
1011
|
};
|
|
935
1012
|
}
|
|
936
1013
|
const previous = current.toDocument();
|
|
1014
|
+
assertStoryboardReassemblyAllowed(previous, row.id);
|
|
937
1015
|
const foreign = foreignTimelineParts(previous, (clip) => clip.storyboardBoardId === row.id ||
|
|
938
1016
|
(!!scriptId && clip.scriptId === scriptId));
|
|
939
1017
|
const tracks = [...assembled.tracks, ...foreign.tracks];
|
|
940
1018
|
const clips = [...assembled.clips, ...foreign.clips];
|
|
941
|
-
const durationMs = clips.reduce((end, clip) => Math.max(end, clip.startMs + clip.durationMs),
|
|
1019
|
+
const durationMs = clips.reduce((end, clip) => Math.max(end, clip.startMs + clip.durationMs), assembled.durationMs);
|
|
942
1020
|
const nextDocument = {
|
|
943
1021
|
...previous,
|
|
944
1022
|
tracks,
|
|
@@ -1215,6 +1293,10 @@ const SHOT_EDIT_FIELDS = new Set([
|
|
|
1215
1293
|
"slug",
|
|
1216
1294
|
"camera",
|
|
1217
1295
|
"motion",
|
|
1296
|
+
"end_state",
|
|
1297
|
+
"sound",
|
|
1298
|
+
"graphics",
|
|
1299
|
+
"production",
|
|
1218
1300
|
"dialogue",
|
|
1219
1301
|
"narration",
|
|
1220
1302
|
"notes",
|
|
@@ -1267,8 +1349,16 @@ const BOARD_EDIT_FIELDS = new Set([
|
|
|
1267
1349
|
"aspect_ratio",
|
|
1268
1350
|
"entity_ids",
|
|
1269
1351
|
"image_model",
|
|
1270
|
-
"video_model"
|
|
1352
|
+
"video_model",
|
|
1353
|
+
"narration",
|
|
1354
|
+
"music_prompt",
|
|
1355
|
+
"motion_design"
|
|
1271
1356
|
]);
|
|
1357
|
+
const screenplayDirection = z.object({
|
|
1358
|
+
narration: z.string().optional(),
|
|
1359
|
+
music_prompt: z.string().optional(),
|
|
1360
|
+
motion_design: storyboardMotionDesign.nullable().optional()
|
|
1361
|
+
});
|
|
1272
1362
|
/**
|
|
1273
1363
|
* The board-level twin of {@link assertKnownShotFields}.
|
|
1274
1364
|
*
|
|
@@ -1350,6 +1440,45 @@ function applyShotFields(shot, args, shots = []) {
|
|
|
1350
1440
|
next.camera = args["camera"];
|
|
1351
1441
|
if (args["motion"] !== undefined)
|
|
1352
1442
|
next.motion = String(args["motion"]);
|
|
1443
|
+
for (const field of ["end_state", "sound"]) {
|
|
1444
|
+
const value = args[field];
|
|
1445
|
+
if (value === undefined)
|
|
1446
|
+
continue;
|
|
1447
|
+
if (value === null || String(value).trim() === "") {
|
|
1448
|
+
delete next[field];
|
|
1449
|
+
}
|
|
1450
|
+
else {
|
|
1451
|
+
next[field] = String(value);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
if (args["graphics"] !== undefined) {
|
|
1455
|
+
if (args["graphics"] === null) {
|
|
1456
|
+
delete next.graphics;
|
|
1457
|
+
}
|
|
1458
|
+
else {
|
|
1459
|
+
const parsed = storyboardShotGraphics.safeParse(args["graphics"]);
|
|
1460
|
+
if (!parsed.success) {
|
|
1461
|
+
throw new Error(`graphics must be a valid Storyboard graphics object: ${parsed.error.issues
|
|
1462
|
+
.map((issue) => issue.path.join(".") || issue.message)
|
|
1463
|
+
.join(", ")}.`);
|
|
1464
|
+
}
|
|
1465
|
+
next.graphics = parsed.data;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
if (args["production"] !== undefined) {
|
|
1469
|
+
if (args["production"] === null) {
|
|
1470
|
+
delete next.production;
|
|
1471
|
+
}
|
|
1472
|
+
else {
|
|
1473
|
+
const parsed = productionRequirement.safeParse(args["production"]);
|
|
1474
|
+
if (!parsed.success) {
|
|
1475
|
+
throw new Error(`production must be a valid production requirement: ${parsed.error.issues
|
|
1476
|
+
.map((issue) => issue.path.join(".") || issue.message)
|
|
1477
|
+
.join(", ")}.`);
|
|
1478
|
+
}
|
|
1479
|
+
next.production = parsed.data;
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1353
1482
|
if (args["dialogue"] !== undefined)
|
|
1354
1483
|
next.dialogue = String(args["dialogue"]);
|
|
1355
1484
|
if (args["narration"] !== undefined)
|
|
@@ -1763,6 +1892,13 @@ function applyBoardOp(doc, { op, args }, entities = []) {
|
|
|
1763
1892
|
}
|
|
1764
1893
|
case "set_board": {
|
|
1765
1894
|
assertKnownBoardFields(args);
|
|
1895
|
+
const direction = screenplayDirection.safeParse(args);
|
|
1896
|
+
if (!direction.success) {
|
|
1897
|
+
throw new Error("set_board has invalid screenplay direction: " +
|
|
1898
|
+
direction.error.issues
|
|
1899
|
+
.map((issue) => `${issue.path.join(".") || "direction"}: ${issue.message}`)
|
|
1900
|
+
.join("; "));
|
|
1901
|
+
}
|
|
1766
1902
|
if (args["brief"] !== undefined)
|
|
1767
1903
|
doc.brief = String(args["brief"]);
|
|
1768
1904
|
if (args["style"] !== undefined)
|
|
@@ -1797,13 +1933,45 @@ function applyBoardOp(doc, { op, args }, entities = []) {
|
|
|
1797
1933
|
}
|
|
1798
1934
|
doc.videoModel = videoModel;
|
|
1799
1935
|
}
|
|
1936
|
+
if (args["narration"] !== undefined ||
|
|
1937
|
+
args["music_prompt"] !== undefined ||
|
|
1938
|
+
args["motion_design"] !== undefined) {
|
|
1939
|
+
const needsScreenplay = args["narration"] !== undefined ||
|
|
1940
|
+
args["music_prompt"] !== undefined ||
|
|
1941
|
+
direction.data.motion_design !== null;
|
|
1942
|
+
if (needsScreenplay) {
|
|
1943
|
+
doc.screenplay = doc.screenplay ?? {
|
|
1944
|
+
type: "screenplay",
|
|
1945
|
+
id: newDocId("sp"),
|
|
1946
|
+
title: "",
|
|
1947
|
+
shots: []
|
|
1948
|
+
};
|
|
1949
|
+
}
|
|
1950
|
+
if (doc.screenplay && direction.data.narration !== undefined) {
|
|
1951
|
+
doc.screenplay.narration = direction.data.narration;
|
|
1952
|
+
}
|
|
1953
|
+
if (doc.screenplay && direction.data.music_prompt !== undefined) {
|
|
1954
|
+
doc.screenplay.music_prompt = direction.data.music_prompt;
|
|
1955
|
+
}
|
|
1956
|
+
if (doc.screenplay && direction.data.motion_design !== undefined) {
|
|
1957
|
+
if (direction.data.motion_design === null) {
|
|
1958
|
+
delete doc.screenplay.motion_design;
|
|
1959
|
+
}
|
|
1960
|
+
else {
|
|
1961
|
+
doc.screenplay.motion_design = direction.data.motion_design;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1800
1965
|
return {
|
|
1801
1966
|
brief: doc.brief,
|
|
1802
1967
|
style: doc.style,
|
|
1803
1968
|
aspect_ratio: doc.aspectRatio,
|
|
1804
1969
|
entity_ids: doc.entityIds,
|
|
1805
1970
|
image_model: doc.imageModel,
|
|
1806
|
-
video_model: doc.videoModel
|
|
1971
|
+
video_model: doc.videoModel,
|
|
1972
|
+
narration: doc.screenplay?.narration,
|
|
1973
|
+
music_prompt: doc.screenplay?.music_prompt,
|
|
1974
|
+
motion_design: doc.screenplay?.motion_design
|
|
1807
1975
|
};
|
|
1808
1976
|
}
|
|
1809
1977
|
}
|
|
@@ -1830,6 +1998,50 @@ async function loadStyleEntities(run, doc, ops) {
|
|
|
1830
1998
|
});
|
|
1831
1999
|
return [...cast, ...extra];
|
|
1832
2000
|
}
|
|
2001
|
+
/** Resolve source refs before any edit writes. Guest IDs stay short, stored refs stay canonical. */
|
|
2002
|
+
async function resolveStoryboardEditSources(run, ops) {
|
|
2003
|
+
const { Asset } = await import("@nodetool-ai/models");
|
|
2004
|
+
const canonical = new Map();
|
|
2005
|
+
const resolve = async (id) => {
|
|
2006
|
+
if (!isFullResourceId(id) && !isShortResourceId(id)) {
|
|
2007
|
+
return id;
|
|
2008
|
+
}
|
|
2009
|
+
const cached = canonical.get(id);
|
|
2010
|
+
if (cached) {
|
|
2011
|
+
return cached;
|
|
2012
|
+
}
|
|
2013
|
+
const asset = run.context.userId ? await Asset.find(run.context.userId, id) : null;
|
|
2014
|
+
if (!asset) {
|
|
2015
|
+
throw new Error(`Source asset or entity ${id} is unavailable.`);
|
|
2016
|
+
}
|
|
2017
|
+
canonical.set(id, asset.id);
|
|
2018
|
+
return asset.id;
|
|
2019
|
+
};
|
|
2020
|
+
const resolved = structuredClone(ops);
|
|
2021
|
+
for (const { args } of resolved) {
|
|
2022
|
+
const references = [args];
|
|
2023
|
+
const graphics = args["graphics"];
|
|
2024
|
+
if (isRecord(graphics) && Array.isArray(graphics["elements"])) {
|
|
2025
|
+
references.push(...graphics["elements"].filter(isRecord));
|
|
2026
|
+
}
|
|
2027
|
+
const production = args["production"];
|
|
2028
|
+
if (isRecord(production) && Array.isArray(production["protected_inputs"])) {
|
|
2029
|
+
references.push(...production["protected_inputs"].filter(isRecord));
|
|
2030
|
+
}
|
|
2031
|
+
for (const reference of references) {
|
|
2032
|
+
for (const field of ["asset_id", "entity_id", "location_id"]) {
|
|
2033
|
+
const id = reference[field];
|
|
2034
|
+
if (isString(id)) {
|
|
2035
|
+
reference[field] = await resolve(id);
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
if (Array.isArray(args["entity_ids"])) {
|
|
2040
|
+
args["entity_ids"] = await Promise.all(args["entity_ids"].map(async (id) => isString(id) ? resolve(id) : id));
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
return resolved;
|
|
2044
|
+
}
|
|
1833
2045
|
const editStoryboard = {
|
|
1834
2046
|
spec: editStoryboardSpec,
|
|
1835
2047
|
impl: async (run, params) => {
|
|
@@ -1842,12 +2054,22 @@ const editStoryboard = {
|
|
|
1842
2054
|
if (isError(board))
|
|
1843
2055
|
return board;
|
|
1844
2056
|
const { row, doc } = board;
|
|
2057
|
+
if (params["expected_revision"] !== undefined && params["expected_revision"] !== row.revision) {
|
|
2058
|
+
return { error: "Storyboard revision conflict. Refresh the board before editing." };
|
|
2059
|
+
}
|
|
1845
2060
|
// A failing op is recorded and the script continues: stopping at the
|
|
1846
2061
|
// first error hides every problem behind it.
|
|
1847
2062
|
const records = [];
|
|
1848
|
-
|
|
2063
|
+
let sourceOps;
|
|
2064
|
+
try {
|
|
2065
|
+
sourceOps = await resolveStoryboardEditSources(run, ops);
|
|
2066
|
+
}
|
|
2067
|
+
catch (error) {
|
|
2068
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
2069
|
+
}
|
|
2070
|
+
const entities = await loadStyleEntities(run, doc, sourceOps);
|
|
1849
2071
|
const resolvedOps = [];
|
|
1850
|
-
for (const parsed of
|
|
2072
|
+
for (const parsed of sourceOps) {
|
|
1851
2073
|
try {
|
|
1852
2074
|
const result = applyBoardOp(doc, parsed, entities);
|
|
1853
2075
|
records.push({
|
|
@@ -1888,6 +2110,9 @@ const editStoryboard = {
|
|
|
1888
2110
|
resolvedOps.push({ tool: parsed.op, input: parsed.args });
|
|
1889
2111
|
}
|
|
1890
2112
|
}
|
|
2113
|
+
if (doc.screenplay) {
|
|
2114
|
+
doc.screenplay.shots = doc.shots;
|
|
2115
|
+
}
|
|
1891
2116
|
const saved = await Storyboard.updateFieldsIfUnchanged(row.id, row.updated_at, {
|
|
1892
2117
|
document: JSON.stringify(doc)
|
|
1893
2118
|
},
|
|
@@ -1900,6 +2125,7 @@ const editStoryboard = {
|
|
|
1900
2125
|
return {
|
|
1901
2126
|
storyboard_id: row.id,
|
|
1902
2127
|
updated_at: saved.updated_at,
|
|
2128
|
+
revision: saved.revision,
|
|
1903
2129
|
applied: records.length - failed.length,
|
|
1904
2130
|
failed: failed.length,
|
|
1905
2131
|
ops: records,
|
|
@@ -1920,6 +2146,212 @@ const editStoryboard = {
|
|
|
1920
2146
|
}
|
|
1921
2147
|
};
|
|
1922
2148
|
// ---------------------------------------------------------------------------
|
|
2149
|
+
// derive_shot_from_clip
|
|
2150
|
+
// ---------------------------------------------------------------------------
|
|
2151
|
+
const DEFAULT_DERIVED_FRAMES = 3;
|
|
2152
|
+
const formatSeconds = (ms) => `${(ms / 1000).toFixed(1)}s`;
|
|
2153
|
+
/**
|
|
2154
|
+
* The headless twin of the editor's Derived shot section
|
|
2155
|
+
* (`useDeriveShotFromClip`): frames → assets → a shot after the source shot
|
|
2156
|
+
* → a clip following it on a new track above the source clip. The board is
|
|
2157
|
+
* written before the timeline, so a timeline conflict leaves the shot on the
|
|
2158
|
+
* board and says so.
|
|
2159
|
+
*/
|
|
2160
|
+
const deriveShotFromClip = {
|
|
2161
|
+
spec: deriveShotFromClipSpec,
|
|
2162
|
+
impl: async (run, params) => {
|
|
2163
|
+
const timelineId = params["timeline_id"];
|
|
2164
|
+
if (!isNonBlankString(timelineId)) {
|
|
2165
|
+
return {
|
|
2166
|
+
error: "timeline_id is required (use list_timelines to find one)."
|
|
2167
|
+
};
|
|
2168
|
+
}
|
|
2169
|
+
if (!isNonBlankString(params["clip_id"])) {
|
|
2170
|
+
return { error: "clip_id is required (a clip id or name)." };
|
|
2171
|
+
}
|
|
2172
|
+
const { MAX_DERIVED_FRAMES } = await import("@nodetool-ai/timeline");
|
|
2173
|
+
const frameCount = params["frame_count"] === undefined
|
|
2174
|
+
? DEFAULT_DERIVED_FRAMES
|
|
2175
|
+
: params["frame_count"];
|
|
2176
|
+
if (!isNumber(frameCount) ||
|
|
2177
|
+
!Number.isInteger(frameCount) ||
|
|
2178
|
+
frameCount < 1 ||
|
|
2179
|
+
frameCount > MAX_DERIVED_FRAMES) {
|
|
2180
|
+
return {
|
|
2181
|
+
error: `frame_count must be a whole number from 1 to ${MAX_DERIVED_FRAMES}.`
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2184
|
+
const actionParam = params["action"];
|
|
2185
|
+
if (actionParam !== undefined && !isString(actionParam)) {
|
|
2186
|
+
return { error: "action must be a string." };
|
|
2187
|
+
}
|
|
2188
|
+
const { TimelineSequence, Storyboard } = await import("@nodetool-ai/models");
|
|
2189
|
+
const sequence = await TimelineSequence.findById(timelineId);
|
|
2190
|
+
if (!sequence || sequence.user_id !== run.context.userId) {
|
|
2191
|
+
return { error: `Timeline ${timelineId} was not found.` };
|
|
2192
|
+
}
|
|
2193
|
+
const { findDocumentClip, captureDerivedFrames, placeDerivedShotClip } = await import("./derive-shot.js");
|
|
2194
|
+
const source = findDocumentClip(sequence.toDocument().clips, params["clip_id"]);
|
|
2195
|
+
if (!source) {
|
|
2196
|
+
return {
|
|
2197
|
+
error: `No clip matching "${params["clip_id"]}" in timeline ${timelineId}.`
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
2200
|
+
const boardId = source.storyboardBoardId;
|
|
2201
|
+
const sourceShotId = source.storyboardShotId;
|
|
2202
|
+
if (!boardId || !sourceShotId) {
|
|
2203
|
+
return {
|
|
2204
|
+
error: `Clip "${source.name}" is not linked to a storyboard shot.`
|
|
2205
|
+
};
|
|
2206
|
+
}
|
|
2207
|
+
if (source.mediaType !== "video" || !source.currentAssetId) {
|
|
2208
|
+
return {
|
|
2209
|
+
error: "Reference frames come from a video clip with footage."
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
const board = await loadBoard(run, boardId);
|
|
2213
|
+
if (isError(board))
|
|
2214
|
+
return board;
|
|
2215
|
+
const sourceShot = board.doc.shots.find((shot) => shot.id === sourceShotId);
|
|
2216
|
+
if (!sourceShot) {
|
|
2217
|
+
return {
|
|
2218
|
+
error: `The shot clip "${source.name}" follows is no longer on its board.`
|
|
2219
|
+
};
|
|
2220
|
+
}
|
|
2221
|
+
const label = sourceShot.slug ?? `Shot ${sourceShot.index + 1}`;
|
|
2222
|
+
let frames;
|
|
2223
|
+
try {
|
|
2224
|
+
frames = await captureDerivedFrames(run.context, source, frameCount);
|
|
2225
|
+
}
|
|
2226
|
+
catch (error) {
|
|
2227
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
2228
|
+
}
|
|
2229
|
+
const bindings = [];
|
|
2230
|
+
for (const [index, frame] of frames.entries()) {
|
|
2231
|
+
const created = await run.context.createAsset({
|
|
2232
|
+
name: `${label}-frame-${index + 1}.png`,
|
|
2233
|
+
contentType: "image/png",
|
|
2234
|
+
content: frame.png
|
|
2235
|
+
});
|
|
2236
|
+
const assetId = isRecord(created) && isString(created["id"]) ? created["id"] : null;
|
|
2237
|
+
if (!assetId) {
|
|
2238
|
+
return { error: "A reference frame was saved without an asset id." };
|
|
2239
|
+
}
|
|
2240
|
+
bindings.push({
|
|
2241
|
+
kind: "style",
|
|
2242
|
+
asset_id: assetId,
|
|
2243
|
+
label: `${label} at ${formatSeconds(frame.sourceTimeMs)}`
|
|
2244
|
+
});
|
|
2245
|
+
}
|
|
2246
|
+
const action = actionParam?.trim() || sourceShot.action;
|
|
2247
|
+
const shotArgs = {
|
|
2248
|
+
after_shot_id: sourceShot.id,
|
|
2249
|
+
action,
|
|
2250
|
+
slug: `${label} (derived)`,
|
|
2251
|
+
duration_seconds: source.durationMs / 1000,
|
|
2252
|
+
duration_source: "manual",
|
|
2253
|
+
render_mode: "reference",
|
|
2254
|
+
production: {
|
|
2255
|
+
schema_version: 1,
|
|
2256
|
+
speech_mode: "none",
|
|
2257
|
+
requested_take_count: 1,
|
|
2258
|
+
reference_bindings: bindings
|
|
2259
|
+
}
|
|
2260
|
+
};
|
|
2261
|
+
if (sourceShot.camera !== undefined)
|
|
2262
|
+
shotArgs["camera"] = sourceShot.camera;
|
|
2263
|
+
if (sourceShot.motion !== undefined)
|
|
2264
|
+
shotArgs["motion"] = sourceShot.motion;
|
|
2265
|
+
if (sourceShot.entity_ids !== undefined) {
|
|
2266
|
+
shotArgs["entity_ids"] = sourceShot.entity_ids;
|
|
2267
|
+
}
|
|
2268
|
+
if (sourceShot.location_id !== undefined) {
|
|
2269
|
+
shotArgs["location_id"] = sourceShot.location_id;
|
|
2270
|
+
}
|
|
2271
|
+
let shot;
|
|
2272
|
+
for (let attempt = 0; attempt < CAS_ATTEMPTS && !shot; attempt++) {
|
|
2273
|
+
const current = await loadBoard(run, boardId);
|
|
2274
|
+
if (isError(current))
|
|
2275
|
+
return current;
|
|
2276
|
+
const { row, doc } = current;
|
|
2277
|
+
let shotId;
|
|
2278
|
+
try {
|
|
2279
|
+
const added = applyBoardOp(doc, { op: "add_shot", args: shotArgs });
|
|
2280
|
+
shotId = added.id;
|
|
2281
|
+
}
|
|
2282
|
+
catch (error) {
|
|
2283
|
+
return {
|
|
2284
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2285
|
+
};
|
|
2286
|
+
}
|
|
2287
|
+
const index = doc.shots.findIndex((candidate) => candidate.id === shotId);
|
|
2288
|
+
if (sourceShot.clip_model !== undefined) {
|
|
2289
|
+
doc.shots[index] = {
|
|
2290
|
+
...doc.shots[index],
|
|
2291
|
+
clip_model: sourceShot.clip_model
|
|
2292
|
+
};
|
|
2293
|
+
}
|
|
2294
|
+
if (doc.screenplay) {
|
|
2295
|
+
doc.screenplay.shots = doc.shots;
|
|
2296
|
+
}
|
|
2297
|
+
const saved = await Storyboard.updateFieldsIfUnchanged(row.id, row.updated_at, { document: JSON.stringify(doc) }, { ops: [{ tool: "add_shot", input: { ...shotArgs, id: shotId } }] });
|
|
2298
|
+
if (saved)
|
|
2299
|
+
shot = doc.shots[index];
|
|
2300
|
+
}
|
|
2301
|
+
if (!shot) {
|
|
2302
|
+
return {
|
|
2303
|
+
error: `Storyboard ${boardId} is being modified concurrently; nothing was saved. Retry the call.`
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
for (let attempt = 0; attempt < CAS_ATTEMPTS; attempt++) {
|
|
2307
|
+
const current = await TimelineSequence.findById(timelineId);
|
|
2308
|
+
if (!current)
|
|
2309
|
+
break;
|
|
2310
|
+
const document = current.toDocument();
|
|
2311
|
+
const latest = document.clips.find((clip) => clip.id === source.id);
|
|
2312
|
+
if (!latest)
|
|
2313
|
+
break;
|
|
2314
|
+
const placed = placeDerivedShotClip(document, latest, {
|
|
2315
|
+
boardId,
|
|
2316
|
+
shotId: shot.id,
|
|
2317
|
+
name: shot.slug ?? "Derived shot"
|
|
2318
|
+
});
|
|
2319
|
+
const saved = await TimelineSequence.updateDocumentIfUnchanged(current.id, current.updated_at, { ...document, tracks: placed.tracks, clips: placed.clips }, {
|
|
2320
|
+
ops: [
|
|
2321
|
+
{
|
|
2322
|
+
tool: "ui_timeline_add_track",
|
|
2323
|
+
input: { id: placed.trackId, type: "video" }
|
|
2324
|
+
},
|
|
2325
|
+
{
|
|
2326
|
+
tool: "ui_timeline_add_media_clip",
|
|
2327
|
+
input: { id: placed.clipId, track_id: placed.trackId }
|
|
2328
|
+
}
|
|
2329
|
+
]
|
|
2330
|
+
});
|
|
2331
|
+
if (saved) {
|
|
2332
|
+
return {
|
|
2333
|
+
storyboard_id: boardId,
|
|
2334
|
+
shot_id: shot.id,
|
|
2335
|
+
shot_index: shot.index,
|
|
2336
|
+
slug: shot.slug,
|
|
2337
|
+
reference_asset_ids: bindings.map((binding) => binding.asset_id),
|
|
2338
|
+
timeline_id: timelineId,
|
|
2339
|
+
track_id: placed.trackId,
|
|
2340
|
+
clip_id: placed.clipId,
|
|
2341
|
+
next: "Render the shot with render_storyboard_clips, targets " +
|
|
2342
|
+
`["${shot.id}"]. The clip plays the take once it lands.`
|
|
2343
|
+
};
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
return {
|
|
2347
|
+
error: `Shot ${shot.id} was added to storyboard ${boardId}, but timeline ` +
|
|
2348
|
+
`${timelineId} changed or its source clip was removed, so no clip ` +
|
|
2349
|
+
"was placed. Add a clip for the shot with edit_timeline, or remove " +
|
|
2350
|
+
"the shot with edit_storyboard."
|
|
2351
|
+
};
|
|
2352
|
+
}
|
|
2353
|
+
};
|
|
2354
|
+
// ---------------------------------------------------------------------------
|
|
1923
2355
|
// direct_storyboard
|
|
1924
2356
|
// ---------------------------------------------------------------------------
|
|
1925
2357
|
const DEFAULT_DIRECTED_SHOTS = 6;
|
|
@@ -2021,6 +2453,8 @@ const directStoryboard = {
|
|
|
2021
2453
|
...held,
|
|
2022
2454
|
...shot,
|
|
2023
2455
|
index,
|
|
2456
|
+
graphics: held.graphics,
|
|
2457
|
+
production: held.production,
|
|
2024
2458
|
keyframe: held.keyframe,
|
|
2025
2459
|
keyframe_versions: held.keyframe_versions,
|
|
2026
2460
|
clip: held.clip,
|
|
@@ -2029,7 +2463,11 @@ const directStoryboard = {
|
|
|
2029
2463
|
status: held.status
|
|
2030
2464
|
};
|
|
2031
2465
|
});
|
|
2032
|
-
|
|
2466
|
+
const previousMotionDesign = next.screenplay?.motion_design;
|
|
2467
|
+
next.screenplay = { ...screenplay, shots: next.shots };
|
|
2468
|
+
if (previousMotionDesign !== undefined) {
|
|
2469
|
+
next.screenplay.motion_design = previousMotionDesign;
|
|
2470
|
+
}
|
|
2033
2471
|
next.style = screenplay.style_bible ?? next.style;
|
|
2034
2472
|
next.aspectRatio = screenplay.aspect_ratio ?? next.aspectRatio;
|
|
2035
2473
|
if (screenplay.genre)
|
|
@@ -2040,6 +2478,7 @@ const directStoryboard = {
|
|
|
2040
2478
|
return {
|
|
2041
2479
|
storyboard_id: current.row.id,
|
|
2042
2480
|
updated_at: saved.updated_at,
|
|
2481
|
+
revision: saved.revision,
|
|
2043
2482
|
title: screenplay.title,
|
|
2044
2483
|
genre: next.genre,
|
|
2045
2484
|
redirected: params["redirect"] === true,
|
|
@@ -2225,7 +2664,248 @@ const deleteStoryboard = {
|
|
|
2225
2664
|
: { error: `Storyboard ${id} was not found, or it is not yours.` };
|
|
2226
2665
|
}
|
|
2227
2666
|
};
|
|
2667
|
+
// ---------------------------------------------------------------------------
|
|
2668
|
+
// get_storyboard_one_take / update_storyboard_one_take
|
|
2669
|
+
// ---------------------------------------------------------------------------
|
|
2670
|
+
/** Above this the providers that take one continuous clip refuse or truncate. */
|
|
2671
|
+
const ONE_TAKE_MAX_SECONDS = 30;
|
|
2672
|
+
/** The most reference images a one-take provider accepts. */
|
|
2673
|
+
const ONE_TAKE_MAX_IMAGES = 9;
|
|
2674
|
+
const oneTakeUpdateInput = z.object({
|
|
2675
|
+
prompt: z.string().optional(),
|
|
2676
|
+
duration_seconds: z.number().positive().nullable().optional(),
|
|
2677
|
+
aspect_ratio: z.string().trim().min(1).nullable().optional(),
|
|
2678
|
+
resolution: z.string().trim().min(1).nullable().optional(),
|
|
2679
|
+
model: z
|
|
2680
|
+
.object({
|
|
2681
|
+
provider: z.string().trim().min(1),
|
|
2682
|
+
id: z.string().trim().min(1),
|
|
2683
|
+
name: z.string().optional()
|
|
2684
|
+
})
|
|
2685
|
+
.nullable()
|
|
2686
|
+
.optional(),
|
|
2687
|
+
shots: z
|
|
2688
|
+
.array(z.object({
|
|
2689
|
+
shot_id: z.string().trim().min(1),
|
|
2690
|
+
end_state: z.string().nullable().optional(),
|
|
2691
|
+
sound: z.string().nullable().optional()
|
|
2692
|
+
}))
|
|
2693
|
+
.optional()
|
|
2694
|
+
});
|
|
2695
|
+
/** The one-take render settings a call may set; null clears one. */
|
|
2696
|
+
const ONE_TAKE_SETTINGS = [
|
|
2697
|
+
"duration_seconds",
|
|
2698
|
+
"aspect_ratio",
|
|
2699
|
+
"resolution",
|
|
2700
|
+
"model"
|
|
2701
|
+
];
|
|
2702
|
+
/** The board's `videoModel` as a model ref, or null when it names none. */
|
|
2703
|
+
function boardVideoModel(value) {
|
|
2704
|
+
if (!value || typeof value !== "object")
|
|
2705
|
+
return null;
|
|
2706
|
+
const record = value;
|
|
2707
|
+
const id = record["id"];
|
|
2708
|
+
const provider = record["provider"];
|
|
2709
|
+
if (typeof id !== "string" || id === "" || typeof provider !== "string" || provider === "") {
|
|
2710
|
+
return null;
|
|
2711
|
+
}
|
|
2712
|
+
const model = {
|
|
2713
|
+
id,
|
|
2714
|
+
provider: provider
|
|
2715
|
+
};
|
|
2716
|
+
const name = record["name"];
|
|
2717
|
+
if (typeof name === "string") {
|
|
2718
|
+
model.name = name;
|
|
2719
|
+
}
|
|
2720
|
+
return model;
|
|
2721
|
+
}
|
|
2722
|
+
/** The shape both one-take capabilities return. */
|
|
2723
|
+
function oneTakeSummary(row, doc) {
|
|
2724
|
+
const compiled = compileOneTake({
|
|
2725
|
+
shots: doc.shots,
|
|
2726
|
+
oneTake: doc.one_take
|
|
2727
|
+
});
|
|
2728
|
+
const direction = doc.one_take;
|
|
2729
|
+
const settings = {
|
|
2730
|
+
duration_seconds: direction?.duration_seconds ?? null,
|
|
2731
|
+
aspect_ratio: direction?.aspect_ratio ?? null,
|
|
2732
|
+
resolution: direction?.resolution ?? null,
|
|
2733
|
+
model: direction?.model ?? null
|
|
2734
|
+
};
|
|
2735
|
+
const effective = {
|
|
2736
|
+
duration_seconds: compiled.duration_seconds,
|
|
2737
|
+
shot_total_seconds: compiled.shot_total_seconds,
|
|
2738
|
+
aspect_ratio: settings.aspect_ratio ?? doc.aspectRatio ?? null,
|
|
2739
|
+
resolution: settings.resolution,
|
|
2740
|
+
model: settings.model ?? boardVideoModel(doc.videoModel)
|
|
2741
|
+
};
|
|
2742
|
+
const warnings = [];
|
|
2743
|
+
if (!effective.model) {
|
|
2744
|
+
warnings.push("No video model is chosen: set `model` here or the board's video model.");
|
|
2745
|
+
}
|
|
2746
|
+
if (compiled.duration_seconds > ONE_TAKE_MAX_SECONDS) {
|
|
2747
|
+
warnings.push(`The take runs ${compiled.duration_seconds}s, over the ${ONE_TAKE_MAX_SECONDS}s one-take limit.`);
|
|
2748
|
+
}
|
|
2749
|
+
if (compiled.references.length > ONE_TAKE_MAX_IMAGES) {
|
|
2750
|
+
warnings.push(`${compiled.references.length} reference images; one-take models accept at most ${ONE_TAKE_MAX_IMAGES}.`);
|
|
2751
|
+
}
|
|
2752
|
+
const byId = new Map(doc.shots.map((shot) => [shot.id, shot]));
|
|
2753
|
+
const withoutStill = compiled.steps
|
|
2754
|
+
.map((step) => byId.get(step.shot_id))
|
|
2755
|
+
.filter((shot) => !!shot && !shot.keyframe?.asset_id);
|
|
2756
|
+
if (withoutStill.length > 0) {
|
|
2757
|
+
warnings.push(`Shots without a still send no image: ${withoutStill
|
|
2758
|
+
.map((shot) => shot.slug?.trim() || shot.id)
|
|
2759
|
+
.join(", ")}.`);
|
|
2760
|
+
}
|
|
2761
|
+
return {
|
|
2762
|
+
storyboard_id: row.id,
|
|
2763
|
+
revision: row.revision,
|
|
2764
|
+
updated_at: row.updated_at,
|
|
2765
|
+
stored: doc.one_take !== undefined,
|
|
2766
|
+
prompt: doc.one_take?.prompt ?? "",
|
|
2767
|
+
compiled: compiled.compiled,
|
|
2768
|
+
full_prompt: compiled.prompt,
|
|
2769
|
+
references: compiled.references.map((reference, index) => ({
|
|
2770
|
+
image_number: index + 1,
|
|
2771
|
+
marker: `[Image ${index + 1}]`,
|
|
2772
|
+
...reference
|
|
2773
|
+
})),
|
|
2774
|
+
steps: compiled.steps.map((step) => {
|
|
2775
|
+
const shot = byId.get(step.shot_id);
|
|
2776
|
+
return {
|
|
2777
|
+
shot_id: step.shot_id,
|
|
2778
|
+
index: shot?.index,
|
|
2779
|
+
slug: shot?.slug,
|
|
2780
|
+
start_seconds: step.start_seconds,
|
|
2781
|
+
end_seconds: step.end_seconds,
|
|
2782
|
+
end_state: shot?.end_state ?? null,
|
|
2783
|
+
sound: shot?.sound ?? null
|
|
2784
|
+
};
|
|
2785
|
+
}),
|
|
2786
|
+
duration_seconds: compiled.duration_seconds,
|
|
2787
|
+
settings,
|
|
2788
|
+
effective,
|
|
2789
|
+
warnings
|
|
2790
|
+
};
|
|
2791
|
+
}
|
|
2792
|
+
const getStoryboardOneTake = {
|
|
2793
|
+
spec: getStoryboardOneTakeSpec,
|
|
2794
|
+
impl: async (run, params) => {
|
|
2795
|
+
const board = await loadBoard(run, params["storyboard_id"]);
|
|
2796
|
+
if (isError(board))
|
|
2797
|
+
return board;
|
|
2798
|
+
return oneTakeSummary(board.row, board.doc);
|
|
2799
|
+
}
|
|
2800
|
+
};
|
|
2801
|
+
const updateStoryboardOneTake = {
|
|
2802
|
+
spec: updateStoryboardOneTakeSpec,
|
|
2803
|
+
impl: async (run, params) => {
|
|
2804
|
+
const parsed = oneTakeUpdateInput.safeParse({
|
|
2805
|
+
prompt: params["prompt"],
|
|
2806
|
+
duration_seconds: params["duration_seconds"],
|
|
2807
|
+
aspect_ratio: params["aspect_ratio"],
|
|
2808
|
+
resolution: params["resolution"],
|
|
2809
|
+
model: params["model"],
|
|
2810
|
+
shots: params["shots"]
|
|
2811
|
+
});
|
|
2812
|
+
if (!parsed.success) {
|
|
2813
|
+
return {
|
|
2814
|
+
error: parsed.error.issues
|
|
2815
|
+
.map((issue) => `${issue.path.join(".") || "input"}: ${issue.message}`)
|
|
2816
|
+
.join("; ")
|
|
2817
|
+
};
|
|
2818
|
+
}
|
|
2819
|
+
const { prompt, shots: shotPatches } = parsed.data;
|
|
2820
|
+
const settingsGiven = ONE_TAKE_SETTINGS.filter((key) => parsed.data[key] !== undefined);
|
|
2821
|
+
if (prompt === undefined && settingsGiven.length === 0 && !shotPatches) {
|
|
2822
|
+
return {
|
|
2823
|
+
error: "Pass prompt, duration_seconds, aspect_ratio, resolution, model or shots to update."
|
|
2824
|
+
};
|
|
2825
|
+
}
|
|
2826
|
+
const { Storyboard } = await import("@nodetool-ai/models");
|
|
2827
|
+
for (let attempt = 0; attempt < CAS_ATTEMPTS; attempt++) {
|
|
2828
|
+
const board = await loadBoard(run, params["storyboard_id"]);
|
|
2829
|
+
if (isError(board))
|
|
2830
|
+
return board;
|
|
2831
|
+
const { row } = board;
|
|
2832
|
+
const doc = board.doc;
|
|
2833
|
+
if (params["expected_revision"] !== undefined &&
|
|
2834
|
+
params["expected_revision"] !== row.revision) {
|
|
2835
|
+
return {
|
|
2836
|
+
error: "Storyboard revision conflict. Refresh the board before editing."
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
const ops = [];
|
|
2840
|
+
if (prompt !== undefined || settingsGiven.length > 0) {
|
|
2841
|
+
const next = {
|
|
2842
|
+
...doc.one_take,
|
|
2843
|
+
prompt: prompt ?? doc.one_take?.prompt ?? ""
|
|
2844
|
+
};
|
|
2845
|
+
const { duration_seconds, aspect_ratio, resolution, model } = parsed.data;
|
|
2846
|
+
if (duration_seconds !== undefined)
|
|
2847
|
+
next.duration_seconds = duration_seconds;
|
|
2848
|
+
if (aspect_ratio !== undefined)
|
|
2849
|
+
next.aspect_ratio = aspect_ratio;
|
|
2850
|
+
if (resolution !== undefined)
|
|
2851
|
+
next.resolution = resolution;
|
|
2852
|
+
if (model !== undefined) {
|
|
2853
|
+
next.model = model && {
|
|
2854
|
+
...model,
|
|
2855
|
+
provider: model.provider
|
|
2856
|
+
};
|
|
2857
|
+
}
|
|
2858
|
+
// A null clears the setting: store it absent, not null.
|
|
2859
|
+
for (const key of ONE_TAKE_SETTINGS) {
|
|
2860
|
+
if (next[key] === null)
|
|
2861
|
+
delete next[key];
|
|
2862
|
+
}
|
|
2863
|
+
doc.one_take = next;
|
|
2864
|
+
// Field-level, the way set_board is: an open editor takes the
|
|
2865
|
+
// direction whole.
|
|
2866
|
+
ops.push({ tool: "set_board", input: { one_take: doc.one_take } });
|
|
2867
|
+
}
|
|
2868
|
+
for (const patch of shotPatches ?? []) {
|
|
2869
|
+
const shot = findShot(doc.shots, patch.shot_id);
|
|
2870
|
+
if (!shot) {
|
|
2871
|
+
return {
|
|
2872
|
+
error: `No shot matches "${patch.shot_id}". Call get_storyboard for shot ids.`
|
|
2873
|
+
};
|
|
2874
|
+
}
|
|
2875
|
+
const next = { ...shot };
|
|
2876
|
+
for (const field of ["end_state", "sound"]) {
|
|
2877
|
+
const value = patch[field];
|
|
2878
|
+
if (value === undefined)
|
|
2879
|
+
continue;
|
|
2880
|
+
if (value === null || value.trim() === "") {
|
|
2881
|
+
delete next[field];
|
|
2882
|
+
}
|
|
2883
|
+
else {
|
|
2884
|
+
next[field] = value;
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
doc.shots = doc.shots.map((s) => (s.id === shot.id ? next : s));
|
|
2888
|
+
ops.push({
|
|
2889
|
+
tool: "update_shot",
|
|
2890
|
+
input: { id: shot.id, target: shot.id }
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2893
|
+
if (doc.screenplay)
|
|
2894
|
+
doc.screenplay.shots = doc.shots;
|
|
2895
|
+
const saved = await Storyboard.updateFieldsIfUnchanged(row.id, row.updated_at, { document: JSON.stringify(doc) }, { ops });
|
|
2896
|
+
if (!saved)
|
|
2897
|
+
continue;
|
|
2898
|
+
return oneTakeSummary(saved, doc);
|
|
2899
|
+
}
|
|
2900
|
+
return {
|
|
2901
|
+
error: `Storyboard ${String(params["storyboard_id"])} is being modified concurrently; nothing was saved. Retry the call.`
|
|
2902
|
+
};
|
|
2903
|
+
}
|
|
2904
|
+
};
|
|
2228
2905
|
export const STORYBOARD_CAPABILITIES = [
|
|
2906
|
+
finishStoryboard,
|
|
2907
|
+
layoutStoryboard,
|
|
2908
|
+
previewStoryboardDesign,
|
|
2229
2909
|
listStoryboards,
|
|
2230
2910
|
createStoryboard,
|
|
2231
2911
|
getStoryboard,
|
|
@@ -2233,14 +2913,17 @@ export const STORYBOARD_CAPABILITIES = [
|
|
|
2233
2913
|
renderStoryboardClips,
|
|
2234
2914
|
reviseStoryboardClip,
|
|
2235
2915
|
assembleStoryboardTimeline,
|
|
2916
|
+
deriveShotFromClip,
|
|
2236
2917
|
editStoryboard,
|
|
2237
2918
|
directStoryboard,
|
|
2238
2919
|
extractScriptFromStoryboard,
|
|
2239
|
-
deleteStoryboard
|
|
2920
|
+
deleteStoryboard,
|
|
2921
|
+
getStoryboardOneTake,
|
|
2922
|
+
updateStoryboardOneTake
|
|
2240
2923
|
];
|
|
2241
2924
|
export const module = {
|
|
2242
2925
|
module: "storyboards",
|
|
2243
2926
|
exports: STORYBOARD_CAPABILITIES
|
|
2244
2927
|
};
|
|
2245
|
-
export { listStoryboards, createStoryboard, getStoryboard, renderStoryboardStills, renderStoryboardClips, reviseStoryboardClip, assembleStoryboardTimeline, editStoryboard, directStoryboard, extractScriptFromStoryboard, deleteStoryboard };
|
|
2928
|
+
export { finishStoryboard, layoutStoryboard, previewStoryboardDesign, listStoryboards, createStoryboard, getStoryboard, renderStoryboardStills, renderStoryboardClips, reviseStoryboardClip, assembleStoryboardTimeline, deriveShotFromClip, editStoryboard, directStoryboard, extractScriptFromStoryboard, deleteStoryboard, getStoryboardOneTake, updateStoryboardOneTake };
|
|
2246
2929
|
//# sourceMappingURL=storyboards.js.map
|