@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.
Files changed (604) hide show
  1. package/dist/adapters/account-limits.js +30 -0
  2. package/dist/adapters/alignment/cache.js +3 -5
  3. package/dist/adapters/alignment/ctc.js +1 -2
  4. package/dist/adapters/alignment/lock.js +4 -3
  5. package/dist/adapters/alignment/multilingual.js +0 -3
  6. package/dist/adapters/alignment/prefetch.js +2 -1
  7. package/dist/adapters/alignment/worker.js +2 -1
  8. package/dist/adapters/explain.js +0 -3
  9. package/dist/adapters/ffmpeg.js +19 -1
  10. package/dist/adapters/host-cli/index.js +19 -3
  11. package/dist/adapters/http-failure.js +53 -0
  12. package/dist/adapters/image/codex.js +36 -4
  13. package/dist/adapters/image/fal.js +17 -50
  14. package/dist/adapters/image/google.js +31 -55
  15. package/dist/adapters/image/openai.js +20 -47
  16. package/dist/adapters/image/reference.js +36 -0
  17. package/dist/adapters/image/replicate.js +18 -47
  18. package/dist/adapters/interest/search-interest.js +113 -0
  19. package/dist/adapters/key-probes.js +53 -2
  20. package/dist/adapters/llm/antigravity.js +4 -0
  21. package/dist/adapters/llm/assistant-cli.js +388 -0
  22. package/dist/adapters/llm/child-session.js +83 -0
  23. package/dist/adapters/llm/claude-code-models.js +51 -98
  24. package/dist/adapters/llm/claude-code.js +13 -2
  25. package/dist/adapters/llm/codex-limits.js +27 -68
  26. package/dist/adapters/llm/codex-server-models.js +61 -109
  27. package/dist/adapters/llm/codex.js +12 -1
  28. package/dist/adapters/llm/openrouter.js +10 -47
  29. package/dist/adapters/llm/run-cli.js +6 -22
  30. package/dist/adapters/llm/sse-lines.js +5 -1
  31. package/dist/adapters/model-access.js +37 -0
  32. package/dist/adapters/tts/cartesia.js +15 -46
  33. package/dist/adapters/tts/elevenlabs.js +20 -52
  34. package/dist/adapters/tts/gemini.js +19 -40
  35. package/dist/adapters/tts/inworld-async.js +4 -1
  36. package/dist/adapters/tts/inworld.js +3 -0
  37. package/dist/adapters/tts/openai.js +20 -50
  38. package/dist/assets/models-lifecycle.yaml +6 -0
  39. package/dist/assistant-wiring.js +60 -0
  40. package/dist/autopilot-timers.js +59 -0
  41. package/dist/catalog/lifecycle.js +52 -0
  42. package/dist/catalog/propose.js +204 -0
  43. package/dist/catalog/registry.js +3 -1
  44. package/dist/catalog/schema.js +2 -0
  45. package/dist/catalog/store.js +39 -0
  46. package/dist/edge/autostart/native.js +3 -5
  47. package/dist/edge/autostart/prompt.js +2 -1
  48. package/dist/edge/autostart/service.js +3 -4
  49. package/dist/edge/cli-args.js +3 -4
  50. package/dist/edge/cli.js +2 -1
  51. package/dist/edge/docker-install/apply.js +11 -11
  52. package/dist/edge/docker-install/run.js +2 -1
  53. package/dist/edge/docker-install/state.js +4 -3
  54. package/dist/edge/docker-install/tree.js +2 -4
  55. package/dist/edge/docker-install/volume.js +3 -2
  56. package/dist/edge/docker.js +5 -4
  57. package/dist/edge/events/hub.js +5 -5
  58. package/dist/edge/http/actions.js +4 -25
  59. package/dist/edge/http/actor.js +5 -3
  60. package/dist/edge/http/app.js +85 -10
  61. package/dist/edge/http/assistant.js +127 -0
  62. package/dist/edge/http/audio-preview.js +4 -11
  63. package/dist/edge/http/auditions.js +1 -1
  64. package/dist/edge/http/autostart.js +5 -5
  65. package/dist/edge/http/backups.js +1 -3
  66. package/dist/edge/http/channel-memory.js +7 -20
  67. package/dist/edge/http/channels.js +13 -26
  68. package/dist/edge/http/checkpoints.js +33 -17
  69. package/dist/edge/http/design-templates.js +167 -0
  70. package/dist/edge/http/designs.js +178 -0
  71. package/dist/edge/http/diagnostics.js +5 -1
  72. package/dist/edge/http/document-themes.js +2 -11
  73. package/dist/edge/http/draft-files.js +1 -3
  74. package/dist/edge/http/draft-problem.js +4 -9
  75. package/dist/edge/http/drafts.js +3 -3
  76. package/dist/edge/http/entries.js +6 -9
  77. package/dist/edge/http/extension-auth.js +27 -0
  78. package/dist/edge/http/external-reviews.js +12 -11
  79. package/dist/edge/http/files.js +5 -11
  80. package/dist/edge/http/folder-location.js +1 -4
  81. package/dist/edge/http/fonts.js +0 -7
  82. package/dist/edge/http/home.js +38 -13
  83. package/dist/edge/http/host-cli.js +18 -8
  84. package/dist/edge/http/ids.js +8 -0
  85. package/dist/edge/http/keywords.js +35 -0
  86. package/dist/edge/http/model-checks.js +132 -0
  87. package/dist/edge/http/narration-peaks.js +5 -13
  88. package/dist/edge/http/onboarding.js +1 -14
  89. package/dist/edge/http/open-folder.js +5 -10
  90. package/dist/edge/http/outputs.js +4 -12
  91. package/dist/edge/http/patch-notes.js +4 -10
  92. package/dist/edge/http/planning.js +2 -6
  93. package/dist/edge/http/problem.js +2 -4
  94. package/dist/edge/http/project-create.js +1 -0
  95. package/dist/edge/http/project-templates.js +29 -17
  96. package/dist/edge/http/projects.js +2 -12
  97. package/dist/edge/http/prompts.js +7 -14
  98. package/dist/edge/http/pronunciations.js +1 -2
  99. package/dist/edge/http/providers.js +39 -24
  100. package/dist/edge/http/refusal.js +29 -0
  101. package/dist/edge/http/remote-access.js +40 -0
  102. package/dist/edge/http/remote-guard.js +71 -0
  103. package/dist/edge/http/request-guard.js +91 -0
  104. package/dist/edge/http/reviews.js +11 -24
  105. package/dist/edge/http/revision-files.js +5 -10
  106. package/dist/edge/http/revisions.js +10 -15
  107. package/dist/edge/http/run-cost.js +1 -2
  108. package/dist/edge/http/same-page.js +80 -0
  109. package/dist/edge/http/schedules.js +59 -32
  110. package/dist/edge/http/settings.js +22 -13
  111. package/dist/edge/http/social.js +282 -0
  112. package/dist/edge/http/staging.js +2 -4
  113. package/dist/edge/http/storage-files.js +5 -7
  114. package/dist/edge/http/storage.js +23 -23
  115. package/dist/edge/http/studio.js +23 -50
  116. package/dist/edge/http/style-preview.js +1 -4
  117. package/dist/edge/http/subtitles.js +3 -17
  118. package/dist/edge/http/template-studio.js +433 -0
  119. package/dist/edge/http/trash.js +10 -11
  120. package/dist/edge/http/tutorial.js +1 -2
  121. package/dist/edge/http/tutorials.js +5 -11
  122. package/dist/edge/http/update.js +7 -13
  123. package/dist/edge/http/waveform.js +3 -6
  124. package/dist/edge/http/youtube-edits.js +2 -3
  125. package/dist/edge/mcp/assistant.js +279 -0
  126. package/dist/edge/mcp/attribution.js +8 -2
  127. package/dist/edge/mcp/call-route.js +11 -2
  128. package/dist/edge/mcp/excluded-routes.js +25 -0
  129. package/dist/edge/mcp/http.js +11 -2
  130. package/dist/edge/mcp/instructions.js +5 -3
  131. package/dist/edge/mcp/library-tools.js +1 -0
  132. package/dist/edge/mcp/route-tool.js +35 -15
  133. package/dist/edge/mcp/server.js +13 -8
  134. package/dist/edge/mcp/tools-channels.js +2 -0
  135. package/dist/edge/mcp/tools-designs.js +165 -0
  136. package/dist/edge/mcp/tools-library.js +14 -2
  137. package/dist/edge/mcp/tools-planning.js +23 -4
  138. package/dist/edge/mcp/tools-projects.js +28 -1
  139. package/dist/edge/mcp/tools-runs.js +14 -1
  140. package/dist/edge/mcp/tools-schedules.js +28 -4
  141. package/dist/edge/mcp/tools-setup.js +61 -3
  142. package/dist/edge/mcp/tools-social.js +46 -0
  143. package/dist/edge/mcp/tools-storage.js +8 -0
  144. package/dist/edge/mcp/tools-template-studio.js +166 -0
  145. package/dist/edge/mcp/tools.js +6 -0
  146. package/dist/edge/remote-access/cli.js +71 -0
  147. package/dist/edge/remote-access/model.js +32 -0
  148. package/dist/edge/remote-access/rules.js +207 -0
  149. package/dist/edge/remote-access/service.js +203 -0
  150. package/dist/edge/remote-access/store.js +44 -0
  151. package/dist/edge/remote-access/views.js +43 -0
  152. package/dist/extension/slopify-studio-chrome.zip +0 -0
  153. package/dist/extension/slopify-studio-firefox.zip +0 -0
  154. package/dist/host-cli/install.js +2 -2
  155. package/dist/host-cli/open-folder.js +2 -2
  156. package/dist/host-cli/paths.js +2 -4
  157. package/dist/host-cli/server.js +4 -4
  158. package/dist/host-cli/service.js +3 -3
  159. package/dist/host-cli/status.js +7 -7
  160. package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
  161. package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
  162. package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
  163. package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
  164. package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
  165. package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
  166. package/dist/kernel/db/migrations/0070-designs.sql +53 -0
  167. package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
  168. package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
  169. package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
  170. package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
  171. package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
  172. package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
  173. package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
  174. package/dist/kernel/db/tx.js +2 -4
  175. package/dist/kernel/errors.js +27 -1
  176. package/dist/kernel/json-answer.js +15 -0
  177. package/dist/kernel/lock.js +4 -9
  178. package/dist/kernel/paths.js +8 -0
  179. package/dist/kernel/ports/assistant-cli.js +4 -0
  180. package/dist/kernel/ports/host-cli.js +3 -0
  181. package/dist/kernel/ports/interest.js +4 -0
  182. package/dist/kernel/ports/languages.js +0 -3
  183. package/dist/kernel/ports/model.js +2 -0
  184. package/dist/kernel/runner/attempt.js +3 -1
  185. package/dist/kernel/runner/audition.js +3 -1
  186. package/dist/kernel/runner/checkpoint-authority.js +2 -1
  187. package/dist/kernel/runner/index.js +8 -10
  188. package/dist/kernel/runner/model-access.js +40 -0
  189. package/dist/kernel/runner/model-check.js +153 -0
  190. package/dist/kernel/runner/providers.js +15 -10
  191. package/dist/kernel/runner/standalone.js +9 -5
  192. package/dist/main.js +334 -19
  193. package/dist/model-checks.js +166 -0
  194. package/dist/patch-notes/3.25.9.md +5 -0
  195. package/dist/patch-notes/4.0.0.md +51 -0
  196. package/dist/patch-notes/index.json +12 -0
  197. package/dist/slices/admission/heads.js +2 -1
  198. package/dist/slices/admission/repo.js +2 -1
  199. package/dist/slices/admission/rules.js +43 -8
  200. package/dist/slices/admission/schema.js +8 -0
  201. package/dist/slices/admission/stage-writes.js +0 -3
  202. package/dist/slices/admission/start.js +48 -31
  203. package/dist/slices/admission/substitute.js +7 -4
  204. package/dist/slices/agents/attention-posts.js +31 -0
  205. package/dist/slices/agents/attention-templates.js +33 -0
  206. package/dist/slices/agents/attention.js +10 -1
  207. package/dist/slices/agents/connection.js +2 -6
  208. package/dist/slices/agents/model.js +6 -3
  209. package/dist/slices/agents/repo.js +15 -7
  210. package/dist/slices/article/continuation.js +0 -63
  211. package/dist/slices/article/plain.js +3 -2
  212. package/dist/slices/article/segments.js +2 -62
  213. package/dist/slices/assistant/access.js +1 -0
  214. package/dist/slices/assistant/asks.js +80 -0
  215. package/dist/slices/assistant/cost.js +54 -0
  216. package/dist/slices/assistant/gate.js +222 -0
  217. package/dist/slices/assistant/model.js +79 -0
  218. package/dist/slices/assistant/names.js +23 -0
  219. package/dist/slices/assistant/prompt.js +74 -0
  220. package/dist/slices/assistant/repo.js +74 -0
  221. package/dist/slices/assistant/tokens.js +18 -0
  222. package/dist/slices/assistant/turn.js +342 -0
  223. package/dist/slices/autopilot/buffer.js +76 -0
  224. package/dist/slices/autopilot/model.js +14 -0
  225. package/dist/slices/autopilot/notify.js +27 -0
  226. package/dist/slices/autopilot/repo.js +34 -0
  227. package/dist/slices/autopilot/signals.js +194 -0
  228. package/dist/slices/autopilot/warnings.js +85 -0
  229. package/dist/slices/autopilot/weekly.js +100 -0
  230. package/dist/slices/backups/files.js +2 -6
  231. package/dist/slices/backups/repo.js +3 -15
  232. package/dist/slices/backups/service.js +4 -3
  233. package/dist/slices/channels/cast-images.js +2 -1
  234. package/dist/slices/channels/model.js +0 -1
  235. package/dist/slices/channels/rebrand.js +0 -3
  236. package/dist/slices/channels/repo.js +4 -0
  237. package/dist/slices/channels/schema.js +6 -0
  238. package/dist/slices/channels/service.js +10 -0
  239. package/dist/slices/channels/videos.js +2 -14
  240. package/dist/slices/checkpoints/index.js +0 -1
  241. package/dist/slices/control/providers.js +0 -26
  242. package/dist/slices/designs/artwork.js +66 -0
  243. package/dist/slices/designs/budget.js +23 -0
  244. package/dist/slices/designs/calls.js +124 -0
  245. package/dist/slices/designs/check-context.js +38 -0
  246. package/dist/slices/designs/check-text.js +43 -0
  247. package/dist/slices/designs/fields.js +88 -0
  248. package/dist/slices/designs/frames.js +34 -0
  249. package/dist/slices/designs/gate.js +128 -0
  250. package/dist/slices/designs/layout.js +293 -0
  251. package/dist/slices/designs/model.js +35 -0
  252. package/dist/slices/designs/pdf-job.js +23 -0
  253. package/dist/slices/designs/pdf-pages.js +30 -0
  254. package/dist/slices/designs/pdf-runner.js +68 -0
  255. package/dist/slices/designs/pdf-worker.js +24 -0
  256. package/dist/slices/designs/picture-size.js +79 -0
  257. package/dist/slices/designs/pictures.js +55 -0
  258. package/dist/slices/designs/quote.js +24 -0
  259. package/dist/slices/designs/render-args.js +36 -0
  260. package/dist/slices/designs/render-input.js +59 -0
  261. package/dist/slices/designs/render.js +215 -0
  262. package/dist/slices/designs/repo.js +101 -0
  263. package/dist/slices/designs/requests.js +80 -0
  264. package/dist/slices/designs/runner.js +239 -0
  265. package/dist/slices/designs/sample-repo.js +91 -0
  266. package/dist/slices/designs/sample.js +222 -0
  267. package/dist/slices/designs/schema.js +87 -0
  268. package/dist/slices/designs/sections.js +44 -0
  269. package/dist/slices/designs/service.js +233 -0
  270. package/dist/slices/designs/steps-repo.js +102 -0
  271. package/dist/slices/designs/studio-kind.js +39 -0
  272. package/dist/slices/designs/template-checks.js +44 -0
  273. package/dist/slices/designs/template-make.js +118 -0
  274. package/dist/slices/designs/templates.js +218 -0
  275. package/dist/slices/document/fonts.js +2 -1
  276. package/dist/slices/episodes/summarize.js +5 -1
  277. package/dist/slices/estimate/index.js +45 -7
  278. package/dist/slices/fonts/catalog.js +3 -2
  279. package/dist/slices/fonts/discovery.js +3 -2
  280. package/dist/slices/fonts/files.js +2 -6
  281. package/dist/slices/fonts/index.js +0 -1
  282. package/dist/slices/fonts/sfnt.js +45 -10
  283. package/dist/slices/images/appearance.js +6 -15
  284. package/dist/slices/images/scenes.js +100 -27
  285. package/dist/slices/keywords/digest.js +84 -0
  286. package/dist/slices/keywords/facts.js +92 -0
  287. package/dist/slices/keywords/fill.js +80 -0
  288. package/dist/slices/keywords/model.js +75 -0
  289. package/dist/slices/keywords/rules.js +187 -0
  290. package/dist/slices/keywords/schema.js +28 -0
  291. package/dist/slices/keywords/specs.js +260 -0
  292. package/dist/slices/keywords/values.js +74 -0
  293. package/dist/slices/library/lint.js +29 -12
  294. package/dist/slices/library/model.js +2 -0
  295. package/dist/slices/library/photorealistic.js +4 -12
  296. package/dist/slices/library/rename.js +9 -7
  297. package/dist/slices/library/save.js +14 -10
  298. package/dist/slices/library/slots.js +37 -11
  299. package/dist/slices/library/transfer.js +2 -1
  300. package/dist/slices/library/used-by.js +25 -10
  301. package/dist/slices/loudness/loudnorm.js +51 -11
  302. package/dist/slices/model-checks/cost.js +61 -0
  303. package/dist/slices/model-checks/listing.js +124 -0
  304. package/dist/slices/model-checks/model.js +20 -0
  305. package/dist/slices/model-checks/record.js +32 -0
  306. package/dist/slices/model-checks/repo.js +120 -0
  307. package/dist/slices/model-checks/rules.js +112 -0
  308. package/dist/slices/model-checks/run.js +143 -0
  309. package/dist/slices/model-checks/service.js +198 -0
  310. package/dist/slices/model-upkeep/switch.js +70 -25
  311. package/dist/slices/model-upkeep/usage.js +26 -11
  312. package/dist/slices/narration/breaths.js +2 -1
  313. package/dist/slices/narration/clean-pieces.js +2 -1
  314. package/dist/slices/narration/concat.js +2 -1
  315. package/dist/slices/narration/peaks.js +3 -4
  316. package/dist/slices/narration/pronunciation-chunks.js +4 -3
  317. package/dist/slices/narration/pronunciation.js +3 -2
  318. package/dist/slices/narration/steering.js +4 -3
  319. package/dist/slices/notifications/notifier.js +4 -3
  320. package/dist/slices/notifications/rules.js +5 -2
  321. package/dist/slices/notifications/settings.js +4 -12
  322. package/dist/slices/notifications/subject.js +2 -1
  323. package/dist/slices/onboarding/copy.js +2 -1
  324. package/dist/slices/onboarding/first-run.js +3 -2
  325. package/dist/slices/onboarding/full-video.js +3 -2
  326. package/dist/slices/onboarding/install.js +4 -3
  327. package/dist/slices/onboarding/model.js +0 -16
  328. package/dist/slices/onboarding/packs.js +22 -22
  329. package/dist/slices/onboarding/quick-short.js +2 -1
  330. package/dist/slices/onboarding/sample.js +0 -1
  331. package/dist/slices/onboarding/state.js +2 -11
  332. package/dist/slices/onboarding/template.js +2 -1
  333. package/dist/slices/patch-notes/library.js +3 -2
  334. package/dist/slices/play-drafts/convert.js +4 -0
  335. package/dist/slices/play-drafts/review-inputs.js +8 -2
  336. package/dist/slices/play-drafts/review.js +5 -4
  337. package/dist/slices/play-drafts/schema.js +4 -0
  338. package/dist/slices/project-templates/from-project.js +9 -2
  339. package/dist/slices/project-templates/repo.js +6 -1
  340. package/dist/slices/project-templates/setup.js +8 -0
  341. package/dist/slices/project-templates/stand-ins.js +22 -0
  342. package/dist/slices/rebuild/activity.js +2 -0
  343. package/dist/slices/rebuild/admission-repo.js +3 -2
  344. package/dist/slices/rebuild/narration-history.js +4 -5
  345. package/dist/slices/rebuild/narration-retry.js +2 -1
  346. package/dist/slices/rebuild/preview-details.js +27 -9
  347. package/dist/slices/rebuild/preview-plan.js +3 -8
  348. package/dist/slices/rebuild/recipe-build.js +8 -3
  349. package/dist/slices/rebuild/recipe-describe.js +3 -3
  350. package/dist/slices/rebuild/recipe-digest.js +58 -0
  351. package/dist/slices/rebuild/recipe-input-schema.js +10 -0
  352. package/dist/slices/rebuild/recipe-keywords.js +71 -0
  353. package/dist/slices/rebuild/recipe-legacy.js +5 -1
  354. package/dist/slices/rebuild/recipe-model.js +4 -0
  355. package/dist/slices/rebuild/recipe-narration-text.js +2 -1
  356. package/dist/slices/rebuild/recipe-preparation.js +3 -3
  357. package/dist/slices/rebuild/recipe-reference.js +8 -4
  358. package/dist/slices/rebuild/recipe-reviews.js +27 -7
  359. package/dist/slices/rebuild/recipe-save.js +6 -3
  360. package/dist/slices/rebuild/recipe-scenes.js +40 -11
  361. package/dist/slices/rebuild/recipe-shorts.js +8 -8
  362. package/dist/slices/rebuild/recipe-social.js +46 -0
  363. package/dist/slices/rebuild/recipe-text.js +64 -20
  364. package/dist/slices/rebuild/recipe-validation.js +98 -28
  365. package/dist/slices/rebuild/recipe-visual.js +55 -16
  366. package/dist/slices/rebuild/recipe-work.js +15 -3
  367. package/dist/slices/rebuild/recipe-youtube.js +4 -3
  368. package/dist/slices/rebuild/recovery-selection.js +3 -1
  369. package/dist/slices/rebuild/recovery.js +3 -2
  370. package/dist/slices/rebuild/repo.js +4 -3
  371. package/dist/slices/rebuild/review-promise.js +25 -0
  372. package/dist/slices/rebuild/review-redo.js +2 -1
  373. package/dist/slices/rebuild/runtime-admission.js +4 -3
  374. package/dist/slices/rebuild/runtime-agent-review.js +11 -5
  375. package/dist/slices/rebuild/runtime-animate.js +9 -8
  376. package/dist/slices/rebuild/runtime-article.js +3 -2
  377. package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
  378. package/dist/slices/rebuild/runtime-document.js +8 -11
  379. package/dist/slices/rebuild/runtime-export-bed.js +6 -11
  380. package/dist/slices/rebuild/runtime-export-edit.js +6 -15
  381. package/dist/slices/rebuild/runtime-export-inputs.js +7 -7
  382. package/dist/slices/rebuild/runtime-export-short.js +8 -4
  383. package/dist/slices/rebuild/runtime-export.js +34 -12
  384. package/dist/slices/rebuild/runtime-figure-card.js +2 -1
  385. package/dist/slices/rebuild/runtime-image.js +4 -9
  386. package/dist/slices/rebuild/runtime-instructions.js +2 -0
  387. package/dist/slices/rebuild/runtime-keywords.js +59 -0
  388. package/dist/slices/rebuild/runtime-lines.js +2 -11
  389. package/dist/slices/rebuild/runtime-local.js +14 -20
  390. package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
  391. package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
  392. package/dist/slices/rebuild/runtime-narration-text.js +10 -15
  393. package/dist/slices/rebuild/runtime-pictures.js +2 -4
  394. package/dist/slices/rebuild/runtime-piece-label.js +10 -6
  395. package/dist/slices/rebuild/runtime-plan.js +31 -5
  396. package/dist/slices/rebuild/runtime-provider.js +60 -19
  397. package/dist/slices/rebuild/runtime-publication.js +10 -9
  398. package/dist/slices/rebuild/runtime-review.js +33 -28
  399. package/dist/slices/rebuild/runtime-run.js +4 -1
  400. package/dist/slices/rebuild/runtime-shorts.js +34 -50
  401. package/dist/slices/rebuild/runtime-store.js +3 -8
  402. package/dist/slices/rebuild/runtime-subtitles.js +16 -14
  403. package/dist/slices/rebuild/runtime-voices.js +8 -15
  404. package/dist/slices/rebuild/runtime-youtube.js +11 -29
  405. package/dist/slices/rebuild/transition-repo.js +6 -5
  406. package/dist/slices/rebuild/work-records.js +6 -0
  407. package/dist/slices/reruns/cascade.js +1 -2
  408. package/dist/slices/reruns/index.js +6 -9
  409. package/dist/slices/reviews/external-model.js +3 -0
  410. package/dist/slices/reviews/external-repo.js +2 -1
  411. package/dist/slices/reviews/external-rows.js +2 -3
  412. package/dist/slices/reviews/model.js +26 -8
  413. package/dist/slices/reviews/repo.js +2 -1
  414. package/dist/slices/reviews/rules.js +1 -0
  415. package/dist/slices/reviews/view.js +5 -2
  416. package/dist/slices/revisions/downloads.js +4 -5
  417. package/dist/slices/revisions/mutation-assets.js +7 -4
  418. package/dist/slices/revisions/mutation-cues.js +2 -5
  419. package/dist/slices/revisions/mutations.js +0 -1
  420. package/dist/slices/revisions/repo.js +3 -1
  421. package/dist/slices/revisions/schema.js +1 -0
  422. package/dist/slices/revisions/view.js +20 -0
  423. package/dist/slices/run-cost/limits.js +5 -2
  424. package/dist/slices/run-cost/meter.js +12 -5
  425. package/dist/slices/run-cost/panel.js +8 -74
  426. package/dist/slices/run-cost/plan-readings.js +127 -0
  427. package/dist/slices/run-cost/plan-use.js +169 -0
  428. package/dist/slices/run-cost/pricing.js +3 -3
  429. package/dist/slices/run-cost/week.js +32 -4
  430. package/dist/slices/schedules/agenda.js +11 -2
  431. package/dist/slices/schedules/by-date.js +42 -0
  432. package/dist/slices/schedules/calendar.js +5 -0
  433. package/dist/slices/schedules/design-agenda.js +36 -0
  434. package/dist/slices/schedules/design-check.js +41 -0
  435. package/dist/slices/schedules/design-run.js +126 -0
  436. package/dist/slices/schedules/next-run.js +62 -0
  437. package/dist/slices/schedules/prepare.js +18 -2
  438. package/dist/slices/schedules/repo.js +24 -16
  439. package/dist/slices/schedules/rescore.js +35 -0
  440. package/dist/slices/schedules/scheduler.js +13 -3
  441. package/dist/slices/schedules/schema.js +54 -3
  442. package/dist/slices/schedules/score.js +107 -0
  443. package/dist/slices/schedules/service.js +57 -24
  444. package/dist/slices/schedules/topic-list.js +15 -0
  445. package/dist/slices/schedules/topic-scores.js +104 -0
  446. package/dist/slices/schedules/topics.js +48 -36
  447. package/dist/slices/settings/cli-paths.js +4 -6
  448. package/dist/slices/settings/first-run.js +2 -11
  449. package/dist/slices/settings/model-reach.js +3 -17
  450. package/dist/slices/settings/model.js +10 -0
  451. package/dist/slices/settings/playback.js +33 -22
  452. package/dist/slices/settings/probe-read.js +16 -0
  453. package/dist/slices/settings/repo.js +33 -0
  454. package/dist/slices/settings/tutorial.js +2 -2
  455. package/dist/slices/settings/voices.js +4 -12
  456. package/dist/slices/shorts/pick.js +2 -15
  457. package/dist/slices/shorts/prompts.js +2 -13
  458. package/dist/slices/shorts/render.js +3 -0
  459. package/dist/slices/social/channel.js +44 -0
  460. package/dist/slices/social/defaults.js +17 -0
  461. package/dist/slices/social/due.js +36 -0
  462. package/dist/slices/social/extension.js +18 -0
  463. package/dist/slices/social/fit.js +115 -0
  464. package/dist/slices/social/limits.js +186 -0
  465. package/dist/slices/social/links.js +21 -0
  466. package/dist/slices/social/media.js +131 -0
  467. package/dist/slices/social/model.js +75 -0
  468. package/dist/slices/social/notice.js +19 -0
  469. package/dist/slices/social/pack.js +176 -0
  470. package/dist/slices/social/post-prompt.js +55 -0
  471. package/dist/slices/social/queue.js +31 -0
  472. package/dist/slices/social/repo.js +133 -0
  473. package/dist/slices/social/reshape.js +97 -0
  474. package/dist/slices/social/rules.js +5 -0
  475. package/dist/slices/social/schema.js +70 -0
  476. package/dist/slices/social/serve.js +51 -0
  477. package/dist/slices/social/service.js +128 -0
  478. package/dist/slices/social/settings.js +21 -0
  479. package/dist/slices/social/sources.js +114 -0
  480. package/dist/slices/social/state.js +110 -0
  481. package/dist/slices/social/text.js +149 -0
  482. package/dist/slices/storage/arrange.js +3 -1
  483. package/dist/slices/storage/assets.js +8 -10
  484. package/dist/slices/storage/backup-designs.js +74 -0
  485. package/dist/slices/storage/backup-export.js +8 -3
  486. package/dist/slices/storage/backup-format.js +10 -0
  487. package/dist/slices/storage/backup-import.js +20 -2
  488. package/dist/slices/storage/delete-project.js +6 -5
  489. package/dist/slices/storage/files-location.js +6 -8
  490. package/dist/slices/storage/layout.js +13 -2
  491. package/dist/slices/storage/model.js +3 -0
  492. package/dist/slices/storage/portable.js +16 -11
  493. package/dist/slices/storage/schema.js +2 -0
  494. package/dist/slices/storage/staging-refs.js +2 -1
  495. package/dist/slices/storage/staging.js +6 -9
  496. package/dist/slices/storage/trim.js +10 -3
  497. package/dist/slices/studio/calendar.js +4 -1
  498. package/dist/slices/studio/pick.js +2 -11
  499. package/dist/slices/studio/plan.js +6 -15
  500. package/dist/slices/studio/queue.js +3 -14
  501. package/dist/slices/studio/releases.js +26 -0
  502. package/dist/slices/studio/settings.js +14 -51
  503. package/dist/slices/studio/videos.js +12 -0
  504. package/dist/slices/style-preview/render.js +34 -13
  505. package/dist/slices/style-preview/schema.js +13 -0
  506. package/dist/slices/style-preview/service.js +2 -1
  507. package/dist/slices/style-preview/settings.js +33 -5
  508. package/dist/slices/telemetry/collector-client.js +2 -4
  509. package/dist/slices/telemetry/flush.js +2 -4
  510. package/dist/slices/telemetry/model.js +0 -7
  511. package/dist/slices/telemetry/record.js +10 -3
  512. package/dist/slices/template-studio/anatomy-view.js +118 -0
  513. package/dist/slices/template-studio/anatomy.js +73 -0
  514. package/dist/slices/template-studio/bakeoff-make.js +225 -0
  515. package/dist/slices/template-studio/bakeoff-repo.js +83 -0
  516. package/dist/slices/template-studio/bakeoff.js +333 -0
  517. package/dist/slices/template-studio/budget.js +103 -0
  518. package/dist/slices/template-studio/checks.js +273 -0
  519. package/dist/slices/template-studio/document-sample.js +56 -0
  520. package/dist/slices/template-studio/edit.js +15 -0
  521. package/dist/slices/template-studio/for-all.js +161 -0
  522. package/dist/slices/template-studio/free-video.js +31 -0
  523. package/dist/slices/template-studio/free.js +176 -0
  524. package/dist/slices/template-studio/gate.js +40 -0
  525. package/dist/slices/template-studio/hidden.js +20 -0
  526. package/dist/slices/template-studio/jobs.js +79 -0
  527. package/dist/slices/template-studio/loudness.js +111 -0
  528. package/dist/slices/template-studio/make.js +40 -0
  529. package/dist/slices/template-studio/model.js +54 -0
  530. package/dist/slices/template-studio/pack-import.js +253 -0
  531. package/dist/slices/template-studio/pack-samples.js +60 -0
  532. package/dist/slices/template-studio/pack.js +205 -0
  533. package/dist/slices/template-studio/paid-view.js +66 -0
  534. package/dist/slices/template-studio/paid.js +348 -0
  535. package/dist/slices/template-studio/quote.js +148 -0
  536. package/dist/slices/template-studio/ready.js +104 -0
  537. package/dist/slices/template-studio/repo.js +134 -0
  538. package/dist/slices/template-studio/reviews-path.js +58 -0
  539. package/dist/slices/template-studio/runner.js +84 -0
  540. package/dist/slices/template-studio/save.js +236 -0
  541. package/dist/slices/template-studio/say-it-as.js +248 -0
  542. package/dist/slices/template-studio/schedule-gate.js +34 -0
  543. package/dist/slices/template-studio/schedule-price.js +30 -0
  544. package/dist/slices/template-studio/schedule-sample.js +87 -0
  545. package/dist/slices/template-studio/schema.js +218 -0
  546. package/dist/slices/template-studio/scope.js +124 -0
  547. package/dist/slices/template-studio/sections.js +176 -0
  548. package/dist/slices/template-studio/service.js +173 -0
  549. package/dist/slices/template-studio/status.js +174 -0
  550. package/dist/slices/template-studio/topic.js +223 -0
  551. package/dist/slices/trash/designs.js +76 -0
  552. package/dist/slices/trash/model.js +13 -4
  553. package/dist/slices/trash/service.js +52 -2
  554. package/dist/slices/tutorials/library.js +3 -2
  555. package/dist/slices/video/ass-text.js +17 -0
  556. package/dist/slices/video/audio-export.js +2 -64
  557. package/dist/slices/video/encoding.js +160 -0
  558. package/dist/slices/video/ffmpeg.js +23 -21
  559. package/dist/slices/video/figure-card.js +1 -15
  560. package/dist/slices/video/slideshow.js +43 -18
  561. package/dist/slices/voices/palette.js +0 -3
  562. package/dist/slices/youtube/answer.js +2 -15
  563. package/dist/slices/youtube/edits-repo.js +2 -11
  564. package/dist/tutorials/Agents-MCP.md +2 -1
  565. package/dist/tutorials/Assistant.md +42 -0
  566. package/dist/tutorials/Channels.md +2 -0
  567. package/dist/tutorials/Home-and-Projects.md +19 -0
  568. package/dist/tutorials/Install.md +1 -0
  569. package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
  570. package/dist/tutorials/Models.md +33 -1
  571. package/dist/tutorials/Notifications.md +6 -0
  572. package/dist/tutorials/Play-Images.md +4 -0
  573. package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
  574. package/dist/tutorials/Prompts.md +10 -6
  575. package/dist/tutorials/Remote-Access.md +63 -0
  576. package/dist/tutorials/Reviews-and-Checkpoints.md +13 -2
  577. package/dist/tutorials/Schedules.md +21 -1
  578. package/dist/tutorials/Settings-Reference.md +50 -8
  579. package/dist/tutorials/Template-Studio.md +125 -0
  580. package/dist/tutorials/Templates.md +3 -0
  581. package/dist/tutorials/_Sidebar.md +5 -0
  582. package/dist/updater/work-in-progress.js +42 -12
  583. package/dist/web/assets/index-CkAI_2E7.css +1 -0
  584. package/dist/web/assets/index-DcD0cdfo.js +334 -0
  585. package/dist/web/assets/{pdf-T7MCwjIv.js → pdf-TODRwF31.js} +1 -1
  586. package/dist/web/index.html +2 -2
  587. package/package.json +5 -1
  588. package/dist/slices/article/provided-entries.js +0 -66
  589. package/dist/slices/article/run.js +0 -145
  590. package/dist/slices/images/run.js +0 -234
  591. package/dist/slices/narration/legacy-plan.js +0 -58
  592. package/dist/slices/narration/run.js +0 -270
  593. package/dist/slices/rebuild/runtime-actions.js +0 -90
  594. package/dist/slices/research/run.js +0 -224
  595. package/dist/slices/subtitles/prepare.js +0 -194
  596. package/dist/slices/subtitles/transcript.js +0 -34
  597. package/dist/slices/thumbnail/run.js +0 -219
  598. package/dist/slices/video/audio-inputs.js +0 -33
  599. package/dist/slices/video/reuse-audio.js +0 -62
  600. package/dist/slices/video/run.js +0 -78
  601. package/dist/slices/video/write-export.js +0 -158
  602. package/dist/slices/video/write-subtitles.js +0 -59
  603. package/dist/web/assets/index-BadsoORk.css +0 -1
  604. package/dist/web/assets/index-D8LqNsCl.js +0 -326
