@gentbajko/slopify 2.5.0 → 3.0.1
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/LICENSE +201 -21
- package/NOTICE +12 -0
- package/README.md +24 -41
- package/SUBTITLES.md +1 -1
- package/dist/adapter-registry.js +31 -0
- package/dist/adapters/alignment/cache.js +4 -1
- package/dist/adapters/alignment/ctc.js +25 -23
- package/dist/adapters/alignment/index.js +37 -6
- package/dist/adapters/alignment/multilingual.js +267 -0
- package/dist/adapters/alignment/protocol.js +11 -0
- package/dist/adapters/alignment/quality.js +4 -3
- package/dist/adapters/alignment/sentences.js +95 -0
- package/dist/adapters/alignment/spec.js +24 -0
- package/dist/adapters/alignment/spell.js +769 -0
- package/dist/adapters/alignment/text.js +56 -9
- package/dist/adapters/alignment/window.js +34 -30
- package/dist/adapters/alignment/worker.js +23 -21
- package/dist/adapters/explain.js +11 -11
- package/dist/adapters/host-cli/index.js +44 -5
- package/dist/adapters/host-cli/transport.js +7 -5
- package/dist/adapters/image/bytes.js +2 -2
- package/dist/adapters/image/codex-output.js +1 -1
- package/dist/adapters/image/codex.js +87 -22
- package/dist/adapters/image/fal.js +13 -5
- package/dist/adapters/image/google.js +11 -8
- package/dist/adapters/image/openai.js +14 -7
- package/dist/adapters/image/reference.js +34 -0
- package/dist/adapters/image/replicate.js +7 -2
- package/dist/adapters/image/video.js +2 -2
- package/dist/adapters/key-probes.js +85 -0
- package/dist/adapters/llm/claude-code.js +168 -32
- package/dist/adapters/llm/cli-login-error.js +1 -1
- package/dist/adapters/llm/codex-limits.js +157 -0
- package/dist/adapters/llm/codex.js +99 -12
- package/dist/adapters/llm/document-workspace.js +2 -2
- package/dist/adapters/llm/gemini-workspace.js +1 -1
- package/dist/adapters/llm/gemini.js +16 -3
- package/dist/adapters/llm/image-workspace.js +58 -0
- package/dist/adapters/llm/openrouter.js +11 -3
- package/dist/adapters/llm/run-cli.js +12 -7
- package/dist/adapters/tts/cartesia.js +10 -0
- package/dist/adapters/tts/elevenlabs.js +31 -9
- package/dist/adapters/tts/gemini.js +206 -0
- package/dist/adapters/tts/inworld-async.js +9 -5
- package/dist/adapters/tts/inworld.js +17 -3
- package/dist/adapters/tts/openai.js +3 -0
- package/dist/adapters/tts/pcm-mp3.js +62 -0
- package/dist/adapters/tts/system.js +147 -0
- package/dist/adapters/tts/voice-languages.js +80 -0
- package/dist/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/NotoSansArabic-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/NotoSansDevanagari-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/NotoSansHebrew-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/NotoSansThai-Regular.ttf +0 -0
- package/dist/assets/fonts/noto/OFL.txt +93 -0
- package/dist/assets/fonts/noto/SOURCE.txt +18 -0
- package/dist/assets/models.yaml +38 -0
- package/dist/assets/sample/sample-audiobook.tar +0 -0
- package/dist/assets/sample/sample-podcast.tar +0 -0
- package/dist/assets/sample/sample-project.tar +0 -0
- package/dist/assets/style-preview/narration.mp3 +0 -0
- package/dist/assets/style-preview/tall-1.jpg +0 -0
- package/dist/assets/style-preview/tall-2.jpg +0 -0
- package/dist/assets/style-preview/tall-3.jpg +0 -0
- package/dist/assets/style-preview/wide-1.jpg +0 -0
- package/dist/assets/style-preview/wide-2.jpg +0 -0
- package/dist/assets/style-preview/wide-3.jpg +0 -0
- package/dist/catalog/merge.js +132 -0
- package/dist/catalog/registry.js +17 -14
- package/dist/catalog/schema.js +2 -0
- package/dist/catalog/store.js +147 -8
- package/dist/catalog/validate.js +2 -2
- package/dist/compose.yaml +71 -0
- package/dist/edge/autostart/docker-record.js +32 -0
- package/dist/edge/autostart/docker.js +118 -0
- package/dist/edge/autostart/index.js +78 -0
- package/dist/edge/autostart/launcher.js +176 -0
- package/dist/edge/autostart/model.js +3 -0
- package/dist/edge/autostart/native.js +210 -0
- package/dist/edge/autostart/prompt.js +72 -0
- package/dist/edge/autostart/service.js +90 -0
- package/dist/edge/cli-args.js +71 -0
- package/dist/edge/cli.js +64 -63
- package/dist/edge/docker-install/activation.js +56 -0
- package/dist/edge/docker-install/apply.js +458 -0
- package/dist/edge/docker-install/engine.js +362 -0
- package/dist/edge/docker-install/run.js +160 -0
- package/dist/edge/docker-install/state.js +146 -0
- package/dist/edge/{docker-projects → docker-install}/volume.js +1 -5
- package/dist/edge/docker.js +14 -22
- package/dist/edge/events/hub.js +3 -1
- package/dist/edge/host-cli.js +1 -1
- package/dist/edge/http/actions.js +38 -11
- package/dist/edge/http/app.js +60 -2
- package/dist/edge/http/auditions.js +70 -0
- package/dist/edge/http/autostart.js +37 -0
- package/dist/edge/http/byte-range.js +42 -0
- package/dist/edge/http/channel-memory.js +92 -0
- package/dist/edge/http/channels.js +128 -0
- package/dist/edge/http/diagnostics.js +1 -0
- package/dist/edge/http/draft-files.js +2 -4
- package/dist/edge/http/entries.js +22 -3
- package/dist/edge/http/files.js +11 -7
- package/dist/edge/http/folder-location.js +1 -1
- package/dist/edge/http/home.js +39 -0
- package/dist/edge/http/host-cli.js +29 -5
- package/dist/edge/http/narration-peaks.js +76 -0
- package/dist/edge/http/onboarding.js +212 -0
- package/dist/edge/http/open-folder.js +1 -1
- package/dist/edge/http/patch-notes.js +45 -0
- package/dist/edge/http/planning.js +4 -2
- package/dist/edge/http/project-create.js +87 -0
- package/dist/edge/http/project-templates.js +19 -2
- package/dist/edge/http/projects.js +37 -100
- package/dist/edge/http/prompts.js +40 -3
- package/dist/edge/http/pronunciations.js +23 -4
- package/dist/edge/http/providers.js +119 -3
- package/dist/edge/http/reviews.js +131 -0
- package/dist/edge/http/revision-files.js +3 -5
- package/dist/edge/http/revisions.js +1 -1
- package/dist/edge/http/run-cost.js +25 -0
- package/dist/edge/http/schedules.js +115 -6
- package/dist/edge/http/settings.js +84 -6
- package/dist/edge/http/storage-files.js +50 -0
- package/dist/edge/http/storage.js +43 -2
- package/dist/edge/http/studio.js +287 -0
- package/dist/edge/http/style-preview.js +61 -0
- package/dist/edge/http/subtitles.js +1 -1
- package/dist/edge/http/trash.js +69 -0
- package/dist/edge/http/tutorials.js +59 -0
- package/dist/edge/http/update.js +24 -3
- package/dist/edge/http/whats-new.js +15 -0
- package/dist/edge/http/youtube-edits.js +92 -0
- package/dist/edge/native-update.js +62 -0
- package/dist/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/host-cli/gemini-login.js +83 -0
- package/dist/host-cli/open-folder.js +10 -10
- package/dist/host-cli/runtime.js +9 -1
- package/dist/host-cli/status.js +4 -2
- package/dist/kernel/db/migrations/0025-automatic-reviews.sql +40 -0
- package/dist/kernel/db/migrations/0026-schedule-topic-generation.sql +23 -0
- package/dist/kernel/db/migrations/0027-run-cost.sql +58 -0
- package/dist/kernel/db/migrations/0030-automatic-retries.sql +18 -0
- package/dist/kernel/db/migrations/0031-prompt-history-and-description-edits.sql +33 -0
- package/dist/kernel/db/migrations/0032-channels.sql +65 -0
- package/dist/kernel/db/migrations/0034-script-prompts.sql +23 -0
- package/dist/kernel/db/migrations/0035-narration-aliases.sql +13 -0
- package/dist/kernel/db/migrations/0037-project-uploads.sql +8 -0
- package/dist/kernel/db/migrations/0038-voice-languages.sql +7 -0
- package/dist/kernel/db/migrations/0039-channel-essentials.sql +64 -0
- package/dist/kernel/db/migrations/0040-standalone-usage.sql +35 -0
- package/dist/kernel/db/migrations/0041-cast-hosts.sql +3 -0
- package/dist/kernel/paths.js +27 -6
- package/dist/kernel/pipeline.js +4 -1
- package/dist/kernel/ports/host-cli.js +122 -14
- package/dist/kernel/ports/key-probe.js +1 -0
- package/dist/kernel/ports/languages.js +157 -0
- package/dist/kernel/ports/model.js +10 -5
- package/dist/kernel/ports/narration-aliases.js +60 -0
- package/dist/kernel/ports/plan-limits.js +36 -0
- package/dist/kernel/ports/system-speech.js +203 -0
- package/dist/kernel/runner/attempt.js +17 -8
- package/dist/kernel/runner/audition.js +36 -0
- package/dist/kernel/runner/graph.js +40 -5
- package/dist/kernel/runner/index.js +39 -9
- package/dist/kernel/runner/meter.js +1 -0
- package/dist/kernel/runner/providers.js +142 -7
- package/dist/kernel/runner/retry-policy.js +43 -0
- package/dist/kernel/runner/standalone.js +134 -0
- package/dist/kernel/runner/work-authority.js +28 -2
- package/dist/main.js +277 -16
- package/dist/model-catalog.js +2 -0
- package/dist/patch-notes/0.4.2-to-1.0.md +93 -0
- package/dist/patch-notes/1.0-to-2.0.md +74 -0
- package/dist/patch-notes/2.0-to-3.0.md +257 -0
- package/dist/patch-notes/3.0.0.md +70 -0
- package/dist/patch-notes/3.0.1.md +105 -0
- package/dist/patch-notes/index.json +32 -0
- package/dist/slices/admission/model.js +27 -0
- package/dist/slices/admission/repo.js +24 -4
- package/dist/slices/admission/rules.js +80 -2
- package/dist/slices/admission/schema.js +58 -1
- package/dist/slices/admission/short-mode.js +47 -0
- package/dist/slices/admission/start.js +42 -6
- package/dist/slices/article/continuation.js +2 -2
- package/dist/slices/article/provided-entries.js +2 -2
- package/dist/slices/article/run.js +6 -2
- package/dist/slices/article/segments.js +3 -3
- package/dist/slices/backups/folder.js +14 -6
- package/dist/slices/batch/index.js +7 -2
- package/dist/slices/cancel/index.js +1 -1
- package/dist/slices/channels/cast-images.js +110 -0
- package/dist/slices/channels/cast-match.js +32 -0
- package/dist/slices/channels/images.js +19 -0
- package/dist/slices/channels/model.js +5 -0
- package/dist/slices/channels/rebrand.js +100 -0
- package/dist/slices/channels/repo.js +221 -0
- package/dist/slices/channels/runs.js +129 -0
- package/dist/slices/channels/schema.js +152 -0
- package/dist/slices/channels/service.js +180 -0
- package/dist/slices/channels/studio-csv.js +110 -0
- package/dist/slices/channels/videos.js +120 -0
- package/dist/slices/checkpoints/recovery.js +10 -0
- package/dist/slices/control/index.js +5 -2
- package/dist/slices/control/providers.js +4 -1
- package/dist/slices/document/fonts.js +1 -1
- package/dist/slices/document/render.js +1 -1
- package/dist/slices/episodes/related.js +90 -0
- package/dist/slices/episodes/repo.js +60 -0
- package/dist/slices/episodes/service.js +58 -0
- package/dist/slices/episodes/summarize.js +170 -0
- package/dist/slices/estimate/index.js +109 -28
- package/dist/slices/estimate/requests.js +68 -2
- package/dist/slices/eta/history.js +56 -0
- package/dist/slices/eta/model.js +63 -0
- package/dist/slices/eta/view.js +25 -0
- package/dist/slices/fixes/rules.js +73 -0
- package/dist/slices/fonts/coverage.js +82 -0
- package/dist/slices/fonts/sfnt.js +74 -0
- package/dist/slices/images/run.js +8 -5
- package/dist/slices/images/scale.js +84 -0
- package/dist/slices/library/diff.js +122 -0
- package/dist/slices/library/history.js +100 -0
- package/dist/slices/library/model.js +3 -0
- package/dist/slices/library/photorealistic.js +49 -0
- package/dist/slices/library/repo.js +19 -14
- package/dist/slices/library/save.js +62 -12
- package/dist/slices/library/slots.js +7 -1
- package/dist/slices/library/used-by.js +153 -0
- package/dist/slices/loudness/level-pieces.js +41 -0
- package/dist/slices/loudness/loudnorm.js +164 -0
- package/dist/slices/loudness/model.js +153 -0
- package/dist/slices/model-upkeep/model.js +10 -0
- package/dist/slices/model-upkeep/switch.js +217 -0
- package/dist/slices/model-upkeep/usage.js +185 -0
- package/dist/slices/narration/aliases-library.js +31 -0
- package/dist/slices/narration/aliases-schema.js +53 -0
- package/dist/slices/narration/aliases.js +49 -0
- package/dist/slices/narration/blocks.js +352 -0
- package/dist/slices/narration/chunk.js +19 -7
- package/dist/slices/narration/concat.js +2 -2
- package/dist/slices/narration/describe.js +45 -0
- package/dist/slices/narration/pauses-model.js +63 -0
- package/dist/slices/narration/pauses.js +269 -0
- package/dist/slices/narration/peaks-model.js +1 -0
- package/dist/slices/narration/peaks.js +94 -0
- package/dist/slices/narration/preparation.js +21 -3
- package/dist/slices/narration/pronunciation-chunks.js +3 -3
- package/dist/slices/narration/pronunciation.js +72 -25
- package/dist/slices/narration/run.js +6 -6
- package/dist/slices/narration/shared-glossary.js +1 -1
- package/dist/slices/narration/steering.js +15 -4
- package/dist/slices/notifications/notifier.js +47 -3
- package/dist/slices/notifications/rules.js +48 -3
- package/dist/slices/onboarding/copy.js +143 -0
- package/dist/slices/onboarding/first-run.js +72 -0
- package/dist/slices/onboarding/full-video.js +81 -0
- package/dist/slices/onboarding/install.js +119 -0
- package/dist/slices/onboarding/model.js +85 -0
- package/dist/slices/onboarding/packs.js +491 -0
- package/dist/slices/onboarding/quick-short.js +144 -0
- package/dist/slices/onboarding/sample.js +132 -0
- package/dist/slices/onboarding/state.js +68 -0
- package/dist/slices/onboarding/template.js +73 -0
- package/dist/slices/patch-notes/library.js +73 -0
- package/dist/slices/patch-notes/seen.js +77 -0
- package/dist/slices/play-drafts/convert.js +127 -8
- package/dist/slices/play-drafts/readiness.js +4 -1
- package/dist/slices/play-drafts/repo.js +2 -0
- package/dist/slices/play-drafts/review-inputs.js +20 -3
- package/dist/slices/play-drafts/schema.js +89 -0
- package/dist/slices/play-drafts/service.js +4 -1
- package/dist/slices/play-drafts/start.js +43 -18
- package/dist/slices/project-templates/from-project.js +59 -6
- package/dist/slices/project-templates/next-chapter.js +94 -0
- package/dist/slices/project-templates/one-off.js +26 -0
- package/dist/slices/project-templates/repo.js +2 -1
- package/dist/slices/project-templates/schema.js +7 -1
- package/dist/slices/project-templates/service.js +15 -4
- package/dist/slices/project-templates/setup.js +18 -2
- package/dist/slices/rebuild/admission-repo.js +1 -1
- package/dist/slices/rebuild/model.js +6 -0
- package/dist/slices/rebuild/preview-details.js +46 -3
- package/dist/slices/rebuild/preview-plan.js +13 -6
- package/dist/slices/rebuild/recipe-audio-parts.js +40 -7
- package/dist/slices/rebuild/recipe-audio.js +66 -12
- package/dist/slices/rebuild/recipe-build.js +8 -4
- package/dist/slices/rebuild/recipe-cast.js +18 -0
- package/dist/slices/rebuild/recipe-checkpoints.js +11 -9
- package/dist/slices/rebuild/recipe-describe.js +93 -0
- package/dist/slices/rebuild/recipe-edit.js +13 -1
- package/dist/slices/rebuild/recipe-exports.js +67 -8
- package/dist/slices/rebuild/recipe-input-schema.js +35 -0
- package/dist/slices/rebuild/recipe-legacy.js +9 -0
- package/dist/slices/rebuild/recipe-loudness.js +45 -0
- package/dist/slices/rebuild/recipe-model.js +25 -6
- package/dist/slices/rebuild/recipe-pauses.js +7 -0
- package/dist/slices/rebuild/recipe-preparation.js +3 -3
- package/dist/slices/rebuild/recipe-provider-choice.js +11 -1
- package/dist/slices/rebuild/recipe-reference.js +15 -1
- package/dist/slices/rebuild/recipe-reviews.js +117 -0
- package/dist/slices/rebuild/recipe-save.js +4 -1
- package/dist/slices/rebuild/recipe-shorts.js +23 -3
- package/dist/slices/rebuild/recipe-text.js +114 -19
- package/dist/slices/rebuild/recipe-validation.js +14 -2
- package/dist/slices/rebuild/recipe-visual.js +96 -33
- package/dist/slices/rebuild/recipe-voices.js +286 -0
- package/dist/slices/rebuild/recipe-work.js +77 -6
- package/dist/slices/rebuild/recipe-youtube.js +2 -0
- package/dist/slices/rebuild/recovery-conflict.js +7 -3
- package/dist/slices/rebuild/recovery-model.js +3 -0
- package/dist/slices/rebuild/recovery-selection.js +28 -2
- package/dist/slices/rebuild/recovery.js +35 -17
- package/dist/slices/rebuild/repo.js +3 -3
- package/dist/slices/rebuild/retry.js +18 -0
- package/dist/slices/rebuild/review-redo.js +125 -0
- package/dist/slices/rebuild/runtime-actions.js +5 -0
- package/dist/slices/rebuild/runtime-admission.js +4 -1
- package/dist/slices/rebuild/runtime-animate.js +4 -4
- package/dist/slices/rebuild/runtime-article.js +5 -5
- package/dist/slices/rebuild/runtime-document.js +4 -4
- package/dist/slices/rebuild/runtime-export-bed.js +43 -0
- package/dist/slices/rebuild/runtime-export-edit.js +70 -11
- package/dist/slices/rebuild/runtime-export-inputs.js +52 -10
- package/dist/slices/rebuild/runtime-export-short.js +85 -0
- package/dist/slices/rebuild/runtime-export.js +84 -19
- package/dist/slices/rebuild/runtime-figure-card.js +87 -0
- package/dist/slices/rebuild/runtime-image.js +21 -2
- package/dist/slices/rebuild/runtime-local.js +148 -24
- package/dist/slices/rebuild/runtime-materialize.js +8 -0
- package/dist/slices/rebuild/runtime-narration-reuse.js +2 -1
- package/dist/slices/rebuild/runtime-narration-text.js +7 -7
- package/dist/slices/rebuild/runtime-pictures.js +28 -0
- package/dist/slices/rebuild/runtime-piece-label.js +27 -0
- package/dist/slices/rebuild/runtime-provider.js +126 -18
- package/dist/slices/rebuild/runtime-publication.js +21 -5
- package/dist/slices/rebuild/runtime-review.js +267 -0
- package/dist/slices/rebuild/runtime-run.js +17 -11
- package/dist/slices/rebuild/runtime-shorts.js +44 -17
- package/dist/slices/rebuild/runtime-store.js +62 -11
- package/dist/slices/rebuild/runtime-subtitles.js +72 -19
- package/dist/slices/rebuild/runtime-voices.js +103 -0
- package/dist/slices/rebuild/runtime-youtube.js +7 -6
- package/dist/slices/rebuild/service-readiness.js +3 -3
- package/dist/slices/rebuild/soften.js +49 -0
- package/dist/slices/rebuild/transition-repo.js +9 -2
- package/dist/slices/research/run.js +4 -4
- package/dist/slices/research/synthesis.js +2 -2
- package/dist/slices/reviews/model.js +105 -0
- package/dist/slices/reviews/outcome.js +22 -0
- package/dist/slices/reviews/repo.js +118 -0
- package/dist/slices/reviews/rules.js +63 -0
- package/dist/slices/reviews/verdict.js +71 -0
- package/dist/slices/reviews/view.js +30 -0
- package/dist/slices/revisions/adopt-content.js +5 -2
- package/dist/slices/revisions/adopt.js +3 -1
- package/dist/slices/revisions/downloads.js +7 -1
- package/dist/slices/revisions/image-plan.js +183 -0
- package/dist/slices/revisions/mutation-assets.js +10 -0
- package/dist/slices/revisions/mutation-cues.js +71 -0
- package/dist/slices/revisions/mutation-request.js +2 -1
- package/dist/slices/revisions/mutations.js +97 -3
- package/dist/slices/revisions/schema.js +11 -1
- package/dist/slices/run-cost/limits.js +128 -0
- package/dist/slices/run-cost/meter.js +47 -0
- package/dist/slices/run-cost/panel.js +256 -0
- package/dist/slices/run-cost/pricing.js +95 -0
- package/dist/slices/run-cost/week.js +108 -0
- package/dist/slices/schedules/agenda.js +222 -0
- package/dist/slices/schedules/repo.js +58 -18
- package/dist/slices/schedules/scheduler.js +68 -17
- package/dist/slices/schedules/schema.js +179 -1
- package/dist/slices/schedules/service.js +43 -4
- package/dist/slices/schedules/similar.js +128 -0
- package/dist/slices/schedules/topic-list.js +163 -0
- package/dist/slices/schedules/topics.js +523 -0
- package/dist/slices/settings/first-run.js +106 -0
- package/dist/slices/settings/health.js +247 -0
- package/dist/slices/settings/key-guides.js +138 -0
- package/dist/slices/settings/key-test.js +93 -0
- package/dist/slices/settings/keys.js +10 -5
- package/dist/slices/settings/model-reach.js +52 -0
- package/dist/slices/settings/model.js +55 -1
- package/dist/slices/settings/models.js +5 -1
- package/dist/slices/settings/playback.js +15 -0
- package/dist/slices/settings/readiness.js +14 -2
- package/dist/slices/settings/repo.js +17 -3
- package/dist/slices/settings/tutorial-schema.js +5 -0
- package/dist/slices/settings/voices.js +64 -4
- package/dist/slices/settings/whats-new.js +64 -0
- package/dist/slices/shorts/captions.js +9 -0
- package/dist/slices/shorts/pick.js +3 -3
- package/dist/slices/shorts/prompts.js +1 -1
- package/dist/slices/shorts/render.js +63 -13
- package/dist/slices/storage/asset-name.js +3 -0
- package/dist/slices/storage/backup-export.js +48 -9
- package/dist/slices/storage/backup-format.js +38 -1
- package/dist/slices/storage/backup-import.js +191 -19
- package/dist/slices/storage/delete-project.js +7 -4
- package/dist/slices/storage/documents.js +87 -0
- package/dist/slices/storage/downloads.js +33 -1
- package/dist/slices/storage/files-location.js +531 -0
- package/dist/slices/storage/layout.js +14 -4
- package/dist/slices/storage/model.js +11 -0
- package/dist/slices/storage/portable.js +94 -12
- package/dist/slices/storage/reconcile.js +14 -1
- package/dist/slices/storage/repo.js +4 -1
- package/dist/slices/storage/schema.js +11 -0
- package/dist/slices/storage/trim.js +146 -0
- package/dist/slices/studio/disclosure.js +74 -0
- package/dist/slices/studio/model.js +30 -0
- package/dist/slices/studio/pack.js +211 -0
- package/dist/slices/studio/queue.js +69 -0
- package/dist/slices/studio/settings.js +170 -0
- package/dist/slices/style-preview/images.js +61 -0
- package/dist/slices/style-preview/narration.js +33 -0
- package/dist/slices/style-preview/render.js +148 -0
- package/dist/slices/style-preview/schema.js +59 -0
- package/dist/slices/style-preview/service.js +92 -0
- package/dist/slices/style-preview/settings.js +139 -0
- package/dist/slices/subtitles/captions.js +42 -9
- package/dist/slices/subtitles/model.js +22 -0
- package/dist/slices/subtitles/prepare.js +27 -16
- package/dist/slices/subtitles/transcript.js +1 -1
- package/dist/slices/thumbnail/run.js +7 -7
- package/dist/slices/trash/model.js +25 -0
- package/dist/slices/trash/service.js +273 -0
- package/dist/slices/tutorials/anchors.js +57 -0
- package/dist/slices/tutorials/library.js +185 -0
- package/dist/slices/uploads/repo.js +20 -0
- package/dist/slices/video/ambient-bed-schema.js +15 -0
- package/dist/slices/video/ambient-bed.js +95 -0
- package/dist/slices/video/ambient-mix.js +72 -0
- package/dist/slices/video/audio-inputs.js +2 -2
- package/dist/slices/video/cards.js +5 -2
- package/dist/slices/video/edit-list.js +23 -2
- package/dist/slices/video/edit-settings.js +13 -3
- package/dist/slices/video/ffmpeg.js +63 -9
- package/dist/slices/video/figure-card.js +492 -0
- package/dist/slices/video/figure-spans.js +51 -0
- package/dist/slices/video/plan.js +125 -13
- package/dist/slices/video/run.js +14 -12
- package/dist/slices/video/slideshow.js +39 -4
- package/dist/slices/voices/attribution.js +69 -0
- package/dist/slices/voices/audio-files.js +87 -0
- package/dist/slices/voices/audition.js +25 -0
- package/dist/slices/voices/cast.js +74 -0
- package/dist/slices/voices/grouping.js +59 -0
- package/dist/slices/voices/join.js +35 -0
- package/dist/slices/voices/languages.js +25 -0
- package/dist/slices/voices/model.js +218 -0
- package/dist/slices/voices/palette.js +26 -0
- package/dist/slices/voices/panel.js +91 -0
- package/dist/slices/voices/portraits.js +55 -0
- package/dist/slices/voices/script.js +136 -0
- package/dist/slices/voices/timing.js +58 -0
- package/dist/slices/youtube/answer.js +1 -1
- package/dist/slices/youtube/chapters.js +126 -0
- package/dist/slices/youtube/edits-repo.js +84 -0
- package/dist/slices/youtube/edits.js +89 -0
- package/dist/slices/youtube/placeholders.js +98 -0
- package/dist/slices/youtube/transcript.js +11 -4
- package/dist/tutorials/AI-CLIs.md +146 -0
- package/dist/tutorials/Backups.md +121 -0
- package/dist/tutorials/Calendar.md +103 -0
- package/dist/tutorials/Cast-Library.md +112 -0
- package/dist/tutorials/Channels.md +148 -0
- package/dist/tutorials/Costs-and-Run-Cost.md +136 -0
- package/dist/tutorials/Docker.md +171 -0
- package/dist/tutorials/Document-Themes.md +207 -0
- package/dist/tutorials/Editing-a-Project.md +204 -0
- package/dist/tutorials/FAQ.md +134 -0
- package/dist/tutorials/First-Launch-and-Welcome.md +153 -0
- package/dist/tutorials/Home-and-Projects.md +174 -0
- package/dist/tutorials/Home.md +119 -0
- package/dist/tutorials/Install.md +154 -0
- package/dist/tutorials/Intros-and-Outros.md +86 -0
- package/dist/tutorials/Keyboard-Shortcuts-and-Command-Palette.md +215 -0
- package/dist/tutorials/Library-Overview.md +75 -0
- package/dist/tutorials/Models.md +133 -0
- package/dist/tutorials/Multiple-Voices.md +161 -0
- package/dist/tutorials/Narration-Aliases-and-Glossary.md +129 -0
- package/dist/tutorials/Notifications.md +86 -0
- package/dist/tutorials/Other-Languages.md +110 -0
- package/dist/tutorials/PDF-Documents.md +100 -0
- package/dist/tutorials/Play-Images.md +135 -0
- package/dist/tutorials/Play-Narration.md +167 -0
- package/dist/tutorials/Play-Outputs.md +109 -0
- package/dist/tutorials/Play-Overview.md +216 -0
- package/dist/tutorials/Play-Title-and-Article.md +135 -0
- package/dist/tutorials/Play-Video-and-Style.md +143 -0
- package/dist/tutorials/Project-Page.md +228 -0
- package/dist/tutorials/Prompts.md +136 -0
- package/dist/tutorials/Providers-and-Keys.md +290 -0
- package/dist/tutorials/Publishing-to-YouTube.md +135 -0
- package/dist/tutorials/Recovery-and-Retries.md +141 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +143 -0
- package/dist/tutorials/Schedules.md +154 -0
- package/dist/tutorials/Settings-Reference.md +258 -0
- package/dist/tutorials/Shorts.md +116 -0
- package/dist/tutorials/Start-at-Login.md +126 -0
- package/dist/tutorials/Studio-Extension.md +146 -0
- package/dist/tutorials/Templates.md +146 -0
- package/dist/tutorials/Trash.md +87 -0
- package/dist/tutorials/Troubleshooting.md +149 -0
- package/dist/tutorials/Uninstalling-and-Moving.md +113 -0
- package/dist/tutorials/Updating-and-Patch-Notes.md +120 -0
- package/dist/tutorials/Video-Editing.md +135 -0
- package/dist/tutorials/Where-Your-Files-Live.md +149 -0
- package/dist/tutorials/YouTube-Description.md +132 -0
- package/dist/tutorials/Your-First-Short.md +125 -0
- package/dist/tutorials/_Footer.md +1 -0
- package/dist/tutorials/_Sidebar.md +69 -0
- package/dist/updater/service.js +66 -21
- package/dist/web/assets/index-DBLSfqA-.css +1 -0
- package/dist/web/assets/index-DFdIhmm0.js +307 -0
- package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- package/dist/web/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- package/dist/web/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/dist/web/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- package/dist/web/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- package/dist/web/assets/{pdf-BLF2i8c2.js → pdf-B9OY1ioX.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +5 -5
- package/dist/edge/docker-launch.js +0 -81
- package/dist/edge/docker-projects/activation.js +0 -35
- package/dist/edge/docker-projects/claims.js +0 -85
- package/dist/edge/docker-projects/committed.js +0 -40
- package/dist/edge/docker-projects/engine.js +0 -461
- package/dist/edge/docker-projects/install.js +0 -254
- package/dist/edge/docker-projects/prune.js +0 -66
- package/dist/edge/docker-projects/recover.js +0 -100
- package/dist/edge/docker-projects/state.js +0 -225
- package/dist/web/assets/index-CktpxlJd.js +0 -171
- package/dist/web/assets/index-DB-vOnGU.css +0 -1
- package/scripts/docker-run.sh +0 -3
- /package/dist/edge/{docker-projects → docker-install}/tree.js +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
https://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Noto Sans (Latin, Greek, Cyrillic), Noto Sans Arabic, Noto Sans Hebrew, Noto Sans Devanagari
|
|
2
|
+
and Noto Sans Thai, Regular. Caption fallbacks for project languages the chosen caption font
|
|
3
|
+
cannot draw (src/slices/fonts/coverage.ts).
|
|
4
|
+
|
|
5
|
+
Source: the Noto Project (https://github.com/notofonts), static Regular instances as packaged
|
|
6
|
+
by Arch Linux noto-fonts 1:2026.09.01-1 (/usr/share/fonts/noto/). Noto Sans reports
|
|
7
|
+
"Version 2.015".
|
|
8
|
+
Licence: SIL Open Font License 1.1, OFL.txt beside this file, from
|
|
9
|
+
https://raw.githubusercontent.com/notofonts/latin-greek-cyrillic/main/OFL.txt
|
|
10
|
+
(SHA-256 cee9892f9f0cc8fe882c9e9537ee6a89621d86ee7ceaf70b02e2b2b1c25c061a). Each family is
|
|
11
|
+
"Copyright 2022 The Noto Project Authors" under the same licence.
|
|
12
|
+
|
|
13
|
+
SHA-256:
|
|
14
|
+
478c558ea716033cd60c03438f628dfa75694dcf6b5f6d505a2f05fd2b4f3823 NotoSans-Regular.ttf
|
|
15
|
+
bdff3e5659d67e67def05b33f749683b9376ae819d65d3dd62ac4640b3aaef48 NotoSansArabic-Regular.ttf
|
|
16
|
+
cdefaf8efd47045f6820928eba84db5bed7557539328952b5f828315485e02ee NotoSansHebrew-Regular.ttf
|
|
17
|
+
306b53ecfb182a504dd8a7446093c316387d2fd8dc350d0792ed1753fe0996cd NotoSansDevanagari-Regular.ttf
|
|
18
|
+
61cf814eec46b294d6ea4401ac295d0cecd5207bd2331dcc5a15e7301d30ee44 NotoSansThai-Regular.ttf
|
package/dist/assets/models.yaml
CHANGED
|
@@ -14,6 +14,8 @@ providers:
|
|
|
14
14
|
maxConcurrent: 3
|
|
15
15
|
inworld:
|
|
16
16
|
maxConcurrent: 5
|
|
17
|
+
google-tts:
|
|
18
|
+
maxConcurrent: 3
|
|
17
19
|
fal:
|
|
18
20
|
maxConcurrent: 3
|
|
19
21
|
replicate:
|
|
@@ -435,3 +437,39 @@ tts:
|
|
|
435
437
|
tts:
|
|
436
438
|
maxCharacters: 4096
|
|
437
439
|
streaming: true
|
|
440
|
+
- provider: google-tts
|
|
441
|
+
id: gemini-2.5-flash-preview-tts
|
|
442
|
+
name: Gemini 2.5 Flash TTS (preview)
|
|
443
|
+
source: https://ai.google.dev/gemini-api/docs/speech-generation
|
|
444
|
+
keywords:
|
|
445
|
+
- tts
|
|
446
|
+
pricing:
|
|
447
|
+
note: Billed per text token in and audio token out on your Gemini API key; estimate
|
|
448
|
+
unavailable.
|
|
449
|
+
tts:
|
|
450
|
+
maxCharacters: 4000
|
|
451
|
+
streaming: false
|
|
452
|
+
- provider: google-tts
|
|
453
|
+
id: gemini-2.5-pro-preview-tts
|
|
454
|
+
name: Gemini 2.5 Pro TTS (preview)
|
|
455
|
+
source: https://ai.google.dev/gemini-api/docs/speech-generation
|
|
456
|
+
keywords:
|
|
457
|
+
- tts
|
|
458
|
+
pricing:
|
|
459
|
+
note: Billed per text token in and audio token out on your Gemini API key; estimate
|
|
460
|
+
unavailable.
|
|
461
|
+
tts:
|
|
462
|
+
maxCharacters: 4000
|
|
463
|
+
streaming: false
|
|
464
|
+
- provider: google-tts
|
|
465
|
+
id: gemini-3.1-flash-tts-preview
|
|
466
|
+
name: Gemini 3.1 Flash TTS (preview)
|
|
467
|
+
source: https://ai.google.dev/gemini-api/docs/speech-generation
|
|
468
|
+
keywords:
|
|
469
|
+
- tts
|
|
470
|
+
pricing:
|
|
471
|
+
note: Billed per text token in and audio token out on your Gemini API key; estimate
|
|
472
|
+
unavailable.
|
|
473
|
+
tts:
|
|
474
|
+
maxCharacters: 4000
|
|
475
|
+
streaming: false
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// What an automatic catalogue check found. Every change is reported, none is applied to a
|
|
2
|
+
// template, schedule, draft or project: a retired model is only flagged.
|
|
3
|
+
export const catalogueFamilies = ["llm", "image", "tts"];
|
|
4
|
+
export const noChanges = { added: [], retired: [], priced: [] };
|
|
5
|
+
export function modelKey(family, provider, id) {
|
|
6
|
+
return `${family}:${provider}:${id}`;
|
|
7
|
+
}
|
|
8
|
+
function ref(family, model) {
|
|
9
|
+
return { family, provider: model.provider, id: model.id, name: model.name };
|
|
10
|
+
}
|
|
11
|
+
function samePricing(a, b) {
|
|
12
|
+
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
13
|
+
for (const key of keys) {
|
|
14
|
+
if (key === "note")
|
|
15
|
+
continue;
|
|
16
|
+
const x = a[key];
|
|
17
|
+
const y = b[key];
|
|
18
|
+
// A price read back from per-token figures differs from the curated one only in rounding.
|
|
19
|
+
if (typeof x === "number" && typeof y === "number") {
|
|
20
|
+
if (Math.abs(x - y) > 1e-9 * Math.max(1, Math.abs(x), Math.abs(y)))
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
else if (x !== y)
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
// Folds the published catalogue into the local one instead of replacing it:
|
|
29
|
+
// - a published model replaces the local row (prices, names, capabilities), except that a model
|
|
30
|
+
// the user switched off stays off and a speech model keeps its local character limit, which
|
|
31
|
+
// decides how narration is split and so what existing projects count as up to date;
|
|
32
|
+
// - a published model the local file lacks is added;
|
|
33
|
+
// - a local model that was published before and no longer is, or that the published file marks
|
|
34
|
+
// deprecated, is kept and marked deprecated, so pickers hide it and the places that use it can
|
|
35
|
+
// be listed; a model the user added themselves (never published) is left alone.
|
|
36
|
+
export function mergeCatalogue(local, published, knownPublished) {
|
|
37
|
+
const added = [];
|
|
38
|
+
const retired = [];
|
|
39
|
+
const priced = [];
|
|
40
|
+
const known = new Set(knownPublished);
|
|
41
|
+
const merge = (family, localRows, publishedRows) => {
|
|
42
|
+
const localByKey = new Map(localRows.map((row) => [modelKey(family, row.provider, row.id), row]));
|
|
43
|
+
const publishedKeys = new Set();
|
|
44
|
+
const rows = [];
|
|
45
|
+
for (const row of publishedRows) {
|
|
46
|
+
const key = modelKey(family, row.provider, row.id);
|
|
47
|
+
publishedKeys.add(key);
|
|
48
|
+
known.add(key);
|
|
49
|
+
const before = localByKey.get(key);
|
|
50
|
+
if (before === undefined) {
|
|
51
|
+
added.push(ref(family, row));
|
|
52
|
+
rows.push(row);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
let next = before.enabled ? row : { ...row, enabled: false };
|
|
56
|
+
if ("tts" in before && "tts" in next)
|
|
57
|
+
next = { ...next, tts: { ...next.tts, maxCharacters: before.tts.maxCharacters } };
|
|
58
|
+
if (!before.deprecated && next.deprecated)
|
|
59
|
+
retired.push(ref(family, next));
|
|
60
|
+
if (!samePricing(before.pricing, next.pricing))
|
|
61
|
+
priced.push({ ...ref(family, next), before: before.pricing, after: next.pricing });
|
|
62
|
+
rows.push(next);
|
|
63
|
+
}
|
|
64
|
+
for (const row of localRows) {
|
|
65
|
+
const key = modelKey(family, row.provider, row.id);
|
|
66
|
+
if (publishedKeys.has(key))
|
|
67
|
+
continue;
|
|
68
|
+
if (knownPublished.has(key) && !row.deprecated) {
|
|
69
|
+
retired.push(ref(family, row));
|
|
70
|
+
rows.push({ ...row, deprecated: true });
|
|
71
|
+
}
|
|
72
|
+
else
|
|
73
|
+
rows.push(row);
|
|
74
|
+
}
|
|
75
|
+
return rows;
|
|
76
|
+
};
|
|
77
|
+
const catalogue = {
|
|
78
|
+
schemaVersion: 1,
|
|
79
|
+
updatedAt: published.updatedAt > local.updatedAt ? published.updatedAt : local.updatedAt,
|
|
80
|
+
providers: { ...local.providers, ...published.providers },
|
|
81
|
+
llm: merge("llm", local.llm, published.llm),
|
|
82
|
+
image: merge("image", local.image, published.image),
|
|
83
|
+
tts: merge("tts", local.tts, published.tts),
|
|
84
|
+
};
|
|
85
|
+
return { catalogue, changes: { added, retired, priced }, known };
|
|
86
|
+
}
|
|
87
|
+
export function applyOpenRouterListing(catalogue, listing) {
|
|
88
|
+
if (listing.length === 0)
|
|
89
|
+
return { catalogue, changes: noChanges };
|
|
90
|
+
const byId = new Map(listing.map((row) => [row.id, row]));
|
|
91
|
+
const retired = [];
|
|
92
|
+
const priced = [];
|
|
93
|
+
const llm = catalogue.llm.map((row) => {
|
|
94
|
+
if (row.provider !== "openrouter" || row.deprecated)
|
|
95
|
+
return row;
|
|
96
|
+
const live = byId.get(row.id);
|
|
97
|
+
if (live === undefined) {
|
|
98
|
+
retired.push(ref("llm", row));
|
|
99
|
+
return { ...row, deprecated: true };
|
|
100
|
+
}
|
|
101
|
+
const pricing = {
|
|
102
|
+
...row.pricing,
|
|
103
|
+
...(live.promptPerToken === undefined
|
|
104
|
+
? {}
|
|
105
|
+
: { inputPerMillionTokens: perMillion(live.promptPerToken) }),
|
|
106
|
+
...(live.completionPerToken === undefined
|
|
107
|
+
? {}
|
|
108
|
+
: { outputPerMillionTokens: perMillion(live.completionPerToken) }),
|
|
109
|
+
};
|
|
110
|
+
if (samePricing(row.pricing, pricing))
|
|
111
|
+
return row;
|
|
112
|
+
priced.push({ ...ref("llm", row), before: row.pricing, after: pricing });
|
|
113
|
+
return { ...row, pricing };
|
|
114
|
+
});
|
|
115
|
+
return { catalogue: { ...catalogue, llm }, changes: { added: [], retired, priced } };
|
|
116
|
+
}
|
|
117
|
+
function perMillion(perToken) {
|
|
118
|
+
return Math.round(perToken * 1_000_000 * 1_000_000) / 1_000_000;
|
|
119
|
+
}
|
|
120
|
+
export function combineChanges(a, b) {
|
|
121
|
+
const priced = new Map();
|
|
122
|
+
for (const row of [...a.priced, ...b.priced]) {
|
|
123
|
+
const key = modelKey(row.family, row.provider, row.id);
|
|
124
|
+
const earlier = priced.get(key);
|
|
125
|
+
priced.set(key, earlier === undefined ? row : { ...row, before: earlier.before });
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
added: [...a.added, ...b.added],
|
|
129
|
+
retired: [...a.retired, ...b.retired],
|
|
130
|
+
priced: [...priced.values()],
|
|
131
|
+
};
|
|
132
|
+
}
|
package/dist/catalog/registry.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { thinkingModes } from "../kernel/ports/llm.js";
|
|
2
2
|
import { providerError } from "../kernel/ports/model.js";
|
|
3
|
-
import { isLocalCliProvider } from "../slices/settings/model.js";
|
|
3
|
+
import { isLocalCliProvider, systemVoiceProvider } from "../slices/settings/model.js";
|
|
4
4
|
import { referenceRefusal, takesReferenceImage } from "./schema.js";
|
|
5
5
|
export function curateRegistry(registry, catalogue) {
|
|
6
6
|
const requireModel = (provider, family, id) => {
|
|
@@ -9,7 +9,7 @@ export function curateRegistry(registry, catalogue) {
|
|
|
9
9
|
if (!model)
|
|
10
10
|
throw providerError({
|
|
11
11
|
kind: "unsupported",
|
|
12
|
-
message: `The chosen ${provider} model is no longer in Slopify's model list. In the Edit tab, choose Edit project and change it under Providers, then use
|
|
12
|
+
message: `The chosen ${provider} model is no longer in Slopify's model list. In the Edit tab, choose Edit project and change it under Providers, then use Continue the run.`,
|
|
13
13
|
});
|
|
14
14
|
return model;
|
|
15
15
|
};
|
|
@@ -25,7 +25,7 @@ export function curateRegistry(registry, catalogue) {
|
|
|
25
25
|
if (request.model.trim() === "")
|
|
26
26
|
throw providerError({
|
|
27
27
|
kind: "unsupported",
|
|
28
|
-
message: "No model is chosen for this step. In the Edit tab, choose Edit project and change it under Providers, then use
|
|
28
|
+
message: "No model is chosen for this step. In the Edit tab, choose Edit project and change it under Providers, then use Continue the run.",
|
|
29
29
|
});
|
|
30
30
|
let models;
|
|
31
31
|
try {
|
|
@@ -39,19 +39,19 @@ export function curateRegistry(registry, catalogue) {
|
|
|
39
39
|
if (models !== undefined && selected === undefined)
|
|
40
40
|
throw providerError({
|
|
41
41
|
kind: "unsupported",
|
|
42
|
-
message: "The chosen model is not available in the AI command-line tool on your computer. Update the tool, or pick another model: in the Edit tab, choose Edit project and change it under Providers, then use
|
|
42
|
+
message: "The chosen model is not available in the AI command-line tool on your computer. Update the tool, or pick another model: in the Edit tab, choose Edit project and change it under Providers, then use Continue the run.",
|
|
43
43
|
});
|
|
44
44
|
if (request.thinking !== undefined &&
|
|
45
45
|
selected !== undefined &&
|
|
46
46
|
!selected.thinkingModes?.includes(request.thinking))
|
|
47
47
|
throw providerError({
|
|
48
48
|
kind: "unsupported",
|
|
49
|
-
message: "The chosen model does not support this thinking setting. In the Edit tab, choose Edit project and change it under Providers, then use
|
|
49
|
+
message: "The chosen model does not support this thinking setting. In the Edit tab, choose Edit project and change it under Providers, then use Continue the run.",
|
|
50
50
|
});
|
|
51
51
|
if (request.webSearch && !port.capabilities.webSearch)
|
|
52
52
|
throw providerError({
|
|
53
53
|
kind: "unsupported",
|
|
54
|
-
message: "This command-line tool cannot search the web for research. Choose another text provider or turn Research off in the Edit tab under Edit project, then use
|
|
54
|
+
message: "This command-line tool cannot search the web for research. Choose another text provider or turn Research off in the Edit tab under Edit project, then use Continue the run.",
|
|
55
55
|
});
|
|
56
56
|
const thinkingConfig = id === "codex" && request.thinking !== undefined
|
|
57
57
|
? { effort: request.thinking === "off" ? "none" : request.thinking }
|
|
@@ -80,13 +80,13 @@ export function curateRegistry(registry, catalogue) {
|
|
|
80
80
|
if (request.webSearch && !model.llm.webSearch)
|
|
81
81
|
throw providerError({
|
|
82
82
|
kind: "unsupported",
|
|
83
|
-
message: "The chosen model cannot search the web for research. Choose another model or turn Research off in the Edit tab under Edit project, then use
|
|
83
|
+
message: "The chosen model cannot search the web for research. Choose another model or turn Research off in the Edit tab under Edit project, then use Continue the run.",
|
|
84
84
|
});
|
|
85
85
|
const thinkingConfig = request.thinking === undefined ? undefined : model.llm.thinking?.[request.thinking];
|
|
86
86
|
if (request.thinking !== undefined && !thinkingConfig)
|
|
87
87
|
throw providerError({
|
|
88
88
|
kind: "unsupported",
|
|
89
|
-
message: "The chosen model does not support this thinking setting. In the Edit tab, choose Edit project and change it under Providers, then use
|
|
89
|
+
message: "The chosen model does not support this thinking setting. In the Edit tab, choose Edit project and change it under Providers, then use Continue the run.",
|
|
90
90
|
});
|
|
91
91
|
yield* port.complete({
|
|
92
92
|
...request,
|
|
@@ -107,14 +107,14 @@ export function curateRegistry(registry, catalogue) {
|
|
|
107
107
|
throw providerError({
|
|
108
108
|
kind: "unsupported",
|
|
109
109
|
message: request.model === "codex-imagegen"
|
|
110
|
-
? "Image generation is not available in the Codex CLI on your computer. Update Codex CLI, or choose another image provider in the Edit tab under Edit project, then use
|
|
111
|
-
: "The chosen Codex model for images is not in the Codex CLI's model list on your computer. Update Codex CLI, or pick another model for images: in the Edit tab, choose Edit project and change it under Providers, then use
|
|
110
|
+
? "Image generation is not available in the Codex CLI on your computer. Update Codex CLI, or choose another image provider in the Edit tab under Edit project, then use Continue the run."
|
|
111
|
+
: "The chosen Codex model for images is not in the Codex CLI's model list on your computer. Update Codex CLI, or pick another model for images: in the Edit tab, choose Edit project and change it under Providers, then use Continue the run.",
|
|
112
112
|
});
|
|
113
113
|
if (request.thinking !== undefined &&
|
|
114
114
|
!selected.thinkingModes?.includes(request.thinking))
|
|
115
115
|
throw providerError({
|
|
116
116
|
kind: "unsupported",
|
|
117
|
-
message: "The chosen Codex model does not support this effort for images. In the Edit tab, choose Edit project and change the images' Effort under Providers, then use
|
|
117
|
+
message: "The chosen Codex model does not support this effort for images. In the Edit tab, choose Edit project and change the images' Effort under Providers, then use Continue the run.",
|
|
118
118
|
});
|
|
119
119
|
return port.generate(request);
|
|
120
120
|
},
|
|
@@ -128,12 +128,12 @@ export function curateRegistry(registry, catalogue) {
|
|
|
128
128
|
if (!("image" in model) || !model.image.aspectRatios.includes(request.aspect))
|
|
129
129
|
throw providerError({
|
|
130
130
|
kind: "unsupported",
|
|
131
|
-
message: "The chosen image model cannot make images in this video's shape. In the Edit tab, choose Edit project and change it under Providers, then use
|
|
131
|
+
message: "The chosen image model cannot make images in this video's shape. In the Edit tab, choose Edit project and change it under Providers, then use Continue the run.",
|
|
132
132
|
});
|
|
133
133
|
if (request.thinking !== undefined)
|
|
134
134
|
throw providerError({
|
|
135
135
|
kind: "unsupported",
|
|
136
|
-
message: "The chosen image model has no effort setting. In the Edit tab, choose Edit project and set the images' Effort back to Model default under Providers, then use
|
|
136
|
+
message: "The chosen image model has no effort setting. In the Edit tab, choose Edit project and set the images' Effort back to Model default under Providers, then use Continue the run.",
|
|
137
137
|
});
|
|
138
138
|
if (request.reference !== undefined && !takesReferenceImage(model))
|
|
139
139
|
throw providerError({
|
|
@@ -146,6 +146,9 @@ export function curateRegistry(registry, catalogue) {
|
|
|
146
146
|
},
|
|
147
147
|
tts: (id) => {
|
|
148
148
|
const port = registry.tts(id);
|
|
149
|
+
// The system voice's models are the speech programs on this computer, not list rows.
|
|
150
|
+
if (id === systemVoiceProvider)
|
|
151
|
+
return port;
|
|
149
152
|
return {
|
|
150
153
|
...port,
|
|
151
154
|
models: async () => catalogue.models(id, "tts"),
|
|
@@ -159,7 +162,7 @@ export function curateRegistry(registry, catalogue) {
|
|
|
159
162
|
if (request.text.length > model.tts.maxCharacters)
|
|
160
163
|
throw providerError({
|
|
161
164
|
kind: "unsupported",
|
|
162
|
-
message: `A piece of narration is longer than this voice model's ${model.tts.maxCharacters}-character limit. Use
|
|
165
|
+
message: `A piece of narration is longer than this voice model's ${model.tts.maxCharacters}-character limit. Use More → make it again in its section on Audio so Slopify splits it into shorter pieces.`,
|
|
163
166
|
});
|
|
164
167
|
return port.synthesize({ ...request, model: model.id });
|
|
165
168
|
},
|
package/dist/catalog/schema.js
CHANGED
|
@@ -14,6 +14,8 @@ const base = z.object({
|
|
|
14
14
|
.object({
|
|
15
15
|
inputPerMillionTokens: money.optional(),
|
|
16
16
|
outputPerMillionTokens: money.optional(),
|
|
17
|
+
// Input read from the provider's prompt cache. Absent, cached input is priced as input.
|
|
18
|
+
cachedInputPerMillionTokens: money.optional(),
|
|
17
19
|
perMillionCharacters: money.optional(),
|
|
18
20
|
perImage: money.optional(),
|
|
19
21
|
perMinute: money.optional(),
|
package/dist/catalog/store.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { parse } from "yaml";
|
|
3
|
+
import { parse, stringify } from "yaml";
|
|
4
4
|
import { isLocalCliProvider } from "../slices/settings/model.js";
|
|
5
|
+
import { applyOpenRouterListing, catalogueFamilies, combineChanges, mergeCatalogue, modelKey, noChanges, } from "./merge.js";
|
|
5
6
|
import { catalogueSchema, isVideoModel } from "./schema.js";
|
|
6
7
|
export const catalogueSource = "https://raw.githubusercontent.com/GentBajko/slopify/main/packages/app/src/assets/models.yaml";
|
|
8
|
+
// OpenRouter's public model list: live ids and per-token prices, no key needed.
|
|
9
|
+
export const openRouterModelsSource = "https://openrouter.ai/api/v1/models";
|
|
10
|
+
// How often the automatic check runs; it also runs once at every start.
|
|
11
|
+
export const catalogueCheckIntervalMs = 24 * 60 * 60 * 1000;
|
|
7
12
|
export function parseCatalogue(text) {
|
|
8
13
|
if (Buffer.byteLength(text) > 1024 * 1024)
|
|
9
14
|
throw new Error("Model catalogue exceeds 1 MB");
|
|
@@ -26,6 +31,9 @@ export function createCatalogueStore(deps) {
|
|
|
26
31
|
let stamp = "";
|
|
27
32
|
let warning = null;
|
|
28
33
|
let refreshing;
|
|
34
|
+
let syncing;
|
|
35
|
+
const syncPath = join(deps.dataDir, "models-sync.json");
|
|
36
|
+
const now = deps.now ?? (() => new Date());
|
|
29
37
|
function read() {
|
|
30
38
|
try {
|
|
31
39
|
const file = statSync(path);
|
|
@@ -40,12 +48,12 @@ export function createCatalogueStore(deps) {
|
|
|
40
48
|
}
|
|
41
49
|
catch {
|
|
42
50
|
warning =
|
|
43
|
-
"Your models.yaml file is missing or has a mistake, so Slopify is still using the last working model list. Fix the file, or use
|
|
51
|
+
"Your models.yaml file is missing or has a mistake, so Slopify is still using the last working model list. Fix the file, or use Replace with published file in Settings → Models.";
|
|
44
52
|
}
|
|
45
53
|
return current;
|
|
46
54
|
}
|
|
47
|
-
async function
|
|
48
|
-
const response = await deps.fetch(
|
|
55
|
+
async function download(url, maxBytes) {
|
|
56
|
+
const response = await deps.fetch(url, {
|
|
49
57
|
signal: AbortSignal.timeout(15000),
|
|
50
58
|
redirect: "error",
|
|
51
59
|
});
|
|
@@ -62,8 +70,8 @@ export function createCatalogueStore(deps) {
|
|
|
62
70
|
if (next.done)
|
|
63
71
|
break;
|
|
64
72
|
size += next.value.byteLength;
|
|
65
|
-
if (size >
|
|
66
|
-
throw new Error("
|
|
73
|
+
if (size > maxBytes)
|
|
74
|
+
throw new Error("Download is too large");
|
|
67
75
|
chunks.push(next.value);
|
|
68
76
|
}
|
|
69
77
|
}
|
|
@@ -71,7 +79,10 @@ export function createCatalogueStore(deps) {
|
|
|
71
79
|
await reader.cancel().catch(() => { });
|
|
72
80
|
reader.releaseLock();
|
|
73
81
|
}
|
|
74
|
-
|
|
82
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
83
|
+
}
|
|
84
|
+
async function refresh() {
|
|
85
|
+
const text = await download(catalogueSource, 1024 * 1024);
|
|
75
86
|
const next = parseCatalogue(text);
|
|
76
87
|
mkdirSync(deps.dataDir, { recursive: true, mode: 0o700 });
|
|
77
88
|
// A manual refresh replaces the local catalogue; retain the previous text for recovery.
|
|
@@ -84,10 +95,91 @@ export function createCatalogueStore(deps) {
|
|
|
84
95
|
warning = null;
|
|
85
96
|
read();
|
|
86
97
|
}
|
|
98
|
+
function readSync() {
|
|
99
|
+
try {
|
|
100
|
+
const parsed = JSON.parse(readFileSync(syncPath, "utf8"));
|
|
101
|
+
if (isSyncFile(parsed))
|
|
102
|
+
return parsed;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Absent or damaged: the first check starts from the bundled list below.
|
|
106
|
+
}
|
|
107
|
+
return { checkedAt: null, known: null, changes: noChanges, warning: null };
|
|
108
|
+
}
|
|
109
|
+
function writeSync(value) {
|
|
110
|
+
writeFileSync(`${syncPath}.next`, JSON.stringify(value), { mode: 0o600 });
|
|
111
|
+
renameSync(`${syncPath}.next`, syncPath);
|
|
112
|
+
}
|
|
113
|
+
async function openRouterListing() {
|
|
114
|
+
try {
|
|
115
|
+
return parseOpenRouterListing(JSON.parse(await download(openRouterModelsSource, 16 * 1024 * 1024)));
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Optional: the published catalogue still carries OpenRouter's curated prices.
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function sync() {
|
|
123
|
+
const saved = readSync();
|
|
124
|
+
const local = read();
|
|
125
|
+
if (warning !== null) {
|
|
126
|
+
// Never overwrite a file the user is in the middle of fixing.
|
|
127
|
+
writeSync({ ...saved, warning });
|
|
128
|
+
return { checkedAt: saved.checkedAt, changes: saved.changes, warning };
|
|
129
|
+
}
|
|
130
|
+
let published;
|
|
131
|
+
try {
|
|
132
|
+
published = parseCatalogue(await download(catalogueSource, 1024 * 1024));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
const failed = "Slopify could not download the latest model list, so it is still using the one it has. Check your internet connection, then choose Check now in Settings → Models.";
|
|
136
|
+
writeSync({ ...saved, warning: failed });
|
|
137
|
+
return { checkedAt: saved.checkedAt, changes: saved.changes, warning: failed };
|
|
138
|
+
}
|
|
139
|
+
// Before the first check the models shipped with this version count as published, so a
|
|
140
|
+
// model the user added to the file is never mistaken for a retired one.
|
|
141
|
+
const known = new Set(saved.known ?? keysOf(parseCatalogue(bundled)));
|
|
142
|
+
const merged = mergeCatalogue(local, published, known);
|
|
143
|
+
const live = applyOpenRouterListing(merged.catalogue, await openRouterListing());
|
|
144
|
+
const changes = combineChanges(merged.changes, live.changes);
|
|
145
|
+
const text = `${syncedHeader}${stringify(live.catalogue, { aliasDuplicateObjects: false })}`;
|
|
146
|
+
const next = parseCatalogue(text);
|
|
147
|
+
if (JSON.stringify(next) !== JSON.stringify(local)) {
|
|
148
|
+
if (existsSync(path))
|
|
149
|
+
writeFileSync(`${path}.previous`, readFileSync(path), { mode: 0o600 });
|
|
150
|
+
writeFileSync(`${path}.next`, text, { mode: 0o600 });
|
|
151
|
+
renameSync(`${path}.next`, path);
|
|
152
|
+
current = next;
|
|
153
|
+
stamp = "";
|
|
154
|
+
read();
|
|
155
|
+
}
|
|
156
|
+
const status = { checkedAt: now().toISOString(), changes, warning: null };
|
|
157
|
+
writeSync({ ...status, known: [...merged.known].sort() });
|
|
158
|
+
return status;
|
|
159
|
+
}
|
|
87
160
|
return {
|
|
161
|
+
sync: () => {
|
|
162
|
+
syncing ??= sync().finally(() => {
|
|
163
|
+
syncing = undefined;
|
|
164
|
+
});
|
|
165
|
+
return syncing;
|
|
166
|
+
},
|
|
167
|
+
syncDue: (at) => {
|
|
168
|
+
const last = readSync().checkedAt;
|
|
169
|
+
return last === null || at - Date.parse(last) >= catalogueCheckIntervalMs;
|
|
170
|
+
},
|
|
88
171
|
read,
|
|
89
172
|
models: (provider, family) => read()[family].filter((m) => m.provider === provider && m.enabled && !m.deprecated && !isVideoModel(m)),
|
|
90
|
-
status: () =>
|
|
173
|
+
status: () => {
|
|
174
|
+
const saved = readSync();
|
|
175
|
+
return {
|
|
176
|
+
updatedAt: read().updatedAt,
|
|
177
|
+
path,
|
|
178
|
+
warning,
|
|
179
|
+
source: catalogueSource,
|
|
180
|
+
sync: { checkedAt: saved.checkedAt, changes: saved.changes, warning: saved.warning },
|
|
181
|
+
};
|
|
182
|
+
},
|
|
91
183
|
refresh: () => {
|
|
92
184
|
refreshing ??= refresh().finally(() => {
|
|
93
185
|
refreshing = undefined;
|
|
@@ -96,3 +188,50 @@ export function createCatalogueStore(deps) {
|
|
|
96
188
|
},
|
|
97
189
|
};
|
|
98
190
|
}
|
|
191
|
+
const syncedHeader = "# Slopify's model list, kept up to date automatically from the published catalogue.\n" +
|
|
192
|
+
"# Your edits are kept; retired models stay listed with deprecated: true.\n";
|
|
193
|
+
function isSyncFile(value) {
|
|
194
|
+
if (typeof value !== "object" || value === null)
|
|
195
|
+
return false;
|
|
196
|
+
const row = value;
|
|
197
|
+
const changes = row.changes;
|
|
198
|
+
return ((row.checkedAt === null || typeof row.checkedAt === "string") &&
|
|
199
|
+
(row.known === null || Array.isArray(row.known)) &&
|
|
200
|
+
(row.warning === null || typeof row.warning === "string") &&
|
|
201
|
+
typeof changes === "object" &&
|
|
202
|
+
changes !== null &&
|
|
203
|
+
Array.isArray(changes.added) &&
|
|
204
|
+
Array.isArray(changes.retired) &&
|
|
205
|
+
Array.isArray(changes.priced));
|
|
206
|
+
}
|
|
207
|
+
function keysOf(catalogue) {
|
|
208
|
+
return catalogueFamilies.flatMap((family) => catalogue[family].map((row) => modelKey(family, row.provider, row.id)));
|
|
209
|
+
}
|
|
210
|
+
// `{ data: [{ id, pricing: { prompt, completion } }] }`, prices in USD per token as strings.
|
|
211
|
+
// Rows that do not read cleanly are skipped; a negative price means "varies" and is ignored.
|
|
212
|
+
export function parseOpenRouterListing(value) {
|
|
213
|
+
if (typeof value !== "object" || value === null)
|
|
214
|
+
return [];
|
|
215
|
+
const data = value.data;
|
|
216
|
+
if (!Array.isArray(data))
|
|
217
|
+
return [];
|
|
218
|
+
const price = (raw) => {
|
|
219
|
+
const number = typeof raw === "string" || typeof raw === "number" ? Number(raw) : Number.NaN;
|
|
220
|
+
return Number.isFinite(number) && number >= 0 ? number : undefined;
|
|
221
|
+
};
|
|
222
|
+
const rows = [];
|
|
223
|
+
for (const row of data) {
|
|
224
|
+
if (typeof row !== "object" || row === null)
|
|
225
|
+
continue;
|
|
226
|
+
const { id, pricing } = row;
|
|
227
|
+
if (typeof id !== "string" || id === "")
|
|
228
|
+
continue;
|
|
229
|
+
const prices = typeof pricing === "object" && pricing !== null ? pricing : {};
|
|
230
|
+
rows.push({
|
|
231
|
+
id,
|
|
232
|
+
promptPerToken: price(prices.prompt),
|
|
233
|
+
completionPerToken: price(prices.completion),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
return rows;
|
|
237
|
+
}
|