@gentbajko/slopify 3.25.9 → 4.1.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 (718) hide show
  1. package/dist/adapters/account-limits.js +30 -0
  2. package/dist/adapters/alignment/audio.js +1 -1
  3. package/dist/adapters/alignment/cache.js +4 -6
  4. package/dist/adapters/alignment/ctc.js +1 -2
  5. package/dist/adapters/alignment/lock.js +4 -3
  6. package/dist/adapters/alignment/multilingual.js +2 -4
  7. package/dist/adapters/alignment/prefetch.js +2 -1
  8. package/dist/adapters/alignment/runner.js +1 -1
  9. package/dist/adapters/alignment/worker.js +3 -2
  10. package/dist/adapters/explain.js +10 -12
  11. package/dist/adapters/ffmpeg.js +19 -1
  12. package/dist/adapters/host-cli/index.js +21 -4
  13. package/dist/adapters/host-cli/transport.js +2 -1
  14. package/dist/adapters/http-failure.js +53 -0
  15. package/dist/adapters/image/bytes.js +2 -1
  16. package/dist/adapters/image/codex.js +42 -9
  17. package/dist/adapters/image/fal.js +21 -53
  18. package/dist/adapters/image/google.js +33 -56
  19. package/dist/adapters/image/models.js +2 -2
  20. package/dist/adapters/image/openai.js +22 -48
  21. package/dist/adapters/image/reference.js +36 -0
  22. package/dist/adapters/image/replicate.js +21 -49
  23. package/dist/adapters/image/video.js +2 -1
  24. package/dist/adapters/interest/search-interest.js +113 -0
  25. package/dist/adapters/key-probes.js +54 -3
  26. package/dist/adapters/llm/antigravity-models.js +1 -1
  27. package/dist/adapters/llm/antigravity.js +11 -6
  28. package/dist/adapters/llm/assistant-cli.js +388 -0
  29. package/dist/adapters/llm/child-session.js +83 -0
  30. package/dist/adapters/llm/claude-code-models.js +52 -99
  31. package/dist/adapters/llm/claude-code.js +16 -4
  32. package/dist/adapters/llm/codex-limits.js +27 -68
  33. package/dist/adapters/llm/codex-models.js +1 -1
  34. package/dist/adapters/llm/codex-server-models.js +61 -109
  35. package/dist/adapters/llm/codex.js +12 -1
  36. package/dist/adapters/llm/document-workspace.js +3 -2
  37. package/dist/adapters/llm/image-workspace.js +3 -2
  38. package/dist/adapters/llm/openrouter.js +12 -48
  39. package/dist/adapters/llm/run-cli.js +9 -24
  40. package/dist/adapters/llm/sse-lines.js +5 -1
  41. package/dist/adapters/model-access.js +37 -0
  42. package/dist/adapters/tts/cartesia.js +15 -46
  43. package/dist/adapters/tts/elevenlabs.js +20 -52
  44. package/dist/adapters/tts/gemini.js +21 -41
  45. package/dist/adapters/tts/inworld-async.js +6 -2
  46. package/dist/adapters/tts/inworld.js +6 -2
  47. package/dist/adapters/tts/openai.js +20 -50
  48. package/dist/adapters/tts/system.js +2 -1
  49. package/dist/assets/models-lifecycle.yaml +6 -0
  50. package/dist/assistant-wiring.js +60 -0
  51. package/dist/autopilot-timers.js +59 -0
  52. package/dist/catalog/lifecycle.js +52 -0
  53. package/dist/catalog/propose.js +204 -0
  54. package/dist/catalog/registry.js +23 -14
  55. package/dist/catalog/schema.js +4 -1
  56. package/dist/catalog/store.js +39 -0
  57. package/dist/catalog/validate.js +5 -2
  58. package/dist/edge/autostart/native.js +3 -5
  59. package/dist/edge/autostart/prompt.js +2 -1
  60. package/dist/edge/autostart/service.js +3 -4
  61. package/dist/edge/cli-args.js +3 -4
  62. package/dist/edge/cli.js +2 -1
  63. package/dist/edge/docker-install/apply.js +11 -11
  64. package/dist/edge/docker-install/run.js +2 -1
  65. package/dist/edge/docker-install/state.js +4 -3
  66. package/dist/edge/docker-install/tree.js +2 -4
  67. package/dist/edge/docker-install/volume.js +3 -2
  68. package/dist/edge/docker.js +5 -4
  69. package/dist/edge/events/hub.js +5 -5
  70. package/dist/edge/http/actions.js +11 -32
  71. package/dist/edge/http/actor.js +5 -3
  72. package/dist/edge/http/app.js +86 -11
  73. package/dist/edge/http/assistant.js +129 -0
  74. package/dist/edge/http/audio-preview.js +4 -11
  75. package/dist/edge/http/auditions.js +1 -1
  76. package/dist/edge/http/autostart.js +5 -5
  77. package/dist/edge/http/backups.js +2 -4
  78. package/dist/edge/http/channel-memory.js +9 -22
  79. package/dist/edge/http/channels.js +14 -27
  80. package/dist/edge/http/checkpoints.js +39 -21
  81. package/dist/edge/http/design-templates.js +167 -0
  82. package/dist/edge/http/designs.js +178 -0
  83. package/dist/edge/http/diagnostics.js +5 -1
  84. package/dist/edge/http/document-themes.js +5 -14
  85. package/dist/edge/http/draft-files.js +1 -3
  86. package/dist/edge/http/draft-problem.js +5 -10
  87. package/dist/edge/http/drafts.js +3 -3
  88. package/dist/edge/http/entries.js +6 -9
  89. package/dist/edge/http/extension-auth.js +27 -0
  90. package/dist/edge/http/external-reviews.js +12 -11
  91. package/dist/edge/http/files.js +5 -11
  92. package/dist/edge/http/folder-location.js +1 -4
  93. package/dist/edge/http/fonts.js +0 -7
  94. package/dist/edge/http/home.js +47 -14
  95. package/dist/edge/http/host-cli.js +18 -8
  96. package/dist/edge/http/ids.js +8 -0
  97. package/dist/edge/http/keywords.js +35 -0
  98. package/dist/edge/http/model-checks.js +132 -0
  99. package/dist/edge/http/narration-peaks.js +5 -13
  100. package/dist/edge/http/onboarding.js +30 -26
  101. package/dist/edge/http/open-folder.js +5 -10
  102. package/dist/edge/http/outputs.js +7 -14
  103. package/dist/edge/http/patch-notes.js +6 -12
  104. package/dist/edge/http/planning.js +3 -7
  105. package/dist/edge/http/problem.js +2 -4
  106. package/dist/edge/http/project-create.js +2 -1
  107. package/dist/edge/http/project-templates.js +31 -19
  108. package/dist/edge/http/projects.js +24 -16
  109. package/dist/edge/http/prompts.js +9 -16
  110. package/dist/edge/http/pronunciations.js +1 -2
  111. package/dist/edge/http/providers.js +48 -34
  112. package/dist/edge/http/refusal.js +29 -0
  113. package/dist/edge/http/remote-access.js +40 -0
  114. package/dist/edge/http/remote-guard.js +71 -0
  115. package/dist/edge/http/request-guard.js +91 -0
  116. package/dist/edge/http/reviews.js +12 -25
  117. package/dist/edge/http/revision-files.js +6 -11
  118. package/dist/edge/http/revisions.js +14 -19
  119. package/dist/edge/http/run-cost.js +1 -2
  120. package/dist/edge/http/same-page.js +80 -0
  121. package/dist/edge/http/schedules.js +69 -40
  122. package/dist/edge/http/settings.js +27 -14
  123. package/dist/edge/http/social.js +283 -0
  124. package/dist/edge/http/staging.js +3 -5
  125. package/dist/edge/http/storage-files.js +5 -7
  126. package/dist/edge/http/storage.js +33 -25
  127. package/dist/edge/http/studio.js +94 -69
  128. package/dist/edge/http/style-preview.js +3 -6
  129. package/dist/edge/http/subtitles.js +3 -17
  130. package/dist/edge/http/template-studio.js +436 -0
  131. package/dist/edge/http/trash.js +11 -12
  132. package/dist/edge/http/tutorial.js +1 -2
  133. package/dist/edge/http/tutorials.js +5 -11
  134. package/dist/edge/http/update.js +7 -13
  135. package/dist/edge/http/waveform.js +3 -6
  136. package/dist/edge/http/youtube-edits.js +3 -4
  137. package/dist/edge/mcp/assistant.js +279 -0
  138. package/dist/edge/mcp/attribution.js +8 -2
  139. package/dist/edge/mcp/call-route.js +11 -2
  140. package/dist/edge/mcp/excluded-routes.js +29 -3
  141. package/dist/edge/mcp/http.js +11 -2
  142. package/dist/edge/mcp/instructions.js +6 -4
  143. package/dist/edge/mcp/library-tools.js +9 -5
  144. package/dist/edge/mcp/remake-tools.js +7 -4
  145. package/dist/edge/mcp/route-tool.js +35 -15
  146. package/dist/edge/mcp/server.js +13 -8
  147. package/dist/edge/mcp/tools-channels.js +11 -9
  148. package/dist/edge/mcp/tools-designs.js +165 -0
  149. package/dist/edge/mcp/tools-library.js +19 -7
  150. package/dist/edge/mcp/tools-planning.js +40 -21
  151. package/dist/edge/mcp/tools-projects.js +38 -11
  152. package/dist/edge/mcp/tools-publishing.js +9 -9
  153. package/dist/edge/mcp/tools-runs.js +23 -10
  154. package/dist/edge/mcp/tools-schedules.js +32 -8
  155. package/dist/edge/mcp/tools-setup.js +75 -11
  156. package/dist/edge/mcp/tools-social.js +47 -0
  157. package/dist/edge/mcp/tools-storage.js +11 -3
  158. package/dist/edge/mcp/tools-template-studio.js +166 -0
  159. package/dist/edge/mcp/tools.js +6 -0
  160. package/dist/edge/remote-access/cli.js +71 -0
  161. package/dist/edge/remote-access/model.js +32 -0
  162. package/dist/edge/remote-access/rules.js +207 -0
  163. package/dist/edge/remote-access/service.js +203 -0
  164. package/dist/edge/remote-access/store.js +44 -0
  165. package/dist/edge/remote-access/views.js +43 -0
  166. package/dist/extension/slopify-studio-chrome.zip +0 -0
  167. package/dist/extension/slopify-studio-firefox.zip +0 -0
  168. package/dist/host-cli/install.js +2 -2
  169. package/dist/host-cli/open-folder.js +2 -2
  170. package/dist/host-cli/paths.js +2 -4
  171. package/dist/host-cli/server.js +4 -4
  172. package/dist/host-cli/service.js +3 -3
  173. package/dist/host-cli/status.js +7 -7
  174. package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
  175. package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
  176. package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
  177. package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
  178. package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
  179. package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
  180. package/dist/kernel/db/migrations/0070-designs.sql +53 -0
  181. package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
  182. package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
  183. package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
  184. package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
  185. package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
  186. package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
  187. package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
  188. package/dist/kernel/db/migrations/0078-uploaded-from-links.sql +7 -0
  189. package/dist/kernel/db/tx.js +2 -4
  190. package/dist/kernel/errors.js +27 -1
  191. package/dist/kernel/json-answer.js +15 -0
  192. package/dist/kernel/lock.js +4 -9
  193. package/dist/kernel/paths.js +8 -0
  194. package/dist/kernel/pipeline.js +12 -0
  195. package/dist/kernel/ports/assistant-cli.js +4 -0
  196. package/dist/kernel/ports/host-cli.js +3 -0
  197. package/dist/kernel/ports/interest.js +4 -0
  198. package/dist/kernel/ports/languages.js +0 -3
  199. package/dist/kernel/ports/model.js +2 -0
  200. package/dist/kernel/ports/settings-places.js +31 -0
  201. package/dist/kernel/ports/system-speech.js +31 -3
  202. package/dist/kernel/runner/attempt.js +14 -4
  203. package/dist/kernel/runner/audition.js +3 -1
  204. package/dist/kernel/runner/checkpoint-authority.js +2 -1
  205. package/dist/kernel/runner/index.js +8 -10
  206. package/dist/kernel/runner/model-access.js +40 -0
  207. package/dist/kernel/runner/model-check.js +153 -0
  208. package/dist/kernel/runner/providers.js +18 -12
  209. package/dist/kernel/runner/standalone.js +11 -7
  210. package/dist/main.js +338 -21
  211. package/dist/model-catalog.js +20 -0
  212. package/dist/model-checks.js +166 -0
  213. package/dist/patch-notes/4.0.0.md +51 -0
  214. package/dist/patch-notes/4.1.0.md +42 -0
  215. package/dist/patch-notes/index.json +12 -0
  216. package/dist/slices/admission/heads.js +2 -1
  217. package/dist/slices/admission/listing-facts.js +95 -0
  218. package/dist/slices/admission/repo.js +11 -7
  219. package/dist/slices/admission/rules.js +50 -15
  220. package/dist/slices/admission/schema.js +8 -0
  221. package/dist/slices/admission/stage-writes.js +0 -3
  222. package/dist/slices/admission/start.js +48 -31
  223. package/dist/slices/admission/state-words.js +34 -5
  224. package/dist/slices/admission/substitute.js +7 -4
  225. package/dist/slices/agents/attention-posts.js +31 -0
  226. package/dist/slices/agents/attention-templates.js +33 -0
  227. package/dist/slices/agents/attention.js +10 -1
  228. package/dist/slices/agents/connection.js +2 -6
  229. package/dist/slices/agents/model.js +6 -3
  230. package/dist/slices/agents/repo.js +15 -7
  231. package/dist/slices/article/continuation.js +0 -63
  232. package/dist/slices/article/plain.js +3 -2
  233. package/dist/slices/article/segments.js +2 -62
  234. package/dist/slices/assistant/access.js +1 -0
  235. package/dist/slices/assistant/asks.js +80 -0
  236. package/dist/slices/assistant/cost.js +54 -0
  237. package/dist/slices/assistant/gate.js +222 -0
  238. package/dist/slices/assistant/model.js +86 -0
  239. package/dist/slices/assistant/names.js +23 -0
  240. package/dist/slices/assistant/prompt.js +74 -0
  241. package/dist/slices/assistant/repo.js +74 -0
  242. package/dist/slices/assistant/tokens.js +18 -0
  243. package/dist/slices/assistant/turn.js +344 -0
  244. package/dist/slices/autopilot/buffer.js +76 -0
  245. package/dist/slices/autopilot/model.js +14 -0
  246. package/dist/slices/autopilot/notify.js +27 -0
  247. package/dist/slices/autopilot/repo.js +34 -0
  248. package/dist/slices/autopilot/signals.js +194 -0
  249. package/dist/slices/autopilot/warnings.js +85 -0
  250. package/dist/slices/autopilot/weekly.js +100 -0
  251. package/dist/slices/backups/files.js +2 -6
  252. package/dist/slices/backups/repo.js +3 -15
  253. package/dist/slices/backups/service.js +8 -7
  254. package/dist/slices/channels/cast-images.js +3 -2
  255. package/dist/slices/channels/model.js +0 -1
  256. package/dist/slices/channels/rebrand.js +0 -3
  257. package/dist/slices/channels/repo.js +4 -0
  258. package/dist/slices/channels/schema.js +7 -1
  259. package/dist/slices/channels/service.js +10 -0
  260. package/dist/slices/channels/videos.js +3 -15
  261. package/dist/slices/checkpoints/index.js +0 -1
  262. package/dist/slices/control/providers.js +2 -28
  263. package/dist/slices/designs/artwork.js +66 -0
  264. package/dist/slices/designs/budget.js +23 -0
  265. package/dist/slices/designs/calls.js +124 -0
  266. package/dist/slices/designs/check-context.js +38 -0
  267. package/dist/slices/designs/check-text.js +43 -0
  268. package/dist/slices/designs/fields.js +88 -0
  269. package/dist/slices/designs/frames.js +34 -0
  270. package/dist/slices/designs/gate.js +130 -0
  271. package/dist/slices/designs/layout.js +293 -0
  272. package/dist/slices/designs/model.js +35 -0
  273. package/dist/slices/designs/pdf-job.js +23 -0
  274. package/dist/slices/designs/pdf-pages.js +30 -0
  275. package/dist/slices/designs/pdf-runner.js +68 -0
  276. package/dist/slices/designs/pdf-worker.js +24 -0
  277. package/dist/slices/designs/picture-size.js +79 -0
  278. package/dist/slices/designs/pictures.js +55 -0
  279. package/dist/slices/designs/quote.js +24 -0
  280. package/dist/slices/designs/render-args.js +36 -0
  281. package/dist/slices/designs/render-input.js +59 -0
  282. package/dist/slices/designs/render.js +215 -0
  283. package/dist/slices/designs/repo.js +101 -0
  284. package/dist/slices/designs/requests.js +80 -0
  285. package/dist/slices/designs/runner.js +239 -0
  286. package/dist/slices/designs/sample-repo.js +91 -0
  287. package/dist/slices/designs/sample.js +223 -0
  288. package/dist/slices/designs/schema.js +87 -0
  289. package/dist/slices/designs/sections.js +44 -0
  290. package/dist/slices/designs/service.js +233 -0
  291. package/dist/slices/designs/steps-repo.js +102 -0
  292. package/dist/slices/designs/studio-kind.js +39 -0
  293. package/dist/slices/designs/template-checks.js +44 -0
  294. package/dist/slices/designs/template-make.js +118 -0
  295. package/dist/slices/designs/templates.js +218 -0
  296. package/dist/slices/document/fonts.js +2 -1
  297. package/dist/slices/document/model.js +7 -4
  298. package/dist/slices/document/render.js +2 -1
  299. package/dist/slices/document/theme-schema.js +1 -1
  300. package/dist/slices/document/theme.js +49 -3
  301. package/dist/slices/episodes/summarize.js +6 -2
  302. package/dist/slices/estimate/index.js +72 -28
  303. package/dist/slices/estimate/requests.js +4 -4
  304. package/dist/slices/fixes/rules.js +3 -1
  305. package/dist/slices/fonts/catalog.js +5 -3
  306. package/dist/slices/fonts/coverage.js +2 -1
  307. package/dist/slices/fonts/discovery.js +3 -2
  308. package/dist/slices/fonts/files.js +2 -6
  309. package/dist/slices/fonts/index.js +0 -1
  310. package/dist/slices/fonts/sfnt.js +45 -10
  311. package/dist/slices/images/appearance.js +8 -16
  312. package/dist/slices/images/scenes.js +102 -28
  313. package/dist/slices/keywords/digest.js +85 -0
  314. package/dist/slices/keywords/facts.js +92 -0
  315. package/dist/slices/keywords/fill.js +80 -0
  316. package/dist/slices/keywords/model.js +75 -0
  317. package/dist/slices/keywords/rules.js +187 -0
  318. package/dist/slices/keywords/schema.js +28 -0
  319. package/dist/slices/keywords/specs.js +260 -0
  320. package/dist/slices/keywords/values.js +74 -0
  321. package/dist/slices/library/lint.js +29 -12
  322. package/dist/slices/library/model.js +2 -0
  323. package/dist/slices/library/photorealistic.js +4 -12
  324. package/dist/slices/library/rename.js +9 -7
  325. package/dist/slices/library/save.js +14 -10
  326. package/dist/slices/library/slots.js +37 -11
  327. package/dist/slices/library/transfer.js +5 -4
  328. package/dist/slices/library/used-by.js +25 -10
  329. package/dist/slices/loudness/loudnorm.js +53 -12
  330. package/dist/slices/loudness/model.js +3 -2
  331. package/dist/slices/loudness/sentence-level.js +2 -1
  332. package/dist/slices/model-checks/cost.js +61 -0
  333. package/dist/slices/model-checks/listing.js +124 -0
  334. package/dist/slices/model-checks/model.js +20 -0
  335. package/dist/slices/model-checks/record.js +32 -0
  336. package/dist/slices/model-checks/repo.js +120 -0
  337. package/dist/slices/model-checks/rules.js +125 -0
  338. package/dist/slices/model-checks/run.js +143 -0
  339. package/dist/slices/model-checks/service.js +198 -0
  340. package/dist/slices/model-upkeep/model.js +1 -1
  341. package/dist/slices/model-upkeep/switch.js +72 -27
  342. package/dist/slices/model-upkeep/usage.js +39 -13
  343. package/dist/slices/narration/breaths.js +3 -1
  344. package/dist/slices/narration/clean-pieces.js +3 -1
  345. package/dist/slices/narration/concat.js +2 -1
  346. package/dist/slices/narration/pauses-model.js +3 -2
  347. package/dist/slices/narration/peaks.js +3 -4
  348. package/dist/slices/narration/pronunciation-chunks.js +4 -3
  349. package/dist/slices/narration/pronunciation.js +6 -4
  350. package/dist/slices/narration/steering.js +4 -3
  351. package/dist/slices/notifications/notifier.js +4 -3
  352. package/dist/slices/notifications/rules.js +5 -2
  353. package/dist/slices/notifications/settings.js +4 -12
  354. package/dist/slices/notifications/subject.js +4 -3
  355. package/dist/slices/onboarding/copy.js +21 -3
  356. package/dist/slices/onboarding/first-run.js +16 -40
  357. package/dist/slices/onboarding/full-video.js +3 -2
  358. package/dist/slices/onboarding/install.js +6 -4
  359. package/dist/slices/onboarding/model.js +26 -37
  360. package/dist/slices/onboarding/packs.js +22 -22
  361. package/dist/slices/onboarding/preferred-model.js +14 -0
  362. package/dist/slices/onboarding/quick-short.js +105 -65
  363. package/dist/slices/onboarding/sample.js +4 -2
  364. package/dist/slices/onboarding/state.js +9 -11
  365. package/dist/slices/onboarding/template.js +8 -6
  366. package/dist/slices/outputs/add.js +3 -2
  367. package/dist/slices/outputs/service.js +2 -2
  368. package/dist/slices/patch-notes/library.js +4 -3
  369. package/dist/slices/play-drafts/convert.js +4 -0
  370. package/dist/slices/play-drafts/readiness.js +3 -3
  371. package/dist/slices/play-drafts/review-inputs.js +9 -3
  372. package/dist/slices/play-drafts/review.js +5 -4
  373. package/dist/slices/play-drafts/schema.js +4 -0
  374. package/dist/slices/play-drafts/service.js +17 -7
  375. package/dist/slices/project-templates/from-project.js +9 -2
  376. package/dist/slices/project-templates/next-chapter.js +2 -1
  377. package/dist/slices/project-templates/provider-defaults.js +22 -0
  378. package/dist/slices/project-templates/repo.js +6 -1
  379. package/dist/slices/project-templates/setup-sections.js +26 -0
  380. package/dist/slices/project-templates/setup.js +14 -1
  381. package/dist/slices/project-templates/stand-ins.js +22 -0
  382. package/dist/slices/rebuild/activity.js +2 -0
  383. package/dist/slices/rebuild/admission-repo.js +3 -2
  384. package/dist/slices/rebuild/narration-history.js +4 -5
  385. package/dist/slices/rebuild/narration-retry.js +2 -1
  386. package/dist/slices/rebuild/preview-details.js +32 -14
  387. package/dist/slices/rebuild/preview-plan.js +3 -8
  388. package/dist/slices/rebuild/recipe-build.js +8 -3
  389. package/dist/slices/rebuild/recipe-describe.js +3 -3
  390. package/dist/slices/rebuild/recipe-digest.js +58 -0
  391. package/dist/slices/rebuild/recipe-input-schema.js +10 -0
  392. package/dist/slices/rebuild/recipe-keywords.js +71 -0
  393. package/dist/slices/rebuild/recipe-legacy.js +5 -1
  394. package/dist/slices/rebuild/recipe-model.js +4 -0
  395. package/dist/slices/rebuild/recipe-narration-text.js +2 -1
  396. package/dist/slices/rebuild/recipe-preparation.js +4 -4
  397. package/dist/slices/rebuild/recipe-reference.js +8 -4
  398. package/dist/slices/rebuild/recipe-reviews.js +27 -7
  399. package/dist/slices/rebuild/recipe-save.js +8 -5
  400. package/dist/slices/rebuild/recipe-scenes.js +40 -11
  401. package/dist/slices/rebuild/recipe-shorts.js +8 -8
  402. package/dist/slices/rebuild/recipe-social.js +46 -0
  403. package/dist/slices/rebuild/recipe-text.js +64 -20
  404. package/dist/slices/rebuild/recipe-validation.js +102 -31
  405. package/dist/slices/rebuild/recipe-visual.js +55 -16
  406. package/dist/slices/rebuild/recipe-voices.js +3 -2
  407. package/dist/slices/rebuild/recipe-work.js +19 -7
  408. package/dist/slices/rebuild/recipe-youtube.js +4 -3
  409. package/dist/slices/rebuild/recovery-selection.js +3 -1
  410. package/dist/slices/rebuild/recovery.js +9 -8
  411. package/dist/slices/rebuild/remake-outdated.js +5 -5
  412. package/dist/slices/rebuild/repo.js +4 -3
  413. package/dist/slices/rebuild/review-promise.js +25 -0
  414. package/dist/slices/rebuild/review-redo.js +3 -2
  415. package/dist/slices/rebuild/runtime-admission.js +4 -3
  416. package/dist/slices/rebuild/runtime-agent-review.js +11 -5
  417. package/dist/slices/rebuild/runtime-animate.js +10 -9
  418. package/dist/slices/rebuild/runtime-article.js +7 -5
  419. package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
  420. package/dist/slices/rebuild/runtime-document.js +11 -13
  421. package/dist/slices/rebuild/runtime-export-bed.js +8 -12
  422. package/dist/slices/rebuild/runtime-export-edit.js +8 -16
  423. package/dist/slices/rebuild/runtime-export-inputs.js +12 -11
  424. package/dist/slices/rebuild/runtime-export-short.js +9 -5
  425. package/dist/slices/rebuild/runtime-export.js +38 -15
  426. package/dist/slices/rebuild/runtime-figure-card.js +2 -1
  427. package/dist/slices/rebuild/runtime-image.js +8 -12
  428. package/dist/slices/rebuild/runtime-instructions.js +2 -0
  429. package/dist/slices/rebuild/runtime-keywords.js +59 -0
  430. package/dist/slices/rebuild/runtime-lines.js +2 -11
  431. package/dist/slices/rebuild/runtime-local.js +17 -22
  432. package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
  433. package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
  434. package/dist/slices/rebuild/runtime-narration-text.js +13 -17
  435. package/dist/slices/rebuild/runtime-pictures.js +2 -4
  436. package/dist/slices/rebuild/runtime-piece-label.js +10 -6
  437. package/dist/slices/rebuild/runtime-plan.js +31 -5
  438. package/dist/slices/rebuild/runtime-provider.js +67 -25
  439. package/dist/slices/rebuild/runtime-publication.js +10 -9
  440. package/dist/slices/rebuild/runtime-review.js +39 -33
  441. package/dist/slices/rebuild/runtime-run.js +4 -1
  442. package/dist/slices/rebuild/runtime-shorts.js +31 -50
  443. package/dist/slices/rebuild/runtime-store.js +20 -10
  444. package/dist/slices/rebuild/runtime-subtitles.js +28 -25
  445. package/dist/slices/rebuild/runtime-voices.js +10 -16
  446. package/dist/slices/rebuild/runtime-youtube.js +14 -31
  447. package/dist/slices/rebuild/service-readiness.js +11 -3
  448. package/dist/slices/rebuild/transition-repo.js +6 -5
  449. package/dist/slices/rebuild/work-records.js +6 -0
  450. package/dist/slices/reruns/cascade.js +1 -2
  451. package/dist/slices/reruns/index.js +6 -9
  452. package/dist/slices/research/synthesis.js +3 -2
  453. package/dist/slices/reviews/external-model.js +4 -1
  454. package/dist/slices/reviews/external-repo.js +2 -1
  455. package/dist/slices/reviews/external-rows.js +2 -3
  456. package/dist/slices/reviews/holds.js +5 -4
  457. package/dist/slices/reviews/model.js +32 -11
  458. package/dist/slices/reviews/repo.js +2 -1
  459. package/dist/slices/reviews/rules.js +4 -3
  460. package/dist/slices/reviews/verdict.js +2 -1
  461. package/dist/slices/reviews/view.js +5 -2
  462. package/dist/slices/revisions/downloads.js +4 -5
  463. package/dist/slices/revisions/image-plan.js +1 -1
  464. package/dist/slices/revisions/mutation-assets.js +9 -5
  465. package/dist/slices/revisions/mutation-cues.js +2 -5
  466. package/dist/slices/revisions/mutations.js +3 -3
  467. package/dist/slices/revisions/repo.js +3 -1
  468. package/dist/slices/revisions/schema.js +1 -0
  469. package/dist/slices/revisions/view.js +20 -0
  470. package/dist/slices/run-cost/limits.js +5 -2
  471. package/dist/slices/run-cost/meter.js +12 -5
  472. package/dist/slices/run-cost/panel.js +8 -74
  473. package/dist/slices/run-cost/plan-readings.js +127 -0
  474. package/dist/slices/run-cost/plan-use.js +169 -0
  475. package/dist/slices/run-cost/pricing.js +3 -3
  476. package/dist/slices/run-cost/week.js +32 -4
  477. package/dist/slices/schedules/agenda.js +18 -7
  478. package/dist/slices/schedules/by-date.js +42 -0
  479. package/dist/slices/schedules/calendar.js +5 -0
  480. package/dist/slices/schedules/design-agenda.js +36 -0
  481. package/dist/slices/schedules/design-check.js +41 -0
  482. package/dist/slices/schedules/design-run.js +126 -0
  483. package/dist/slices/schedules/next-run.js +62 -0
  484. package/dist/slices/schedules/prepare.js +18 -2
  485. package/dist/slices/schedules/repo.js +30 -21
  486. package/dist/slices/schedules/rescore.js +35 -0
  487. package/dist/slices/schedules/scheduler.js +13 -3
  488. package/dist/slices/schedules/schema.js +57 -3
  489. package/dist/slices/schedules/score.js +107 -0
  490. package/dist/slices/schedules/service.js +57 -24
  491. package/dist/slices/schedules/topic-list.js +15 -0
  492. package/dist/slices/schedules/topic-scores.js +104 -0
  493. package/dist/slices/schedules/topics.js +53 -41
  494. package/dist/slices/settings/cli-paths.js +4 -6
  495. package/dist/slices/settings/first-run.js +8 -43
  496. package/dist/slices/settings/health.js +30 -15
  497. package/dist/slices/settings/key-test.js +1 -1
  498. package/dist/slices/settings/model-reach.js +3 -17
  499. package/dist/slices/settings/model.js +14 -2
  500. package/dist/slices/settings/playback.js +34 -23
  501. package/dist/slices/settings/probe-read.js +16 -0
  502. package/dist/slices/settings/repo.js +33 -0
  503. package/dist/slices/settings/tutorial.js +2 -2
  504. package/dist/slices/settings/voices.js +4 -12
  505. package/dist/slices/shorts/keep.js +2 -1
  506. package/dist/slices/shorts/pick.js +6 -18
  507. package/dist/slices/shorts/prompts.js +4 -14
  508. package/dist/slices/shorts/render.js +6 -2
  509. package/dist/slices/social/channel.js +44 -0
  510. package/dist/slices/social/defaults.js +17 -0
  511. package/dist/slices/social/due.js +36 -0
  512. package/dist/slices/social/extension.js +18 -0
  513. package/dist/slices/social/fit.js +115 -0
  514. package/dist/slices/social/limits.js +186 -0
  515. package/dist/slices/social/links.js +21 -0
  516. package/dist/slices/social/media.js +132 -0
  517. package/dist/slices/social/model.js +75 -0
  518. package/dist/slices/social/notice.js +19 -0
  519. package/dist/slices/social/pack.js +176 -0
  520. package/dist/slices/social/post-prompt.js +56 -0
  521. package/dist/slices/social/queue.js +31 -0
  522. package/dist/slices/social/repo.js +133 -0
  523. package/dist/slices/social/reshape.js +97 -0
  524. package/dist/slices/social/rules.js +5 -0
  525. package/dist/slices/social/schema.js +70 -0
  526. package/dist/slices/social/serve.js +51 -0
  527. package/dist/slices/social/service.js +129 -0
  528. package/dist/slices/social/settings.js +21 -0
  529. package/dist/slices/social/sources.js +114 -0
  530. package/dist/slices/social/state.js +110 -0
  531. package/dist/slices/social/text.js +149 -0
  532. package/dist/slices/storage/arrange.js +3 -1
  533. package/dist/slices/storage/assets.js +8 -10
  534. package/dist/slices/storage/backup-designs.js +74 -0
  535. package/dist/slices/storage/backup-export.js +8 -3
  536. package/dist/slices/storage/backup-format.js +10 -0
  537. package/dist/slices/storage/backup-import.js +22 -4
  538. package/dist/slices/storage/delete-project.js +6 -5
  539. package/dist/slices/storage/files-location.js +6 -8
  540. package/dist/slices/storage/layout.js +13 -2
  541. package/dist/slices/storage/model.js +3 -0
  542. package/dist/slices/storage/portable.js +17 -12
  543. package/dist/slices/storage/schema.js +2 -0
  544. package/dist/slices/storage/staging-refs.js +2 -1
  545. package/dist/slices/storage/staging.js +6 -9
  546. package/dist/slices/storage/trim.js +26 -9
  547. package/dist/slices/studio/calendar.js +7 -2
  548. package/dist/slices/studio/disclosure.js +4 -4
  549. package/dist/slices/studio/model.js +1 -1
  550. package/dist/slices/studio/pack.js +9 -8
  551. package/dist/slices/studio/pick.js +2 -11
  552. package/dist/slices/studio/plan.js +7 -16
  553. package/dist/slices/studio/queue.js +3 -14
  554. package/dist/slices/studio/releases.js +26 -0
  555. package/dist/slices/studio/settings.js +20 -57
  556. package/dist/slices/studio/videos.js +35 -4
  557. package/dist/slices/style-preview/render.js +37 -16
  558. package/dist/slices/style-preview/schema.js +14 -1
  559. package/dist/slices/style-preview/service.js +2 -1
  560. package/dist/slices/style-preview/settings.js +33 -5
  561. package/dist/slices/subtitles/captions.js +1 -1
  562. package/dist/slices/telemetry/collector-client.js +2 -4
  563. package/dist/slices/telemetry/flush.js +2 -4
  564. package/dist/slices/telemetry/model.js +0 -7
  565. package/dist/slices/telemetry/record.js +10 -3
  566. package/dist/slices/template-studio/anatomy-view.js +161 -0
  567. package/dist/slices/template-studio/anatomy.js +73 -0
  568. package/dist/slices/template-studio/bakeoff-make.js +225 -0
  569. package/dist/slices/template-studio/bakeoff-repo.js +83 -0
  570. package/dist/slices/template-studio/bakeoff.js +333 -0
  571. package/dist/slices/template-studio/budget.js +106 -0
  572. package/dist/slices/template-studio/cards.js +78 -0
  573. package/dist/slices/template-studio/checks.js +322 -0
  574. package/dist/slices/template-studio/document-sample.js +56 -0
  575. package/dist/slices/template-studio/edit.js +15 -0
  576. package/dist/slices/template-studio/for-all.js +161 -0
  577. package/dist/slices/template-studio/free-video.js +31 -0
  578. package/dist/slices/template-studio/free.js +176 -0
  579. package/dist/slices/template-studio/gate.js +40 -0
  580. package/dist/slices/template-studio/hidden.js +20 -0
  581. package/dist/slices/template-studio/jobs.js +79 -0
  582. package/dist/slices/template-studio/loudness.js +111 -0
  583. package/dist/slices/template-studio/make.js +40 -0
  584. package/dist/slices/template-studio/model.js +58 -0
  585. package/dist/slices/template-studio/pack-import.js +253 -0
  586. package/dist/slices/template-studio/pack-samples.js +60 -0
  587. package/dist/slices/template-studio/pack.js +207 -0
  588. package/dist/slices/template-studio/paid-view.js +66 -0
  589. package/dist/slices/template-studio/paid.js +355 -0
  590. package/dist/slices/template-studio/quote.js +155 -0
  591. package/dist/slices/template-studio/ready.js +104 -0
  592. package/dist/slices/template-studio/repo.js +134 -0
  593. package/dist/slices/template-studio/reviews-path.js +58 -0
  594. package/dist/slices/template-studio/runner.js +84 -0
  595. package/dist/slices/template-studio/save.js +236 -0
  596. package/dist/slices/template-studio/say-it-as.js +248 -0
  597. package/dist/slices/template-studio/schedule-gate.js +34 -0
  598. package/dist/slices/template-studio/schedule-price.js +32 -0
  599. package/dist/slices/template-studio/schedule-sample.js +91 -0
  600. package/dist/slices/template-studio/schema.js +243 -0
  601. package/dist/slices/template-studio/scope.js +124 -0
  602. package/dist/slices/template-studio/sections.js +176 -0
  603. package/dist/slices/template-studio/service.js +175 -0
  604. package/dist/slices/template-studio/status.js +191 -0
  605. package/dist/slices/template-studio/topic.js +223 -0
  606. package/dist/slices/thumbnail/by-llm.js +1 -1
  607. package/dist/slices/trash/designs.js +76 -0
  608. package/dist/slices/trash/model.js +13 -4
  609. package/dist/slices/trash/service.js +52 -2
  610. package/dist/slices/tutorials/library.js +3 -2
  611. package/dist/slices/uploads/repo.js +37 -1
  612. package/dist/slices/uploads/rules.js +3 -2
  613. package/dist/slices/video/ass-text.js +17 -0
  614. package/dist/slices/video/audio-export.js +2 -64
  615. package/dist/slices/video/edit-list.js +2 -2
  616. package/dist/slices/video/edit-settings.js +1 -1
  617. package/dist/slices/video/encoding.js +169 -0
  618. package/dist/slices/video/ffmpeg.js +23 -21
  619. package/dist/slices/video/figure-card.js +1 -15
  620. package/dist/slices/video/plan.js +2 -1
  621. package/dist/slices/video/slideshow.js +43 -18
  622. package/dist/slices/voices/attribution.js +3 -2
  623. package/dist/slices/voices/model.js +9 -8
  624. package/dist/slices/voices/palette.js +0 -3
  625. package/dist/slices/voices/script.js +2 -1
  626. package/dist/slices/youtube/answer.js +4 -16
  627. package/dist/slices/youtube/edits-repo.js +3 -12
  628. package/dist/tutorials/AI-CLIs.md +25 -25
  629. package/dist/tutorials/Agents-MCP.md +34 -33
  630. package/dist/tutorials/Assistant.md +42 -0
  631. package/dist/tutorials/Backups.md +7 -7
  632. package/dist/tutorials/Calendar.md +17 -25
  633. package/dist/tutorials/Cast-Library.md +19 -19
  634. package/dist/tutorials/Channels.md +42 -35
  635. package/dist/tutorials/Costs-and-Run-Cost.md +38 -40
  636. package/dist/tutorials/Create-Article.md +114 -0
  637. package/dist/tutorials/Create-Extras.md +112 -0
  638. package/dist/tutorials/Create-Images.md +165 -0
  639. package/dist/tutorials/Create-Narration.md +178 -0
  640. package/dist/tutorials/Create-Overview.md +244 -0
  641. package/dist/tutorials/Create-Video-and-Style.md +144 -0
  642. package/dist/tutorials/Docker.md +3 -3
  643. package/dist/tutorials/Document-Themes.md +32 -32
  644. package/dist/tutorials/Editing-a-Project.md +94 -94
  645. package/dist/tutorials/FAQ.md +18 -18
  646. package/dist/tutorials/First-Launch-and-Welcome.md +50 -64
  647. package/dist/tutorials/Home-and-Projects.md +115 -71
  648. package/dist/tutorials/Home.md +33 -33
  649. package/dist/tutorials/Install.md +14 -13
  650. package/dist/tutorials/Intros-and-Outros.md +33 -34
  651. package/dist/tutorials/Keyboard-Shortcuts-and-Command-Palette.md +62 -58
  652. package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
  653. package/dist/tutorials/Models.md +53 -21
  654. package/dist/tutorials/Multiple-Voices.md +41 -40
  655. package/dist/tutorials/Narration-Aliases-and-Glossary.md +14 -14
  656. package/dist/tutorials/Notifications.md +27 -17
  657. package/dist/tutorials/Other-Languages.md +15 -15
  658. package/dist/tutorials/PDF-Documents.md +38 -29
  659. package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
  660. package/dist/tutorials/Project-Page.md +118 -120
  661. package/dist/tutorials/Prompts-and-Templates.md +84 -0
  662. package/dist/tutorials/Prompts.md +48 -44
  663. package/dist/tutorials/Providers-and-Keys.md +105 -98
  664. package/dist/tutorials/Publishing-to-YouTube.md +31 -31
  665. package/dist/tutorials/Recovery-and-Retries.md +31 -31
  666. package/dist/tutorials/Remote-Access.md +63 -0
  667. package/dist/tutorials/Reviews-and-Checkpoints.md +98 -90
  668. package/dist/tutorials/Schedules.md +46 -27
  669. package/dist/tutorials/Settings-Reference.md +194 -174
  670. package/dist/tutorials/Shorts.md +34 -33
  671. package/dist/tutorials/Start-at-Login.md +3 -3
  672. package/dist/tutorials/Studio-Extension.md +22 -24
  673. package/dist/tutorials/Template-Studio.md +128 -0
  674. package/dist/tutorials/Templates.md +51 -77
  675. package/dist/tutorials/Trash.md +4 -4
  676. package/dist/tutorials/Troubleshooting.md +44 -44
  677. package/dist/tutorials/Uninstalling-and-Moving.md +5 -5
  678. package/dist/tutorials/Updating-and-Patch-Notes.md +18 -18
  679. package/dist/tutorials/Video-Editing.md +34 -34
  680. package/dist/tutorials/Where-Your-Files-Live.md +10 -10
  681. package/dist/tutorials/YouTube-Description.md +26 -26
  682. package/dist/tutorials/Your-First-Short.md +35 -35
  683. package/dist/tutorials/_Sidebar.md +19 -14
  684. package/dist/updater/work-in-progress.js +42 -12
  685. package/dist/web/assets/index-BNftKQrA.css +1 -0
  686. package/dist/web/assets/index-Cpa58woP.js +459 -0
  687. package/dist/web/assets/pdf-BKh8f7R6.js +56 -0
  688. package/dist/web/assets/pdf.worker.min-BmVo14Nb.mjs +28 -0
  689. package/dist/web/assets/pdf.worker.min-D7i8o3wR.js +1 -0
  690. package/dist/web/index.html +2 -2
  691. package/package.json +6 -2
  692. package/dist/slices/article/provided-entries.js +0 -66
  693. package/dist/slices/article/run.js +0 -145
  694. package/dist/slices/images/run.js +0 -234
  695. package/dist/slices/narration/legacy-plan.js +0 -58
  696. package/dist/slices/narration/run.js +0 -270
  697. package/dist/slices/rebuild/runtime-actions.js +0 -90
  698. package/dist/slices/research/run.js +0 -224
  699. package/dist/slices/subtitles/prepare.js +0 -194
  700. package/dist/slices/subtitles/transcript.js +0 -34
  701. package/dist/slices/thumbnail/run.js +0 -219
  702. package/dist/slices/video/audio-inputs.js +0 -33
  703. package/dist/slices/video/reuse-audio.js +0 -62
  704. package/dist/slices/video/run.js +0 -78
  705. package/dist/slices/video/write-export.js +0 -158
  706. package/dist/slices/video/write-subtitles.js +0 -59
  707. package/dist/tutorials/Library-Overview.md +0 -76
  708. package/dist/tutorials/Play-Images.md +0 -161
  709. package/dist/tutorials/Play-Narration.md +0 -167
  710. package/dist/tutorials/Play-Outputs.md +0 -109
  711. package/dist/tutorials/Play-Overview.md +0 -227
  712. package/dist/tutorials/Play-Title-and-Article.md +0 -136
  713. package/dist/tutorials/Play-Video-and-Style.md +0 -143
  714. package/dist/web/assets/index-BadsoORk.css +0 -1
  715. package/dist/web/assets/index-D8LqNsCl.js +0 -326
  716. package/dist/web/assets/pdf-T7MCwjIv.js +0 -54
  717. package/dist/web/assets/pdf.worker.min-Dswkl-cV.mjs +0 -29
  718. package/dist/web/assets/pdf.worker.min-zC6nfbxG.js +0 -1