@@ -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, missingKey, noAudio, refreshList, unreadable, voiceFix } from "../explain.js";
5
- import { retryAfter } from "../retry-after.js";
4
+ import { httpFailure, noAudio, refreshList, unreadable, 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 { elevenLabsLanguages, lookUp } from "./voice-languages.js";
7
8
  // The HTTP gateway adapter for ElevenLabs: the platform's own `fetch` and nothing else. The
8
9
  // response body already is the `ReadableStream<Uint8Array>` the port asks for, so an SDK
@@ -99,52 +100,27 @@ export function elevenLabsTts(deps) {
99
100
  };
100
101
  }
101
102
  function keyOf(deps) {
102
- const key = deps.key();
103
- // `missing_key`, not `auth`, because that rule makes it terminal.
104
- if (key === undefined || key === "") {
105
- throw providerError({ kind: "missing_key", message: missingKey("ElevenLabs") });
106
- }
107
- return key;
108
- }
109
- // Only the adapter sees the vendor's status code, so only the adapter names the kind.
110
- function kindOf(status) {
111
- if (status === 401 || status === 403) {
112
- return "auth";
113
- }
114
- if (status === 429) {
115
- return "rate_limit";
116
- }
117
- // ceiling: everything else is `other` and is retried, so a text past the character limit
118
- // fails the same way four times over. A terminal "this will never work" kind has to reach the
119
- // port's error contract first, which is not this adapter's to widen.
120
- // The provider's own server failed; the same request may well succeed later.
121
- if (status >= 500)
122
- return "dropped";
123
- return "other";
103
+ return requireKey(deps.key(), "ElevenLabs");
124
104
  }
