@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
|
@@ -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 → Providers' 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
|
+
}
|
|
@@ -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);
|
|
@@ -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 });
|
|
@@ -121,9 +121,6 @@ export const multilingualGates = {
|
|
|
121
121
|
anchorLetters: 20,
|
|
122
122
|
anchorConfidence: 0.75,
|
|
123
123
|
};
|
|
124
|
-
export function multilingualLanguages() {
|
|
125
|
-
return Object.keys(alphabets);
|
|
126
|
-
}
|
|
127
124
|
// The model and language view the aligner uses for a project language. English keeps its own
|
|
128
125
|
// model and every constant it had.
|
|
129
126
|
export function alignmentSpecFor(language) {
|
|
@@ -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
|
}
|
|
@@ -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
|
: {}),
|
package/dist/adapters/explain.js
CHANGED
|
@@ -58,9 +58,6 @@ export function refusedImage(provider, detail) {
|
|
|
58
58
|
export function voiceFix(voiceId) {
|
|
59
59
|
return `Check that voice "${voiceId}" still exists in Settings → Voices and that each narration part fits the model's length limit (Chunking, in the Providers section of Edit project), then use Try again.`;
|
|
60
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.`;
|
|
63
|
-
}
|
|
64
61
|
const cliNames = {
|
|
65
62
|
claude: "Claude Code CLI",
|
|
66
63
|
"claude-code": "Claude Code CLI",
|
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,10 +1,11 @@
|
|
|
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
5
|
import { sniffImage } from "../image/bytes.js";
|
|
6
6
|
import { claudePlanLimit } from "../llm/claude-code.js";
|
|
7
7
|
import { codexPlanLimit } from "../llm/codex-limits.js";
|
|
8
|
+
import { accessField } from "../model-access.js";
|
|
8
9
|
import { hostRequest, hostUnavailable, readHostBytes, } from "./transport.js";
|
|
9
10
|
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 inputs shorter in Edit project, then use Try again; if it happens again, use Download diagnostics in Settings and report it.";
|
|
10
11
|
export function createHostCliClient(options) {
|
|
@@ -16,7 +17,7 @@ export function createHostCliClient(options) {
|
|
|
16
17
|
try {
|
|
17
18
|
const parsed = hostFaultSchema.safeParse(JSON.parse((await readHostBytes(response, bridgeLimits.status)).toString("utf8")));
|
|
18
19
|
if (parsed.success)
|
|
19
|
-
throw
|
|
20
|
+
throw bridgedFault(parsed.data.kind, parsed.data.message);
|
|
20
21
|
}
|
|
21
22
|
catch (error) {
|
|
22
23
|
if (isProviderError(error))
|
|
@@ -163,6 +164,16 @@ export function createHostCliClient(options) {
|
|
|
163
164
|
base64: Buffer.from(req.reference.bytes).toString("base64"),
|
|
164
165
|
},
|
|
165
166
|
}),
|
|
167
|
+
...(req.edit === undefined
|
|
168
|
+
? {}
|
|
169
|
+
: {
|
|
170
|
+
edit: {
|
|
171
|
+
source: {
|
|
172
|
+
mime: req.edit.source.mime,
|
|
173
|
+
base64: Buffer.from(req.edit.source.bytes).toString("base64"),
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
}),
|
|
166
177
|
...(req.cast === undefined
|
|
167
178
|
? {}
|
|
168
179
|
: {
|
|
@@ -216,6 +227,11 @@ export function createHostCliClient(options) {
|
|
|
216
227
|
},
|
|
217
228
|
};
|
|
218
229
|
}
|
|
230
|
+
// A fault from the host helper carries its kind and the host adapter's words only; whether it
|
|
231
|
+
// was about the model's access is read again from those words, as the plan limit is below.
|
|
232
|
+
export function bridgedFault(kind, message) {
|
|
233
|
+
return providerError({ kind, message: redact(message), ...accessField(null, message) });
|
|
234
|
+
}
|
|
219
235
|
// A used-up plan crosses the bridge as a rate-limit fault carrying the CLI's own words, which
|
|
220
236
|
// the host-side adapter already quoted; they are read again here so a Docker run waits for the
|
|
221
237
|
// reset like a local one instead of failing.
|
|
@@ -256,7 +272,7 @@ async function* readEvents(response) {
|
|
|
256
272
|
throw hostUnavailable(true);
|
|
257
273
|
const event = hostFrameSchema.parse(JSON.parse(line));
|
|
258
274
|
if (event.type === "error")
|
|
259
|
-
throw
|
|
275
|
+
throw bridgedFault(event.kind, event.message);
|
|
260
276
|
if (event.type === "done")
|
|
261
277
|
terminal = event;
|
|
262
278
|
else
|
|
@@ -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
|
+
}
|
|
@@ -11,8 +11,9 @@ import { codexLimitError, readingOf } from "../llm/codex.js";
|
|
|
11
11
|
import { codexPlanLimit } from "../llm/codex-limits.js";
|
|
12
12
|
import { cliEvent, cliShaped, endedKind, endedWithout, stopCliRun, } from "../llm/run-cli.js";
|
|
13
13
|
import { lines } from "../llm/sse-lines.js";
|
|
14
|
+
import { accessField } from "../model-access.js";
|
|
14
15
|
import { codexGeneratedImage, codexImageCount } from "./codex-output.js";
|
|
15
|
-
import {
|
|
16
|
+
import { attachedPictures, editNote } from "./reference.js";
|
|
16
17
|
// "Codex default" puts no model and no effort on the command line, so the CLI's own defaults
|
|
17
18
|
// draw the image; it is what every project saved before the choice existed runs. Every other
|
|
18
19
|
// model id is one of the Codex CLI's own models - the list the Codex text provider shows -
|
|
@@ -46,7 +47,7 @@ const alwaysDisabled = [
|
|
|
46
47
|
function reviews(req) {
|
|
47
48
|
return (req.model !== codexImageModel.id ||
|
|
48
49
|
req.thinking !== undefined ||
|
|
49
|
-
|
|
50
|
+
attachedPictures(req).length > 0);
|
|
50
51
|
}
|
|
51
52
|
// The binary's image tool (`ImagegenArgs`: prompt, referenced_image_paths,
|
|
52
53
|
// num_last_images_to_include) takes each referenced image as an absolute path it reads
|
|
@@ -57,10 +58,12 @@ export function codexReferencePath(directory, image) {
|
|
|
57
58
|
// Every picture the request carries, each at its own path: the establishing image keeps the
|
|
58
59
|
// name it always had, the cast pictures follow it as reference-2, reference-3 and so on.
|
|
59
60
|
export function codexReferencePaths(directory, req) {
|
|
60
|
-
return
|
|
61
|
+
return attachedPictures(req).map((picture, index) => ({
|
|
61
62
|
picture,
|
|
62
63
|
path: index === 0
|
|
63
|
-
?
|
|
64
|
+
? req.edit === undefined
|
|
65
|
+
? codexReferencePath(directory, picture.image)
|
|
66
|
+
: join(directory, picture.image.mime === "image/jpeg" ? "source.jpg" : "source.png")
|
|
64
67
|
: join(directory, `reference-${String(index + 1)}${picture.image.mime === "image/jpeg" ? ".jpg" : ".png"}`),
|
|
65
68
|
}));
|
|
66
69
|
}
|
|
@@ -78,7 +81,34 @@ function describeMember(req, name) {
|
|
|
78
81
|
const description = req.cast?.find((member) => member.name === name)?.description.trim() ?? "";
|
|
79
82
|
return description === "" ? "" : ` (${description})`;
|
|
80
83
|
}
|
|
84
|
+
// An edit's instructions: the first path is the picture to change, the rest are the cast.
|
|
85
|
+
function editInstructions(req, directory) {
|
|
86
|
+
const paths = codexReferencePaths(directory, req);
|
|
87
|
+
return [
|
|
88
|
+
`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
|
|
89
|
+
? `, followed by: ${paths
|
|
90
|
+
.slice(1)
|
|
91
|
+
.map((row) => row.path)
|
|
92
|
+
.join(", ")}`
|
|
93
|
+
: ""}.`,
|
|
94
|
+
...paths
|
|
95
|
+
.slice(1)
|
|
96
|
+
.map((row) => `${row.path} shows ${row.picture.member ?? ""}${describeMember(req, row.picture.member ?? "")}: draw ${row.picture.member ?? ""} to look exactly like this.`),
|
|
97
|
+
editNote.replace("the first attached image", "that picture"),
|
|
98
|
+
].join(" ");
|
|
99
|
+
}
|
|
81
100
|
export function codexImageInstructions(req, reference, directory) {
|
|
101
|
+
if (req.edit !== undefined && directory !== undefined)
|
|
102
|
+
return [
|
|
103
|
+
"You are editing one picture for Slopify, a video creation app, with the image generation tool.",
|
|
104
|
+
editInstructions(req, directory),
|
|
105
|
+
"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.",
|
|
106
|
+
"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.",
|
|
107
|
+
"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.",
|
|
108
|
+
`Target aspect ratio: ${req.aspect}.`,
|
|
109
|
+
"Instruction follows as data:",
|
|
110
|
+
req.prompt,
|
|
111
|
+
].join("\n\n");
|
|
82
112
|
return [
|
|
83
113
|
"You are making one finished image for Slopify, a video creation app, with the image generation tool.",
|
|
84
114
|
"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.",
|
|
@@ -271,6 +301,7 @@ export function codexImage(deps) {
|
|
|
271
301
|
message: /refus|content.policy|safety/i.test(message)
|
|
272
302
|
? refusedImage("The Codex CLI", redact(message))
|
|
273
303
|
: cliReported(binary, redact(message), imageNext),
|
|
304
|
+
...(/refus|content.policy|safety/i.test(message) ? {} : accessField(null, message)),
|
|
274
305
|
});
|
|
275
306
|
}
|
|
276
307
|
else if (event.type === "error") {
|
|
@@ -288,6 +319,7 @@ export function codexImage(deps) {
|
|
|
288
319
|
message: /image.generation|image tool|feature.*unavailable/i.test(message)
|
|
289
320
|
? `The Codex CLI cannot make images${quoted("", redact(message))}. ${cannotDraw}`
|
|
290
321
|
: cliReported(binary, redact(message), imageNext),
|
|
322
|
+
...accessField(null, message),
|
|
291
323
|
});
|
|
292
324
|
}
|
|
293
325
|
else if (event.type === "item.completed") {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { internalError } from "../../kernel/errors.js";
|
|
2
3
|
import { redact } from "../../kernel/log.js";
|
|
3
4
|
import { providerError } from "../../kernel/ports/model.js";
|
|
4
|
-
import { httpFailure,
|
|
5
|
-
import {
|
|
5
|
+
import { httpFailure, noImage, providerSaid, unreadable } from "../explain.js";
|
|
6
|
+
import { failureText, httpProviderError, kindOfStatus, requireKey, safeJson, } from "../http-failure.js";
|
|
7
|
+
import { modelAccessOf } from "../model-access.js";
|
|
6
8
|
import { downloadImage } from "./bytes.js";
|
|
7
|
-
import {
|
|
9
|
+
import { attachedPictures, promptFor } from "./reference.js";
|
|
8
10
|
import { dataUri, downloadVideo } from "./video.js";
|
|
9
11
|
// The HTTP gateway adapter for fal.ai: `fetch` and the downloader beside this file, no SDK.
|
|
10
12
|
// `@fal-ai/client` would buy queue polling, which only the video clips need and which is three
|
|
@@ -60,6 +62,7 @@ const editModels = [
|
|
|
60
62
|
function editEndpoint(model) {
|
|
61
63
|
return editModels.includes(model) ? `${model}/edit` : undefined;
|
|
62
64
|
}
|
|
65
|
+
export const falEditRefusal = "This fal.ai model can't edit a picture. Choose FLUX.2 or Nano Banana 2 on fal.ai, or Codex CLI, OpenAI or Google, under Made with … · change.";
|
|
63
66
|
// Image-to-video runs on fal's queue, not the synchronous host: a clip takes one to five
|
|
64
67
|
// minutes, and fal documents the queue as the way to call anything that slow. A request is
|
|
65
68
|
// submitted, its status polled until it completes, and its answer fetched from the links the
|
|
@@ -104,8 +107,10 @@ export function falImage(deps) {
|
|
|
104
107
|
// `image_urls`; only the models that have one are marked as taking a reference.
|
|
105
108
|
// Cast pictures ride the same list; a model without an edit endpoint gets the cast in
|
|
106
109
|
// words instead, since only the establishing image is something the user turned on.
|
|
107
|
-
const pictures =
|
|
110
|
+
const pictures = attachedPictures(req);
|
|
108
111
|
const edit = pictures.length === 0 ? undefined : editEndpoint(req.model);
|
|
112
|
+
if (req.edit !== undefined && edit === undefined)
|
|
113
|
+
throw providerError({ kind: "unsupported", message: falEditRefusal });
|
|
109
114
|
if (req.reference !== undefined && edit === undefined)
|
|
110
115
|
throw providerError({
|
|
111
116
|
kind: "unsupported",
|
|
@@ -116,7 +121,7 @@ export function falImage(deps) {
|
|
|
116
121
|
signal: req.signal,
|
|
117
122
|
headers: { Authorization: `Key ${keyOf(deps)}`, "Content-Type": "application/json" },
|
|
118
123
|
body: JSON.stringify({
|
|
119
|
-
prompt:
|
|
124
|
+
prompt: promptFor(req.prompt, req, edit === undefined ? 0 : pictures.length),
|
|
120
125
|
...(edit === undefined
|
|
121
126
|
? {}
|
|
122
127
|
: { image_urls: pictures.map((picture) => dataUri(picture.image)) }),
|
|
@@ -129,7 +134,7 @@ export function falImage(deps) {
|
|
|
129
134
|
}),
|
|
130
135
|
});
|
|
131
136
|
if (!response.ok) {
|
|
132
|
-
throw await failure(response);
|
|
137
|
+
throw await failure(response, "image request", true);
|
|
133
138
|
}
|
|
134
139
|
const answer = parse(await response.text());
|
|
135
140
|
refused(answer, req.prompt);
|
|
@@ -162,7 +167,7 @@ export function falImage(deps) {
|
|
|
162
167
|
}),
|
|
163
168
|
});
|
|
164
169
|
if (!submitted.ok)
|
|
165
|
-
throw await failure(submitted, "video clip request");
|
|
170
|
+
throw await failure(submitted, "video clip request", true);
|
|
166
171
|
const links = read(queued, await submitted.text());
|
|
167
172
|
for (;;) {
|
|
168
173
|
const status = await deps.fetch(links.status_url, { signal: req.signal, headers });
|
|
@@ -198,12 +203,7 @@ function read(schema, text) {
|
|
|
198
203
|
return parsed.data;
|
|
199
204
|
}
|
|
200
205
|
function keyOf(deps) {
|
|
201
|
-
|
|
202
|
-
const key = deps.key();
|
|
203
|
-
if (key === undefined || key === "") {
|
|
204
|
-
throw providerError({ kind: "missing_key", message: missingKey("fal.ai") });
|
|
205
|
-
}
|
|
206
|
-
return key;
|
|
206
|
+
return requireKey(deps.key(), "fal.ai");
|
|
207
207
|
}
|
|
208
208
|
// A content-policy refusal is final, named here and made terminal by the wrapper. fal declines
|
|
209
209
|
// inside a 200 - the safety checker flags the image and hands back a blank one. With no
|
|
@@ -217,37 +217,12 @@ function refused(answer, prompt) {
|
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
-
//
|
|
221
|
-
function
|
|
222
|
-
|
|
223
|
-
return "auth";
|
|
224
|
-
}
|
|
225
|
-
if (status === 429) {
|
|
226
|
-
return "rate_limit";
|
|
227
|
-
}
|
|
228
|
-
// ceiling: everything else is `other` and is retried, so a 422 naming an input this model
|
|
229
|
-
// does not take fails the same way four times over. A terminal "this will never work" kind
|
|
230
|
-
// has to reach the port's error contract first, which is not this adapter's to widen.
|
|
231
|
-
// The provider's own server failed; the same request may well succeed later.
|
|
232
|
-
if (status >= 500)
|
|
233
|
-
return "dropped";
|
|
234
|
-
return "other";
|
|
235
|
-
}
|
|
236
|
-
async function failure(response, subject = "image request") {
|
|
237
|
-
const text = await response.text().catch(() => "");
|
|
220
|
+
// `atModel`: the request went to the model's own address, so a 404 or 403 is about the model.
|
|
221
|
+
async function failure(response, subject = "image request", atModel = false) {
|
|
222
|
+
const text = await failureText(response);
|
|
238
223
|
// The provider's own words, through the redactor - an error body may quote the key back.
|
|
239
224
|
const message = redact(detailOf(text) || response.statusText);
|
|
240
|
-
|
|
241
|
-
return providerError({
|
|
242
|
-
kind: kindOf(response.status),
|
|
243
|
-
message: httpFailure({
|
|
244
|
-
provider: "fal.ai",
|
|
245
|
-
status: response.status,
|
|
246
|
-
detail: message,
|
|
247
|
-
subject,
|
|
248
|
-
}),
|
|
249
|
-
...(retryAfterMs === undefined ? {} : { retryAfterMs }),
|
|
250
|
-
});
|
|
225
|
+
return httpProviderError(response, kindOfStatus(response.status), httpFailure({ provider: "fal.ai", status: response.status, detail: message, subject }), undefined, modelAccessOf(response.status, text, atModel));
|
|
251
226
|
}
|
|
252
227
|
function detailOf(text) {
|
|
253
228
|
const parsed = errorBody.safeParse(safeJson(text));
|
|
@@ -270,11 +245,3 @@ function parse(text) {
|
|
|
270
245
|
}
|
|
271
246
|
return parsed.data;
|
|
272
247
|
}
|
|
273
|
-
function safeJson(text) {
|
|
274
|
-
try {
|
|
275
|
-
return JSON.parse(text);
|
|
276
|
-
}
|
|
277
|
-
catch {
|
|
278
|
-
return undefined;
|
|
279
|
-
}
|
|
280
|
-
}
|