@@ -4,6 +4,8 @@ import { storeArticleText } from "../article/store.js";
4
4
  import { resolveChannelId, setProjectChannel } from "../channels/repo.js";
5
5
  import { defaultDocumentTheme } from "../document/model.js";
6
6
  import { earlierEpisodesFor } from "../episodes/related.js";
7
+ import { keywordFactsFor } from "../keywords/facts.js";
8
+ import { usesFacts } from "../keywords/rules.js";
7
9
  import { listNarrationAliases } from "../narration/aliases-library.js";
8
10
  import { currentPronunciationRules } from "../narration/pronunciation.js";
9
11
  import { collectSharedGlossary } from "../narration/shared-glossary.js";
@@ -33,37 +35,8 @@ export function initialState(source) {
33
35
  export function startRun(deps, draft, rendered, retainStaged = false, templates) {
34
36
  const id = deps.ids.next();
35
37
  const at = deps.clock.now().toISOString();
36
- const shared = usesPronunciationGlossary(draft) && draft.audio?.shareGlossary === true
37
- ? collectSharedGlossary(deps).entries
38
- : [];
39
- // Library → Aliases as they are now: later edits there never change this project.
40
- const aliases = draft.sources.audio === "generate" && draft.audio?.useNarrationAliases === true
41
- ? listNarrationAliases(deps.db)
42
- : [];
43
- // The title may name keywords too ("History: {{Topic}}"), filled like a prompt's, so a
44
- // template or Play keeps the pattern and each project gets its own title.
45
- const title = render(draft.title, draft.values).trim() || draft.title;
46
- // The channel's related earlier episodes as they are now (`slices/episodes`): later edits
47
- // there never change this project. A draft never brings its own.
48
- const { earlierEpisodes: _carried, ...fresh } = draft;
49
- const earlier = earlierEpisodesFor(deps.db, draft, title);
50
- const config = {
51
- ...fresh,
52
- title,
53
- ...(title !== draft.title && detectSlots(draft.title).names.length > 0
54
- ? { titlePattern: draft.title }
55
- : {}),
56
- // A new project always names its document theme: a config without one reads as the
57
- // DiceMaster of older projects (see documentThemeOf), which no new project should get.
58
- ...(sourceOf(draft.sources, "document") === "generate" && draft.document === undefined
59
- ? { document: { theme: defaultDocumentTheme } }
60
- : {}),
61
- rendered,
62
- ...(shared.length === 0 ? {} : { sharedGlossary: shared }),
63
- ...(aliases.length === 0 ? {} : { narrationAliases: aliases }),
64
- pronunciationRules: currentPronunciationRules,
65
- ...(earlier === undefined ? {} : { earlierEpisodes: earlier }),
66
- };
38
+ const config = configOf(deps, draft, rendered, deps.clock.now(), templates);
39
+ const { title } = config;
67
40
  const project = {
68
41
  id,
69
42
  title,
@@ -130,6 +103,50 @@ export function startRun(deps, draft, rendered, retainStaged = false, templates)
130
103
  }
131
104
  return { project, stages };
132
105
  }
106
+ // The config a run starts with: the draft as filled, with what Slopify copies in when it starts
107
+ // (the shared glossary, Library → Aliases, the pronunciation rules, the channel's earlier
108
+ // episodes) as they are now. The template studio saves its sample's next revision from it.
109
+ export function configOf(deps, draft, rendered, now, templates,
110
+ // The project the config is for when it exists already (a template sample's next
111
+ // revision): it is neither its own previous video nor one it covered before.
112
+ projectId) {
113
+ const shared = usesPronunciationGlossary(draft) && draft.audio?.shareGlossary === true
114
+ ? collectSharedGlossary(deps).entries
115
+ : [];
116
+ // Library → Aliases as they are now: later edits there never change this project.
117
+ const aliases = draft.sources.audio === "generate" && draft.audio?.useNarrationAliases === true
118
+ ? listNarrationAliases(deps.db)
119
+ : [];
120
+ // The title may name keywords too ("History: {{Topic}}"), filled like a prompt's, so a
121
+ // template or Play keeps the pattern and each project gets its own title.
122
+ const title = render(draft.title, draft.values).trim() || draft.title;
123
+ // The channel's related earlier episodes as they are now (`slices/episodes`): later edits
124
+ // there never change this project. A draft never brings its own.
125
+ const { earlierEpisodes: _carried, keywordFacts: _facts, ...fresh } = draft;
126
+ const earlier = earlierEpisodesFor(deps.db, draft, title);
127
+ const titlePattern = title !== draft.title && detectSlots(draft.title).names.length > 0 ? draft.title : undefined;
128
+ // The facts the keywords Slopify fills come from, as they are now, and only when a picked
129
+ // prompt asks for one: a run that uses none saves the config it always did.
130
+ const facts = usesFacts(Object.values(templates ?? rendered))
131
+ ? keywordFactsFor(deps, { ...draft, title, titlePattern }, now, projectId)
132
+ : undefined;
133
+ return {
134
+ ...fresh,
135
+ title,
136
+ ...(titlePattern === undefined ? {} : { titlePattern }),
137
+ // A new project always names its document theme: a config without one reads as the
138
+ // DiceMaster of older projects (see documentThemeOf), which no new project should get.
139
+ ...(sourceOf(draft.sources, "document") === "generate" && draft.document === undefined
140
+ ? { document: { theme: defaultDocumentTheme } }
141
+ : {}),
142
+ rendered,
143
+ ...(shared.length === 0 ? {} : { sharedGlossary: shared }),
144
+ ...(aliases.length === 0 ? {} : { narrationAliases: aliases }),
145
+ pronunciationRules: currentPronunciationRules,
146
+ ...(earlier === undefined ? {} : { earlierEpisodes: earlier }),
147
+ ...(facts === undefined ? {} : { keywordFacts: facts }),
148
+ };
149
+ }
133
150
  function attachProvided(deps, projectId, draft, collected, retainStaged) {
134
151
  const { sources, provided } = draft;
135
152
  if (sources.research === "provide" && provided.research !== undefined) {
@@ -28,8 +28,13 @@ export const stageStateWords = {
28
28
  export const heldWord = "Waiting for your review";
29
29
  export const waitingForAgentWord = "Waiting for the agent";
30
30
  export const stoppedWord = "Stopped";
31
- export const preparedWord = "Prepared";
31
+ // Made ahead by its schedule (Make ahead): everything but the video is made, and the video is
32
+ // put together on the run's day.
33
+ export const preparedWord = "Waiting for its day";
32
34
  export const keptAsIsWord = "Kept as is";
35
+ // A running run whose only movement is a step that failed on something time can fix (a rate
36
+ // limit, a dropped connection) and runs again by itself at a set time.
37
+ export const retryingWord = "Waiting to try again";
33
38
  export const heldStateWords = [
34
39
  heldWord,
35
40
  waitingForAgentWord,
@@ -38,15 +43,25 @@ export const heldStateWords = [
38
43
  keptAsIsWord,
39
44
  ];
40
45
  // A run that ran and is held: a waiting project with some of its run done (`progress` is the
41
- // run's share done, `progressOf`) or a step failed, or one stopped or parked on an agent's review
42
- // before it got going. One with none done that waits for neither is Queued, waiting its turn.
46
+ // run's share done, `progressOf`) or a step failed, one a checkpoint holds (it reached it with
47
+ // every step before it supplied), or one stopped or parked on an agent's review before it got
48
+ // going. One with none done that waits for none of these is Queued, waiting its turn.
43
49
  export function heldRun(project) {
44
50
  return (project.status === "pending" &&
45
51
  (project.progress > 0 ||
46
52
  project.stepFailed === true ||
53
+ (project.holding?.length ?? 0) > 0 ||
47
54
  project.stopped === true ||
48
55
  project.waitingForAgent === true));
49
56
  }
57
+ // When the run tries again by itself: the soonest wait of a step that failed on something time
58
+ // can fix, while no step runs. Undefined while one runs (the run reads Running) or none waits.
59
+ export function retryingAt(stages) {
60
+ if (stages.some((stage) => stage.state === "running"))
61
+ return undefined;
62
+ const waits = stages.flatMap((stage) => stage.state === "pending" && typeof stage.retryAt === "string" ? [stage.retryAt] : []);
63
+ return waits.toSorted()[0];
64
+ }
50
65
  // Whether the person is the one it waits for (to approve, or to Continue the run): not when it
51
66
  // is Kept as is, waits for an agent or for its scheduled day.
52
67
  function heldForPerson(project) {
@@ -78,9 +93,18 @@ export function runningNow(project) {
78
93
  export function queuedRun(project) {
79
94
  return project.status === "pending" && !heldRun(project);
80
95
  }
81
- // An uploaded project already reads "done" from the projects route (`uploadedAndSettled`).
96
+ // A settled project already reads "done" from the projects route (`settledProjects`). A
97
+ // running run that only waits to try a step again says so.
82
98
  export function projectStateWord(project) {
83
- return heldRun(project) ? heldStateWord(project) : projectStateWords[project.status];
99
+ if (heldRun(project))
100
+ return heldStateWord(project);
101
+ if (retryingRun(project))
102
+ return retryingWord;
103
+ return projectStateWords[project.status];
104
+ }
105
+ // Running, and the one thing it does is wait to try a failed step again at a set time.
106
+ export function retryingRun(project) {
107
+ return project.status === "running" && project.retryAt !== undefined;
84
108
  }
85
109
  // A run that ran and now waits for the person, held or paused: Home's Needs you, the Projects
86
110
  // "Needs you" filter and its waiting-first sort.
@@ -108,3 +132,8 @@ export function stepFailedWhileWaiting(status, stages) {
108
132
  export function failedRun(project) {
109
133
  return project.status === "failed" || project.stepFailed === true;
110
134
  }
135
+ // Everything a run asks of the person, the one set Home's Needs you lists and the Projects
136
+ // "Needs you" filter holds: a decision (approve, Continue the run, resume) or a failure to fix.
137
+ export function needsYou(project) {
138
+ return waitsForPerson(project) || failedRun(project);
139
+ }
@@ -2,6 +2,7 @@
2
2
  // name case-sensitive and free to hold anything but `{`, `}` and a newline (so
3
3
  // `{{Middle of Words}}` is one name). There is no escape syntax. Hand-rolled on purpose: a
4
4
  // template library would bring its own grammar.
5
+ import { keywordNames, legacyNames } from "../keywords/specs.js";
5
6
  export const slotLintKinds = ["unclosed", "empty", "nested"];
6
7
  export const fieldGroups = ["common", "text", "image"];
7
8
  // A well-formed slot: no brace and no newline between the delimiters.
@@ -38,16 +39,18 @@ export function detectSlots(body) {
38
39
  return { names, errors };
39
40
  }
40
41
  // Filled by Slopify, never by the person: each image's own scene, which the project's AI model
41
- // writes from the article when an image prompt asks for it (`images/scenes.ts`).
42
+ // writes from the article when an image prompt asks for it (`images/scenes.ts`). The old name
43
+ // of {{Slopify_Scene}}, which keeps its own meaning (`keywords/specs.ts`).
42
44
  export const sceneKeyword = "Scene";
43
45
  // Filled by Slopify too: how the video's subject and the characters in an image look, which the
44
46
  // project's AI model looks up on the web when a prompt asks for it (`images/appearance.ts`).
45
47
  export const appearanceKeyword = "Appearance";
46
- // The keywords Slopify fills itself, which are never fields for the person.
47
- export const filledKeywords = [sceneKeyword, appearanceKeyword];
48
+ // The keywords Slopify fills itself, which are never fields for the person: every `Slopify_`
49
+ // keyword and the two old names. An unknown `Slopify_` name is not one of them.
50
+ export const filledKeywords = [...keywordNames, ...legacyNames];
48
51
  // One field per distinct name; Common when a name is used on both sides, otherwise Text or
49
52
  // Image. The order is first appearance, which is why both sides arrive as ordered lists of
50
- // bodies rather than as sets. The scene and appearance keywords are not fields: Slopify fills them.
53
+ // bodies rather than as sets. The keywords Slopify fills are not fields.
51
54
  export function collectFields(textBodies, imageBodies) {
52
55
  const text = namesOf(textBodies);
53
56
  const image = namesOf(imageBodies);
@@ -0,0 +1,31 @@
1
+ import { projectById } from "../admission/repo.js";
2
+ import { platformLabels } from "../social/model.js";
3
+ import { postsIn } from "../social/repo.js";
4
+ // Posts the extension filled in a site's form, waiting for the person to press Post (or
5
+ // Schedule) there, and fills that stopped. Posting is the person's: an agent reports them.
6
+ export function postsWaiting(deps) {
7
+ return postsIn(deps.db, ["filled", "failed"]).flatMap((post) => {
8
+ const project = projectById(deps.db, post.projectId);
9
+ if (project === undefined)
10
+ return [];
11
+ const site = platformLabels[post.platform];
12
+ const filled = post.state === "filled";
13
+ return [
14
+ {
15
+ kind: filled ? "post-due" : "extension-failure",
16
+ since: (filled ? post.filledAt : post.updatedAt) ?? post.updatedAt ?? "",
17
+ projectId: post.projectId,
18
+ title: project.title,
19
+ stage: "video",
20
+ itemKey: `social:${post.platform}`,
21
+ reason: filled
22
+ ? `The ${site} post is filled in ${site}'s form and waits for the person to press Post there. Posting is the person's: report it.`
23
+ : `Filling the ${site} post failed: ${post.message ?? "the extension gave no reason."} Fixing it is the extension's or the person's: report it.`,
24
+ autoRetryInFlight: false,
25
+ agentCanAct: false,
26
+ ids: { projectId: post.projectId, platform: post.platform },
27
+ tools: ["get_post_packs"],
28
+ },
29
+ ];
30
+ });
31
+ }
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ import { notReadySentence } from "../template-studio/schedule-gate.js";
3
+ import { rowsOf } from "./attention-work.js";
4
+ const scheduleRow = z.object({ id: z.string(), name: z.string(), template_id: z.string() });
5
+ // An active schedule whose gated template has no version it may run skips every run until the
6
+ // person marks one ready: the agent reports it. The gate keeps no time it began, so it is dated
7
+ // when it is read.
8
+ export function templatesNotReady(db, now, skip, notReady = (id) => notReadySentence(db, id)) {
9
+ const rows = db
10
+ .prepare("SELECT id, name, template_id FROM schedules WHERE deleted_at IS NULL AND status='active' AND template_kind='project' ORDER BY lower(name), id")
11
+ .all();
12
+ return rowsOf(rows, "schedules", skip, (value) => {
13
+ const row = scheduleRow.parse(value);
14
+ const sentence = notReady(row.template_id);
15
+ return sentence === undefined
16
+ ? []
17
+ : [
18
+ {
19
+ kind: "template-not-ready",
20
+ since: now.toISOString(),
21
+ projectId: null,
22
+ title: row.name,
23
+ stage: null,
24
+ itemKey: null,
25
+ reason: `${sentence} Marking a version ready is the person's: report it.`,
26
+ autoRetryInFlight: false,
27
+ agentCanAct: false,
28
+ ids: { id: row.id, templateId: row.template_id },
29
+ tools: ["get_schedule", "get_template_checks"],
30
+ },
31
+ ];
32
+ });
33
+ }
@@ -4,7 +4,10 @@ import { liveProject } from "../admission/repo.js";
4
4
  import { externalReviewOf } from "../reviews/external-rows.js";
5
5
  import { waitingExternalReviewRows } from "../reviews/external-waiting.js";
6
6
  import { projectHolds } from "../reviews/holds.js";
7
+ import { templateSampleProjects } from "../template-studio/repo.js";
7
8
  import { setAsideProjects } from "../uploads/repo.js";
9
+ import { postsWaiting } from "./attention-posts.js";
10
+ import { templatesNotReady } from "./attention-templates.js";
8
11
  import { extensionFailures, failedSteps, heldTopics, lateUploads, pausedRuns, rowsOf, stoppedRuns, } from "./attention-work.js";
9
12
  export const attentionKinds = [
10
13
  "external-review",
@@ -16,6 +19,9 @@ export const attentionKinds = [
16
19
  "held-topics",
17
20
  "late-upload",
18
21
  "extension-failure",
22
+ "template-not-ready",
23
+ // A post filled in another site's form, waiting for the person to press Post (`slices/social`).
24
+ "post-due",
19
25
  ];
20
26
  const projectOf = z.object({ project_id: z.string() });
21
27
  // Oldest first. A project Kept as is waits for nobody, so none of its entries is listed. Each
@@ -47,8 +53,11 @@ export function needsAttention(deps, now) {
47
53
  ["held topics", () => heldTopics(db, skip)],
48
54
  ["late uploads", () => lateUploads(deps, now)],
49
55
  ["extension failures", () => extensionFailures(db, skip)],
56
+ ["templates not ready", () => templatesNotReady(db, now, skip, deps.notReady)],
57
+ ["posts", () => postsWaiting(deps)],
50
58
  ];
51
59
  const aside = setAsideProjects(db);
60
+ const samples = templateSampleProjects(db);
52
61
  return sources
53
62
  .flatMap(([source, entries]) => {
54
63
  try {
@@ -61,7 +70,7 @@ export function needsAttention(deps, now) {
61
70
  return [];
62
71
  }
63
72
  })
64
- .filter((entry) => entry.projectId === null || !aside.has(entry.projectId))
73
+ .filter((entry) => entry.projectId === null || (!aside.has(entry.projectId) && !samples.has(entry.projectId)))
65
74
  .toSorted((a, b) => a.since.localeCompare(b.since));
66
75
  }
67
76
  function titles(db) {
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { readSetting, writeSetting } from "../settings/repo.js";
2
+ import { readJsonSetting, writeSetting } from "../settings/repo.js";
3
3
  // When an agent last opened an MCP session. This install's own fact, so backups leave it out
4
4
  // (`storage/portable.ts`).
5
5
  export const agentConnectionKey = "agents.lastConnectedAt";
@@ -7,9 +7,5 @@ export function recordAgentConnection(db, at) {
7
7
  writeSetting(db, agentConnectionKey, JSON.stringify(at));
8
8
  }
9
9
  export function lastAgentConnection(db) {
10
- const raw = readSetting(db, agentConnectionKey);
11
- if (raw === undefined)
12
- return null;
13
- const parsed = z.iso.datetime().safeParse(JSON.parse(raw));
14
- return parsed.success ? parsed.data : null;
10
+ return readJsonSetting(db, agentConnectionKey, z.iso.datetime(), null);
15
11
  }
@@ -1,7 +1,10 @@
1
1
  import { z } from "zod";
2
- // Agents: an AI agent (Claude Code, Codex, ...) driving Slopify through its MCP endpoint.
3
- // Browser-safe: Settings → Connections → Agents (MCP) builds its setup lines from these.
4
- export const actors = ["person", "agent"];
2
+ // Agents: an AI agent (Claude Code, Codex, ...) driving Slopify through its MCP endpoint, and
3
+ // the in-app assistant, which drives it the same way from Slopify's own chat. Browser-safe:
4
+ // Settings → Connections → Agents (MCP) builds its setup lines from these.
5
+ export const actors = ["person", "agent", "assistant"];
6
+ // Who an MCP call recorded in `agent_actions` came from.
7
+ export const agentActors = ["agent", "assistant"];
5
8
  export const mcpPath = "/mcp";
6
9
  export function mcpUrl(origin) {
7
10
  return `${origin.replace(/\/+$/, "")}${mcpPath}`;
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { actors } from "./model.js";
2
+ import { actors, agentActors } from "./model.js";
3
3
  // ceiling: Settings shows the latest twenty; a project's own are in its history.
4
4
  export const recentAgentActionsMax = 20;
5
5
  const actionRow = z.object({
@@ -10,6 +10,7 @@ const actionRow = z.object({
10
10
  title: z.string(),
11
11
  revision_id: z.string().nullable(),
12
12
  created_at: z.string(),
13
+ actor: z.enum(agentActors),
13
14
  });
14
15
  function actionOf(value) {
15
16
  const row = actionRow.parse(value);
@@ -21,16 +22,17 @@ function actionOf(value) {
21
22
  title: row.title,
22
23
  revisionId: row.revision_id,
23
24
  createdAt: row.created_at,
25
+ actor: row.actor,
24
26
  };
25
27
  }
26
28
  // A project the call itself deleted for good is gone: the action is kept without it. A call
27
29
  // sent again with its idempotencyKey was answered with its first answer, so it adds no second
28
30
  // row (`agent_actions_once`); any other failure to record it is thrown.
29
31
  export function recordAgentAction(db, action, idempotencyKey) {
30
- db.prepare(`INSERT INTO agent_actions(id,project_id,schedule_id,tool,title,revision_id,created_at,idempotency_key)
31
- VALUES (?,(SELECT id FROM projects WHERE id=?),?,?,?,?,?,?)
32
+ db.prepare(`INSERT INTO agent_actions(id,project_id,schedule_id,tool,title,revision_id,created_at,idempotency_key,actor)
33
+ VALUES (?,(SELECT id FROM projects WHERE id=?),?,?,?,?,?,?,?)
32
34
  ON CONFLICT(tool,COALESCE(project_id,''),idempotency_key) WHERE idempotency_key IS NOT NULL
33
- DO NOTHING`).run(action.id, action.projectId, action.scheduleId, action.tool, action.title, action.revisionId, action.createdAt, idempotencyKey ?? null);
35
+ DO NOTHING`).run(action.id, action.projectId, action.scheduleId, action.tool, action.title, action.revisionId, action.createdAt, idempotencyKey ?? null, action.actor);
34
36
  }
35
37
  export function agentActionsOf(db, projectId) {
36
38
  return db
@@ -38,12 +40,18 @@ export function agentActionsOf(db, projectId) {
38
40
  .all(projectId)
39
41
  .map(actionOf);
40
42
  }
41
- export function agentRevisionIds(db, projectId) {
43
+ function revisionIdsBy(db, projectId, actor) {
42
44
  return new Set(db
43
- .prepare("SELECT DISTINCT revision_id FROM agent_actions WHERE project_id=? AND revision_id IS NOT NULL")
44
- .all(projectId)
45
+ .prepare("SELECT DISTINCT revision_id FROM agent_actions WHERE project_id=? AND actor=? AND revision_id IS NOT NULL")
46
+ .all(projectId, actor)
45
47
  .map((row) => String(row.revision_id)));
46
48
  }
49
+ export function agentRevisionIds(db, projectId) {
50
+ return revisionIdsBy(db, projectId, "agent");
51
+ }
52
+ export function assistantRevisionIds(db, projectId) {
53
+ return revisionIdsBy(db, projectId, "assistant");
54
+ }
47
55
  export function recentAgentActions(db) {
48
56
  return db
49
57
  .prepare(`SELECT a.*, COALESCE(p.title, s.name) AS subject FROM agent_actions a
@@ -1,9 +1,5 @@
1
- import { noTokens, plusUsage } from "../telemetry/model.js";
2
1
  // At most 3 continuations; still unfinished after the third is a failed attempt.
3
2
  export const continuationLimit = 3;
4
- // The provider's own word for "I stopped because I ran out of room", which is what every
5
- // adapter maps its finish reason to (`kernel/ports/llm.ts`).
6
- const truncatedReason = "length";
7
3
  // A fixed 'Research notes' header followed by the notes, then the rendered article prompt;
8
4
  // without research, the rendered prompt alone. One user message, and no parameters of the app's
9
5
  // own: the provider's defaults are used.
@@ -35,62 +31,3 @@ export function continuationMessages(base, soFar) {
35
31
  },
36
32
  ];
37
33
  }
38
- export async function writeArticle(providers, choice, brief, onDelta) {
39
- const base = articleMessages(brief);
40
- const sent = [{ label: "Article", messages: base }];
41
- const stream = (event) => {
42
- if (event.type === "delta") {
43
- onDelta(event.text);
44
- }
45
- };
46
- let result = await providers.llm({
47
- provider: choice.provider,
48
- model: choice.model,
49
- ...(choice.thinking === undefined ? {} : { thinking: choice.thinking }),
50
- messages: base,
51
- check: written,
52
- }, stream);
53
- if (!result.ok)
54
- return result;
55
- let answer = result.value;
56
- const pieces = [answer.text];
57
- let tokens = plusUsage(noTokens, answer.usage);
58
- for (let n = 1; truncated(answer) && n <= continuationLimit; n += 1) {
59
- const messages = continuationMessages(base, pieces.join(""));
60
- sent.push({ label: `Continuation ${String(n)}`, messages });
61
- result = await providers.llm({
62
- provider: choice.provider,
63
- model: choice.model,
64
- ...(choice.thinking === undefined ? {} : { thinking: choice.thinking }),
65
- messages,
66
- // The last continuation allowed is the one that has to end the article: a fourth
67
- // truncation is a failed attempt, which is the wrapper's to retry. The
68
- // loop therefore never sees a truncated answer with its budget spent.
69
- check: n === continuationLimit ? finished : written,
70
- }, stream);
71
- if (!result.ok)
72
- return result;
73
- answer = result.value;
74
- pieces.push(answer.text);
75
- tokens = plusUsage(tokens, answer.usage);
76
- }
77
- return { ok: true, value: { markdown: pieces.join(""), sent, tokens } };
78
- }
79
- function truncated(answer) {
80
- return answer.finishReason === truncatedReason;
81
- }
82
- // Empty response → failed attempt.
83
- function written(answer) {
84
- return answer.text.trim() === ""
85
- ? "The AI model returned an empty article. Try again; if it keeps happening, choose a different model in Edit project → Providers."
86
- : undefined;
87
- }
88
- function finished(answer) {
89
- const empty = written(answer);
90
- if (empty !== undefined) {
91
- return empty;
92
- }
93
- return truncated(answer)
94
- ? `The article was still unfinished after ${String(continuationLimit)} continuations because the AI model kept stopping at its length limit. Ask for a shorter article in Edit project → Prompts, or choose a model with a larger output limit in Edit project → Providers, then Try again.`
95
- : undefined;
96
- }
@@ -1,6 +1,7 @@
1
1
  import { remark } from "remark";
2
2
  import remarkGfm from "remark-gfm";
3
3
  import stripMarkdown from "strip-markdown";
4
+ import { internalError } from "../../kernel/errors.js";
4
5
  // ceiling: conversions remembered. The same article is converted again every time a run plans
5
6
  // its work, which is several times a step; a long article took seconds each time, on the
6
7
  // thread that answers the page. The oldest goes first.
@@ -26,11 +27,11 @@ function convert(markdown) {
26
27
  const paragraphs = tree.children
27
28
  .map((node) => {
28
29
  if (node.type !== "paragraph")
29
- throw new Error("Slopify hit an internal error (the article couldn't be turned into plain text). Try again; if it happens again, use Download diagnostics in Settings and report it.");
30
+ throw new Error(internalError("the article couldn't be turned into plain text"));
30
31
  return node.children
31
32
  .map((child) => {
32
33
  if (child.type !== "text")
33
- throw new Error("Slopify hit an internal error (the article couldn't be turned into plain text). Try again; if it happens again, use Download diagnostics in Settings and report it.");
34
+ throw new Error(internalError("the article couldn't be turned into plain text"));
34
35
  return child.value;
35
36
  })
36
37
  .join("");
@@ -1,41 +1,6 @@
1
- import { insertPiece, piecesOf, setPiece } from "../../kernel/runner/piece-repo.js";
2
1
  import { subjectOf } from "../admission/model.js";
3
- import { noTokens, plusUsage } from "../telemetry/model.js";
4
- export const categories = ["intro", "outro"];
5
- export async function writeSegment(providers, choice, config, category, article, sent) {
6
- const picked = config[category];
7
- if (picked === undefined)
8
- return { ok: true, value: undefined };
9
- const body = config.rendered[category];
10
- if (body === undefined)
11
- throw new Error(`Slopify hit an internal error (the ${category} text was never filled in). Try again; if it happens again, use Download diagnostics in Settings and report it.`);
12
- const common = { category, name: picked.name, mode: picked.mode };
13
- if (picked.mode === "text")
14
- return { ok: true, value: { ...common, text: body, tokens: noTokens } };
15
- if (choice === undefined)
16
- throw new Error(`No AI model is set for writing the ${category}. Choose one in Edit project → Providers, then Try again.`);
17
- const messages = segmentMessages(body, config, article);
18
- sent.push({ label: category === "intro" ? "Intro" : "Outro", messages });
19
- const answer = await providers.llm({
20
- provider: choice.provider,
21
- model: choice.model,
22
- ...(choice.thinking === undefined ? {} : { thinking: choice.thinking }),
23
- messages,
24
- check: (given) => given.text.trim() === ""
25
- ? `The AI model returned an empty ${category}. Try again; if it keeps happening, choose a different model in Edit project → Providers.`
26
- : undefined,
27
- });
28
- if (!answer.ok)
29
- return answer;
30
- return {
31
- ok: true,
32
- value: {
33
- ...common,
34
- text: answer.value.text.trim(),
35
- tokens: plusUsage(noTokens, answer.value.usage),
36
- },
37
- };
38
- }
2
+ // The message an intro or outro is written from by the text model: its prompt, the title, the
3
+ // run's keywords and the article's plain text (`rebuild/recipe-text.ts`).
39
4
  export function segmentMessages(body, config, article) {
40
5
  const values = Object.entries(config.values);
41
6
  return [
@@ -59,28 +24,3 @@ export function segmentMessages(body, config, article) {
59
24
  },
60
25
  ];
61
26
  }
62
- export function keepSegment(deps, context, segment, idx) {
63
- const payload = JSON.stringify({
64
- category: segment.category,
65
- name: segment.name,
66
- mode: segment.mode,
67
- text: segment.text,
68
- });
69
- const existing = piecesOf(deps.db, context.stage.id, "segment").find((piece) => piece.idx === idx);
70
- if (existing === undefined) {
71
- insertPiece(deps.db, {
72
- id: deps.ids.next(),
73
- stageId: context.stage.id,
74
- kind: "segment",
75
- idx,
76
- state: "done",
77
- payload,
78
- });
79
- }
80
- else
81
- setPiece(deps.db, existing.id, "done", payload);
82
- }
83
- export function instructionsText(sent) {
84
- const parts = sent.map((one) => `=== ${one.label} ===\n\n${one.messages.map((message) => message.content).join("\n\n")}`);
85
- return `${parts.join("\n\n")}\n`;
86
- }
@@ -0,0 +1 @@
1
+ export {};