videobook 0.0.0-stage → 0.2.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 (565) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/LICENSE +21 -0
  3. package/README.md +195 -2
  4. package/bin/videobook.js +7 -0
  5. package/dist/acestep/client.js +203 -0
  6. package/dist/acestep/config.js +62 -0
  7. package/dist/acestep/errors.js +8 -0
  8. package/dist/acestep/process.js +175 -0
  9. package/dist/alive-captions/analyze.js +117 -0
  10. package/dist/alive-captions/audio.js +179 -0
  11. package/dist/alive-captions/frames.js +59 -0
  12. package/dist/alive-captions/model.js +37 -0
  13. package/dist/alive-captions/schema.js +49 -0
  14. package/dist/alive-captions/track.js +9 -0
  15. package/dist/api-key.js +33 -0
  16. package/dist/app-state.js +56 -0
  17. package/dist/app.js +257 -0
  18. package/dist/archive-b2.js +332 -0
  19. package/dist/archive-store.js +169 -0
  20. package/dist/artifact-label.js +36 -0
  21. package/dist/artifact-refs.js +49 -0
  22. package/dist/asset-tag-extraction.js +169 -0
  23. package/dist/asset-tags.js +228 -0
  24. package/dist/asset-usage.js +23 -0
  25. package/dist/audio-cue.js +71 -0
  26. package/dist/audio-encoding.js +32 -0
  27. package/dist/audio-sync-request.js +1 -0
  28. package/dist/audio-sync.js +223 -0
  29. package/dist/audio-trim-range.js +31 -0
  30. package/dist/book-context.js +31 -0
  31. package/dist/book-manager.js +374 -0
  32. package/dist/catalog-gc.js +26 -0
  33. package/dist/chain-executor.js +815 -0
  34. package/dist/chain-generation.js +115 -0
  35. package/dist/chain-plan.js +746 -0
  36. package/dist/chain-step-review.js +60 -0
  37. package/dist/character-name.js +25 -0
  38. package/dist/chat-generation-routing.js +73 -0
  39. package/dist/chat-generation-settings.js +78 -0
  40. package/dist/chat-models.js +44 -0
  41. package/dist/chat-prompt-rewrite.js +67 -0
  42. package/dist/chat-router.js +628 -0
  43. package/dist/chat-view-actions.js +49 -0
  44. package/dist/cli/args.js +242 -0
  45. package/dist/cli/config-command.js +103 -0
  46. package/dist/cli/doctor-command.js +289 -0
  47. package/dist/cli/entry.js +2 -0
  48. package/dist/cli/key-report.js +16 -0
  49. package/dist/cli/main.js +104 -0
  50. package/dist/cli/mcp-command.js +88 -0
  51. package/dist/cli/mcp-relay.js +51 -0
  52. package/dist/cli/open-browser.js +14 -0
  53. package/dist/cli/run-command.js +231 -0
  54. package/dist/cli/serve-command.js +62 -0
  55. package/dist/cli/setup-command.js +60 -0
  56. package/dist/cli/stdio-guard.js +8 -0
  57. package/dist/cold-open-model.js +7 -0
  58. package/dist/cold-open.js +79 -0
  59. package/dist/command-reference.js +95 -0
  60. package/dist/content-store.js +74 -0
  61. package/dist/cost.js +8 -0
  62. package/dist/crop-geometry.js +23 -0
  63. package/dist/dancing-workflow.js +447 -0
  64. package/dist/data-home.js +44 -0
  65. package/dist/diagnostics.js +109 -0
  66. package/dist/dialog-quality.js +34 -0
  67. package/dist/downloads-dest.js +56 -0
  68. package/dist/editing-moments.js +194 -0
  69. package/dist/elevenlabs-audio-extension.js +66 -0
  70. package/dist/engine.js +54 -0
  71. package/dist/env-file.js +91 -0
  72. package/dist/env-secrets.js +148 -0
  73. package/dist/ffmpeg-binary.js +12 -0
  74. package/dist/ffmpeg.js +425 -0
  75. package/dist/ffprobe-binary.js +77 -0
  76. package/dist/forget-asset.js +216 -0
  77. package/dist/frame-utils.js +27 -0
  78. package/dist/generation-credit-error.js +11 -0
  79. package/dist/generation-input-mentions.js +117 -0
  80. package/dist/generation-input-policy.js +68 -0
  81. package/dist/generation-reference-mentions.js +97 -0
  82. package/dist/goal-characters.js +49 -0
  83. package/dist/goal-plan-v3.js +273 -0
  84. package/dist/goal-plan.js +220 -0
  85. package/dist/goal-planner-prompt.js +28 -0
  86. package/dist/goal-prompt-budget.js +4 -0
  87. package/dist/goal-reference-images.js +25 -0
  88. package/dist/goal-state.js +261 -0
  89. package/dist/goal-stills.js +153 -0
  90. package/dist/goal-store.js +144 -0
  91. package/dist/goal-styles.js +144 -0
  92. package/dist/goal-v3-runtime.js +157 -0
  93. package/dist/guides/character_schema_guide.md +70 -0
  94. package/dist/guides/gpt_image_2_5_prompting_guide.md +21 -0
  95. package/dist/guides/grok_imagine_prompting_guide.md +72 -0
  96. package/dist/guides/image_reproduction_guide.md +84 -0
  97. package/dist/guides/kling_3_0_prompting_guide.md +136 -0
  98. package/dist/guides/nano_banana_pro_prompting_guide.md +28 -0
  99. package/dist/guides/seedance_2_prompting_guide.md +172 -0
  100. package/dist/http-access.js +49 -0
  101. package/dist/http-byte-range.js +31 -0
  102. package/dist/hydration.js +56 -0
  103. package/dist/image-compress.js +77 -0
  104. package/dist/image-edit-default.js +1 -0
  105. package/dist/image-edit-models.js +41 -0
  106. package/dist/image-edit-settings.js +11 -0
  107. package/dist/image-region-edit.js +32 -0
  108. package/dist/image-subject-map.js +523 -0
  109. package/dist/image.js +46 -0
  110. package/dist/index.js +12 -0
  111. package/dist/job-deadline.js +60 -0
  112. package/dist/jobs/_alibaba-upload.js +30 -0
  113. package/dist/jobs/_audio-chunks.js +31 -0
  114. package/dist/jobs/_download-into-asset.js +15 -0
  115. package/dist/jobs/_fal-shared.js +22 -0
  116. package/dist/jobs/_fal-upload.js +35 -0
  117. package/dist/jobs/_image-edit-adapter.js +213 -0
  118. package/dist/jobs/_kie-poll.js +119 -0
  119. package/dist/jobs/_kie-upload.js +32 -0
  120. package/dist/jobs/_lease.js +163 -0
  121. package/dist/jobs/_persist-output.js +19 -0
  122. package/dist/jobs/_storage-retry.js +21 -0
  123. package/dist/jobs/_transcribe.js +245 -0
  124. package/dist/jobs/_translate-transcript.js +270 -0
  125. package/dist/jobs/analyze-alive-captions.js +10 -0
  126. package/dist/jobs/analyze-editing-moments.js +104 -0
  127. package/dist/jobs/analyze-jokes.js +143 -0
  128. package/dist/jobs/analyze-keyword-placement.js +155 -0
  129. package/dist/jobs/analyze-music.js +14 -0
  130. package/dist/jobs/analyze-video.js +282 -0
  131. package/dist/jobs/apply-cuts.js +83 -0
  132. package/dist/jobs/apply-sfx.js +107 -0
  133. package/dist/jobs/archive-clip.js +458 -0
  134. package/dist/jobs/assemble-goal.js +98 -0
  135. package/dist/jobs/audio-boost.js +71 -0
  136. package/dist/jobs/audio-mix.js +161 -0
  137. package/dist/jobs/backfill-asset-tags.js +144 -0
  138. package/dist/jobs/burn-watermark.js +316 -0
  139. package/dist/jobs/change-video-speed.js +176 -0
  140. package/dist/jobs/clean-video-audio.js +207 -0
  141. package/dist/jobs/cold-open.js +166 -0
  142. package/dist/jobs/combine-goal.js +108 -0
  143. package/dist/jobs/complete-provider-task.js +185 -0
  144. package/dist/jobs/copy-library-asset.js +33 -0
  145. package/dist/jobs/cost-estimate-assessment.js +113 -0
  146. package/dist/jobs/crop-image.js +47 -0
  147. package/dist/jobs/crop-video.js +71 -0
  148. package/dist/jobs/describe-image.js +181 -0
  149. package/dist/jobs/detect-scenes.js +33 -0
  150. package/dist/jobs/doctor-fix.js +100 -0
  151. package/dist/jobs/download-video.js +427 -0
  152. package/dist/jobs/enqueue-search-index.js +24 -0
  153. package/dist/jobs/even-split.js +122 -0
  154. package/dist/jobs/export-sequence.js +365 -0
  155. package/dist/jobs/extend-audio.js +229 -0
  156. package/dist/jobs/extract-audio.js +72 -0
  157. package/dist/jobs/extract-frame.js +58 -0
  158. package/dist/jobs/extract-notebook-audio.js +82 -0
  159. package/dist/jobs/extract-notebook-frame.js +93 -0
  160. package/dist/jobs/extract-video-clip.js +8 -0
  161. package/dist/jobs/extract-video-poster.js +55 -0
  162. package/dist/jobs/extract-waveform.js +25 -0
  163. package/dist/jobs/finish-goal.js +255 -0
  164. package/dist/jobs/forget-asset.js +11 -0
  165. package/dist/jobs/generate-acestep-cover.js +219 -0
  166. package/dist/jobs/generate-media.js +70 -0
  167. package/dist/jobs/image-subjects.js +1059 -0
  168. package/dist/jobs/index.js +18 -0
  169. package/dist/jobs/inject-first-frame.js +175 -0
  170. package/dist/jobs/isolate-vocals.js +69 -0
  171. package/dist/jobs/kie-paygate.js +177 -0
  172. package/dist/jobs/label-music-sections.js +5 -0
  173. package/dist/jobs/osg-placement.js +135 -0
  174. package/dist/jobs/pad-video.js +72 -0
  175. package/dist/jobs/plan-goal.js +97 -0
  176. package/dist/jobs/post-record.js +21 -0
  177. package/dist/jobs/post-to-x.js +21 -0
  178. package/dist/jobs/prepare-search-reference.js +190 -0
  179. package/dist/jobs/prepare-temporal-search.js +16 -0
  180. package/dist/jobs/process-audio.js +67 -0
  181. package/dist/jobs/process-image.js +58 -0
  182. package/dist/jobs/process-upload.js +166 -0
  183. package/dist/jobs/process-video.js +438 -0
  184. package/dist/jobs/register-all.js +161 -0
  185. package/dist/jobs/relayout-notebook.js +78 -0
  186. package/dist/jobs/remove-sound.js +299 -0
  187. package/dist/jobs/render-project.js +380 -0
  188. package/dist/jobs/render-qr-outro.js +138 -0
  189. package/dist/jobs/render-timeline.js +283 -0
  190. package/dist/jobs/repair-search-indexes.js +42 -0
  191. package/dist/jobs/replace-video-audio.js +64 -0
  192. package/dist/jobs/restore-archive-clip.js +53 -0
  193. package/dist/jobs/reverse-video.js +53 -0
  194. package/dist/jobs/rewrite-script.js +173 -0
  195. package/dist/jobs/run-notebook.js +3335 -0
  196. package/dist/jobs/semantic-index.js +797 -0
  197. package/dist/jobs/smooth-scene-concat.js +257 -0
  198. package/dist/jobs/splice-video.js +280 -0
  199. package/dist/jobs/split-video.js +127 -0
  200. package/dist/jobs/suggest-cuts.js +149 -0
  201. package/dist/jobs/suggest-sfx.js +135 -0
  202. package/dist/jobs/sync-video-to-audio.js +329 -0
  203. package/dist/jobs/tag-asset.js +266 -0
  204. package/dist/jobs/task-failure.js +16 -0
  205. package/dist/jobs/timewarp-video.js +152 -0
  206. package/dist/jobs/transcribe-video-audio.js +117 -0
  207. package/dist/jobs/transcribe.js +35 -0
  208. package/dist/jobs/translate-transcript.js +55 -0
  209. package/dist/jobs/trim-audio.js +133 -0
  210. package/dist/jobs/trim-video.js +291 -0
  211. package/dist/jobs/xai-paygate.js +26 -0
  212. package/dist/keyword-placement-cache.js +74 -0
  213. package/dist/lazy-render.js +142 -0
  214. package/dist/library-browse.js +78 -0
  215. package/dist/lightning-defaults.js +206 -0
  216. package/dist/load-env.js +12 -0
  217. package/dist/local-search-models.js +206 -0
  218. package/dist/local-upload.js +318 -0
  219. package/dist/logger.js +69 -0
  220. package/dist/media/adapters/alibaba.js +20 -0
  221. package/dist/media/adapters/elevenlabs.js +58 -0
  222. package/dist/media/adapters/fal.js +45 -0
  223. package/dist/media/adapters/index.js +26 -0
  224. package/dist/media/adapters/kie.js +120 -0
  225. package/dist/media/adapters/pending.js +21 -0
  226. package/dist/media/adapters/types.js +5 -0
  227. package/dist/media/adapters/xai.js +18 -0
  228. package/dist/media/catalog.js +236 -0
  229. package/dist/media/complete.js +191 -0
  230. package/dist/media/cost.js +45 -0
  231. package/dist/media/descriptor.js +157 -0
  232. package/dist/media/endpoints.js +11 -0
  233. package/dist/media/frame-options.js +18 -0
  234. package/dist/media/insert-video-timing.js +17 -0
  235. package/dist/media/json-schema.js +75 -0
  236. package/dist/media/legacy-task-types.js +129 -0
  237. package/dist/media/listing.js +24 -0
  238. package/dist/media/model-id.js +14 -0
  239. package/dist/media/preview.js +86 -0
  240. package/dist/media/prompt-dialects.js +65 -0
  241. package/dist/media/ref-fields.js +106 -0
  242. package/dist/media/refs.js +131 -0
  243. package/dist/media/request.js +188 -0
  244. package/dist/media/types.js +6 -0
  245. package/dist/media/wire.js +161 -0
  246. package/dist/media-library.js +535 -0
  247. package/dist/media-output-path.js +33 -0
  248. package/dist/multyculty-workflow.js +757 -0
  249. package/dist/notebook-action-catalog.js +608 -0
  250. package/dist/notebook-cell-outputs.js +726 -0
  251. package/dist/notebook-credit-retry.js +45 -0
  252. package/dist/notebook-fixtures.js +8 -0
  253. package/dist/notebook-generation-contract.js +77 -0
  254. package/dist/notebook-generation-controls.js +145 -0
  255. package/dist/notebook-goal-layout.js +40 -0
  256. package/dist/notebook-graph.js +37 -0
  257. package/dist/notebook-image-edit.js +84 -0
  258. package/dist/notebook-initial-generation-prompt.js +222 -0
  259. package/dist/notebook-live-analysis.js +941 -0
  260. package/dist/notebook-media-ops.js +579 -0
  261. package/dist/notebook-mutations.js +20 -0
  262. package/dist/notebook-placement.js +41 -0
  263. package/dist/notebook-provider-failure.js +87 -0
  264. package/dist/notebook-published-post.js +26 -0
  265. package/dist/notebook-reference-resolver.js +227 -0
  266. package/dist/notebook-relayout.js +270 -0
  267. package/dist/notebook-run-plan.js +519 -0
  268. package/dist/notebook-shots.js +162 -0
  269. package/dist/notebook-workflow.js +856 -0
  270. package/dist/one-password.js +200 -0
  271. package/dist/openai-intelligence.js +99 -0
  272. package/dist/original-media-file.js +12 -0
  273. package/dist/osg-assets.js +36 -0
  274. package/dist/osg-placement-cache.js +64 -0
  275. package/dist/osg-settings.js +27 -0
  276. package/dist/paid-tools.js +22 -0
  277. package/dist/platform-guidance.js +26 -0
  278. package/dist/posts/dropbox-auth.js +91 -0
  279. package/dist/posts/dropbox-upload.js +132 -0
  280. package/dist/posts/icloud-drive.js +134 -0
  281. package/dist/posts/icloud-status.js +64 -0
  282. package/dist/posts/post-contract.js +2 -0
  283. package/dist/posts/post-copy-format.js +43 -0
  284. package/dist/posts/post-copy.js +193 -0
  285. package/dist/posts/post-folder.js +18 -0
  286. package/dist/posts/post-metrics.js +119 -0
  287. package/dist/posts/post-store.js +340 -0
  288. package/dist/posts/x-post-target.js +43 -0
  289. package/dist/preview-payload.js +90 -0
  290. package/dist/prompt-surfaces.js +22 -0
  291. package/dist/provider-prompt-transform.js +77 -0
  292. package/dist/provider-status-link.js +21 -0
  293. package/dist/provider-task-record.js +78 -0
  294. package/dist/provider-task-status.js +47 -0
  295. package/dist/provider-usage.js +294 -0
  296. package/dist/queue.js +810 -0
  297. package/dist/reference-video-duration.js +17 -0
  298. package/dist/remotion/BlurFillVideo.js +51 -0
  299. package/dist/remotion/KeywordGraphicsOverlay.js +68 -0
  300. package/dist/remotion/OsgOverlay.js +30 -0
  301. package/dist/remotion/QrOutroComposition.js +47 -0
  302. package/dist/remotion/RenderComposition.js +11 -0
  303. package/dist/remotion/browser.js +59 -0
  304. package/dist/remotion/constants.js +35 -0
  305. package/dist/remotion/index.js +66 -0
  306. package/dist/remotion/keyword-graphics.js +151 -0
  307. package/dist/remotion/keyword-placement.js +182 -0
  308. package/dist/remotion/osg-spec.js +198 -0
  309. package/dist/remotion/public/qr-outro-impact.wav +0 -0
  310. package/dist/remotion/qr-outro-audio.js +1 -0
  311. package/dist/remotion/qr-outro-spec.js +211 -0
  312. package/dist/remotion/shared-bundle.js +37 -0
  313. package/dist/remotion/subtitles/AliveCaptions.js +83 -0
  314. package/dist/remotion/subtitles/Highlight.js +58 -0
  315. package/dist/remotion/subtitles/Impact.js +67 -0
  316. package/dist/remotion/subtitles/SubtitleOverlay.js +9 -0
  317. package/dist/remotion/subtitles/alive-layout.js +321 -0
  318. package/dist/remotion/subtitles/alive-types.js +17 -0
  319. package/dist/remotion/subtitles/chunker.js +68 -0
  320. package/dist/remotion/subtitles/segments.js +42 -0
  321. package/dist/remotion/subtitles/styles.js +4 -0
  322. package/dist/remotion/subtitles/types.js +1 -0
  323. package/dist/remotion/util.js +18 -0
  324. package/dist/remotion-cancellation.js +15 -0
  325. package/dist/rename-helpers.js +204 -0
  326. package/dist/rhythm/analyze.js +128 -0
  327. package/dist/rhythm/contract.js +14 -0
  328. package/dist/rhythm/draft-model.js +19 -0
  329. package/dist/rhythm/energy.js +133 -0
  330. package/dist/rhythm/fft.js +44 -0
  331. package/dist/rhythm/model.js +71 -0
  332. package/dist/rhythm/music-analysis.js +124 -0
  333. package/dist/rhythm/music-draft.js +261 -0
  334. package/dist/rhythm/onset.js +101 -0
  335. package/dist/rhythm/run-worker.js +51 -0
  336. package/dist/rhythm/score.js +47 -0
  337. package/dist/rhythm/section-labels.js +168 -0
  338. package/dist/rhythm/sequence-rhythm.js +67 -0
  339. package/dist/rhythm/synthesize.js +103 -0
  340. package/dist/rhythm/timing.js +98 -0
  341. package/dist/rhythm/track.js +320 -0
  342. package/dist/rhythm/visual-fit.js +4 -0
  343. package/dist/rhythm/worker.js +25 -0
  344. package/dist/scene-detect.js +200 -0
  345. package/dist/scene-transition.js +12 -0
  346. package/dist/scheduled-posts.js +200 -0
  347. package/dist/search-index-coverage.js +13 -0
  348. package/dist/search-index-media.js +71 -0
  349. package/dist/search-reference-store.js +60 -0
  350. package/dist/search-scoring.js +17 -0
  351. package/dist/serve.js +125 -0
  352. package/dist/server-lock.js +143 -0
  353. package/dist/server.js +42 -0
  354. package/dist/srt.js +16 -0
  355. package/dist/tag-backfill-state.js +121 -0
  356. package/dist/tag-settings.js +30 -0
  357. package/dist/tag-vocabulary.js +237 -0
  358. package/dist/test-queue-cleanup.js +1 -0
  359. package/dist/time-parse.js +50 -0
  360. package/dist/timeline-helpers.js +554 -0
  361. package/dist/timewarp.js +87 -0
  362. package/dist/tools/_image-inputs.js +9 -0
  363. package/dist/tools/_media-refs.js +84 -0
  364. package/dist/tools/_shared.js +59 -0
  365. package/dist/tools/_suggest-shared.js +279 -0
  366. package/dist/tools/add-timeline-audio.js +73 -0
  367. package/dist/tools/alive-captions.js +157 -0
  368. package/dist/tools/analyze-jokes.js +56 -0
  369. package/dist/tools/analyze-video.js +66 -0
  370. package/dist/tools/animate-keywords.js +217 -0
  371. package/dist/tools/api-status.js +42 -0
  372. package/dist/tools/application-commands.js +34 -0
  373. package/dist/tools/apply-cuts.js +112 -0
  374. package/dist/tools/apply-sfx.js +152 -0
  375. package/dist/tools/apply-watermark.js +670 -0
  376. package/dist/tools/archive-clip.js +74 -0
  377. package/dist/tools/asset-history.js +61 -0
  378. package/dist/tools/asset-manifest.js +24 -0
  379. package/dist/tools/asset-tags.js +151 -0
  380. package/dist/tools/assign-slot.js +97 -0
  381. package/dist/tools/audio-boost.js +107 -0
  382. package/dist/tools/audio-mix.js +121 -0
  383. package/dist/tools/book-usage.js +16 -0
  384. package/dist/tools/chain.js +136 -0
  385. package/dist/tools/change-video-speed.js +105 -0
  386. package/dist/tools/chat-history.js +5 -0
  387. package/dist/tools/chat.js +848 -0
  388. package/dist/tools/clean-video-audio.js +97 -0
  389. package/dist/tools/clear-failed-tasks.js +66 -0
  390. package/dist/tools/cold-open.js +114 -0
  391. package/dist/tools/command-plan.js +1680 -0
  392. package/dist/tools/commands.js +1666 -0
  393. package/dist/tools/concat-images.js +236 -0
  394. package/dist/tools/connect-service.js +55 -0
  395. package/dist/tools/copy-file-to-clipboard.js +58 -0
  396. package/dist/tools/create-character.js +114 -0
  397. package/dist/tools/create-qart.js +253 -0
  398. package/dist/tools/create-qr-outro.js +149 -0
  399. package/dist/tools/create-qrbtf.js +215 -0
  400. package/dist/tools/create-watermark.js +97 -0
  401. package/dist/tools/crop-asset.js +18 -0
  402. package/dist/tools/crop-image.js +120 -0
  403. package/dist/tools/crop-video.js +97 -0
  404. package/dist/tools/delete-asset.js +104 -0
  405. package/dist/tools/describe-image.js +69 -0
  406. package/dist/tools/detect-scenes.js +44 -0
  407. package/dist/tools/doctor.js +126 -0
  408. package/dist/tools/download-video.js +114 -0
  409. package/dist/tools/duplicate-asset.js +184 -0
  410. package/dist/tools/edit-timeline.js +59 -0
  411. package/dist/tools/editing-moments.js +105 -0
  412. package/dist/tools/estimate-cost.js +171 -0
  413. package/dist/tools/even-split.js +295 -0
  414. package/dist/tools/export-asset-file.js +22 -0
  415. package/dist/tools/export-asset.js +140 -0
  416. package/dist/tools/export-sequence.js +250 -0
  417. package/dist/tools/export-to-downloads.js +54 -0
  418. package/dist/tools/export-transcript-srt.js +79 -0
  419. package/dist/tools/extend-audio.js +100 -0
  420. package/dist/tools/extract-audio.js +174 -0
  421. package/dist/tools/extract-frame.js +108 -0
  422. package/dist/tools/extract-notebook-audio.js +173 -0
  423. package/dist/tools/extract-notebook-frame.js +160 -0
  424. package/dist/tools/extract-video-clip.js +101 -0
  425. package/dist/tools/generate-media.js +157 -0
  426. package/dist/tools/generation-payload.js +48 -0
  427. package/dist/tools/get-timeline.js +12 -0
  428. package/dist/tools/get-watermark-config.js +38 -0
  429. package/dist/tools/goal.js +644 -0
  430. package/dist/tools/image-subjects.js +711 -0
  431. package/dist/tools/index.js +323 -0
  432. package/dist/tools/inject-first-frame.js +154 -0
  433. package/dist/tools/invert-image.js +70 -0
  434. package/dist/tools/isolate-vocals.js +66 -0
  435. package/dist/tools/list-assets.js +98 -0
  436. package/dist/tools/list-cell-generations.js +225 -0
  437. package/dist/tools/list-elevenlabs-voices.js +163 -0
  438. package/dist/tools/log-wrapper.js +29 -0
  439. package/dist/tools/make-cover-song.js +95 -0
  440. package/dist/tools/mark-asset-seen.js +23 -0
  441. package/dist/tools/media-library.js +245 -0
  442. package/dist/tools/move-timeline-audio.js +35 -0
  443. package/dist/tools/music-analysis.js +60 -0
  444. package/dist/tools/music-draft.js +29 -0
  445. package/dist/tools/pad-video.js +87 -0
  446. package/dist/tools/post-record.js +83 -0
  447. package/dist/tools/post.js +168 -0
  448. package/dist/tools/prompt-history.js +164 -0
  449. package/dist/tools/provider-key-status.js +248 -0
  450. package/dist/tools/qrbtf-render.js +849 -0
  451. package/dist/tools/read-asset-metadata.js +26 -0
  452. package/dist/tools/read-file-at-commit.js +29 -0
  453. package/dist/tools/read-transcript.js +41 -0
  454. package/dist/tools/reconcile-project-work.js +1452 -0
  455. package/dist/tools/recover-asset.js +28 -0
  456. package/dist/tools/remove-sound.js +72 -0
  457. package/dist/tools/remove-timeline-audio.js +34 -0
  458. package/dist/tools/remove-timeline-slot.js +40 -0
  459. package/dist/tools/rename-all.js +434 -0
  460. package/dist/tools/rename-asset.js +34 -0
  461. package/dist/tools/render-settings.js +47 -0
  462. package/dist/tools/render-timeline.js +120 -0
  463. package/dist/tools/render.js +384 -0
  464. package/dist/tools/reorder-character-images.js +45 -0
  465. package/dist/tools/replace-video-audio.js +133 -0
  466. package/dist/tools/restore-archive-clips.js +209 -0
  467. package/dist/tools/restore-asset-version.js +37 -0
  468. package/dist/tools/retry-generation.js +54 -0
  469. package/dist/tools/reverse-video.js +74 -0
  470. package/dist/tools/rewrite-prompt.js +388 -0
  471. package/dist/tools/rewrite-script.js +67 -0
  472. package/dist/tools/schema-from-apicity.js +66 -0
  473. package/dist/tools/search-archive.js +150 -0
  474. package/dist/tools/semantic-search.js +1214 -0
  475. package/dist/tools/sequence-rhythm.js +43 -0
  476. package/dist/tools/set-character-metadata.js +84 -0
  477. package/dist/tools/set-env-secret.js +40 -0
  478. package/dist/tools/set-osg.js +143 -0
  479. package/dist/tools/show-folder.js +37 -0
  480. package/dist/tools/smooth-scene-concat.js +122 -0
  481. package/dist/tools/splice-video.js +149 -0
  482. package/dist/tools/split-video.js +202 -0
  483. package/dist/tools/suggest-cuts.js +45 -0
  484. package/dist/tools/suggest-sfx.js +43 -0
  485. package/dist/tools/sync-video-to-audio.js +115 -0
  486. package/dist/tools/tag-backfill.js +177 -0
  487. package/dist/tools/timewarp-video.js +85 -0
  488. package/dist/tools/tool-def.js +1 -0
  489. package/dist/tools/tool-json-schema.js +116 -0
  490. package/dist/tools/transcribe.js +90 -0
  491. package/dist/tools/translate-subtitles.js +59 -0
  492. package/dist/tools/trim-audio.js +139 -0
  493. package/dist/tools/trim-video.js +168 -0
  494. package/dist/tools/update-script.js +25 -0
  495. package/dist/tools/update-timeline-audio.js +40 -0
  496. package/dist/tools/upload-file.js +41 -0
  497. package/dist/tools/verify-x-mentions.js +141 -0
  498. package/dist/tools/video-editing-command-contract.js +291 -0
  499. package/dist/tools/video-source-reference.js +30 -0
  500. package/dist/tools/video-time-input.js +18 -0
  501. package/dist/tools/videobook-domain.js +2021 -0
  502. package/dist/tools/wait-for-asset-ready.js +143 -0
  503. package/dist/tools/workspace-actions.js +54 -0
  504. package/dist/transcript-projection.js +202 -0
  505. package/dist/transcript-srt.js +33 -0
  506. package/dist/upload.js +76 -0
  507. package/dist/usage-providers.js +25 -0
  508. package/dist/video-analysis-projection.js +46 -0
  509. package/dist/video-poster.js +33 -0
  510. package/dist/video-proxy.js +99 -0
  511. package/dist/vision-regions.js +111 -0
  512. package/dist/voice-actions.js +90 -0
  513. package/dist/voice-audio.js +55 -0
  514. package/dist/voice-config.js +122 -0
  515. package/dist/voice-continuation.js +54 -0
  516. package/dist/voice-contract.js +1 -0
  517. package/dist/voice-http.js +145 -0
  518. package/dist/voice-reply-progress.js +55 -0
  519. package/dist/voice-session.js +992 -0
  520. package/dist/watermark-badge.js +259 -0
  521. package/dist/watermark-config.js +111 -0
  522. package/dist/watermark-handle-position.js +55 -0
  523. package/dist/watermark-platform.js +15 -0
  524. package/dist/watermark-timing.js +16 -0
  525. package/dist/workspace-action-catalog.js +315 -0
  526. package/dist/workspace-action-contract.js +21 -0
  527. package/dist/workspace-action-groups.js +98 -0
  528. package/dist/workspace-action-surfaces.js +7 -0
  529. package/dist/x/account.js +88 -0
  530. package/dist/x/authenticated-handle.js +30 -0
  531. package/dist/x/oauth-flow.js +191 -0
  532. package/dist/x/post-contract.js +1 -0
  533. package/dist/x/post-metadata.js +44 -0
  534. package/dist/x/post-to-x.js +456 -0
  535. package/dist/x/published-post-cell.js +90 -0
  536. package/dist/x/x-tokens.js +69 -0
  537. package/dist/ytdlp-binary.js +65 -0
  538. package/dist/zod-slots.js +334 -0
  539. package/package.json +84 -4
  540. package/ui/assets/alive-captions-BWb5nLKj.css +1 -0
  541. package/ui/assets/alive-captions-DPEr1nKM.js +1 -0
  542. package/ui/assets/confirm-bodies-D8ouHXKy.js +1 -0
  543. package/ui/assets/confirm-bodies-DrMhaXC6.css +1 -0
  544. package/ui/assets/fullscreen-B7nw4YbE.js +1 -0
  545. package/ui/assets/goal-ui-DK-xTCK0.js +2 -0
  546. package/ui/assets/goal-ui-DXdUM2KF.css +1 -0
  547. package/ui/assets/index-DzPAnCUj.css +1 -0
  548. package/ui/assets/index-kS1905s5.js +37 -0
  549. package/ui/assets/inspector-MlzQbTVo.js +1 -0
  550. package/ui/assets/jobs-ui-CoinOWx0.js +1 -0
  551. package/ui/assets/music-video-Cbe80kmQ.js +1 -0
  552. package/ui/assets/music-video-DPaiKKEq.css +1 -0
  553. package/ui/assets/ui-Oirr9VOf.css +1 -0
  554. package/ui/assets/ui-xo_Y1yQg.js +2 -0
  555. package/ui/assets/vendor-D2rfiZ5j.css +1 -0
  556. package/ui/assets/vendor-DfTCWgKm.js +19 -0
  557. package/ui/assets/vendor-flow-BXbeWxW7.js +7 -0
  558. package/ui/assets/vendor-flow-BnuhLJ6X.css +1 -0
  559. package/ui/assets/vendor-icons-CGqhCIXV.js +1 -0
  560. package/ui/assets/vendor-mcp-BTlEJcHV.js +67 -0
  561. package/ui/assets/vendor-react-Dj7D1fD4.js +9 -0
  562. package/ui/assets/vendor-remotion-CH1HXrlc.js +95 -0
  563. package/ui/assets/videobook-Qlp9HQFu.js +20 -0
  564. package/ui/favicon.svg +8 -0
  565. package/ui/index.html +126 -0