125
105
  async function failure(response, voiceId, next) {
126
- const text = await response.text().catch(() => "");
106
+ const text = await failureText(response);
127
107
  // The provider's own words, through the redactor - an error body may quote the key back.
128
108
  const message = redact(detailOf(text) || response.statusText);
129
- const retryAfterMs = retryAfter(response.headers.get("retry-after"));
130
- return providerError({
131
- kind: kindOf(response.status),
132
- // A rejected voice ID has to be named, and it is the one part of the
133
- // request the user chose. It is not secret, unlike everything else on the wire.
134
- message: httpFailure({
135
- provider: "ElevenLabs",
136
- status: response.status,
137
- detail: message,
138
- next,
139
- ...(voiceId === undefined
140
- ? {}
141
- : {
142
- subject: `narration request for voice "${voiceId}"`,
143
- fix: voiceFix(voiceId),
144
- }),
145
- }),
146
- ...(retryAfterMs === undefined ? {} : { retryAfterMs }),
147
- });
109
+ return httpProviderError(response, kindOfStatus(response.status),
110
+ // A rejected voice ID has to be named, and it is the one part of the
111
+ // request the user chose. It is not secret, unlike everything else on the wire.
112
+ httpFailure({
113
+ provider: "ElevenLabs",
114
+ status: response.status,
115
+ detail: message,
116
+ next,
117
+ ...(voiceId === undefined
118
+ ? {}
119
+ : {
120
+ subject: `narration request for voice "${voiceId}"`,
121
+ fix: voiceFix(voiceId),
122
+ }),
123
+ }), undefined, modelAccessOf(response.status, text));
148
124
  }
