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,77 @@
1
+ import { scanNotebookMentions } from "videobook-engine/notebook-mentions";
2
+ import { PREVIEW_PLACEHOLDER_HOST } from "./preview-payload.js";
3
+ // An @<artifact-id> token is the internal reference currency between the
4
+ // grid resolver and the per-tool dialect rewrite; one surviving into a
5
+ // provider payload means the rewrite missed it.
6
+ const ARTIFACT_ID_MENTION_PATTERN = /@[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(?![\w-])/giu;
7
+ export class ProviderMentionError extends Error {
8
+ tokens;
9
+ toolName;
10
+ constructor(toolName, tokens) {
11
+ super(`Unresolved provider mention${tokens.length === 1 ? "" : "s"} `
12
+ + `${tokens.join(", ")} in ${toolName}`);
13
+ this.name = "ProviderMentionError";
14
+ this.tokens = tokens;
15
+ this.toolName = toolName;
16
+ }
17
+ }
18
+ class ProviderPlaceholderError extends Error {
19
+ paths;
20
+ toolName;
21
+ constructor(toolName, paths) {
22
+ super(`Preview placeholder URL reached wire payload for ${toolName}: ${paths.join(", ")}`);
23
+ this.name = "ProviderPlaceholderError";
24
+ this.paths = paths;
25
+ this.toolName = toolName;
26
+ }
27
+ }
28
+ export function unresolvedProviderMentions(prompt) {
29
+ const leaks = [
30
+ ...scanNotebookMentions(prompt).map((mention) => mention.raw),
31
+ ...[...prompt.matchAll(ARTIFACT_ID_MENTION_PATTERN)].map((match) => match[0]),
32
+ ];
33
+ return [...new Set(leaks)];
34
+ }
35
+ export function assertNoUnresolvedMentions(prompt, options) {
36
+ const tokens = unresolvedProviderMentions(prompt);
37
+ if (tokens.length > 0)
38
+ throw new ProviderMentionError(options.toolName, tokens);
39
+ }
40
+ function visitProviderPayload(value, path, key, leaks, placeholders) {
41
+ if (typeof value === "string") {
42
+ if (value.includes(PREVIEW_PLACEHOLDER_HOST))
43
+ placeholders.push(path);
44
+ if (key.toLowerCase().includes("prompt") || key === "text") {
45
+ for (const token of unresolvedProviderMentions(value)) {
46
+ leaks.push({ path, token });
47
+ }
48
+ }
49
+ return;
50
+ }
51
+ if (Array.isArray(value)) {
52
+ value.forEach((item, index) => {
53
+ visitProviderPayload(item, `${path}[${index}]`, key, leaks, placeholders);
54
+ });
55
+ return;
56
+ }
57
+ if (!value || typeof value !== "object")
58
+ return;
59
+ for (const [childKey, childValue] of Object.entries(value)) {
60
+ visitProviderPayload(childValue, path ? `${path}.${childKey}` : childKey, childKey, leaks, placeholders);
61
+ }
62
+ }
63
+ function inspectProviderPayload(value) {
64
+ const promptLeaks = [];
65
+ const placeholderPaths = [];
66
+ visitProviderPayload(value, "", "", promptLeaks, placeholderPaths);
67
+ return { promptLeaks, placeholderPaths };
68
+ }
69
+ export function assertProviderPayload(value, options) {
70
+ const inspection = inspectProviderPayload(value);
71
+ const tokens = [...new Set(inspection.promptLeaks.map((leak) => leak.token))];
72
+ if (tokens.length > 0)
73
+ throw new ProviderMentionError(options.toolName, tokens);
74
+ if (options.wire && inspection.placeholderPaths.length > 0) {
75
+ throw new ProviderPlaceholderError(options.toolName, inspection.placeholderPaths);
76
+ }
77
+ }
@@ -0,0 +1,21 @@
1
+ export function providerStatusUrl(provider, model) {
2
+ if (provider === "kie")
3
+ return "https://kie.ai/logs";
4
+ if (provider !== "fal" || !model || !/^[a-z0-9_-]+(?:\/[a-z0-9_.-]+)+$/iu.test(model))
5
+ return null;
6
+ if (model.split("/").some((part) => part === "." || part === ".."))
7
+ return null;
8
+ return `https://fal.ai/models/${model.split("/").map(encodeURIComponent).join("/")}/requests`;
9
+ }
10
+ export function parseProviderTaskStatus(value) {
11
+ if (!value || typeof value !== "object" || Array.isArray(value))
12
+ return null;
13
+ const record = value;
14
+ if (record.provider !== "kie" && record.provider !== "fal")
15
+ return null;
16
+ return {
17
+ provider: record.provider,
18
+ model: typeof record.model === "string" ? record.model : null,
19
+ taskId: typeof record.taskId === "string" ? record.taskId : null,
20
+ };
21
+ }
@@ -0,0 +1,78 @@
1
+ function taskRecord(value) {
2
+ if (!value || typeof value !== "object" || Array.isArray(value))
3
+ return null;
4
+ const record = value;
5
+ if (typeof record.taskId !== "string" || !record.taskId
6
+ || typeof record.taskType !== "string" || !record.taskType
7
+ || typeof record.createdAt !== "number"
8
+ || !record.meta || typeof record.meta !== "object" || Array.isArray(record.meta))
9
+ return null;
10
+ return {
11
+ taskId: record.taskId,
12
+ taskType: record.taskType,
13
+ createdAt: record.createdAt,
14
+ meta: record.meta,
15
+ };
16
+ }
17
+ export async function preserveProviderTask(engine, task) {
18
+ const written = await engine.metadata.artifacts.write(task.artifactId, "provider-task", {
19
+ taskId: task.taskId,
20
+ taskType: task.taskType,
21
+ createdAt: task.createdAt,
22
+ meta: task.meta,
23
+ });
24
+ if (!written.ok)
25
+ throw new Error(written.error.message);
26
+ }
27
+ export async function readProviderTaskRecord(engine, artifactId) {
28
+ const pending = engine.jobs.pending.read(artifactId);
29
+ if (pending.ok && pending.value)
30
+ return pending.value;
31
+ const saved = await engine.metadata.artifacts.read(artifactId, "provider-task");
32
+ const record = saved.ok ? taskRecord(saved.value) : null;
33
+ return record;
34
+ }
35
+ export async function recoverNotebookProviderTask(engine, artifactId) {
36
+ const pending = engine.jobs.pending.read(artifactId);
37
+ if (!pending.ok)
38
+ return false;
39
+ if (pending.value) {
40
+ if (pending.value.completing) {
41
+ const active = engine.jobs.queue.list({ states: ["queued", "running", "completing"] });
42
+ if (!active.some((job) => job.type === "complete_kie_task"
43
+ && job.payload.assetId === artifactId
44
+ && job.payload.taskId === pending.value?.taskId)) {
45
+ const cleared = engine.jobs.pending.clearCompleting(artifactId);
46
+ if (!cleared.ok)
47
+ throw new Error(cleared.error.message);
48
+ }
49
+ }
50
+ return true;
51
+ }
52
+ const failure = engine.jobs.failures.read(artifactId);
53
+ if (!failure.ok || failure.value)
54
+ return false;
55
+ if (engine.jobs.queue.list({
56
+ states: ["queued", "running", "completing"], artifactId,
57
+ }).length > 0)
58
+ return false;
59
+ const status = await engine.status.get(artifactId);
60
+ if (!status.ok || status.value === "ready")
61
+ return false;
62
+ const record = await readProviderTaskRecord(engine, artifactId);
63
+ if (!record || record.taskId === "queued")
64
+ return false;
65
+ const owner = engine.jobs.artifactWork.begin(artifactId, {
66
+ kind: "generate", ownerKind: "job", durationMs: 60_000,
67
+ });
68
+ if (!owner)
69
+ return false;
70
+ const restored = await engine.jobs.pending.write({ artifactId, ...record }, owner.ownerId);
71
+ if (!restored.ok)
72
+ throw new Error(restored.error.message);
73
+ if (!restored.value)
74
+ return false;
75
+ await preserveProviderTask(engine, restored.value.task);
76
+ engine.jobs.artifactWork.complete(artifactId, owner.ownerId);
77
+ return true;
78
+ }
@@ -0,0 +1,47 @@
1
+ import { parseModelId } from "./media/model-id.js";
2
+ import { legacyMediaForTaskType } from "./media/legacy-task-types.js";
3
+ import { readProviderTaskRecord } from "./provider-task-record.js";
4
+ function record(value) {
5
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
6
+ }
7
+ function firstString(...values) {
8
+ return values.find((value) => typeof value === "string" && value.length > 0) ?? null;
9
+ }
10
+ export async function readProviderTaskStatus(engine, artifactId, hints = {}) {
11
+ const [saved, payloadResult, idResult] = artifactId ? await Promise.all([
12
+ readProviderTaskRecord(engine, artifactId),
13
+ engine.metadata.artifacts.read(artifactId, "generation-payload"),
14
+ engine.metadata.artifacts.read(artifactId, "kie-task-id"),
15
+ ]) : [null, null, null];
16
+ const payload = payloadResult?.ok ? record(payloadResult.value) : {};
17
+ const storedId = idResult?.ok ? record(idResult.value) : {};
18
+ const endpoint = firstString(payload.endpoint_id, saved?.meta.falEndpointId, saved?.meta.endpointId, saved?.meta.endpoint_id);
19
+ const catalogModelId = firstString(saved?.meta.model, hints.model) ?? "";
20
+ const catalogModel = parseModelId(catalogModelId);
21
+ if (catalogModelId.includes(":") && !catalogModel)
22
+ return null;
23
+ const model = firstString(endpoint, payload.model, catalogModel?.apiId, saved?.meta.apiModel, saved?.meta.model, hints.model);
24
+ const taskId = firstString(saved?.taskId, storedId.taskId, hints.taskId);
25
+ if (saved && /^(?:xai|alibaba)_/u.test(saved.taskType))
26
+ return null;
27
+ if (saved && saved.taskType !== "media_kie" && saved.taskType !== "isolate_vocals"
28
+ && !saved.taskType.startsWith("fal_") && legacyMediaForTaskType(saved.taskType) === null)
29
+ return null;
30
+ const provider = endpoint || saved?.taskType.startsWith("fal_") ? "fal"
31
+ : catalogModel?.provider ?? hints.provider ?? (storedId.taskId || saved ? "kie" : null);
32
+ if (provider !== "kie" && provider !== "fal")
33
+ return null;
34
+ return { provider, model, taskId: taskId === "queued" ? null : taskId };
35
+ }
36
+ export async function jobProviderTaskStatus(engine, job) {
37
+ if (!job.type.startsWith("generate_") && job.type !== "await_notebook_output"
38
+ && !/^complete_.*task$/u.test(job.type))
39
+ return null;
40
+ const catalogModel = parseModelId(firstString(job.payload.model) ?? "");
41
+ const artifactId = firstString(job.payload.providerArtifactId, job.artifactId, job.payload.imageAssetId, job.payload.imgAssetId, job.payload.vidAssetId, job.payload.assetId);
42
+ return readProviderTaskStatus(engine, artifactId, {
43
+ provider: catalogModel?.provider ?? null,
44
+ model: firstString(job.payload.endpointId, job.payload.modelId, job.payload.model),
45
+ taskId: firstString(record(job.result).taskId, job.payload.taskId),
46
+ });
47
+ }
@@ -0,0 +1,294 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { createCost, PRICING, PRICING_AS_OF } from "@apicity/cost";
6
+ import { currentBookContext } from "./book-context.js";
7
+ function installedPackageVersion(name) {
8
+ let dir = dirname(fileURLToPath(import.meta.resolve(name)));
9
+ while (dir !== dirname(dir)) {
10
+ try {
11
+ const manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
12
+ if (manifest.name === name && manifest.version)
13
+ return manifest.version;
14
+ }
15
+ catch {
16
+ void 0;
17
+ }
18
+ dir = dirname(dir);
19
+ }
20
+ return "unknown";
21
+ }
22
+ const COST_PACKAGE_VERSION = installedPackageVersion("@apicity/cost");
23
+ const incomplete = new WeakSet();
24
+ const cost = createCost();
25
+ function object(value) {
26
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
27
+ }
28
+ function number(value) {
29
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
30
+ }
31
+ function text(value) {
32
+ return typeof value === "string" && value.length > 0 ? value : null;
33
+ }
34
+ function safeRecord(engine, entry) {
35
+ try {
36
+ const result = engine.usage.record(entry);
37
+ if (result.ok)
38
+ return;
39
+ }
40
+ catch {
41
+ void 0;
42
+ }
43
+ incomplete.add(engine);
44
+ try {
45
+ engine.settings.set("usage-incomplete", true);
46
+ }
47
+ catch {
48
+ void 0;
49
+ }
50
+ }
51
+ export function usageIncomplete(engine) {
52
+ const scoped = currentBookContext()?.engine ?? engine;
53
+ return incomplete.has(scoped) || scoped.settings.get("usage-incomplete") === true;
54
+ }
55
+ export async function settleFinishedUsage(engine) {
56
+ const pending = engine.usage.recent(200).filter((entry) => entry.status === "pending" && entry.externalId !== null && entry.artifactId !== null);
57
+ for (const entry of pending) {
58
+ const task = engine.jobs.pending.findByExternalId(entry.externalId);
59
+ if (!task.ok || task.value)
60
+ continue;
61
+ const status = await engine.status.get(entry.artifactId);
62
+ if (!status.ok)
63
+ continue;
64
+ if (status.value === "ready")
65
+ safeRecord(engine, { ...entry, status: "completed" });
66
+ else if (status.value === "error")
67
+ safeRecord(engine, { ...entry, status: "failed" });
68
+ }
69
+ }
70
+ function reportedTokens(value) {
71
+ const usage = object(value);
72
+ const inputTokens = number(usage.input_tokens) ?? number(usage.prompt_tokens) ?? number(usage.inputTokens);
73
+ const outputTokens = number(usage.output_tokens) ?? number(usage.completion_tokens) ?? number(usage.outputTokens);
74
+ const details = object(usage.input_tokens_details ?? usage.prompt_tokens_details ?? usage.input_token_details);
75
+ const cachedTokens = number(details.cached_tokens) ?? number(usage.cached_tokens);
76
+ return { inputTokens, outputTokens, cachedTokens: cachedTokens !== null && inputTokens !== null ? Math.min(cachedTokens, inputTokens) : cachedTokens };
77
+ }
78
+ function rateFor(provider, model) {
79
+ const rates = PRICING[provider];
80
+ return rates?.[model];
81
+ }
82
+ function unknownPrice(warnings = ["Price unavailable for this model"]) {
83
+ return { costUsd: null, basis: "unknown", rateSource: null, pricingVersion: `apicity-${COST_PACKAGE_VERSION}:${PRICING_AS_OF}`, warnings, units: null, unit: null };
84
+ }
85
+ function tokenPrice(provider, model, tokens) {
86
+ const rate = rateFor(provider, model);
87
+ if (rate?.kind !== "tokens" || tokens.inputTokens === null || tokens.outputTokens === null)
88
+ return unknownPrice();
89
+ const cached = tokens.cachedTokens ?? 0;
90
+ const usd = ((tokens.inputTokens - cached) * rate.rate.input + cached * (rate.rate.cacheRead ?? rate.rate.input) + tokens.outputTokens * rate.rate.output) / 1e6;
91
+ return { ...unknownPrice([]), costUsd: usd, basis: "estimated", rateSource: rate.source.url, unit: "tokens", units: tokens.inputTokens + tokens.outputTokens };
92
+ }
93
+ function priceRequest(provider, model, payload, endpoint, hints) {
94
+ try {
95
+ const request = { provider, payload, ...(provider === "fal" ? { endpoint } : {}), ...(hints ? { costHints: hints } : {}) };
96
+ const estimate = cost.estimate(request);
97
+ if (estimate.warnings.length || estimate.source === "tokens-heuristic+table")
98
+ return unknownPrice(estimate.warnings.length ? estimate.warnings : ["Waiting for reported token usage"]);
99
+ return {
100
+ ...unknownPrice([]), costUsd: estimate.usd, basis: estimate.source === "free" ? "free" : "estimated",
101
+ rateSource: rateFor(provider, model)?.source.url ?? null, pricingVersion: `apicity-${COST_PACKAGE_VERSION}:${estimate.rateAsOf}`,
102
+ units: estimate.breakdown.units ?? null, unit: estimate.breakdown.unit ?? null,
103
+ };
104
+ }
105
+ catch {
106
+ return unknownPrice();
107
+ }
108
+ }
109
+ function activityFor(model, path, operation = "") {
110
+ if (/\/(responses|completions)$/u.test(path) && /chat|rewrite_prompt/u.test(operation))
111
+ return "chat";
112
+ if (/transcrib|speech.to.text|analy|describe|tag_|rename|suggest|translate|vision|image.subjects|regions|verify/iu.test(`${operation} ${path}`))
113
+ return "analysis";
114
+ if (/video|veo|wan\/|kling|seedance|happyhorse|lipsync/iu.test(`${model} ${path}`))
115
+ return "video";
116
+ if (/audio|speech|music|sound|sfx|suno|vocal/iu.test(`${model} ${path}`))
117
+ return "audio";
118
+ if (/image|banana|seedream|qwen|flux|ideogram/iu.test(`${model} ${path}`))
119
+ return "images";
120
+ return "analysis";
121
+ }
122
+ function isBillable(provider, path, method) {
123
+ if (method !== "POST")
124
+ return false;
125
+ if (provider === "openai" || provider === "xai")
126
+ return /\/(responses|chat\/completions|images\/(generations|edits)|videos\/(generations|edits|extensions)|audio\/(speech|transcriptions|translations)|embeddings|tts|stt)$/u.test(path);
127
+ if (provider === "kie")
128
+ return /\/(createTask|veo\/(generate|extend))$/u.test(path);
129
+ if (provider === "fal")
130
+ return /^\/(fal-ai|alibaba)\//u.test(path) && !/\/requests\//u.test(path);
131
+ if (provider === "alibaba")
132
+ return path.includes("/services/aigc/");
133
+ if (provider === "elevenlabs")
134
+ return /\/(text-to-speech|speech-to-text|speech-to-speech|sound-generation|audio-isolation|music)(\/|$)/u.test(path);
135
+ return /\/(videos|images)(\/|$)/u.test(path);
136
+ }
137
+ async function payloadOf(input, init) {
138
+ const body = init?.body;
139
+ if (typeof body === "string") {
140
+ try {
141
+ return object(JSON.parse(body));
142
+ }
143
+ catch {
144
+ return {};
145
+ }
146
+ }
147
+ if (body instanceof FormData)
148
+ return Object.fromEntries([...body.entries()].filter((entry) => typeof entry[1] === "string"));
149
+ if (input instanceof Request && input.headers.get("content-type")?.includes("application/json")) {
150
+ try {
151
+ return object(await input.clone().json());
152
+ }
153
+ catch {
154
+ return {};
155
+ }
156
+ }
157
+ return {};
158
+ }
159
+ function remoteId(body, url, method) {
160
+ const data = object(body.data);
161
+ const output = object(body.output);
162
+ const pathId = url.searchParams.get("taskId") ?? url.searchParams.get("task_id")
163
+ ?? (/\/(requests|tasks|jobs|videos)\/([^/]+)(?:\/status)?$/u.exec(url.pathname)?.[2] ?? null);
164
+ if (method === "GET" && pathId)
165
+ return decodeURIComponent(pathId);
166
+ return text(data.taskId) ?? text(data.task_id) ?? text(body.request_id) ?? text(body.job_id)
167
+ ?? text(output.task_id) ?? text(body.id);
168
+ }
169
+ function responseStatus(body, accepted) {
170
+ const data = object(body.data);
171
+ const output = object(body.output);
172
+ const state = String(body.status ?? data.state ?? data.status ?? output.task_status ?? "").toLowerCase();
173
+ if (body.error || data.failCode || (typeof body.code === "number" && body.code >= 400) || data.successFlag === 2 || ["failed", "fail", "error"].includes(state))
174
+ return "failed";
175
+ if (["cancelled", "canceled"].includes(state))
176
+ return "cancelled";
177
+ if (state === "uncertain" || state === "expired")
178
+ return "uncertain";
179
+ if (data.successFlag === 1 || ["success", "succeeded", "completed", "done"].includes(state))
180
+ return "completed";
181
+ if (["created", "pending", "queued", "in_queue", "running", "in_progress", "processing", "started", "waiting"].includes(state))
182
+ return "pending";
183
+ return accepted ? "pending" : "completed";
184
+ }
185
+ function usageOf(body) {
186
+ return object(body.usage ?? object(body.data).usage ?? object(body.output).usage ?? object(body.response).usage);
187
+ }
188
+ function observedPatch(provider, entry, body, status) {
189
+ const usage = usageOf(body);
190
+ const reported = reportedTokens(usage);
191
+ const tokens = {
192
+ inputTokens: reported.inputTokens ?? entry.inputTokens ?? null,
193
+ outputTokens: reported.outputTokens ?? entry.outputTokens ?? null,
194
+ cachedTokens: reported.cachedTokens ?? entry.cachedTokens ?? null,
195
+ };
196
+ const ticks = provider === "xai" ? number(usage.cost_in_usd_ticks) : null;
197
+ const reportedUsd = number(usage.cost_usd) ?? number(body.cost_usd) ?? number(usage.cost_in_usd) ?? (ticks === null ? null : ticks / 1e10);
198
+ const hasTokens = reported.inputTokens !== null || reported.outputTokens !== null;
199
+ const price = reportedUsd !== null
200
+ ? { costUsd: reportedUsd, basis: "reported", warnings: [] }
201
+ : entry.tokenBased && hasTokens ? tokenPrice(provider, entry.model, tokens) : {};
202
+ return { status, ...(hasTokens ? tokens : {}), ...price };
203
+ }
204
+ async function costHints(engine, artifactId) {
205
+ if (!artifactId)
206
+ return undefined;
207
+ const result = await engine.metadata.artifacts.read(artifactId, "generation-cost-hints");
208
+ if (!result.ok)
209
+ return undefined;
210
+ const hints = result.value;
211
+ const durationSeconds = number(hints.durationSeconds) ?? number(hints.duration);
212
+ const inputDurationSeconds = number(hints.inputDurationSeconds) ?? number(hints.inputDuration);
213
+ return { ...(durationSeconds !== null ? { durationSeconds } : {}), ...(inputDurationSeconds !== null ? { inputDurationSeconds } : {}) };
214
+ }
215
+ export function providerUsageFetch(provider, transport = fetch) {
216
+ return async (input, init) => {
217
+ const context = currentBookContext();
218
+ if (!context)
219
+ return transport(input, init);
220
+ const engine = context.engine;
221
+ const url = new URL(input instanceof Request ? input.url : String(input));
222
+ const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
223
+ const billable = isBillable(provider, url.pathname, method);
224
+ let entry = null;
225
+ if (billable) {
226
+ const payload = await payloadOf(input, init);
227
+ const endpoint = url.pathname.replace(/^\//u, "");
228
+ const model = text(payload.model) ?? text(payload.model_id) ?? (provider === "fal" ? endpoint : endpoint.split("/").slice(-2).join("/"));
229
+ let hints;
230
+ try {
231
+ hints = await costHints(engine, context.artifactId);
232
+ }
233
+ catch {
234
+ void 0;
235
+ }
236
+ const activity = activityFor(model, url.pathname, context.operation);
237
+ entry = {
238
+ id: randomUUID(), provider, model, activity, status: "pending",
239
+ tokenBased: /\/(responses|completions|embeddings)$/u.test(url.pathname) || rateFor(provider, model)?.kind === "tokens",
240
+ operation: context.operation ?? null, artifactId: context.artifactId ?? null,
241
+ ...priceRequest(provider, model, payload, endpoint, hints),
242
+ };
243
+ safeRecord(engine, entry);
244
+ }
245
+ let response;
246
+ try {
247
+ response = await transport(input, init);
248
+ }
249
+ catch (error) {
250
+ if (entry)
251
+ safeRecord(engine, { ...entry, status: "uncertain", basis: "unknown", warnings: ["Provider outcome unavailable"] });
252
+ throw error;
253
+ }
254
+ try {
255
+ const json = response.headers.get("content-type")?.includes("json");
256
+ const body = json ? object(await response.clone().json()) : {};
257
+ const externalId = remoteId(body, url, method);
258
+ if (entry) {
259
+ const accepted = !!externalId && (provider === "kie" || provider === "fal" || /videos|tasks/u.test(url.pathname) || !!object(body.output).task_id);
260
+ const status = response.ok ? responseStatus(body, accepted) : "failed";
261
+ safeRecord(engine, { ...entry, ...(externalId ? { externalId } : {}), ...observedPatch(provider, entry, body, status) });
262
+ }
263
+ else if (method === "GET" && externalId && response.ok && json) {
264
+ const existing = engine.usage.find(provider, externalId);
265
+ if (existing) {
266
+ const status = responseStatus(body, /\/status$/u.test(url.pathname));
267
+ safeRecord(engine, { ...existing, ...observedPatch(provider, existing, body, status) });
268
+ }
269
+ }
270
+ }
271
+ catch {
272
+ if (entry)
273
+ safeRecord(engine, { ...entry, status: "uncertain", basis: "unknown", warnings: ["Provider usage unavailable"] });
274
+ }
275
+ return response;
276
+ };
277
+ }
278
+ export function recordVoiceUsage(engine, provider, model, sessionId, responseId, response) {
279
+ const body = object(response);
280
+ const entry = {
281
+ id: `voice:${sessionId}:${responseId}`, externalId: `voice:${sessionId}:${responseId}`,
282
+ provider, model, activity: "voice", tokenBased: true,
283
+ ...unknownPrice(),
284
+ };
285
+ safeRecord(engine, { ...entry, ...observedPatch(provider, entry, body, responseStatus(body, false)) });
286
+ }
287
+ export function recordTranscriptionUsage(engine, model, sessionId, itemId, event) {
288
+ const body = object(event);
289
+ const entry = {
290
+ id: `transcription:${sessionId}:${itemId}`, externalId: `transcription:${sessionId}:${itemId}`,
291
+ provider: "openai", model, activity: "analysis", tokenBased: true, ...unknownPrice(),
292
+ };
293
+ safeRecord(engine, { ...entry, ...observedPatch("openai", entry, body, responseStatus(body, false)) });
294
+ }