@gentbajko/slopify 3.25.9 → 4.1.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/audio.js +1 -1
- package/dist/adapters/alignment/cache.js +4 -6
- package/dist/adapters/alignment/ctc.js +1 -2
- package/dist/adapters/alignment/lock.js +4 -3
- package/dist/adapters/alignment/multilingual.js +2 -4
- package/dist/adapters/alignment/prefetch.js +2 -1
- package/dist/adapters/alignment/runner.js +1 -1
- package/dist/adapters/alignment/worker.js +3 -2
- package/dist/adapters/explain.js +10 -12
- package/dist/adapters/ffmpeg.js +19 -1
- package/dist/adapters/host-cli/index.js +21 -4
- package/dist/adapters/host-cli/transport.js +2 -1
- package/dist/adapters/http-failure.js +53 -0
- package/dist/adapters/image/bytes.js +2 -1
- package/dist/adapters/image/codex.js +42 -9
- package/dist/adapters/image/fal.js +21 -53
- package/dist/adapters/image/google.js +33 -56
- package/dist/adapters/image/models.js +2 -2
- package/dist/adapters/image/openai.js +22 -48
- package/dist/adapters/image/reference.js +36 -0
- package/dist/adapters/image/replicate.js +21 -49
- package/dist/adapters/image/video.js +2 -1
- package/dist/adapters/interest/search-interest.js +113 -0
- package/dist/adapters/key-probes.js +54 -3
- package/dist/adapters/llm/antigravity-models.js +1 -1
- package/dist/adapters/llm/antigravity.js +11 -6
- 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 +52 -99
- package/dist/adapters/llm/claude-code.js +16 -4
- package/dist/adapters/llm/codex-limits.js +27 -68
- package/dist/adapters/llm/codex-models.js +1 -1
- package/dist/adapters/llm/codex-server-models.js +61 -109
- package/dist/adapters/llm/codex.js +12 -1
- package/dist/adapters/llm/document-workspace.js +3 -2
- package/dist/adapters/llm/image-workspace.js +3 -2
- package/dist/adapters/llm/openrouter.js +12 -48
- package/dist/adapters/llm/run-cli.js +9 -24
- 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 +21 -41
- package/dist/adapters/tts/inworld-async.js +6 -2
- package/dist/adapters/tts/inworld.js +6 -2
- package/dist/adapters/tts/openai.js +20 -50
- package/dist/adapters/tts/system.js +2 -1
- 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 +23 -14
- package/dist/catalog/schema.js +4 -1
- package/dist/catalog/store.js +39 -0
- package/dist/catalog/validate.js +5 -2
- 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 +11 -32
- package/dist/edge/http/actor.js +5 -3
- package/dist/edge/http/app.js +86 -11
- package/dist/edge/http/assistant.js +129 -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 +2 -4
- package/dist/edge/http/channel-memory.js +9 -22
- package/dist/edge/http/channels.js +14 -27
- package/dist/edge/http/checkpoints.js +39 -21
- 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 +5 -14
- package/dist/edge/http/draft-files.js +1 -3
- package/dist/edge/http/draft-problem.js +5 -10
- 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 +47 -14
- 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 +30 -26
- package/dist/edge/http/open-folder.js +5 -10
- package/dist/edge/http/outputs.js +7 -14
- package/dist/edge/http/patch-notes.js +6 -12
- package/dist/edge/http/planning.js +3 -7
- package/dist/edge/http/problem.js +2 -4
- package/dist/edge/http/project-create.js +2 -1
- package/dist/edge/http/project-templates.js +31 -19
- package/dist/edge/http/projects.js +24 -16
- package/dist/edge/http/prompts.js +9 -16
- package/dist/edge/http/pronunciations.js +1 -2
- package/dist/edge/http/providers.js +48 -34
- 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 +12 -25
- package/dist/edge/http/revision-files.js +6 -11
- package/dist/edge/http/revisions.js +14 -19
- package/dist/edge/http/run-cost.js +1 -2
- package/dist/edge/http/same-page.js +80 -0
- package/dist/edge/http/schedules.js +69 -40
- package/dist/edge/http/settings.js +27 -14
- package/dist/edge/http/social.js +283 -0
- package/dist/edge/http/staging.js +3 -5
- package/dist/edge/http/storage-files.js +5 -7
- package/dist/edge/http/storage.js +33 -25
- package/dist/edge/http/studio.js +94 -69
- package/dist/edge/http/style-preview.js +3 -6
- package/dist/edge/http/subtitles.js +3 -17
- package/dist/edge/http/template-studio.js +436 -0
- package/dist/edge/http/trash.js +11 -12
- 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 +3 -4
- 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 +29 -3
- package/dist/edge/mcp/http.js +11 -2
- package/dist/edge/mcp/instructions.js +6 -4
- package/dist/edge/mcp/library-tools.js +9 -5
- package/dist/edge/mcp/remake-tools.js +7 -4
- package/dist/edge/mcp/route-tool.js +35 -15
- package/dist/edge/mcp/server.js +13 -8
- package/dist/edge/mcp/tools-channels.js +11 -9
- package/dist/edge/mcp/tools-designs.js +165 -0
- package/dist/edge/mcp/tools-library.js +19 -7
- package/dist/edge/mcp/tools-planning.js +40 -21
- package/dist/edge/mcp/tools-projects.js +38 -11
- package/dist/edge/mcp/tools-publishing.js +9 -9
- package/dist/edge/mcp/tools-runs.js +23 -10
- package/dist/edge/mcp/tools-schedules.js +32 -8
- package/dist/edge/mcp/tools-setup.js +75 -11
- package/dist/edge/mcp/tools-social.js +47 -0
- package/dist/edge/mcp/tools-storage.js +11 -3
- 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/migrations/0078-uploaded-from-links.sql +7 -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/pipeline.js +12 -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/ports/settings-places.js +31 -0
- package/dist/kernel/ports/system-speech.js +31 -3
- package/dist/kernel/runner/attempt.js +14 -4
- 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 +18 -12
- package/dist/kernel/runner/standalone.js +11 -7
- package/dist/main.js +338 -21
- package/dist/model-catalog.js +20 -0
- package/dist/model-checks.js +166 -0
- package/dist/patch-notes/4.0.0.md +51 -0
- package/dist/patch-notes/4.1.0.md +42 -0
- package/dist/patch-notes/index.json +12 -0
- package/dist/slices/admission/heads.js +2 -1
- package/dist/slices/admission/listing-facts.js +95 -0
- package/dist/slices/admission/repo.js +11 -7
- package/dist/slices/admission/rules.js +50 -15
- 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/state-words.js +34 -5
- 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 +86 -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 +344 -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 +8 -7
- package/dist/slices/channels/cast-images.js +3 -2
- 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 +7 -1
- package/dist/slices/channels/service.js +10 -0
- package/dist/slices/channels/videos.js +3 -15
- package/dist/slices/checkpoints/index.js +0 -1
- package/dist/slices/control/providers.js +2 -28
- 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 +130 -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 +223 -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/document/model.js +7 -4
- package/dist/slices/document/render.js +2 -1
- package/dist/slices/document/theme-schema.js +1 -1
- package/dist/slices/document/theme.js +49 -3
- package/dist/slices/episodes/summarize.js +6 -2
- package/dist/slices/estimate/index.js +72 -28
- package/dist/slices/estimate/requests.js +4 -4
- package/dist/slices/fixes/rules.js +3 -1
- package/dist/slices/fonts/catalog.js +5 -3
- package/dist/slices/fonts/coverage.js +2 -1
- 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 +8 -16
- package/dist/slices/images/scenes.js +102 -28
- package/dist/slices/keywords/digest.js +85 -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 +5 -4
- package/dist/slices/library/used-by.js +25 -10
- package/dist/slices/loudness/loudnorm.js +53 -12
- package/dist/slices/loudness/model.js +3 -2
- package/dist/slices/loudness/sentence-level.js +2 -1
- 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 +125 -0
- package/dist/slices/model-checks/run.js +143 -0
- package/dist/slices/model-checks/service.js +198 -0
- package/dist/slices/model-upkeep/model.js +1 -1
- package/dist/slices/model-upkeep/switch.js +72 -27
- package/dist/slices/model-upkeep/usage.js +39 -13
- package/dist/slices/narration/breaths.js +3 -1
- package/dist/slices/narration/clean-pieces.js +3 -1
- package/dist/slices/narration/concat.js +2 -1
- package/dist/slices/narration/pauses-model.js +3 -2
- package/dist/slices/narration/peaks.js +3 -4
- package/dist/slices/narration/pronunciation-chunks.js +4 -3
- package/dist/slices/narration/pronunciation.js +6 -4
- 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 +4 -3
- package/dist/slices/onboarding/copy.js +21 -3
- package/dist/slices/onboarding/first-run.js +16 -40
- package/dist/slices/onboarding/full-video.js +3 -2
- package/dist/slices/onboarding/install.js +6 -4
- package/dist/slices/onboarding/model.js +26 -37
- package/dist/slices/onboarding/packs.js +22 -22
- package/dist/slices/onboarding/preferred-model.js +14 -0
- package/dist/slices/onboarding/quick-short.js +105 -65
- package/dist/slices/onboarding/sample.js +4 -2
- package/dist/slices/onboarding/state.js +9 -11
- package/dist/slices/onboarding/template.js +8 -6
- package/dist/slices/outputs/add.js +3 -2
- package/dist/slices/outputs/service.js +2 -2
- package/dist/slices/patch-notes/library.js +4 -3
- package/dist/slices/play-drafts/convert.js +4 -0
- package/dist/slices/play-drafts/readiness.js +3 -3
- package/dist/slices/play-drafts/review-inputs.js +9 -3
- package/dist/slices/play-drafts/review.js +5 -4
- package/dist/slices/play-drafts/schema.js +4 -0
- package/dist/slices/play-drafts/service.js +17 -7
- package/dist/slices/project-templates/from-project.js +9 -2
- package/dist/slices/project-templates/next-chapter.js +2 -1
- package/dist/slices/project-templates/provider-defaults.js +22 -0
- package/dist/slices/project-templates/repo.js +6 -1
- package/dist/slices/project-templates/setup-sections.js +26 -0
- package/dist/slices/project-templates/setup.js +14 -1
- 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 +32 -14
- 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 +4 -4
- 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 +8 -5
- 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 +102 -31
- package/dist/slices/rebuild/recipe-visual.js +55 -16
- package/dist/slices/rebuild/recipe-voices.js +3 -2
- package/dist/slices/rebuild/recipe-work.js +19 -7
- package/dist/slices/rebuild/recipe-youtube.js +4 -3
- package/dist/slices/rebuild/recovery-selection.js +3 -1
- package/dist/slices/rebuild/recovery.js +9 -8
- package/dist/slices/rebuild/remake-outdated.js +5 -5
- package/dist/slices/rebuild/repo.js +4 -3
- package/dist/slices/rebuild/review-promise.js +25 -0
- package/dist/slices/rebuild/review-redo.js +3 -2
- 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 +10 -9
- package/dist/slices/rebuild/runtime-article.js +7 -5
- package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
- package/dist/slices/rebuild/runtime-document.js +11 -13
- package/dist/slices/rebuild/runtime-export-bed.js +8 -12
- package/dist/slices/rebuild/runtime-export-edit.js +8 -16
- package/dist/slices/rebuild/runtime-export-inputs.js +12 -11
- package/dist/slices/rebuild/runtime-export-short.js +9 -5
- package/dist/slices/rebuild/runtime-export.js +38 -15
- package/dist/slices/rebuild/runtime-figure-card.js +2 -1
- package/dist/slices/rebuild/runtime-image.js +8 -12
- 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 +17 -22
- 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 +13 -17
- 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 +67 -25
- package/dist/slices/rebuild/runtime-publication.js +10 -9
- package/dist/slices/rebuild/runtime-review.js +39 -33
- package/dist/slices/rebuild/runtime-run.js +4 -1
- package/dist/slices/rebuild/runtime-shorts.js +31 -50
- package/dist/slices/rebuild/runtime-store.js +20 -10
- package/dist/slices/rebuild/runtime-subtitles.js +28 -25
- package/dist/slices/rebuild/runtime-voices.js +10 -16
- package/dist/slices/rebuild/runtime-youtube.js +14 -31
- package/dist/slices/rebuild/service-readiness.js +11 -3
- 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/research/synthesis.js +3 -2
- package/dist/slices/reviews/external-model.js +4 -1
- package/dist/slices/reviews/external-repo.js +2 -1
- package/dist/slices/reviews/external-rows.js +2 -3
- package/dist/slices/reviews/holds.js +5 -4
- package/dist/slices/reviews/model.js +32 -11
- package/dist/slices/reviews/repo.js +2 -1
- package/dist/slices/reviews/rules.js +4 -3
- package/dist/slices/reviews/verdict.js +2 -1
- package/dist/slices/reviews/view.js +5 -2
- package/dist/slices/revisions/downloads.js +4 -5
- package/dist/slices/revisions/image-plan.js +1 -1
- package/dist/slices/revisions/mutation-assets.js +9 -5
- package/dist/slices/revisions/mutation-cues.js +2 -5
- package/dist/slices/revisions/mutations.js +3 -3
- 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 +18 -7
- 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 +30 -21
- package/dist/slices/schedules/rescore.js +35 -0
- package/dist/slices/schedules/scheduler.js +13 -3
- package/dist/slices/schedules/schema.js +57 -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 +53 -41
- package/dist/slices/settings/cli-paths.js +4 -6
- package/dist/slices/settings/first-run.js +8 -43
- package/dist/slices/settings/health.js +30 -15
- package/dist/slices/settings/key-test.js +1 -1
- package/dist/slices/settings/model-reach.js +3 -17
- package/dist/slices/settings/model.js +14 -2
- package/dist/slices/settings/playback.js +34 -23
- 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/keep.js +2 -1
- package/dist/slices/shorts/pick.js +6 -18
- package/dist/slices/shorts/prompts.js +4 -14
- package/dist/slices/shorts/render.js +6 -2
- 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 +132 -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 +56 -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 +129 -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 +22 -4
- 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 +17 -12
- 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 +26 -9
- package/dist/slices/studio/calendar.js +7 -2
- package/dist/slices/studio/disclosure.js +4 -4
- package/dist/slices/studio/model.js +1 -1
- package/dist/slices/studio/pack.js +9 -8
- package/dist/slices/studio/pick.js +2 -11
- package/dist/slices/studio/plan.js +7 -16
- package/dist/slices/studio/queue.js +3 -14
- package/dist/slices/studio/releases.js +26 -0
- package/dist/slices/studio/settings.js +20 -57
- package/dist/slices/studio/videos.js +35 -4
- package/dist/slices/style-preview/render.js +37 -16
- package/dist/slices/style-preview/schema.js +14 -1
- package/dist/slices/style-preview/service.js +2 -1
- package/dist/slices/style-preview/settings.js +33 -5
- package/dist/slices/subtitles/captions.js +1 -1
- 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 +161 -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 +106 -0
- package/dist/slices/template-studio/cards.js +78 -0
- package/dist/slices/template-studio/checks.js +322 -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 +58 -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 +207 -0
- package/dist/slices/template-studio/paid-view.js +66 -0
- package/dist/slices/template-studio/paid.js +355 -0
- package/dist/slices/template-studio/quote.js +155 -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 +32 -0
- package/dist/slices/template-studio/schedule-sample.js +91 -0
- package/dist/slices/template-studio/schema.js +243 -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 +175 -0
- package/dist/slices/template-studio/status.js +191 -0
- package/dist/slices/template-studio/topic.js +223 -0
- package/dist/slices/thumbnail/by-llm.js +1 -1
- 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/uploads/repo.js +37 -1
- package/dist/slices/uploads/rules.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/edit-list.js +2 -2
- package/dist/slices/video/edit-settings.js +1 -1
- package/dist/slices/video/encoding.js +169 -0
- package/dist/slices/video/ffmpeg.js +23 -21
- package/dist/slices/video/figure-card.js +1 -15
- package/dist/slices/video/plan.js +2 -1
- package/dist/slices/video/slideshow.js +43 -18
- package/dist/slices/voices/attribution.js +3 -2
- package/dist/slices/voices/model.js +9 -8
- package/dist/slices/voices/palette.js +0 -3
- package/dist/slices/voices/script.js +2 -1
- package/dist/slices/youtube/answer.js +4 -16
- package/dist/slices/youtube/edits-repo.js +3 -12
- package/dist/tutorials/AI-CLIs.md +25 -25
- package/dist/tutorials/Agents-MCP.md +34 -33
- package/dist/tutorials/Assistant.md +42 -0
- package/dist/tutorials/Backups.md +7 -7
- package/dist/tutorials/Calendar.md +17 -25
- package/dist/tutorials/Cast-Library.md +19 -19
- package/dist/tutorials/Channels.md +42 -35
- package/dist/tutorials/Costs-and-Run-Cost.md +38 -40
- package/dist/tutorials/Create-Article.md +114 -0
- package/dist/tutorials/Create-Extras.md +112 -0
- package/dist/tutorials/Create-Images.md +165 -0
- package/dist/tutorials/Create-Narration.md +178 -0
- package/dist/tutorials/Create-Overview.md +244 -0
- package/dist/tutorials/Create-Video-and-Style.md +144 -0
- package/dist/tutorials/Docker.md +3 -3
- package/dist/tutorials/Document-Themes.md +32 -32
- package/dist/tutorials/Editing-a-Project.md +94 -94
- package/dist/tutorials/FAQ.md +18 -18
- package/dist/tutorials/First-Launch-and-Welcome.md +50 -64
- package/dist/tutorials/Home-and-Projects.md +115 -71
- package/dist/tutorials/Home.md +33 -33
- package/dist/tutorials/Install.md +14 -13
- package/dist/tutorials/Intros-and-Outros.md +33 -34
- package/dist/tutorials/Keyboard-Shortcuts-and-Command-Palette.md +62 -58
- package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
- package/dist/tutorials/Models.md +53 -21
- package/dist/tutorials/Multiple-Voices.md +41 -40
- package/dist/tutorials/Narration-Aliases-and-Glossary.md +14 -14
- package/dist/tutorials/Notifications.md +27 -17
- package/dist/tutorials/Other-Languages.md +15 -15
- package/dist/tutorials/PDF-Documents.md +38 -29
- package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
- package/dist/tutorials/Project-Page.md +118 -120
- package/dist/tutorials/Prompts-and-Templates.md +84 -0
- package/dist/tutorials/Prompts.md +48 -44
- package/dist/tutorials/Providers-and-Keys.md +105 -98
- package/dist/tutorials/Publishing-to-YouTube.md +31 -31
- package/dist/tutorials/Recovery-and-Retries.md +31 -31
- package/dist/tutorials/Remote-Access.md +63 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +98 -90
- package/dist/tutorials/Schedules.md +46 -27
- package/dist/tutorials/Settings-Reference.md +194 -174
- package/dist/tutorials/Shorts.md +34 -33
- package/dist/tutorials/Start-at-Login.md +3 -3
- package/dist/tutorials/Studio-Extension.md +22 -24
- package/dist/tutorials/Template-Studio.md +128 -0
- package/dist/tutorials/Templates.md +51 -77
- package/dist/tutorials/Trash.md +4 -4
- package/dist/tutorials/Troubleshooting.md +44 -44
- package/dist/tutorials/Uninstalling-and-Moving.md +5 -5
- package/dist/tutorials/Updating-and-Patch-Notes.md +18 -18
- package/dist/tutorials/Video-Editing.md +34 -34
- package/dist/tutorials/Where-Your-Files-Live.md +10 -10
- package/dist/tutorials/YouTube-Description.md +26 -26
- package/dist/tutorials/Your-First-Short.md +35 -35
- package/dist/tutorials/_Sidebar.md +19 -14
- package/dist/updater/work-in-progress.js +42 -12
- package/dist/web/assets/index-BNftKQrA.css +1 -0
- package/dist/web/assets/index-Cpa58woP.js +459 -0
- package/dist/web/assets/pdf-BKh8f7R6.js +56 -0
- package/dist/web/assets/pdf.worker.min-BmVo14Nb.mjs +28 -0
- package/dist/web/assets/pdf.worker.min-D7i8o3wR.js +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +6 -2
- 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/tutorials/Library-Overview.md +0 -76
- package/dist/tutorials/Play-Images.md +0 -161
- package/dist/tutorials/Play-Narration.md +0 -167
- package/dist/tutorials/Play-Outputs.md +0 -109
- package/dist/tutorials/Play-Overview.md +0 -227
- package/dist/tutorials/Play-Title-and-Article.md +0 -136
- package/dist/tutorials/Play-Video-and-Style.md +0 -143
- package/dist/web/assets/index-BadsoORk.css +0 -1
- package/dist/web/assets/index-D8LqNsCl.js +0 -326
- package/dist/web/assets/pdf-T7MCwjIv.js +0 -54
- package/dist/web/assets/pdf.worker.min-Dswkl-cV.mjs +0 -29
- package/dist/web/assets/pdf.worker.min-zC6nfbxG.js +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { statfs } from "node:fs/promises";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
// The autopilot's hourly look at what may stop the schedules: the OpenRouter key's spending
|
|
4
|
+
// limit (`GET /api/v1/key`, the same read Settings → Keys & services' Test makes) and the free disk.
|
|
5
|
+
// Read-only: neither starts paid work.
|
|
6
|
+
const keyAnswer = z.object({
|
|
7
|
+
data: z.object({ limit: z.number().nullable(), limit_remaining: z.number().nullable() }).loose(),
|
|
8
|
+
});
|
|
9
|
+
// The key's limit and what is left of it; null for a key with no limit. Throws, with the
|
|
10
|
+
// status only, when OpenRouter refuses or answers something else: the caller skips the check.
|
|
11
|
+
export async function openRouterKeyLimit(fetchImpl, key, signal) {
|
|
12
|
+
const response = await fetchImpl("https://openrouter.ai/api/v1/key", {
|
|
13
|
+
headers: { Authorization: `Bearer ${key}` },
|
|
14
|
+
signal,
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok)
|
|
17
|
+
throw new Error(`OpenRouter answered ${String(response.status)}`);
|
|
18
|
+
const parsed = keyAnswer.safeParse(await response.json());
|
|
19
|
+
if (!parsed.success)
|
|
20
|
+
throw new Error("OpenRouter's answer wasn't the key's limits");
|
|
21
|
+
const { limit, limit_remaining: remaining } = parsed.data.data;
|
|
22
|
+
return limit === null || remaining === null ? null : { limit, remaining };
|
|
23
|
+
}
|
|
24
|
+
export async function diskSpaceAt(path) {
|
|
25
|
+
const stats = await statfs(path);
|
|
26
|
+
return {
|
|
27
|
+
freeBytes: Number(stats.bavail) * Number(stats.bsize),
|
|
28
|
+
totalBytes: Number(stats.blocks) * Number(stats.bsize),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -33,7 +33,7 @@ export async function decodeAudio(ffmpeg, source, output, signal) {
|
|
|
33
33
|
child.on("close", (code) => {
|
|
34
34
|
signal.removeEventListener("abort", abort);
|
|
35
35
|
if (signal.aborted)
|
|
36
|
-
reject(new Error("
|
|
36
|
+
reject(new Error("Caption audio preparation was canceled."));
|
|
37
37
|
else if (code !== 0)
|
|
38
38
|
reject(new Error(`Could not prepare the narration for subtitles. ${errorText}`));
|
|
39
39
|
else
|
|
@@ -5,6 +5,7 @@ import { join } from "node:path";
|
|
|
5
5
|
import { Readable } from "node:stream";
|
|
6
6
|
import { pipeline } from "node:stream/promises";
|
|
7
7
|
import { setTimeout as delay } from "node:timers/promises";
|
|
8
|
+
import { hasErrnoCode } from "../../kernel/errors.js";
|
|
8
9
|
import { defaultEnglishSubtitleModel, } from "../../kernel/ports/subtitles.js";
|
|
9
10
|
// Xenova/wav2vec2-base-960h at one pinned revision, which carries the same model at three
|
|
10
11
|
// precisions. Each keeps its own file name so the cache can hold any of them at once; int8
|
|
@@ -144,7 +145,7 @@ async function downloadModel(input, deps, target) {
|
|
|
144
145
|
catch (error) {
|
|
145
146
|
if (await verified(target, deps.model, input.signal))
|
|
146
147
|
return target;
|
|
147
|
-
if (!
|
|
148
|
+
if (!hasErrnoCode(error, "EEXIST") && !hasErrnoCode(error, "EPERM"))
|
|
148
149
|
throw error;
|
|
149
150
|
await rm(target, { force: true });
|
|
150
151
|
await rename(part, target);
|
|
@@ -169,7 +170,7 @@ async function seedModel(input, seed, target) {
|
|
|
169
170
|
await rm(staging, { recursive: true, force: true });
|
|
170
171
|
}
|
|
171
172
|
}
|
|
172
|
-
const smaller = " To download less, pick a smaller model in Settings → Production defaults →
|
|
173
|
+
const smaller = " To download less, pick a smaller model in Settings → Production defaults → Caption timing model.";
|
|
173
174
|
function megabytes(bytes) {
|
|
174
175
|
return `${String(Math.round(bytes / 1_000_000))} MB`;
|
|
175
176
|
}
|
|
@@ -187,11 +188,8 @@ async function verified(path, model, signal) {
|
|
|
187
188
|
return hash.digest("hex") === model.sha256;
|
|
188
189
|
}
|
|
189
190
|
catch (error) {
|
|
190
|
-
if (
|
|
191
|
+
if (hasErrnoCode(error, "ENOENT"))
|
|
191
192
|
return false;
|
|
192
193
|
throw error;
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
|
-
function isCode(error, code) {
|
|
196
|
-
return error instanceof Error && "code" in error && error.code === code;
|
|
197
|
-
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { englishSpec } from "./spec.js";
|
|
2
2
|
export const frameSeconds = 0.02;
|
|
3
|
-
export const mismatch = englishMismatch;
|
|
4
3
|
export function alignWindow(logits, frames, words, complete, spec = englishSpec) {
|
|
5
4
|
const labels = spec.labels;
|
|
6
5
|
if (frames < 1 || frames > 1100 || logits.length !== frames * labels)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { open, readFile, rm, stat } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { setTimeout } from "node:timers/promises";
|
|
4
|
+
import { hasErrnoCode } from "../../kernel/errors.js";
|
|
4
5
|
// Models run one at a time per data directory, including requests from separate app
|
|
5
6
|
// processes. A canceled waiter never removes another request's lock.
|
|
6
7
|
export async function claimWorker(cacheDir, signal) {
|
|
@@ -26,7 +27,7 @@ export async function claimWorker(cacheDir, signal) {
|
|
|
26
27
|
};
|
|
27
28
|
}
|
|
28
29
|
catch (error) {
|
|
29
|
-
if (!(error
|
|
30
|
+
if (!hasErrnoCode(error, "EEXIST"))
|
|
30
31
|
throw error;
|
|
31
32
|
}
|
|
32
33
|
try {
|
|
@@ -41,7 +42,7 @@ export async function claimWorker(cacheDir, signal) {
|
|
|
41
42
|
process.kill(owner, 0);
|
|
42
43
|
}
|
|
43
44
|
catch (error) {
|
|
44
|
-
if (error
|
|
45
|
+
if (hasErrnoCode(error, "ESRCH")) {
|
|
45
46
|
await rm(path, { force: true });
|
|
46
47
|
continue;
|
|
47
48
|
}
|
|
@@ -50,7 +51,7 @@ export async function claimWorker(cacheDir, signal) {
|
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
catch (error) {
|
|
53
|
-
if (!(error
|
|
54
|
+
if (!hasErrnoCode(error, "ENOENT"))
|
|
54
55
|
throw error;
|
|
55
56
|
}
|
|
56
57
|
await setTimeout(250, undefined, { signal });
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { languageInfo } from "../../kernel/ports/languages.js";
|
|
2
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
2
3
|
import { englishSpec } from "./spec.js";
|
|
3
4
|
import { spellers, spokenNumber } from "./spell.js";
|
|
4
5
|
import { respoken, speechWords } from "./text.js";
|
|
@@ -121,9 +122,6 @@ export const multilingualGates = {
|
|
|
121
122
|
anchorLetters: 20,
|
|
122
123
|
anchorConfidence: 0.75,
|
|
123
124
|
};
|
|
124
|
-
export function multilingualLanguages() {
|
|
125
|
-
return Object.keys(alphabets);
|
|
126
|
-
}
|
|
127
125
|
// The model and language view the aligner uses for a project language. English keeps its own
|
|
128
126
|
// model and every constant it had.
|
|
129
127
|
export function alignmentSpecFor(language) {
|
|
@@ -242,7 +240,7 @@ function spell(text, alphabet, raw, language) {
|
|
|
242
240
|
}
|
|
243
241
|
const folded = fold(character);
|
|
244
242
|
if (folded === undefined)
|
|
245
|
-
throw new Error(`Word timing for ${languageInfo(language).name} reads Latin letters only, and "${raw}" has letters from another alphabet. Write that word in Latin letters in the article (
|
|
243
|
+
throw new Error(`Word timing for ${languageInfo(language).name} reads Latin letters only, and "${raw}" has letters from another alphabet. Write that word in Latin letters in the article (${editSettings.article}), then Try again.`);
|
|
246
244
|
result += folded;
|
|
247
245
|
}
|
|
248
246
|
return result.replace(/\s+/g, " ").trim();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdir, readFile, rm } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { hasErrnoCode } from "../../kernel/errors.js";
|
|
3
4
|
import { defaultEnglishSubtitleModel, } from "../../kernel/ports/subtitles.js";
|
|
4
5
|
import { englishModels, prepareModel } from "./cache.js";
|
|
5
6
|
import { claimWorker } from "./lock.js";
|
|
@@ -31,7 +32,7 @@ async function clearOwnLock(cacheDir) {
|
|
|
31
32
|
owner = await readFile(path, "utf8");
|
|
32
33
|
}
|
|
33
34
|
catch (error) {
|
|
34
|
-
if (error
|
|
35
|
+
if (hasErrnoCode(error, "ENOENT"))
|
|
35
36
|
return;
|
|
36
37
|
throw error;
|
|
37
38
|
}
|
|
@@ -24,7 +24,7 @@ export async function runAlignmentWorker(input, signal, onProgress, worker = new
|
|
|
24
24
|
signal.removeEventListener("abort", abort);
|
|
25
25
|
child.kill("SIGKILL");
|
|
26
26
|
};
|
|
27
|
-
const abort = () => finish(new Error("
|
|
27
|
+
const abort = () => finish(new Error("Caption timing was canceled."));
|
|
28
28
|
signal.addEventListener("abort", abort, { once: true });
|
|
29
29
|
child.stderr?.on("data", (data) => {
|
|
30
30
|
stderr = (stderr + data.toString("utf8")).slice(-2000);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { open, readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { errorText } from "../../kernel/errors.js";
|
|
2
3
|
import { SubtitleMismatch } from "../../kernel/ports/subtitles.js";
|
|
3
4
|
import { alignmentSpecFor } from "./multilingual.js";
|
|
4
5
|
import { workerInput } from "./protocol.js";
|
|
@@ -15,7 +16,7 @@ process.once("message", (raw) => {
|
|
|
15
16
|
}
|
|
16
17
|
run(input.data).then((words) => send({ type: "done", words }), (error) => send({
|
|
17
18
|
type: "error",
|
|
18
|
-
message:
|
|
19
|
+
message: errorText(error),
|
|
19
20
|
...(error instanceof SubtitleMismatch
|
|
20
21
|
? { mismatch: { at: error.at, expected: error.expected, heard: error.heard } }
|
|
21
22
|
: {}),
|
|
@@ -167,7 +168,7 @@ async function openSession(modelPath) {
|
|
|
167
168
|
const reason = nativeError instanceof Error
|
|
168
169
|
? (nativeError.message.split("\n")[0] ?? "")
|
|
169
170
|
: String(nativeError);
|
|
170
|
-
throw new Error(`
|
|
171
|
+
throw new Error(`Caption timing could not start: neither of its speech engines loaded on this computer (${system}): ${reason}. Reinstall Slopify so npm installs the engine for this system, then try again; if it keeps failing, turn captions off for this project.`);
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
174
|
const session = await native.InferenceSession.create(modelPath, {
|
package/dist/adapters/explain.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { editSettings } from "../kernel/ports/settings-places.js";
|
|
1
2
|
// The sentences a failed provider call shows. Whatever an adapter throws becomes the stage's
|
|
2
3
|
// failure reason on the project page, read by someone who only wants the video, so each one
|
|
3
4
|
// says what failed, the likely cause and the next step, using the names on screen. The
|
|
@@ -6,19 +7,19 @@
|
|
|
6
7
|
// A provider's error body can be a whole HTML page; the first few hundred characters say why.
|
|
7
8
|
const detailMax = 300;
|
|
8
9
|
export function missingKey(provider) {
|
|
9
|
-
return `No ${provider} API key is saved. Add one in Settings →
|
|
10
|
+
return `No ${provider} API key is saved. Add one in Settings → Keys & services, then use Try again.`;
|
|
10
11
|
}
|
|
11
12
|
export const refreshList = "refresh the list";
|
|
12
|
-
export const checkChoice =
|
|
13
|
+
export const checkChoice = `Check the service and model chosen in ${editSettings.open} (under Written by in Article, in Narration or in Images), then use Try again.`;
|
|
13
14
|
export function httpFailure(failure) {
|
|
14
15
|
const { provider, status } = failure;
|
|
15
16
|
const said = quoted(failure.label ?? `error ${String(status)}`, failure.detail);
|
|
16
17
|
const next = failure.next ?? "use Try again";
|
|
17
18
|
if (status === 401) {
|
|
18
|
-
return `${provider} did not accept the API key${said}. The key may be wrong, expired or revoked: paste a current key in Settings →
|
|
19
|
+
return `${provider} did not accept the API key${said}. The key may be wrong, expired or revoked: paste a current key in Settings → Keys & services, then ${next}.`;
|
|
19
20
|
}
|
|
20
21
|
if (status === 403) {
|
|
21
|
-
return `${provider} refused access${said}. The API key may not be allowed to use this model, or the account needs attention: check your ${provider} account and the key in Settings →
|
|
22
|
+
return `${provider} refused access${said}. The API key may not be allowed to use this model, or the account needs attention: check your ${provider} account and the key in Settings → Keys & services, then ${next}.`;
|
|
22
23
|
}
|
|
23
24
|
if (status === 402) {
|
|
24
25
|
return `${provider} says the account is out of credits${said}. Add credits on the ${provider} website, then ${next}.`;
|
|
@@ -27,7 +28,7 @@ export function httpFailure(failure) {
|
|
|
27
28
|
return `${provider} is limiting requests${said}. Too many requests were sent at once or the plan's quota is used up: wait a few minutes or check your ${provider} usage and billing, then ${next}.`;
|
|
28
29
|
}
|
|
29
30
|
if (status >= 400 && status < 500) {
|
|
30
|
-
return `${provider} rejected the ${failure.subject ?? "request"}${said}. ${failure.fix ?? (failure.next === undefined ? checkChoice : `Check the key in Settings →
|
|
31
|
+
return `${provider} rejected the ${failure.subject ?? "request"}${said}. ${failure.fix ?? (failure.next === undefined ? checkChoice : `Check the key in Settings → Keys & services, then ${next}.`)}`;
|
|
31
32
|
}
|
|
32
33
|
if (status >= 500) {
|
|
33
34
|
return `${provider} had a problem on its side${said}. This is usually temporary: wait a few minutes, then ${next}.`;
|
|
@@ -48,18 +49,15 @@ export function noAudio(provider) {
|
|
|
48
49
|
return `${provider} finished without sending any audio. Use Try again; if it keeps happening, check the voice in Settings → Voices.`;
|
|
49
50
|
}
|
|
50
51
|
export function noImage(provider) {
|
|
51
|
-
return `${provider} finished without sending an image. Use Try again; if it keeps happening, reword the image prompt in
|
|
52
|
+
return `${provider} finished without sending an image. Use Try again; if it keeps happening, reword the image prompt in ${editSettings.images} or choose another image model there.`;
|
|
52
53
|
}
|
|
53
54
|
export function refusedImage(provider, detail) {
|
|
54
|
-
return `${provider} refused to make this image under its content rules${quoted("", detail)}. Reword the image prompt in
|
|
55
|
+
return `${provider} refused to make this image under its content rules${quoted("", detail)}. Reword the image prompt in ${editSettings.images}, or choose another image service there.`;
|
|
55
56
|
}
|
|
56
57
|
// A narration request the provider turned down is most often a voice that no longer exists
|
|
57
58
|
// or a part longer than the model takes.
|
|
58
59
|
export function voiceFix(voiceId) {
|
|
59
|
-
return `Check that voice "${voiceId}" still exists in Settings → Voices and that each narration part fits the model's length limit (Chunking, in
|
|
60
|
-
}
|
|
61
|
-
export function internalError(what) {
|
|
62
|
-
return `Slopify hit an internal error (${what}). Use Try again; if it happens again, use Download diagnostics in Settings and report it.`;
|
|
60
|
+
return `Check that voice "${voiceId}" still exists in Settings → Voices and that each narration part fits the model's length limit (Chunking, in ${editSettings.narration}), then use Try again.`;
|
|
63
61
|
}
|
|
64
62
|
const cliNames = {
|
|
65
63
|
claude: "Claude Code CLI",
|
|
@@ -82,7 +80,7 @@ export function cliReported(binary, detail, next) {
|
|
|
82
80
|
return `The ${cliName(binary)} reported an error${quoted("", detail)}. ${next}`;
|
|
83
81
|
}
|
|
84
82
|
export function cliCheck(binary) {
|
|
85
|
-
return `Use Try again; if it keeps failing, run ${commandOf(binary)} in a terminal to check it works and is signed in, or choose another model in
|
|
83
|
+
return `Use Try again; if it keeps failing, run ${commandOf(binary)} in a terminal to check it works and is signed in, or choose another model in ${editSettings.writer}.`;
|
|
86
84
|
}
|
|
87
85
|
// ` (error 401: "Unauthorized")`, ` (error 401)`, ` ("Unauthorized")`, or nothing.
|
|
88
86
|
export function quoted(label, detail) {
|
package/dist/adapters/ffmpeg.js
CHANGED
|
@@ -4,6 +4,7 @@ import { createRequire } from "node:module";
|
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { errorText } from "../kernel/errors.js";
|
|
7
8
|
import { redact } from "../kernel/log.js";
|
|
8
9
|
// ffmpeg-static exports a path even when npm skipped its install script. Recover using
|
|
9
10
|
// that dependency's own downloader, including its source notice and license, without
|
|
@@ -73,6 +74,23 @@ async function verify(bin) {
|
|
|
73
74
|
throw new Error(`ffmpeg at ${bin} could not be started. Reinstall ffmpeg or check your antivirus has not quarantined it, then restart Slopify. ${remedy} ${detail(error)}`);
|
|
74
75
|
}
|
|
75
76
|
}
|
|
77
|
+
// One short ffmpeg run to its end, answering its stdout; a failure carries the last thing it
|
|
78
|
+
// said on stderr. For questions about an ffmpeg (its encoders, a test encode), never renders.
|
|
79
|
+
export async function ffmpegOutput(bin, args) {
|
|
80
|
+
try {
|
|
81
|
+
const { stdout } = await promisify(execFile)(bin, [...args], {
|
|
82
|
+
windowsHide: true,
|
|
83
|
+
timeout: 30_000,
|
|
84
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
85
|
+
});
|
|
86
|
+
return stdout;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const stderr = z.object({ stderr: z.string() }).safeParse(error);
|
|
90
|
+
const said = stderr.success ? stderr.data.stderr.trim().split("\n").slice(-2).join(" / ") : "";
|
|
91
|
+
throw new Error(said === "" ? detail(error) : redact(said));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
76
94
|
function detail(error) {
|
|
77
|
-
return redact(
|
|
95
|
+
return redact(errorText(error));
|
|
78
96
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { redact } from "../../kernel/log.js";
|
|
2
2
|
import { bridgeLimits, decodeHostImageReport, hostFaultSchema, hostFrameSchema, hostHealthSchema, hostImageReportHeader, hostImageSchema, hostLlmSchema, hostModelsSchema, hostOpenedSchema, hostOpenFolderSchema, hostStatusSchema, } from "../../kernel/ports/host-cli.js";
|
|
3
3
|
import { agentImageTimeoutMs } from "../../kernel/ports/image.js";
|
|
4
|
-
import { isProviderError, providerError } from "../../kernel/ports/model.js";
|
|
4
|
+
import { isProviderError, providerError, } from "../../kernel/ports/model.js";
|
|
5
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
5
6
|
import { sniffImage } from "../image/bytes.js";
|
|
6
7
|
import { claudePlanLimit } from "../llm/claude-code.js";
|
|
7
8
|
import { codexPlanLimit } from "../llm/codex-limits.js";
|
|
9
|
+
import { accessField } from "../model-access.js";
|
|
8
10
|
import { hostRequest, hostUnavailable, readHostBytes, } from "./transport.js";
|
|
9
|
-
const tooBigForHost =
|
|
11
|
+
const tooBigForHost = `Slopify could not send this request to the host helper because it is larger than, or shaped differently from, what the helper accepts. Make the article or its research notes shorter in ${editSettings.article}, then use Try again; if it happens again, use Download diagnostics in Settings and report it.`;
|
|
10
12
|
export function createHostCliClient(options) {
|
|
11
13
|
async function request(input) {
|
|
12
14
|
if (!options.directory)
|
|
@@ -16,7 +18,7 @@ export function createHostCliClient(options) {
|
|
|
16
18
|
try {
|
|
17
19
|
const parsed = hostFaultSchema.safeParse(JSON.parse((await readHostBytes(response, bridgeLimits.status)).toString("utf8")));
|
|
18
20
|
if (parsed.success)
|
|
19
|
-
throw
|
|
21
|
+
throw bridgedFault(parsed.data.kind, parsed.data.message);
|
|
20
22
|
}
|
|
21
23
|
catch (error) {
|
|
22
24
|
if (isProviderError(error))
|
|
@@ -163,6 +165,16 @@ export function createHostCliClient(options) {
|
|
|
163
165
|
base64: Buffer.from(req.reference.bytes).toString("base64"),
|
|
164
166
|
},
|
|
165
167
|
}),
|
|
168
|
+
...(req.edit === undefined
|
|
169
|
+
? {}
|
|
170
|
+
: {
|
|
171
|
+
edit: {
|
|
172
|
+
source: {
|
|
173
|
+
mime: req.edit.source.mime,
|
|
174
|
+
base64: Buffer.from(req.edit.source.bytes).toString("base64"),
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
166
178
|
...(req.cast === undefined
|
|
167
179
|
? {}
|
|
168
180
|
: {
|
|
@@ -216,6 +228,11 @@ export function createHostCliClient(options) {
|
|
|
216
228
|
},
|
|
217
229
|
};
|
|
218
230
|
}
|
|
231
|
+
// A fault from the host helper carries its kind and the host adapter's words only; whether it
|
|
232
|
+
// was about the model's access is read again from those words, as the plan limit is below.
|
|
233
|
+
export function bridgedFault(kind, message) {
|
|
234
|
+
return providerError({ kind, message: redact(message), ...accessField(null, message) });
|
|
235
|
+
}
|
|
219
236
|
// A used-up plan crosses the bridge as a rate-limit fault carrying the CLI's own words, which
|
|
220
237
|
// the host-side adapter already quoted; they are read again here so a Docker run waits for the
|
|
221
238
|
// reset like a local one instead of failing.
|
|
@@ -256,7 +273,7 @@ async function* readEvents(response) {
|
|
|
256
273
|
throw hostUnavailable(true);
|
|
257
274
|
const event = hostFrameSchema.parse(JSON.parse(line));
|
|
258
275
|
if (event.type === "error")
|
|
259
|
-
throw
|
|
276
|
+
throw bridgedFault(event.kind, event.message);
|
|
260
277
|
if (event.type === "done")
|
|
261
278
|
terminal = event;
|
|
262
279
|
else
|
|
@@ -5,6 +5,7 @@ import { join } from "node:path";
|
|
|
5
5
|
import { bridgeLimits, hostFramesHeader, hostFramesVersion } from "../../kernel/ports/host-cli.js";
|
|
6
6
|
import { agentImageTimeoutMs } from "../../kernel/ports/image.js";
|
|
7
7
|
import { providerError } from "../../kernel/ports/model.js";
|
|
8
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
8
9
|
export function hostUnavailable(submitted = false) {
|
|
9
10
|
return providerError({
|
|
10
11
|
kind: "unavailable",
|
|
@@ -34,7 +35,7 @@ export async function hostRequest(options) {
|
|
|
34
35
|
if (options.body && options.body.byteLength > bridgeLimits.request)
|
|
35
36
|
throw providerError({
|
|
36
37
|
kind: "unsupported",
|
|
37
|
-
message:
|
|
38
|
+
message: `This request is larger than the host helper accepts (16 MB), so nothing was sent. Make the article or its research notes shorter in ${editSettings.article}, or choose an API service such as OpenRouter under Written by there, then use Try again.`,
|
|
38
39
|
});
|
|
39
40
|
let token;
|
|
40
41
|
try {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { providerError } from "../kernel/ports/model.js";
|
|
2
|
+
import { missingKey } from "./explain.js";
|
|
3
|
+
import { retryAfter } from "./retry-after.js";
|
|
4
|
+
// The plumbing every HTTP provider adapter repeats around a failed call. What the provider
|
|
5
|
+
// said and which sentence it earns stay in each adapter; only the shape is shared.
|
|
6
|
+
export function safeJson(text) {
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(text);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// The body of a failed response, or nothing when it cannot be read.
|
|
15
|
+
export async function failureText(response) {
|
|
16
|
+
return await response.text().catch(() => "");
|
|
17
|
+
}
|
|
18
|
+
// Only the adapter sees the vendor's status code, so only the adapter names the kind.
|
|
19
|
+
export function kindOfStatus(status) {
|
|
20
|
+
if (status === 401 || status === 403) {
|
|
21
|
+
return "auth";
|
|
22
|
+
}
|
|
23
|
+
if (status === 429) {
|
|
24
|
+
return "rate_limit";
|
|
25
|
+
}
|
|
26
|
+
// ceiling: everything else is `other` and is retried, so a request the provider will never
|
|
27
|
+
// accept fails the same way four times over. A terminal "this will never work" kind has to
|
|
28
|
+
// reach the port's error contract first, which is not an adapter's to widen.
|
|
29
|
+
// The provider's own server failed; the same request may well succeed later.
|
|
30
|
+
if (status >= 500)
|
|
31
|
+
return "dropped";
|
|
32
|
+
return "other";
|
|
33
|
+
}
|
|
34
|
+
// `missing_key`, not `auth`, because that rule makes it terminal: an absent key never becomes
|
|
35
|
+
// a request.
|
|
36
|
+
export function requireKey(key, provider) {
|
|
37
|
+
if (key === undefined || key === "") {
|
|
38
|
+
throw providerError({ kind: "missing_key", message: missingKey(provider) });
|
|
39
|
+
}
|
|
40
|
+
return key;
|
|
41
|
+
}
|
|
42
|
+
// A 429's Retry-After replaces the fixed backoff; `fallbackRetryMs` is the provider's own
|
|
43
|
+
// hint, used when the header is absent. `access` is what the failure says about the chosen
|
|
44
|
+
// model (see model-access.ts); it never changes the kind.
|
|
45
|
+
export function httpProviderError(response, kind, message, fallbackRetryMs, access) {
|
|
46
|
+
const retryAfterMs = retryAfter(response.headers.get("retry-after")) ?? fallbackRetryMs;
|
|
47
|
+
return providerError({
|
|
48
|
+
kind,
|
|
49
|
+
message,
|
|
50
|
+
...(access === undefined ? {} : { access }),
|
|
51
|
+
...(retryAfterMs === undefined ? {} : { retryAfterMs }),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { providerError } from "../../kernel/ports/model.js";
|
|
2
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
2
3
|
// Two of the three image providers answer with a link rather than with bytes, so fetching
|
|
3
4
|
// that link is part of the provider call and belongs inside the attempt with it: a URL
|
|
4
5
|
// that 404s or hands back an HTML error page is a failed attempt, not a corrupt file on
|
|
@@ -48,7 +49,7 @@ export async function downloadImage(download) {
|
|
|
48
49
|
if (mime === undefined) {
|
|
49
50
|
throw providerError({
|
|
50
51
|
kind: "other",
|
|
51
|
-
message: `${download.provider} sent back something that is not a PNG or JPEG image (${describeBytes(bytes)}). Use Try again; if it keeps happening, choose another image model in
|
|
52
|
+
message: `${download.provider} sent back something that is not a PNG or JPEG image (${describeBytes(bytes)}). Use Try again; if it keeps happening, choose another image model in ${editSettings.images}.`,
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
55
|
return { bytes, mime };
|
|
@@ -5,14 +5,16 @@ import { z } from "zod";
|
|
|
5
5
|
import { redact } from "../../kernel/log.js";
|
|
6
6
|
import { agentImageTimeoutMs, } from "../../kernel/ports/image.js";
|
|
7
7
|
import { providerError } from "../../kernel/ports/model.js";
|
|
8
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
8
9
|
import { cliReported, quoted, refusedImage } from "../explain.js";
|
|
9
10
|
import { cliLoginError } from "../llm/cli-login-error.js";
|
|
10
11
|
import { codexLimitError, readingOf } from "../llm/codex.js";
|
|
11
12
|
import { codexPlanLimit } from "../llm/codex-limits.js";
|
|
12
13
|
import { cliEvent, cliShaped, endedKind, endedWithout, stopCliRun, } from "../llm/run-cli.js";
|
|
13
14
|
import { lines } from "../llm/sse-lines.js";
|
|
15
|
+
import { accessField } from "../model-access.js";
|
|
14
16
|
import { codexGeneratedImage, codexImageCount } from "./codex-output.js";
|
|
15
|
-
import {
|
|
17
|
+
import { attachedPictures, editNote } from "./reference.js";
|
|
16
18
|
// "Codex default" puts no model and no effort on the command line, so the CLI's own defaults
|
|
17
19
|
// draw the image; it is what every project saved before the choice existed runs. Every other
|
|
18
20
|
// model id is one of the Codex CLI's own models - the list the Codex text provider shows -
|
|
@@ -46,7 +48,7 @@ const alwaysDisabled = [
|
|
|
46
48
|
function reviews(req) {
|
|
47
49
|
return (req.model !== codexImageModel.id ||
|
|
48
50
|
req.thinking !== undefined ||
|
|
49
|
-
|
|
51
|
+
attachedPictures(req).length > 0);
|
|
50
52
|
}
|
|
51
53
|
// The binary's image tool (`ImagegenArgs`: prompt, referenced_image_paths,
|
|
52
54
|
// num_last_images_to_include) takes each referenced image as an absolute path it reads
|
|
@@ -57,10 +59,12 @@ export function codexReferencePath(directory, image) {
|
|
|
57
59
|
// Every picture the request carries, each at its own path: the establishing image keeps the
|
|
58
60
|
// name it always had, the cast pictures follow it as reference-2, reference-3 and so on.
|
|
59
61
|
export function codexReferencePaths(directory, req) {
|
|
60
|
-
return
|
|
62
|
+
return attachedPictures(req).map((picture, index) => ({
|
|
61
63
|
picture,
|
|
62
64
|
path: index === 0
|
|
63
|
-
?
|
|
65
|
+
? req.edit === undefined
|
|
66
|
+
? codexReferencePath(directory, picture.image)
|
|
67
|
+
: join(directory, picture.image.mime === "image/jpeg" ? "source.jpg" : "source.png")
|
|
64
68
|
: join(directory, `reference-${String(index + 1)}${picture.image.mime === "image/jpeg" ? ".jpg" : ".png"}`),
|
|
65
69
|
}));
|
|
66
70
|
}
|
|
@@ -78,7 +82,34 @@ function describeMember(req, name) {
|
|
|
78
82
|
const description = req.cast?.find((member) => member.name === name)?.description.trim() ?? "";
|
|
79
83
|
return description === "" ? "" : ` (${description})`;
|
|
80
84
|
}
|
|
85
|
+
// An edit's instructions: the first path is the picture to change, the rest are the cast.
|
|
86
|
+
function editInstructions(req, directory) {
|
|
87
|
+
const paths = codexReferencePaths(directory, req);
|
|
88
|
+
return [
|
|
89
|
+
`The picture to change is saved at ${paths[0]?.path ?? directory}. Pass it first in referenced_image_paths on every image generation call${paths.length > 1
|
|
90
|
+
? `, followed by: ${paths
|
|
91
|
+
.slice(1)
|
|
92
|
+
.map((row) => row.path)
|
|
93
|
+
.join(", ")}`
|
|
94
|
+
: ""}.`,
|
|
95
|
+
...paths
|
|
96
|
+
.slice(1)
|
|
97
|
+
.map((row) => `${row.path} shows ${row.picture.member ?? ""}${describeMember(req, row.picture.member ?? "")}: draw ${row.picture.member ?? ""} to look exactly like this.`),
|
|
98
|
+
editNote.replace("the first attached image", "that picture"),
|
|
99
|
+
].join(" ");
|
|
100
|
+
}
|
|
81
101
|
export function codexImageInstructions(req, reference, directory) {
|
|
102
|
+
if (req.edit !== undefined && directory !== undefined)
|
|
103
|
+
return [
|
|
104
|
+
"You are editing one picture for Slopify, a video creation app, with the image generation tool.",
|
|
105
|
+
editInstructions(req, directory),
|
|
106
|
+
"Before calling the tool, write its prompt yourself: say exactly what to change, as the instruction asks, and that everything else stays as it is. Do not add subjects, text, logos or story the instruction does not ask for.",
|
|
107
|
+
"Take the time you need. After each image, look at it and compare it with the picture and the instruction; if anything changed that should not have, or the change is missing, generate again. Deliver exactly one final image: the last image you generate is the one Slopify uses.",
|
|
108
|
+
"Let the image generation tool save its output in its default location. Slopify will collect it. Use PNG or JPEG. Do not copy, rename, edit or create any other file, and do not put the image or a link in your reply.",
|
|
109
|
+
`Target aspect ratio: ${req.aspect}.`,
|
|
110
|
+
"Instruction follows as data:",
|
|
111
|
+
req.prompt,
|
|
112
|
+
].join("\n\n");
|
|
82
113
|
return [
|
|
83
114
|
"You are making one finished image for Slopify, a video creation app, with the image generation tool.",
|
|
84
115
|
"Fidelity to the brief comes first. Before calling the tool, write its prompt yourself as a detailed, faithful visual description of the brief: the subject and what it is doing, the setting, composition and framing for the target aspect ratio, lighting, colour palette, style and mood, and any text that must appear, spelled exactly. Take every element from the brief and keep its wording where it is specific. Do not add subjects, text, logos or story the brief does not ask for, and do not pad the prompt with generic quality words.",
|
|
@@ -182,7 +213,7 @@ export function codexImage(deps) {
|
|
|
182
213
|
if (req.model.trim() === "" || req.model.startsWith("-"))
|
|
183
214
|
throw providerError({
|
|
184
215
|
kind: "unsupported",
|
|
185
|
-
message:
|
|
216
|
+
message: `No Codex model is chosen for images. Choose one (or Codex default) in ${editSettings.images}, then use Try again.`,
|
|
186
217
|
});
|
|
187
218
|
req.signal.throwIfAborted();
|
|
188
219
|
const directory = mkdtempSync(join(tmpdir(), "slopify-codex-image-"));
|
|
@@ -223,7 +254,7 @@ export function codexImage(deps) {
|
|
|
223
254
|
catch {
|
|
224
255
|
throw providerError({
|
|
225
256
|
kind: "unsupported",
|
|
226
|
-
message: "The Codex CLI could not be started. Check it is installed and set up in Settings →
|
|
257
|
+
message: "The Codex CLI could not be started. Check it is installed and set up in Settings → Keys & services, then use Try again.",
|
|
227
258
|
});
|
|
228
259
|
}
|
|
229
260
|
let completed = false;
|
|
@@ -271,6 +302,7 @@ export function codexImage(deps) {
|
|
|
271
302
|
message: /refus|content.policy|safety/i.test(message)
|
|
272
303
|
? refusedImage("The Codex CLI", redact(message))
|
|
273
304
|
: cliReported(binary, redact(message), imageNext),
|
|
305
|
+
...(/refus|content.policy|safety/i.test(message) ? {} : accessField(null, message)),
|
|
274
306
|
});
|
|
275
307
|
}
|
|
276
308
|
else if (event.type === "error") {
|
|
@@ -288,6 +320,7 @@ export function codexImage(deps) {
|
|
|
288
320
|
message: /image.generation|image tool|feature.*unavailable/i.test(message)
|
|
289
321
|
? `The Codex CLI cannot make images${quoted("", redact(message))}. ${cannotDraw}`
|
|
290
322
|
: cliReported(binary, redact(message), imageNext),
|
|
323
|
+
...accessField(null, message),
|
|
291
324
|
});
|
|
292
325
|
}
|
|
293
326
|
else if (event.type === "item.completed") {
|
|
@@ -305,7 +338,7 @@ export function codexImage(deps) {
|
|
|
305
338
|
if (ended.error !== null)
|
|
306
339
|
throw providerError({
|
|
307
340
|
kind: "unsupported",
|
|
308
|
-
message: "The Codex CLI could not be started. Check it is installed and set up in Settings →
|
|
341
|
+
message: "The Codex CLI could not be started. Check it is installed and set up in Settings → Keys & services, then use Try again.",
|
|
309
342
|
});
|
|
310
343
|
const stderrLimit = codexPlanLimit(run.stderr(), new Date());
|
|
311
344
|
if ((ended.code !== 0 || !completed) && stderrLimit !== undefined)
|
|
@@ -365,8 +398,8 @@ async function* bounded(source, maximum) {
|
|
|
365
398
|
yield chunk;
|
|
366
399
|
}
|
|
367
400
|
}
|
|
368
|
-
const imageNext =
|
|
369
|
-
const cannotDraw =
|
|
401
|
+
const imageNext = `Use Try again; if it keeps failing, run codex in a terminal to check it works and is signed in, or choose another image service in ${editSettings.images}.`;
|
|
402
|
+
const cannotDraw = `Update the Codex CLI and check your ChatGPT plan includes image generation, or choose another image service in ${editSettings.images}.`;
|
|
370
403
|
function imageEnvironment(directory, source) {
|
|
371
404
|
const env = { PWD: directory };
|
|
372
405
|
const allowed = [
|