@gentbajko/slopify 4.0.0 → 4.2.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 +1 -1
- package/dist/adapters/alignment/audio.js +1 -1
- package/dist/adapters/alignment/cache.js +1 -1
- package/dist/adapters/alignment/multilingual.js +2 -1
- package/dist/adapters/alignment/runner.js +1 -1
- package/dist/adapters/alignment/worker.js +1 -1
- package/dist/adapters/explain.js +10 -9
- package/dist/adapters/host-cli/index.js +2 -1
- package/dist/adapters/host-cli/transport.js +2 -1
- package/dist/adapters/image/bytes.js +2 -1
- package/dist/adapters/image/codex.js +6 -5
- package/dist/adapters/image/fal.js +4 -3
- package/dist/adapters/image/google.js +3 -2
- package/dist/adapters/image/models.js +2 -2
- package/dist/adapters/image/openai.js +2 -1
- package/dist/adapters/image/replicate.js +3 -2
- package/dist/adapters/image/video.js +2 -1
- package/dist/adapters/key-probes.js +1 -1
- package/dist/adapters/llm/antigravity-models.js +1 -1
- package/dist/adapters/llm/antigravity.js +7 -6
- package/dist/adapters/llm/assistant-cli.js +1 -1
- package/dist/adapters/llm/claude-code-models.js +1 -1
- package/dist/adapters/llm/claude-code.js +3 -2
- package/dist/adapters/llm/codex-models.js +1 -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 +2 -1
- package/dist/adapters/llm/run-cli.js +3 -2
- package/dist/adapters/tts/gemini.js +2 -1
- package/dist/adapters/tts/inworld-async.js +2 -1
- package/dist/adapters/tts/inworld.js +3 -2
- package/dist/adapters/tts/system.js +2 -1
- package/dist/catalog/registry.js +20 -13
- package/dist/catalog/schema.js +2 -1
- package/dist/catalog/validate.js +5 -2
- package/dist/edge/http/actions.js +7 -7
- package/dist/edge/http/app.js +5 -3
- package/dist/edge/http/assistant.js +3 -1
- package/dist/edge/http/backups.js +1 -1
- package/dist/edge/http/channel-memory.js +2 -2
- package/dist/edge/http/channels.js +1 -1
- package/dist/edge/http/checkpoints.js +7 -5
- package/dist/edge/http/design-templates.js +3 -3
- package/dist/edge/http/designs.js +1 -1
- package/dist/edge/http/document-themes.js +3 -3
- package/dist/edge/http/draft-problem.js +1 -1
- package/dist/edge/http/extension-auth.js +1 -1
- package/dist/edge/http/home.js +9 -1
- package/dist/edge/http/model-checks.js +4 -4
- package/dist/edge/http/onboarding.js +29 -12
- package/dist/edge/http/outputs.js +3 -2
- package/dist/edge/http/patch-notes.js +2 -2
- package/dist/edge/http/planning.js +1 -1
- package/dist/edge/http/project-create.js +1 -1
- package/dist/edge/http/project-templates.js +2 -2
- package/dist/edge/http/projects.js +22 -4
- package/dist/edge/http/prompts.js +2 -2
- package/dist/edge/http/pronunciation-check.js +133 -0
- package/dist/edge/http/pronunciations.js +26 -0
- package/dist/edge/http/providers.js +9 -10
- package/dist/edge/http/refusal.js +1 -1
- package/dist/edge/http/remote-access.js +4 -4
- package/dist/edge/http/remote-guard.js +2 -2
- package/dist/edge/http/reviews.js +1 -1
- package/dist/edge/http/revision-files.js +1 -1
- package/dist/edge/http/revisions.js +4 -4
- package/dist/edge/http/schedules.js +13 -11
- package/dist/edge/http/settings.js +6 -2
- package/dist/edge/http/social.js +5 -4
- package/dist/edge/http/staging.js +1 -1
- package/dist/edge/http/storage.js +12 -4
- package/dist/edge/http/studio.js +71 -19
- package/dist/edge/http/style-preview.js +2 -2
- package/dist/edge/http/template-studio.js +12 -9
- package/dist/edge/http/trash.js +1 -1
- package/dist/edge/http/youtube-edits.js +1 -1
- package/dist/edge/mcp/excluded-routes.js +4 -3
- package/dist/edge/mcp/instructions.js +3 -3
- package/dist/edge/mcp/library-tools.js +8 -5
- package/dist/edge/mcp/remake-tools.js +7 -4
- package/dist/edge/mcp/server.js +1 -1
- package/dist/edge/mcp/tools-channels.js +9 -9
- package/dist/edge/mcp/tools-designs.js +9 -9
- package/dist/edge/mcp/tools-library.js +31 -7
- package/dist/edge/mcp/tools-planning.js +18 -18
- package/dist/edge/mcp/tools-projects.js +10 -10
- package/dist/edge/mcp/tools-publishing.js +9 -9
- package/dist/edge/mcp/tools-runs.js +9 -9
- package/dist/edge/mcp/tools-schedules.js +6 -6
- package/dist/edge/mcp/tools-setup.js +20 -14
- package/dist/edge/mcp/tools-social.js +5 -4
- package/dist/edge/mcp/tools-storage.js +3 -3
- package/dist/edge/mcp/tools-template-studio.js +18 -18
- package/dist/edge/remote-access/model.js +1 -1
- package/dist/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/kernel/db/migrations/0078-uploaded-from-links.sql +7 -0
- package/dist/kernel/pipeline.js +12 -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 +11 -3
- package/dist/kernel/runner/providers.js +3 -2
- package/dist/kernel/runner/standalone.js +2 -2
- package/dist/main.js +5 -3
- package/dist/model-catalog.js +20 -0
- package/dist/patch-notes/4.0.0.md +13 -13
- package/dist/patch-notes/4.1.0.md +42 -0
- package/dist/patch-notes/4.2.0.md +28 -0
- package/dist/patch-notes/index.json +12 -0
- package/dist/slices/admission/listing-facts.js +95 -0
- package/dist/slices/admission/repo.js +9 -6
- package/dist/slices/admission/rules.js +7 -7
- package/dist/slices/admission/schema.js +2 -0
- package/dist/slices/admission/start.js +7 -0
- package/dist/slices/admission/state-words.js +34 -5
- package/dist/slices/assistant/cost.js +1 -1
- package/dist/slices/assistant/gate.js +1 -0
- package/dist/slices/assistant/model.js +10 -3
- package/dist/slices/assistant/turn.js +5 -3
- package/dist/slices/autopilot/warnings.js +1 -1
- package/dist/slices/backups/service.js +5 -5
- package/dist/slices/channels/cast-images.js +1 -1
- package/dist/slices/channels/schema.js +1 -1
- package/dist/slices/channels/videos.js +1 -1
- package/dist/slices/control/providers.js +2 -2
- package/dist/slices/designs/budget.js +1 -1
- package/dist/slices/designs/calls.js +2 -2
- package/dist/slices/designs/check-context.js +4 -4
- package/dist/slices/designs/fields.js +4 -4
- package/dist/slices/designs/gate.js +7 -5
- package/dist/slices/designs/render-input.js +1 -1
- package/dist/slices/designs/requests.js +1 -1
- package/dist/slices/designs/runner.js +1 -1
- package/dist/slices/designs/sample.js +2 -1
- package/dist/slices/designs/service.js +1 -1
- package/dist/slices/designs/template-checks.js +2 -2
- package/dist/slices/designs/template-make.js +3 -3
- package/dist/slices/designs/templates.js +3 -3
- package/dist/slices/document/fonts.js +1 -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 +2 -2
- package/dist/slices/estimate/index.js +28 -22
- package/dist/slices/estimate/requests.js +4 -4
- package/dist/slices/fixes/rules.js +3 -1
- package/dist/slices/fonts/catalog.js +2 -1
- package/dist/slices/fonts/coverage.js +2 -1
- package/dist/slices/images/appearance.js +2 -1
- package/dist/slices/images/scenes.js +2 -1
- package/dist/slices/keywords/digest.js +2 -1
- package/dist/slices/keywords/rules.js +2 -2
- package/dist/slices/keywords/specs.js +5 -5
- package/dist/slices/keywords/values.js +1 -1
- package/dist/slices/library/transfer.js +3 -3
- package/dist/slices/loudness/loudnorm.js +2 -1
- package/dist/slices/loudness/model.js +3 -2
- package/dist/slices/loudness/sentence-level.js +2 -1
- package/dist/slices/model-checks/rules.js +13 -0
- package/dist/slices/model-upkeep/model.js +1 -1
- package/dist/slices/model-upkeep/switch.js +3 -3
- package/dist/slices/model-upkeep/usage.js +13 -2
- package/dist/slices/narration/breaths.js +2 -1
- package/dist/slices/narration/clean-pieces.js +2 -1
- package/dist/slices/narration/pauses-model.js +3 -2
- package/dist/slices/narration/pronunciation-check.js +226 -0
- package/dist/slices/narration/pronunciation.js +7 -2
- package/dist/slices/narration/pronunciations-library.js +94 -0
- package/dist/slices/notifications/subject.js +2 -2
- package/dist/slices/onboarding/copy.js +19 -2
- package/dist/slices/onboarding/first-run.js +13 -38
- package/dist/slices/onboarding/install.js +2 -1
- package/dist/slices/onboarding/model.js +26 -21
- package/dist/slices/onboarding/preferred-model.js +14 -0
- package/dist/slices/onboarding/quick-short.js +103 -64
- package/dist/slices/onboarding/sample.js +4 -1
- package/dist/slices/onboarding/state.js +7 -0
- package/dist/slices/onboarding/template.js +6 -5
- package/dist/slices/outputs/add.js +3 -2
- package/dist/slices/outputs/service.js +2 -2
- package/dist/slices/patch-notes/library.js +1 -1
- package/dist/slices/play-drafts/readiness.js +3 -3
- package/dist/slices/play-drafts/review-inputs.js +1 -1
- package/dist/slices/play-drafts/service.js +17 -7
- 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/setup-sections.js +26 -0
- package/dist/slices/project-templates/setup.js +6 -1
- package/dist/slices/rebuild/preview-details.js +5 -5
- package/dist/slices/rebuild/recipe-preparation.js +1 -1
- package/dist/slices/rebuild/recipe-save.js +2 -2
- package/dist/slices/rebuild/recipe-text.js +16 -4
- package/dist/slices/rebuild/recipe-validation.js +5 -4
- package/dist/slices/rebuild/recipe-voices.js +3 -2
- package/dist/slices/rebuild/recipe-work.js +4 -4
- package/dist/slices/rebuild/recovery.js +6 -6
- package/dist/slices/rebuild/remake-outdated.js +5 -5
- package/dist/slices/rebuild/review-redo.js +1 -1
- package/dist/slices/rebuild/runtime-animate.js +2 -2
- package/dist/slices/rebuild/runtime-article.js +4 -3
- package/dist/slices/rebuild/runtime-document.js +5 -4
- package/dist/slices/rebuild/runtime-export-bed.js +2 -1
- package/dist/slices/rebuild/runtime-export-edit.js +2 -1
- package/dist/slices/rebuild/runtime-export-inputs.js +5 -4
- package/dist/slices/rebuild/runtime-export-short.js +1 -1
- package/dist/slices/rebuild/runtime-export.js +4 -3
- package/dist/slices/rebuild/runtime-image.js +4 -3
- package/dist/slices/rebuild/runtime-local.js +3 -2
- package/dist/slices/rebuild/runtime-narration-text.js +3 -2
- package/dist/slices/rebuild/runtime-provider.js +7 -6
- package/dist/slices/rebuild/runtime-review.js +6 -5
- package/dist/slices/rebuild/runtime-shorts.js +6 -5
- package/dist/slices/rebuild/runtime-store.js +17 -2
- package/dist/slices/rebuild/runtime-subtitles.js +13 -12
- package/dist/slices/rebuild/runtime-voices.js +2 -1
- package/dist/slices/rebuild/runtime-youtube.js +3 -2
- package/dist/slices/rebuild/service-readiness.js +11 -3
- package/dist/slices/research/synthesis.js +3 -2
- package/dist/slices/reviews/external-model.js +1 -1
- package/dist/slices/reviews/holds.js +5 -4
- package/dist/slices/reviews/model.js +8 -5
- package/dist/slices/reviews/rules.js +3 -3
- package/dist/slices/reviews/verdict.js +2 -1
- package/dist/slices/revisions/image-plan.js +1 -1
- package/dist/slices/revisions/mutation-assets.js +2 -1
- package/dist/slices/revisions/mutations.js +3 -2
- package/dist/slices/schedules/agenda.js +7 -5
- package/dist/slices/schedules/design-check.js +4 -4
- package/dist/slices/schedules/design-run.js +3 -3
- package/dist/slices/schedules/repo.js +6 -5
- package/dist/slices/schedules/schema.js +3 -0
- package/dist/slices/schedules/topics.js +5 -5
- package/dist/slices/settings/first-run.js +6 -32
- package/dist/slices/settings/health.js +30 -15
- package/dist/slices/settings/key-test.js +1 -1
- package/dist/slices/settings/model.js +4 -2
- package/dist/slices/settings/playback.js +2 -2
- package/dist/slices/shorts/keep.js +2 -1
- package/dist/slices/shorts/pick.js +4 -3
- package/dist/slices/shorts/prompts.js +2 -1
- package/dist/slices/shorts/render.js +3 -2
- package/dist/slices/social/media.js +5 -4
- package/dist/slices/social/pack.js +1 -1
- package/dist/slices/social/post-prompt.js +2 -1
- package/dist/slices/social/reshape.js +2 -2
- package/dist/slices/social/serve.js +1 -1
- package/dist/slices/social/service.js +3 -2
- package/dist/slices/social/state.js +1 -1
- package/dist/slices/storage/backup-import.js +2 -2
- package/dist/slices/storage/portable.js +1 -1
- package/dist/slices/storage/trim.js +23 -13
- package/dist/slices/studio/calendar.js +3 -1
- 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/plan.js +1 -1
- package/dist/slices/studio/settings.js +6 -6
- package/dist/slices/studio/videos.js +23 -4
- package/dist/slices/style-preview/render.js +3 -3
- package/dist/slices/style-preview/schema.js +1 -1
- package/dist/slices/subtitles/captions.js +1 -1
- package/dist/slices/template-studio/anatomy-view.js +46 -3
- package/dist/slices/template-studio/bakeoff.js +3 -3
- package/dist/slices/template-studio/budget.js +6 -3
- package/dist/slices/template-studio/cards.js +78 -0
- package/dist/slices/template-studio/checks.js +99 -50
- package/dist/slices/template-studio/for-all.js +5 -5
- package/dist/slices/template-studio/free-video.js +1 -1
- package/dist/slices/template-studio/free.js +5 -5
- package/dist/slices/template-studio/model.js +19 -15
- package/dist/slices/template-studio/pack-import.js +14 -14
- package/dist/slices/template-studio/pack.js +9 -7
- package/dist/slices/template-studio/paid.js +12 -5
- package/dist/slices/template-studio/quote.js +18 -11
- package/dist/slices/template-studio/ready.js +7 -7
- package/dist/slices/template-studio/runner.js +1 -1
- package/dist/slices/template-studio/save.js +12 -12
- package/dist/slices/template-studio/say-it-as.js +3 -3
- package/dist/slices/template-studio/schedule-gate.js +1 -1
- package/dist/slices/template-studio/schedule-price.js +3 -1
- package/dist/slices/template-studio/schedule-sample.js +5 -1
- package/dist/slices/template-studio/schema.js +25 -0
- package/dist/slices/template-studio/service.js +3 -1
- package/dist/slices/template-studio/status.js +26 -9
- package/dist/slices/template-studio/topic.js +3 -3
- package/dist/slices/thumbnail/by-llm.js +1 -1
- package/dist/slices/uploads/repo.js +37 -1
- package/dist/slices/uploads/rules.js +3 -2
- package/dist/slices/video/edit-list.js +2 -2
- package/dist/slices/video/edit-settings.js +1 -1
- package/dist/slices/video/encoding.js +14 -5
- package/dist/slices/video/ffmpeg.js +2 -2
- package/dist/slices/video/plan.js +2 -1
- package/dist/slices/video/slideshow.js +1 -1
- package/dist/slices/voices/attribution.js +3 -2
- package/dist/slices/voices/model.js +9 -8
- package/dist/slices/voices/script.js +2 -1
- package/dist/slices/youtube/answer.js +2 -1
- package/dist/slices/youtube/edits-repo.js +1 -1
- package/dist/tutorials/AI-CLIs.md +25 -25
- package/dist/tutorials/Agents-MCP.md +32 -32
- package/dist/tutorials/Assistant.md +5 -5
- 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 +40 -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 +95 -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 +101 -76
- package/dist/tutorials/Home.md +33 -33
- package/dist/tutorials/Install.md +13 -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 +21 -21
- package/dist/tutorials/Models.md +27 -27
- package/dist/tutorials/Multiple-Voices.md +41 -40
- package/dist/tutorials/Narration-Aliases-and-Glossary.md +101 -19
- package/dist/tutorials/Notifications.md +21 -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 +12 -12
- package/dist/tutorials/Project-Page.md +118 -120
- package/dist/tutorials/Prompts-and-Templates.md +84 -0
- package/dist/tutorials/Prompts.md +45 -45
- 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 +2 -2
- package/dist/tutorials/Reviews-and-Checkpoints.md +90 -93
- package/dist/tutorials/Schedules.md +27 -28
- package/dist/tutorials/Settings-Reference.md +183 -204
- 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 +45 -42
- package/dist/tutorials/Templates.md +50 -79
- 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 +15 -15
- package/dist/web/assets/index-BNftKQrA.css +1 -0
- package/dist/web/assets/index-CQASqwjT.js +460 -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 +2 -2
- package/dist/tutorials/Library-Overview.md +0 -76
- package/dist/tutorials/Play-Images.md +0 -165
- 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-CkAI_2E7.css +0 -1
- package/dist/web/assets/index-DcD0cdfo.js +0 -334
- package/dist/web/assets/pdf-TODRwF31.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
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { internalError } from "../../kernel/errors.js";
|
|
3
3
|
import { redact } from "../../kernel/log.js";
|
|
4
4
|
import { providerError } from "../../kernel/ports/model.js";
|
|
5
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
5
6
|
import { httpFailure, noAudio, providerSaid, refreshList, unreadable, voiceFix, } from "../explain.js";
|
|
6
7
|
import { failureText, httpProviderError, kindOfStatus, requireKey, safeJson, } from "../http-failure.js";
|
|
7
8
|
import { modelAccessOf } from "../model-access.js";
|
|
@@ -134,7 +135,7 @@ function audioOf(text) {
|
|
|
134
135
|
if (blocked)
|
|
135
136
|
throw providerError({
|
|
136
137
|
kind: "refusal",
|
|
137
|
-
message: providerSaid("Google", "refused to speak this narration under its content rules", blocked,
|
|
138
|
+
message: providerSaid("Google", "refused to speak this narration under its content rules", blocked, `Reword that part of the script or article, or choose another voice service under Speakers (${editSettings.narration}).`),
|
|
138
139
|
});
|
|
139
140
|
for (const candidate of parsed.data.candidates ?? [])
|
|
140
141
|
for (const part of candidate.content?.parts ?? []) {
|
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { internalError } from "../../kernel/errors.js";
|
|
3
3
|
import { redact } from "../../kernel/log.js";
|
|
4
4
|
import { providerError } from "../../kernel/ports/model.js";
|
|
5
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
5
6
|
import { httpFailure, noAudio, providerSaid, unreadable, voiceFix } from "../explain.js";
|
|
6
7
|
import { accessField } from "../model-access.js";
|
|
7
8
|
import { retryAfter } from "../retry-after.js";
|
|
@@ -25,7 +26,7 @@ export async function* inworldAsync(deps, request, key) {
|
|
|
25
26
|
if (saved === undefined && request.text.length > 100_000) {
|
|
26
27
|
throw providerError({
|
|
27
28
|
kind: "unsupported",
|
|
28
|
-
message:
|
|
29
|
+
message: `This narration part is longer than the 100,000 characters Inworld takes at once (10,000 on On-Demand accounts). Set Chunking to Paragraph in ${editSettings.narration}, then use Try again.`,
|
|
29
30
|
});
|
|
30
31
|
}
|
|
31
32
|
const headers = { Authorization: `Basic ${key}`, "Content-Type": "application/json" };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { redact } from "../../kernel/log.js";
|
|
3
3
|
import { providerError } from "../../kernel/ports/model.js";
|
|
4
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
4
5
|
import { httpFailure, missingKey, noAudio, unreadable, voiceFix } from "../explain.js";
|
|
5
6
|
import { accessField } from "../model-access.js";
|
|
6
7
|
import { retryAfter } from "../retry-after.js";
|
|
@@ -70,7 +71,7 @@ async function* synthesizeRequest(deps, request, key) {
|
|
|
70
71
|
if (request.text.trim().length === 0)
|
|
71
72
|
throw providerError({
|
|
72
73
|
kind: "unsupported",
|
|
73
|
-
message:
|
|
74
|
+
message: `Inworld was sent an empty piece of narration. Check the article has text in ${editSettings.article}, then use Try again.`,
|
|
74
75
|
});
|
|
75
76
|
if ((request.model ?? "inworld-tts-2") === "inworld-tts-2" && request.text.length > 4000) {
|
|
76
77
|
yield* inworldAsync(deps, request, key);
|
|
@@ -79,7 +80,7 @@ async function* synthesizeRequest(deps, request, key) {
|
|
|
79
80
|
if (request.text.length > 4000)
|
|
80
81
|
throw providerError({
|
|
81
82
|
kind: "unsupported",
|
|
82
|
-
message:
|
|
83
|
+
message: `This narration part is longer than the 4,000 characters Inworld's Flash model takes at once. In ${editSettings.narration}, set Chunking to Paragraph or a smaller character count, or switch to the Realtime TTS-2 voice model.`,
|
|
83
84
|
});
|
|
84
85
|
request.signal.throwIfAborted();
|
|
85
86
|
const response = await deps.fetch("https://api.inworld.ai/tts/v1/voice:stream", {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { providerError } from "../../kernel/ports/model.js";
|
|
4
|
+
import { editSettings } from "../../kernel/ports/settings-places.js";
|
|
4
5
|
import { defaultSpeechVoice, noSpeechFix, primaryLanguage, } from "../../kernel/ports/system-speech.js";
|
|
5
6
|
export const systemVoiceId = "system-voice";
|
|
6
7
|
// Windows speaks through System.Speech. Every input arrives in an environment variable, so no
|
|
@@ -48,7 +49,7 @@ export function systemTts(deps) {
|
|
|
48
49
|
kind: "unavailable",
|
|
49
50
|
message: found.engines.length === 0
|
|
50
51
|
? (found.issue ?? `No speech program was found on this computer, ${noSpeechFix}`)
|
|
51
|
-
: `The speech program "${model}" chosen for this narration isn't on this computer any more.
|
|
52
|
+
: `The speech program "${model}" chosen for this narration isn't on this computer any more. Pick another voice model (${found.engines.map((one) => one.name).join(", ")}) in ${editSettings.narration}, then use Continue the run.`,
|
|
52
53
|
});
|
|
53
54
|
};
|
|
54
55
|
return {
|
package/dist/catalog/registry.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { thinkingModes } from "../kernel/ports/llm.js";
|
|
2
2
|
import { providerError } from "../kernel/ports/model.js";
|
|
3
|
+
import { editSettings } from "../kernel/ports/settings-places.js";
|
|
3
4
|
import { isLocalCliProvider, systemVoiceProvider } from "../slices/settings/model.js";
|
|
4
5
|
import { editRefusal, referenceRefusal, takesReferenceImage } from "./schema.js";
|
|
6
|
+
// Where a project's settings choose the model of each family.
|
|
7
|
+
const modelPlace = {
|
|
8
|
+
llm: editSettings.writer,
|
|
9
|
+
tts: editSettings.narration,
|
|
10
|
+
image: editSettings.images,
|
|
11
|
+
};
|
|
5
12
|
export function curateRegistry(registry, catalogue) {
|
|
6
13
|
const requireModel = (provider, family, id) => {
|
|
7
14
|
const models = catalogue.models(provider, family);
|
|
@@ -9,7 +16,7 @@ export function curateRegistry(registry, catalogue) {
|
|
|
9
16
|
if (!model)
|
|
10
17
|
throw providerError({
|
|
11
18
|
kind: "unsupported",
|
|
12
|
-
message: `The chosen ${provider} model is no longer in Slopify's model list.
|
|
19
|
+
message: `The chosen ${provider} model is no longer in Slopify's model list. Pick another in ${modelPlace[family]}, then use Continue the run.`,
|
|
13
20
|
});
|
|
14
21
|
return model;
|
|
15
22
|
};
|
|
@@ -25,7 +32,7 @@ export function curateRegistry(registry, catalogue) {
|
|
|
25
32
|
if (request.model.trim() === "")
|
|
26
33
|
throw providerError({
|
|
27
34
|
kind: "unsupported",
|
|
28
|
-
message:
|
|
35
|
+
message: `No model is chosen for this step. Pick one in ${editSettings.writer}, then use Continue the run.`,
|
|
29
36
|
});
|
|
30
37
|
let models;
|
|
31
38
|
try {
|
|
@@ -39,19 +46,19 @@ export function curateRegistry(registry, catalogue) {
|
|
|
39
46
|
if (models !== undefined && selected === undefined)
|
|
40
47
|
throw providerError({
|
|
41
48
|
kind: "unsupported",
|
|
42
|
-
message:
|
|
49
|
+
message: `The chosen model is not available in the AI command-line tool on your computer. Update the tool, or pick another model in ${editSettings.writer}, then use Continue the run.`,
|
|
43
50
|
});
|
|
44
51
|
if (request.thinking !== undefined &&
|
|
45
52
|
selected !== undefined &&
|
|
46
53
|
!selected.thinkingModes?.includes(request.thinking))
|
|
47
54
|
throw providerError({
|
|
48
55
|
kind: "unsupported",
|
|
49
|
-
message:
|
|
56
|
+
message: `The chosen model does not support this Thinking level. Change it in ${editSettings.writer}, then use Continue the run.`,
|
|
50
57
|
});
|
|
51
58
|
if (request.webSearch && !port.capabilities.webSearch)
|
|
52
59
|
throw providerError({
|
|
53
60
|
kind: "unsupported",
|
|
54
|
-
message:
|
|
61
|
+
message: `This command-line tool cannot search the web for research. Choose another service in ${editSettings.writer}, or set Research source to Off in ${editSettings.article}, then use Continue the run.`,
|
|
55
62
|
});
|
|
56
63
|
const thinkingConfig = id === "codex" && request.thinking !== undefined
|
|
57
64
|
? { effort: request.thinking === "off" ? "none" : request.thinking }
|
|
@@ -80,13 +87,13 @@ export function curateRegistry(registry, catalogue) {
|
|
|
80
87
|
if (request.webSearch && !model.llm.webSearch)
|
|
81
88
|
throw providerError({
|
|
82
89
|
kind: "unsupported",
|
|
83
|
-
message:
|
|
90
|
+
message: `The chosen model cannot search the web for research. Choose another model in ${editSettings.writer}, or set Research source to Off in ${editSettings.article}, then use Continue the run.`,
|
|
84
91
|
});
|
|
85
92
|
const thinkingConfig = request.thinking === undefined ? undefined : model.llm.thinking?.[request.thinking];
|
|
86
93
|
if (request.thinking !== undefined && !thinkingConfig)
|
|
87
94
|
throw providerError({
|
|
88
95
|
kind: "unsupported",
|
|
89
|
-
message:
|
|
96
|
+
message: `The chosen model does not support this Thinking level. Change it in ${editSettings.writer}, then use Continue the run.`,
|
|
90
97
|
});
|
|
91
98
|
yield* port.complete({
|
|
92
99
|
...request,
|
|
@@ -107,14 +114,14 @@ export function curateRegistry(registry, catalogue) {
|
|
|
107
114
|
throw providerError({
|
|
108
115
|
kind: "unsupported",
|
|
109
116
|
message: request.model === "codex-imagegen"
|
|
110
|
-
?
|
|
111
|
-
:
|
|
117
|
+
? `Image generation is not available in the Codex CLI on your computer. Update Codex CLI, or choose another image service in ${editSettings.images}, then use Continue the run.`
|
|
118
|
+
: `The chosen Codex model for images is not in the Codex CLI's model list on your computer. Update Codex CLI, or pick another image model in ${editSettings.images}, then use Continue the run.`,
|
|
112
119
|
});
|
|
113
120
|
if (request.thinking !== undefined &&
|
|
114
121
|
!selected.thinkingModes?.includes(request.thinking))
|
|
115
122
|
throw providerError({
|
|
116
123
|
kind: "unsupported",
|
|
117
|
-
message:
|
|
124
|
+
message: `The chosen Codex model does not support this effort for images. Change Effort in ${editSettings.images}, then use Continue the run.`,
|
|
118
125
|
});
|
|
119
126
|
return port.generate(request);
|
|
120
127
|
},
|
|
@@ -128,12 +135,12 @@ export function curateRegistry(registry, catalogue) {
|
|
|
128
135
|
if (!("image" in model) || !model.image.aspectRatios.includes(request.aspect))
|
|
129
136
|
throw providerError({
|
|
130
137
|
kind: "unsupported",
|
|
131
|
-
message:
|
|
138
|
+
message: `The chosen image model cannot make images in this video's shape. Pick another in ${editSettings.images}, then use Continue the run.`,
|
|
132
139
|
});
|
|
133
140
|
if (request.thinking !== undefined)
|
|
134
141
|
throw providerError({
|
|
135
142
|
kind: "unsupported",
|
|
136
|
-
message:
|
|
143
|
+
message: `The chosen image model has no effort setting. Set Effort back to Model default in ${editSettings.images}, then use Continue the run.`,
|
|
137
144
|
});
|
|
138
145
|
if (request.edit !== undefined && !takesReferenceImage(model))
|
|
139
146
|
throw providerError({ kind: "unsupported", message: editRefusal });
|
|
@@ -164,7 +171,7 @@ export function curateRegistry(registry, catalogue) {
|
|
|
164
171
|
if (request.text.length > model.tts.maxCharacters)
|
|
165
172
|
throw providerError({
|
|
166
173
|
kind: "unsupported",
|
|
167
|
-
message: `A piece of narration is longer than this voice model's ${model.tts.maxCharacters}-character limit.
|
|
174
|
+
message: `A piece of narration is longer than this voice model's ${model.tts.maxCharacters}-character limit. Press Make the narration again in the project's Narration section, so Slopify splits it into shorter pieces.`,
|
|
168
175
|
});
|
|
169
176
|
return port.synthesize({ ...request, model: model.id });
|
|
170
177
|
},
|
package/dist/catalog/schema.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { thinkingModes } from "../kernel/ports/llm.js";
|
|
3
|
+
import { createRows, editSettings } from "../kernel/ports/settings-places.js";
|
|
3
4
|
import { providers } from "../slices/settings/model.js";
|
|
4
5
|
const money = z.number().finite().nonnegative();
|
|
5
6
|
const base = z.object({
|
|
@@ -105,7 +106,7 @@ export function takesReferenceImage(model) {
|
|
|
105
106
|
return model.keywords.includes("reference");
|
|
106
107
|
}
|
|
107
108
|
// What the run says when the chosen image model cannot take the establishing image.
|
|
108
|
-
export const referenceRefusal =
|
|
109
|
+
export const referenceRefusal = `The chosen image model can't use an establishing image as a reference, so the images can't be drawn to match it. Choose an image model that can (Codex CLI, OpenAI, Google, or a fal.ai model listed with reference) in ${createRows.images} or ${editSettings.images}, or set Establishing image to Off there.`;
|
|
109
110
|
// What a design's edit says when the chosen image model takes no input picture.
|
|
110
111
|
export const editRefusal = "This image model can't edit a picture. Choose Codex CLI, OpenAI, Google, or FLUX.2 or Nano Banana 2 on fal.ai under Made with … · change.";
|
|
111
112
|
// The image-to-video models a provider offers, as Animate images lists them.
|
package/dist/catalog/validate.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRows, editSettings } from "../kernel/ports/settings-places.js";
|
|
1
2
|
import { usesNarrationPreparation, usesReference, usesShorts, usesYoutubeDescription, } from "../slices/admission/rules.js";
|
|
2
3
|
import { isLocalCliProvider, isUncataloguedProvider } from "../slices/settings/model.js";
|
|
3
4
|
import { usesAnimation } from "../slices/video/edit-settings.js";
|
|
@@ -32,7 +33,9 @@ export function modelFields(draft, catalogue) {
|
|
|
32
33
|
},
|
|
33
34
|
];
|
|
34
35
|
for (const { field, family, choice, needed } of checks) {
|
|
35
|
-
|
|
36
|
+
// No model at all is admission's to say ("Choose a Service and a Model under …"): none was
|
|
37
|
+
// chosen, so none is "no longer" in the list.
|
|
38
|
+
if (!needed || !choice || choice.model === "" || isUncataloguedProvider(choice.provider))
|
|
36
39
|
continue;
|
|
37
40
|
const model = catalogue.models(choice.provider, family).find((m) => m.id === choice.model);
|
|
38
41
|
if (!model)
|
|
@@ -87,7 +90,7 @@ export function modelFields(draft, catalogue) {
|
|
|
87
90
|
if (offered.length === 0)
|
|
88
91
|
fields.push({
|
|
89
92
|
field: "videoEdit.animateModel",
|
|
90
|
-
message:
|
|
93
|
+
message: `This image service can't animate images. Choose fal.ai or Replicate as the image service (in ${createRows.images}, or ${editSettings.images}), or turn Animate images off.`,
|
|
91
94
|
});
|
|
92
95
|
else if (model.trim() !== "" && !offered.some((one) => one.id === model))
|
|
93
96
|
fields.push({
|
|
@@ -96,7 +96,7 @@ export function actionRoutes(deps) {
|
|
|
96
96
|
"revision-required": "This page is out of date. Reload the page, then try again.",
|
|
97
97
|
conflict: "This project changed since the page loaded. Reload the page to see the latest, then try again.",
|
|
98
98
|
"idempotency-conflict": "This action was already sent with different details. Reload the page, then try again.",
|
|
99
|
-
"rebuild-required": "This change needs some outputs to be made again.
|
|
99
|
+
"rebuild-required": "This change needs some outputs to be made again. Use Choose what to make again (in the project's More menu) to see what will be made again and what it costs.",
|
|
100
100
|
};
|
|
101
101
|
return problem(c, {
|
|
102
102
|
status: codes[result.reason],
|
|
@@ -127,13 +127,13 @@ export function actionRoutes(deps) {
|
|
|
127
127
|
"no-revision": "The project's saved settings changed since the page loaded. Reload the page, then try again.",
|
|
128
128
|
conflict: "This project changed since the page loaded. Reload the page to see the latest, then use Continue the run again.",
|
|
129
129
|
"idempotency-conflict": "This action was already sent with different details. Reload the page, then try again.",
|
|
130
|
-
"invalid-edit": "This section has settings that need fixing first.
|
|
130
|
+
"invalid-edit": "This section has settings that need fixing first. Correct this section in Edit settings, then try again.",
|
|
131
131
|
"stale-preview": "What needs to be made changed since the page loaded. Reload the page, then use Continue the run again.",
|
|
132
|
-
"invalid-selection": "This section has nothing generated to
|
|
133
|
-
"review-required": "Content you supplied or captions you edited by hand would be replaced. Change them in
|
|
134
|
-
"cost-ack-required": "
|
|
132
|
+
"invalid-selection": "This section has nothing generated to make again because its content was supplied by you. To change it, use Edit settings.",
|
|
133
|
+
"review-required": "Content you supplied or captions you edited by hand would be replaced. Change them in Edit settings, or use Choose what to make again (in the project's More menu) to confirm the replacement.",
|
|
134
|
+
"cost-ack-required": "Making this again needs you to review its cost first. Use Choose what to make again (in the project's More menu).",
|
|
135
135
|
readiness: "Slopify cannot run this yet. Check the provider, model, voice and any files you supplied, then use Continue the run.",
|
|
136
|
-
running: "This section is still running. Wait for it to finish, or Pause the project, before
|
|
136
|
+
running: "This section is still running. Wait for it to finish, or Pause the project, before making it again.",
|
|
137
137
|
"accepted-job": "This section has a finished provider job that Slopify has not collected yet.",
|
|
138
138
|
"control-changed": "Another action on this project (such as Pause or Cancel) happened at the same time. Reload the page to see its current state, then try again.",
|
|
139
139
|
};
|
|
@@ -143,7 +143,7 @@ export function actionRoutes(deps) {
|
|
|
143
143
|
...(result.intentRevisionId === undefined
|
|
144
144
|
? []
|
|
145
145
|
: [
|
|
146
|
-
"Your
|
|
146
|
+
"Your request to make it again was saved. Use Continue the run to go on with it instead of asking again.",
|
|
147
147
|
]),
|
|
148
148
|
].join(" ");
|
|
149
149
|
return problem(c, {
|
package/dist/edge/http/app.js
CHANGED
|
@@ -39,6 +39,7 @@ import { problem, problemFromError } from "./problem.js";
|
|
|
39
39
|
import { projectTemplateRoutes } from "./project-templates.js";
|
|
40
40
|
import { projectRoutes } from "./projects.js";
|
|
41
41
|
import { promptRoutes } from "./prompts.js";
|
|
42
|
+
import { pronunciationCheckRoutes } from "./pronunciation-check.js";
|
|
42
43
|
import { pronunciationRoutes } from "./pronunciations.js";
|
|
43
44
|
import { providerRoutes } from "./providers.js";
|
|
44
45
|
import { remoteAccessRoutes } from "./remote-access.js";
|
|
@@ -103,6 +104,7 @@ function apiRoutes(deps, startedAt, runAllowed) {
|
|
|
103
104
|
.route("/projects", openFolderRoutes(deps))
|
|
104
105
|
.route("/projects", audioPreviewRoutes(deps))
|
|
105
106
|
.route("/projects", narrationPeakRoutes(deps))
|
|
107
|
+
.route("/projects", pronunciationCheckRoutes(deps))
|
|
106
108
|
.route("/projects", runCostRoutes(deps))
|
|
107
109
|
.route("/projects", uploadedRoutes(deps))
|
|
108
110
|
.route("/home", homeRoutes(deps))
|
|
@@ -156,7 +158,7 @@ export function createApp(deps) {
|
|
|
156
158
|
return next();
|
|
157
159
|
return problem(c, {
|
|
158
160
|
status: 403,
|
|
159
|
-
detail: "Slopify doesn't answer the public internet: this request came through Tailscale Funnel. On the computer Slopify runs on, run tailscale funnel status to see which port has Funnel, turn it off with tailscale funnel --https=<that port> off, and open Slopify on your other devices through Settings →
|
|
161
|
+
detail: "Slopify doesn't answer the public internet: this request came through Tailscale Funnel. On the computer Slopify runs on, run tailscale funnel status to see which port has Funnel, turn it off with tailscale funnel --https=<that port> off, and open Slopify on your other devices through Settings → Remote access instead.",
|
|
160
162
|
});
|
|
161
163
|
})
|
|
162
164
|
// Only Slopify's own names, and changes only from its own page (`request-guard.ts`).
|
|
@@ -222,7 +224,7 @@ export function createApp(deps) {
|
|
|
222
224
|
return next();
|
|
223
225
|
return problem(c, {
|
|
224
226
|
status: 409,
|
|
225
|
-
detail: "This is
|
|
227
|
+
detail: "This is a sample project, which is read-only so trying things on it never spends anything. Press Make my own copy at the top right of its page, then change and make the copy again.",
|
|
226
228
|
extensions: { reason: "sample-read-only" },
|
|
227
229
|
});
|
|
228
230
|
})
|
|
@@ -236,7 +238,7 @@ export function createApp(deps) {
|
|
|
236
238
|
return next();
|
|
237
239
|
return problem(c, {
|
|
238
240
|
status: 409,
|
|
239
|
-
detail: `This is the
|
|
241
|
+
detail: `This is the sample project of the template ${owner.name}. Change the template in Edit template instead: Templates → ${owner.name} → Edit template.`,
|
|
240
242
|
extensions: { reason: "template-sample" },
|
|
241
243
|
});
|
|
242
244
|
})
|
|
@@ -48,15 +48,17 @@ runAllowed) {
|
|
|
48
48
|
reason: notWired,
|
|
49
49
|
fix: null,
|
|
50
50
|
preference: "auto",
|
|
51
|
+
ready: [],
|
|
51
52
|
session: null,
|
|
52
53
|
});
|
|
53
|
-
const { choice, preference } = await assistant.status();
|
|
54
|
+
const { choice, preference, ready } = await assistant.status();
|
|
54
55
|
return c.json({
|
|
55
56
|
available: choice.ok,
|
|
56
57
|
cli: choice.ok ? choice.cli : null,
|
|
57
58
|
reason: choice.ok ? null : choice.reason,
|
|
58
59
|
fix: choice.ok ? null : choice.fix,
|
|
59
60
|
preference,
|
|
61
|
+
ready,
|
|
60
62
|
session: assistant.session() ?? null,
|
|
61
63
|
});
|
|
62
64
|
})
|
|
@@ -3,7 +3,7 @@ import { Hono } from "hono";
|
|
|
3
3
|
import { HTTPException } from "hono/http-exception";
|
|
4
4
|
import { backupConfigInputSchema } from "../../slices/backups/model.js";
|
|
5
5
|
import { onInvalid, problem } from "./problem.js";
|
|
6
|
-
// Settings →
|
|
6
|
+
// Settings → Backup & storage: the schedule, the folder, the last result and Back up now. Writing an
|
|
7
7
|
// archive takes minutes, so Back up now answers at once and the screen polls this view.
|
|
8
8
|
export function backupRoutes(service) {
|
|
9
9
|
const backups = () => {
|
|
@@ -72,8 +72,8 @@ function refused(c, result, about) {
|
|
|
72
72
|
const detail = result.message ??
|
|
73
73
|
(result.reason === "not-found"
|
|
74
74
|
? about === "episode"
|
|
75
|
-
? "This channel or episode summary no longer exists; it may have been deleted in another tab. Reload the channel's
|
|
76
|
-
: "This channel or video title no longer exists; it may have been deleted in another tab. Reload the channel's
|
|
75
|
+
? "This channel or episode summary no longer exists; it may have been deleted in another tab. Reload the channel's Memory tab."
|
|
76
|
+
: "This channel or video title no longer exists; it may have been deleted in another tab. Reload the channel's Titles to avoid tab."
|
|
77
77
|
: "This request isn't valid. Reload the page and try again.");
|
|
78
78
|
return refusal(c, result.reason, { statuses: { "not-found": 404 }, otherwise: 400, detail });
|
|
79
79
|
}
|
|
@@ -109,7 +109,7 @@ const details = {
|
|
|
109
109
|
"has-templates": "This channel still has templates. Move them to another channel in its Templates tab, or delete them, then delete the channel.",
|
|
110
110
|
"not-an-image": "This file is not a PNG or JPEG picture. Upload a PNG or JPEG file.",
|
|
111
111
|
"too-many-images": "This cast member already has the most pictures it can keep. Delete one first.",
|
|
112
|
-
"no-image-provider": "Slopify can't make pictures here yet. Set up an image
|
|
112
|
+
"no-image-provider": "Slopify can't make pictures here yet. Set up an image service in Settings → Keys & services, or upload a picture instead.",
|
|
113
113
|
};
|
|
114
114
|
function refused(c, result) {
|
|
115
115
|
return refusal(c, result.reason, {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { zValidator } from "@hono/zod-validator";
|
|
2
2
|
import { Hono } from "hono";
|
|
3
3
|
import { errorText } from "../../kernel/errors.js";
|
|
4
|
+
import { stageWords } from "../../kernel/pipeline.js";
|
|
4
5
|
import { projectPaused } from "../../slices/admission/repo.js";
|
|
5
6
|
import { changeCheckpoints, checkpointChangeSchema, readCheckpointStatus, replayCheckpointApproval, validateCheckpointApproval, } from "../../slices/checkpoints/change.js";
|
|
6
7
|
import { listCheckpoints } from "../../slices/checkpoints/repo.js";
|
|
@@ -21,25 +22,26 @@ function refused(c, reason) {
|
|
|
21
22
|
statuses: { "not-found": 404, "invalid-input": 400 },
|
|
22
23
|
otherwise: 409,
|
|
23
24
|
detail: reason === "not-found"
|
|
24
|
-
? "This
|
|
25
|
+
? "This pause no longer exists; the project may have moved on or changed. Reload the page to see where it is now."
|
|
25
26
|
: reason === "invalid-input"
|
|
26
|
-
? "This
|
|
27
|
-
: "This
|
|
27
|
+
? "This answer to the pause could not be read. Reload the page and try again."
|
|
28
|
+
: "This pause changed since the page loaded, for example it was already approved. Reload the page to see its current state, then try again.",
|
|
28
29
|
});
|
|
29
30
|
}
|
|
30
31
|
// Taking a checkpoint off that holds the run now would start the paid steps behind it without
|
|
31
32
|
// the review: that goes through Approve, which checks what is approved is what was looked at.
|
|
32
33
|
function heldThere(c, stage) {
|
|
34
|
+
const name = stageWords[stage];
|
|
33
35
|
return problem(c, {
|
|
34
36
|
status: 409,
|
|
35
|
-
detail: `The run is waiting
|
|
37
|
+
detail: `The run is waiting for your review before ${name}, so that pause can't be taken off now: that would start the next steps without the review. Look over what is made, then press Approve and make the ${name.toLowerCase()} (agents: approve_checkpoint).`,
|
|
36
38
|
extensions: { reason: "held-at-checkpoint" },
|
|
37
39
|
});
|
|
38
40
|
}
|
|
39
41
|
function alreadyApproved(c) {
|
|
40
42
|
return problem(c, {
|
|
41
43
|
status: 409,
|
|
42
|
-
detail: "This
|
|
44
|
+
detail: "This pause was already approved, so nothing changed. Reload the page (or call needs_attention) to see what waits now.",
|
|
43
45
|
extensions: { reason: "already-approved" },
|
|
44
46
|
});
|
|
45
47
|
}
|
|
@@ -22,7 +22,7 @@ export const sampleRequestSchema = z
|
|
|
22
22
|
const quoteBodySchema = z.object({ document: designDocumentSchema }).strict();
|
|
23
23
|
const notFoundRefusal = {
|
|
24
24
|
reason: "not-found",
|
|
25
|
-
message: "This design template no longer exists. Open
|
|
25
|
+
message: "This design template no longer exists. Open Templates → Poster templates to choose another.",
|
|
26
26
|
};
|
|
27
27
|
export function designTemplateRoutes(deps) {
|
|
28
28
|
const unavailable = (c) => problem(c, {
|
|
@@ -44,7 +44,7 @@ export function designTemplateRoutes(deps) {
|
|
|
44
44
|
return template === undefined
|
|
45
45
|
? designRefused(c, {
|
|
46
46
|
reason: "not-found",
|
|
47
|
-
message: "This design template no longer exists. Open
|
|
47
|
+
message: "This design template no longer exists. Open Templates → Poster templates to choose another.",
|
|
48
48
|
})
|
|
49
49
|
: c.json({ ...template, sample: deps.samples?.state?.(template.id) ?? null });
|
|
50
50
|
})
|
|
@@ -90,7 +90,7 @@ export function designTemplateRoutes(deps) {
|
|
|
90
90
|
? c.body(null, 204)
|
|
91
91
|
: designRefused(c, {
|
|
92
92
|
reason: "not-found",
|
|
93
|
-
message: "This design template no longer exists. Open
|
|
93
|
+
message: "This design template no longer exists. Open Templates → Poster templates to choose another.",
|
|
94
94
|
});
|
|
95
95
|
})
|
|
96
96
|
.post("/:id/quote", zValidator("param", idParam, onInvalid), async (c) => {
|
|
@@ -97,7 +97,7 @@ export function designRoutes(deps) {
|
|
|
97
97
|
if (!result.ok)
|
|
98
98
|
return designRefused(c, {
|
|
99
99
|
reason: "not-found",
|
|
100
|
-
message: "This design no longer exists.
|
|
100
|
+
message: "This design no longer exists. Go back to Designs to choose another.",
|
|
101
101
|
});
|
|
102
102
|
deps.service.emit?.({ type: "design.changed", designId: id });
|
|
103
103
|
return c.body(null, 204);
|
|
@@ -51,11 +51,11 @@ function refused(c, failure) {
|
|
|
51
51
|
case "invalid":
|
|
52
52
|
return problem(c, {
|
|
53
53
|
status: 400,
|
|
54
|
-
detail: "This
|
|
54
|
+
detail: "This look can't be saved yet. Fix the highlighted settings and try again.",
|
|
55
55
|
extensions: { fields: failure.fields },
|
|
56
56
|
});
|
|
57
57
|
case "duplicate-name": {
|
|
58
|
-
const message = "Another PDF
|
|
58
|
+
const message = "Another PDF look already has this name. Choose a different name.";
|
|
59
59
|
return problem(c, {
|
|
60
60
|
status: 409,
|
|
61
61
|
detail: message,
|
|
@@ -65,7 +65,7 @@ function refused(c, failure) {
|
|
|
65
65
|
case "not-found":
|
|
66
66
|
return problem(c, {
|
|
67
67
|
status: 404,
|
|
68
|
-
detail: "This PDF
|
|
68
|
+
detail: "This PDF look no longer exists; it may have been deleted in another tab. Go back to the PDF looks (Settings → Production defaults → Edit PDF looks).",
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -3,7 +3,7 @@ export function draftProblem(c, result) {
|
|
|
3
3
|
const { ok: _ok, ...extensions } = result;
|
|
4
4
|
const details = {
|
|
5
5
|
"not-found": "This draft no longer exists; it may have been started or deleted. Reload the page to start a new one.",
|
|
6
|
-
"invalid-draft": "This saved draft could not be read. Reload the page and set the video up again
|
|
6
|
+
"invalid-draft": "This saved draft could not be read. Reload the page and set the video up again on Create.",
|
|
7
7
|
conflict: "This draft changed in another tab or window. Reload the page to see the latest, then make your change again.",
|
|
8
8
|
"invalid-edit": "Some settings need fixing. Fix the highlighted fields, then try again.",
|
|
9
9
|
"pending-start": "This video is already starting. Wait a moment, then find it in Projects.",
|
|
@@ -21,7 +21,7 @@ export function extensionAuth(db) {
|
|
|
21
21
|
const refused = (c) => problem(c, {
|
|
22
22
|
status: 401,
|
|
23
23
|
title: "Unauthorized",
|
|
24
|
-
detail: "The Slopify Studio extension isn't paired with this Slopify. Copy the pairing token from Slopify's Settings → YouTube Studio into the extension's options and press Pair.",
|
|
24
|
+
detail: "The Slopify Studio extension isn't paired with this Slopify. Copy the pairing token from Slopify's Settings → YouTube Studio and posting into the extension's options and press Pair.",
|
|
25
25
|
});
|
|
26
26
|
return { allowOrigin, allowed, refused };
|
|
27
27
|
}
|
package/dist/edge/http/home.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { zValidator } from "@hono/zod-validator";
|
|
2
2
|
import { Hono } from "hono";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { transact } from "../../kernel/db/tx.js";
|
|
4
5
|
import { snoozeDays } from "../../slices/autopilot/model.js";
|
|
5
6
|
import { setWeeklyNotify, snoozeWarning, weeklyNotifyOf } from "../../slices/autopilot/repo.js";
|
|
6
7
|
import { autopilotView } from "../../slices/autopilot/signals.js";
|
|
7
8
|
import { weekSummary } from "../../slices/run-cost/week.js";
|
|
9
|
+
import { markNotUploaded } from "../../slices/studio/videos.js";
|
|
8
10
|
import { notReadySentence, runnableTemplate } from "../../slices/template-studio/schedule-gate.js";
|
|
9
11
|
import { markUploaded, setAside } from "../../slices/uploads/repo.js";
|
|
10
12
|
import { idParam, idString } from "./ids.js";
|
|
@@ -65,7 +67,13 @@ export function uploadedRoutes(deps) {
|
|
|
65
67
|
return c.json({ setAside: c.req.valid("json").setAside });
|
|
66
68
|
})
|
|
67
69
|
.put("/:id/uploaded", zValidator("param", idParam, onInvalid), zValidator("json", z.object({ uploaded: z.boolean() }).strict(), onInvalid), (c) => {
|
|
68
|
-
const
|
|
70
|
+
const { id } = c.req.valid("param");
|
|
71
|
+
const at = deps.clock.now().toISOString();
|
|
72
|
+
// The long video's YouTube link and the mark are one fact (`studio/videos.ts`):
|
|
73
|
+
// Mark not uploaded forgets the link too.
|
|
74
|
+
const result = c.req.valid("json").uploaded
|
|
75
|
+
? markUploaded(deps.db, id, true, at)
|
|
76
|
+
: transact(deps.db, () => markNotUploaded(deps.db, id, at));
|
|
69
77
|
if (!result.ok)
|
|
70
78
|
return problem(c, {
|
|
71
79
|
status: 404,
|
|
@@ -5,7 +5,7 @@ import { errorText } from "../../kernel/errors.js";
|
|
|
5
5
|
import { providerFamilies } from "../../kernel/ports/model.js";
|
|
6
6
|
import { autoModes } from "../../slices/model-checks/model.js";
|
|
7
7
|
import { accountOf, markNoticesSeen, writeAuto } from "../../slices/model-checks/repo.js";
|
|
8
|
-
import { dollarsText } from "../../slices/model-checks/rules.js";
|
|
8
|
+
import { costPhrase, dollarsText } from "../../slices/model-checks/rules.js";
|
|
9
9
|
import { providerById, providerIds } from "../../slices/settings/model.js";
|
|
10
10
|
import { onInvalid, problem } from "./problem.js";
|
|
11
11
|
const providerParam = z.object({ id: z.enum(providerIds) });
|
|
@@ -50,8 +50,8 @@ function noAccount(c, id) {
|
|
|
50
50
|
return problem(c, {
|
|
51
51
|
status: 400,
|
|
52
52
|
detail: auth === "key"
|
|
53
|
-
? `No ${displayName} key is saved, so its models can't be checked. Paste a key in Settings →
|
|
54
|
-
: `${displayName} is not set up, so its models can't be checked. Set it up in Settings →
|
|
53
|
+
? `No ${displayName} key is saved, so its models can't be checked. Paste a key in Settings → Keys & services → ${displayName} and choose Save, then choose Check models in Settings → Models.`
|
|
54
|
+
: `${displayName} is not set up, so its models can't be checked. Set it up in Settings → Keys & services, then choose Check models in Settings → Models.`,
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
// The provider-scoped half: its estimate and its Check models button.
|
|
@@ -98,7 +98,7 @@ export function providerCheckRoutes(deps) {
|
|
|
98
98
|
const estimate = estimateOf(answer.plan);
|
|
99
99
|
return problem(c, {
|
|
100
100
|
status: 409,
|
|
101
|
-
detail: `Checking ${String(estimate.count)} ${name} model${estimate.count === 1 ? "" : "s"} costs ${estimate.
|
|
101
|
+
detail: `Checking ${String(estimate.count)} ${name} model${estimate.count === 1 ? "" : "s"} costs ${costPhrase(estimate.totalDollars, estimate.unpriced)}, and nothing was sent yet. Choose Check models in Settings → Models again and confirm the estimate to go ahead.`,
|
|
102
102
|
extensions: { estimate },
|
|
103
103
|
});
|
|
104
104
|
}
|