@gentbajko/slopify 3.25.9 → 4.0.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/adapters/account-limits.js +30 -0
- package/dist/adapters/alignment/cache.js +3 -5
- package/dist/adapters/alignment/ctc.js +1 -2
- package/dist/adapters/alignment/lock.js +4 -3
- package/dist/adapters/alignment/multilingual.js +0 -3
- package/dist/adapters/alignment/prefetch.js +2 -1
- package/dist/adapters/alignment/worker.js +2 -1
- package/dist/adapters/explain.js +0 -3
- package/dist/adapters/ffmpeg.js +19 -1
- package/dist/adapters/host-cli/index.js +19 -3
- package/dist/adapters/http-failure.js +53 -0
- package/dist/adapters/image/codex.js +36 -4
- package/dist/adapters/image/fal.js +17 -50
- package/dist/adapters/image/google.js +31 -55
- package/dist/adapters/image/openai.js +20 -47
- package/dist/adapters/image/reference.js +36 -0
- package/dist/adapters/image/replicate.js +18 -47
- package/dist/adapters/interest/search-interest.js +113 -0
- package/dist/adapters/key-probes.js +53 -2
- package/dist/adapters/llm/antigravity.js +4 -0
- package/dist/adapters/llm/assistant-cli.js +388 -0
- package/dist/adapters/llm/child-session.js +83 -0
- package/dist/adapters/llm/claude-code-models.js +51 -98
- package/dist/adapters/llm/claude-code.js +13 -2
- package/dist/adapters/llm/codex-limits.js +27 -68
- package/dist/adapters/llm/codex-server-models.js +61 -109
- package/dist/adapters/llm/codex.js +12 -1
- package/dist/adapters/llm/openrouter.js +10 -47
- package/dist/adapters/llm/run-cli.js +6 -22
- package/dist/adapters/llm/sse-lines.js +5 -1
- package/dist/adapters/model-access.js +37 -0
- package/dist/adapters/tts/cartesia.js +15 -46
- package/dist/adapters/tts/elevenlabs.js +20 -52
- package/dist/adapters/tts/gemini.js +19 -40
- package/dist/adapters/tts/inworld-async.js +4 -1
- package/dist/adapters/tts/inworld.js +3 -0
- package/dist/adapters/tts/openai.js +20 -50
- package/dist/assets/models-lifecycle.yaml +6 -0
- package/dist/assistant-wiring.js +60 -0
- package/dist/autopilot-timers.js +59 -0
- package/dist/catalog/lifecycle.js +52 -0
- package/dist/catalog/propose.js +204 -0
- package/dist/catalog/registry.js +3 -1
- package/dist/catalog/schema.js +2 -0
- package/dist/catalog/store.js +39 -0
- package/dist/edge/autostart/native.js +3 -5
- package/dist/edge/autostart/prompt.js +2 -1
- package/dist/edge/autostart/service.js +3 -4
- package/dist/edge/cli-args.js +3 -4
- package/dist/edge/cli.js +2 -1
- package/dist/edge/docker-install/apply.js +11 -11
- package/dist/edge/docker-install/run.js +2 -1
- package/dist/edge/docker-install/state.js +4 -3
- package/dist/edge/docker-install/tree.js +2 -4
- package/dist/edge/docker-install/volume.js +3 -2
- package/dist/edge/docker.js +5 -4
- package/dist/edge/events/hub.js +5 -5
- package/dist/edge/http/actions.js +4 -25
- package/dist/edge/http/actor.js +5 -3
- package/dist/edge/http/app.js +85 -10
- package/dist/edge/http/assistant.js +127 -0
- package/dist/edge/http/audio-preview.js +4 -11
- package/dist/edge/http/auditions.js +1 -1
- package/dist/edge/http/autostart.js +5 -5
- package/dist/edge/http/backups.js +1 -3
- package/dist/edge/http/channel-memory.js +7 -20
- package/dist/edge/http/channels.js +13 -26
- package/dist/edge/http/checkpoints.js +33 -17
- package/dist/edge/http/design-templates.js +167 -0
- package/dist/edge/http/designs.js +178 -0
- package/dist/edge/http/diagnostics.js +5 -1
- package/dist/edge/http/document-themes.js +2 -11
- package/dist/edge/http/draft-files.js +1 -3
- package/dist/edge/http/draft-problem.js +4 -9
- package/dist/edge/http/drafts.js +3 -3
- package/dist/edge/http/entries.js +6 -9
- package/dist/edge/http/extension-auth.js +27 -0
- package/dist/edge/http/external-reviews.js +12 -11
- package/dist/edge/http/files.js +5 -11
- package/dist/edge/http/folder-location.js +1 -4
- package/dist/edge/http/fonts.js +0 -7
- package/dist/edge/http/home.js +38 -13
- package/dist/edge/http/host-cli.js +18 -8
- package/dist/edge/http/ids.js +8 -0
- package/dist/edge/http/keywords.js +35 -0
- package/dist/edge/http/model-checks.js +132 -0
- package/dist/edge/http/narration-peaks.js +5 -13
- package/dist/edge/http/onboarding.js +1 -14
- package/dist/edge/http/open-folder.js +5 -10
- package/dist/edge/http/outputs.js +4 -12
- package/dist/edge/http/patch-notes.js +4 -10
- package/dist/edge/http/planning.js +2 -6
- package/dist/edge/http/problem.js +2 -4
- package/dist/edge/http/project-create.js +1 -0
- package/dist/edge/http/project-templates.js +29 -17
- package/dist/edge/http/projects.js +2 -12
- package/dist/edge/http/prompts.js +7 -14
- package/dist/edge/http/pronunciations.js +1 -2
- package/dist/edge/http/providers.js +39 -24
- package/dist/edge/http/refusal.js +29 -0
- package/dist/edge/http/remote-access.js +40 -0
- package/dist/edge/http/remote-guard.js +71 -0
- package/dist/edge/http/request-guard.js +91 -0
- package/dist/edge/http/reviews.js +11 -24
- package/dist/edge/http/revision-files.js +5 -10
- package/dist/edge/http/revisions.js +10 -15
- package/dist/edge/http/run-cost.js +1 -2
- package/dist/edge/http/same-page.js +80 -0
- package/dist/edge/http/schedules.js +59 -32
- package/dist/edge/http/settings.js +22 -13
- package/dist/edge/http/social.js +282 -0
- package/dist/edge/http/staging.js +2 -4
- package/dist/edge/http/storage-files.js +5 -7
- package/dist/edge/http/storage.js +23 -23
- package/dist/edge/http/studio.js +23 -50
- package/dist/edge/http/style-preview.js +1 -4
- package/dist/edge/http/subtitles.js +3 -17
- package/dist/edge/http/template-studio.js +433 -0
- package/dist/edge/http/trash.js +10 -11
- package/dist/edge/http/tutorial.js +1 -2
- package/dist/edge/http/tutorials.js +5 -11
- package/dist/edge/http/update.js +7 -13
- package/dist/edge/http/waveform.js +3 -6
- package/dist/edge/http/youtube-edits.js +2 -3
- package/dist/edge/mcp/assistant.js +279 -0
- package/dist/edge/mcp/attribution.js +8 -2
- package/dist/edge/mcp/call-route.js +11 -2
- package/dist/edge/mcp/excluded-routes.js +25 -0
- package/dist/edge/mcp/http.js +11 -2
- package/dist/edge/mcp/instructions.js +5 -3
- package/dist/edge/mcp/library-tools.js +1 -0
- package/dist/edge/mcp/route-tool.js +35 -15
- package/dist/edge/mcp/server.js +13 -8
- package/dist/edge/mcp/tools-channels.js +2 -0
- package/dist/edge/mcp/tools-designs.js +165 -0
- package/dist/edge/mcp/tools-library.js +14 -2
- package/dist/edge/mcp/tools-planning.js +23 -4
- package/dist/edge/mcp/tools-projects.js +28 -1
- package/dist/edge/mcp/tools-runs.js +14 -1
- package/dist/edge/mcp/tools-schedules.js +28 -4
- package/dist/edge/mcp/tools-setup.js +61 -3
- package/dist/edge/mcp/tools-social.js +46 -0
- package/dist/edge/mcp/tools-storage.js +8 -0
- package/dist/edge/mcp/tools-template-studio.js +166 -0
- package/dist/edge/mcp/tools.js +6 -0
- package/dist/edge/remote-access/cli.js +71 -0
- package/dist/edge/remote-access/model.js +32 -0
- package/dist/edge/remote-access/rules.js +207 -0
- package/dist/edge/remote-access/service.js +203 -0
- package/dist/edge/remote-access/store.js +44 -0
- package/dist/edge/remote-access/views.js +43 -0
- package/dist/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/host-cli/install.js +2 -2
- package/dist/host-cli/open-folder.js +2 -2
- package/dist/host-cli/paths.js +2 -4
- package/dist/host-cli/server.js +4 -4
- package/dist/host-cli/service.js +3 -3
- package/dist/host-cli/status.js +7 -7
- package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
- package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
- package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
- package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
- package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
- package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
- package/dist/kernel/db/migrations/0070-designs.sql +53 -0
- package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
- package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
- package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
- package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
- package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
- package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
- package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
- package/dist/kernel/db/tx.js +2 -4
- package/dist/kernel/errors.js +27 -1
- package/dist/kernel/json-answer.js +15 -0
- package/dist/kernel/lock.js +4 -9
- package/dist/kernel/paths.js +8 -0
- package/dist/kernel/ports/assistant-cli.js +4 -0
- package/dist/kernel/ports/host-cli.js +3 -0
- package/dist/kernel/ports/interest.js +4 -0
- package/dist/kernel/ports/languages.js +0 -3
- package/dist/kernel/ports/model.js +2 -0
- package/dist/kernel/runner/attempt.js +3 -1
- package/dist/kernel/runner/audition.js +3 -1
- package/dist/kernel/runner/checkpoint-authority.js +2 -1
- package/dist/kernel/runner/index.js +8 -10
- package/dist/kernel/runner/model-access.js +40 -0
- package/dist/kernel/runner/model-check.js +153 -0
- package/dist/kernel/runner/providers.js +15 -10
- package/dist/kernel/runner/standalone.js +9 -5
- package/dist/main.js +334 -19
- package/dist/model-checks.js +166 -0
- package/dist/patch-notes/4.0.0.md +51 -0
- package/dist/patch-notes/index.json +6 -0
- package/dist/slices/admission/heads.js +2 -1
- package/dist/slices/admission/repo.js +2 -1
- package/dist/slices/admission/rules.js +43 -8
- package/dist/slices/admission/schema.js +8 -0
- package/dist/slices/admission/stage-writes.js +0 -3
- package/dist/slices/admission/start.js +48 -31
- package/dist/slices/admission/substitute.js +7 -4
- package/dist/slices/agents/attention-posts.js +31 -0
- package/dist/slices/agents/attention-templates.js +33 -0
- package/dist/slices/agents/attention.js +10 -1
- package/dist/slices/agents/connection.js +2 -6
- package/dist/slices/agents/model.js +6 -3
- package/dist/slices/agents/repo.js +15 -7
- package/dist/slices/article/continuation.js +0 -63
- package/dist/slices/article/plain.js +3 -2
- package/dist/slices/article/segments.js +2 -62
- package/dist/slices/assistant/access.js +1 -0
- package/dist/slices/assistant/asks.js +80 -0
- package/dist/slices/assistant/cost.js +54 -0
- package/dist/slices/assistant/gate.js +222 -0
- package/dist/slices/assistant/model.js +79 -0
- package/dist/slices/assistant/names.js +23 -0
- package/dist/slices/assistant/prompt.js +74 -0
- package/dist/slices/assistant/repo.js +74 -0
- package/dist/slices/assistant/tokens.js +18 -0
- package/dist/slices/assistant/turn.js +342 -0
- package/dist/slices/autopilot/buffer.js +76 -0
- package/dist/slices/autopilot/model.js +14 -0
- package/dist/slices/autopilot/notify.js +27 -0
- package/dist/slices/autopilot/repo.js +34 -0
- package/dist/slices/autopilot/signals.js +194 -0
- package/dist/slices/autopilot/warnings.js +85 -0
- package/dist/slices/autopilot/weekly.js +100 -0
- package/dist/slices/backups/files.js +2 -6
- package/dist/slices/backups/repo.js +3 -15
- package/dist/slices/backups/service.js +4 -3
- package/dist/slices/channels/cast-images.js +2 -1
- package/dist/slices/channels/model.js +0 -1
- package/dist/slices/channels/rebrand.js +0 -3
- package/dist/slices/channels/repo.js +4 -0
- package/dist/slices/channels/schema.js +6 -0
- package/dist/slices/channels/service.js +10 -0
- package/dist/slices/channels/videos.js +2 -14
- package/dist/slices/checkpoints/index.js +0 -1
- package/dist/slices/control/providers.js +0 -26
- package/dist/slices/designs/artwork.js +66 -0
- package/dist/slices/designs/budget.js +23 -0
- package/dist/slices/designs/calls.js +124 -0
- package/dist/slices/designs/check-context.js +38 -0
- package/dist/slices/designs/check-text.js +43 -0
- package/dist/slices/designs/fields.js +88 -0
- package/dist/slices/designs/frames.js +34 -0
- package/dist/slices/designs/gate.js +128 -0
- package/dist/slices/designs/layout.js +293 -0
- package/dist/slices/designs/model.js +35 -0
- package/dist/slices/designs/pdf-job.js +23 -0
- package/dist/slices/designs/pdf-pages.js +30 -0
- package/dist/slices/designs/pdf-runner.js +68 -0
- package/dist/slices/designs/pdf-worker.js +24 -0
- package/dist/slices/designs/picture-size.js +79 -0
- package/dist/slices/designs/pictures.js +55 -0
- package/dist/slices/designs/quote.js +24 -0
- package/dist/slices/designs/render-args.js +36 -0
- package/dist/slices/designs/render-input.js +59 -0
- package/dist/slices/designs/render.js +215 -0
- package/dist/slices/designs/repo.js +101 -0
- package/dist/slices/designs/requests.js +80 -0
- package/dist/slices/designs/runner.js +239 -0
- package/dist/slices/designs/sample-repo.js +91 -0
- package/dist/slices/designs/sample.js +222 -0
- package/dist/slices/designs/schema.js +87 -0
- package/dist/slices/designs/sections.js +44 -0
- package/dist/slices/designs/service.js +233 -0
- package/dist/slices/designs/steps-repo.js +102 -0
- package/dist/slices/designs/studio-kind.js +39 -0
- package/dist/slices/designs/template-checks.js +44 -0
- package/dist/slices/designs/template-make.js +118 -0
- package/dist/slices/designs/templates.js +218 -0
- package/dist/slices/document/fonts.js +2 -1
- package/dist/slices/episodes/summarize.js +5 -1
- package/dist/slices/estimate/index.js +45 -7
- package/dist/slices/fonts/catalog.js +3 -2
- package/dist/slices/fonts/discovery.js +3 -2
- package/dist/slices/fonts/files.js +2 -6
- package/dist/slices/fonts/index.js +0 -1
- package/dist/slices/fonts/sfnt.js +45 -10
- package/dist/slices/images/appearance.js +6 -15
- package/dist/slices/images/scenes.js +100 -27
- package/dist/slices/keywords/digest.js +84 -0
- package/dist/slices/keywords/facts.js +92 -0
- package/dist/slices/keywords/fill.js +80 -0
- package/dist/slices/keywords/model.js +75 -0
- package/dist/slices/keywords/rules.js +187 -0
- package/dist/slices/keywords/schema.js +28 -0
- package/dist/slices/keywords/specs.js +260 -0
- package/dist/slices/keywords/values.js +74 -0
- package/dist/slices/library/lint.js +29 -12
- package/dist/slices/library/model.js +2 -0
- package/dist/slices/library/photorealistic.js +4 -12
- package/dist/slices/library/rename.js +9 -7
- package/dist/slices/library/save.js +14 -10
- package/dist/slices/library/slots.js +37 -11
- package/dist/slices/library/transfer.js +2 -1
- package/dist/slices/library/used-by.js +25 -10
- package/dist/slices/loudness/loudnorm.js +51 -11
- package/dist/slices/model-checks/cost.js +61 -0
- package/dist/slices/model-checks/listing.js +124 -0
- package/dist/slices/model-checks/model.js +20 -0
- package/dist/slices/model-checks/record.js +32 -0
- package/dist/slices/model-checks/repo.js +120 -0
- package/dist/slices/model-checks/rules.js +112 -0
- package/dist/slices/model-checks/run.js +143 -0
- package/dist/slices/model-checks/service.js +198 -0
- package/dist/slices/model-upkeep/switch.js +70 -25
- package/dist/slices/model-upkeep/usage.js +26 -11
- package/dist/slices/narration/breaths.js +2 -1
- package/dist/slices/narration/clean-pieces.js +2 -1
- package/dist/slices/narration/concat.js +2 -1
- package/dist/slices/narration/peaks.js +3 -4
- package/dist/slices/narration/pronunciation-chunks.js +4 -3
- package/dist/slices/narration/pronunciation.js +3 -2
- package/dist/slices/narration/steering.js +4 -3
- package/dist/slices/notifications/notifier.js +4 -3
- package/dist/slices/notifications/rules.js +5 -2
- package/dist/slices/notifications/settings.js +4 -12
- package/dist/slices/notifications/subject.js +2 -1
- package/dist/slices/onboarding/copy.js +2 -1
- package/dist/slices/onboarding/first-run.js +3 -2
- package/dist/slices/onboarding/full-video.js +3 -2
- package/dist/slices/onboarding/install.js +4 -3
- package/dist/slices/onboarding/model.js +0 -16
- package/dist/slices/onboarding/packs.js +22 -22
- package/dist/slices/onboarding/quick-short.js +2 -1
- package/dist/slices/onboarding/sample.js +0 -1
- package/dist/slices/onboarding/state.js +2 -11
- package/dist/slices/onboarding/template.js +2 -1
- package/dist/slices/patch-notes/library.js +3 -2
- package/dist/slices/play-drafts/convert.js +4 -0
- package/dist/slices/play-drafts/review-inputs.js +8 -2
- package/dist/slices/play-drafts/review.js +5 -4
- package/dist/slices/play-drafts/schema.js +4 -0
- package/dist/slices/project-templates/from-project.js +9 -2
- package/dist/slices/project-templates/repo.js +6 -1
- package/dist/slices/project-templates/setup.js +8 -0
- package/dist/slices/project-templates/stand-ins.js +22 -0
- package/dist/slices/rebuild/activity.js +2 -0
- package/dist/slices/rebuild/admission-repo.js +3 -2
- package/dist/slices/rebuild/narration-history.js +4 -5
- package/dist/slices/rebuild/narration-retry.js +2 -1
- package/dist/slices/rebuild/preview-details.js +27 -9
- package/dist/slices/rebuild/preview-plan.js +3 -8
- package/dist/slices/rebuild/recipe-build.js +8 -3
- package/dist/slices/rebuild/recipe-describe.js +3 -3
- package/dist/slices/rebuild/recipe-digest.js +58 -0
- package/dist/slices/rebuild/recipe-input-schema.js +10 -0
- package/dist/slices/rebuild/recipe-keywords.js +71 -0
- package/dist/slices/rebuild/recipe-legacy.js +5 -1
- package/dist/slices/rebuild/recipe-model.js +4 -0
- package/dist/slices/rebuild/recipe-narration-text.js +2 -1
- package/dist/slices/rebuild/recipe-preparation.js +3 -3
- package/dist/slices/rebuild/recipe-reference.js +8 -4
- package/dist/slices/rebuild/recipe-reviews.js +27 -7
- package/dist/slices/rebuild/recipe-save.js +6 -3
- package/dist/slices/rebuild/recipe-scenes.js +40 -11
- package/dist/slices/rebuild/recipe-shorts.js +8 -8
- package/dist/slices/rebuild/recipe-social.js +46 -0
- package/dist/slices/rebuild/recipe-text.js +64 -20
- package/dist/slices/rebuild/recipe-validation.js +98 -28
- package/dist/slices/rebuild/recipe-visual.js +55 -16
- package/dist/slices/rebuild/recipe-work.js +15 -3
- package/dist/slices/rebuild/recipe-youtube.js +4 -3
- package/dist/slices/rebuild/recovery-selection.js +3 -1
- package/dist/slices/rebuild/recovery.js +3 -2
- package/dist/slices/rebuild/repo.js +4 -3
- package/dist/slices/rebuild/review-promise.js +25 -0
- package/dist/slices/rebuild/review-redo.js +2 -1
- package/dist/slices/rebuild/runtime-admission.js +4 -3
- package/dist/slices/rebuild/runtime-agent-review.js +11 -5
- package/dist/slices/rebuild/runtime-animate.js +9 -8
- package/dist/slices/rebuild/runtime-article.js +3 -2
- package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
- package/dist/slices/rebuild/runtime-document.js +8 -11
- package/dist/slices/rebuild/runtime-export-bed.js +6 -11
- package/dist/slices/rebuild/runtime-export-edit.js +6 -15
- package/dist/slices/rebuild/runtime-export-inputs.js +7 -7
- package/dist/slices/rebuild/runtime-export-short.js +8 -4
- package/dist/slices/rebuild/runtime-export.js +34 -12
- package/dist/slices/rebuild/runtime-figure-card.js +2 -1
- package/dist/slices/rebuild/runtime-image.js +4 -9
- package/dist/slices/rebuild/runtime-instructions.js +2 -0
- package/dist/slices/rebuild/runtime-keywords.js +59 -0
- package/dist/slices/rebuild/runtime-lines.js +2 -11
- package/dist/slices/rebuild/runtime-local.js +14 -20
- package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
- package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
- package/dist/slices/rebuild/runtime-narration-text.js +10 -15
- package/dist/slices/rebuild/runtime-pictures.js +2 -4
- package/dist/slices/rebuild/runtime-piece-label.js +10 -6
- package/dist/slices/rebuild/runtime-plan.js +31 -5
- package/dist/slices/rebuild/runtime-provider.js +60 -19
- package/dist/slices/rebuild/runtime-publication.js +10 -9
- package/dist/slices/rebuild/runtime-review.js +33 -28
- package/dist/slices/rebuild/runtime-run.js +4 -1
- package/dist/slices/rebuild/runtime-shorts.js +25 -45
- package/dist/slices/rebuild/runtime-store.js +3 -8
- package/dist/slices/rebuild/runtime-subtitles.js +16 -14
- package/dist/slices/rebuild/runtime-voices.js +8 -15
- package/dist/slices/rebuild/runtime-youtube.js +11 -29
- package/dist/slices/rebuild/transition-repo.js +6 -5
- package/dist/slices/rebuild/work-records.js +6 -0
- package/dist/slices/reruns/cascade.js +1 -2
- package/dist/slices/reruns/index.js +6 -9
- package/dist/slices/reviews/external-model.js +3 -0
- package/dist/slices/reviews/external-repo.js +2 -1
- package/dist/slices/reviews/external-rows.js +2 -3
- package/dist/slices/reviews/model.js +26 -8
- package/dist/slices/reviews/repo.js +2 -1
- package/dist/slices/reviews/rules.js +1 -0
- package/dist/slices/reviews/view.js +5 -2
- package/dist/slices/revisions/downloads.js +4 -5
- package/dist/slices/revisions/mutation-assets.js +7 -4
- package/dist/slices/revisions/mutation-cues.js +2 -5
- package/dist/slices/revisions/mutations.js +0 -1
- package/dist/slices/revisions/repo.js +3 -1
- package/dist/slices/revisions/schema.js +1 -0
- package/dist/slices/revisions/view.js +20 -0
- package/dist/slices/run-cost/limits.js +5 -2
- package/dist/slices/run-cost/meter.js +12 -5
- package/dist/slices/run-cost/panel.js +8 -74
- package/dist/slices/run-cost/plan-readings.js +127 -0
- package/dist/slices/run-cost/plan-use.js +169 -0
- package/dist/slices/run-cost/pricing.js +3 -3
- package/dist/slices/run-cost/week.js +32 -4
- package/dist/slices/schedules/agenda.js +11 -2
- package/dist/slices/schedules/by-date.js +42 -0
- package/dist/slices/schedules/calendar.js +5 -0
- package/dist/slices/schedules/design-agenda.js +36 -0
- package/dist/slices/schedules/design-check.js +41 -0
- package/dist/slices/schedules/design-run.js +126 -0
- package/dist/slices/schedules/next-run.js +62 -0
- package/dist/slices/schedules/prepare.js +18 -2
- package/dist/slices/schedules/repo.js +24 -16
- package/dist/slices/schedules/rescore.js +35 -0
- package/dist/slices/schedules/scheduler.js +13 -3
- package/dist/slices/schedules/schema.js +54 -3
- package/dist/slices/schedules/score.js +107 -0
- package/dist/slices/schedules/service.js +57 -24
- package/dist/slices/schedules/topic-list.js +15 -0
- package/dist/slices/schedules/topic-scores.js +104 -0
- package/dist/slices/schedules/topics.js +48 -36
- package/dist/slices/settings/cli-paths.js +4 -6
- package/dist/slices/settings/first-run.js +2 -11
- package/dist/slices/settings/model-reach.js +3 -17
- package/dist/slices/settings/model.js +10 -0
- package/dist/slices/settings/playback.js +33 -22
- package/dist/slices/settings/probe-read.js +16 -0
- package/dist/slices/settings/repo.js +33 -0
- package/dist/slices/settings/tutorial.js +2 -2
- package/dist/slices/settings/voices.js +4 -12
- package/dist/slices/shorts/pick.js +2 -15
- package/dist/slices/shorts/prompts.js +2 -13
- package/dist/slices/shorts/render.js +3 -0
- package/dist/slices/social/channel.js +44 -0
- package/dist/slices/social/defaults.js +17 -0
- package/dist/slices/social/due.js +36 -0
- package/dist/slices/social/extension.js +18 -0
- package/dist/slices/social/fit.js +115 -0
- package/dist/slices/social/limits.js +186 -0
- package/dist/slices/social/links.js +21 -0
- package/dist/slices/social/media.js +131 -0
- package/dist/slices/social/model.js +75 -0
- package/dist/slices/social/notice.js +19 -0
- package/dist/slices/social/pack.js +176 -0
- package/dist/slices/social/post-prompt.js +55 -0
- package/dist/slices/social/queue.js +31 -0
- package/dist/slices/social/repo.js +133 -0
- package/dist/slices/social/reshape.js +97 -0
- package/dist/slices/social/rules.js +5 -0
- package/dist/slices/social/schema.js +70 -0
- package/dist/slices/social/serve.js +51 -0
- package/dist/slices/social/service.js +128 -0
- package/dist/slices/social/settings.js +21 -0
- package/dist/slices/social/sources.js +114 -0
- package/dist/slices/social/state.js +110 -0
- package/dist/slices/social/text.js +149 -0
- package/dist/slices/storage/arrange.js +3 -1
- package/dist/slices/storage/assets.js +8 -10
- package/dist/slices/storage/backup-designs.js +74 -0
- package/dist/slices/storage/backup-export.js +8 -3
- package/dist/slices/storage/backup-format.js +10 -0
- package/dist/slices/storage/backup-import.js +20 -2
- package/dist/slices/storage/delete-project.js +6 -5
- package/dist/slices/storage/files-location.js +6 -8
- package/dist/slices/storage/layout.js +13 -2
- package/dist/slices/storage/model.js +3 -0
- package/dist/slices/storage/portable.js +16 -11
- package/dist/slices/storage/schema.js +2 -0
- package/dist/slices/storage/staging-refs.js +2 -1
- package/dist/slices/storage/staging.js +6 -9
- package/dist/slices/storage/trim.js +10 -3
- package/dist/slices/studio/calendar.js +4 -1
- package/dist/slices/studio/pick.js +2 -11
- package/dist/slices/studio/plan.js +6 -15
- package/dist/slices/studio/queue.js +3 -14
- package/dist/slices/studio/releases.js +26 -0
- package/dist/slices/studio/settings.js +14 -51
- package/dist/slices/studio/videos.js +12 -0
- package/dist/slices/style-preview/render.js +34 -13
- package/dist/slices/style-preview/schema.js +13 -0
- package/dist/slices/style-preview/service.js +2 -1
- package/dist/slices/style-preview/settings.js +33 -5
- package/dist/slices/telemetry/collector-client.js +2 -4
- package/dist/slices/telemetry/flush.js +2 -4
- package/dist/slices/telemetry/model.js +0 -7
- package/dist/slices/telemetry/record.js +10 -3
- package/dist/slices/template-studio/anatomy-view.js +118 -0
- package/dist/slices/template-studio/anatomy.js +73 -0
- package/dist/slices/template-studio/bakeoff-make.js +225 -0
- package/dist/slices/template-studio/bakeoff-repo.js +83 -0
- package/dist/slices/template-studio/bakeoff.js +333 -0
- package/dist/slices/template-studio/budget.js +103 -0
- package/dist/slices/template-studio/checks.js +273 -0
- package/dist/slices/template-studio/document-sample.js +56 -0
- package/dist/slices/template-studio/edit.js +15 -0
- package/dist/slices/template-studio/for-all.js +161 -0
- package/dist/slices/template-studio/free-video.js +31 -0
- package/dist/slices/template-studio/free.js +176 -0
- package/dist/slices/template-studio/gate.js +40 -0
- package/dist/slices/template-studio/hidden.js +20 -0
- package/dist/slices/template-studio/jobs.js +79 -0
- package/dist/slices/template-studio/loudness.js +111 -0
- package/dist/slices/template-studio/make.js +40 -0
- package/dist/slices/template-studio/model.js +54 -0
- package/dist/slices/template-studio/pack-import.js +253 -0
- package/dist/slices/template-studio/pack-samples.js +60 -0
- package/dist/slices/template-studio/pack.js +205 -0
- package/dist/slices/template-studio/paid-view.js +66 -0
- package/dist/slices/template-studio/paid.js +348 -0
- package/dist/slices/template-studio/quote.js +148 -0
- package/dist/slices/template-studio/ready.js +104 -0
- package/dist/slices/template-studio/repo.js +134 -0
- package/dist/slices/template-studio/reviews-path.js +58 -0
- package/dist/slices/template-studio/runner.js +84 -0
- package/dist/slices/template-studio/save.js +236 -0
- package/dist/slices/template-studio/say-it-as.js +248 -0
- package/dist/slices/template-studio/schedule-gate.js +34 -0
- package/dist/slices/template-studio/schedule-price.js +30 -0
- package/dist/slices/template-studio/schedule-sample.js +87 -0
- package/dist/slices/template-studio/schema.js +218 -0
- package/dist/slices/template-studio/scope.js +124 -0
- package/dist/slices/template-studio/sections.js +176 -0
- package/dist/slices/template-studio/service.js +173 -0
- package/dist/slices/template-studio/status.js +174 -0
- package/dist/slices/template-studio/topic.js +223 -0
- package/dist/slices/trash/designs.js +76 -0
- package/dist/slices/trash/model.js +13 -4
- package/dist/slices/trash/service.js +52 -2
- package/dist/slices/tutorials/library.js +3 -2
- package/dist/slices/video/ass-text.js +17 -0
- package/dist/slices/video/audio-export.js +2 -64
- package/dist/slices/video/encoding.js +160 -0
- package/dist/slices/video/ffmpeg.js +23 -21
- package/dist/slices/video/figure-card.js +1 -15
- package/dist/slices/video/slideshow.js +43 -18
- package/dist/slices/voices/palette.js +0 -3
- package/dist/slices/youtube/answer.js +2 -15
- package/dist/slices/youtube/edits-repo.js +2 -11
- package/dist/tutorials/Agents-MCP.md +2 -1
- package/dist/tutorials/Assistant.md +42 -0
- package/dist/tutorials/Channels.md +2 -0
- package/dist/tutorials/Home-and-Projects.md +19 -0
- package/dist/tutorials/Install.md +1 -0
- package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
- package/dist/tutorials/Models.md +33 -1
- package/dist/tutorials/Notifications.md +6 -0
- package/dist/tutorials/Play-Images.md +4 -0
- package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
- package/dist/tutorials/Prompts.md +10 -6
- package/dist/tutorials/Remote-Access.md +63 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +13 -2
- package/dist/tutorials/Schedules.md +21 -1
- package/dist/tutorials/Settings-Reference.md +50 -8
- package/dist/tutorials/Template-Studio.md +125 -0
- package/dist/tutorials/Templates.md +3 -0
- package/dist/tutorials/_Sidebar.md +5 -0
- package/dist/updater/work-in-progress.js +42 -12
- package/dist/web/assets/index-CkAI_2E7.css +1 -0
- package/dist/web/assets/index-DcD0cdfo.js +334 -0
- package/dist/web/assets/{pdf-T7MCwjIv.js → pdf-TODRwF31.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +5 -1
- package/dist/slices/article/provided-entries.js +0 -66
- package/dist/slices/article/run.js +0 -145
- package/dist/slices/images/run.js +0 -234
- package/dist/slices/narration/legacy-plan.js +0 -58
- package/dist/slices/narration/run.js +0 -270
- package/dist/slices/rebuild/runtime-actions.js +0 -90
- package/dist/slices/research/run.js +0 -224
- package/dist/slices/subtitles/prepare.js +0 -194
- package/dist/slices/subtitles/transcript.js +0 -34
- package/dist/slices/thumbnail/run.js +0 -219
- package/dist/slices/video/audio-inputs.js +0 -33
- package/dist/slices/video/reuse-audio.js +0 -62
- package/dist/slices/video/run.js +0 -78
- package/dist/slices/video/write-export.js +0 -158
- package/dist/slices/video/write-subtitles.js +0 -59
- package/dist/web/assets/index-BadsoORk.css +0 -1
- package/dist/web/assets/index-D8LqNsCl.js +0 -326
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
|
+
import { internalError } from "../../kernel/errors.js";
|
|
2
3
|
import { referenceKey, thumbnailVariant } from "../admission/model.js";
|
|
3
4
|
import { plainText } from "../article/plain.js";
|
|
4
5
|
import { splitEndMatter } from "../article/split.js";
|
|
5
6
|
import { checkAppearance } from "../images/appearance.js";
|
|
6
7
|
import { checkScenes, sceneCountOf } from "../images/scenes.js";
|
|
8
|
+
import { checkDigest } from "../keywords/digest.js";
|
|
7
9
|
import { spokenPassage } from "../narration/describe.js";
|
|
8
10
|
import { observeNarration } from "../narration/live.js";
|
|
9
11
|
import { validatePreparation } from "../narration/preparation.js";
|
|
@@ -11,24 +13,25 @@ import { prepareRequests } from "../narration/steering.js";
|
|
|
11
13
|
import { chaptersFrom } from "../research/planner.js";
|
|
12
14
|
import { sourcedAnswer } from "../research/synthesis.js";
|
|
13
15
|
import { imageReviewers } from "../reviews/model.js";
|
|
16
|
+
import { checkPost, postText } from "../social/post-prompt.js";
|
|
14
17
|
import { discardPreparedAssets, writeAsset } from "../storage/assets.js";
|
|
15
18
|
import { outputPath } from "../storage/layout.js";
|
|
16
19
|
import { probeDurationMs } from "../video/ffmpeg.js";
|
|
17
20
|
import { parseAttribution } from "../voices/attribution.js";
|
|
18
21
|
import { parseScript } from "../voices/script.js";
|
|
19
22
|
import { imageAppearanceKey } from "./recipe-appearance.js";
|
|
23
|
+
import { digestKey } from "./recipe-digest.js";
|
|
20
24
|
import { imageScenesKey, thumbnailScenesKey } from "./recipe-scenes.js";
|
|
21
25
|
import { executeArticleRequests } from "./runtime-article.js";
|
|
22
26
|
import { imageCall } from "./runtime-image.js";
|
|
23
27
|
import { frozenInstructions } from "./runtime-instructions.js";
|
|
24
28
|
import { articlePicture } from "./runtime-pictures.js";
|
|
25
|
-
import { executionPlan, executionView,
|
|
29
|
+
import { executionPlan, executionView, workCatalogue, workCatalogueIfSaved, } from "./runtime-plan.js";
|
|
26
30
|
import { preparedResult, preparedTexts, publishResult } from "./runtime-publication.js";
|
|
27
31
|
import { clearSoftening, softenedPrompt, softeningRequested, softenMessages } from "./soften.js";
|
|
32
|
+
import { pieceAlreadyDone } from "./work-records.js";
|
|
28
33
|
export async function executeProviderRecipe(deps, context, providers, piece) {
|
|
29
|
-
if (deps.db
|
|
30
|
-
.prepare("SELECT state FROM revision_work_pieces WHERE id=? AND work_id=?")
|
|
31
|
-
.get(piece.id, context.work.workId)?.state === "done")
|
|
34
|
+
if (pieceAlreadyDone(deps.db, context.work.workId, piece.id))
|
|
32
35
|
return "done";
|
|
33
36
|
const input = piece.input;
|
|
34
37
|
const wrapped = providers.forPiece(piece.id);
|
|
@@ -64,7 +67,7 @@ export async function executeProviderRecipe(deps, context, providers, piece) {
|
|
|
64
67
|
...(segment === undefined ? {} : { segment }),
|
|
65
68
|
tokensIn: answer.value.usage?.inputTokens ?? 0,
|
|
66
69
|
tokensOut: answer.value.usage?.outputTokens ?? 0,
|
|
67
|
-
});
|
|
70
|
+
}, context.work.projectId);
|
|
68
71
|
return "done";
|
|
69
72
|
}
|
|
70
73
|
if (input.kind === "tts") {
|
|
@@ -116,7 +119,7 @@ export async function executeProviderRecipe(deps, context, providers, piece) {
|
|
|
116
119
|
provider: input.provider,
|
|
117
120
|
model: input.model,
|
|
118
121
|
...(durationMs === undefined ? {} : { audioSeconds: durationMs / 1000 }),
|
|
119
|
-
});
|
|
122
|
+
}, context.work.projectId);
|
|
120
123
|
}
|
|
121
124
|
finally {
|
|
122
125
|
discardPreparedAssets(deps, [asset]);
|
|
@@ -164,10 +167,10 @@ export async function executeProviderRecipe(deps, context, providers, piece) {
|
|
|
164
167
|
provider: input.provider,
|
|
165
168
|
model: input.model,
|
|
166
169
|
...(variant !== undefined ? { thumbnails: 1 } : { images: 1 }),
|
|
167
|
-
});
|
|
170
|
+
}, context.work.projectId);
|
|
168
171
|
return "done";
|
|
169
172
|
}
|
|
170
|
-
throw new Error("
|
|
173
|
+
throw new Error(internalError("this step has no provider request to run"));
|
|
171
174
|
}
|
|
172
175
|
// Soften and retry (`soften.ts`): the project's AI model rewords a refused image prompt
|
|
173
176
|
// before the image is drawn again. Undefined when nobody asked, or the project has no model.
|
|
@@ -209,6 +212,14 @@ function checkAnswer(piece, answer) {
|
|
|
209
212
|
const checked = checkAppearance(answer.text);
|
|
210
213
|
return checked.ok ? undefined : checked.reason;
|
|
211
214
|
}
|
|
215
|
+
// The keyword digest: every part written.
|
|
216
|
+
if (piece.key === digestKey && piece.input.kind === "llm") {
|
|
217
|
+
const checked = checkDigest(answer.text);
|
|
218
|
+
return checked.ok ? undefined : checked.reason;
|
|
219
|
+
}
|
|
220
|
+
// A post for another site: within its limit.
|
|
221
|
+
if (piece.input.kind === "llm" && piece.input.social !== undefined)
|
|
222
|
+
return checkPost(answer.text, piece.input.social);
|
|
212
223
|
if (piece.key === "research:planner")
|
|
213
224
|
return chaptersFrom(answer.text).length === 0
|
|
214
225
|
? "The AI model's research plan listed no chapters, so research could not go on. Use Try again; if it keeps happening, choose another model in the Providers section of Edit project."
|
|
@@ -240,7 +251,11 @@ async function publishText(deps, context, piece, answer) {
|
|
|
240
251
|
throw new Error(checked.reason);
|
|
241
252
|
await publishResult(deps, context, piece, preparedTexts(deps, context, piece, [
|
|
242
253
|
["instructions", "instructions.md", frozenInstructions(deps, context, piece)],
|
|
243
|
-
]), {
|
|
254
|
+
]), {
|
|
255
|
+
scenes: checked.scenes,
|
|
256
|
+
...(checked.details === undefined ? {} : { details: checked.details }),
|
|
257
|
+
text: answer.text,
|
|
258
|
+
});
|
|
244
259
|
return;
|
|
245
260
|
}
|
|
246
261
|
if (piece.key === imageAppearanceKey && piece.input.kind === "llm") {
|
|
@@ -252,6 +267,37 @@ async function publishText(deps, context, piece, answer) {
|
|
|
252
267
|
]), { appearance: checked.appearance, text: answer.text });
|
|
253
268
|
return;
|
|
254
269
|
}
|
|
270
|
+
if (piece.input.kind === "llm" && piece.input.social !== undefined) {
|
|
271
|
+
const target = piece.input.social;
|
|
272
|
+
const problem = checkPost(answer.text, target);
|
|
273
|
+
if (problem !== undefined)
|
|
274
|
+
throw new Error(problem);
|
|
275
|
+
const text = postText(answer.text);
|
|
276
|
+
const asset = writeAsset(deps, context.work.projectId, `post-${target.platform}.txt`, Buffer.from(text));
|
|
277
|
+
let outputs;
|
|
278
|
+
try {
|
|
279
|
+
outputs = [
|
|
280
|
+
preparedResult(deps, context, piece, "social_post", asset, null, {
|
|
281
|
+
platform: target.platform,
|
|
282
|
+
}),
|
|
283
|
+
];
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
discardPreparedAssets(deps, [asset]);
|
|
287
|
+
throw error;
|
|
288
|
+
}
|
|
289
|
+
await publishResult(deps, context, piece, outputs, { text });
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
if (piece.key === digestKey && piece.input.kind === "llm") {
|
|
293
|
+
const checked = checkDigest(answer.text);
|
|
294
|
+
if (!checked.ok)
|
|
295
|
+
throw new Error(checked.reason);
|
|
296
|
+
await publishResult(deps, context, piece, preparedTexts(deps, context, piece, [
|
|
297
|
+
["instructions", "instructions.md", frozenInstructions(deps, context, piece)],
|
|
298
|
+
]), { digest: checked.digest, text: answer.text });
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
255
301
|
if (piece.input.kind === "llm" && piece.input.preparation !== undefined) {
|
|
256
302
|
const checked = validatePreparation(answer.text, piece.input.preparation.source);
|
|
257
303
|
if (!checked.ok)
|
|
@@ -314,7 +360,7 @@ async function publishText(deps, context, piece, answer) {
|
|
|
314
360
|
: [];
|
|
315
361
|
const title = titles[Number(piece.key.split(":").at(-1)) - 1];
|
|
316
362
|
if (typeof title !== "string")
|
|
317
|
-
throw new Error("
|
|
363
|
+
throw new Error(internalError("a research chapter has no title in the research plan"));
|
|
318
364
|
const asset = writeAsset(deps, context.work.projectId, `research-${piece.key.split(":").at(-1)}.md`, Buffer.from(answer.text));
|
|
319
365
|
await publishResult(deps, context, piece, [], { title, notes: answer.text }, asset);
|
|
320
366
|
return;
|
|
@@ -328,13 +374,11 @@ function narrationLabel(deps, context, piece) {
|
|
|
328
374
|
return "Narration";
|
|
329
375
|
const name = piece.input.segment === "body" ? "Body" : piece.input.segment === "intro" ? "Intro" : "Outro";
|
|
330
376
|
const view = executionView(deps, context.work.projectId, context.work.revisionId);
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
.get(context.work.workId);
|
|
334
|
-
if (view === undefined || row?.recipe_context === undefined || row.recipe_context === null)
|
|
377
|
+
const catalogue = workCatalogueIfSaved(deps.db, context.work.workId);
|
|
378
|
+
if (view === undefined || catalogue === undefined)
|
|
335
379
|
return name;
|
|
336
380
|
const segment = piece.input.segment;
|
|
337
|
-
const parts = executionPlan(deps, view,
|
|
381
|
+
const parts = executionPlan(deps, view, catalogue).recipes.filter((recipe) => recipe.input.kind === "tts" && recipe.input.segment === segment);
|
|
338
382
|
const index = parts.findIndex((recipe) => recipe.key === piece.key);
|
|
339
383
|
return parts.length > 1 && index >= 0 ? `${name} part ${index + 1} of ${parts.length}` : name;
|
|
340
384
|
}
|
|
@@ -345,10 +389,7 @@ function checkPreparation(deps, context, piece, answer) {
|
|
|
345
389
|
const checked = validatePreparation(answer.text, source);
|
|
346
390
|
if (!checked.ok)
|
|
347
391
|
return checked.reason;
|
|
348
|
-
const
|
|
349
|
-
.prepare("SELECT recipe_context FROM revision_work WHERE id=?")
|
|
350
|
-
.get(context.work.workId);
|
|
351
|
-
const model = savedCatalogue(row?.recipe_context).tts.find((model) => model.provider === "inworld" && model.id === "inworld-tts-2");
|
|
392
|
+
const model = workCatalogue(deps.db, context.work.workId).tts.find((model) => model.provider === "inworld" && model.id === "inworld-tts-2");
|
|
352
393
|
const prepared = prepareRequests(source, checked.cues, model?.tts.maxCharacters ?? 4000);
|
|
353
394
|
return prepared.ok ? undefined : prepared.reason;
|
|
354
395
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { transact } from "../../kernel/db/tx.js";
|
|
2
|
+
import { internalError } from "../../kernel/errors.js";
|
|
2
3
|
import { fingerprint } from "../../kernel/runner/work.js";
|
|
3
4
|
import { publicationAuthority } from "../revisions/publication-rules.js";
|
|
4
5
|
import { commitRevisionOutputs } from "../revisions/publish.js";
|
|
5
6
|
import { insertAsset, insertManifestOutput, revisionById } from "../revisions/repo.js";
|
|
6
7
|
import { discardPreparedAssets, writeAsset } from "../storage/assets.js";
|
|
7
8
|
import { rebindPublishedNarration } from "./runtime-narration-publication.js";
|
|
8
|
-
import { executionPlan, executionView,
|
|
9
|
+
import { executionPlan, executionView, workCatalogueIfSaved } from "./runtime-plan.js";
|
|
9
10
|
export function preparedResult(deps, context, piece, role, asset, durationMs = null, meta = {}) {
|
|
10
11
|
return {
|
|
11
12
|
// A project holds many images, and one video and several images per short.
|
|
@@ -15,6 +16,8 @@ export function preparedResult(deps, context, piece, role, asset, durationMs = n
|
|
|
15
16
|
role === "animated_image" ||
|
|
16
17
|
// Level the volume: one levelled narration per segment.
|
|
17
18
|
role === "audio_levelled" ||
|
|
19
|
+
// A post per site.
|
|
20
|
+
role === "social_post" ||
|
|
18
21
|
// The second and third thumbnails; the first keeps the slot it always had.
|
|
19
22
|
(role === "thumbnail" && piece.key !== "thumbnail:image")
|
|
20
23
|
? piece.key
|
|
@@ -39,7 +42,7 @@ export function preparedResult(deps, context, piece, role, asset, durationMs = n
|
|
|
39
42
|
export function preparedText(deps, context, piece, role, filename, text) {
|
|
40
43
|
const output = preparedTexts(deps, context, piece, [[role, filename, text]])[0];
|
|
41
44
|
if (output === undefined)
|
|
42
|
-
throw new Error("
|
|
45
|
+
throw new Error(internalError("a text file could not be prepared"));
|
|
43
46
|
return output;
|
|
44
47
|
}
|
|
45
48
|
export function preparedTexts(deps, context, piece, texts) {
|
|
@@ -173,11 +176,9 @@ function pieceIndex(deps, context, piece) {
|
|
|
173
176
|
if (localIndex >= 0)
|
|
174
177
|
return localIndex + 1;
|
|
175
178
|
const view = executionView(deps, context.work.projectId, context.work.revisionId);
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
.
|
|
179
|
-
if (view !== undefined && row?.recipe_context !== null && row?.recipe_context !== undefined) {
|
|
180
|
-
const keys = executionPlan(deps, view, savedCatalogue(row.recipe_context)).recipes.filter((recipe) => recipe.stage === context.work.kind &&
|
|
179
|
+
const catalogue = workCatalogueIfSaved(deps.db, context.work.workId);
|
|
180
|
+
if (view !== undefined && catalogue !== undefined) {
|
|
181
|
+
const keys = executionPlan(deps, view, catalogue).recipes.filter((recipe) => recipe.stage === context.work.kind &&
|
|
181
182
|
(piece.input.kind !== "llm" ||
|
|
182
183
|
piece.input.preparation?.segment !== "body" ||
|
|
183
184
|
(recipe.input.kind === "llm" && recipe.input.preparation?.segment === "body")) &&
|
|
@@ -206,10 +207,10 @@ export function retainPartialArticle(deps, context, piece, text) {
|
|
|
206
207
|
if (authority === undefined)
|
|
207
208
|
return;
|
|
208
209
|
if (authority.key !== piece.key || authority.fingerprint !== piece.fingerprint)
|
|
209
|
-
throw new Error("
|
|
210
|
+
throw new Error(internalError("a partly written article doesn't match its saved step"));
|
|
210
211
|
const revision = revisionById(deps.db, context.work.projectId, context.work.revisionId);
|
|
211
212
|
if (revision === undefined)
|
|
212
|
-
throw new Error("
|
|
213
|
+
throw new Error(internalError("the project version for a partly written article is missing"));
|
|
213
214
|
insertAsset(deps.db, result.asset);
|
|
214
215
|
insertManifestOutput(deps.db, revision, {
|
|
215
216
|
slot: `article:partial:${piece.id}`,
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { internalError } from "../../kernel/errors.js";
|
|
3
4
|
import { thinkingModes } from "../../kernel/ports/llm.js";
|
|
4
5
|
import { plainText } from "../article/plain.js";
|
|
5
6
|
import { defaultReviewPrompts, narrationItemKey, reviewStages, } from "../reviews/model.js";
|
|
6
7
|
import { nextAttempt, reviewOutcome } from "../reviews/outcome.js";
|
|
7
8
|
import { latestVerdict, saveVerdict } from "../reviews/repo.js";
|
|
8
9
|
import { parseVerdict, reviewMessages } from "../reviews/verdict.js";
|
|
10
|
+
import { isReadyOutput } from "../revisions/view.js";
|
|
9
11
|
import { pickedShortsOf } from "../shorts/clips.js";
|
|
10
12
|
import { outputPath } from "../storage/layout.js";
|
|
13
|
+
import { openingOf, spokenArticle } from "./review-promise.js";
|
|
11
14
|
import { exportSnapshot, revisionTranscript, } from "./runtime-export-inputs.js";
|
|
12
|
-
import {
|
|
15
|
+
import { workLlm } from "./runtime-plan.js";
|
|
13
16
|
import { publishResult } from "./runtime-publication.js";
|
|
14
17
|
import { wordsSchema } from "./runtime-subtitles.js";
|
|
18
|
+
import { pieceAlreadyDone } from "./work-records.js";
|
|
15
19
|
// What `recipe-reviews.ts` saves in the step's values, by position.
|
|
16
20
|
const valuesSchema = z.tuple([
|
|
17
21
|
z.enum(reviewStages),
|
|
@@ -32,9 +36,7 @@ const textMax = 60_000;
|
|
|
32
36
|
// saved as a pending redo, which `review-redo.ts` starts once this step has finished, and
|
|
33
37
|
// until then the item's dependents are held (`reviewHold`).
|
|
34
38
|
export async function executeReviewRecipe(deps, context, providers, piece) {
|
|
35
|
-
if (deps.db
|
|
36
|
-
.prepare("SELECT state FROM revision_work_pieces WHERE id=? AND work_id=?")
|
|
37
|
-
.get(piece.id, context.work.workId)?.state === "done")
|
|
39
|
+
if (pieceAlreadyDone(deps.db, context.work.workId, piece.id))
|
|
38
40
|
return "done";
|
|
39
41
|
if (!context.maySubmit(piece.id))
|
|
40
42
|
return "held";
|
|
@@ -44,33 +46,24 @@ export async function executeReviewRecipe(deps, context, providers, piece) {
|
|
|
44
46
|
? valuesSchema.safeParse(input.values)
|
|
45
47
|
: undefined;
|
|
46
48
|
if (values === undefined || !values.success)
|
|
47
|
-
throw new Error("
|
|
49
|
+
throw new Error(internalError("a review step was set up wrongly"));
|
|
48
50
|
const [stage, itemKey, , provider, model, thinking, prompt, mode, retries] = values.data;
|
|
49
51
|
const snapshot = exportSnapshot(deps, context, piece);
|
|
50
52
|
const material = reviewMaterial(deps, context, snapshot, stage, itemKey, prompt);
|
|
51
53
|
const previous = latestVerdict(deps.db, context.work.projectId, itemKey);
|
|
52
54
|
const attempt = nextAttempt(previous, material.itemFingerprint);
|
|
53
|
-
const row = deps.db
|
|
54
|
-
.prepare("SELECT recipe_context FROM revision_work WHERE id=?")
|
|
55
|
-
.get(context.work.workId);
|
|
56
|
-
const catalogued = savedCatalogue(row?.recipe_context).llm.find((one) => one.provider === provider && one.id === model);
|
|
57
55
|
const level = thinking === null ? undefined : z.enum(thinkingModes).parse(thinking);
|
|
56
|
+
const call = workLlm(deps.db, context.work.workId, { provider, model, thinking: level }, piece.key);
|
|
58
57
|
if (!context.maySubmit(piece.id))
|
|
59
58
|
return "held";
|
|
60
|
-
const answer = await providers.forPiece(piece.id).llm({
|
|
61
|
-
provider,
|
|
62
|
-
model,
|
|
63
|
-
...(level === undefined ? {} : { thinking: level }),
|
|
64
|
-
thinkingConfig: level === undefined ? null : (catalogued?.llm.thinking?.[level] ?? null),
|
|
59
|
+
const answer = await providers.forPiece(piece.id).llm(call({
|
|
65
60
|
messages: reviewMessages(material.request),
|
|
66
|
-
webSearch: false,
|
|
67
61
|
...(material.images.length === 0 ? {} : { images: material.images }),
|
|
68
|
-
previewLabel: piece.key,
|
|
69
62
|
check: (value) => {
|
|
70
63
|
const parsed = parseVerdict(value.text);
|
|
71
64
|
return parsed.ok ? undefined : parsed.reason;
|
|
72
65
|
},
|
|
73
|
-
});
|
|
66
|
+
}));
|
|
74
67
|
if (!answer.ok)
|
|
75
68
|
return "held";
|
|
76
69
|
const verdict = parseVerdict(answer.value.text);
|
|
@@ -126,10 +119,7 @@ export async function executeReviewRecipe(deps, context, providers, piece) {
|
|
|
126
119
|
// and outro, and the prepared or hand-edited spoken text rather than the article as written.
|
|
127
120
|
// Falls back to the article when those texts can't be read.
|
|
128
121
|
function spokenText(deps, snapshot) {
|
|
129
|
-
const present = ["intro", "body", "outro"].filter((kind) => snapshot.view.outputs.some((one) => one.
|
|
130
|
-
one.available &&
|
|
131
|
-
one.state === "ready" &&
|
|
132
|
-
one.output.role === `audio_${kind}`));
|
|
122
|
+
const present = ["intro", "body", "outro"].filter((kind) => snapshot.view.outputs.some((one) => isReadyOutput(one) && one.output.role === `audio_${kind}`));
|
|
133
123
|
try {
|
|
134
124
|
const text = present.map((kind) => revisionTranscript(deps, snapshot, kind)).join("\n\n");
|
|
135
125
|
if (text.trim() !== "")
|
|
@@ -145,9 +135,7 @@ export function reviewMaterial(deps, context, snapshot, stage, itemKey, prompt)
|
|
|
145
135
|
const recipes = snapshot.plan.recipes;
|
|
146
136
|
const config = view.revision.config;
|
|
147
137
|
const output = (workKey, role) => view.outputs.find((row) => row.workKey === workKey &&
|
|
148
|
-
row
|
|
149
|
-
row.available &&
|
|
150
|
-
row.state === "ready" &&
|
|
138
|
+
isReadyOutput(row) &&
|
|
151
139
|
(role === undefined || row.output.role === role));
|
|
152
140
|
const path = (row) => outputPath(deps.paths, context.work.projectId, row.output.path);
|
|
153
141
|
const text = (row) => clip(readFileSync(path(row), "utf8"));
|
|
@@ -178,6 +166,26 @@ export function reviewMaterial(deps, context, snapshot, stage, itemKey, prompt)
|
|
|
178
166
|
itemFingerprint: article.fingerprint,
|
|
179
167
|
};
|
|
180
168
|
}
|
|
169
|
+
// The opening as the viewer will hear it, against what the title and the thumbnail brief
|
|
170
|
+
// promise; the whole article shows whether the promise is kept later on.
|
|
171
|
+
case "promise": {
|
|
172
|
+
const article = output("article:body", "article_md");
|
|
173
|
+
if (article === undefined)
|
|
174
|
+
throw missing("article", "Use More → Write the article again in the Article section");
|
|
175
|
+
const spoken = spokenArticle(readFileSync(path(article), "utf8"));
|
|
176
|
+
const thumbnail = recipes.find((one) => one.key === "thumbnail:image");
|
|
177
|
+
const brief = thumbnail?.input.kind === "image" ? thumbnail.input.prompt.trim() : "";
|
|
178
|
+
return {
|
|
179
|
+
request: request([
|
|
180
|
+
{ label: "Video title", text: config.title },
|
|
181
|
+
...(brief === "" ? [] : [{ label: "Thumbnail brief", text: clip(brief) }]),
|
|
182
|
+
{ label: "Opening (first ~30 s)", text: openingOf(spoken) },
|
|
183
|
+
{ label: "Whole article", text: clip(spoken) },
|
|
184
|
+
]),
|
|
185
|
+
images: [],
|
|
186
|
+
itemFingerprint: article.fingerprint,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
181
189
|
case "images":
|
|
182
190
|
case "thumbnail": {
|
|
183
191
|
const image = output(itemKey);
|
|
@@ -252,10 +260,7 @@ export function reviewMaterial(deps, context, snapshot, stage, itemKey, prompt)
|
|
|
252
260
|
const title = pickedShortsOf(pick?.piece.payload)?.shorts.find((clip) => clip.number === number)?.title ??
|
|
253
261
|
"";
|
|
254
262
|
const stills = view.outputs
|
|
255
|
-
.filter((row) => row.workKey.startsWith(`${itemKey}:image:`) &&
|
|
256
|
-
row.selected &&
|
|
257
|
-
row.available &&
|
|
258
|
-
row.state === "ready")
|
|
263
|
+
.filter((row) => row.workKey.startsWith(`${itemKey}:image:`) && isReadyOutput(row))
|
|
259
264
|
.slice(0, 6);
|
|
260
265
|
if (stills.length === 0)
|
|
261
266
|
throw missing("short's images", "Use Make this short again in Edit project → Shorts");
|
|
@@ -2,6 +2,7 @@ import { executeAgentReviewRecipe } from "./runtime-agent-review.js";
|
|
|
2
2
|
import { executeAnimateRecipe } from "./runtime-animate.js";
|
|
3
3
|
import { executeDocumentRecipe } from "./runtime-document.js";
|
|
4
4
|
import { executeExportRecipe } from "./runtime-export.js";
|
|
5
|
+
import { lateKeywordProviders, lateValuesOf } from "./runtime-keywords.js";
|
|
5
6
|
import { executeLocalRecipe } from "./runtime-local.js";
|
|
6
7
|
import { pieceLabel } from "./runtime-piece-label.js";
|
|
7
8
|
import { executeProviderRecipe } from "./runtime-provider.js";
|
|
@@ -11,7 +12,9 @@ import { executeSubtitleRecipe } from "./runtime-subtitles.js";
|
|
|
11
12
|
import { executeVoicesRecipe } from "./runtime-voices.js";
|
|
12
13
|
import { executeYoutubeRecipe } from "./runtime-youtube.js";
|
|
13
14
|
import { workPieces } from "./work-records.js";
|
|
14
|
-
export async function runRevisionInvocation(deps, context,
|
|
15
|
+
export async function runRevisionInvocation(deps, context, sent) {
|
|
16
|
+
// `{{Slopify_Release_Date}}` and `{{Slopify_Duration}}` are filled as a request is sent.
|
|
17
|
+
const providers = lateKeywordProviders(sent, () => lateValuesOf(deps, context));
|
|
15
18
|
const pieces = workPieces(deps.db, context.work.workId).filter((piece) => !piece.key.startsWith("article:continuation:"));
|
|
16
19
|
let waiting = false;
|
|
17
20
|
for (const piece of pieces) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { z } from "zod";
|
|
1
|
+
import { errorText, internalError } from "../../kernel/errors.js";
|
|
3
2
|
import { withLanguage, wordTimingUnavailable } from "../../kernel/ports/languages.js";
|
|
4
3
|
import { usesFigureCards, usesShorts } from "../admission/rules.js";
|
|
5
4
|
import { captionBoldFont } from "../fonts/coverage.js";
|
|
6
|
-
import { resolveBoldFont } from "../fonts/index.js";
|
|
7
5
|
import { masterGoal } from "../loudness/model.js";
|
|
6
|
+
import { assetPathOrUndefined } from "../revisions/mutation-assets.js";
|
|
7
|
+
import { readyOutput } from "../revisions/view.js";
|
|
8
8
|
import { clipWords } from "../shorts/captions.js";
|
|
9
9
|
import { effectiveClips, pickedShortsOf } from "../shorts/clips.js";
|
|
10
10
|
import { anchorKept, lostMessage, withNewPicks } from "../shorts/keep.js";
|
|
@@ -18,21 +18,21 @@ import { probeDurationMs } from "../video/ffmpeg.js";
|
|
|
18
18
|
import { usesVoices } from "../voices/model.js";
|
|
19
19
|
import { sentencesText, transcriptSentences } from "../youtube/transcript.js";
|
|
20
20
|
import { shortsPickKey } from "./recipe-shorts.js";
|
|
21
|
+
import { exportMachine, warningsOf } from "./runtime-export.js";
|
|
21
22
|
import { figureShots } from "./runtime-export-edit.js";
|
|
22
23
|
import { exportSnapshot, revisionAudio } from "./runtime-export-inputs.js";
|
|
23
24
|
import { imageCall } from "./runtime-image.js";
|
|
24
|
-
import {
|
|
25
|
+
import { workLlm } from "./runtime-plan.js";
|
|
25
26
|
import { softenIfAsked } from "./runtime-provider.js";
|
|
26
27
|
import { preparedResult, preparedTexts, publishResult } from "./runtime-publication.js";
|
|
27
|
-
import {
|
|
28
|
+
import { readTimingWords } from "./runtime-subtitles.js";
|
|
28
29
|
import { clearSoftening } from "./soften.js";
|
|
30
|
+
import { pieceAlreadyDone } from "./work-records.js";
|
|
29
31
|
// The Shorts step's four kinds of work (`recipe-shorts.ts`): the pick, each clip's image
|
|
30
32
|
// prompts, each image, and each clip's render. Each is one piece of its own, so a failure
|
|
31
33
|
// names the clip it belongs to and Try again redoes only what did not finish.
|
|
32
34
|
export async function executeShortsRecipe(deps, context, providers, piece) {
|
|
33
|
-
if (deps.db
|
|
34
|
-
.prepare("SELECT state FROM revision_work_pieces WHERE id=? AND work_id=?")
|
|
35
|
-
.get(piece.id, context.work.workId)?.state === "done")
|
|
35
|
+
if (pieceAlreadyDone(deps.db, context.work.workId, piece.id))
|
|
36
36
|
return "done";
|
|
37
37
|
if (!context.maySubmit(piece.id))
|
|
38
38
|
return "held";
|
|
@@ -67,7 +67,7 @@ async function pick(deps, context, providers, piece, snapshot) {
|
|
|
67
67
|
const llm = config.llm;
|
|
68
68
|
if (llm === undefined || llm.provider.trim() === "" || llm.model.trim() === "")
|
|
69
69
|
throw new Error("Shorts need an AI text model to pick the clips, and none is chosen. Choose one in Edit project → Providers, then Try again.");
|
|
70
|
-
const sentences = transcriptSentences(
|
|
70
|
+
const sentences = transcriptSentences(readTimingWords(deps, context, view, shortsTimingPurpose).words);
|
|
71
71
|
if (sentences.length === 0)
|
|
72
72
|
throw new Error("The narration's word timing holds no words, so there is nothing to cut shorts from. Use More → Render the video again in the Video section, then Try again.");
|
|
73
73
|
const audio = await revisionAudio(deps, context, view);
|
|
@@ -236,12 +236,12 @@ async function render(deps, context, piece, snapshot, clip) {
|
|
|
236
236
|
.filter((recipe) => recipe.key.startsWith(prefix))
|
|
237
237
|
.toSorted((left, right) => imageIndex(left.key) - imageIndex(right.key))
|
|
238
238
|
.map((recipe) => {
|
|
239
|
-
const row = view
|
|
239
|
+
const row = readyOutput(view, { workKey: recipe.key });
|
|
240
240
|
if (row === undefined)
|
|
241
241
|
throw new Error(`Short ${String(clip.number)} is missing one of its images. Try again to make it again; if it keeps happening, use Make this short again in Edit project → Shorts.`);
|
|
242
242
|
return outputPath(deps.paths, context.work.projectId, row.output.path);
|
|
243
243
|
});
|
|
244
|
-
const allWords =
|
|
244
|
+
const allWords = readTimingWords(deps, context, view, shortsTimingPurpose).words;
|
|
245
245
|
const words = clipWords(allWords, clip.start, clip.end);
|
|
246
246
|
// The upright cards whose descriptions fall in the clip, on the clip's own timeline.
|
|
247
247
|
const figures = usesFigureCards(config)
|
|
@@ -268,8 +268,11 @@ async function render(deps, context, piece, snapshot, clip) {
|
|
|
268
268
|
const prepared = [];
|
|
269
269
|
const seconds = (clip.end - clip.start) / speed;
|
|
270
270
|
try {
|
|
271
|
+
const machine = await exportMachine(deps, context.work.projectId);
|
|
271
272
|
const master = await renderShort({
|
|
272
273
|
bin: deps.ffmpeg,
|
|
274
|
+
machine: machine.machine,
|
|
275
|
+
notice: machine.notice,
|
|
273
276
|
master: masterGoal(config, "video"),
|
|
274
277
|
timeline,
|
|
275
278
|
start: clip.start,
|
|
@@ -303,12 +306,13 @@ async function render(deps, context, piece, snapshot, clip) {
|
|
|
303
306
|
prepared.push(preparedResult(deps, context, piece, "short_video", asset, durationMs, {
|
|
304
307
|
short: clip.number,
|
|
305
308
|
sentences: [clip.first, clip.last],
|
|
309
|
+
...warningsOf(machine.notices),
|
|
306
310
|
...(master === undefined ? {} : { master }),
|
|
307
311
|
}));
|
|
308
312
|
await publishResult(deps, context, piece, prepared, { short: clip.number, start: clip.start, end: clip.end, durationMs }, asset);
|
|
309
313
|
// One per rendered short, with no stage: stage "video" would read as a finished video.
|
|
310
314
|
// Its pick and prompt tokens are not counted here.
|
|
311
|
-
deps.count?.("stage.completed", { shorts: 1 });
|
|
315
|
+
deps.count?.("stage.completed", { shorts: 1 }, context.work.projectId);
|
|
312
316
|
return "done";
|
|
313
317
|
}
|
|
314
318
|
finally {
|
|
@@ -341,57 +345,33 @@ async function backgroundMusic(deps, context, view) {
|
|
|
341
345
|
if (assetId === undefined || shorts === undefined)
|
|
342
346
|
return undefined;
|
|
343
347
|
const fix = "Choose another file under Background music in Edit project → Shorts, or remove the music, then Try again.";
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
.safeParse(deps.db
|
|
347
|
-
.prepare("SELECT path FROM project_assets WHERE project_id=? AND id=?")
|
|
348
|
-
.get(context.work.projectId, assetId));
|
|
349
|
-
if (!row.success)
|
|
348
|
+
const saved = assetPathOrUndefined(deps, context.work.projectId, assetId);
|
|
349
|
+
if (saved === undefined)
|
|
350
350
|
throw new Error(`The shorts' background music file is no longer in the project. ${fix}`);
|
|
351
|
-
const path = outputPath(deps.paths, context.work.projectId,
|
|
351
|
+
const path = outputPath(deps.paths, context.work.projectId, saved);
|
|
352
352
|
let durationMs;
|
|
353
353
|
try {
|
|
354
354
|
durationMs = await probeDurationMs(deps.ffmpeg, path, context.signal, deps.log);
|
|
355
355
|
}
|
|
356
356
|
catch (error) {
|
|
357
357
|
context.signal.throwIfAborted();
|
|
358
|
-
throw new Error(`The shorts' background music couldn't be read as audio (${
|
|
358
|
+
throw new Error(`The shorts' background music couldn't be read as audio (${errorText(error)}). ${fix}`);
|
|
359
359
|
}
|
|
360
360
|
if (durationMs <= 0)
|
|
361
361
|
throw new Error(`The shorts' background music file holds no sound. ${fix}`);
|
|
362
362
|
return { path, volume: musicVolumeOf(shorts) };
|
|
363
363
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
row.available &&
|
|
367
|
-
row.state === "ready" &&
|
|
368
|
-
row.workKey === "subtitles:timing" &&
|
|
369
|
-
row.output.role === "subtitle_words");
|
|
370
|
-
if (timing === undefined)
|
|
371
|
-
throw new Error("The narration's word timing, which the shorts are cut and captioned from, is missing. Use More → Render the video again in the Video section, then Try again.");
|
|
372
|
-
return wordsSchema.parse(JSON.parse(readFileSync(outputPath(deps.paths, context.work.projectId, timing.output.path), "utf8"))).words;
|
|
373
|
-
}
|
|
364
|
+
// What the shorts read the narration's word timing for, in the sentence a missing one fails with.
|
|
365
|
+
const shortsTimingPurpose = "the shorts are cut and captioned from";
|
|
374
366
|
// The project's text model, with the thinking settings saved for this step's catalogue.
|
|
375
367
|
function llmCall(deps, context, piece, view, check) {
|
|
376
368
|
const llm = view.revision.config.llm ?? { provider: "", model: "" };
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
.get(context.work.workId);
|
|
380
|
-
const model = savedCatalogue(row?.recipe_context).llm.find((one) => one.provider === llm.provider && one.id === llm.model);
|
|
381
|
-
return (messages) => ({
|
|
382
|
-
provider: llm.provider,
|
|
383
|
-
model: llm.model,
|
|
384
|
-
...(llm.thinking === undefined ? {} : { thinking: llm.thinking }),
|
|
385
|
-
thinkingConfig: llm.thinking === undefined ? null : (model?.llm.thinking?.[llm.thinking] ?? null),
|
|
386
|
-
messages,
|
|
387
|
-
webSearch: false,
|
|
388
|
-
previewLabel: piece.key,
|
|
389
|
-
check: (value) => check(value.text),
|
|
390
|
-
});
|
|
369
|
+
const call = workLlm(deps.db, context.work.workId, llm, piece.key);
|
|
370
|
+
return (messages) => call({ messages, check: (value) => check(value.text) });
|
|
391
371
|
}
|
|
392
372
|
function imageIndex(key) {
|
|
393
373
|
return Number(key.split(":").at(-1));
|
|
394
374
|
}
|
|
395
375
|
function setupError() {
|
|
396
|
-
return new Error("
|
|
376
|
+
return new Error(internalError("a Shorts step was set up wrongly"));
|
|
397
377
|
}
|
|
@@ -6,7 +6,7 @@ import { sourceOf } from "../admission/model.js";
|
|
|
6
6
|
import { usesShorts, usesYoutubeDescription } from "../admission/rules.js";
|
|
7
7
|
import { reviewsNarration } from "../reviews/rules.js";
|
|
8
8
|
import { currentRevisionId } from "../revisions/repo.js";
|
|
9
|
-
import { getRevisionView } from "../revisions/view.js";
|
|
9
|
+
import { getRevisionView, isDonePiece, isReadyOutput } from "../revisions/view.js";
|
|
10
10
|
import { settleScheduleRunsForProject } from "../schedules/repo.js";
|
|
11
11
|
import { editNeedsTiming } from "../video/edit-settings.js";
|
|
12
12
|
import { executionPlan, executionView, savedCatalogue } from "./runtime-plan.js";
|
|
@@ -146,14 +146,9 @@ export function executionStandings(deps, projectId, derived) {
|
|
|
146
146
|
.map((entry) => {
|
|
147
147
|
const pieces = workPieces(deps.db, entry.work.workId);
|
|
148
148
|
const retained = pieces.length > 0 &&
|
|
149
|
-
pieces.every((piece) => view.outputs.some((output) => output.workKey === piece.key &&
|
|
150
|
-
output.selected &&
|
|
151
|
-
output.available &&
|
|
152
|
-
output.state === "ready") ||
|
|
149
|
+
pieces.every((piece) => view.outputs.some((output) => output.workKey === piece.key && isReadyOutput(output)) ||
|
|
153
150
|
view.pieces.some((output) => output.key === piece.key &&
|
|
154
|
-
output
|
|
155
|
-
output.available &&
|
|
156
|
-
output.piece.state === "done" &&
|
|
151
|
+
isDonePiece(output) &&
|
|
157
152
|
(output.fingerprint === piece.fingerprint ||
|
|
158
153
|
madeFrom(deps, projectId, piece.key, output.fingerprint, piece.fingerprint))));
|
|
159
154
|
// Save can bind an existing asset without granting its placeholder invocation.
|