149
125
  function detailOf(text) {
150
126
  const parsed = errorBody.safeParse(safeJson(text));
@@ -159,11 +135,3 @@ function detailOf(text) {
159
135
  // (`max_character_limit_exceeded`, `voice_not_found`) and the message is the sentence.
160
136
  return [detail.status, detail.message].filter((part) => part !== undefined).join(": ");
161
137
  }
162
- function safeJson(text) {
163
- try {
164
- return JSON.parse(text);
165
- }
166
- catch {
167
- return undefined;
168
- }
169
- }
@@ -1,8 +1,10 @@
1
1
  import { z } from "zod";
2
+ import { internalError } from "../../kernel/errors.js";
2
3
  import { redact } from "../../kernel/log.js";
3
4
  import { providerError } from "../../kernel/ports/model.js";
4
- import { httpFailure, internalError, missingKey, noAudio, providerSaid, refreshList, unreadable, voiceFix, } from "../explain.js";
5
- import { retryAfter } from "../retry-after.js";
5
+ import { httpFailure, noAudio, providerSaid, refreshList, unreadable, voiceFix, } from "../explain.js";
6
+ import { failureText, httpProviderError, kindOfStatus, requireKey, safeJson, } from "../http-failure.js";
7
+ import { modelAccessOf } from "../model-access.js";
6
8
  // The HTTP gateway adapter for Gemini's speech generation (generateContent with an AUDIO
7
9
  // response, https://ai.google.dev/gemini-api/docs/speech-generation), billed to a Gemini API
8
10
  // key. One voice is `speechConfig.voiceConfig`; a conversation of exactly two voices is
@@ -156,24 +158,10 @@ function streamOf(bytes) {
156
158
  });
