@gentbajko/slopify 3.25.8 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/account-limits.js +30 -0
- package/dist/adapters/alignment/cache.js +3 -5
- package/dist/adapters/alignment/ctc.js +1 -2
- package/dist/adapters/alignment/lock.js +4 -3
- package/dist/adapters/alignment/multilingual.js +0 -3
- package/dist/adapters/alignment/prefetch.js +2 -1
- package/dist/adapters/alignment/worker.js +2 -1
- package/dist/adapters/explain.js +0 -3
- package/dist/adapters/ffmpeg.js +19 -1
- package/dist/adapters/host-cli/index.js +19 -3
- package/dist/adapters/http-failure.js +53 -0
- package/dist/adapters/image/codex.js +36 -4
- package/dist/adapters/image/fal.js +17 -50
- package/dist/adapters/image/google.js +31 -55
- package/dist/adapters/image/openai.js +20 -47
- package/dist/adapters/image/reference.js +36 -0
- package/dist/adapters/image/replicate.js +18 -47
- package/dist/adapters/interest/search-interest.js +113 -0
- package/dist/adapters/key-probes.js +53 -2
- package/dist/adapters/llm/antigravity.js +4 -0
- package/dist/adapters/llm/assistant-cli.js +388 -0
- package/dist/adapters/llm/child-session.js +83 -0
- package/dist/adapters/llm/claude-code-models.js +51 -98
- package/dist/adapters/llm/claude-code.js +13 -2
- package/dist/adapters/llm/codex-limits.js +27 -68
- package/dist/adapters/llm/codex-server-models.js +61 -109
- package/dist/adapters/llm/codex.js +12 -1
- package/dist/adapters/llm/openrouter.js +10 -47
- package/dist/adapters/llm/run-cli.js +6 -22
- package/dist/adapters/llm/sse-lines.js +5 -1
- package/dist/adapters/model-access.js +37 -0
- package/dist/adapters/tts/cartesia.js +15 -46
- package/dist/adapters/tts/elevenlabs.js +20 -52
- package/dist/adapters/tts/gemini.js +19 -40
- package/dist/adapters/tts/inworld-async.js +4 -1
- package/dist/adapters/tts/inworld.js +3 -0
- package/dist/adapters/tts/openai.js +20 -50
- package/dist/assets/models-lifecycle.yaml +6 -0
- package/dist/assistant-wiring.js +60 -0
- package/dist/autopilot-timers.js +59 -0
- package/dist/catalog/lifecycle.js +52 -0
- package/dist/catalog/propose.js +204 -0
- package/dist/catalog/registry.js +3 -1
- package/dist/catalog/schema.js +2 -0
- package/dist/catalog/store.js +39 -0
- package/dist/edge/autostart/native.js +3 -5
- package/dist/edge/autostart/prompt.js +2 -1
- package/dist/edge/autostart/service.js +3 -4
- package/dist/edge/cli-args.js +3 -4
- package/dist/edge/cli.js +2 -1
- package/dist/edge/docker-install/apply.js +11 -11
- package/dist/edge/docker-install/run.js +2 -1
- package/dist/edge/docker-install/state.js +4 -3
- package/dist/edge/docker-install/tree.js +2 -4
- package/dist/edge/docker-install/volume.js +3 -2
- package/dist/edge/docker.js +5 -4
- package/dist/edge/events/hub.js +5 -5
- package/dist/edge/http/actions.js +4 -25
- package/dist/edge/http/actor.js +5 -3
- package/dist/edge/http/app.js +85 -10
- package/dist/edge/http/assistant.js +127 -0
- package/dist/edge/http/audio-preview.js +4 -11
- package/dist/edge/http/auditions.js +1 -1
- package/dist/edge/http/autostart.js +5 -5
- package/dist/edge/http/backups.js +1 -3
- package/dist/edge/http/channel-memory.js +7 -20
- package/dist/edge/http/channels.js +13 -26
- package/dist/edge/http/checkpoints.js +33 -17
- package/dist/edge/http/design-templates.js +167 -0
- package/dist/edge/http/designs.js +178 -0
- package/dist/edge/http/diagnostics.js +5 -1
- package/dist/edge/http/document-themes.js +2 -11
- package/dist/edge/http/draft-files.js +1 -3
- package/dist/edge/http/draft-problem.js +4 -9
- package/dist/edge/http/drafts.js +3 -3
- package/dist/edge/http/entries.js +6 -9
- package/dist/edge/http/extension-auth.js +27 -0
- package/dist/edge/http/external-reviews.js +12 -11
- package/dist/edge/http/files.js +5 -11
- package/dist/edge/http/folder-location.js +1 -4
- package/dist/edge/http/fonts.js +0 -7
- package/dist/edge/http/home.js +38 -13
- package/dist/edge/http/host-cli.js +18 -8
- package/dist/edge/http/ids.js +8 -0
- package/dist/edge/http/keywords.js +35 -0
- package/dist/edge/http/model-checks.js +132 -0
- package/dist/edge/http/narration-peaks.js +5 -13
- package/dist/edge/http/onboarding.js +1 -14
- package/dist/edge/http/open-folder.js +5 -10
- package/dist/edge/http/outputs.js +4 -12
- package/dist/edge/http/patch-notes.js +4 -10
- package/dist/edge/http/planning.js +2 -6
- package/dist/edge/http/problem.js +2 -4
- package/dist/edge/http/project-create.js +1 -0
- package/dist/edge/http/project-templates.js +29 -17
- package/dist/edge/http/projects.js +2 -12
- package/dist/edge/http/prompts.js +7 -14
- package/dist/edge/http/pronunciations.js +1 -2
- package/dist/edge/http/providers.js +39 -24
- package/dist/edge/http/refusal.js +29 -0
- package/dist/edge/http/remote-access.js +40 -0
- package/dist/edge/http/remote-guard.js +71 -0
- package/dist/edge/http/request-guard.js +91 -0
- package/dist/edge/http/reviews.js +11 -24
- package/dist/edge/http/revision-files.js +5 -10
- package/dist/edge/http/revisions.js +10 -15
- package/dist/edge/http/run-cost.js +1 -2
- package/dist/edge/http/same-page.js +80 -0
- package/dist/edge/http/schedules.js +59 -32
- package/dist/edge/http/settings.js +22 -13
- package/dist/edge/http/social.js +282 -0
- package/dist/edge/http/staging.js +2 -4
- package/dist/edge/http/storage-files.js +5 -7
- package/dist/edge/http/storage.js +23 -23
- package/dist/edge/http/studio.js +23 -50
- package/dist/edge/http/style-preview.js +1 -4
- package/dist/edge/http/subtitles.js +3 -17
- package/dist/edge/http/template-studio.js +433 -0
- package/dist/edge/http/trash.js +10 -11
- package/dist/edge/http/tutorial.js +1 -2
- package/dist/edge/http/tutorials.js +5 -11
- package/dist/edge/http/update.js +7 -13
- package/dist/edge/http/waveform.js +3 -6
- package/dist/edge/http/youtube-edits.js +2 -3
- package/dist/edge/mcp/assistant.js +279 -0
- package/dist/edge/mcp/attribution.js +8 -2
- package/dist/edge/mcp/call-route.js +11 -2
- package/dist/edge/mcp/excluded-routes.js +25 -0
- package/dist/edge/mcp/http.js +11 -2
- package/dist/edge/mcp/instructions.js +5 -3
- package/dist/edge/mcp/library-tools.js +1 -0
- package/dist/edge/mcp/route-tool.js +35 -15
- package/dist/edge/mcp/server.js +13 -8
- package/dist/edge/mcp/tools-channels.js +2 -0
- package/dist/edge/mcp/tools-designs.js +165 -0
- package/dist/edge/mcp/tools-library.js +14 -2
- package/dist/edge/mcp/tools-planning.js +23 -4
- package/dist/edge/mcp/tools-projects.js +28 -1
- package/dist/edge/mcp/tools-runs.js +14 -1
- package/dist/edge/mcp/tools-schedules.js +28 -4
- package/dist/edge/mcp/tools-setup.js +61 -3
- package/dist/edge/mcp/tools-social.js +46 -0
- package/dist/edge/mcp/tools-storage.js +8 -0
- package/dist/edge/mcp/tools-template-studio.js +166 -0
- package/dist/edge/mcp/tools.js +6 -0
- package/dist/edge/remote-access/cli.js +71 -0
- package/dist/edge/remote-access/model.js +32 -0
- package/dist/edge/remote-access/rules.js +207 -0
- package/dist/edge/remote-access/service.js +203 -0
- package/dist/edge/remote-access/store.js +44 -0
- package/dist/edge/remote-access/views.js +43 -0
- package/dist/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/host-cli/install.js +2 -2
- package/dist/host-cli/open-folder.js +2 -2
- package/dist/host-cli/paths.js +2 -4
- package/dist/host-cli/server.js +4 -4
- package/dist/host-cli/service.js +3 -3
- package/dist/host-cli/status.js +7 -7
- package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
- package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
- package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
- package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
- package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
- package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
- package/dist/kernel/db/migrations/0070-designs.sql +53 -0
- package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
- package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
- package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
- package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
- package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
- package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
- package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
- package/dist/kernel/db/tx.js +2 -4
- package/dist/kernel/errors.js +27 -1
- package/dist/kernel/json-answer.js +15 -0
- package/dist/kernel/lock.js +4 -9
- package/dist/kernel/paths.js +8 -0
- package/dist/kernel/ports/assistant-cli.js +4 -0
- package/dist/kernel/ports/host-cli.js +3 -0
- package/dist/kernel/ports/interest.js +4 -0
- package/dist/kernel/ports/languages.js +0 -3
- package/dist/kernel/ports/model.js +2 -0
- package/dist/kernel/runner/attempt.js +3 -1
- package/dist/kernel/runner/audition.js +3 -1
- package/dist/kernel/runner/checkpoint-authority.js +2 -1
- package/dist/kernel/runner/index.js +8 -10
- package/dist/kernel/runner/model-access.js +40 -0
- package/dist/kernel/runner/model-check.js +153 -0
- package/dist/kernel/runner/providers.js +15 -10
- package/dist/kernel/runner/standalone.js +9 -5
- package/dist/main.js +334 -19
- package/dist/model-checks.js +166 -0
- package/dist/patch-notes/3.25.9.md +5 -0
- package/dist/patch-notes/4.0.0.md +51 -0
- package/dist/patch-notes/index.json +12 -0
- package/dist/slices/admission/heads.js +2 -1
- package/dist/slices/admission/repo.js +2 -1
- package/dist/slices/admission/rules.js +43 -8
- package/dist/slices/admission/schema.js +8 -0
- package/dist/slices/admission/stage-writes.js +0 -3
- package/dist/slices/admission/start.js +48 -31
- package/dist/slices/admission/substitute.js +7 -4
- package/dist/slices/agents/attention-posts.js +31 -0
- package/dist/slices/agents/attention-templates.js +33 -0
- package/dist/slices/agents/attention.js +10 -1
- package/dist/slices/agents/connection.js +2 -6
- package/dist/slices/agents/model.js +6 -3
- package/dist/slices/agents/repo.js +15 -7
- package/dist/slices/article/continuation.js +0 -63
- package/dist/slices/article/plain.js +3 -2
- package/dist/slices/article/segments.js +2 -62
- package/dist/slices/assistant/access.js +1 -0
- package/dist/slices/assistant/asks.js +80 -0
- package/dist/slices/assistant/cost.js +54 -0
- package/dist/slices/assistant/gate.js +222 -0
- package/dist/slices/assistant/model.js +79 -0
- package/dist/slices/assistant/names.js +23 -0
- package/dist/slices/assistant/prompt.js +74 -0
- package/dist/slices/assistant/repo.js +74 -0
- package/dist/slices/assistant/tokens.js +18 -0
- package/dist/slices/assistant/turn.js +342 -0
- package/dist/slices/autopilot/buffer.js +76 -0
- package/dist/slices/autopilot/model.js +14 -0
- package/dist/slices/autopilot/notify.js +27 -0
- package/dist/slices/autopilot/repo.js +34 -0
- package/dist/slices/autopilot/signals.js +194 -0
- package/dist/slices/autopilot/warnings.js +85 -0
- package/dist/slices/autopilot/weekly.js +100 -0
- package/dist/slices/backups/files.js +2 -6
- package/dist/slices/backups/repo.js +3 -15
- package/dist/slices/backups/service.js +4 -3
- package/dist/slices/channels/cast-images.js +2 -1
- package/dist/slices/channels/model.js +0 -1
- package/dist/slices/channels/rebrand.js +0 -3
- package/dist/slices/channels/repo.js +4 -0
- package/dist/slices/channels/schema.js +6 -0
- package/dist/slices/channels/service.js +10 -0
- package/dist/slices/channels/videos.js +2 -14
- package/dist/slices/checkpoints/index.js +0 -1
- package/dist/slices/control/providers.js +0 -26
- package/dist/slices/designs/artwork.js +66 -0
- package/dist/slices/designs/budget.js +23 -0
- package/dist/slices/designs/calls.js +124 -0
- package/dist/slices/designs/check-context.js +38 -0
- package/dist/slices/designs/check-text.js +43 -0
- package/dist/slices/designs/fields.js +88 -0
- package/dist/slices/designs/frames.js +34 -0
- package/dist/slices/designs/gate.js +128 -0
- package/dist/slices/designs/layout.js +293 -0
- package/dist/slices/designs/model.js +35 -0
- package/dist/slices/designs/pdf-job.js +23 -0
- package/dist/slices/designs/pdf-pages.js +30 -0
- package/dist/slices/designs/pdf-runner.js +68 -0
- package/dist/slices/designs/pdf-worker.js +24 -0
- package/dist/slices/designs/picture-size.js +79 -0
- package/dist/slices/designs/pictures.js +55 -0
- package/dist/slices/designs/quote.js +24 -0
- package/dist/slices/designs/render-args.js +36 -0
- package/dist/slices/designs/render-input.js +59 -0
- package/dist/slices/designs/render.js +215 -0
- package/dist/slices/designs/repo.js +101 -0
- package/dist/slices/designs/requests.js +80 -0
- package/dist/slices/designs/runner.js +239 -0
- package/dist/slices/designs/sample-repo.js +91 -0
- package/dist/slices/designs/sample.js +222 -0
- package/dist/slices/designs/schema.js +87 -0
- package/dist/slices/designs/sections.js +44 -0
- package/dist/slices/designs/service.js +233 -0
- package/dist/slices/designs/steps-repo.js +102 -0
- package/dist/slices/designs/studio-kind.js +39 -0
- package/dist/slices/designs/template-checks.js +44 -0
- package/dist/slices/designs/template-make.js +118 -0
- package/dist/slices/designs/templates.js +218 -0
- package/dist/slices/document/fonts.js +2 -1
- package/dist/slices/episodes/summarize.js +5 -1
- package/dist/slices/estimate/index.js +45 -7
- package/dist/slices/fonts/catalog.js +3 -2
- package/dist/slices/fonts/discovery.js +3 -2
- package/dist/slices/fonts/files.js +2 -6
- package/dist/slices/fonts/index.js +0 -1
- package/dist/slices/fonts/sfnt.js +45 -10
- package/dist/slices/images/appearance.js +6 -15
- package/dist/slices/images/scenes.js +100 -27
- package/dist/slices/keywords/digest.js +84 -0
- package/dist/slices/keywords/facts.js +92 -0
- package/dist/slices/keywords/fill.js +80 -0
- package/dist/slices/keywords/model.js +75 -0
- package/dist/slices/keywords/rules.js +187 -0
- package/dist/slices/keywords/schema.js +28 -0
- package/dist/slices/keywords/specs.js +260 -0
- package/dist/slices/keywords/values.js +74 -0
- package/dist/slices/library/lint.js +29 -12
- package/dist/slices/library/model.js +2 -0
- package/dist/slices/library/photorealistic.js +4 -12
- package/dist/slices/library/rename.js +9 -7
- package/dist/slices/library/save.js +14 -10
- package/dist/slices/library/slots.js +37 -11
- package/dist/slices/library/transfer.js +2 -1
- package/dist/slices/library/used-by.js +25 -10
- package/dist/slices/loudness/loudnorm.js +51 -11
- package/dist/slices/model-checks/cost.js +61 -0
- package/dist/slices/model-checks/listing.js +124 -0
- package/dist/slices/model-checks/model.js +20 -0
- package/dist/slices/model-checks/record.js +32 -0
- package/dist/slices/model-checks/repo.js +120 -0
- package/dist/slices/model-checks/rules.js +112 -0
- package/dist/slices/model-checks/run.js +143 -0
- package/dist/slices/model-checks/service.js +198 -0
- package/dist/slices/model-upkeep/switch.js +70 -25
- package/dist/slices/model-upkeep/usage.js +26 -11
- package/dist/slices/narration/breaths.js +2 -1
- package/dist/slices/narration/clean-pieces.js +2 -1
- package/dist/slices/narration/concat.js +2 -1
- package/dist/slices/narration/peaks.js +3 -4
- package/dist/slices/narration/pronunciation-chunks.js +4 -3
- package/dist/slices/narration/pronunciation.js +3 -2
- package/dist/slices/narration/steering.js +4 -3
- package/dist/slices/notifications/notifier.js +4 -3
- package/dist/slices/notifications/rules.js +5 -2
- package/dist/slices/notifications/settings.js +4 -12
- package/dist/slices/notifications/subject.js +2 -1
- package/dist/slices/onboarding/copy.js +2 -1
- package/dist/slices/onboarding/first-run.js +3 -2
- package/dist/slices/onboarding/full-video.js +3 -2
- package/dist/slices/onboarding/install.js +4 -3
- package/dist/slices/onboarding/model.js +0 -16
- package/dist/slices/onboarding/packs.js +22 -22
- package/dist/slices/onboarding/quick-short.js +2 -1
- package/dist/slices/onboarding/sample.js +0 -1
- package/dist/slices/onboarding/state.js +2 -11
- package/dist/slices/onboarding/template.js +2 -1
- package/dist/slices/patch-notes/library.js +3 -2
- package/dist/slices/play-drafts/convert.js +4 -0
- package/dist/slices/play-drafts/review-inputs.js +8 -2
- package/dist/slices/play-drafts/review.js +5 -4
- package/dist/slices/play-drafts/schema.js +4 -0
- package/dist/slices/project-templates/from-project.js +9 -2
- package/dist/slices/project-templates/repo.js +6 -1
- package/dist/slices/project-templates/setup.js +8 -0
- package/dist/slices/project-templates/stand-ins.js +22 -0
- package/dist/slices/rebuild/activity.js +2 -0
- package/dist/slices/rebuild/admission-repo.js +3 -2
- package/dist/slices/rebuild/narration-history.js +4 -5
- package/dist/slices/rebuild/narration-retry.js +2 -1
- package/dist/slices/rebuild/preview-details.js +27 -9
- package/dist/slices/rebuild/preview-plan.js +3 -8
- package/dist/slices/rebuild/recipe-build.js +8 -3
- package/dist/slices/rebuild/recipe-describe.js +3 -3
- package/dist/slices/rebuild/recipe-digest.js +58 -0
- package/dist/slices/rebuild/recipe-input-schema.js +10 -0
- package/dist/slices/rebuild/recipe-keywords.js +71 -0
- package/dist/slices/rebuild/recipe-legacy.js +5 -1
- package/dist/slices/rebuild/recipe-model.js +4 -0
- package/dist/slices/rebuild/recipe-narration-text.js +2 -1
- package/dist/slices/rebuild/recipe-preparation.js +3 -3
- package/dist/slices/rebuild/recipe-reference.js +8 -4
- package/dist/slices/rebuild/recipe-reviews.js +27 -7
- package/dist/slices/rebuild/recipe-save.js +6 -3
- package/dist/slices/rebuild/recipe-scenes.js +40 -11
- package/dist/slices/rebuild/recipe-shorts.js +8 -8
- package/dist/slices/rebuild/recipe-social.js +46 -0
- package/dist/slices/rebuild/recipe-text.js +64 -20
- package/dist/slices/rebuild/recipe-validation.js +98 -28
- package/dist/slices/rebuild/recipe-visual.js +55 -16
- package/dist/slices/rebuild/recipe-work.js +15 -3
- package/dist/slices/rebuild/recipe-youtube.js +4 -3
- package/dist/slices/rebuild/recovery-selection.js +3 -1
- package/dist/slices/rebuild/recovery.js +3 -2
- package/dist/slices/rebuild/repo.js +4 -3
- package/dist/slices/rebuild/review-promise.js +25 -0
- package/dist/slices/rebuild/review-redo.js +2 -1
- package/dist/slices/rebuild/runtime-admission.js +4 -3
- package/dist/slices/rebuild/runtime-agent-review.js +11 -5
- package/dist/slices/rebuild/runtime-animate.js +9 -8
- package/dist/slices/rebuild/runtime-article.js +3 -2
- package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
- package/dist/slices/rebuild/runtime-document.js +8 -11
- package/dist/slices/rebuild/runtime-export-bed.js +6 -11
- package/dist/slices/rebuild/runtime-export-edit.js +6 -15
- package/dist/slices/rebuild/runtime-export-inputs.js +7 -7
- package/dist/slices/rebuild/runtime-export-short.js +8 -4
- package/dist/slices/rebuild/runtime-export.js +34 -12
- package/dist/slices/rebuild/runtime-figure-card.js +2 -1
- package/dist/slices/rebuild/runtime-image.js +4 -9
- package/dist/slices/rebuild/runtime-instructions.js +2 -0
- package/dist/slices/rebuild/runtime-keywords.js +59 -0
- package/dist/slices/rebuild/runtime-lines.js +2 -11
- package/dist/slices/rebuild/runtime-local.js +14 -20
- package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
- package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
- package/dist/slices/rebuild/runtime-narration-text.js +10 -15
- package/dist/slices/rebuild/runtime-pictures.js +2 -4
- package/dist/slices/rebuild/runtime-piece-label.js +10 -6
- package/dist/slices/rebuild/runtime-plan.js +31 -5
- package/dist/slices/rebuild/runtime-provider.js +60 -19
- package/dist/slices/rebuild/runtime-publication.js +10 -9
- package/dist/slices/rebuild/runtime-review.js +33 -28
- package/dist/slices/rebuild/runtime-run.js +4 -1
- package/dist/slices/rebuild/runtime-shorts.js +34 -50
- package/dist/slices/rebuild/runtime-store.js +3 -8
- package/dist/slices/rebuild/runtime-subtitles.js +16 -14
- package/dist/slices/rebuild/runtime-voices.js +8 -15
- package/dist/slices/rebuild/runtime-youtube.js +11 -29
- package/dist/slices/rebuild/transition-repo.js +6 -5
- package/dist/slices/rebuild/work-records.js +6 -0
- package/dist/slices/reruns/cascade.js +1 -2
- package/dist/slices/reruns/index.js +6 -9
- package/dist/slices/reviews/external-model.js +3 -0
- package/dist/slices/reviews/external-repo.js +2 -1
- package/dist/slices/reviews/external-rows.js +2 -3
- package/dist/slices/reviews/model.js +26 -8
- package/dist/slices/reviews/repo.js +2 -1
- package/dist/slices/reviews/rules.js +1 -0
- package/dist/slices/reviews/view.js +5 -2
- package/dist/slices/revisions/downloads.js +4 -5
- package/dist/slices/revisions/mutation-assets.js +7 -4
- package/dist/slices/revisions/mutation-cues.js +2 -5
- package/dist/slices/revisions/mutations.js +0 -1
- package/dist/slices/revisions/repo.js +3 -1
- package/dist/slices/revisions/schema.js +1 -0
- package/dist/slices/revisions/view.js +20 -0
- package/dist/slices/run-cost/limits.js +5 -2
- package/dist/slices/run-cost/meter.js +12 -5
- package/dist/slices/run-cost/panel.js +8 -74
- package/dist/slices/run-cost/plan-readings.js +127 -0
- package/dist/slices/run-cost/plan-use.js +169 -0
- package/dist/slices/run-cost/pricing.js +3 -3
- package/dist/slices/run-cost/week.js +32 -4
- package/dist/slices/schedules/agenda.js +11 -2
- package/dist/slices/schedules/by-date.js +42 -0
- package/dist/slices/schedules/calendar.js +5 -0
- package/dist/slices/schedules/design-agenda.js +36 -0
- package/dist/slices/schedules/design-check.js +41 -0
- package/dist/slices/schedules/design-run.js +126 -0
- package/dist/slices/schedules/next-run.js +62 -0
- package/dist/slices/schedules/prepare.js +18 -2
- package/dist/slices/schedules/repo.js +24 -16
- package/dist/slices/schedules/rescore.js +35 -0
- package/dist/slices/schedules/scheduler.js +13 -3
- package/dist/slices/schedules/schema.js +54 -3
- package/dist/slices/schedules/score.js +107 -0
- package/dist/slices/schedules/service.js +57 -24
- package/dist/slices/schedules/topic-list.js +15 -0
- package/dist/slices/schedules/topic-scores.js +104 -0
- package/dist/slices/schedules/topics.js +48 -36
- package/dist/slices/settings/cli-paths.js +4 -6
- package/dist/slices/settings/first-run.js +2 -11
- package/dist/slices/settings/model-reach.js +3 -17
- package/dist/slices/settings/model.js +10 -0
- package/dist/slices/settings/playback.js +33 -22
- package/dist/slices/settings/probe-read.js +16 -0
- package/dist/slices/settings/repo.js +33 -0
- package/dist/slices/settings/tutorial.js +2 -2
- package/dist/slices/settings/voices.js +4 -12
- package/dist/slices/shorts/pick.js +2 -15
- package/dist/slices/shorts/prompts.js +2 -13
- package/dist/slices/shorts/render.js +3 -0
- package/dist/slices/social/channel.js +44 -0
- package/dist/slices/social/defaults.js +17 -0
- package/dist/slices/social/due.js +36 -0
- package/dist/slices/social/extension.js +18 -0
- package/dist/slices/social/fit.js +115 -0
- package/dist/slices/social/limits.js +186 -0
- package/dist/slices/social/links.js +21 -0
- package/dist/slices/social/media.js +131 -0
- package/dist/slices/social/model.js +75 -0
- package/dist/slices/social/notice.js +19 -0
- package/dist/slices/social/pack.js +176 -0
- package/dist/slices/social/post-prompt.js +55 -0
- package/dist/slices/social/queue.js +31 -0
- package/dist/slices/social/repo.js +133 -0
- package/dist/slices/social/reshape.js +97 -0
- package/dist/slices/social/rules.js +5 -0
- package/dist/slices/social/schema.js +70 -0
- package/dist/slices/social/serve.js +51 -0
- package/dist/slices/social/service.js +128 -0
- package/dist/slices/social/settings.js +21 -0
- package/dist/slices/social/sources.js +114 -0
- package/dist/slices/social/state.js +110 -0
- package/dist/slices/social/text.js +149 -0
- package/dist/slices/storage/arrange.js +3 -1
- package/dist/slices/storage/assets.js +8 -10
- package/dist/slices/storage/backup-designs.js +74 -0
- package/dist/slices/storage/backup-export.js +8 -3
- package/dist/slices/storage/backup-format.js +10 -0
- package/dist/slices/storage/backup-import.js +20 -2
- package/dist/slices/storage/delete-project.js +6 -5
- package/dist/slices/storage/files-location.js +6 -8
- package/dist/slices/storage/layout.js +13 -2
- package/dist/slices/storage/model.js +3 -0
- package/dist/slices/storage/portable.js +16 -11
- package/dist/slices/storage/schema.js +2 -0
- package/dist/slices/storage/staging-refs.js +2 -1
- package/dist/slices/storage/staging.js +6 -9
- package/dist/slices/storage/trim.js +10 -3
- package/dist/slices/studio/calendar.js +4 -1
- package/dist/slices/studio/pick.js +2 -11
- package/dist/slices/studio/plan.js +6 -15
- package/dist/slices/studio/queue.js +3 -14
- package/dist/slices/studio/releases.js +26 -0
- package/dist/slices/studio/settings.js +14 -51
- package/dist/slices/studio/videos.js +12 -0
- package/dist/slices/style-preview/render.js +34 -13
- package/dist/slices/style-preview/schema.js +13 -0
- package/dist/slices/style-preview/service.js +2 -1
- package/dist/slices/style-preview/settings.js +33 -5
- package/dist/slices/telemetry/collector-client.js +2 -4
- package/dist/slices/telemetry/flush.js +2 -4
- package/dist/slices/telemetry/model.js +0 -7
- package/dist/slices/telemetry/record.js +10 -3
- package/dist/slices/template-studio/anatomy-view.js +118 -0
- package/dist/slices/template-studio/anatomy.js +73 -0
- package/dist/slices/template-studio/bakeoff-make.js +225 -0
- package/dist/slices/template-studio/bakeoff-repo.js +83 -0
- package/dist/slices/template-studio/bakeoff.js +333 -0
- package/dist/slices/template-studio/budget.js +103 -0
- package/dist/slices/template-studio/checks.js +273 -0
- package/dist/slices/template-studio/document-sample.js +56 -0
- package/dist/slices/template-studio/edit.js +15 -0
- package/dist/slices/template-studio/for-all.js +161 -0
- package/dist/slices/template-studio/free-video.js +31 -0
- package/dist/slices/template-studio/free.js +176 -0
- package/dist/slices/template-studio/gate.js +40 -0
- package/dist/slices/template-studio/hidden.js +20 -0
- package/dist/slices/template-studio/jobs.js +79 -0
- package/dist/slices/template-studio/loudness.js +111 -0
- package/dist/slices/template-studio/make.js +40 -0
- package/dist/slices/template-studio/model.js +54 -0
- package/dist/slices/template-studio/pack-import.js +253 -0
- package/dist/slices/template-studio/pack-samples.js +60 -0
- package/dist/slices/template-studio/pack.js +205 -0
- package/dist/slices/template-studio/paid-view.js +66 -0
- package/dist/slices/template-studio/paid.js +348 -0
- package/dist/slices/template-studio/quote.js +148 -0
- package/dist/slices/template-studio/ready.js +104 -0
- package/dist/slices/template-studio/repo.js +134 -0
- package/dist/slices/template-studio/reviews-path.js +58 -0
- package/dist/slices/template-studio/runner.js +84 -0
- package/dist/slices/template-studio/save.js +236 -0
- package/dist/slices/template-studio/say-it-as.js +248 -0
- package/dist/slices/template-studio/schedule-gate.js +34 -0
- package/dist/slices/template-studio/schedule-price.js +30 -0
- package/dist/slices/template-studio/schedule-sample.js +87 -0
- package/dist/slices/template-studio/schema.js +218 -0
- package/dist/slices/template-studio/scope.js +124 -0
- package/dist/slices/template-studio/sections.js +176 -0
- package/dist/slices/template-studio/service.js +173 -0
- package/dist/slices/template-studio/status.js +174 -0
- package/dist/slices/template-studio/topic.js +223 -0
- package/dist/slices/trash/designs.js +76 -0
- package/dist/slices/trash/model.js +13 -4
- package/dist/slices/trash/service.js +52 -2
- package/dist/slices/tutorials/library.js +3 -2
- package/dist/slices/video/ass-text.js +17 -0
- package/dist/slices/video/audio-export.js +2 -64
- package/dist/slices/video/encoding.js +160 -0
- package/dist/slices/video/ffmpeg.js +23 -21
- package/dist/slices/video/figure-card.js +1 -15
- package/dist/slices/video/slideshow.js +43 -18
- package/dist/slices/voices/palette.js +0 -3
- package/dist/slices/youtube/answer.js +2 -15
- package/dist/slices/youtube/edits-repo.js +2 -11
- package/dist/tutorials/Agents-MCP.md +2 -1
- package/dist/tutorials/Assistant.md +42 -0
- package/dist/tutorials/Channels.md +2 -0
- package/dist/tutorials/Home-and-Projects.md +19 -0
- package/dist/tutorials/Install.md +1 -0
- package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
- package/dist/tutorials/Models.md +33 -1
- package/dist/tutorials/Notifications.md +6 -0
- package/dist/tutorials/Play-Images.md +4 -0
- package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
- package/dist/tutorials/Prompts.md +10 -6
- package/dist/tutorials/Remote-Access.md +63 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +13 -2
- package/dist/tutorials/Schedules.md +21 -1
- package/dist/tutorials/Settings-Reference.md +50 -8
- package/dist/tutorials/Template-Studio.md +125 -0
- package/dist/tutorials/Templates.md +3 -0
- package/dist/tutorials/_Sidebar.md +5 -0
- package/dist/updater/work-in-progress.js +42 -12
- package/dist/web/assets/index-CkAI_2E7.css +1 -0
- package/dist/web/assets/index-DcD0cdfo.js +334 -0
- package/dist/web/assets/{pdf-T7MCwjIv.js → pdf-TODRwF31.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +5 -1
- package/dist/slices/article/provided-entries.js +0 -66
- package/dist/slices/article/run.js +0 -145
- package/dist/slices/images/run.js +0 -234
- package/dist/slices/narration/legacy-plan.js +0 -58
- package/dist/slices/narration/run.js +0 -270
- package/dist/slices/rebuild/runtime-actions.js +0 -90
- package/dist/slices/research/run.js +0 -224
- package/dist/slices/subtitles/prepare.js +0 -194
- package/dist/slices/subtitles/transcript.js +0 -34
- package/dist/slices/thumbnail/run.js +0 -219
- package/dist/slices/video/audio-inputs.js +0 -33
- package/dist/slices/video/reuse-audio.js +0 -62
- package/dist/slices/video/run.js +0 -78
- package/dist/slices/video/write-export.js +0 -158
- package/dist/slices/video/write-subtitles.js +0 -59
- package/dist/web/assets/index-BadsoORk.css +0 -1
- package/dist/web/assets/index-D8LqNsCl.js +0 -326
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
1
|
import { z } from "zod";
|
|
6
2
|
import { cliCommand } from "../../kernel/cli-command.js";
|
|
7
3
|
import { isoOfEpoch, windowKindOf, } from "../../kernel/ports/plan-limits.js";
|
|
4
|
+
import { withChildSession } from "./child-session.js";
|
|
5
|
+
import { lines } from "./sse-lines.js";
|
|
8
6
|
// The Codex plan windows. `codex exec --json` reports none, so they are asked of the CLI's
|
|
9
7
|
// app server with `account/rateLimits/read` - a metadata-only exchange that starts no thread
|
|
10
8
|
// and spends nothing. Measured on 0.155.1: the reply carries `rateLimits.primary` and
|
|
@@ -40,49 +38,26 @@ export function codexWindows(result) {
|
|
|
40
38
|
// method, a slow start: the windows are reported beside a run, never needed for it.
|
|
41
39
|
export async function nodeCodexLimits(binary, env, timeoutMs = 10_000) {
|
|
42
40
|
const command = cliCommand(binary);
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
child
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
child.kill(signal);
|
|
66
|
-
};
|
|
67
|
-
const timer = setTimeout(() => terminate("SIGKILL"), timeoutMs);
|
|
68
|
-
const send = (message) => child.stdin.write(`${JSON.stringify(message)}\n`);
|
|
69
|
-
let buffer = "";
|
|
70
|
-
try {
|
|
71
|
-
send({
|
|
72
|
-
id: 1,
|
|
73
|
-
method: "initialize",
|
|
74
|
-
params: { clientInfo: { name: "slopify_limits", version: "1.0" } },
|
|
75
|
-
});
|
|
76
|
-
child.stdout.setEncoding("utf8");
|
|
77
|
-
for await (const piece of child.stdout) {
|
|
78
|
-
buffer += piece;
|
|
79
|
-
if (buffer.length > 1024 * 1024)
|
|
80
|
-
return null;
|
|
81
|
-
let newline = buffer.indexOf("\n");
|
|
82
|
-
while (newline >= 0) {
|
|
83
|
-
const line = buffer.slice(0, newline).trim();
|
|
84
|
-
buffer = buffer.slice(newline + 1);
|
|
85
|
-
newline = buffer.indexOf("\n");
|
|
41
|
+
const oversize = () => new Error("Oversized reply");
|
|
42
|
+
return withChildSession({
|
|
43
|
+
file: command.file,
|
|
44
|
+
args: [...command.args, "app-server", "--listen", "stdio://"],
|
|
45
|
+
env: (directory) => ({ ...env, PWD: directory }),
|
|
46
|
+
directoryPrefix: "slopify-codex-limits-",
|
|
47
|
+
timeoutMs,
|
|
48
|
+
graceMs: 1000,
|
|
49
|
+
}, async ({ child, send }) => {
|
|
50
|
+
try {
|
|
51
|
+
send({
|
|
52
|
+
id: 1,
|
|
53
|
+
method: "initialize",
|
|
54
|
+
params: { clientInfo: { name: "slopify_limits", version: "1.0" } },
|
|
55
|
+
});
|
|
56
|
+
for await (const raw of lines(child.stdout, undefined, {
|
|
57
|
+
chars: 1024 * 1024,
|
|
58
|
+
error: oversize,
|
|
59
|
+
})) {
|
|
60
|
+
const line = raw.trim();
|
|
86
61
|
if (line === "")
|
|
87
62
|
continue;
|
|
88
63
|
const reply = z
|
|
@@ -99,28 +74,12 @@ export async function nodeCodexLimits(binary, env, timeoutMs = 10_000) {
|
|
|
99
74
|
return windows.length === 0 ? null : windows;
|
|
100
75
|
}
|
|
101
76
|
}
|
|
77
|
+
return null;
|
|
102
78
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
finally {
|
|
109
|
-
clearTimeout(timer);
|
|
110
|
-
terminate("SIGTERM");
|
|
111
|
-
let grace;
|
|
112
|
-
await Promise.race([
|
|
113
|
-
closed,
|
|
114
|
-
new Promise((resolve) => {
|
|
115
|
-
grace = setTimeout(() => {
|
|
116
|
-
terminate("SIGKILL");
|
|
117
|
-
resolve();
|
|
118
|
-
}, 1000);
|
|
119
|
-
}),
|
|
120
|
-
]);
|
|
121
|
-
clearTimeout(grace);
|
|
122
|
-
await rm(directory, { recursive: true, force: true });
|
|
123
|
-
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
124
83
|
}
|
|
125
84
|
const months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
|
|
126
85
|
// Codex refuses a turn over the plan's allowance with "You've hit your usage limit. … Try
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
1
|
import { z } from "zod";
|
|
6
2
|
import { cliCommand } from "../../kernel/cli-command.js";
|
|
7
3
|
import { thinkingModes as knownEfforts } from "../../kernel/ports/llm.js";
|
|
4
|
+
import { cappedOutput, withChildSession } from "./child-session.js";
|
|
5
|
+
import { lines } from "./sse-lines.js";
|
|
8
6
|
const text = z
|
|
9
7
|
.string()
|
|
10
8
|
.trim()
|
|
@@ -28,39 +26,18 @@ const pageSchema = z.object({
|
|
|
28
26
|
// model/list is a metadata-only app-server exchange: no thread, turn or tool is started.
|
|
29
27
|
export async function nodeCodexServerModels(binary, env, timeoutMs = 15_000) {
|
|
30
28
|
const command = cliCommand(binary);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
env: { ...env, PWD: directory },
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
function terminate(signal) {
|
|
44
|
-
if (process.platform !== "win32" && child.pid !== undefined) {
|
|
45
|
-
try {
|
|
46
|
-
process.kill(-child.pid, signal);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
/* The process may already have exited. */
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
child.kill(signal);
|
|
54
|
-
}
|
|
55
|
-
const timer = setTimeout(() => terminate("SIGKILL"), timeoutMs);
|
|
56
|
-
const send = (message) => child.stdin.write(`${JSON.stringify(message)}\n`);
|
|
57
|
-
let expectedId = 1;
|
|
58
|
-
let pages = 0;
|
|
59
|
-
let bytes = 0;
|
|
60
|
-
let buffer = "";
|
|
61
|
-
const models = new Map();
|
|
62
|
-
const cursors = new Set();
|
|
63
|
-
try {
|
|
29
|
+
return withChildSession({
|
|
30
|
+
file: command.file,
|
|
31
|
+
args: [...command.args, "app-server", "--listen", "stdio://"],
|
|
32
|
+
env: (directory) => ({ ...env, PWD: directory }),
|
|
33
|
+
directoryPrefix: "slopify-codex-models-",
|
|
34
|
+
timeoutMs,
|
|
35
|
+
graceMs: 500,
|
|
36
|
+
}, async ({ child, send }) => {
|
|
37
|
+
let expectedId = 1;
|
|
38
|
+
let pages = 0;
|
|
39
|
+
const models = new Map();
|
|
40
|
+
const cursors = new Set();
|
|
64
41
|
send({
|
|
65
42
|
id: expectedId,
|
|
66
43
|
method: "initialize",
|
|
@@ -68,83 +45,58 @@ export async function nodeCodexServerModels(binary, env, timeoutMs = 15_000) {
|
|
|
68
45
|
clientInfo: { name: "slopify_model_discovery", version: "1.0" },
|
|
69
46
|
},
|
|
70
47
|
});
|
|
71
|
-
|
|
72
|
-
for await (const
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
48
|
+
const oversize = () => new Error("Oversized metadata");
|
|
49
|
+
for await (const raw of lines(cappedOutput(child.stdout, 4 * 1024 * 1024, oversize))) {
|
|
50
|
+
const line = raw.trim();
|
|
51
|
+
if (line === "")
|
|
52
|
+
continue;
|
|
53
|
+
const event = z
|
|
54
|
+
.object({
|
|
55
|
+
id: z.unknown().optional(),
|
|
56
|
+
result: z.unknown().optional(),
|
|
57
|
+
error: z.unknown().optional(),
|
|
58
|
+
})
|
|
59
|
+
.parse(JSON.parse(line));
|
|
60
|
+
if (event.id !== expectedId)
|
|
61
|
+
continue;
|
|
62
|
+
if (event.error !== undefined)
|
|
63
|
+
throw new Error("Discovery refused");
|
|
64
|
+
let cursor;
|
|
65
|
+
if (expectedId === 1) {
|
|
66
|
+
send({ method: "initialized" });
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const page = pageSchema.parse(event.result);
|
|
70
|
+
for (const row of page.data) {
|
|
71
|
+
if (row.hidden === true || models.has(row.model))
|
|
72
|
+
continue;
|
|
73
|
+
const thinkingModes = row.supportedReasoningEfforts
|
|
74
|
+
?.map((item) => item.reasoningEffort)
|
|
75
|
+
.filter((effort) => knownEfforts.includes(effort));
|
|
76
|
+
models.set(row.model, {
|
|
77
|
+
id: row.model,
|
|
78
|
+
name: codexModelName(row.displayName),
|
|
79
|
+
...(thinkingModes?.length ? { thinkingModes } : {}),
|
|
80
|
+
});
|
|
98
81
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const thinkingModes = row.supportedReasoningEfforts
|
|
105
|
-
?.map((item) => item.reasoningEffort)
|
|
106
|
-
.filter((effort) => knownEfforts.includes(effort));
|
|
107
|
-
models.set(row.model, {
|
|
108
|
-
id: row.model,
|
|
109
|
-
name: codexModelName(row.displayName),
|
|
110
|
-
...(thinkingModes?.length ? { thinkingModes } : {}),
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
cursor = page.nextCursor;
|
|
114
|
-
if (!cursor) {
|
|
115
|
-
if (models.size === 0)
|
|
116
|
-
throw new Error("No visible models");
|
|
117
|
-
return [...models.values()];
|
|
118
|
-
}
|
|
119
|
-
if (cursors.has(cursor) || ++pages >= 20)
|
|
120
|
-
throw new Error("Invalid pagination");
|
|
121
|
-
cursors.add(cursor);
|
|
82
|
+
cursor = page.nextCursor;
|
|
83
|
+
if (!cursor) {
|
|
84
|
+
if (models.size === 0)
|
|
85
|
+
throw new Error("No visible models");
|
|
86
|
+
return [...models.values()];
|
|
122
87
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
params: { limit: 100, includeHidden: false, ...(cursor ? { cursor } : {}) },
|
|
127
|
-
});
|
|
88
|
+
if (cursors.has(cursor) || ++pages >= 20)
|
|
89
|
+
throw new Error("Invalid pagination");
|
|
90
|
+
cursors.add(cursor);
|
|
128
91
|
}
|
|
92
|
+
send({
|
|
93
|
+
id: ++expectedId,
|
|
94
|
+
method: "model/list",
|
|
95
|
+
params: { limit: 100, includeHidden: false, ...(cursor ? { cursor } : {}) },
|
|
96
|
+
});
|
|
129
97
|
}
|
|
130
98
|
throw new Error("Discovery ended before its reply");
|
|
131
|
-
}
|
|
132
|
-
finally {
|
|
133
|
-
clearTimeout(timer);
|
|
134
|
-
terminate("SIGTERM");
|
|
135
|
-
let grace;
|
|
136
|
-
await Promise.race([
|
|
137
|
-
closed,
|
|
138
|
-
new Promise((resolve) => {
|
|
139
|
-
grace = setTimeout(() => {
|
|
140
|
-
terminate("SIGKILL");
|
|
141
|
-
resolve();
|
|
142
|
-
}, 500);
|
|
143
|
-
}),
|
|
144
|
-
]);
|
|
145
|
-
clearTimeout(grace);
|
|
146
|
-
await rm(directory, { recursive: true, force: true, maxRetries: 3, retryDelay: 50 });
|
|
147
|
-
}
|
|
99
|
+
});
|
|
148
100
|
}
|
|
149
101
|
export function codexModelName(name) {
|
|
150
102
|
return name.replace(/^(GPT-\d+(?:\.\d+)?)-/i, "$1 ");
|
|
@@ -5,6 +5,7 @@ import { z } from "zod";
|
|
|
5
5
|
import { redact } from "../../kernel/log.js";
|
|
6
6
|
import { providerError } from "../../kernel/ports/model.js";
|
|
7
7
|
import { cliCheck, cliReported } from "../explain.js";
|
|
8
|
+
import { accessField } from "../model-access.js";
|
|
8
9
|
import { cliLoginError } from "./cli-login-error.js";
|
|
9
10
|
import { codexPlanLimit } from "./codex-limits.js";
|
|
10
11
|
import { nodeCodexModels } from "./codex-models.js";
|
|
@@ -52,7 +53,10 @@ const disabledFeatures = [
|
|
|
52
53
|
// "-i, --image <FILE>... Optional image(s) to attach to the initial prompt"), which needs no
|
|
53
54
|
// tool: `view_image` stays disabled. Each is given as its own flag so a path is never read as
|
|
54
55
|
// the prompt.
|
|
55
|
-
|
|
56
|
+
// One ephemeral, read-only turn in `directory` with every local tool, hook, plugin, skill and
|
|
57
|
+
// project document left out. The content adapter and the in-app assistant (`assistant-cli.ts`)
|
|
58
|
+
// both start from it and add their own instructions, search setting and MCP servers.
|
|
59
|
+
export function hardenedCodexBase(directory) {
|
|
56
60
|
return [
|
|
57
61
|
"exec",
|
|
58
62
|
"--json",
|
|
@@ -86,6 +90,11 @@ export function codexArgs(req, directory, documents, images) {
|
|
|
86
90
|
"include_environment_context=false",
|
|
87
91
|
"-c",
|
|
88
92
|
'shell_environment_policy.inherit="none"',
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
export function codexArgs(req, directory, documents, images) {
|
|
96
|
+
return [
|
|
97
|
+
...hardenedCodexBase(directory),
|
|
89
98
|
"-c",
|
|
90
99
|
`instructions=${JSON.stringify(writingRole + (documents ? " Use the explicitly supplied research MCP tool to read request documents; it is the only permitted local reference source." : ""))}`,
|
|
91
100
|
"-c",
|
|
@@ -221,6 +230,7 @@ export function codexLlm(deps) {
|
|
|
221
230
|
throw codexLimitError(failed, planLimit);
|
|
222
231
|
throw providerError({
|
|
223
232
|
kind: "other",
|
|
233
|
+
...accessField(null, failed),
|
|
224
234
|
message: cliReported(binary, redact(cliShaped(binary, turnFailed, event.value).error.message), cliCheck(binary)),
|
|
225
235
|
});
|
|
226
236
|
}
|
|
@@ -234,6 +244,7 @@ export function codexLlm(deps) {
|
|
|
234
244
|
throw codexLimitError(failed, planLimit);
|
|
235
245
|
throw providerError({
|
|
236
246
|
kind: "other",
|
|
247
|
+
...accessField(null, failed),
|
|
237
248
|
message: cliReported(binary, redact(cliShaped(binary, errorEvent, event.value).message), cliCheck(binary)),
|
|
238
249
|
});
|
|
239
250
|
}
|
|
@@ -2,8 +2,9 @@ import { z } from "zod";
|
|
|
2
2
|
import { redact } from "../../kernel/log.js";
|
|
3
3
|
import { documentMessages } from "../../kernel/ports/llm-documents.js";
|
|
4
4
|
import { providerError } from "../../kernel/ports/model.js";
|
|
5
|
-
import { droppedStream, httpFailure,
|
|
6
|
-
import {
|
|
5
|
+
import { droppedStream, httpFailure, providerSaid, refreshList, unreadable } from "../explain.js";
|
|
6
|
+
import { failureText, httpProviderError, kindOfStatus, requireKey, safeJson, } from "../http-failure.js";
|
|
7
|
+
import { accessField, modelAccessOf } from "../model-access.js";
|
|
7
8
|
import { noImages } from "./image-workspace.js";
|
|
8
9
|
import { sseData } from "./sse-lines.js";
|
|
9
10
|
// The HTTP gateway adapter: the platform's own `fetch` plus the line reader beside this
|
|
@@ -86,7 +87,8 @@ export function openRouterLlm(deps) {
|
|
|
86
87
|
// A stream that has already answered 200 reports a mid-flight failure in a data
|
|
87
88
|
// frame; without this the stage would store half an article as a success.
|
|
88
89
|
throw providerError({
|
|
89
|
-
kind:
|
|
90
|
+
kind: kindOfStatus(statusOf(chunk.error.code)),
|
|
91
|
+
...accessField(statusOf(chunk.error.code), chunk.error.message),
|
|
90
92
|
message: streamFailure(statusOf(chunk.error.code), redact(chunk.error.message)),
|
|
91
93
|
});
|
|
92
94
|
}
|
|
@@ -147,47 +149,16 @@ export function openRouterLlm(deps) {
|
|
|
147
149
|
};
|
|
148
150
|
}
|
|
149
151
|
function headers(key) {
|
|
150
|
-
// An attempt that finds no key fails rather than calling anonymously
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
// retry until the user saves a key, and the wrapper is where that is decided.
|
|
154
|
-
if (key === undefined || key === "") {
|
|
155
|
-
throw providerError({ kind: "missing_key", message: missingKey("OpenRouter") });
|
|
156
|
-
}
|
|
157
|
-
return { Authorization: `Bearer ${key}`, ...appHeaders };
|
|
158
|
-
}
|
|
159
|
-
// Only the adapter sees the vendor's status code, so only the adapter names the kind.
|
|
160
|
-
function kindOf(status) {
|
|
161
|
-
if (status === 401 || status === 403) {
|
|
162
|
-
return "auth";
|
|
163
|
-
}
|
|
164
|
-
if (status === 429) {
|
|
165
|
-
return "rate_limit";
|
|
166
|
-
}
|
|
167
|
-
// ceiling: everything else is `other` and is retried, so a 400 or a 402 fails the same
|
|
168
|
-
// way four times over. A terminal "this will never work" kind has to reach the port's
|
|
169
|
-
// error contract first, which is not this adapter's to widen.
|
|
170
|
-
// The provider's own server failed; the same request may well succeed later.
|
|
171
|
-
if (status >= 500)
|
|
172
|
-
return "dropped";
|
|
173
|
-
return "other";
|
|
152
|
+
// An attempt that finds no key fails rather than calling anonymously and being told off by
|
|
153
|
+
// the provider in words the user cannot act on.
|
|
154
|
+
return { Authorization: `Bearer ${requireKey(key, "OpenRouter")}`, ...appHeaders };
|
|
174
155
|
}
|
|
175
156
|
async function failure(response, next) {
|
|
176
|
-
const text = await response
|
|
157
|
+
const text = await failureText(response);
|
|
177
158
|
const parsed = errorBody.safeParse(safeJson(text));
|
|
178
159
|
// The provider's own words, through the redactor - an error body may quote the key back.
|
|
179
160
|
const message = redact(parsed.success ? parsed.data.error.message : text.trim() || response.statusText);
|
|
180
|
-
|
|
181
|
-
return providerError({
|
|
182
|
-
kind: kindOf(response.status),
|
|
183
|
-
message: httpFailure({
|
|
184
|
-
provider: "OpenRouter",
|
|
185
|
-
status: response.status,
|
|
186
|
-
detail: message,
|
|
187
|
-
next,
|
|
188
|
-
}),
|
|
189
|
-
...(retryAfterMs === undefined ? {} : { retryAfterMs }),
|
|
190
|
-
});
|
|
161
|
+
return httpProviderError(response, kindOfStatus(response.status), httpFailure({ provider: "OpenRouter", status: response.status, detail: message, next }), undefined, modelAccessOf(response.status, message));
|
|
191
162
|
}
|
|
192
163
|
// A mid-stream error carries an HTTP-like code; with none, the provider's words are all there is.
|
|
193
164
|
function streamFailure(status, detail) {
|
|
@@ -211,11 +182,3 @@ function parseChunk(data) {
|
|
|
211
182
|
}
|
|
212
183
|
return parsed.data;
|
|
213
184
|
}
|
|
214
|
-
function safeJson(text) {
|
|
215
|
-
try {
|
|
216
|
-
return JSON.parse(text);
|
|
217
|
-
}
|
|
218
|
-
catch {
|
|
219
|
-
return undefined;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
@@ -4,6 +4,7 @@ import { cliCommand } from "../../kernel/cli-command.js";
|
|
|
4
4
|
import { redact } from "../../kernel/log.js";
|
|
5
5
|
import { providerError } from "../../kernel/ports/model.js";
|
|
6
6
|
import { cliName, commandOf, quoted } from "../explain.js";
|
|
7
|
+
import { safeJson } from "../http-failure.js";
|
|
7
8
|
// ceiling: the last 8 KiB of stderr is kept. A CLI that writes megabytes of progress there
|
|
8
9
|
// would otherwise be held in memory for the length of a run, and the tail is the part that
|
|
9
10
|
// says why it stopped. Streaming stderr to the log is the upgrade if a provider ever
|
|
@@ -108,7 +109,7 @@ export function nodeRunCli(binary, args, signal, options) {
|
|
|
108
109
|
return {
|
|
109
110
|
...(inputWritten === undefined ? {} : { inputWritten }),
|
|
110
111
|
pid: child.pid,
|
|
111
|
-
stdout:
|
|
112
|
+
stdout: bytesOf(child.stdout),
|
|
112
113
|
stderr: () => stderr,
|
|
113
114
|
ended,
|
|
114
115
|
kill: terminate,
|
|
@@ -181,13 +182,6 @@ export function endedKind(ended) {
|
|
|
181
182
|
export function stuckCli(binary) {
|
|
182
183
|
return `The ${cliName(binary)} stopped responding and could not be shut down. Close any leftover ${commandOf(binary)} processes or restart your computer, then use Try again.`;
|
|
183
184
|
}
|
|
184
|
-
// Unreachable while stdio names `pipe` for fd 1; it is here so the type carries no null
|
|
185
|
-
// and no non-null assertion is needed to read the stream.
|
|
186
|
-
const nothing = {
|
|
187
|
-
[Symbol.asyncIterator]: () => ({
|
|
188
|
-
next: () => Promise.resolve({ done: true, value: undefined }),
|
|
189
|
-
}),
|
|
190
|
-
};
|
|
191
185
|
const typed = z.object({ type: z.string() });
|
|
192
186
|
// A JSONL line off a CLI's stdout. The raw value travels with its `type` because a schema
|
|
193
187
|
// that names only `type` strips every other key, and each event's own shape is checked
|
|
@@ -215,22 +209,12 @@ export function cliShaped(binary, schema, value) {
|
|
|
215
209
|
}
|
|
216
210
|
return parsed.data;
|
|
217
211
|
}
|
|
212
|
+
// fd 1 is always a pipe with no encoding, so its pieces are bytes; the null check is for the type.
|
|
218
213
|
async function* bytesOf(source) {
|
|
214
|
+
if (source === null)
|
|
215
|
+
return;
|
|
219
216
|
for await (const piece of source) {
|
|
220
|
-
if (
|
|
221
|
-
yield new TextEncoder().encode(piece);
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
if (piece instanceof Uint8Array) {
|
|
217
|
+
if (piece instanceof Uint8Array)
|
|
225
218
|
yield piece;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
function safeJson(text) {
|
|
230
|
-
try {
|
|
231
|
-
return JSON.parse(text);
|
|
232
|
-
}
|
|
233
|
-
catch {
|
|
234
|
-
return undefined;
|
|
235
219
|
}
|
|
236
220
|
}
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
// the middle of one, or inside a multi-byte character. TextDecoder's streaming mode holds
|
|
6
6
|
// back the tail of a split UTF-8 sequence instead of emitting a replacement character,
|
|
7
7
|
// and the leftover buffer holds back a split line.
|
|
8
|
-
export async function* lines(chunks, signal
|
|
8
|
+
export async function* lines(chunks, signal,
|
|
9
|
+
// A producer that never ends a line would otherwise grow the buffer without bound.
|
|
10
|
+
pending) {
|
|
9
11
|
const decoder = new TextDecoder("utf-8");
|
|
10
12
|
let buffer = "";
|
|
11
13
|
for await (const chunk of chunks) {
|
|
@@ -15,6 +17,8 @@ export async function* lines(chunks, signal) {
|
|
|
15
17
|
yield withoutCr(buffer.slice(0, at));
|
|
16
18
|
buffer = buffer.slice(at + 1);
|
|
17
19
|
}
|
|
20
|
+
if (pending !== undefined && buffer.length > pending.chars)
|
|
21
|
+
throw pending.error();
|
|
18
22
|
}
|
|
19
23
|
buffer += decoder.decode();
|
|
20
24
|
// A producer that ends without a trailing newline still wrote a whole line, and one cut
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Whether a provider's failure says the account can't use the chosen model. Read from the
|
|
2
|
+
// status and the provider's own words, since only the adapter sees them; it never changes the
|
|
3
|
+
// error's kind, so a run fails exactly as before. Undefined: the failure says nothing about
|
|
4
|
+
// the model.
|
|
5
|
+
// Not-found comes first: OpenAI's "does not exist or you do not have access to it" is about a
|
|
6
|
+
// model id, not a plan. The loose phrases count only when the text is about a model, so a
|
|
7
|
+
// voice or a file that does not exist is not mistaken for one.
|
|
8
|
+
const notFound = /model_not_found|not a valid model|model not found|no endpoints found|invalid model|unknown model|is not found for api version|models\/[^ ]+ is not found/i;
|
|
9
|
+
const looseNotFound = /does not exist|may not exist|not[_ ]found/i;
|
|
10
|
+
const noAccess = /not supported when using codex with a chatgpt account|not (?:available|included|supported) (?:on|in|for|with) your (?:current )?(?:plan|account|subscription|tier|region|country)|upgrade your (?:plan|subscription)|must be verified to use the model|does not have access to (?:the )?model|do not have access to (?:this|the) model|not allowed to (?:use|access) (?:this|the) model|requires a paid plan/i;
|
|
11
|
+
const mentionsModel = /\bmodel/i;
|
|
12
|
+
// `atModel`: the request went to the model's own address (fal.ai's and Replicate's endpoints,
|
|
13
|
+
// Google's models/<id>), so a 404 or 403 there is about the model whatever the words say.
|
|
14
|
+
export function modelAccessOf(status, text, atModel = false) {
|
|
15
|
+
if (notFound.test(text))
|
|
16
|
+
return "not-found";
|
|
17
|
+
// "Upgrade your plan" or "not found" alone is as often about credits, a voice or a feature
|
|
18
|
+
// as about a model.
|
|
19
|
+
if (mentionsModel.test(text)) {
|
|
20
|
+
if (looseNotFound.test(text))
|
|
21
|
+
return "not-found";
|
|
22
|
+
if (noAccess.test(text))
|
|
23
|
+
return "no-access";
|
|
24
|
+
}
|
|
25
|
+
else if (!atModel)
|
|
26
|
+
return undefined;
|
|
27
|
+
if (status === 404)
|
|
28
|
+
return "not-found";
|
|
29
|
+
if (status === 403)
|
|
30
|
+
return "no-access";
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
// Spread into a providerError init.
|
|
34
|
+
export function accessField(status, text, atModel = false) {
|
|
35
|
+
const access = modelAccessOf(status, text, atModel);
|
|
36
|
+
return access === undefined ? {} : { access };
|
|
37
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { redact } from "../../kernel/log.js";
|
|
3
3
|
import { providerError } from "../../kernel/ports/model.js";
|
|
4
|
-
import { httpFailure,
|
|
5
|
-
import {
|
|
4
|
+
import { httpFailure, noAudio, voiceFix } from "../explain.js";
|
|
5
|
+
import { failureText, httpProviderError, kindOfStatus, requireKey, safeJson, } from "../http-failure.js";
|
|
6
|
+
import { modelAccessOf } from "../model-access.js";
|
|
6
7
|
import { cartesiaLanguages, lookUp } from "./voice-languages.js";
|
|
7
8
|
// The HTTP gateway adapter for Cartesia. `fetch` and
|
|
8
9
|
// nothing else; `/tts/bytes` streams the audio it renders, so the response body is
|
|
@@ -69,45 +70,21 @@ export function cartesiaTts(deps) {
|
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
function keyOf(deps) {
|
|
72
|
-
|
|
73
|
-
// An absent key is terminal, so it never becomes a request.
|
|
74
|
-
if (key === undefined || key === "") {
|
|
75
|
-
throw providerError({ kind: "missing_key", message: missingKey("Cartesia") });
|
|
76
|
-
}
|
|
77
|
-
return key;
|
|
78
|
-
}
|
|
79
|
-
function kindOf(status) {
|
|
80
|
-
if (status === 401 || status === 403) {
|
|
81
|
-
return "auth";
|
|
82
|
-
}
|
|
83
|
-
// `concurrency_limited` is the plan's own limit and arrives as a 429 like any other, so
|
|
84
|
-
// the status is enough and the code below only reaches the message.
|
|
85
|
-
if (status === 429) {
|
|
86
|
-
return "rate_limit";
|
|
87
|
-
}
|
|
88
|
-
// ceiling: as in the other two adapters, everything else is `other` and is retried.
|
|
89
|
-
// The provider's own server failed; the same request may well succeed later.
|
|
90
|
-
if (status >= 500)
|
|
91
|
-
return "dropped";
|
|
92
|
-
return "other";
|
|
73
|
+
return requireKey(deps.key(), "Cartesia");
|
|
93
74
|
}
|
|
94
75
|
async function failure(response, voiceId) {
|
|
95
|
-
const text = await response
|
|
76
|
+
const text = await failureText(response);
|
|
96
77
|
const message = redact(detailOf(text) || response.statusText);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
fix: voiceFix(voiceId),
|
|
108
|
-
}),
|
|
109
|
-
...(retryAfterMs === undefined ? {} : { retryAfterMs }),
|
|
110
|
-
});
|
|
78
|
+
return httpProviderError(response, kindOfStatus(response.status),
|
|
79
|
+
// `voice_not_found` has to say which voice was asked for; Cartesia's
|
|
80
|
+
// own message does not repeat the id.
|
|
81
|
+
httpFailure({
|
|
82
|
+
provider: "Cartesia",
|
|
83
|
+
status: response.status,
|
|
84
|
+
detail: message,
|
|
85
|
+
subject: `narration request for voice "${voiceId}"`,
|
|
86
|
+
fix: voiceFix(voiceId),
|
|
87
|
+
}), undefined, modelAccessOf(response.status, text));
|
|
111
88
|
}
|
|
112
89
|
function detailOf(text) {
|
|
113
90
|
const parsed = errorBody.safeParse(safeJson(text));
|
|
@@ -120,11 +97,3 @@ function detailOf(text) {
|
|
|
120
97
|
const parts = [code, message].filter((part) => part !== undefined && part !== "");
|
|
121
98
|
return parts.length === 0 ? text.trim() : parts.join(": ");
|
|
122
99
|
}
|
|
123
|
-
function safeJson(text) {
|
|
124
|
-
try {
|
|
125
|
-
return JSON.parse(text);
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
}
|