@gentbajko/slopify 2.5.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -21
- package/NOTICE +12 -0
- package/README.md +21 -40
- package/SUBTITLES.md +1 -1
- package/dist/adapter-registry.js +3 -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 +36 -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/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/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/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/catalog/merge.js +132 -0
- package/dist/catalog/registry.js +13 -13
- package/dist/catalog/schema.js +2 -0
- package/dist/catalog/store.js +147 -8
- package/dist/compose.yaml +71 -0
- package/dist/edge/autostart/docker-record.js +32 -0
- package/dist/edge/autostart/docker.js +50 -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 +66 -0
- package/dist/edge/autostart/service.js +81 -0
- package/dist/edge/cli.js +57 -51
- 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 +154 -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/host-cli.js +1 -1
- package/dist/edge/http/actions.js +32 -10
- package/dist/edge/http/app.js +58 -2
- package/dist/edge/http/auditions.js +70 -0
- package/dist/edge/http/autostart.js +37 -0
- package/dist/edge/http/channel-memory.js +92 -0
- package/dist/edge/http/channels.js +128 -0
- package/dist/edge/http/entries.js +22 -3
- package/dist/edge/http/files.js +1 -1
- 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 +152 -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/projects.js +31 -99
- package/dist/edge/http/prompts.js +40 -3
- package/dist/edge/http/pronunciations.js +23 -4
- package/dist/edge/http/providers.js +86 -0
- package/dist/edge/http/reviews.js +121 -0
- package/dist/edge/http/revision-files.js +1 -1
- package/dist/edge/http/revisions.js +1 -1
- package/dist/edge/http/run-cost.js +25 -0
- package/dist/edge/http/schedules.js +111 -6
- package/dist/edge/http/settings.js +84 -6
- package/dist/edge/http/storage-files.js +50 -0
- package/dist/edge/http/storage.js +29 -2
- package/dist/edge/http/studio.js +207 -0
- package/dist/edge/http/style-preview.js +100 -0
- package/dist/edge/http/subtitles.js +1 -1
- package/dist/edge/http/trash.js +69 -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 +83 -0
- package/dist/edge/native-update.js +62 -0
- package/dist/host-cli/open-folder.js +10 -10
- package/dist/host-cli/runtime.js +9 -1
- 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/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 +5 -2
- package/dist/kernel/ports/narration-aliases.js +60 -0
- package/dist/kernel/ports/plan-limits.js +36 -0
- package/dist/kernel/runner/attempt.js +17 -8
- package/dist/kernel/runner/audition.js +36 -0
- package/dist/kernel/runner/graph.js +24 -5
- package/dist/kernel/runner/index.js +35 -5
- 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 +272 -16
- 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/index.json +26 -0
- package/dist/slices/admission/model.js +27 -0
- package/dist/slices/admission/repo.js +24 -4
- package/dist/slices/admission/rules.js +79 -1
- package/dist/slices/admission/schema.js +58 -1
- package/dist/slices/admission/short-mode.js +47 -0
- package/dist/slices/admission/start.js +41 -5
- 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 +218 -0
- package/dist/slices/channels/runs.js +129 -0
- package/dist/slices/channels/schema.js +129 -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 +2 -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 +60 -2
- 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 +183 -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 +21 -3
- package/dist/slices/notifications/rules.js +22 -1
- package/dist/slices/onboarding/copy.js +143 -0
- package/dist/slices/onboarding/first-run.js +46 -0
- package/dist/slices/onboarding/install.js +119 -0
- package/dist/slices/onboarding/model.js +64 -0
- package/dist/slices/onboarding/packs.js +491 -0
- package/dist/slices/onboarding/quick-short.js +129 -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 +125 -6
- package/dist/slices/play-drafts/readiness.js +3 -0
- 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 +50 -4
- package/dist/slices/project-templates/one-off.js +26 -0
- package/dist/slices/project-templates/repo.js +2 -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 +62 -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 +110 -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 +237 -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 +39 -10
- 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/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 +106 -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 +234 -0
- package/dist/slices/run-cost/pricing.js +92 -0
- package/dist/slices/run-cost/week.js +108 -0
- package/dist/slices/schedules/agenda.js +158 -0
- package/dist/slices/schedules/repo.js +58 -18
- package/dist/slices/schedules/scheduler.js +67 -16
- package/dist/slices/schedules/schema.js +138 -1
- package/dist/slices/schedules/service.js +43 -4
- package/dist/slices/schedules/similar.js +90 -0
- package/dist/slices/schedules/topic-list.js +163 -0
- package/dist/slices/schedules/topics.js +422 -0
- package/dist/slices/settings/first-run.js +102 -0
- package/dist/slices/settings/health.js +190 -0
- package/dist/slices/settings/key-guides.js +128 -0
- package/dist/slices/settings/key-test.js +85 -0
- package/dist/slices/settings/model.js +6 -1
- package/dist/slices/settings/playback.js +15 -0
- package/dist/slices/settings/repo.js +17 -3
- 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 +54 -5
- 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 +79 -0
- 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 +92 -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 +28 -0
- package/dist/slices/studio/pack.js +209 -0
- package/dist/slices/studio/settings.js +133 -0
- package/dist/slices/style-preview/images.js +61 -0
- package/dist/slices/style-preview/render.js +161 -0
- package/dist/slices/style-preview/schema.js +45 -0
- package/dist/slices/style-preview/service.js +93 -0
- package/dist/slices/style-preview/settings.js +89 -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/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 +82 -0
- package/dist/slices/voices/audition.js +25 -0
- package/dist/slices/voices/cast.js +56 -0
- package/dist/slices/voices/grouping.js +49 -0
- package/dist/slices/voices/join.js +35 -0
- package/dist/slices/voices/languages.js +25 -0
- package/dist/slices/voices/model.js +179 -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 +69 -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/updater/service.js +66 -21
- package/dist/web/assets/index-CUA2sUxU.css +1 -0
- package/dist/web/assets/index-CX590kE-.js +303 -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-BG8n_uc5.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +4 -4
- 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
|
@@ -4,6 +4,7 @@ import { providerError } from "../../kernel/ports/model.js";
|
|
|
4
4
|
import { httpFailure, missingKey, noAudio, unreadable, voiceFix } from "../explain.js";
|
|
5
5
|
import { retryAfter } from "../retry-after.js";
|
|
6
6
|
import { inworldAsync, streamFailure } from "./inworld-async.js";
|
|
7
|
+
import { inworldLanguages, lookUp } from "./voice-languages.js";
|
|
7
8
|
export const inworldModels = [
|
|
8
9
|
{ id: "inworld-tts-2", name: "Realtime TTS-2" },
|
|
9
10
|
{ id: "inworld-tts-2-flash", name: "Realtime TTS-2 Flash" },
|
|
@@ -16,6 +17,15 @@ export function inworldTts(deps) {
|
|
|
16
17
|
return {
|
|
17
18
|
id: "inworld",
|
|
18
19
|
capabilities: { streams: true },
|
|
20
|
+
voiceLanguages: async (voiceId, signal) => {
|
|
21
|
+
const key = deps
|
|
22
|
+
.key()
|
|
23
|
+
?.trim()
|
|
24
|
+
.replace(/^Basic\s+/i, "");
|
|
25
|
+
if (!key)
|
|
26
|
+
return undefined;
|
|
27
|
+
return inworldLanguages(await lookUp(deps.fetch, `https://api.inworld.ai/voices/v1/voices/${encodeURIComponent(voiceId)}`, { Authorization: `Basic ${key}` }, signal));
|
|
28
|
+
},
|
|
19
29
|
models: async () => inworldModels,
|
|
20
30
|
synthesize: async (request) => {
|
|
21
31
|
const key = deps
|
|
@@ -59,7 +69,7 @@ async function* synthesizeRequest(deps, request, key) {
|
|
|
59
69
|
if (request.text.trim().length === 0)
|
|
60
70
|
throw providerError({
|
|
61
71
|
kind: "unsupported",
|
|
62
|
-
message: "Inworld was sent an empty piece of narration. Check the article has text in the Article section of Edit project, then use
|
|
72
|
+
message: "Inworld was sent an empty piece of narration. Check the article has text in the Article section of Edit project, then use Try again.",
|
|
63
73
|
});
|
|
64
74
|
if ((request.model ?? "inworld-tts-2") === "inworld-tts-2" && request.text.length > 4000) {
|
|
65
75
|
yield* inworldAsync(deps, request, key);
|
|
@@ -93,7 +103,9 @@ async function* synthesizeRequest(deps, request, key) {
|
|
|
93
103
|
? "rate_limit"
|
|
94
104
|
: response.status === 400 || response.status === 404
|
|
95
105
|
? "unsupported"
|
|
96
|
-
:
|
|
106
|
+
: response.status >= 500
|
|
107
|
+
? "dropped"
|
|
108
|
+
: "other",
|
|
97
109
|
message: clean(httpFailure({
|
|
98
110
|
provider: "Inworld",
|
|
99
111
|
status: response.status,
|
|
@@ -128,7 +140,9 @@ async function* synthesizeRequest(deps, request, key) {
|
|
|
128
140
|
? "rate_limit"
|
|
129
141
|
: code === 3 || code === 5
|
|
130
142
|
? "unsupported"
|
|
131
|
-
:
|
|
143
|
+
: code === 14
|
|
144
|
+
? "dropped"
|
|
145
|
+
: "other",
|
|
132
146
|
message: streamFailure(code, clean(message ?? "", key), request.voiceId),
|
|
133
147
|
});
|
|
134
148
|
}
|
|
@@ -95,6 +95,9 @@ function kindOf(status) {
|
|
|
95
95
|
}
|
|
96
96
|
// ceiling: as in the OpenRouter adapter, a 400 is retried three more times because the
|
|
97
97
|
// port's error contract has no terminal kind for a request that cannot be repaired.
|
|
98
|
+
// The provider's own server failed; the same request may well succeed later.
|
|
99
|
+
if (status >= 500)
|
|
100
|
+
return "dropped";
|
|
98
101
|
return "other";
|
|
99
102
|
}
|
|
100
103
|
async function failure(response, voiceId, next) {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// What each provider's voice API says a voice speaks, reduced to lower-case primary language
|
|
3
|
+
// subtags ("es-MX" and "ES_MX" are both "es"). Undefined when the provider said nothing
|
|
4
|
+
// usable: an unknown voice speaks every language as far as the app is concerned.
|
|
5
|
+
export function primaryLanguages(values) {
|
|
6
|
+
const codes = values.flatMap((value) => {
|
|
7
|
+
const code = value?.trim().split(/[-_]/)[0]?.toLowerCase();
|
|
8
|
+
return code !== undefined && /^[a-z]{2,3}$/.test(code) ? [code] : [];
|
|
9
|
+
});
|
|
10
|
+
return codes.length === 0 ? undefined : [...new Set(codes)];
|
|
11
|
+
}
|
|
12
|
+
// Asks once, briefly: the answer only fills a hint in Settings → Voices, so a slow or failed
|
|
13
|
+
// lookup is simply no answer.
|
|
14
|
+
export async function lookUp(fetcher, url, headers, signal) {
|
|
15
|
+
try {
|
|
16
|
+
const response = await fetcher(url, {
|
|
17
|
+
headers,
|
|
18
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(8000)]),
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
await response.body?.cancel();
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return await response.json();
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
signal.throwIfAborted();
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// GET /v1/voices/{id}: `verified_languages[].language` (or `.locale`), and the older
|
|
32
|
+
// `labels.language` and `fine_tuning.language`.
|
|
33
|
+
const elevenLabsVoice = z.object({
|
|
34
|
+
verified_languages: z
|
|
35
|
+
.array(z.object({ language: z.string().nullish(), locale: z.string().nullish() }))
|
|
36
|
+
.nullish(),
|
|
37
|
+
labels: z.object({ language: z.string().nullish() }).partial().nullish(),
|
|
38
|
+
fine_tuning: z.object({ language: z.string().nullish() }).partial().nullish(),
|
|
39
|
+
});
|
|
40
|
+
export function elevenLabsLanguages(body) {
|
|
41
|
+
const parsed = elevenLabsVoice.safeParse(body);
|
|
42
|
+
if (!parsed.success)
|
|
43
|
+
return undefined;
|
|
44
|
+
return primaryLanguages([
|
|
45
|
+
...(parsed.data.verified_languages ?? []).flatMap((one) => [one.language, one.locale]),
|
|
46
|
+
parsed.data.labels?.language,
|
|
47
|
+
parsed.data.fine_tuning?.language,
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
50
|
+
// GET /voices/{id}: `language` (ISO 639-1) and `accents[].locale`.
|
|
51
|
+
const cartesiaVoice = z.object({
|
|
52
|
+
language: z.string().nullish(),
|
|
53
|
+
accents: z.array(z.object({ locale: z.string().nullish() })).nullish(),
|
|
54
|
+
});
|
|
55
|
+
export function cartesiaLanguages(body) {
|
|
56
|
+
const parsed = cartesiaVoice.safeParse(body);
|
|
57
|
+
if (!parsed.success)
|
|
58
|
+
return undefined;
|
|
59
|
+
return primaryLanguages([
|
|
60
|
+
parsed.data.language,
|
|
61
|
+
...(parsed.data.accents ?? []).map((one) => one.locale),
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
// GET /voices/v1/voices/{id}: `languageCode` ("en-US"), `langCode` ("EN_US") and, for a
|
|
65
|
+
// multilingual voice, `promptLanguages`.
|
|
66
|
+
const inworldVoice = z.object({
|
|
67
|
+
languageCode: z.string().nullish(),
|
|
68
|
+
langCode: z.string().nullish(),
|
|
69
|
+
promptLanguages: z.array(z.string()).nullish(),
|
|
70
|
+
});
|
|
71
|
+
export function inworldLanguages(body) {
|
|
72
|
+
const parsed = inworldVoice.safeParse(typeof body === "object" && body !== null && "voice" in body ? body.voice : body);
|
|
73
|
+
if (!parsed.success)
|
|
74
|
+
return undefined;
|
|
75
|
+
return primaryLanguages([
|
|
76
|
+
parsed.data.languageCode,
|
|
77
|
+
parsed.data.langCode,
|
|
78
|
+
...(parsed.data.promptLanguages ?? []),
|
|
79
|
+
]);
|
|
80
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
|
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
|
@@ -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({
|
|
@@ -159,7 +159,7 @@ export function curateRegistry(registry, catalogue) {
|
|
|
159
159
|
if (request.text.length > model.tts.maxCharacters)
|
|
160
160
|
throw providerError({
|
|
161
161
|
kind: "unsupported",
|
|
162
|
-
message: `A piece of narration is longer than this voice model's ${model.tts.maxCharacters}-character limit. Use
|
|
162
|
+
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
163
|
});
|
|
164
164
|
return port.synthesize({ ...request, model: model.id });
|
|
165
165
|
},
|
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(),
|