@@ -0,0 +1,60 @@
1
+ import { assessToolCallEstimate, logUnavailableCostEstimate, } from "./jobs/cost-estimate-assessment.js";
2
+ /** Keys whose values never belong on a review sheet or in a spoken line. */
3
+ const SENSITIVE_KEY = /api.?key|secret|(?:^|[_-])token(?:$|[_-])|password|credential|authorization/iu;
4
+ function humanize(value) {
5
+ const words = value.replaceAll("_", " ").replace(/^generate kie /u, "generate ");
6
+ return words.charAt(0).toUpperCase() + words.slice(1);
7
+ }
8
+ function reviewParams(params) {
9
+ return Object.fromEntries(Object.entries(params)
10
+ .filter(([key]) => key !== "book_id" && key !== "notebook_id")
11
+ .map(([key, value]) => [key, SENSITIVE_KEY.test(key) ? "Hidden" : value]));
12
+ }
13
+ function formatUsd(usd) {
14
+ return usd < 0.01 ? `${Math.round(usd * 100)} cents` : `$${usd.toFixed(2)}`;
15
+ }
16
+ /** One sentence naming the step, what it consumes, and what approving costs. */
17
+ function reviewReason(input) {
18
+ const position = `Step ${input.index + 1} of ${input.total}`;
19
+ const source = input.address ? ` from ${input.address}` : "";
20
+ const cost = input.estimateUsd === null
21
+ ? "I can't price this one"
22
+ : `about ${formatUsd(input.estimateUsd)}`;
23
+ return `${position}: ${input.title.toLowerCase()}${source}, ${cost}. Apply to spend it, or cancel to stop the whole chain.`;
24
+ }
25
+ /**
26
+ * Price a paused step from its dispatch-ready params. Estimating earlier would
27
+ * price the {$ref} placeholder rather than the value the step actually receives.
28
+ */
29
+ export async function buildChainStepReview(input) {
30
+ const assessment = await assessToolCallEstimate(input.engine, input.tool, input.dispatchParams);
31
+ if (!assessment.available) {
32
+ await logUnavailableCostEstimate({
33
+ assessment,
34
+ engine: input.engine,
35
+ correlation: { bookId: input.bookId, tool: input.tool, stage: "chain-step" },
36
+ });
37
+ }
38
+ const estimateUsd = assessment.available ? assessment.usd : null;
39
+ const title = humanize(input.tool);
40
+ const address = input.pins[0]?.address ?? null;
41
+ return {
42
+ stepId: input.stepId,
43
+ index: input.index,
44
+ total: input.total,
45
+ tool: input.tool,
46
+ title,
47
+ address,
48
+ params: reviewParams(input.dispatchParams),
49
+ estimateUsd,
50
+ estimateUnavailable: !assessment.available,
51
+ estimateWarnings: assessment.warnings,
52
+ reason: reviewReason({
53
+ title,
54
+ index: input.index,
55
+ total: input.total,
56
+ address,
57
+ estimateUsd,
58
+ }),
59
+ };
60
+ }
@@ -0,0 +1,25 @@
1
+ const MIN_STEM_LEN = 3;
2
+ /** Strip @ and normalize to bare asset id. */
3
+ export function bareAssetId(reference) {
4
+ return reference.startsWith("@") ? reference.slice(1) : reference;
5
+ }
6
+ /**
7
+ * Stem suitable for a short character name. Artifact ids are opaque UUIDs, so
8
+ * the stem comes from the source artifact's free-text label.
9
+ * "french-head" → french-head
10
+ * "French Head" → French Head
11
+ * "n" → "" (degenerate)
12
+ * "" (unlabelled artifact) → ""
13
+ */
14
+ export function characterNameStem(label) {
15
+ const stem = label.trim();
16
+ return stem.length >= MIN_STEM_LEN ? stem : "";
17
+ }
18
+ /** Asset create name + display_name: stem or fallback. */
19
+ export function resolveCharacterCreateName(explicitNameParts, imageLabels) {
20
+ if (explicitNameParts.length > 0) {
21
+ return explicitNameParts.join("-");
22
+ }
23
+ const fromImage = imageLabels[0] ? characterNameStem(imageLabels[0]) : "";
24
+ return fromImage || "character";
25
+ }
@@ -0,0 +1,73 @@
1
+ import { LIGHTNING_SCENE_MODEL, LIGHTNING_VIDEO_MODEL } from "./lightning-defaults.js";
2
+ import { listElevenLabsVoices } from "./tools/list-elevenlabs-voices.js";
3
+ import { isChainRef } from "./chain-plan.js";
4
+ export const CHAT_DEFAULT_MODELS = {
5
+ generate_image: LIGHTNING_SCENE_MODEL,
6
+ generate_video: LIGHTNING_VIDEO_MODEL,
7
+ generate_audio: "elevenlabs:text-to-speech",
8
+ };
9
+ const FLAT_REF_FIELDS = {
10
+ image_refs: "image",
11
+ image_ref: "image",
12
+ video_refs: "video",
13
+ video_ref: "video",
14
+ audio_refs: "audio",
15
+ audio_ref: "audio",
16
+ first_frame_ref: "first_frame",
17
+ last_frame_ref: "last_frame",
18
+ };
19
+ function record(value) {
20
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
21
+ }
22
+ function list(value) {
23
+ const values = Array.isArray(value) ? value : value === undefined || value === null ? [] : [value];
24
+ return values.filter((entry) => (typeof entry === "string" && entry.trim() !== "") || isChainRef(entry));
25
+ }
26
+ function foldFlatRefs(params) {
27
+ const refs = Object.fromEntries(Object.entries(record(params.refs)).map(([role, value]) => [role, list(value)]));
28
+ const next = { ...params };
29
+ for (const [field, role] of Object.entries(FLAT_REF_FIELDS)) {
30
+ if (!(field in next))
31
+ continue;
32
+ refs[role] = [...(refs[role] ?? []), ...list(next[field])];
33
+ delete next[field];
34
+ }
35
+ const kept = Object.fromEntries(Object.entries(refs).filter(([, values]) => values.length > 0));
36
+ return Object.keys(kept).length > 0 ? { ...next, refs: kept } : next;
37
+ }
38
+ async function withDefaultVoice(params) {
39
+ if (params.model !== "elevenlabs:text-to-speech")
40
+ return params;
41
+ const options = record(params.options);
42
+ if (typeof options.voice_id === "string" && options.voice_id.trim() !== "")
43
+ return params;
44
+ const fallback = (await listElevenLabsVoices()).voices[0]?.voice_id;
45
+ return fallback ? { ...params, options: { ...options, voice_id: fallback } } : params;
46
+ }
47
+ /**
48
+ * Fill routing gaps for chat-dispatched generations: the router may omit the
49
+ * model, keep provider-era ref fields at the top level, or leave the ElevenLabs
50
+ * voice unset because it cannot know voice ids. The review sheet shows the
51
+ * filled values before anything runs.
52
+ */
53
+ export async function applyGenerationRoutingDefaults(tool, params) {
54
+ if (tool === "chain" && Array.isArray(params.steps)) {
55
+ const steps = await Promise.all(params.steps.map(async (entry) => {
56
+ const step = record(entry);
57
+ if (typeof step.tool !== "string" || !CHAT_DEFAULT_MODELS[step.tool])
58
+ return entry;
59
+ if (!step.params || typeof step.params !== "object" || Array.isArray(step.params))
60
+ return entry;
61
+ return { ...step, params: await applyGenerationRoutingDefaults(step.tool, record(step.params)) };
62
+ }));
63
+ return { ...params, steps };
64
+ }
65
+ const defaultModel = CHAT_DEFAULT_MODELS[tool];
66
+ if (!defaultModel)
67
+ return params;
68
+ const folded = foldFlatRefs(params);
69
+ const withModel = typeof folded.model === "string" && folded.model.trim() !== ""
70
+ ? folded
71
+ : { ...folded, model: defaultModel };
72
+ return withDefaultVoice(withModel);
73
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Optional generation settings the request never asked for.
3
+ *
4
+ * The routing prompt already carries the rule — "Omit optional parameters
5
+ * unless the user explicitly requests them so the tool can apply its defaults"
6
+ * (chat-router.ts) — and nothing enforced it. A spoken "make a Seedance video
7
+ * of the kittens in @a1 dancing like @a2" came back carrying duration 22 and
8
+ * generate_audio false: neither was in the request, neither is derivable from
9
+ * the asset context the router sees, and generate_audio false is the opposite
10
+ * of the provider's own default.
11
+ *
12
+ * So the rule moves out of the prompt and into code. A setting the router
13
+ * emitted survives only when the request shows evidence for it, and dropping
14
+ * one is safe by construction: the tool then applies the default the guideline
15
+ * wanted in the first place. Settings with no entry in the evidence table are
16
+ * left alone, so this narrows what the router can invent without becoming a
17
+ * second guess at what it meant.
18
+ */
19
+ // The audio toggle is spelled four ways across providers, but what a person
20
+ // says to ask for it is the same either way.
21
+ const AUDIO_EVIDENCE = /\b(?:audio|sound|sounds|sfx|music|musical|soundtrack|score|silent|silence|mute|muted|voice|voices|vocal|vocals|dialogue|dialog|narration|noise)\b/iu;
22
+ const RESOLUTION_EVIDENCE = /\b(?:480p|720p|1080p|1440p|2k|4k|8k|hd|uhd|resolution|sharper|crisper)\b/iu;
23
+ const SAFETY_EVIDENCE = /\b(?:nsfw|safety|safe|filter|filtered|explicit|censor|censored|uncensored|spicy)\b/iu;
24
+ // What counts as asking for a setting. Deliberately generous about phrasing and
25
+ // strict about shape: a missed cue costs the provider default, an over-eager
26
+ // match keeps a value the router invented. Enum-valued settings match their own
27
+ // vocabulary (720p, 16:9) rather than a bare number, so a timestamp or a shot
28
+ // count never reads as a resolution or a ratio.
29
+ const SETTING_EVIDENCE = {
30
+ duration: /\b\d+(?:\.\d+)?\s*(?:s|sec|secs|second|seconds|m|min|mins|minute|minutes)\b|\b(?:duration|length|long|longer|short|shorter|brief)\b/iu,
31
+ resolution: RESOLUTION_EVIDENCE,
32
+ output_resolution: RESOLUTION_EVIDENCE,
33
+ aspect_ratio: /\b(?:1:1|4:3|3:4|16:9|9:16|21:9)\b|\b(?:aspect|ratio|square|portrait|landscape|vertical|horizontal|widescreen)\b/iu,
34
+ output_format: /\b(?:mp4|mov|webm|gif|format)\b/iu,
35
+ generate_audio: AUDIO_EVIDENCE,
36
+ audio: AUDIO_EVIDENCE,
37
+ sound: AUDIO_EVIDENCE,
38
+ audio_setting: AUDIO_EVIDENCE,
39
+ return_last_frame: /\b(?:last|final|closing|ending)\s+frame\b/iu,
40
+ web_search: /\bweb\s*search\b|\bsearch\s+the\s+web\b|\blook\s+(?:it|this|that)\s+up\b|\bresearch\b/iu,
41
+ nsfw_checker: SAFETY_EVIDENCE,
42
+ enable_safety_checker: SAFETY_EVIDENCE,
43
+ seed: /\bseed(?:ed|s)?\b/iu,
44
+ watermark: /\bwatermark(?:ed|s)?\b/iu,
45
+ };
46
+ /** Whether the request asks for this setting at all. A setting with no evidence
47
+ * rule is always treated as requested, so only reviewed names can be dropped. */
48
+ export function settingIsRequested(name, query) {
49
+ const evidence = SETTING_EVIDENCE[name];
50
+ return evidence === undefined || evidence.test(query);
51
+ }
52
+ /**
53
+ * Drop the optional settings a generation request never asked for, so the tool
54
+ * applies its own defaults instead of values the router filled in.
55
+ */
56
+ function requestedEntries(entries, query, required, dropped) {
57
+ const kept = {};
58
+ for (const [name, value] of Object.entries(entries)) {
59
+ if (required.has(name) || settingIsRequested(name, query)) {
60
+ kept[name] = value;
61
+ continue;
62
+ }
63
+ dropped.push(name);
64
+ }
65
+ return kept;
66
+ }
67
+ function optionsRecord(value) {
68
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
69
+ }
70
+ export function withoutUnrequestedSettings(input) {
71
+ const required = new Set(input.requiredParams);
72
+ const dropped = [];
73
+ const params = requestedEntries(input.params, input.query, required, dropped);
74
+ const options = optionsRecord(params.options);
75
+ if (options)
76
+ params.options = requestedEntries(options, input.query, new Set(), dropped);
77
+ return { params, dropped };
78
+ }
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ const CHAT_MODEL_IDS = ["gpt-6-astra"];
3
+ export const DEFAULT_CHAT_MODEL = "gpt-6-astra";
4
+ export const CHAT_MODEL_OPTIONS = [
5
+ {
6
+ id: "gpt-6-astra",
7
+ label: "Astra",
8
+ description: "Routes every composer request and configures its tools",
9
+ reasoningEffort: "medium",
10
+ },
11
+ ];
12
+ export function chatIntelligenceRequestOptions(model) {
13
+ const resolved = resolveChatModel(model);
14
+ return {
15
+ model: resolved.id,
16
+ reasoningEffort: resolved.reasoningEffort,
17
+ };
18
+ }
19
+ export const chatModelSchema = z.enum(CHAT_MODEL_IDS);
20
+ export function resolveChatModel(model) {
21
+ return CHAT_MODEL_OPTIONS.find((option) => option.id === model)
22
+ ?? CHAT_MODEL_OPTIONS[0];
23
+ }
24
+ export function listChatModelsDef() {
25
+ return {
26
+ name: "list_chat_models",
27
+ description: "List supported chat routing models and the default selection",
28
+ scope: "global",
29
+ schema: {},
30
+ handler: async () => ({
31
+ content: [{
32
+ type: "text",
33
+ text: JSON.stringify({
34
+ defaultModel: DEFAULT_CHAT_MODEL,
35
+ models: CHAT_MODEL_OPTIONS.map(({ id, label, description }) => ({
36
+ id,
37
+ label,
38
+ description,
39
+ })),
40
+ }),
41
+ }],
42
+ }),
43
+ };
44
+ }
@@ -0,0 +1,67 @@
1
+ import { modelEntry } from "./media/catalog.js";
2
+ import { unresolvedProviderMentions } from "./provider-prompt-transform.js";
3
+ import { rewritePromptDef } from "./tools/rewrite-prompt.js";
4
+ // Rides on rewrite_prompt's custom_prompt, which caps at 500 characters. The
5
+ // mention rule protects the reference wiring; the model-name rule is the reason
6
+ // this call exists at all; the settings rule keeps the guide from narrating
7
+ // duration and framing into the text when those ride their own payload fields.
8
+ export const CHAT_REWRITE_INSTRUCTION = "Keep every @ reference token byte-for-byte as written (e.g. @a1, "
9
+ + "@0199f0e4-9332-7383-b1a9-eb016abd4fdb): never renumber one, never rewrite "
10
+ + "one into @Image1/@Video1/@Audio1 form, never drop one. "
11
+ + "Describe only the media to produce: drop request preambles and any "
12
+ + "instruction naming which model, provider or tool to use. "
13
+ + "Do not state duration, aspect ratio or resolution — those ride their own "
14
+ + "fields, not the prompt.";
15
+ /** The prompting guide for a catalog model, or null when it has none. */
16
+ export function rewriteGuideForModel(model) {
17
+ return modelEntry(model)?.guide ?? null;
18
+ }
19
+ /** Every @ token the rewrite has to hand back. Same scanner the provider
20
+ * transform uses to find tokens it still has to resolve, so the two agree on
21
+ * what counts as a mention. */
22
+ function mentionTokens(prompt) {
23
+ return unresolvedProviderMentions(prompt);
24
+ }
25
+ /**
26
+ * The rewrite to use, which is the original whenever the rewritten text is
27
+ * blank or has lost a mention. Exported for the tests that cover the guard
28
+ * without spending a model call.
29
+ */
30
+ export function usableRewrite(original, rewritten) {
31
+ const candidate = rewritten.trim();
32
+ if (!candidate)
33
+ return original;
34
+ const kept = mentionTokens(candidate);
35
+ const missing = mentionTokens(original).filter((token) => !kept.includes(token));
36
+ return missing.length > 0 ? original : candidate;
37
+ }
38
+ function rewrittenPromptFromResult(result) {
39
+ const text = result.isError ? undefined : result.content[0]?.text;
40
+ if (text === undefined)
41
+ return "";
42
+ const { rewritten_prompt: rewritten } = JSON.parse(text);
43
+ return typeof rewritten === "string" ? rewritten : "";
44
+ }
45
+ /**
46
+ * Rewrite a routed generation prompt against its model's guide. Returns the
47
+ * original prompt when the model has no guide, when the rewrite fails, and when
48
+ * the result would cost a mention — this sits between routing and the confirm
49
+ * sheet, so it must never be the thing that stops a generation.
50
+ */
51
+ export async function rewriteChatGenerationPrompt(engine, input) {
52
+ const guide = rewriteGuideForModel(input.model);
53
+ if (!guide || !input.prompt.trim())
54
+ return input.prompt;
55
+ try {
56
+ const result = await rewritePromptDef(engine).handler({
57
+ book_id: input.bookId,
58
+ prompt: input.prompt,
59
+ model: guide,
60
+ custom_prompt: CHAT_REWRITE_INSTRUCTION,
61
+ });
62
+ return usableRewrite(input.prompt, rewrittenPromptFromResult(result));
63
+ }
64
+ catch {
65
+ return input.prompt;
66
+ }
67
+ }