157
159
  }
158
160
  function keyOf(deps) {
159
- // `missing_key`, not `auth`, because that rule makes it terminal.
160
- const key = deps.key();
161
- if (key === undefined || key === "") {
162
- throw providerError({ kind: "missing_key", message: missingKey("Google") });
163
- }
164
- return key;
165
- }
166
- function kindOf(status) {
167
- if (status === 401 || status === 403)
168
- return "auth";
169
- if (status === 429)
170
- return "rate_limit";
171
- if (status >= 500)
172
- return "dropped";
173
- return "other";
161
+ return requireKey(deps.key(), "Google");
174
162
  }
175
163
  async function failure(response, voiceId, next) {
176
- const text = await response.text().catch(() => "");
164
+ const text = await failureText(response);
177
165
  const parsed = errorBody.safeParse(safeJson(text));
178
166
  // Through the redactor: an error body may quote the key back.
179
167
  const detail = redact((parsed.success ? parsed.data.error.message : undefined) ??
@@ -181,26 +169,17 @@ async function failure(response, voiceId, next) {
181
169
  // Google answers an unknown key with 400 API_KEY_INVALID rather than 401.
182
170
  const badKey = response.status === 400 && text.includes("API_KEY_INVALID");
183
171
  const status = badKey ? 401 : response.status;
184
- const retryAfterMs = retryAfter(response.headers.get("retry-after"));
185
- return providerError({
186
- kind: badKey ? "auth" : kindOf(response.status),
187
- message: httpFailure({
188
- provider: "Google",
189
- status,
190
- detail,
191
- next,
192
- ...(voiceId === undefined
193
- ? {}
194
- : { subject: `narration request for voice "${voiceId}"`, fix: voiceFix(voiceId) }),
195
- }),
196
- ...(retryAfterMs === undefined ? {} : { retryAfterMs }),
197
- });
198
- }
199
- function safeJson(text) {
200
- try {
201
- return JSON.parse(text);
202
- }
203
- catch {
204
- return undefined;
205
- }
172
+ return httpProviderError(response, badKey ? "auth" : kindOfStatus(response.status), httpFailure({
173
+ provider: "Google",
174
+ status,
175
+ detail,
176
+ next,
177
+ ...(voiceId === undefined
178
+ ? {}
179
+ : { subject: `narration request for voice "${voiceId}"`, fix: voiceFix(voiceId) }),
180
+ }), undefined,
181
+ // A narration request goes to the model's own address (models/<id>:generateContent).
182
+ badKey || voiceId === undefined
183
+ ? undefined
184
+ : modelAccessOf(response.status, `${parsed.success ? (parsed.data.error.status ?? "") : ""} ${detail}`, true));
206
185
  }
@@ -1,7 +1,9 @@
1
1
  import { z } from "zod";
2
+ import { internalError } from "../../kernel/errors.js";
2
3
  import { redact } from "../../kernel/log.js";
3
4
  import { providerError } from "../../kernel/ports/model.js";
4
- import { httpFailure, internalError, noAudio, providerSaid, unreadable, voiceFix, } from "../explain.js";
5
+ import { httpFailure, noAudio, providerSaid, unreadable, voiceFix } from "../explain.js";
6
+ import { accessField } from "../model-access.js";
5
7
  import { retryAfter } from "../retry-after.js";
6
8
  const operationName = /^workspaces\/[A-Za-z0-9_-]+\/ttsAsyncJobs\/[A-Za-z0-9_-]+\/operations\/[A-Za-z0-9_-]+$/;
7
9
  const operationSchema = z.object({
@@ -137,6 +139,7 @@ async function check(response, key, voiceId) {
137
139
  const detail = clean(await response.text().catch(() => ""), key);
138
140
  const retryAfterMs = retryAfter(response.headers.get("retry-after"));
139
141
  throw providerError({
142
+ ...accessField(response.status, detail),
140
143
  kind: response.status === 401 || response.status === 403
141
144
  ? "auth"
142
145
  : response.status === 429
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { redact } from "../../kernel/log.js";
3
3
  import { providerError } from "../../kernel/ports/model.js";
4
4
  import { httpFailure, missingKey, noAudio, unreadable, voiceFix } from "../explain.js";
5
+ import { accessField } from "../model-access.js";
5
6
  import { retryAfter } from "../retry-after.js";
6
7
  import { inworldAsync, streamFailure } from "./inworld-async.js";
7
8
  import { inworldLanguages, lookUp } from "./voice-languages.js";
@@ -97,6 +98,7 @@ async function* synthesizeRequest(deps, request, key) {
97
98
  const detail = clean(await response.text().catch(() => ""), key);
98
99
  const retryAfterMs = retryAfter(response.headers.get("retry-after"));
99
100
  throw providerError({
101
+ ...accessField(response.status, detail),
100
102
  kind: response.status === 401 || response.status === 403
101
103
  ? "auth"
102
104
  : response.status === 429
@@ -134,6 +136,7 @@ async function* synthesizeRequest(deps, request, key) {
134
136
  if (parsed.data.error) {
135
137
  const { code, message } = parsed.data.error;
136
138
  throw providerError({
139
+ ...accessField(code === 5 ? 404 : code === 7 ? 403 : null, message ?? ""),
137
140
  kind: code === 16 || code === 7
138
141
  ? "auth"
139
142
  : code === 8
@@ -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, missingKey, noAudio, refreshList, unreadable, voiceFix } from "../explain.js";
5
- import { retryAfter } from "../retry-after.js";
4
+ import { httpFailure, noAudio, refreshList, unreadable, voiceFix } from "../explain.js";
5
+ import { failureText, httpProviderError, kindOfStatus, requireKey, safeJson, } from "../http-failure.js";
6
+ import { modelAccessOf } from "../model-access.js";
6
7
  // The HTTP gateway adapter for OpenAI's speech endpoint. `fetch` and nothing else; the response
7
8
  // body is already the stream the port asks for.
8
9
  export const openAiAudioBase = "https://api.openai.com/v1";
@@ -79,58 +80,27 @@ function voiceOf(voiceId) {
79
80
  return customVoice.test(voiceId) ? { id: voiceId } : voiceId;
80
81
  }
81
82
  function keyOf(deps) {
82
- const key = deps.key();
83
- // An absent key is terminal, so it never becomes a request.
84
- if (key === undefined || key === "") {
85
- throw providerError({ kind: "missing_key", message: missingKey("OpenAI") });
86
- }
87
- return key;
88
- }
89
- function kindOf(status) {
90
- if (status === 401 || status === 403) {
91
- return "auth";
92
- }
93
- if (status === 429) {
94
- return "rate_limit";
95
- }
96
- // ceiling: as in the OpenRouter adapter, a 400 is retried three more times because the
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";
101
- return "other";
83
+ return requireKey(deps.key(), "OpenAI");
102
84
  }
103
85
  async function failure(response, voiceId, next) {
104
- const text = await response.text().catch(() => "");
86
+ const text = await failureText(response);
105
87
  const parsed = errorBody.safeParse(safeJson(text));
106
88
  // Verbatim, through the same redactor the wrapper uses: OpenAI's own 401 quotes the
107
89
  // start of the key back at the caller.
108
90
  const message = redact(parsed.success ? parsed.data.error.message : text.trim() || response.statusText);
109
- const retryAfterMs = retryAfter(response.headers.get("retry-after"));
110
- return providerError({
111
- kind: kindOf(response.status),
112
- // The voice ID is named, so a rejected voice reads differently from
113
- // a rejected key.
114
- message: httpFailure({
115
- provider: "OpenAI",
116
- status: response.status,
117
- detail: message,
118
- next,
119
- ...(voiceId === undefined
120
- ? {}
121
- : {
122
- subject: `narration request for voice "${voiceId}"`,
123
- fix: voiceFix(voiceId),
124
- }),
125
- }),
126
- ...(retryAfterMs === undefined ? {} : { retryAfterMs }),
127
- });
128
- }
129
- function safeJson(text) {
130
- try {
131
- return JSON.parse(text);
132
- }
133
- catch {
134
- return undefined;
135
- }
91
+ return httpProviderError(response, kindOfStatus(response.status),
92
+ // The voice ID is named, so a rejected voice reads differently from
93
+ // a rejected key.
94
+ httpFailure({
95
+ provider: "OpenAI",
96
+ status: response.status,
97
+ detail: message,
98
+ next,
99
+ ...(voiceId === undefined
100
+ ? {}
101
+ : {
102
+ subject: `narration request for voice "${voiceId}"`,
103
+ fix: voiceFix(voiceId),
104
+ }),
105
+ }), undefined, modelAccessOf(response.status, text));
136
106
  }
@@ -0,0 +1,6 @@
1
+ # When a model in models.yaml is due to retire, and what replaces it. Kept apart from
2
+ # models.yaml on purpose: older Slopify versions read models.yaml with a strict schema, so a new
3
+ # field there would break them. Each entry names a model by family, provider and id;
4
+ # replacement (optional) is the id of a model of the same provider and family.
5
+ schemaVersion: 1
6
+ models: []
@@ -0,0 +1,60 @@
1
+ import { assistantCliRunner } from "./adapters/llm/assistant-cli.js";
2
+ import { assistantClis, } from "./slices/assistant/model.js";
3
+ import { createTurnTokens } from "./slices/assistant/tokens.js";
4
+ import { createAssistant } from "./slices/assistant/turn.js";
5
+ import { cliPathStatus } from "./slices/settings/cli-paths.js";
6
+ import { cliProbeTimeoutMs, readinessFromProbe, } from "./slices/settings/cli-status.js";
7
+ import { providerById } from "./slices/settings/model.js";
8
+ // The in-app assistant wired to this computer's CLIs: which are installed and signed in (asked
9
+ // at most once a minute, so opening the panel never waits on a probe twice), the CLI runner,
10
+ // and this server's own address for `/mcp/assistant`.
11
+ // ceiling: a CLI's state is kept a minute; signing in or installing one shows on the next
12
+ // message after that.
13
+ const statesTtlMs = 60_000;
14
+ export function wireAssistant(deps) {
15
+ let cached;
16
+ const stateOf = async (cli) => {
17
+ const provider = providerById(cli);
18
+ if (provider.auth !== "cli")
19
+ return { installed: false, login: "unknown" };
20
+ const { command } = cliPathStatus(deps.db, cli);
21
+ const readiness = readinessFromProbe(await deps.probe(command, provider.versionArgs, cliProbeTimeoutMs), provider);
22
+ if (readiness.kind !== "cli" || !readiness.installed)
23
+ return { installed: false, login: "unknown" };
24
+ const login = await deps.readLogin(command, cli, AbortSignal.timeout(cliProbeTimeoutMs));
25
+ return { installed: true, login, issue: readiness.issue };
26
+ };
27
+ const clis = () => {
28
+ const now = deps.clock.now().valueOf();
29
+ if (cached === undefined || now - cached.at > statesTtlMs) {
30
+ const states = Promise.all(assistantClis.map(stateOf)).then(([claude, codex]) => ({
31
+ "claude-code": claude ?? { installed: false, login: "unknown" },
32
+ codex: codex ?? { installed: false, login: "unknown" },
33
+ }));
34
+ cached = { at: now, states };
35
+ states.catch(() => {
36
+ cached = undefined;
37
+ });
38
+ }
39
+ return cached.states;
40
+ };
41
+ return createAssistant({
42
+ db: deps.db,
43
+ ids: deps.ids,
44
+ clock: deps.clock,
45
+ log: deps.log,
46
+ emit: deps.emit,
47
+ runCli: assistantCliRunner(deps.spawn),
48
+ clis,
49
+ binaryOf: (cli) => cliPathStatus(deps.db, cli).command,
50
+ selfUrl: deps.selfUrl,
51
+ container: deps.container,
52
+ tokens: createTurnTokens(),
53
+ });
54
+ }
55
+ // The address the CLIs reach this server at: loopback when it listens on every address.
56
+ export function assistantSelfUrl(host, port) {
57
+ const wildcard = host === "" || host === "0.0.0.0" || host === "::";
58
+ const reach = wildcard ? "127.0.0.1" : host;
59
+ return `http://${reach.includes(":") ? `[${reach}]` : reach}:${String(port)}`;
60
+ }
@@ -0,0 +1,59 @@
1
+ import { diskSpaceAt, openRouterKeyLimit } from "./adapters/account-limits.js";
2
+ import { causedBy } from "./kernel/errors.js";
3
+ import { sendWeeklyReport } from "./slices/autopilot/notify.js";
4
+ import { createAutopilotHealth } from "./slices/autopilot/signals.js";
5
+ import { cliPathStatus } from "./slices/settings/cli-paths.js";
6
+ import { keyOf } from "./slices/settings/repo.js";
7
+ // ceiling: the first check waits for the server to settle after a start, then runs hourly; the
8
+ // weekly report is looked at every quarter hour, so Monday 09:00 is met within 15 minutes.
9
+ const firstCheckMs = 30_000;
10
+ const checkEveryMs = 60 * 60_000;
11
+ const weeklyEveryMs = 15 * 60_000;
12
+ // Home's autopilot block reads the hourly check's answers; nothing here blocks a request.
13
+ export function startAutopilot(deps) {
14
+ const health = createAutopilotHealth({
15
+ db: deps.db,
16
+ clock: deps.clock,
17
+ log: deps.log,
18
+ template: deps.template,
19
+ catalogue: deps.catalogue,
20
+ cliLogin: async (id, signal) => deps.hostCli === undefined
21
+ ? deps.readLogin(cliPathStatus(deps.db, id).command, id, signal)
22
+ : (await deps.hostCli.status(id)).login,
23
+ openRouterKey: async (signal) => {
24
+ const key = keyOf(deps.db, "openrouter");
25
+ return key === undefined ? null : openRouterKeyLimit(deps.fetch, key, signal);
26
+ },
27
+ disk: () => diskSpaceAt(deps.dataDir),
28
+ });
29
+ const check = () => {
30
+ health.refresh().catch((error) => {
31
+ deps.log.write("error", "autopilot.check", { detail: causedBy(error) });
32
+ });
33
+ };
34
+ const weekly = () => {
35
+ sendWeeklyReport({
36
+ db: deps.db,
37
+ clock: deps.clock,
38
+ send: deps.send,
39
+ log: deps.log,
40
+ timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
41
+ }).catch((error) => {
42
+ deps.log.write("error", "autopilot.weekly", { detail: causedBy(error) });
43
+ });
44
+ };
45
+ const first = setTimeout(() => {
46
+ check();
47
+ weekly();
48
+ }, firstCheckMs);
49
+ const checkTimer = setInterval(check, checkEveryMs);
50
+ const weeklyTimer = setInterval(weekly, weeklyEveryMs);
51
+ return {
52
+ latest: health.latest,
53
+ stop: () => {
54
+ clearTimeout(first);
55
+ clearInterval(checkTimer);
56
+ clearInterval(weeklyTimer);
57
+ },
58
+ };
59
+ }
@@ -0,0 +1,52 @@
1
+ import { parse } from "yaml";
2
+ import { z } from "zod";
3
+ import { providerFamilies } from "../kernel/ports/model.js";
4
+ // models-lifecycle.yaml: retirement dates and replacements for models in models.yaml. Rows
5
+ // keep unknown keys out rather than refusing them, so a later version may add fields without
6
+ // breaking this one.
7
+ const lifecycleRow = z.object({
8
+ family: z.enum(providerFamilies),
9
+ provider: z.string().regex(/^[a-z0-9-]+$/),
10
+ id: z.string().min(1).max(200),
11
+ retiresOn: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
12
+ replacement: z.string().min(1).max(200).optional(),
13
+ });
14
+ export const lifecycleSchema = z.object({
15
+ schemaVersion: z.literal(1),
16
+ models: z.array(lifecycleRow).max(500),
17
+ });
18
+ export const emptyLifecycle = { schemaVersion: 1, models: [] };
19
+ export const lifecycleSource = "https://raw.githubusercontent.com/GentBajko/slopify/main/packages/app/src/assets/models-lifecycle.yaml";
20
+ export function parseLifecycle(text) {
21
+ if (Buffer.byteLength(text) > 256 * 1024)
22
+ throw new Error("Model lifecycle exceeds 256 KB");
23
+ return lifecycleSchema.parse(parse(text, { maxAliasCount: 20, uniqueKeys: true }) ?? {});
24
+ }
25
+ function liveRow(catalogue, row, id) {
26
+ return catalogue[row.family].find((model) => model.provider === row.provider && model.id === id && model.enabled && !model.deprecated);
27
+ }
28
+ // A model due to retire, with its replacement when that one is live. A model already retired
29
+ // in the catalogue (deprecated) is past this: the retired-models flow takes over.
30
+ export function retirementOf(lifecycle, catalogue, model) {
31
+ const row = lifecycle.models.find((one) => one.family === model.family && one.provider === model.provider && one.id === model.model);
32
+ if (row === undefined)
33
+ return undefined;
34
+ const current = catalogue[row.family].find((one) => one.provider === row.provider && one.id === row.id);
35
+ if (current?.deprecated === true)
36
+ return undefined;
37
+ const next = row.replacement === undefined ? undefined : liveRow(catalogue, row, row.replacement);
38
+ return {
39
+ on: row.retiresOn,
40
+ replacement: next === undefined ? null : { id: next.id, name: next.name },
41
+ };
42
+ }
43
+ // The lifecycle's named replacement for a model, when it is live in the catalogue.
44
+ export function lifecycleReplacement(lifecycle, catalogue, model) {
45
+ if (lifecycle === undefined)
46
+ return undefined;
47
+ const row = lifecycle.models.find((one) => one.family === model.family && one.provider === model.provider && one.id === model.model);
48
+ if (row?.replacement === undefined)
49
+ return undefined;
50
+ const next = liveRow(catalogue, row, row.replacement);
51
+ return next === undefined ? undefined : { id: next.id, name: next.name };
52
+ }