@nodetool-ai/agents 0.7.0-rc.23 → 0.8.2

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 (1645) hide show
  1. package/README.md +35 -0
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/analysis/audio-dsp.d.ts +224 -0
  4. package/dist/analysis/audio-dsp.d.ts.map +1 -0
  5. package/dist/analysis/audio-dsp.js +645 -0
  6. package/dist/analysis/audio-dsp.js.map +1 -0
  7. package/dist/analysis/media-decode.d.ts +98 -0
  8. package/dist/analysis/media-decode.d.ts.map +1 -0
  9. package/dist/analysis/media-decode.js +226 -0
  10. package/dist/analysis/media-decode.js.map +1 -0
  11. package/dist/analysis/mediabunny-runtime.d.ts +15 -0
  12. package/dist/analysis/mediabunny-runtime.d.ts.map +1 -0
  13. package/dist/analysis/mediabunny-runtime.js +30 -0
  14. package/dist/analysis/mediabunny-runtime.js.map +1 -0
  15. package/dist/analysis/video-frames.d.ts +120 -0
  16. package/dist/analysis/video-frames.d.ts.map +1 -0
  17. package/dist/analysis/video-frames.js +288 -0
  18. package/dist/analysis/video-frames.js.map +1 -0
  19. package/dist/apify/assets.d.ts +80 -0
  20. package/dist/apify/assets.d.ts.map +1 -0
  21. package/dist/apify/assets.js +192 -0
  22. package/dist/apify/assets.js.map +1 -0
  23. package/dist/apify/catalog.d.ts +44 -0
  24. package/dist/apify/catalog.d.ts.map +1 -0
  25. package/dist/apify/catalog.js +108 -0
  26. package/dist/apify/catalog.js.map +1 -0
  27. package/dist/apify/client.d.ts +137 -0
  28. package/dist/apify/client.d.ts.map +1 -0
  29. package/dist/apify/client.js +346 -0
  30. package/dist/apify/client.js.map +1 -0
  31. package/dist/apify/errors.d.ts +85 -0
  32. package/dist/apify/errors.d.ts.map +1 -0
  33. package/dist/apify/errors.js +90 -0
  34. package/dist/apify/errors.js.map +1 -0
  35. package/dist/apify/normalize.d.ts +131 -0
  36. package/dist/apify/normalize.d.ts.map +1 -0
  37. package/dist/apify/normalize.js +202 -0
  38. package/dist/apify/normalize.js.map +1 -0
  39. package/dist/apify/policy.d.ts +136 -0
  40. package/dist/apify/policy.d.ts.map +1 -0
  41. package/dist/apify/policy.js +223 -0
  42. package/dist/apify/policy.js.map +1 -0
  43. package/dist/apify/run.d.ts +86 -0
  44. package/dist/apify/run.d.ts.map +1 -0
  45. package/dist/apify/run.js +158 -0
  46. package/dist/apify/run.js.map +1 -0
  47. package/dist/app-build/author.d.ts +67 -0
  48. package/dist/app-build/author.d.ts.map +1 -0
  49. package/dist/app-build/author.js +231 -0
  50. package/dist/app-build/author.js.map +1 -0
  51. package/dist/app-build/bridge.d.ts +130 -0
  52. package/dist/app-build/bridge.d.ts.map +1 -0
  53. package/dist/app-build/bridge.js +647 -0
  54. package/dist/app-build/bridge.js.map +1 -0
  55. package/dist/app-build/build-service.d.ts +66 -0
  56. package/dist/app-build/build-service.d.ts.map +1 -0
  57. package/dist/app-build/build-service.js +249 -0
  58. package/dist/app-build/build-service.js.map +1 -0
  59. package/dist/app-build/build.d.ts +115 -0
  60. package/dist/app-build/build.d.ts.map +1 -0
  61. package/dist/app-build/build.js +901 -0
  62. package/dist/app-build/build.js.map +1 -0
  63. package/dist/app-build/interactions.d.ts +20 -0
  64. package/dist/app-build/interactions.d.ts.map +1 -0
  65. package/dist/app-build/interactions.js +121 -0
  66. package/dist/app-build/interactions.js.map +1 -0
  67. package/dist/app-build/judge.d.ts +113 -0
  68. package/dist/app-build/judge.d.ts.map +1 -0
  69. package/dist/app-build/judge.js +318 -0
  70. package/dist/app-build/judge.js.map +1 -0
  71. package/dist/app-build/markdown.d.ts +10 -0
  72. package/dist/app-build/markdown.d.ts.map +1 -0
  73. package/dist/app-build/markdown.js +65 -0
  74. package/dist/app-build/markdown.js.map +1 -0
  75. package/dist/app-build/spec.d.ts +228 -0
  76. package/dist/app-build/spec.d.ts.map +1 -0
  77. package/dist/app-build/spec.js +651 -0
  78. package/dist/app-build/spec.js.map +1 -0
  79. package/dist/app-build/tool-loop.d.ts +84 -0
  80. package/dist/app-build/tool-loop.d.ts.map +1 -0
  81. package/dist/app-build/tool-loop.js +113 -0
  82. package/dist/app-build/tool-loop.js.map +1 -0
  83. package/dist/app-build/types.d.ts +215 -0
  84. package/dist/app-build/types.d.ts.map +1 -0
  85. package/dist/app-build/types.js +28 -0
  86. package/dist/app-build/types.js.map +1 -0
  87. package/dist/author-graph.d.ts +90 -0
  88. package/dist/author-graph.d.ts.map +1 -0
  89. package/dist/author-graph.js +317 -0
  90. package/dist/author-graph.js.map +1 -0
  91. package/dist/background-subtasks.d.ts +79 -0
  92. package/dist/background-subtasks.d.ts.map +1 -0
  93. package/dist/background-subtasks.js +139 -0
  94. package/dist/background-subtasks.js.map +1 -0
  95. package/dist/blender-gate.d.ts +21 -0
  96. package/dist/blender-gate.d.ts.map +1 -0
  97. package/dist/blender-gate.js +27 -0
  98. package/dist/blender-gate.js.map +1 -0
  99. package/dist/browser-gate.d.ts +28 -0
  100. package/dist/browser-gate.d.ts.map +1 -0
  101. package/dist/browser-gate.js +34 -0
  102. package/dist/browser-gate.js.map +1 -0
  103. package/dist/capabilities/GamePublishRequest.d.ts +14 -0
  104. package/dist/capabilities/GamePublishRequest.d.ts.map +1 -0
  105. package/dist/capabilities/GamePublishRequest.js +2 -0
  106. package/dist/capabilities/GamePublishRequest.js.map +1 -0
  107. package/dist/capabilities/adapters.d.ts +27 -0
  108. package/dist/capabilities/adapters.d.ts.map +1 -0
  109. package/dist/capabilities/adapters.js +39 -0
  110. package/dist/capabilities/adapters.js.map +1 -0
  111. package/dist/capabilities/agent-activity.d.ts +27 -0
  112. package/dist/capabilities/agent-activity.d.ts.map +1 -0
  113. package/dist/capabilities/agent-activity.js +103 -0
  114. package/dist/capabilities/agent-activity.js.map +1 -0
  115. package/dist/capabilities/agentic-storyboard-finish.d.ts +67 -0
  116. package/dist/capabilities/agentic-storyboard-finish.d.ts.map +1 -0
  117. package/dist/capabilities/agentic-storyboard-finish.js +1321 -0
  118. package/dist/capabilities/agentic-storyboard-finish.js.map +1 -0
  119. package/dist/capabilities/agents.d.ts +81 -0
  120. package/dist/capabilities/agents.d.ts.map +1 -0
  121. package/dist/capabilities/agents.js +376 -0
  122. package/dist/capabilities/agents.js.map +1 -0
  123. package/dist/capabilities/agents.specs.d.ts +30 -0
  124. package/dist/capabilities/agents.specs.d.ts.map +1 -0
  125. package/dist/capabilities/agents.specs.js +313 -0
  126. package/dist/capabilities/agents.specs.js.map +1 -0
  127. package/dist/capabilities/analysis.d.ts +93 -0
  128. package/dist/capabilities/analysis.d.ts.map +1 -0
  129. package/dist/capabilities/analysis.js +823 -0
  130. package/dist/capabilities/analysis.js.map +1 -0
  131. package/dist/capabilities/analysis.specs.d.ts +39 -0
  132. package/dist/capabilities/analysis.specs.d.ts.map +1 -0
  133. package/dist/capabilities/analysis.specs.js +217 -0
  134. package/dist/capabilities/analysis.specs.js.map +1 -0
  135. package/dist/capabilities/apify.d.ts +34 -0
  136. package/dist/capabilities/apify.d.ts.map +1 -0
  137. package/dist/capabilities/apify.js +449 -0
  138. package/dist/capabilities/apify.js.map +1 -0
  139. package/dist/capabilities/apify.specs.d.ts +28 -0
  140. package/dist/capabilities/apify.specs.d.ts.map +1 -0
  141. package/dist/capabilities/apify.specs.js +232 -0
  142. package/dist/capabilities/apify.specs.js.map +1 -0
  143. package/dist/capabilities/apps.d.ts +40 -0
  144. package/dist/capabilities/apps.d.ts.map +1 -0
  145. package/dist/capabilities/apps.js +415 -0
  146. package/dist/capabilities/apps.js.map +1 -0
  147. package/dist/capabilities/apps.specs.d.ts +23 -0
  148. package/dist/capabilities/apps.specs.d.ts.map +1 -0
  149. package/dist/capabilities/apps.specs.js +236 -0
  150. package/dist/capabilities/apps.specs.js.map +1 -0
  151. package/dist/capabilities/args.d.ts +62 -0
  152. package/dist/capabilities/args.d.ts.map +1 -0
  153. package/dist/capabilities/args.js +215 -0
  154. package/dist/capabilities/args.js.map +1 -0
  155. package/dist/capabilities/assets.d.ts +45 -0
  156. package/dist/capabilities/assets.d.ts.map +1 -0
  157. package/dist/capabilities/assets.js +952 -0
  158. package/dist/capabilities/assets.js.map +1 -0
  159. package/dist/capabilities/assets.specs.d.ts +54 -0
  160. package/dist/capabilities/assets.specs.d.ts.map +1 -0
  161. package/dist/capabilities/assets.specs.js +291 -0
  162. package/dist/capabilities/assets.specs.js.map +1 -0
  163. package/dist/capabilities/background-generation.d.ts +14 -0
  164. package/dist/capabilities/background-generation.d.ts.map +1 -0
  165. package/dist/capabilities/background-generation.js +29 -0
  166. package/dist/capabilities/background-generation.js.map +1 -0
  167. package/dist/capabilities/browser.d.ts +30 -0
  168. package/dist/capabilities/browser.d.ts.map +1 -0
  169. package/dist/capabilities/browser.js +250 -0
  170. package/dist/capabilities/browser.js.map +1 -0
  171. package/dist/capabilities/browser.specs.d.ts +37 -0
  172. package/dist/capabilities/browser.specs.d.ts.map +1 -0
  173. package/dist/capabilities/browser.specs.js +173 -0
  174. package/dist/capabilities/browser.specs.js.map +1 -0
  175. package/dist/capabilities/code-grading.d.ts +68 -0
  176. package/dist/capabilities/code-grading.d.ts.map +1 -0
  177. package/dist/capabilities/code-grading.js +75 -0
  178. package/dist/capabilities/code-grading.js.map +1 -0
  179. package/dist/capabilities/code.d.ts +61 -0
  180. package/dist/capabilities/code.d.ts.map +1 -0
  181. package/dist/capabilities/code.js +366 -0
  182. package/dist/capabilities/code.js.map +1 -0
  183. package/dist/capabilities/code.specs.d.ts +22 -0
  184. package/dist/capabilities/code.specs.d.ts.map +1 -0
  185. package/dist/capabilities/code.specs.js +175 -0
  186. package/dist/capabilities/code.specs.js.map +1 -0
  187. package/dist/capabilities/collections.d.ts +44 -0
  188. package/dist/capabilities/collections.d.ts.map +1 -0
  189. package/dist/capabilities/collections.js +432 -0
  190. package/dist/capabilities/collections.js.map +1 -0
  191. package/dist/capabilities/collections.specs.d.ts +25 -0
  192. package/dist/capabilities/collections.specs.d.ts.map +1 -0
  193. package/dist/capabilities/collections.specs.js +299 -0
  194. package/dist/capabilities/collections.specs.js.map +1 -0
  195. package/dist/capabilities/compositions.d.ts +57 -0
  196. package/dist/capabilities/compositions.d.ts.map +1 -0
  197. package/dist/capabilities/compositions.js +384 -0
  198. package/dist/capabilities/compositions.js.map +1 -0
  199. package/dist/capabilities/compositions.specs.d.ts +22 -0
  200. package/dist/capabilities/compositions.specs.d.ts.map +1 -0
  201. package/dist/capabilities/compositions.specs.js +126 -0
  202. package/dist/capabilities/compositions.specs.js.map +1 -0
  203. package/dist/capabilities/concurrency.d.ts +12 -0
  204. package/dist/capabilities/concurrency.d.ts.map +1 -0
  205. package/dist/capabilities/concurrency.js +30 -0
  206. package/dist/capabilities/concurrency.js.map +1 -0
  207. package/dist/capabilities/costs.d.ts +20 -0
  208. package/dist/capabilities/costs.d.ts.map +1 -0
  209. package/dist/capabilities/costs.js +40 -0
  210. package/dist/capabilities/costs.js.map +1 -0
  211. package/dist/capabilities/costs.specs.d.ts +12 -0
  212. package/dist/capabilities/costs.specs.d.ts.map +1 -0
  213. package/dist/capabilities/costs.specs.js +35 -0
  214. package/dist/capabilities/costs.specs.js.map +1 -0
  215. package/dist/capabilities/dispatcher.d.ts +57 -0
  216. package/dist/capabilities/dispatcher.d.ts.map +1 -0
  217. package/dist/capabilities/dispatcher.js +117 -0
  218. package/dist/capabilities/dispatcher.js.map +1 -0
  219. package/dist/capabilities/documents.d.ts +25 -0
  220. package/dist/capabilities/documents.d.ts.map +1 -0
  221. package/dist/capabilities/documents.js +278 -0
  222. package/dist/capabilities/documents.js.map +1 -0
  223. package/dist/capabilities/documents.specs.d.ts +18 -0
  224. package/dist/capabilities/documents.specs.d.ts.map +1 -0
  225. package/dist/capabilities/documents.specs.js +201 -0
  226. package/dist/capabilities/documents.specs.js.map +1 -0
  227. package/dist/capabilities/email.d.ts +23 -0
  228. package/dist/capabilities/email.d.ts.map +1 -0
  229. package/dist/capabilities/email.js +226 -0
  230. package/dist/capabilities/email.js.map +1 -0
  231. package/dist/capabilities/email.specs.d.ts +16 -0
  232. package/dist/capabilities/email.specs.d.ts.map +1 -0
  233. package/dist/capabilities/email.specs.js +102 -0
  234. package/dist/capabilities/email.specs.js.map +1 -0
  235. package/dist/capabilities/entities.d.ts +52 -0
  236. package/dist/capabilities/entities.d.ts.map +1 -0
  237. package/dist/capabilities/entities.js +478 -0
  238. package/dist/capabilities/entities.js.map +1 -0
  239. package/dist/capabilities/entities.specs.d.ts +25 -0
  240. package/dist/capabilities/entities.specs.d.ts.map +1 -0
  241. package/dist/capabilities/entities.specs.js +247 -0
  242. package/dist/capabilities/entities.specs.js.map +1 -0
  243. package/dist/capabilities/errors.d.ts +19 -0
  244. package/dist/capabilities/errors.d.ts.map +1 -0
  245. package/dist/capabilities/errors.js +109 -0
  246. package/dist/capabilities/errors.js.map +1 -0
  247. package/dist/capabilities/errors.specs.d.ts +11 -0
  248. package/dist/capabilities/errors.specs.d.ts.map +1 -0
  249. package/dist/capabilities/errors.specs.js +100 -0
  250. package/dist/capabilities/errors.specs.js.map +1 -0
  251. package/dist/capabilities/example-timelines.d.ts +3 -0
  252. package/dist/capabilities/example-timelines.d.ts.map +1 -0
  253. package/dist/capabilities/example-timelines.js +233 -0
  254. package/dist/capabilities/example-timelines.js.map +1 -0
  255. package/dist/capabilities/example-timelines.specs.d.ts +6 -0
  256. package/dist/capabilities/example-timelines.specs.d.ts.map +1 -0
  257. package/dist/capabilities/example-timelines.specs.js +71 -0
  258. package/dist/capabilities/example-timelines.specs.js.map +1 -0
  259. package/dist/capabilities/files.d.ts +53 -0
  260. package/dist/capabilities/files.d.ts.map +1 -0
  261. package/dist/capabilities/files.js +1172 -0
  262. package/dist/capabilities/files.js.map +1 -0
  263. package/dist/capabilities/files.specs.d.ts +28 -0
  264. package/dist/capabilities/files.specs.d.ts.map +1 -0
  265. package/dist/capabilities/files.specs.js +259 -0
  266. package/dist/capabilities/files.specs.js.map +1 -0
  267. package/dist/capabilities/finish-storyboard.d.ts +5 -0
  268. package/dist/capabilities/finish-storyboard.d.ts.map +1 -0
  269. package/dist/capabilities/finish-storyboard.js +278 -0
  270. package/dist/capabilities/finish-storyboard.js.map +1 -0
  271. package/dist/capabilities/flow.d.ts +93 -0
  272. package/dist/capabilities/flow.d.ts.map +1 -0
  273. package/dist/capabilities/flow.js +285 -0
  274. package/dist/capabilities/flow.js.map +1 -0
  275. package/dist/capabilities/flow.specs.d.ts +25 -0
  276. package/dist/capabilities/flow.specs.d.ts.map +1 -0
  277. package/dist/capabilities/flow.specs.js +114 -0
  278. package/dist/capabilities/flow.specs.js.map +1 -0
  279. package/dist/capabilities/game-asset-source.d.ts +31 -0
  280. package/dist/capabilities/game-asset-source.d.ts.map +1 -0
  281. package/dist/capabilities/game-asset-source.js +81 -0
  282. package/dist/capabilities/game-asset-source.js.map +1 -0
  283. package/dist/capabilities/game.d.ts +24 -0
  284. package/dist/capabilities/game.d.ts.map +1 -0
  285. package/dist/capabilities/game.js +1432 -0
  286. package/dist/capabilities/game.js.map +1 -0
  287. package/dist/capabilities/game.specs.d.ts +5 -0
  288. package/dist/capabilities/game.specs.d.ts.map +1 -0
  289. package/dist/capabilities/game.specs.js +110 -0
  290. package/dist/capabilities/game.specs.js.map +1 -0
  291. package/dist/capabilities/game3d.d.ts +17 -0
  292. package/dist/capabilities/game3d.d.ts.map +1 -0
  293. package/dist/capabilities/game3d.js +433 -0
  294. package/dist/capabilities/game3d.js.map +1 -0
  295. package/dist/capabilities/gate-from-context.d.ts +39 -0
  296. package/dist/capabilities/gate-from-context.d.ts.map +1 -0
  297. package/dist/capabilities/gate-from-context.js +97 -0
  298. package/dist/capabilities/gate-from-context.js.map +1 -0
  299. package/dist/capabilities/generations.d.ts +81 -0
  300. package/dist/capabilities/generations.d.ts.map +1 -0
  301. package/dist/capabilities/generations.js +387 -0
  302. package/dist/capabilities/generations.js.map +1 -0
  303. package/dist/capabilities/generations.specs.d.ts +62 -0
  304. package/dist/capabilities/generations.specs.d.ts.map +1 -0
  305. package/dist/capabilities/generations.specs.js +230 -0
  306. package/dist/capabilities/generations.specs.js.map +1 -0
  307. package/dist/capabilities/google.d.ts +50 -0
  308. package/dist/capabilities/google.d.ts.map +1 -0
  309. package/dist/capabilities/google.js +246 -0
  310. package/dist/capabilities/google.js.map +1 -0
  311. package/dist/capabilities/google.specs.d.ts +52 -0
  312. package/dist/capabilities/google.specs.d.ts.map +1 -0
  313. package/dist/capabilities/google.specs.js +391 -0
  314. package/dist/capabilities/google.specs.js.map +1 -0
  315. package/dist/capabilities/html-text.d.ts +28 -0
  316. package/dist/capabilities/html-text.d.ts.map +1 -0
  317. package/dist/capabilities/html-text.js +76 -0
  318. package/dist/capabilities/html-text.js.map +1 -0
  319. package/dist/capabilities/index.d.ts +19 -0
  320. package/dist/capabilities/index.d.ts.map +1 -0
  321. package/dist/capabilities/index.js +14 -0
  322. package/dist/capabilities/index.js.map +1 -0
  323. package/dist/capabilities/invoke.d.ts +78 -0
  324. package/dist/capabilities/invoke.d.ts.map +1 -0
  325. package/dist/capabilities/invoke.js +251 -0
  326. package/dist/capabilities/invoke.js.map +1 -0
  327. package/dist/capabilities/jobs.d.ts +32 -0
  328. package/dist/capabilities/jobs.d.ts.map +1 -0
  329. package/dist/capabilities/jobs.js +167 -0
  330. package/dist/capabilities/jobs.js.map +1 -0
  331. package/dist/capabilities/jobs.specs.d.ts +20 -0
  332. package/dist/capabilities/jobs.specs.d.ts.map +1 -0
  333. package/dist/capabilities/jobs.specs.js +105 -0
  334. package/dist/capabilities/jobs.specs.js.map +1 -0
  335. package/dist/capabilities/js-scripts.d.ts +108 -0
  336. package/dist/capabilities/js-scripts.d.ts.map +1 -0
  337. package/dist/capabilities/js-scripts.js +807 -0
  338. package/dist/capabilities/js-scripts.js.map +1 -0
  339. package/dist/capabilities/js-scripts.specs.d.ts +52 -0
  340. package/dist/capabilities/js-scripts.specs.d.ts.map +1 -0
  341. package/dist/capabilities/js-scripts.specs.js +394 -0
  342. package/dist/capabilities/js-scripts.specs.js.map +1 -0
  343. package/dist/capabilities/lazy-tool.d.ts +41 -0
  344. package/dist/capabilities/lazy-tool.d.ts.map +1 -0
  345. package/dist/capabilities/lazy-tool.js +82 -0
  346. package/dist/capabilities/lazy-tool.js.map +1 -0
  347. package/dist/capabilities/legacy-tools.d.ts +15 -0
  348. package/dist/capabilities/legacy-tools.d.ts.map +1 -0
  349. package/dist/capabilities/legacy-tools.js +98 -0
  350. package/dist/capabilities/legacy-tools.js.map +1 -0
  351. package/dist/capabilities/local-browser.d.ts +24 -0
  352. package/dist/capabilities/local-browser.d.ts.map +1 -0
  353. package/dist/capabilities/local-browser.js +105 -0
  354. package/dist/capabilities/local-browser.js.map +1 -0
  355. package/dist/capabilities/media.d.ts +112 -0
  356. package/dist/capabilities/media.d.ts.map +1 -0
  357. package/dist/capabilities/media.js +2258 -0
  358. package/dist/capabilities/media.js.map +1 -0
  359. package/dist/capabilities/media.specs.d.ts +65 -0
  360. package/dist/capabilities/media.specs.d.ts.map +1 -0
  361. package/dist/capabilities/media.specs.js +779 -0
  362. package/dist/capabilities/media.specs.js.map +1 -0
  363. package/dist/capabilities/memory.d.ts +31 -0
  364. package/dist/capabilities/memory.d.ts.map +1 -0
  365. package/dist/capabilities/memory.js +403 -0
  366. package/dist/capabilities/memory.js.map +1 -0
  367. package/dist/capabilities/memory.specs.d.ts +55 -0
  368. package/dist/capabilities/memory.specs.d.ts.map +1 -0
  369. package/dist/capabilities/memory.specs.js +208 -0
  370. package/dist/capabilities/memory.specs.js.map +1 -0
  371. package/dist/capabilities/model3d.d.ts +29 -0
  372. package/dist/capabilities/model3d.d.ts.map +1 -0
  373. package/dist/capabilities/model3d.js +482 -0
  374. package/dist/capabilities/model3d.js.map +1 -0
  375. package/dist/capabilities/model3d.specs.d.ts +28 -0
  376. package/dist/capabilities/model3d.specs.d.ts.map +1 -0
  377. package/dist/capabilities/model3d.specs.js +305 -0
  378. package/dist/capabilities/model3d.specs.js.map +1 -0
  379. package/dist/capabilities/models.d.ts +138 -0
  380. package/dist/capabilities/models.d.ts.map +1 -0
  381. package/dist/capabilities/models.js +805 -0
  382. package/dist/capabilities/models.js.map +1 -0
  383. package/dist/capabilities/models.specs.d.ts +21 -0
  384. package/dist/capabilities/models.specs.d.ts.map +1 -0
  385. package/dist/capabilities/models.specs.js +141 -0
  386. package/dist/capabilities/models.specs.js.map +1 -0
  387. package/dist/capabilities/nodes.d.ts +26 -0
  388. package/dist/capabilities/nodes.d.ts.map +1 -0
  389. package/dist/capabilities/nodes.js +266 -0
  390. package/dist/capabilities/nodes.js.map +1 -0
  391. package/dist/capabilities/nodes.specs.d.ts +20 -0
  392. package/dist/capabilities/nodes.specs.d.ts.map +1 -0
  393. package/dist/capabilities/nodes.specs.js +106 -0
  394. package/dist/capabilities/nodes.specs.js.map +1 -0
  395. package/dist/capabilities/packs.d.ts +69 -0
  396. package/dist/capabilities/packs.d.ts.map +1 -0
  397. package/dist/capabilities/packs.js +246 -0
  398. package/dist/capabilities/packs.js.map +1 -0
  399. package/dist/capabilities/packs.specs.d.ts +27 -0
  400. package/dist/capabilities/packs.specs.d.ts.map +1 -0
  401. package/dist/capabilities/packs.specs.js +64 -0
  402. package/dist/capabilities/packs.specs.js.map +1 -0
  403. package/dist/capabilities/project-scope.d.ts +12 -0
  404. package/dist/capabilities/project-scope.d.ts.map +1 -0
  405. package/dist/capabilities/project-scope.js +19 -0
  406. package/dist/capabilities/project-scope.js.map +1 -0
  407. package/dist/capabilities/projects.d.ts +23 -0
  408. package/dist/capabilities/projects.d.ts.map +1 -0
  409. package/dist/capabilities/projects.js +206 -0
  410. package/dist/capabilities/projects.js.map +1 -0
  411. package/dist/capabilities/projects.specs.d.ts +23 -0
  412. package/dist/capabilities/projects.specs.d.ts.map +1 -0
  413. package/dist/capabilities/projects.specs.js +118 -0
  414. package/dist/capabilities/projects.specs.js.map +1 -0
  415. package/dist/capabilities/registry.d.ts +111 -0
  416. package/dist/capabilities/registry.d.ts.map +1 -0
  417. package/dist/capabilities/registry.js +473 -0
  418. package/dist/capabilities/registry.js.map +1 -0
  419. package/dist/capabilities/run-agent.d.ts +19 -0
  420. package/dist/capabilities/run-agent.d.ts.map +1 -0
  421. package/dist/capabilities/run-agent.js +183 -0
  422. package/dist/capabilities/run-agent.js.map +1 -0
  423. package/dist/capabilities/runs.d.ts +9 -0
  424. package/dist/capabilities/runs.d.ts.map +1 -0
  425. package/dist/capabilities/runs.js +46 -0
  426. package/dist/capabilities/runs.js.map +1 -0
  427. package/dist/capabilities/runs.specs.d.ts +39 -0
  428. package/dist/capabilities/runs.specs.d.ts.map +1 -0
  429. package/dist/capabilities/runs.specs.js +52 -0
  430. package/dist/capabilities/runs.specs.js.map +1 -0
  431. package/dist/capabilities/script-link.d.ts +22 -0
  432. package/dist/capabilities/script-link.d.ts.map +1 -0
  433. package/dist/capabilities/script-link.js +35 -0
  434. package/dist/capabilities/script-link.js.map +1 -0
  435. package/dist/capabilities/scripts.d.ts +43 -0
  436. package/dist/capabilities/scripts.d.ts.map +1 -0
  437. package/dist/capabilities/scripts.js +1795 -0
  438. package/dist/capabilities/scripts.js.map +1 -0
  439. package/dist/capabilities/scripts.specs.d.ts +40 -0
  440. package/dist/capabilities/scripts.specs.d.ts.map +1 -0
  441. package/dist/capabilities/scripts.specs.js +319 -0
  442. package/dist/capabilities/scripts.specs.js.map +1 -0
  443. package/dist/capabilities/serpapi.d.ts +42 -0
  444. package/dist/capabilities/serpapi.d.ts.map +1 -0
  445. package/dist/capabilities/serpapi.js +262 -0
  446. package/dist/capabilities/serpapi.js.map +1 -0
  447. package/dist/capabilities/serpapi.specs.d.ts +24 -0
  448. package/dist/capabilities/serpapi.specs.d.ts.map +1 -0
  449. package/dist/capabilities/serpapi.specs.js +174 -0
  450. package/dist/capabilities/serpapi.specs.js.map +1 -0
  451. package/dist/capabilities/settings.d.ts +48 -0
  452. package/dist/capabilities/settings.d.ts.map +1 -0
  453. package/dist/capabilities/settings.js +226 -0
  454. package/dist/capabilities/settings.js.map +1 -0
  455. package/dist/capabilities/settings.specs.d.ts +42 -0
  456. package/dist/capabilities/settings.specs.d.ts.map +1 -0
  457. package/dist/capabilities/settings.specs.js +126 -0
  458. package/dist/capabilities/settings.specs.js.map +1 -0
  459. package/dist/capabilities/shared.d.ts +35 -0
  460. package/dist/capabilities/shared.d.ts.map +1 -0
  461. package/dist/capabilities/shared.js +165 -0
  462. package/dist/capabilities/shared.js.map +1 -0
  463. package/dist/capabilities/shared.specs.d.ts +19 -0
  464. package/dist/capabilities/shared.specs.d.ts.map +1 -0
  465. package/dist/capabilities/shared.specs.js +134 -0
  466. package/dist/capabilities/shared.specs.js.map +1 -0
  467. package/dist/capabilities/sketches.d.ts +52 -0
  468. package/dist/capabilities/sketches.d.ts.map +1 -0
  469. package/dist/capabilities/sketches.js +1165 -0
  470. package/dist/capabilities/sketches.js.map +1 -0
  471. package/dist/capabilities/sketches.specs.d.ts +44 -0
  472. package/dist/capabilities/sketches.specs.d.ts.map +1 -0
  473. package/dist/capabilities/sketches.specs.js +392 -0
  474. package/dist/capabilities/sketches.specs.js.map +1 -0
  475. package/dist/capabilities/skills.d.ts +28 -0
  476. package/dist/capabilities/skills.d.ts.map +1 -0
  477. package/dist/capabilities/skills.js +289 -0
  478. package/dist/capabilities/skills.js.map +1 -0
  479. package/dist/capabilities/skills.specs.d.ts +17 -0
  480. package/dist/capabilities/skills.specs.d.ts.map +1 -0
  481. package/dist/capabilities/skills.specs.js +108 -0
  482. package/dist/capabilities/skills.specs.js.map +1 -0
  483. package/dist/capabilities/storyboard-layout-check.d.ts +33 -0
  484. package/dist/capabilities/storyboard-layout-check.d.ts.map +1 -0
  485. package/dist/capabilities/storyboard-layout-check.js +229 -0
  486. package/dist/capabilities/storyboard-layout-check.js.map +1 -0
  487. package/dist/capabilities/storyboard-measured-sources.d.ts +10 -0
  488. package/dist/capabilities/storyboard-measured-sources.d.ts.map +1 -0
  489. package/dist/capabilities/storyboard-measured-sources.js +67 -0
  490. package/dist/capabilities/storyboard-measured-sources.js.map +1 -0
  491. package/dist/capabilities/storyboard-review-times.d.ts +4 -0
  492. package/dist/capabilities/storyboard-review-times.d.ts.map +1 -0
  493. package/dist/capabilities/storyboard-review-times.js +39 -0
  494. package/dist/capabilities/storyboard-review-times.js.map +1 -0
  495. package/dist/capabilities/storyboards.d.ts +52 -0
  496. package/dist/capabilities/storyboards.d.ts.map +1 -0
  497. package/dist/capabilities/storyboards.js +2467 -0
  498. package/dist/capabilities/storyboards.js.map +1 -0
  499. package/dist/capabilities/storyboards.specs.d.ts +45 -0
  500. package/dist/capabilities/storyboards.specs.d.ts.map +1 -0
  501. package/dist/capabilities/storyboards.specs.js +457 -0
  502. package/dist/capabilities/storyboards.specs.js.map +1 -0
  503. package/dist/capabilities/threads.d.ts +25 -0
  504. package/dist/capabilities/threads.d.ts.map +1 -0
  505. package/dist/capabilities/threads.js +240 -0
  506. package/dist/capabilities/threads.js.map +1 -0
  507. package/dist/capabilities/threads.specs.d.ts +26 -0
  508. package/dist/capabilities/threads.specs.d.ts.map +1 -0
  509. package/dist/capabilities/threads.specs.js +108 -0
  510. package/dist/capabilities/threads.specs.js.map +1 -0
  511. package/dist/capabilities/timeline-audio-bake.d.ts +114 -0
  512. package/dist/capabilities/timeline-audio-bake.d.ts.map +1 -0
  513. package/dist/capabilities/timeline-audio-bake.js +188 -0
  514. package/dist/capabilities/timeline-audio-bake.js.map +1 -0
  515. package/dist/capabilities/timeline-bake.d.ts +21 -0
  516. package/dist/capabilities/timeline-bake.d.ts.map +1 -0
  517. package/dist/capabilities/timeline-bake.js +118 -0
  518. package/dist/capabilities/timeline-bake.js.map +1 -0
  519. package/dist/capabilities/timeline-bridge.d.ts +359 -0
  520. package/dist/capabilities/timeline-bridge.d.ts.map +1 -0
  521. package/dist/capabilities/timeline-bridge.js +1016 -0
  522. package/dist/capabilities/timeline-bridge.js.map +1 -0
  523. package/dist/capabilities/timeline-clip-frames.d.ts +17 -0
  524. package/dist/capabilities/timeline-clip-frames.d.ts.map +1 -0
  525. package/dist/capabilities/timeline-clip-frames.js +84 -0
  526. package/dist/capabilities/timeline-clip-frames.js.map +1 -0
  527. package/dist/capabilities/timeline-isolate-subject.d.ts +157 -0
  528. package/dist/capabilities/timeline-isolate-subject.d.ts.map +1 -0
  529. package/dist/capabilities/timeline-isolate-subject.js +293 -0
  530. package/dist/capabilities/timeline-isolate-subject.js.map +1 -0
  531. package/dist/capabilities/timeline-media-edit.d.ts +8 -0
  532. package/dist/capabilities/timeline-media-edit.d.ts.map +1 -0
  533. package/dist/capabilities/timeline-media-edit.js +94 -0
  534. package/dist/capabilities/timeline-media-edit.js.map +1 -0
  535. package/dist/capabilities/timeline-native-media.d.ts +4 -0
  536. package/dist/capabilities/timeline-native-media.d.ts.map +1 -0
  537. package/dist/capabilities/timeline-native-media.js +960 -0
  538. package/dist/capabilities/timeline-native-media.js.map +1 -0
  539. package/dist/capabilities/timeline-track-object.d.ts +83 -0
  540. package/dist/capabilities/timeline-track-object.d.ts.map +1 -0
  541. package/dist/capabilities/timeline-track-object.js +195 -0
  542. package/dist/capabilities/timeline-track-object.js.map +1 -0
  543. package/dist/capabilities/timelines.d.ts +250 -0
  544. package/dist/capabilities/timelines.d.ts.map +1 -0
  545. package/dist/capabilities/timelines.js +2825 -0
  546. package/dist/capabilities/timelines.js.map +1 -0
  547. package/dist/capabilities/timelines.specs.d.ts +142 -0
  548. package/dist/capabilities/timelines.specs.d.ts.map +1 -0
  549. package/dist/capabilities/timelines.specs.js +1527 -0
  550. package/dist/capabilities/timelines.specs.js.map +1 -0
  551. package/dist/capabilities/types.d.ts +199 -0
  552. package/dist/capabilities/types.d.ts.map +1 -0
  553. package/dist/capabilities/types.js +19 -0
  554. package/dist/capabilities/types.js.map +1 -0
  555. package/dist/capabilities/ui.d.ts +38 -0
  556. package/dist/capabilities/ui.d.ts.map +1 -0
  557. package/dist/capabilities/ui.js +150 -0
  558. package/dist/capabilities/ui.js.map +1 -0
  559. package/dist/capabilities/ui.specs.d.ts +22 -0
  560. package/dist/capabilities/ui.specs.d.ts.map +1 -0
  561. package/dist/capabilities/ui.specs.js +59 -0
  562. package/dist/capabilities/ui.specs.js.map +1 -0
  563. package/dist/capabilities/video-production-acceptance.d.ts +27 -0
  564. package/dist/capabilities/video-production-acceptance.d.ts.map +1 -0
  565. package/dist/capabilities/video-production-acceptance.js +41 -0
  566. package/dist/capabilities/video-production-acceptance.js.map +1 -0
  567. package/dist/capabilities/video-production.d.ts +179 -0
  568. package/dist/capabilities/video-production.d.ts.map +1 -0
  569. package/dist/capabilities/video-production.js +1492 -0
  570. package/dist/capabilities/video-production.js.map +1 -0
  571. package/dist/capabilities/video-production.specs.d.ts +13 -0
  572. package/dist/capabilities/video-production.specs.d.ts.map +1 -0
  573. package/dist/capabilities/video-production.specs.js +256 -0
  574. package/dist/capabilities/video-production.specs.js.map +1 -0
  575. package/dist/capabilities/web.d.ts +86 -0
  576. package/dist/capabilities/web.d.ts.map +1 -0
  577. package/dist/capabilities/web.js +850 -0
  578. package/dist/capabilities/web.js.map +1 -0
  579. package/dist/capabilities/web.specs.d.ts +33 -0
  580. package/dist/capabilities/web.specs.d.ts.map +1 -0
  581. package/dist/capabilities/web.specs.js +286 -0
  582. package/dist/capabilities/web.specs.js.map +1 -0
  583. package/dist/capabilities/workflows.d.ts +58 -0
  584. package/dist/capabilities/workflows.d.ts.map +1 -0
  585. package/dist/capabilities/workflows.js +1557 -0
  586. package/dist/capabilities/workflows.js.map +1 -0
  587. package/dist/capabilities/workflows.specs.d.ts +63 -0
  588. package/dist/capabilities/workflows.specs.d.ts.map +1 -0
  589. package/dist/capabilities/workflows.specs.js +858 -0
  590. package/dist/capabilities/workflows.specs.js.map +1 -0
  591. package/dist/code-gen/analyze.d.ts +26 -0
  592. package/dist/code-gen/analyze.d.ts.map +1 -0
  593. package/dist/code-gen/analyze.js +79 -0
  594. package/dist/code-gen/analyze.js.map +1 -0
  595. package/dist/code-gen/port-types.d.ts +58 -0
  596. package/dist/code-gen/port-types.d.ts.map +1 -0
  597. package/dist/code-gen/port-types.js +115 -0
  598. package/dist/code-gen/port-types.js.map +1 -0
  599. package/dist/code-gen/prompt.d.ts +37 -0
  600. package/dist/code-gen/prompt.d.ts.map +1 -0
  601. package/dist/code-gen/prompt.js +129 -0
  602. package/dist/code-gen/prompt.js.map +1 -0
  603. package/dist/code-gen/sandbox-manifest.d.ts +120 -0
  604. package/dist/code-gen/sandbox-manifest.d.ts.map +1 -0
  605. package/dist/code-gen/sandbox-manifest.js +1023 -0
  606. package/dist/code-gen/sandbox-manifest.js.map +1 -0
  607. package/dist/code-gen/sandbox-prompt.d.ts +26 -0
  608. package/dist/code-gen/sandbox-prompt.d.ts.map +1 -0
  609. package/dist/code-gen/sandbox-prompt.js +126 -0
  610. package/dist/code-gen/sandbox-prompt.js.map +1 -0
  611. package/dist/code-planner.d.ts +72 -0
  612. package/dist/code-planner.d.ts.map +1 -0
  613. package/dist/code-planner.js +271 -0
  614. package/dist/code-planner.js.map +1 -0
  615. package/dist/codeact/action-diagnostics.d.ts +35 -0
  616. package/dist/codeact/action-diagnostics.d.ts.map +1 -0
  617. package/dist/codeact/action-diagnostics.js +197 -0
  618. package/dist/codeact/action-diagnostics.js.map +1 -0
  619. package/dist/codeact/capability-modules.d.ts +66 -0
  620. package/dist/codeact/capability-modules.d.ts.map +1 -0
  621. package/dist/codeact/capability-modules.js +278 -0
  622. package/dist/codeact/capability-modules.js.map +1 -0
  623. package/dist/codeact/chat-codeact.d.ts +104 -0
  624. package/dist/codeact/chat-codeact.d.ts.map +1 -0
  625. package/dist/codeact/chat-codeact.js +424 -0
  626. package/dist/codeact/chat-codeact.js.map +1 -0
  627. package/dist/codeact/codeact-executor.d.ts +247 -0
  628. package/dist/codeact/codeact-executor.d.ts.map +1 -0
  629. package/dist/codeact/codeact-executor.js +1184 -0
  630. package/dist/codeact/codeact-executor.js.map +1 -0
  631. package/dist/codeact/compact-ids.d.ts +28 -0
  632. package/dist/codeact/compact-ids.d.ts.map +1 -0
  633. package/dist/codeact/compact-ids.js +81 -0
  634. package/dist/codeact/compact-ids.js.map +1 -0
  635. package/dist/codeact/execute-code-contract.d.ts +97 -0
  636. package/dist/codeact/execute-code-contract.d.ts.map +1 -0
  637. package/dist/codeact/execute-code-contract.js +225 -0
  638. package/dist/codeact/execute-code-contract.js.map +1 -0
  639. package/dist/codeact/fabric-package.d.ts +29 -0
  640. package/dist/codeact/fabric-package.d.ts.map +1 -0
  641. package/dist/codeact/fabric-package.js +62 -0
  642. package/dist/codeact/fabric-package.js.map +1 -0
  643. package/dist/codeact/flow-package.d.ts +31 -0
  644. package/dist/codeact/flow-package.d.ts.map +1 -0
  645. package/dist/codeact/flow-package.js +80 -0
  646. package/dist/codeact/flow-package.js.map +1 -0
  647. package/dist/codeact/graph-dsl-package.d.ts +42 -0
  648. package/dist/codeact/graph-dsl-package.d.ts.map +1 -0
  649. package/dist/codeact/graph-dsl-package.js +100 -0
  650. package/dist/codeact/graph-dsl-package.js.map +1 -0
  651. package/dist/codeact/graph-model.d.ts +30 -0
  652. package/dist/codeact/graph-model.d.ts.map +1 -0
  653. package/dist/codeact/graph-model.js +407 -0
  654. package/dist/codeact/graph-model.js.map +1 -0
  655. package/dist/codeact/mcp-guest-contract.d.ts +66 -0
  656. package/dist/codeact/mcp-guest-contract.d.ts.map +1 -0
  657. package/dist/codeact/mcp-guest-contract.js +108 -0
  658. package/dist/codeact/mcp-guest-contract.js.map +1 -0
  659. package/dist/codeact/nodetool-api.d.ts +60 -0
  660. package/dist/codeact/nodetool-api.d.ts.map +1 -0
  661. package/dist/codeact/nodetool-api.js +1974 -0
  662. package/dist/codeact/nodetool-api.js.map +1 -0
  663. package/dist/codeact/prompt.d.ts +88 -0
  664. package/dist/codeact/prompt.d.ts.map +1 -0
  665. package/dist/codeact/prompt.js +326 -0
  666. package/dist/codeact/prompt.js.map +1 -0
  667. package/dist/codeact/sandbox-package-docs.d.ts +48 -0
  668. package/dist/codeact/sandbox-package-docs.d.ts.map +1 -0
  669. package/dist/codeact/sandbox-package-docs.js +55 -0
  670. package/dist/codeact/sandbox-package-docs.js.map +1 -0
  671. package/dist/codeact/sandbox-package-listing.d.ts +81 -0
  672. package/dist/codeact/sandbox-package-listing.d.ts.map +1 -0
  673. package/dist/codeact/sandbox-package-listing.js +101 -0
  674. package/dist/codeact/sandbox-package-listing.js.map +1 -0
  675. package/dist/codeact/sandbox-packages.d.ts +72 -0
  676. package/dist/codeact/sandbox-packages.d.ts.map +1 -0
  677. package/dist/codeact/sandbox-packages.js +230 -0
  678. package/dist/codeact/sandbox-packages.js.map +1 -0
  679. package/dist/codeact/timeline-package.d.ts +5 -0
  680. package/dist/codeact/timeline-package.d.ts.map +1 -0
  681. package/dist/codeact/timeline-package.js +10 -0
  682. package/dist/codeact/timeline-package.js.map +1 -0
  683. package/dist/codeact/tool-api.d.ts +200 -0
  684. package/dist/codeact/tool-api.d.ts.map +1 -0
  685. package/dist/codeact/tool-api.js +452 -0
  686. package/dist/codeact/tool-api.js.map +1 -0
  687. package/dist/codeact/tools-prelude.d.ts +32 -0
  688. package/dist/codeact/tools-prelude.d.ts.map +1 -0
  689. package/dist/codeact/tools-prelude.js +65 -0
  690. package/dist/codeact/tools-prelude.js.map +1 -0
  691. package/dist/constants.d.ts +47 -2
  692. package/dist/constants.d.ts.map +1 -1
  693. package/dist/constants.js +64 -2
  694. package/dist/constants.js.map +1 -1
  695. package/dist/custom-animation-bake.d.ts +57 -0
  696. package/dist/custom-animation-bake.d.ts.map +1 -0
  697. package/dist/custom-animation-bake.js +88 -0
  698. package/dist/custom-animation-bake.js.map +1 -0
  699. package/dist/dynamic-slots.d.ts +72 -0
  700. package/dist/dynamic-slots.d.ts.map +1 -0
  701. package/dist/dynamic-slots.js +0 -0
  702. package/dist/dynamic-slots.js.map +1 -0
  703. package/dist/evals/app-build-cases.d.ts +35 -0
  704. package/dist/evals/app-build-cases.d.ts.map +1 -0
  705. package/dist/evals/app-build-cases.js +722 -0
  706. package/dist/evals/app-build-cases.js.map +1 -0
  707. package/dist/evals/app-build-eval.d.ts +208 -0
  708. package/dist/evals/app-build-eval.d.ts.map +1 -0
  709. package/dist/evals/app-build-eval.js +518 -0
  710. package/dist/evals/app-build-eval.js.map +1 -0
  711. package/dist/evals/app-build-plan.d.ts +76 -0
  712. package/dist/evals/app-build-plan.d.ts.map +1 -0
  713. package/dist/evals/app-build-plan.js +140 -0
  714. package/dist/evals/app-build-plan.js.map +1 -0
  715. package/dist/evals/code-gen-cases.d.ts +13 -0
  716. package/dist/evals/code-gen-cases.d.ts.map +1 -0
  717. package/dist/evals/code-gen-cases.js +124 -0
  718. package/dist/evals/code-gen-cases.js.map +1 -0
  719. package/dist/evals/code-gen-eval.d.ts +109 -0
  720. package/dist/evals/code-gen-eval.d.ts.map +1 -0
  721. package/dist/evals/code-gen-eval.js +299 -0
  722. package/dist/evals/code-gen-eval.js.map +1 -0
  723. package/dist/evals/codeact-api-cases.d.ts +14 -0
  724. package/dist/evals/codeact-api-cases.d.ts.map +1 -0
  725. package/dist/evals/codeact-api-cases.js +31 -0
  726. package/dist/evals/codeact-api-cases.js.map +1 -0
  727. package/dist/evals/codeact-api-core.d.ts +23 -0
  728. package/dist/evals/codeact-api-core.d.ts.map +1 -0
  729. package/dist/evals/codeact-api-core.js +1411 -0
  730. package/dist/evals/codeact-api-core.js.map +1 -0
  731. package/dist/evals/codeact-api-runs.d.ts +3 -0
  732. package/dist/evals/codeact-api-runs.d.ts.map +1 -0
  733. package/dist/evals/codeact-api-runs.js +33 -0
  734. package/dist/evals/codeact-api-runs.js.map +1 -0
  735. package/dist/evals/codeact-api-surfaces.d.ts +25 -0
  736. package/dist/evals/codeact-api-surfaces.d.ts.map +1 -0
  737. package/dist/evals/codeact-api-surfaces.js +2191 -0
  738. package/dist/evals/codeact-api-surfaces.js.map +1 -0
  739. package/dist/evals/codeact-cases.d.ts +76 -0
  740. package/dist/evals/codeact-cases.d.ts.map +1 -0
  741. package/dist/evals/codeact-cases.js +151 -0
  742. package/dist/evals/codeact-cases.js.map +1 -0
  743. package/dist/evals/codeact-eval.d.ts +66 -0
  744. package/dist/evals/codeact-eval.d.ts.map +1 -0
  745. package/dist/evals/codeact-eval.js +250 -0
  746. package/dist/evals/codeact-eval.js.map +1 -0
  747. package/dist/evals/codeact-sandbox-pack-cases.d.ts +31 -0
  748. package/dist/evals/codeact-sandbox-pack-cases.d.ts.map +1 -0
  749. package/dist/evals/codeact-sandbox-pack-cases.js +219 -0
  750. package/dist/evals/codeact-sandbox-pack-cases.js.map +1 -0
  751. package/dist/evals/escalation-cases.d.ts +22 -0
  752. package/dist/evals/escalation-cases.d.ts.map +1 -0
  753. package/dist/evals/escalation-cases.js +343 -0
  754. package/dist/evals/escalation-cases.js.map +1 -0
  755. package/dist/evals/escalation.d.ts +92 -0
  756. package/dist/evals/escalation.d.ts.map +1 -0
  757. package/dist/evals/escalation.js +152 -0
  758. package/dist/evals/escalation.js.map +1 -0
  759. package/dist/evals/goal-judge.d.ts +51 -0
  760. package/dist/evals/goal-judge.d.ts.map +1 -0
  761. package/dist/evals/goal-judge.js +152 -0
  762. package/dist/evals/goal-judge.js.map +1 -0
  763. package/dist/evals/graph-e2e-cases.d.ts +21 -0
  764. package/dist/evals/graph-e2e-cases.d.ts.map +1 -0
  765. package/dist/evals/graph-e2e-cases.js +262 -0
  766. package/dist/evals/graph-e2e-cases.js.map +1 -0
  767. package/dist/evals/graph-e2e-eval.d.ts +202 -0
  768. package/dist/evals/graph-e2e-eval.d.ts.map +1 -0
  769. package/dist/evals/graph-e2e-eval.js +438 -0
  770. package/dist/evals/graph-e2e-eval.js.map +1 -0
  771. package/dist/evals/graph-planner-cases.d.ts +12 -0
  772. package/dist/evals/graph-planner-cases.d.ts.map +1 -0
  773. package/dist/evals/graph-planner-cases.js +256 -0
  774. package/dist/evals/graph-planner-cases.js.map +1 -0
  775. package/dist/evals/graph-planner-eval.d.ts +178 -0
  776. package/dist/evals/graph-planner-eval.d.ts.map +1 -0
  777. package/dist/evals/graph-planner-eval.js +495 -0
  778. package/dist/evals/graph-planner-eval.js.map +1 -0
  779. package/dist/evals/planner-tools.d.ts +21 -0
  780. package/dist/evals/planner-tools.d.ts.map +1 -0
  781. package/dist/evals/planner-tools.js +66 -0
  782. package/dist/evals/planner-tools.js.map +1 -0
  783. package/dist/evals/subtask-cases.d.ts +88 -0
  784. package/dist/evals/subtask-cases.d.ts.map +1 -0
  785. package/dist/evals/subtask-cases.js +322 -0
  786. package/dist/evals/subtask-cases.js.map +1 -0
  787. package/dist/evals/subtask-eval.d.ts +129 -0
  788. package/dist/evals/subtask-eval.d.ts.map +1 -0
  789. package/dist/evals/subtask-eval.js +397 -0
  790. package/dist/evals/subtask-eval.js.map +1 -0
  791. package/dist/evals/surfaces/app.d.ts +19 -0
  792. package/dist/evals/surfaces/app.d.ts.map +1 -0
  793. package/dist/evals/surfaces/app.js +341 -0
  794. package/dist/evals/surfaces/app.js.map +1 -0
  795. package/dist/evals/surfaces/creative-pipeline.d.ts +203 -0
  796. package/dist/evals/surfaces/creative-pipeline.d.ts.map +1 -0
  797. package/dist/evals/surfaces/creative-pipeline.js +909 -0
  798. package/dist/evals/surfaces/creative-pipeline.js.map +1 -0
  799. package/dist/evals/surfaces/game.d.ts +5 -0
  800. package/dist/evals/surfaces/game.d.ts.map +1 -0
  801. package/dist/evals/surfaces/game.js +42 -0
  802. package/dist/evals/surfaces/game.js.map +1 -0
  803. package/dist/evals/surfaces/js-script.d.ts +66 -0
  804. package/dist/evals/surfaces/js-script.d.ts.map +1 -0
  805. package/dist/evals/surfaces/js-script.js +407 -0
  806. package/dist/evals/surfaces/js-script.js.map +1 -0
  807. package/dist/evals/surfaces/memory.d.ts +34 -0
  808. package/dist/evals/surfaces/memory.d.ts.map +1 -0
  809. package/dist/evals/surfaces/memory.js +264 -0
  810. package/dist/evals/surfaces/memory.js.map +1 -0
  811. package/dist/evals/surfaces/model3d.d.ts +45 -0
  812. package/dist/evals/surfaces/model3d.d.ts.map +1 -0
  813. package/dist/evals/surfaces/model3d.js +346 -0
  814. package/dist/evals/surfaces/model3d.js.map +1 -0
  815. package/dist/evals/surfaces/script.d.ts +96 -0
  816. package/dist/evals/surfaces/script.d.ts.map +1 -0
  817. package/dist/evals/surfaces/script.js +709 -0
  818. package/dist/evals/surfaces/script.js.map +1 -0
  819. package/dist/evals/surfaces/sketch.d.ts +126 -0
  820. package/dist/evals/surfaces/sketch.d.ts.map +1 -0
  821. package/dist/evals/surfaces/sketch.js +1306 -0
  822. package/dist/evals/surfaces/sketch.js.map +1 -0
  823. package/dist/evals/surfaces/storyboard.d.ts +97 -0
  824. package/dist/evals/surfaces/storyboard.d.ts.map +1 -0
  825. package/dist/evals/surfaces/storyboard.js +693 -0
  826. package/dist/evals/surfaces/storyboard.js.map +1 -0
  827. package/dist/evals/surfaces/timeline.d.ts +63 -0
  828. package/dist/evals/surfaces/timeline.d.ts.map +1 -0
  829. package/dist/evals/surfaces/timeline.js +655 -0
  830. package/dist/evals/surfaces/timeline.js.map +1 -0
  831. package/dist/evals/task-planner-cases.d.ts +57 -0
  832. package/dist/evals/task-planner-cases.d.ts.map +1 -0
  833. package/dist/evals/task-planner-cases.js +117 -0
  834. package/dist/evals/task-planner-cases.js.map +1 -0
  835. package/dist/evals/task-planner-eval.d.ts +101 -0
  836. package/dist/evals/task-planner-eval.d.ts.map +1 -0
  837. package/dist/evals/task-planner-eval.js +380 -0
  838. package/dist/evals/task-planner-eval.js.map +1 -0
  839. package/dist/evals/tool-loop-bridge.d.ts +61 -0
  840. package/dist/evals/tool-loop-bridge.d.ts.map +1 -0
  841. package/dist/evals/tool-loop-bridge.js +129 -0
  842. package/dist/evals/tool-loop-bridge.js.map +1 -0
  843. package/dist/evals/tool-loop-cases.d.ts +21 -0
  844. package/dist/evals/tool-loop-cases.d.ts.map +1 -0
  845. package/dist/evals/tool-loop-cases.js +401 -0
  846. package/dist/evals/tool-loop-cases.js.map +1 -0
  847. package/dist/evals/tool-loop-eval.d.ts +236 -0
  848. package/dist/evals/tool-loop-eval.d.ts.map +1 -0
  849. package/dist/evals/tool-loop-eval.js +378 -0
  850. package/dist/evals/tool-loop-eval.js.map +1 -0
  851. package/dist/evals/tool-loop-permission.d.ts +29 -0
  852. package/dist/evals/tool-loop-permission.d.ts.map +1 -0
  853. package/dist/evals/tool-loop-permission.js +58 -0
  854. package/dist/evals/tool-loop-permission.js.map +1 -0
  855. package/dist/game-authoring.d.ts +4737 -0
  856. package/dist/game-authoring.d.ts.map +1 -0
  857. package/dist/game-authoring.js +146 -0
  858. package/dist/game-authoring.js.map +1 -0
  859. package/dist/game-code-bake.d.ts +26 -0
  860. package/dist/game-code-bake.d.ts.map +1 -0
  861. package/dist/game-code-bake.js +98 -0
  862. package/dist/game-code-bake.js.map +1 -0
  863. package/dist/game-examples.d.ts +1303 -0
  864. package/dist/game-examples.d.ts.map +1 -0
  865. package/dist/game-examples.js +188 -0
  866. package/dist/game-examples.js.map +1 -0
  867. package/dist/graph-builder.d.ts +55 -3
  868. package/dist/graph-builder.d.ts.map +1 -1
  869. package/dist/graph-builder.js +159 -4
  870. package/dist/graph-builder.js.map +1 -1
  871. package/dist/graph-dsl-core.d.ts +25 -0
  872. package/dist/graph-dsl-core.d.ts.map +1 -0
  873. package/dist/graph-dsl-core.js +312 -0
  874. package/dist/graph-dsl-core.js.map +1 -0
  875. package/dist/graph-dsl.d.ts +30 -0
  876. package/dist/graph-dsl.d.ts.map +1 -0
  877. package/dist/graph-dsl.js +116 -0
  878. package/dist/graph-dsl.js.map +1 -0
  879. package/dist/host-binaries.d.ts +6 -0
  880. package/dist/host-binaries.d.ts.map +1 -0
  881. package/dist/host-binaries.js +6 -0
  882. package/dist/host-binaries.js.map +1 -0
  883. package/dist/host-binary-guard.d.ts +100 -0
  884. package/dist/host-binary-guard.d.ts.map +1 -0
  885. package/dist/host-binary-guard.js +205 -0
  886. package/dist/host-binary-guard.js.map +1 -0
  887. package/dist/host-modules/aws.d.ts +57 -0
  888. package/dist/host-modules/aws.d.ts.map +1 -0
  889. package/dist/host-modules/aws.js +309 -0
  890. package/dist/host-modules/aws.js.map +1 -0
  891. package/dist/host-modules/chrono.d.ts +15 -0
  892. package/dist/host-modules/chrono.d.ts.map +1 -0
  893. package/dist/host-modules/chrono.js +35 -0
  894. package/dist/host-modules/chrono.js.map +1 -0
  895. package/dist/host-modules/csv.d.ts +17 -0
  896. package/dist/host-modules/csv.d.ts.map +1 -0
  897. package/dist/host-modules/csv.js +64 -0
  898. package/dist/host-modules/csv.js.map +1 -0
  899. package/dist/host-modules/diff.d.ts +9 -0
  900. package/dist/host-modules/diff.d.ts.map +1 -0
  901. package/dist/host-modules/diff.js +26 -0
  902. package/dist/host-modules/diff.js.map +1 -0
  903. package/dist/host-modules/dispatcher.d.ts +41 -0
  904. package/dist/host-modules/dispatcher.d.ts.map +1 -0
  905. package/dist/host-modules/dispatcher.js +99 -0
  906. package/dist/host-modules/dispatcher.js.map +1 -0
  907. package/dist/host-modules/docx.d.ts +19 -0
  908. package/dist/host-modules/docx.d.ts.map +1 -0
  909. package/dist/host-modules/docx.js +120 -0
  910. package/dist/host-modules/docx.js.map +1 -0
  911. package/dist/host-modules/epub.d.ts +48 -0
  912. package/dist/host-modules/epub.d.ts.map +1 -0
  913. package/dist/host-modules/epub.js +100 -0
  914. package/dist/host-modules/epub.js.map +1 -0
  915. package/dist/host-modules/exif.d.ts +8 -0
  916. package/dist/host-modules/exif.d.ts.map +1 -0
  917. package/dist/host-modules/exif.js +19 -0
  918. package/dist/host-modules/exif.js.map +1 -0
  919. package/dist/host-modules/expr.d.ts +16 -0
  920. package/dist/host-modules/expr.d.ts.map +1 -0
  921. package/dist/host-modules/expr.js +18 -0
  922. package/dist/host-modules/expr.js.map +1 -0
  923. package/dist/host-modules/fabric.d.ts +46 -0
  924. package/dist/host-modules/fabric.d.ts.map +1 -0
  925. package/dist/host-modules/fabric.js +178 -0
  926. package/dist/host-modules/fabric.js.map +1 -0
  927. package/dist/host-modules/html.d.ts +51 -0
  928. package/dist/host-modules/html.d.ts.map +1 -0
  929. package/dist/host-modules/html.js +198 -0
  930. package/dist/host-modules/html.js.map +1 -0
  931. package/dist/host-modules/ics.d.ts +9 -0
  932. package/dist/host-modules/ics.d.ts.map +1 -0
  933. package/dist/host-modules/ics.js +35 -0
  934. package/dist/host-modules/ics.js.map +1 -0
  935. package/dist/host-modules/limits.d.ts +41 -0
  936. package/dist/host-modules/limits.d.ts.map +1 -0
  937. package/dist/host-modules/limits.js +76 -0
  938. package/dist/host-modules/limits.js.map +1 -0
  939. package/dist/host-modules/mammoth.d.ts +11 -0
  940. package/dist/host-modules/mammoth.d.ts.map +1 -0
  941. package/dist/host-modules/mammoth.js +29 -0
  942. package/dist/host-modules/mammoth.js.map +1 -0
  943. package/dist/host-modules/notion.d.ts +45 -0
  944. package/dist/host-modules/notion.d.ts.map +1 -0
  945. package/dist/host-modules/notion.js +128 -0
  946. package/dist/host-modules/notion.js.map +1 -0
  947. package/dist/host-modules/ocr.d.ts +25 -0
  948. package/dist/host-modules/ocr.d.ts.map +1 -0
  949. package/dist/host-modules/ocr.js +74 -0
  950. package/dist/host-modules/ocr.js.map +1 -0
  951. package/dist/host-modules/pdf.d.ts +21 -0
  952. package/dist/host-modules/pdf.d.ts.map +1 -0
  953. package/dist/host-modules/pdf.js +53 -0
  954. package/dist/host-modules/pdf.js.map +1 -0
  955. package/dist/host-modules/pdflib.d.ts +17 -0
  956. package/dist/host-modules/pdflib.d.ts.map +1 -0
  957. package/dist/host-modules/pdflib.js +138 -0
  958. package/dist/host-modules/pdflib.js.map +1 -0
  959. package/dist/host-modules/pptx.d.ts +19 -0
  960. package/dist/host-modules/pptx.d.ts.map +1 -0
  961. package/dist/host-modules/pptx.js +67 -0
  962. package/dist/host-modules/pptx.js.map +1 -0
  963. package/dist/host-modules/pptxgen.d.ts +13 -0
  964. package/dist/host-modules/pptxgen.d.ts.map +1 -0
  965. package/dist/host-modules/pptxgen.js +98 -0
  966. package/dist/host-modules/pptxgen.js.map +1 -0
  967. package/dist/host-modules/prepared-request.d.ts +41 -0
  968. package/dist/host-modules/prepared-request.d.ts.map +1 -0
  969. package/dist/host-modules/prepared-request.js +104 -0
  970. package/dist/host-modules/prepared-request.js.map +1 -0
  971. package/dist/host-modules/registry.d.ts +31 -0
  972. package/dist/host-modules/registry.d.ts.map +1 -0
  973. package/dist/host-modules/registry.js +193 -0
  974. package/dist/host-modules/registry.js.map +1 -0
  975. package/dist/host-modules/subtitle.d.ts +15 -0
  976. package/dist/host-modules/subtitle.d.ts.map +1 -0
  977. package/dist/host-modules/subtitle.js +45 -0
  978. package/dist/host-modules/subtitle.js.map +1 -0
  979. package/dist/host-modules/supabase.d.ts +42 -0
  980. package/dist/host-modules/supabase.d.ts.map +1 -0
  981. package/dist/host-modules/supabase.js +141 -0
  982. package/dist/host-modules/supabase.js.map +1 -0
  983. package/dist/host-modules/tfjs.d.ts +42 -0
  984. package/dist/host-modules/tfjs.d.ts.map +1 -0
  985. package/dist/host-modules/tfjs.js +186 -0
  986. package/dist/host-modules/tfjs.js.map +1 -0
  987. package/dist/host-modules/tokens.d.ts +17 -0
  988. package/dist/host-modules/tokens.d.ts.map +1 -0
  989. package/dist/host-modules/tokens.js +74 -0
  990. package/dist/host-modules/tokens.js.map +1 -0
  991. package/dist/host-modules/twilio.d.ts +34 -0
  992. package/dist/host-modules/twilio.d.ts.map +1 -0
  993. package/dist/host-modules/twilio.js +67 -0
  994. package/dist/host-modules/twilio.js.map +1 -0
  995. package/dist/host-modules/xlsx.d.ts +26 -0
  996. package/dist/host-modules/xlsx.d.ts.map +1 -0
  997. package/dist/host-modules/xlsx.js +323 -0
  998. package/dist/host-modules/xlsx.js.map +1 -0
  999. package/dist/host-modules/xml.d.ts +23 -0
  1000. package/dist/host-modules/xml.d.ts.map +1 -0
  1001. package/dist/host-modules/xml.js +38 -0
  1002. package/dist/host-modules/xml.js.map +1 -0
  1003. package/dist/host-modules/zip.d.ts +24 -0
  1004. package/dist/host-modules/zip.d.ts.map +1 -0
  1005. package/dist/host-modules/zip.js +70 -0
  1006. package/dist/host-modules/zip.js.map +1 -0
  1007. package/dist/index.d.ts +208 -60
  1008. package/dist/index.d.ts.map +1 -1
  1009. package/dist/index.js +163 -60
  1010. package/dist/index.js.map +1 -1
  1011. package/dist/js-sandbox-worker/engine.d.ts +4 -0
  1012. package/dist/js-sandbox-worker/engine.d.ts.map +1 -0
  1013. package/dist/js-sandbox-worker/engine.js +45 -0
  1014. package/dist/js-sandbox-worker/engine.js.map +1 -0
  1015. package/dist/js-sandbox-worker/host.d.ts +136 -0
  1016. package/dist/js-sandbox-worker/host.d.ts.map +1 -0
  1017. package/dist/js-sandbox-worker/host.js +482 -0
  1018. package/dist/js-sandbox-worker/host.js.map +1 -0
  1019. package/dist/js-sandbox-worker/interpreter.d.ts +276 -0
  1020. package/dist/js-sandbox-worker/interpreter.d.ts.map +1 -0
  1021. package/dist/js-sandbox-worker/interpreter.js +1293 -0
  1022. package/dist/js-sandbox-worker/interpreter.js.map +1 -0
  1023. package/dist/js-sandbox-worker/protocol.d.ts +168 -0
  1024. package/dist/js-sandbox-worker/protocol.d.ts.map +1 -0
  1025. package/dist/js-sandbox-worker/protocol.js +217 -0
  1026. package/dist/js-sandbox-worker/protocol.js.map +1 -0
  1027. package/dist/js-sandbox-worker/worker-entry.d.ts +26 -0
  1028. package/dist/js-sandbox-worker/worker-entry.d.ts.map +1 -0
  1029. package/dist/js-sandbox-worker/worker-entry.js +308 -0
  1030. package/dist/js-sandbox-worker/worker-entry.js.map +1 -0
  1031. package/dist/js-sandbox.d.ts +457 -15
  1032. package/dist/js-sandbox.d.ts.map +1 -1
  1033. package/dist/js-sandbox.js +2008 -311
  1034. package/dist/js-sandbox.js.map +1 -1
  1035. package/dist/js-script-app-runner.d.ts +11 -0
  1036. package/dist/js-script-app-runner.d.ts.map +1 -0
  1037. package/dist/js-script-app-runner.js +54 -0
  1038. package/dist/js-script-app-runner.js.map +1 -0
  1039. package/dist/js-script-sandbox.d.ts +27 -0
  1040. package/dist/js-script-sandbox.d.ts.map +1 -0
  1041. package/dist/js-script-sandbox.js +36 -0
  1042. package/dist/js-script-sandbox.js.map +1 -0
  1043. package/dist/jtbd/friction.d.ts +26 -0
  1044. package/dist/jtbd/friction.d.ts.map +1 -0
  1045. package/dist/jtbd/friction.js +169 -0
  1046. package/dist/jtbd/friction.js.map +1 -0
  1047. package/dist/jtbd/index.d.ts +6 -0
  1048. package/dist/jtbd/index.d.ts.map +1 -0
  1049. package/dist/jtbd/index.js +6 -0
  1050. package/dist/jtbd/index.js.map +1 -0
  1051. package/dist/jtbd/optimize.d.ts +71 -0
  1052. package/dist/jtbd/optimize.d.ts.map +1 -0
  1053. package/dist/jtbd/optimize.js +176 -0
  1054. package/dist/jtbd/optimize.js.map +1 -0
  1055. package/dist/jtbd/registry.d.ts +29 -0
  1056. package/dist/jtbd/registry.d.ts.map +1 -0
  1057. package/dist/jtbd/registry.js +451 -0
  1058. package/dist/jtbd/registry.js.map +1 -0
  1059. package/dist/jtbd/run.d.ts +70 -0
  1060. package/dist/jtbd/run.d.ts.map +1 -0
  1061. package/dist/jtbd/run.js +177 -0
  1062. package/dist/jtbd/run.js.map +1 -0
  1063. package/dist/jtbd/types.d.ts +141 -0
  1064. package/dist/jtbd/types.d.ts.map +1 -0
  1065. package/dist/jtbd/types.js +25 -0
  1066. package/dist/jtbd/types.js.map +1 -0
  1067. package/dist/model-prompting-skills.d.ts +45 -0
  1068. package/dist/model-prompting-skills.d.ts.map +1 -0
  1069. package/dist/model-prompting-skills.js +116 -0
  1070. package/dist/model-prompting-skills.js.map +1 -0
  1071. package/dist/network-guard.d.ts +50 -0
  1072. package/dist/network-guard.d.ts.map +1 -0
  1073. package/dist/network-guard.js +106 -0
  1074. package/dist/network-guard.js.map +1 -0
  1075. package/dist/normalize-model-properties.d.ts +26 -0
  1076. package/dist/normalize-model-properties.d.ts.map +1 -0
  1077. package/dist/normalize-model-properties.js +58 -0
  1078. package/dist/normalize-model-properties.js.map +1 -0
  1079. package/dist/output-format.d.ts +5 -1
  1080. package/dist/output-format.d.ts.map +1 -1
  1081. package/dist/output-format.js.map +1 -1
  1082. package/dist/parallel-task-executor.d.ts +68 -37
  1083. package/dist/parallel-task-executor.d.ts.map +1 -1
  1084. package/dist/parallel-task-executor.js +234 -203
  1085. package/dist/parallel-task-executor.js.map +1 -1
  1086. package/dist/prompts/background-subtask-prompt.d.ts +14 -0
  1087. package/dist/prompts/background-subtask-prompt.d.ts.map +1 -0
  1088. package/dist/prompts/background-subtask-prompt.js +64 -0
  1089. package/dist/prompts/background-subtask-prompt.js.map +1 -0
  1090. package/dist/prompts/product-knowledge.d.ts +3 -0
  1091. package/dist/prompts/product-knowledge.d.ts.map +1 -0
  1092. package/dist/prompts/product-knowledge.js +120 -0
  1093. package/dist/prompts/product-knowledge.js.map +1 -0
  1094. package/dist/prompts/read-only-search-prompt.d.ts +33 -0
  1095. package/dist/prompts/read-only-search-prompt.d.ts.map +1 -0
  1096. package/dist/prompts/read-only-search-prompt.js +109 -0
  1097. package/dist/prompts/read-only-search-prompt.js.map +1 -0
  1098. package/dist/prompts/sandbox-pack-catalog.d.ts +23 -0
  1099. package/dist/prompts/sandbox-pack-catalog.d.ts.map +1 -0
  1100. package/dist/prompts/sandbox-pack-catalog.js +40 -0
  1101. package/dist/prompts/sandbox-pack-catalog.js.map +1 -0
  1102. package/dist/prompts/security-monitor-prompt.d.ts +32 -0
  1103. package/dist/prompts/security-monitor-prompt.d.ts.map +1 -0
  1104. package/dist/prompts/security-monitor-prompt.js +99 -0
  1105. package/dist/prompts/security-monitor-prompt.js.map +1 -0
  1106. package/dist/prompts/workflow-authoring-knowledge.d.ts +77 -0
  1107. package/dist/prompts/workflow-authoring-knowledge.d.ts.map +1 -0
  1108. package/dist/prompts/workflow-authoring-knowledge.js +319 -0
  1109. package/dist/prompts/workflow-authoring-knowledge.js.map +1 -0
  1110. package/dist/run-policy.d.ts +25 -0
  1111. package/dist/run-policy.d.ts.map +1 -0
  1112. package/dist/run-policy.js +54 -0
  1113. package/dist/run-policy.js.map +1 -0
  1114. package/dist/sandbox-av-media.d.ts +33 -0
  1115. package/dist/sandbox-av-media.d.ts.map +1 -0
  1116. package/dist/sandbox-av-media.js +666 -0
  1117. package/dist/sandbox-av-media.js.map +1 -0
  1118. package/dist/sandbox-bootstrap-modules.d.ts +54 -0
  1119. package/dist/sandbox-bootstrap-modules.d.ts.map +1 -0
  1120. package/dist/sandbox-bootstrap-modules.js +104 -0
  1121. package/dist/sandbox-bootstrap-modules.js.map +1 -0
  1122. package/dist/sandbox-bytes.d.ts +43 -0
  1123. package/dist/sandbox-bytes.d.ts.map +1 -0
  1124. package/dist/sandbox-bytes.js +61 -0
  1125. package/dist/sandbox-bytes.js.map +1 -0
  1126. package/dist/sandbox-canvas-api.d.ts +30 -0
  1127. package/dist/sandbox-canvas-api.d.ts.map +1 -0
  1128. package/dist/sandbox-canvas-api.js +81 -0
  1129. package/dist/sandbox-canvas-api.js.map +1 -0
  1130. package/dist/sandbox-constants.d.ts +5 -0
  1131. package/dist/sandbox-constants.d.ts.map +1 -0
  1132. package/dist/sandbox-constants.js +13 -0
  1133. package/dist/sandbox-constants.js.map +1 -0
  1134. package/dist/sandbox-json-transport.d.ts +107 -0
  1135. package/dist/sandbox-json-transport.d.ts.map +1 -0
  1136. package/dist/sandbox-json-transport.js +324 -0
  1137. package/dist/sandbox-json-transport.js.map +1 -0
  1138. package/dist/sandbox-media-handle.d.ts +78 -0
  1139. package/dist/sandbox-media-handle.d.ts.map +1 -0
  1140. package/dist/sandbox-media-handle.js +114 -0
  1141. package/dist/sandbox-media-handle.js.map +1 -0
  1142. package/dist/sandbox-media-ref.d.ts +134 -0
  1143. package/dist/sandbox-media-ref.d.ts.map +1 -0
  1144. package/dist/sandbox-media-ref.js +442 -0
  1145. package/dist/sandbox-media-ref.js.map +1 -0
  1146. package/dist/sandbox-media.d.ts +177 -0
  1147. package/dist/sandbox-media.d.ts.map +1 -0
  1148. package/dist/sandbox-media.js +963 -0
  1149. package/dist/sandbox-media.js.map +1 -0
  1150. package/dist/sandbox-module-fixtures.d.ts +445 -0
  1151. package/dist/sandbox-module-fixtures.d.ts.map +1 -0
  1152. package/dist/sandbox-module-fixtures.js +214 -0
  1153. package/dist/sandbox-module-fixtures.js.map +1 -0
  1154. package/dist/sandbox-pack-resolution.d.ts +21 -0
  1155. package/dist/sandbox-pack-resolution.d.ts.map +1 -0
  1156. package/dist/sandbox-pack-resolution.js +42 -0
  1157. package/dist/sandbox-pack-resolution.js.map +1 -0
  1158. package/dist/sandbox-toolbelt.d.ts +15 -0
  1159. package/dist/sandbox-toolbelt.d.ts.map +1 -0
  1160. package/dist/sandbox-toolbelt.js +70 -0
  1161. package/dist/sandbox-toolbelt.js.map +1 -0
  1162. package/dist/security-monitor.d.ts +89 -0
  1163. package/dist/security-monitor.d.ts.map +1 -0
  1164. package/dist/security-monitor.js +307 -0
  1165. package/dist/security-monitor.js.map +1 -0
  1166. package/dist/serpapi/catalog.d.ts +101 -0
  1167. package/dist/serpapi/catalog.d.ts.map +1 -0
  1168. package/dist/serpapi/catalog.js +246 -0
  1169. package/dist/serpapi/catalog.js.map +1 -0
  1170. package/dist/serpapi/client.d.ts +81 -0
  1171. package/dist/serpapi/client.d.ts.map +1 -0
  1172. package/dist/serpapi/client.js +228 -0
  1173. package/dist/serpapi/client.js.map +1 -0
  1174. package/dist/serpapi/errors.d.ts +49 -0
  1175. package/dist/serpapi/errors.d.ts.map +1 -0
  1176. package/dist/serpapi/errors.js +64 -0
  1177. package/dist/serpapi/errors.js.map +1 -0
  1178. package/dist/serpapi/normalize.d.ts +58 -0
  1179. package/dist/serpapi/normalize.d.ts.map +1 -0
  1180. package/dist/serpapi/normalize.js +140 -0
  1181. package/dist/serpapi/normalize.js.map +1 -0
  1182. package/dist/skill-prompt.d.ts +37 -0
  1183. package/dist/skill-prompt.d.ts.map +1 -0
  1184. package/dist/skill-prompt.js +72 -0
  1185. package/dist/skill-prompt.js.map +1 -0
  1186. package/dist/step-executor.d.ts +90 -77
  1187. package/dist/step-executor.d.ts.map +1 -1
  1188. package/dist/step-executor.js +384 -690
  1189. package/dist/step-executor.js.map +1 -1
  1190. package/dist/subagent.d.ts +275 -0
  1191. package/dist/subagent.d.ts.map +1 -0
  1192. package/dist/subagent.js +444 -0
  1193. package/dist/subagent.js.map +1 -0
  1194. package/dist/supervisor/prompt.d.ts +12 -0
  1195. package/dist/supervisor/prompt.d.ts.map +1 -0
  1196. package/dist/supervisor/prompt.js +51 -0
  1197. package/dist/supervisor/prompt.js.map +1 -0
  1198. package/dist/supervisor/supervisor-agent.d.ts +72 -0
  1199. package/dist/supervisor/supervisor-agent.d.ts.map +1 -0
  1200. package/dist/supervisor/supervisor-agent.js +185 -0
  1201. package/dist/supervisor/supervisor-agent.js.map +1 -0
  1202. package/dist/supervisor/tools.d.ts +56 -0
  1203. package/dist/supervisor/tools.d.ts.map +1 -0
  1204. package/dist/supervisor/tools.js +83 -0
  1205. package/dist/supervisor/tools.js.map +1 -0
  1206. package/dist/supervisor/verdict-schema.d.ts +18 -0
  1207. package/dist/supervisor/verdict-schema.d.ts.map +1 -0
  1208. package/dist/supervisor/verdict-schema.js +58 -0
  1209. package/dist/supervisor/verdict-schema.js.map +1 -0
  1210. package/dist/system-skills.d.ts +74 -0
  1211. package/dist/system-skills.d.ts.map +1 -0
  1212. package/dist/system-skills.js +168 -0
  1213. package/dist/system-skills.js.map +1 -0
  1214. package/dist/task-executor.d.ts +90 -40
  1215. package/dist/task-executor.d.ts.map +1 -1
  1216. package/dist/task-executor.js +259 -282
  1217. package/dist/task-executor.js.map +1 -1
  1218. package/dist/task-planner.d.ts +18 -12
  1219. package/dist/task-planner.d.ts.map +1 -1
  1220. package/dist/task-planner.js +342 -328
  1221. package/dist/task-planner.js.map +1 -1
  1222. package/dist/timeline-capture.d.ts +21 -0
  1223. package/dist/timeline-capture.d.ts.map +1 -0
  1224. package/dist/timeline-capture.js +564 -0
  1225. package/dist/timeline-capture.js.map +1 -0
  1226. package/dist/timeline-code-bake.d.ts +75 -0
  1227. package/dist/timeline-code-bake.d.ts.map +1 -0
  1228. package/dist/timeline-code-bake.js +327 -0
  1229. package/dist/timeline-code-bake.js.map +1 -0
  1230. package/dist/timeline-preview/compare.d.ts +27 -0
  1231. package/dist/timeline-preview/compare.d.ts.map +1 -0
  1232. package/dist/timeline-preview/compare.js +71 -0
  1233. package/dist/timeline-preview/compare.js.map +1 -0
  1234. package/dist/timeline-preview/frames.d.ts +193 -0
  1235. package/dist/timeline-preview/frames.d.ts.map +1 -0
  1236. package/dist/timeline-preview/frames.js +731 -0
  1237. package/dist/timeline-preview/frames.js.map +1 -0
  1238. package/dist/timeline-preview/model3d.d.ts +67 -0
  1239. package/dist/timeline-preview/model3d.d.ts.map +1 -0
  1240. package/dist/timeline-preview/model3d.js +165 -0
  1241. package/dist/timeline-preview/model3d.js.map +1 -0
  1242. package/dist/timeline-preview/rasterize.d.ts +33 -0
  1243. package/dist/timeline-preview/rasterize.d.ts.map +1 -0
  1244. package/dist/timeline-preview/rasterize.js +83 -0
  1245. package/dist/timeline-preview/rasterize.js.map +1 -0
  1246. package/dist/timeline-preview/sheet.d.ts +38 -0
  1247. package/dist/timeline-preview/sheet.d.ts.map +1 -0
  1248. package/dist/timeline-preview/sheet.js +72 -0
  1249. package/dist/timeline-preview/sheet.js.map +1 -0
  1250. package/dist/tools/asset-persist.d.ts +29 -0
  1251. package/dist/tools/asset-persist.d.ts.map +1 -0
  1252. package/dist/tools/asset-persist.js +78 -0
  1253. package/dist/tools/asset-persist.js.map +1 -0
  1254. package/dist/tools/base-tool.d.ts +53 -5
  1255. package/dist/tools/base-tool.d.ts.map +1 -1
  1256. package/dist/tools/base-tool.js +180 -3
  1257. package/dist/tools/base-tool.js.map +1 -1
  1258. package/dist/tools/binary-output.d.ts +54 -0
  1259. package/dist/tools/binary-output.d.ts.map +1 -0
  1260. package/dist/tools/binary-output.js +127 -0
  1261. package/dist/tools/binary-output.js.map +1 -0
  1262. package/dist/tools/browser-tools.d.ts +5 -29
  1263. package/dist/tools/browser-tools.d.ts.map +1 -1
  1264. package/dist/tools/browser-tools.js +5 -205
  1265. package/dist/tools/browser-tools.js.map +1 -1
  1266. package/dist/tools/builtin-tools.d.ts +52 -0
  1267. package/dist/tools/builtin-tools.d.ts.map +1 -0
  1268. package/dist/tools/builtin-tools.js +289 -0
  1269. package/dist/tools/builtin-tools.js.map +1 -0
  1270. package/dist/tools/control-tool.d.ts +2 -5
  1271. package/dist/tools/control-tool.d.ts.map +1 -1
  1272. package/dist/tools/control-tool.js +18 -15
  1273. package/dist/tools/control-tool.js.map +1 -1
  1274. package/dist/tools/dataseo-tools.d.ts +34 -32
  1275. package/dist/tools/dataseo-tools.d.ts.map +1 -1
  1276. package/dist/tools/dataseo-tools.js +148 -233
  1277. package/dist/tools/dataseo-tools.js.map +1 -1
  1278. package/dist/tools/external-capability-tools.d.ts +36 -0
  1279. package/dist/tools/external-capability-tools.d.ts.map +1 -0
  1280. package/dist/tools/external-capability-tools.js +41 -0
  1281. package/dist/tools/external-capability-tools.js.map +1 -0
  1282. package/dist/tools/external-mcp-tools.d.ts +139 -0
  1283. package/dist/tools/external-mcp-tools.d.ts.map +1 -0
  1284. package/dist/tools/external-mcp-tools.js +552 -0
  1285. package/dist/tools/external-mcp-tools.js.map +1 -0
  1286. package/dist/tools/finish-step-tool.d.ts +1 -1
  1287. package/dist/tools/finish-step-tool.d.ts.map +1 -1
  1288. package/dist/tools/finish-step-tool.js +3 -3
  1289. package/dist/tools/finish-step-tool.js.map +1 -1
  1290. package/dist/tools/google-tools.d.ts +28 -39
  1291. package/dist/tools/google-tools.d.ts.map +1 -1
  1292. package/dist/tools/google-tools.js +51 -164
  1293. package/dist/tools/google-tools.js.map +1 -1
  1294. package/dist/tools/google-workspace-tools.d.ts +23 -0
  1295. package/dist/tools/google-workspace-tools.d.ts.map +1 -0
  1296. package/dist/tools/google-workspace-tools.js +26 -0
  1297. package/dist/tools/google-workspace-tools.js.map +1 -0
  1298. package/dist/tools/graph-validation-registry.d.ts +33 -0
  1299. package/dist/tools/graph-validation-registry.d.ts.map +1 -0
  1300. package/dist/tools/graph-validation-registry.js +54 -0
  1301. package/dist/tools/graph-validation-registry.js.map +1 -0
  1302. package/dist/tools/http-tools.d.ts +5 -53
  1303. package/dist/tools/http-tools.d.ts.map +1 -1
  1304. package/dist/tools/http-tools.js +5 -177
  1305. package/dist/tools/http-tools.js.map +1 -1
  1306. package/dist/tools/image-injection.d.ts +51 -0
  1307. package/dist/tools/image-injection.d.ts.map +1 -0
  1308. package/dist/tools/image-injection.js +85 -0
  1309. package/dist/tools/image-injection.js.map +1 -0
  1310. package/dist/tools/mcp-tool-support.d.ts +204 -0
  1311. package/dist/tools/mcp-tool-support.d.ts.map +1 -0
  1312. package/dist/tools/mcp-tool-support.js +537 -0
  1313. package/dist/tools/mcp-tool-support.js.map +1 -0
  1314. package/dist/tools/mcp-tools.d.ts +106 -390
  1315. package/dist/tools/mcp-tools.d.ts.map +1 -1
  1316. package/dist/tools/mcp-tools.js +132 -601
  1317. package/dist/tools/mcp-tools.js.map +1 -1
  1318. package/dist/tools/media-tools.d.ts +9 -272
  1319. package/dist/tools/media-tools.d.ts.map +1 -1
  1320. package/dist/tools/media-tools.js +11 -676
  1321. package/dist/tools/media-tools.js.map +1 -1
  1322. package/dist/tools/memory-tools.d.ts +36 -0
  1323. package/dist/tools/memory-tools.d.ts.map +1 -0
  1324. package/dist/tools/memory-tools.js +52 -0
  1325. package/dist/tools/memory-tools.js.map +1 -0
  1326. package/dist/tools/openai-tools.d.ts +28 -68
  1327. package/dist/tools/openai-tools.d.ts.map +1 -1
  1328. package/dist/tools/openai-tools.js +51 -181
  1329. package/dist/tools/openai-tools.js.map +1 -1
  1330. package/dist/tools/plan-builder-tools.d.ts +141 -7
  1331. package/dist/tools/plan-builder-tools.d.ts.map +1 -1
  1332. package/dist/tools/plan-builder-tools.js +159 -86
  1333. package/dist/tools/plan-builder-tools.js.map +1 -1
  1334. package/dist/tools/run-search-tool.d.ts +82 -0
  1335. package/dist/tools/run-search-tool.d.ts.map +1 -0
  1336. package/dist/tools/run-search-tool.js +121 -0
  1337. package/dist/tools/run-search-tool.js.map +1 -0
  1338. package/dist/tools/run-subtask-tool.d.ts +49 -0
  1339. package/dist/tools/run-subtask-tool.d.ts.map +1 -0
  1340. package/dist/tools/run-subtask-tool.js +88 -0
  1341. package/dist/tools/run-subtask-tool.js.map +1 -0
  1342. package/dist/tools/search-tools.d.ts +5 -36
  1343. package/dist/tools/search-tools.d.ts.map +1 -1
  1344. package/dist/tools/search-tools.js +5 -215
  1345. package/dist/tools/search-tools.js.map +1 -1
  1346. package/dist/tools/serp-providers/apify-provider.d.ts +18 -0
  1347. package/dist/tools/serp-providers/apify-provider.d.ts.map +1 -0
  1348. package/dist/tools/serp-providers/apify-provider.js +93 -0
  1349. package/dist/tools/serp-providers/apify-provider.js.map +1 -0
  1350. package/dist/tools/serp-providers/brave-provider.d.ts +34 -0
  1351. package/dist/tools/serp-providers/brave-provider.d.ts.map +1 -0
  1352. package/dist/tools/serp-providers/brave-provider.js +86 -0
  1353. package/dist/tools/serp-providers/brave-provider.js.map +1 -0
  1354. package/dist/tools/serp-providers/dataforseo-provider.d.ts +14 -1
  1355. package/dist/tools/serp-providers/dataforseo-provider.d.ts.map +1 -1
  1356. package/dist/tools/serp-providers/dataforseo-provider.js +0 -9
  1357. package/dist/tools/serp-providers/dataforseo-provider.js.map +1 -1
  1358. package/dist/tools/serp-providers/gemini-provider.d.ts +45 -0
  1359. package/dist/tools/serp-providers/gemini-provider.d.ts.map +1 -0
  1360. package/dist/tools/serp-providers/gemini-provider.js +148 -0
  1361. package/dist/tools/serp-providers/gemini-provider.js.map +1 -0
  1362. package/dist/tools/serp-providers/index.d.ts +61 -0
  1363. package/dist/tools/serp-providers/index.d.ts.map +1 -1
  1364. package/dist/tools/serp-providers/index.js +119 -3
  1365. package/dist/tools/serp-providers/index.js.map +1 -1
  1366. package/dist/tools/serp-providers/openai-provider.d.ts +58 -0
  1367. package/dist/tools/serp-providers/openai-provider.d.ts.map +1 -0
  1368. package/dist/tools/serp-providers/openai-provider.js +113 -0
  1369. package/dist/tools/serp-providers/openai-provider.js.map +1 -0
  1370. package/dist/tools/serp-providers/serpapi-provider.d.ts +9 -5
  1371. package/dist/tools/serp-providers/serpapi-provider.d.ts.map +1 -1
  1372. package/dist/tools/serp-providers/serpapi-provider.js +26 -44
  1373. package/dist/tools/serp-providers/serpapi-provider.js.map +1 -1
  1374. package/dist/tools/serp-tool-factory.d.ts +27 -0
  1375. package/dist/tools/serp-tool-factory.d.ts.map +1 -0
  1376. package/dist/tools/serp-tool-factory.js +56 -0
  1377. package/dist/tools/serp-tool-factory.js.map +1 -0
  1378. package/dist/tools/shared-tools.d.ts +33 -0
  1379. package/dist/tools/shared-tools.d.ts.map +1 -0
  1380. package/dist/tools/shared-tools.js +39 -0
  1381. package/dist/tools/shared-tools.js.map +1 -0
  1382. package/dist/tools/start-subtask-tool.d.ts +51 -0
  1383. package/dist/tools/start-subtask-tool.d.ts.map +1 -0
  1384. package/dist/tools/start-subtask-tool.js +189 -0
  1385. package/dist/tools/start-subtask-tool.js.map +1 -0
  1386. package/dist/tools/submit-code-tool.d.ts +159 -0
  1387. package/dist/tools/submit-code-tool.d.ts.map +1 -0
  1388. package/dist/tools/submit-code-tool.js +209 -0
  1389. package/dist/tools/submit-code-tool.js.map +1 -0
  1390. package/dist/tools/subtask-fields.d.ts +11 -0
  1391. package/dist/tools/subtask-fields.d.ts.map +1 -0
  1392. package/dist/tools/subtask-fields.js +11 -0
  1393. package/dist/tools/subtask-fields.js.map +1 -0
  1394. package/dist/tools/todo-tools.d.ts +15 -0
  1395. package/dist/tools/todo-tools.d.ts.map +1 -0
  1396. package/dist/tools/todo-tools.js +15 -0
  1397. package/dist/tools/todo-tools.js.map +1 -0
  1398. package/dist/tools/tool-permissions.d.ts +40 -0
  1399. package/dist/tools/tool-permissions.d.ts.map +1 -0
  1400. package/dist/tools/tool-permissions.js +52 -0
  1401. package/dist/tools/tool-permissions.js.map +1 -0
  1402. package/dist/tools/tool-search.d.ts +39 -0
  1403. package/dist/tools/tool-search.d.ts.map +1 -0
  1404. package/dist/tools/tool-search.js +108 -0
  1405. package/dist/tools/tool-search.js.map +1 -0
  1406. package/dist/tools/vector-tool-support.d.ts +15 -0
  1407. package/dist/tools/vector-tool-support.d.ts.map +1 -0
  1408. package/dist/tools/vector-tool-support.js +133 -0
  1409. package/dist/tools/vector-tool-support.js.map +1 -0
  1410. package/dist/tools/vector-tools.d.ts +13 -220
  1411. package/dist/tools/vector-tools.d.ts.map +1 -1
  1412. package/dist/tools/vector-tools.js +7 -578
  1413. package/dist/tools/vector-tools.js.map +1 -1
  1414. package/dist/tools/wait-subtasks-tool.d.ts +27 -0
  1415. package/dist/tools/wait-subtasks-tool.d.ts.map +1 -0
  1416. package/dist/tools/wait-subtasks-tool.js +66 -0
  1417. package/dist/tools/wait-subtasks-tool.js.map +1 -0
  1418. package/dist/types.d.ts +16 -31
  1419. package/dist/types.d.ts.map +1 -1
  1420. package/dist/types.js +8 -1
  1421. package/dist/types.js.map +1 -1
  1422. package/dist/utils/dag-scheduler.d.ts +85 -0
  1423. package/dist/utils/dag-scheduler.d.ts.map +1 -0
  1424. package/dist/utils/dag-scheduler.js +180 -0
  1425. package/dist/utils/dag-scheduler.js.map +1 -0
  1426. package/dist/utils/json-parser.d.ts +32 -1
  1427. package/dist/utils/json-parser.d.ts.map +1 -1
  1428. package/dist/utils/json-parser.js +145 -10
  1429. package/dist/utils/json-parser.js.map +1 -1
  1430. package/dist/utils/json-schema-validate.d.ts +29 -0
  1431. package/dist/utils/json-schema-validate.d.ts.map +1 -0
  1432. package/dist/utils/json-schema-validate.js +228 -0
  1433. package/dist/utils/json-schema-validate.js.map +1 -0
  1434. package/dist/utils/link-abort.d.ts +13 -0
  1435. package/dist/utils/link-abort.d.ts.map +1 -0
  1436. package/dist/utils/link-abort.js +23 -0
  1437. package/dist/utils/link-abort.js.map +1 -0
  1438. package/dist/utils/merge-generators.d.ts +58 -0
  1439. package/dist/utils/merge-generators.d.ts.map +1 -0
  1440. package/dist/utils/merge-generators.js +148 -0
  1441. package/dist/utils/merge-generators.js.map +1 -0
  1442. package/dist/utils/remove-base64-images.d.ts +0 -5
  1443. package/dist/utils/remove-base64-images.d.ts.map +1 -1
  1444. package/dist/utils/remove-base64-images.js.map +1 -1
  1445. package/dist/utils/step-failure.d.ts +20 -0
  1446. package/dist/utils/step-failure.d.ts.map +1 -0
  1447. package/dist/utils/step-failure.js +43 -0
  1448. package/dist/utils/step-failure.js.map +1 -0
  1449. package/dist/utils/think-tags.d.ts +16 -0
  1450. package/dist/utils/think-tags.d.ts.map +1 -0
  1451. package/dist/utils/think-tags.js +23 -0
  1452. package/dist/utils/think-tags.js.map +1 -0
  1453. package/dist/utils/type-guards.d.ts +26 -0
  1454. package/dist/utils/type-guards.d.ts.map +1 -0
  1455. package/dist/utils/type-guards.js +44 -0
  1456. package/dist/utils/type-guards.js.map +1 -0
  1457. package/dist/utils/ui-event-buffer.d.ts +18 -0
  1458. package/dist/utils/ui-event-buffer.d.ts.map +1 -0
  1459. package/dist/utils/ui-event-buffer.js +18 -0
  1460. package/dist/utils/ui-event-buffer.js.map +1 -0
  1461. package/dist/utils/wrap-generators-parallel.d.ts +0 -5
  1462. package/dist/utils/wrap-generators-parallel.d.ts.map +1 -1
  1463. package/dist/utils/wrap-generators-parallel.js +3 -6
  1464. package/dist/utils/wrap-generators-parallel.js.map +1 -1
  1465. package/dist/wasm-sandbox/host.d.ts +106 -0
  1466. package/dist/wasm-sandbox/host.d.ts.map +1 -0
  1467. package/dist/wasm-sandbox/host.js +409 -0
  1468. package/dist/wasm-sandbox/host.js.map +1 -0
  1469. package/dist/wasm-sandbox/workers.d.ts +43 -0
  1470. package/dist/wasm-sandbox/workers.d.ts.map +1 -0
  1471. package/dist/wasm-sandbox/workers.js +150 -0
  1472. package/dist/wasm-sandbox/workers.js.map +1 -0
  1473. package/dist/workspace-paths.d.ts +40 -0
  1474. package/dist/workspace-paths.d.ts.map +1 -0
  1475. package/dist/workspace-paths.js +102 -0
  1476. package/dist/workspace-paths.js.map +1 -0
  1477. package/dist/yt-dlp-gate.d.ts +19 -0
  1478. package/dist/yt-dlp-gate.d.ts.map +1 -0
  1479. package/dist/yt-dlp-gate.js +22 -0
  1480. package/dist/yt-dlp-gate.js.map +1 -0
  1481. package/package.json +114 -14
  1482. package/dist/agent-executor.d.ts +0 -62
  1483. package/dist/agent-executor.d.ts.map +0 -1
  1484. package/dist/agent-executor.js +0 -324
  1485. package/dist/agent-executor.js.map +0 -1
  1486. package/dist/agent-step-executor.d.ts +0 -28
  1487. package/dist/agent-step-executor.d.ts.map +0 -1
  1488. package/dist/agent-step-executor.js +0 -99
  1489. package/dist/agent-step-executor.js.map +0 -1
  1490. package/dist/agent-workflow-runner.d.ts +0 -31
  1491. package/dist/agent-workflow-runner.d.ts.map +0 -1
  1492. package/dist/agent-workflow-runner.js +0 -124
  1493. package/dist/agent-workflow-runner.js.map +0 -1
  1494. package/dist/agent.d.ts +0 -115
  1495. package/dist/agent.d.ts.map +0 -1
  1496. package/dist/agent.js +0 -587
  1497. package/dist/agent.js.map +0 -1
  1498. package/dist/base-agent.d.ts +0 -42
  1499. package/dist/base-agent.d.ts.map +0 -1
  1500. package/dist/base-agent.js +0 -29
  1501. package/dist/base-agent.js.map +0 -1
  1502. package/dist/graph-planner.d.ts +0 -56
  1503. package/dist/graph-planner.d.ts.map +0 -1
  1504. package/dist/graph-planner.js +0 -311
  1505. package/dist/graph-planner.js.map +0 -1
  1506. package/dist/multi-mode-agent.d.ts +0 -86
  1507. package/dist/multi-mode-agent.d.ts.map +0 -1
  1508. package/dist/multi-mode-agent.js +0 -476
  1509. package/dist/multi-mode-agent.js.map +0 -1
  1510. package/dist/prompts/graph-planner-prompt.d.ts +0 -48
  1511. package/dist/prompts/graph-planner-prompt.d.ts.map +0 -1
  1512. package/dist/prompts/graph-planner-prompt.js +0 -180
  1513. package/dist/prompts/graph-planner-prompt.js.map +0 -1
  1514. package/dist/reject-agentic-provider.d.ts +0 -21
  1515. package/dist/reject-agentic-provider.d.ts.map +0 -1
  1516. package/dist/reject-agentic-provider.js +0 -32
  1517. package/dist/reject-agentic-provider.js.map +0 -1
  1518. package/dist/simple-agent.d.ts +0 -29
  1519. package/dist/simple-agent.d.ts.map +0 -1
  1520. package/dist/simple-agent.js +0 -54
  1521. package/dist/simple-agent.js.map +0 -1
  1522. package/dist/sub-agent-planner.d.ts +0 -33
  1523. package/dist/sub-agent-planner.d.ts.map +0 -1
  1524. package/dist/sub-agent-planner.js +0 -203
  1525. package/dist/sub-agent-planner.js.map +0 -1
  1526. package/dist/team/db-task-board.d.ts +0 -54
  1527. package/dist/team/db-task-board.d.ts.map +0 -1
  1528. package/dist/team/db-task-board.js +0 -361
  1529. package/dist/team/db-task-board.js.map +0 -1
  1530. package/dist/team/edge-message-bus.d.ts +0 -51
  1531. package/dist/team/edge-message-bus.d.ts.map +0 -1
  1532. package/dist/team/edge-message-bus.js +0 -169
  1533. package/dist/team/edge-message-bus.js.map +0 -1
  1534. package/dist/team/edge-task-board.d.ts +0 -77
  1535. package/dist/team/edge-task-board.d.ts.map +0 -1
  1536. package/dist/team/edge-task-board.js +0 -140
  1537. package/dist/team/edge-task-board.js.map +0 -1
  1538. package/dist/team/index.d.ts +0 -16
  1539. package/dist/team/index.d.ts.map +0 -1
  1540. package/dist/team/index.js +0 -17
  1541. package/dist/team/index.js.map +0 -1
  1542. package/dist/team/message-bus.d.ts +0 -58
  1543. package/dist/team/message-bus.d.ts.map +0 -1
  1544. package/dist/team/message-bus.js +0 -151
  1545. package/dist/team/message-bus.js.map +0 -1
  1546. package/dist/team/task-board.d.ts +0 -106
  1547. package/dist/team/task-board.d.ts.map +0 -1
  1548. package/dist/team/task-board.js +0 -370
  1549. package/dist/team/task-board.js.map +0 -1
  1550. package/dist/team/team-executor.d.ts +0 -72
  1551. package/dist/team/team-executor.d.ts.map +0 -1
  1552. package/dist/team/team-executor.js +0 -466
  1553. package/dist/team/team-executor.js.map +0 -1
  1554. package/dist/team/team-tools.d.ts +0 -252
  1555. package/dist/team/team-tools.d.ts.map +0 -1
  1556. package/dist/team/team-tools.js +0 -412
  1557. package/dist/team/team-tools.js.map +0 -1
  1558. package/dist/team/types.d.ts +0 -198
  1559. package/dist/team/types.d.ts.map +0 -1
  1560. package/dist/team/types.js +0 -8
  1561. package/dist/team/types.js.map +0 -1
  1562. package/dist/tools/add-edge-tool.d.ts +0 -18
  1563. package/dist/tools/add-edge-tool.d.ts.map +0 -1
  1564. package/dist/tools/add-edge-tool.js +0 -92
  1565. package/dist/tools/add-edge-tool.js.map +0 -1
  1566. package/dist/tools/add-node-tool.d.ts +0 -22
  1567. package/dist/tools/add-node-tool.d.ts.map +0 -1
  1568. package/dist/tools/add-node-tool.js +0 -128
  1569. package/dist/tools/add-node-tool.js.map +0 -1
  1570. package/dist/tools/asset-tools.d.ts +0 -58
  1571. package/dist/tools/asset-tools.d.ts.map +0 -1
  1572. package/dist/tools/asset-tools.js +0 -191
  1573. package/dist/tools/asset-tools.js.map +0 -1
  1574. package/dist/tools/calculator-tool.d.ts +0 -24
  1575. package/dist/tools/calculator-tool.d.ts.map +0 -1
  1576. package/dist/tools/calculator-tool.js +0 -64
  1577. package/dist/tools/calculator-tool.js.map +0 -1
  1578. package/dist/tools/claude-code-tools.d.ts +0 -96
  1579. package/dist/tools/claude-code-tools.d.ts.map +0 -1
  1580. package/dist/tools/claude-code-tools.js +0 -463
  1581. package/dist/tools/claude-code-tools.js.map +0 -1
  1582. package/dist/tools/code-tools.d.ts +0 -26
  1583. package/dist/tools/code-tools.d.ts.map +0 -1
  1584. package/dist/tools/code-tools.js +0 -82
  1585. package/dist/tools/code-tools.js.map +0 -1
  1586. package/dist/tools/create-plan-tool.d.ts +0 -29
  1587. package/dist/tools/create-plan-tool.d.ts.map +0 -1
  1588. package/dist/tools/create-plan-tool.js +0 -355
  1589. package/dist/tools/create-plan-tool.js.map +0 -1
  1590. package/dist/tools/create-task-tool.d.ts +0 -28
  1591. package/dist/tools/create-task-tool.d.ts.map +0 -1
  1592. package/dist/tools/create-task-tool.js +0 -254
  1593. package/dist/tools/create-task-tool.js.map +0 -1
  1594. package/dist/tools/email-tools.d.ts +0 -76
  1595. package/dist/tools/email-tools.d.ts.map +0 -1
  1596. package/dist/tools/email-tools.js +0 -259
  1597. package/dist/tools/email-tools.js.map +0 -1
  1598. package/dist/tools/filesystem-tools.d.ts +0 -77
  1599. package/dist/tools/filesystem-tools.d.ts.map +0 -1
  1600. package/dist/tools/filesystem-tools.js +0 -334
  1601. package/dist/tools/filesystem-tools.js.map +0 -1
  1602. package/dist/tools/find-model-tool.d.ts +0 -25
  1603. package/dist/tools/find-model-tool.d.ts.map +0 -1
  1604. package/dist/tools/find-model-tool.js +0 -236
  1605. package/dist/tools/find-model-tool.js.map +0 -1
  1606. package/dist/tools/finish-graph-tool.d.ts +0 -23
  1607. package/dist/tools/finish-graph-tool.d.ts.map +0 -1
  1608. package/dist/tools/finish-graph-tool.js +0 -46
  1609. package/dist/tools/finish-graph-tool.js.map +0 -1
  1610. package/dist/tools/js-code-tool.d.ts +0 -30
  1611. package/dist/tools/js-code-tool.d.ts.map +0 -1
  1612. package/dist/tools/js-code-tool.js +0 -98
  1613. package/dist/tools/js-code-tool.js.map +0 -1
  1614. package/dist/tools/local-get-node-info-tool.d.ts +0 -19
  1615. package/dist/tools/local-get-node-info-tool.d.ts.map +0 -1
  1616. package/dist/tools/local-get-node-info-tool.js +0 -75
  1617. package/dist/tools/local-get-node-info-tool.js.map +0 -1
  1618. package/dist/tools/local-list-nodes-tool.d.ts +0 -19
  1619. package/dist/tools/local-list-nodes-tool.d.ts.map +0 -1
  1620. package/dist/tools/local-list-nodes-tool.js +0 -69
  1621. package/dist/tools/local-list-nodes-tool.js.map +0 -1
  1622. package/dist/tools/local-search-nodes-tool.d.ts +0 -21
  1623. package/dist/tools/local-search-nodes-tool.d.ts.map +0 -1
  1624. package/dist/tools/local-search-nodes-tool.js +0 -111
  1625. package/dist/tools/local-search-nodes-tool.js.map +0 -1
  1626. package/dist/tools/math-tools.d.ts +0 -156
  1627. package/dist/tools/math-tools.d.ts.map +0 -1
  1628. package/dist/tools/math-tools.js +0 -422
  1629. package/dist/tools/math-tools.js.map +0 -1
  1630. package/dist/tools/model-tools.d.ts +0 -25
  1631. package/dist/tools/model-tools.d.ts.map +0 -1
  1632. package/dist/tools/model-tools.js +0 -48
  1633. package/dist/tools/model-tools.js.map +0 -1
  1634. package/dist/tools/pdf-tools.d.ts +0 -152
  1635. package/dist/tools/pdf-tools.d.ts.map +0 -1
  1636. package/dist/tools/pdf-tools.js +0 -339
  1637. package/dist/tools/pdf-tools.js.map +0 -1
  1638. package/dist/tools/tool-registry.d.ts +0 -9
  1639. package/dist/tools/tool-registry.d.ts.map +0 -1
  1640. package/dist/tools/tool-registry.js +0 -17
  1641. package/dist/tools/tool-registry.js.map +0 -1
  1642. package/dist/tools/workspace-tools.d.ts +0 -58
  1643. package/dist/tools/workspace-tools.d.ts.map +0 -1
  1644. package/dist/tools/workspace-tools.js +0 -152
  1645. package/dist/tools/workspace-tools.js.map +0 -1
@@ -0,0 +1,2825 @@
1
+ /**
2
+ * The `timelines` capability module.
3
+ *
4
+ * Timeline CRUD, versioning, editing, rendering, tracking, and native media
5
+ * candidate capabilities that used to live across several `Tool` subclasses.
6
+ * The native media actions are kept in `timeline-native-media.ts` and attached
7
+ * here so they share the timelines namespace and registry entry.
8
+ *
9
+ * Wire names, descriptions and schemas come from `timelines.specs.ts`; the
10
+ * native media entries are attached here by name so the belt stays lazy.
11
+ *
12
+ * What was a constructor argument is now a field on the run: the tRPC-only
13
+ * timeline loader `validate_timeline` takes is `run.loaders?.timeline`. Every
14
+ * heavy dependency (`@nodetool-ai/models`, the timeline validator, the eval
15
+ * surface's bridge) is imported inside the implementation that needs it, so
16
+ * loading this module costs nothing.
17
+ *
18
+ * Design: docs/tool-class-retirement-design.md § "Migration".
19
+ */
20
+ import { z } from "zod";
21
+ import { applyTimelineTrackOp } from "@nodetool-ai/timeline/ops";
22
+ import { STAGGER_UNITS, ANIMATED_PROPERTIES, DEFAULT_BEAT_TOLERANCE_MS } from "@nodetool-ai/timeline";
23
+ import { buildTimelineToolContracts } from "@nodetool-ai/protocol/api-schemas/timeline-tool-contracts.js";
24
+ import { resolveMoveTrackArgs, resolveDeleteTrackArgs } from "@nodetool-ai/protocol/api-schemas/timeline-tool-params.js";
25
+ import { parseWithTypeCoercion } from "@nodetool-ai/runtime";
26
+ import { listTimelinesSpec, createTimelineSpec, getTimelineSpec, listTimelineVersionsSpec, getTimelineVersionSpec, createTimelineVersionSpec, restoreTimelineVersionSpec, deleteTimelineVersionSpec, editTimelineSpec, validateTimelineSpec, setTimelineDocumentSpec, previewTimelineFrameSpec, compareTimelineFramesSpec, renderTimelineSpec, bakeAudioAnimationSpec, isolateSubjectSpec, ISOLATE_SUBJECT_MODELS, ISOLATE_SUBJECT_RESOLUTIONS, DEFAULT_ISOLATE_SUBJECT_MODEL, DEFAULT_ISOLATE_SUBJECT_RESOLUTION, DEFAULT_BAKE_ATTACK_MS, DEFAULT_BAKE_RELEASE_MS, DEFAULT_BAKE_TOLERANCE, DEFAULT_BAKE_MAX_POINTS, DEFAULT_BAKE_MAX_SECONDS, MAX_BAKE_POINTS, DEFAULT_RENDER_TIMEOUT_MS, MAX_RENDER_TIMEOUT_MS, DEFAULT_PREVIEW_COUNT, DEFAULT_COMPARE_WIDTH, MAX_PREVIEW_TIMES, MAX_PREVIEW_RANGE_COUNT, DEFAULT_VERSION_LIMIT, MAX_VERSION_LIMIT, trackObjectSpec, TRACK_OBJECT_DIRECTIONS, getTimelineCodeSpec, setTimelineCodeSpec, editTimelineCodeSpec, rebakeTimelineCodeSpec, detachTimelineCodeSpec, deleteTimelineSpec } from "./timelines.specs.js";
27
+ import { AUDIO_BAKED_ANIMATION_KIND, normalizeAuthoredDocument, hashSceneSubtree, mergeTimelineSource } from "@nodetool-ai/timeline";
28
+ import { bakeTimelineCode, bakedDocumentMatchesSaved } from "../timeline-code-bake.js";
29
+ import { applyJsScriptEditOps, parseJsScriptEditOps } from "./js-scripts.js";
30
+ import { clipSourceWindowMs } from "./timeline-audio-bake.js";
31
+ import { TIMELINE_NATIVE_MEDIA_CAPABILITIES } from "./timeline-native-media.js";
32
+ import { isFiniteNumber, isRecord, isString } from "../utils/type-guards.js";
33
+ import { resolveProjectId } from "./project-scope.js";
34
+ const isError = (value) => !!value &&
35
+ typeof value === "object" &&
36
+ typeof value.error === "string";
37
+ async function loadTimeline(run, timelineId) {
38
+ if (!isString(timelineId) || !timelineId) {
39
+ return {
40
+ error: "timeline_id is required (use list_timelines to find one)."
41
+ };
42
+ }
43
+ const { TimelineSequence } = await import("@nodetool-ai/models");
44
+ const seq = await TimelineSequence.findById(timelineId);
45
+ // A sequence owned by someone else reads as missing — the same rule the tRPC
46
+ // router's ownership check applies.
47
+ if (!seq || seq.user_id !== run.context.userId) {
48
+ return { error: `Timeline ${timelineId} was not found.` };
49
+ }
50
+ return seq;
51
+ }
52
+ /** The list-item shape the tRPC router returns for a snapshot. */
53
+ function toVersionListItem(version) {
54
+ return {
55
+ id: version.id,
56
+ version: version.version,
57
+ name: version.name,
58
+ saveType: version.save_type,
59
+ fps: version.fps,
60
+ width: version.width,
61
+ height: version.height,
62
+ durationMs: version.duration_ms,
63
+ createdAt: version.created_at
64
+ };
65
+ }
66
+ /**
67
+ * A snapshot's document is JSON text on SQLite and an object on Postgres, so
68
+ * parse only when it is a string. A row that is neither is corrupt, and saying
69
+ * so beats handing back a string the caller will treat as a document.
70
+ */
71
+ function parseVersionDocument(raw) {
72
+ if (!isString(raw))
73
+ return raw;
74
+ try {
75
+ return JSON.parse(raw);
76
+ }
77
+ catch {
78
+ return { error: "The stored version document is not valid JSON." };
79
+ }
80
+ }
81
+ /** One-line count of what a validation found. */
82
+ function validationSummary(validation) {
83
+ const errors = validation.errors.length;
84
+ const warnings = validation.warnings.length;
85
+ if (errors === 0 && warnings === 0)
86
+ return "No issues found.";
87
+ const parts = [];
88
+ if (errors > 0)
89
+ parts.push(`${errors} error${errors === 1 ? "" : "s"}`);
90
+ if (warnings > 0)
91
+ parts.push(`${warnings} warning${warnings === 1 ? "" : "s"}`);
92
+ return parts.join(", ");
93
+ }
94
+ function versionNumber(value) {
95
+ const n = Number(value);
96
+ if (!Number.isInteger(n) || n < 1) {
97
+ return {
98
+ error: "version must be a positive integer (use list_timeline_versions to see the available ones)."
99
+ };
100
+ }
101
+ return n;
102
+ }
103
+ const listTimelines = {
104
+ spec: listTimelinesSpec,
105
+ impl: async (run, params) => {
106
+ const userId = run.context.userId;
107
+ if (!userId)
108
+ return { error: "No user is bound to this session." };
109
+ const { TimelineSequence } = await import("@nodetool-ai/models");
110
+ const limit = Math.max(1, Math.min(Number(params["limit"]) || 20, 100));
111
+ const query = isString(params["query"])
112
+ ? params["query"].trim().toLowerCase()
113
+ : "";
114
+ // Filter after the read: the name filter is not indexed, and the per-user
115
+ // limit is what bounds the scan.
116
+ const rows = await TimelineSequence.listByUser(userId, 100);
117
+ const matching = query
118
+ ? rows.filter((row) => row.name.toLowerCase().includes(query))
119
+ : rows;
120
+ return {
121
+ timelines: matching.slice(0, limit).map((row) => ({
122
+ id: row.id,
123
+ name: row.name,
124
+ project_id: row.project_id,
125
+ fps: row.fps,
126
+ width: row.width,
127
+ height: row.height,
128
+ duration_ms: row.duration_ms,
129
+ updated_at: row.updated_at
130
+ }))
131
+ };
132
+ }
133
+ };
134
+ /** A positive integer setting, or the default when the caller gave none. */
135
+ function sequenceSetting(value, fallback, field) {
136
+ if (value === undefined || value === null)
137
+ return fallback;
138
+ const n = Number(value);
139
+ if (!Number.isFinite(n) || n <= 0) {
140
+ return { error: `${field} must be a positive number.` };
141
+ }
142
+ return Math.round(n);
143
+ }
144
+ /**
145
+ * A new, empty sequence.
146
+ *
147
+ * Every other document surface could make one — sketches, scripts,
148
+ * storyboards — and timelines could not, which left "cut these clips
149
+ * together" with two ways in, both wrong: edit the sequence the user happens
150
+ * to have open, or assemble from a storyboard, which builds a timeline only
151
+ * out of media the board itself rendered. A live session did the first, wiped
152
+ * six clips of somebody's work, and had to restore from a snapshot.
153
+ */
154
+ const createTimeline = {
155
+ spec: createTimelineSpec,
156
+ impl: async (run, params) => {
157
+ const userId = run.context.userId;
158
+ if (!userId)
159
+ return { error: "No user is bound to this session." };
160
+ const name = params["name"];
161
+ if (!isString(name) || name.trim() === "") {
162
+ return { error: "name is required and must be a non-empty string." };
163
+ }
164
+ const fps = sequenceSetting(params["fps"], 30, "fps");
165
+ if (isError(fps))
166
+ return fps;
167
+ const width = sequenceSetting(params["width"], 1920, "width");
168
+ if (isError(width))
169
+ return width;
170
+ const height = sequenceSetting(params["height"], 1080, "height");
171
+ if (isError(height))
172
+ return height;
173
+ const projectId = resolveProjectId(run, params);
174
+ const { TimelineSequence } = await import("@nodetool-ai/models");
175
+ const sequence = new TimelineSequence({
176
+ user_id: userId,
177
+ project_id: projectId,
178
+ name: name.trim(),
179
+ fps,
180
+ width,
181
+ height,
182
+ duration_ms: 0,
183
+ document: JSON.stringify({ tracks: [], clips: [], markers: [] })
184
+ });
185
+ await sequence.save();
186
+ return {
187
+ ok: true,
188
+ timeline_id: sequence.id,
189
+ name: sequence.name,
190
+ fps: sequence.fps,
191
+ width: sequence.width,
192
+ height: sequence.height,
193
+ project_id: sequence.project_id,
194
+ updated_at: sequence.updated_at
195
+ };
196
+ }
197
+ };
198
+ const getTimeline = {
199
+ spec: getTimelineSpec,
200
+ impl: async (run, params) => {
201
+ const seq = await loadTimeline(run, params["timeline_id"]);
202
+ if (isError(seq))
203
+ return seq;
204
+ return { timeline: seq.toTimelineSequence(), revision: seq.revision };
205
+ }
206
+ };
207
+ const listTimelineVersions = {
208
+ spec: listTimelineVersionsSpec,
209
+ impl: async (run, params) => {
210
+ const seq = await loadTimeline(run, params["timeline_id"]);
211
+ if (isError(seq))
212
+ return seq;
213
+ const { TimelineSequenceVersion } = await import("@nodetool-ai/models");
214
+ const limit = Math.max(1, Math.min(Number(params["limit"]) || DEFAULT_VERSION_LIMIT, MAX_VERSION_LIMIT));
215
+ const saveType = isString(params["save_type"])
216
+ ? params["save_type"]
217
+ : undefined;
218
+ const versions = await TimelineSequenceVersion.listForTimeline(seq.id, {
219
+ limit,
220
+ saveType
221
+ });
222
+ return {
223
+ timeline_id: seq.id,
224
+ name: seq.name,
225
+ versions: versions.map(toVersionListItem)
226
+ };
227
+ }
228
+ };
229
+ const getTimelineVersion = {
230
+ spec: getTimelineVersionSpec,
231
+ impl: async (run, params) => {
232
+ const seq = await loadTimeline(run, params["timeline_id"]);
233
+ if (isError(seq))
234
+ return seq;
235
+ const number = versionNumber(params["version"]);
236
+ if (isError(number))
237
+ return number;
238
+ const { TimelineSequenceVersion } = await import("@nodetool-ai/models");
239
+ const version = await TimelineSequenceVersion.findByVersion(seq.id, number);
240
+ if (!version) {
241
+ return {
242
+ error: `Timeline ${seq.id} has no version ${number}. Call list_timeline_versions to see the available ones.`
243
+ };
244
+ }
245
+ const document = parseVersionDocument(version.document);
246
+ if (isError(document))
247
+ return document;
248
+ return {
249
+ timeline_id: seq.id,
250
+ ...toVersionListItem(version),
251
+ document
252
+ };
253
+ }
254
+ };
255
+ const createTimelineVersion = {
256
+ spec: createTimelineVersionSpec,
257
+ impl: async (run, params) => {
258
+ const seq = await loadTimeline(run, params["timeline_id"]);
259
+ if (isError(seq))
260
+ return seq;
261
+ const { TimelineSequenceVersion } = await import("@nodetool-ai/models");
262
+ const name = isString(params["name"]) && params["name"]
263
+ ? params["name"]
264
+ : null;
265
+ const version = await TimelineSequenceVersion.snapshot(seq, {
266
+ saveType: "manual",
267
+ name
268
+ });
269
+ return {
270
+ ok: true,
271
+ timeline_id: seq.id,
272
+ ...toVersionListItem(version)
273
+ };
274
+ }
275
+ };
276
+ const restoreTimelineVersion = {
277
+ spec: restoreTimelineVersionSpec,
278
+ impl: async (run, params) => {
279
+ const seq = await loadTimeline(run, params["timeline_id"]);
280
+ if (isError(seq))
281
+ return seq;
282
+ const number = versionNumber(params["version"]);
283
+ if (isError(number))
284
+ return number;
285
+ const { TimelineSequence, TimelineSequenceVersion } = await import("@nodetool-ai/models");
286
+ const version = await TimelineSequenceVersion.findByVersion(seq.id, number);
287
+ if (!version) {
288
+ return {
289
+ error: `Timeline ${seq.id} has no version ${number}. Call list_timeline_versions to see the available ones.`
290
+ };
291
+ }
292
+ const document = parseVersionDocument(version.document);
293
+ if (isError(document))
294
+ return document;
295
+ // Snapshot what is about to be overwritten first, so a restore is itself
296
+ // undoable.
297
+ const undo = await TimelineSequenceVersion.snapshot(seq, {
298
+ saveType: "restore",
299
+ name: `Before restore to v${number}`
300
+ });
301
+ let updated;
302
+ try {
303
+ updated = await TimelineSequence.updateFieldsIfUnchanged(seq.id, seq.updated_at, {
304
+ document: JSON.stringify(document),
305
+ fps: version.fps,
306
+ width: version.width,
307
+ height: version.height,
308
+ duration_ms: version.duration_ms
309
+ });
310
+ }
311
+ catch (error) {
312
+ // The write rejects a document without tracks/clips/markers arrays. That
313
+ // is a snapshot too old or too broken to restore, not a failed call.
314
+ return {
315
+ error: `Version ${number} of timeline ${seq.id} cannot be restored: ${error instanceof Error ? error.message : String(error)}`,
316
+ undo_version: undo.version
317
+ };
318
+ }
319
+ if (!updated) {
320
+ return {
321
+ error: `Timeline ${seq.id} was modified since it was read (optimistic concurrency conflict); nothing was restored. Retry the call.`,
322
+ undo_version: undo.version
323
+ };
324
+ }
325
+ const { validateTimelineSequence } = await import("@nodetool-ai/execution/timeline-debug");
326
+ const validation = validateTimelineSequence(document, {
327
+ fps: version.fps,
328
+ width: version.width,
329
+ height: version.height
330
+ });
331
+ return {
332
+ ok: true,
333
+ timeline_id: seq.id,
334
+ restored_version: number,
335
+ undo_version: undo.version,
336
+ fps: updated.fps,
337
+ width: updated.width,
338
+ height: updated.height,
339
+ duration_ms: updated.duration_ms,
340
+ updated_at: updated.updated_at,
341
+ validation,
342
+ summary: validationSummary(validation)
343
+ };
344
+ }
345
+ };
346
+ const deleteTimelineVersion = {
347
+ spec: deleteTimelineVersionSpec,
348
+ impl: async (run, params) => {
349
+ const seq = await loadTimeline(run, params["timeline_id"]);
350
+ if (isError(seq))
351
+ return seq;
352
+ const number = versionNumber(params["version"]);
353
+ if (isError(number))
354
+ return number;
355
+ const { TimelineSequenceVersion } = await import("@nodetool-ai/models");
356
+ const version = await TimelineSequenceVersion.findByVersion(seq.id, number);
357
+ if (!version) {
358
+ return {
359
+ error: `Timeline ${seq.id} has no version ${number}. Call list_timeline_versions to see the available ones.`
360
+ };
361
+ }
362
+ await version.delete();
363
+ return {
364
+ ok: true,
365
+ timeline_id: seq.id,
366
+ deleted_version: number
367
+ };
368
+ }
369
+ };
370
+ // ---------------------------------------------------------------------------
371
+ // edit_timeline
372
+ // ---------------------------------------------------------------------------
373
+ /** Attempts to land the document write before reporting a conflict. */
374
+ const CAS_ATTEMPTS = 2;
375
+ /** Operations one call may apply, so a runaway script cannot rewrite a cut. */
376
+ const MAX_OPS = 60;
377
+ const TOOL_PREFIX = "ui_timeline_";
378
+ /** Browser generation without a real provider adapter remains excluded. */
379
+ const EXCLUDED_OPS = new Set([`${TOOL_PREFIX}generate_clip`]);
380
+ const READ_ONLY_OPS = new Set([`${TOOL_PREFIX}get_clip_frames`]);
381
+ /** `add_track`, `ui_add_track`, and `ui_timeline_add_track` all name one tool. */
382
+ function normalizeOpName(name) {
383
+ const trimmed = name.trim();
384
+ if (trimmed.startsWith(TOOL_PREFIX))
385
+ return trimmed;
386
+ const bare = trimmed.startsWith("ui_")
387
+ ? trimmed.slice("ui_".length)
388
+ : trimmed;
389
+ return `${TOOL_PREFIX}${bare}`;
390
+ }
391
+ /** An op is `{op, ...args}` — the arguments sit alongside the verb. */
392
+ export function parseOps(raw) {
393
+ if (!Array.isArray(raw) || raw.length === 0) {
394
+ return {
395
+ error: 'ops must be a non-empty array, e.g. [{"op": "add_track", "type": "audio"}].'
396
+ };
397
+ }
398
+ if (raw.length > MAX_OPS) {
399
+ return {
400
+ error: `ops holds ${raw.length} entries; at most ${MAX_OPS} per call.`
401
+ };
402
+ }
403
+ const parsed = [];
404
+ for (const [index, entry] of raw.entries()) {
405
+ if (!isRecord(entry)) {
406
+ return { error: `ops[${index}] must be an object.` };
407
+ }
408
+ const { op, ...input } = entry;
409
+ if (!isString(op) || op.trim() === "") {
410
+ return { error: `ops[${index}] has no \`op\` name.` };
411
+ }
412
+ parsed.push({ op: normalizeOpName(op), input });
413
+ }
414
+ return parsed;
415
+ }
416
+ /**
417
+ * Read one of the caller's assets for `add_media_clip`.
418
+ *
419
+ * The ref a model has in hand is whatever `list_assets` printed — a bare id or
420
+ * an `asset://<id>.<ext>` URI — so both resolve here.
421
+ */
422
+ async function resolveTimelineAsset(run, ref) {
423
+ const id = ref.startsWith("asset://")
424
+ ? ref.slice("asset://".length).replace(/\.[A-Za-z0-9]{1,8}$/, "")
425
+ : ref;
426
+ if (!id)
427
+ return null;
428
+ const userId = run.context.userId;
429
+ if (!userId)
430
+ return null;
431
+ const { Asset } = await import("@nodetool-ai/models");
432
+ // `find` is already user-scoped: someone else's asset reads as missing.
433
+ const asset = await Asset.find(userId, id);
434
+ if (!asset)
435
+ return null;
436
+ const thumbnails = isRecord(asset.metadata)
437
+ ? asset.metadata["thumbnails"]
438
+ : undefined;
439
+ const thumbnailAssetId = Array.isArray(thumbnails) && isString(thumbnails[0])
440
+ ? thumbnails[0]
441
+ : undefined;
442
+ const resolved = {
443
+ id: asset.id,
444
+ name: asset.name,
445
+ contentType: asset.content_type
446
+ };
447
+ let duration = asset.duration;
448
+ if ((!isFiniteNumber(duration) || duration <= 0) &&
449
+ (asset.content_type.startsWith("audio/") || asset.content_type.startsWith("video/"))) {
450
+ try {
451
+ const { loadMediaRefBytes, probeVideoDurationSeconds } = await import("@nodetool-ai/runtime");
452
+ const bytes = await loadMediaRefBytes({ asset_id: asset.id }, run.context);
453
+ if (bytes) {
454
+ duration = await probeVideoDurationSeconds(bytes, new AbortController().signal);
455
+ if (isFiniteNumber(duration) && duration > 0) {
456
+ asset.duration = duration;
457
+ await asset.save();
458
+ }
459
+ }
460
+ }
461
+ catch {
462
+ // An explicit clip duration remains usable when the source cannot be probed.
463
+ }
464
+ }
465
+ if (isFiniteNumber(duration) && duration > 0) {
466
+ resolved.durationMs = Math.round(duration * 1000);
467
+ }
468
+ if (thumbnailAssetId)
469
+ resolved.thumbnailAssetId = thumbnailAssetId;
470
+ return resolved;
471
+ }
472
+ /**
473
+ * Run a custom animation's body once and return its curves.
474
+ *
475
+ * The bake is the only place that code runs — the curves are stored and every
476
+ * render site samples them — so it goes through `bakeCustomAnimation`, the
477
+ * same hermetic path `POST /api/timelines/animations/bake` uses. Imported
478
+ * lazily: the sandbox is a heavy dependency for a capability most calls never
479
+ * reach.
480
+ */
481
+ async function bakeTimelineAnimation(run, request) {
482
+ const { bakeCustomAnimation } = await import("../custom-animation-bake.js");
483
+ const params = {
484
+ code: request.code,
485
+ role: request.role,
486
+ durationMs: request.durationMs,
487
+ clipDurationMs: request.clipDurationMs,
488
+ canvas: request.canvas
489
+ };
490
+ if (request.params !== undefined)
491
+ params.params = request.params;
492
+ if (request.staggerCount !== undefined) {
493
+ params.staggerCount = request.staggerCount;
494
+ }
495
+ const baked = await bakeCustomAnimation(run.context, params);
496
+ const result = { ok: baked.ok };
497
+ if (baked.curves !== undefined)
498
+ result.curves = baked.curves;
499
+ if (baked.mask !== undefined)
500
+ result.mask = baked.mask;
501
+ if (baked.error !== undefined)
502
+ result.error = baked.error;
503
+ return result;
504
+ }
505
+ /**
506
+ * The bridge hooks that write outside the document: a Blender render of a 3D
507
+ * clip, and the new sequence `retarget_format` creates.
508
+ */
509
+ function writingHooks(run, sequence) {
510
+ return {
511
+ bakeModel3DClip: async (request) => {
512
+ const { bakeModel3DClipOnServer } = await import("./timeline-bake.js");
513
+ return bakeModel3DClipOnServer(run.context, request);
514
+ },
515
+ retargetFormat: async (adapted) => {
516
+ const { TimelineSequence } = await import("@nodetool-ai/models");
517
+ const derivedDocument = {
518
+ tracks: adapted.tracks,
519
+ clips: adapted.clips,
520
+ markers: adapted.markers
521
+ };
522
+ if (adapted.transcript !== undefined) {
523
+ derivedDocument.transcript = adapted.transcript;
524
+ }
525
+ if (adapted.scriptEnabled !== undefined) {
526
+ derivedDocument.scriptEnabled = adapted.scriptEnabled;
527
+ }
528
+ if (adapted.tempo !== undefined)
529
+ derivedDocument.tempo = adapted.tempo;
530
+ if (adapted.camera2d !== undefined)
531
+ derivedDocument.camera2d = adapted.camera2d;
532
+ if (adapted.setup !== undefined)
533
+ derivedDocument.setup = adapted.setup;
534
+ if (adapted.templateId !== undefined) {
535
+ derivedDocument.templateId = adapted.templateId;
536
+ }
537
+ if (adapted.mediaTracks !== undefined) {
538
+ derivedDocument.mediaTracks = adapted.mediaTracks;
539
+ }
540
+ const name = `${sequence.name} (${adapted.width}×${adapted.height})`;
541
+ const created = await TimelineSequence.create({
542
+ user_id: run.context.userId,
543
+ project_id: sequence.project_id,
544
+ workflow_id: sequence.workflow_id,
545
+ name,
546
+ fps: adapted.fps,
547
+ width: adapted.width,
548
+ height: adapted.height,
549
+ duration_ms: adapted.durationMs,
550
+ document: JSON.stringify(derivedDocument)
551
+ });
552
+ return { sequenceId: created.id, name };
553
+ }
554
+ };
555
+ }
556
+ /** Track-only batches need no simulated editor or external hooks. */
557
+ function applyTrackOps(sequence, document, ops) {
558
+ const contracts = buildTimelineToolContracts({
559
+ staggerUnits: STAGGER_UNITS,
560
+ animatedProperties: ANIMATED_PROPERTIES,
561
+ beatToleranceMs: DEFAULT_BEAT_TOLERANCE_MS
562
+ });
563
+ let state = {
564
+ fps: sequence.fps,
565
+ width: sequence.width,
566
+ height: sequence.height,
567
+ tracks: document.tracks,
568
+ clips: document.clips,
569
+ markers: document.markers,
570
+ mediaTracks: document.mediaTracks,
571
+ tempo: document.tempo,
572
+ playheadMs: 0,
573
+ selectedClipIds: []
574
+ };
575
+ const usedIds = new Set([
576
+ ...[
577
+ ...document.tracks,
578
+ ...document.clips,
579
+ ...document.markers,
580
+ ...(document.mediaTracks ?? [])
581
+ ].map((unit) => unit.id),
582
+ ...document.clips.flatMap((clip) => (clip.animations ?? []).map((animation) => animation.id))
583
+ ]);
584
+ let nextId = 0;
585
+ const newId = () => {
586
+ let id;
587
+ do {
588
+ id = `track_${++nextId}`;
589
+ } while (usedIds.has(id));
590
+ usedIds.add(id);
591
+ return id;
592
+ };
593
+ const records = [];
594
+ for (const entry of ops) {
595
+ try {
596
+ let op;
597
+ if (entry.op === "ui_timeline_add_track") {
598
+ const args = parseWithTypeCoercion(z.object(contracts.ui_timeline_add_track.shape), entry.input);
599
+ op = { op: "add_track", ...args };
600
+ }
601
+ else if (entry.op === "ui_timeline_move_track") {
602
+ const args = parseWithTypeCoercion(z.object(contracts.ui_timeline_move_track.shape), entry.input);
603
+ op = { op: "move_track", ...resolveMoveTrackArgs(args) };
604
+ }
605
+ else {
606
+ const args = parseWithTypeCoercion(z.object(contracts.ui_timeline_delete_track.shape), entry.input);
607
+ op = { op: "delete_track", ...resolveDeleteTrackArgs(args) };
608
+ }
609
+ const outcome = applyTimelineTrackOp(state, op, { newId });
610
+ if (outcome.error)
611
+ throw new Error(outcome.error);
612
+ state = outcome.state;
613
+ records.push({ op: entry.op, ok: true, result: outcome.result });
614
+ }
615
+ catch (error) {
616
+ records.push({
617
+ op: entry.op,
618
+ ok: false,
619
+ error: error instanceof Error ? error.message : String(error)
620
+ });
621
+ }
622
+ }
623
+ return {
624
+ records,
625
+ state: {
626
+ fps: state.fps,
627
+ width: state.width,
628
+ height: state.height,
629
+ durationMs: state.clips.reduce((end, clip) => Math.max(end, clip.startMs + clip.durationMs), 0),
630
+ playheadMs: state.playheadMs,
631
+ tracks: state.tracks.map(({ id, name, type, index }) => ({
632
+ id,
633
+ name,
634
+ type,
635
+ index
636
+ })),
637
+ clips: state.clips.map((clip) => ({
638
+ id: clip.id,
639
+ name: clip.name,
640
+ trackId: clip.trackId,
641
+ mediaType: clip.mediaType,
642
+ startMs: clip.startMs,
643
+ durationMs: clip.durationMs,
644
+ prompt: clip.prompt,
645
+ animations: (clip.animations ?? []).map(({ role, preset }) => ({
646
+ role,
647
+ preset
648
+ }))
649
+ })),
650
+ documentTracks: state.tracks,
651
+ documentClips: state.clips,
652
+ markers: state.markers,
653
+ mediaTracks: state.mediaTracks ?? [],
654
+ derivedSequences: [],
655
+ tempo: state.tempo,
656
+ camera2d: document.camera2d ?? null,
657
+ setup: document.setup ?? null,
658
+ transitionCandidates: [],
659
+ appliedTransitionCandidates: [],
660
+ toolLog: ops.map((entry) => entry.op),
661
+ previewTimesMs: [],
662
+ previewedLayerKinds: []
663
+ }
664
+ };
665
+ }
666
+ /**
667
+ * Run `ops` against a bridge seeded from `document`.
668
+ *
669
+ * A failing op is recorded and the script continues: stopping at the first
670
+ * error hides every problem behind it, and the caller wants the whole picture.
671
+ *
672
+ * `hermetic` leaves out the hooks that write outside the document: the 3D
673
+ * render and the new sequence a retarget creates. A code bake sets it. The
674
+ * bridge then uses its in-memory fallbacks for those ops.
675
+ */
676
+ export async function applyOps(run, sequence, document, ops, options = {}) {
677
+ if (ops.every(({ op }) => op === "ui_timeline_add_track" || op === "ui_timeline_move_track" || op === "ui_timeline_delete_track")) {
678
+ return applyTrackOps(sequence, document, ops);
679
+ }
680
+ const { createTimelineToolBridge } = await import("./timeline-bridge.js");
681
+ let operationIndex = 0;
682
+ const init = {
683
+ sequenceId: sequence.id,
684
+ sequenceName: sequence.name,
685
+ projectId: sequence.project_id,
686
+ sequence: {
687
+ fps: sequence.fps,
688
+ width: sequence.width,
689
+ height: sequence.height,
690
+ tracks: document.tracks,
691
+ clips: document.clips,
692
+ markers: document.markers,
693
+ transcript: document.transcript,
694
+ scriptEnabled: document.scriptEnabled,
695
+ templateId: document.templateId,
696
+ tempo: document.tempo,
697
+ camera2d: document.camera2d,
698
+ setup: document.setup,
699
+ mediaTracks: document.mediaTracks
700
+ },
701
+ resolveAsset: (ref) => resolveTimelineAsset(run, ref),
702
+ bakeAnimation: (request) => bakeTimelineAnimation(run, request),
703
+ loadComposition: {
704
+ get: async (id) => {
705
+ const { loadComposition } = await import("./compositions.js");
706
+ const found = await loadComposition(run, id);
707
+ return found ? found.composition : null;
708
+ },
709
+ listIds: async () => {
710
+ const { loadShippedCompositions, loadUserCompositions } = await import("./compositions.js");
711
+ const mine = await loadUserCompositions(run);
712
+ return [
713
+ ...loadShippedCompositions().map((comp) => comp.id),
714
+ ...(Array.isArray(mine) ? mine.map((comp) => comp.id) : [])
715
+ ];
716
+ }
717
+ }
718
+ };
719
+ if (!options.hermetic) {
720
+ Object.assign(init, writingHooks(run, sequence));
721
+ const { timelineMediaEditGenerator } = await import("./timeline-media-edit.js");
722
+ const generate = options.generateMediaEdit ?? timelineMediaEditGenerator(run);
723
+ init.generateMediaEdit = (request) => generate(request, operationIndex);
724
+ init.getClipFrames = async (clip, frameOptions) => {
725
+ const current = bridge.finalState();
726
+ const { inspectTimelineClipFrames } = await import("./timeline-clip-frames.js");
727
+ return inspectTimelineClipFrames(run.context, { ...sequence.toDocument(),
728
+ tracks: current.documentTracks, clips: current.documentClips, markers: current.markers,
729
+ mediaTracks: current.mediaTracks, tempo: current.tempo, camera2d: current.camera2d,
730
+ id: sequence.id, projectId: sequence.project_id ?? "default", name: sequence.name,
731
+ fps: sequence.fps, width: sequence.width, height: sequence.height,
732
+ durationMs: sequence.duration_ms, createdAt: sequence.created_at, updatedAt: sequence.updated_at
733
+ }, clip, frameOptions);
734
+ };
735
+ }
736
+ const bridge = createTimelineToolBridge(init);
737
+ const byName = new Map(bridge.tools
738
+ .filter((tool) => !EXCLUDED_OPS.has(tool.name) && !(options.hermetic && (tool.name === `${TOOL_PREFIX}generatively_edit_clip` || READ_ONLY_OPS.has(tool.name))))
739
+ .map((tool) => [tool.name, tool]));
740
+ const records = [];
741
+ for (const [index, { op, input }] of ops.entries()) {
742
+ operationIndex = index;
743
+ const tool = byName.get(op);
744
+ if (!tool) {
745
+ const known = [...byName.keys()]
746
+ .map((name) => name.slice(TOOL_PREFIX.length))
747
+ .sort()
748
+ .join(", ");
749
+ records.push({
750
+ op,
751
+ ok: false,
752
+ error: `No timeline operation named "${op.slice(TOOL_PREFIX.length)}". Available: ${known}.`
753
+ });
754
+ continue;
755
+ }
756
+ try {
757
+ records.push({ op, ok: true, result: await tool.execute(input) });
758
+ }
759
+ catch (e) {
760
+ records.push({
761
+ op,
762
+ ok: false,
763
+ error: e instanceof Error ? e.message : String(e)
764
+ });
765
+ }
766
+ }
767
+ return { records, state: bridge.finalState() };
768
+ }
769
+ /**
770
+ * The keys an op names its unit under, and which list each one means.
771
+ *
772
+ * `id`, `target`, `clip_id` and `track_id` are resolved against both lists,
773
+ * because `target` addresses a clip on most ops and a track on `move_track`.
774
+ * The midi ops spell theirs `clip` and `track`, which already say which they
775
+ * mean — so each is resolved against that list alone, and a clip sharing a
776
+ * track's name cannot capture it.
777
+ */
778
+ const TIMELINE_OP_ID_KEYS = {
779
+ id: "any",
780
+ target: "any",
781
+ clip_id: "any",
782
+ track_id: "any",
783
+ clip: "clip",
784
+ track: "track"
785
+ };
786
+ function resolveNamedUnit(value, clips, tracks, scope) {
787
+ const lower = value.toLowerCase();
788
+ const match = (units) => (units.find((u) => u.id === value) ??
789
+ units.find((u) => u.name.toLowerCase() === lower))?.id;
790
+ if (scope !== "track") {
791
+ const clip = match(clips);
792
+ if (clip)
793
+ return clip;
794
+ }
795
+ if (scope !== "clip") {
796
+ const track = match(tracks);
797
+ if (track)
798
+ return track;
799
+ }
800
+ return value;
801
+ }
802
+ /**
803
+ * The unit ids one op's result names.
804
+ *
805
+ * The bridge answers `{ok, clip}`, `{ok, track}`, `{ok, marker}`, `{ok, clips}`
806
+ * (a split), `{ok, deleted}` (a delete) or `{ok, selected}` — never a bare
807
+ * `id`, which is why reading `result.id` alone left every `"selected"` target
808
+ * unresolved.
809
+ */
810
+ export function resultUnitIds(result) {
811
+ if (!isRecord(result))
812
+ return [];
813
+ const ids = [];
814
+ const push = (value) => {
815
+ if (isRecord(value) && isString(value["id"]))
816
+ ids.push(value["id"]);
817
+ };
818
+ for (const key of ["clip", "track", "marker", "deleted", "selected"]) {
819
+ push(result[key]);
820
+ }
821
+ const clips = result["clips"];
822
+ if (Array.isArray(clips)) {
823
+ for (const clip of clips)
824
+ push(clip);
825
+ }
826
+ if (isString(result["id"]))
827
+ ids.push(result["id"]);
828
+ return ids;
829
+ }
830
+ /**
831
+ * Canonicalize one op input for the `resource_change` broadcast: names and
832
+ * `"selected"` become ids, and an op that created something carries the id it
833
+ * created. Without that stamp an editor merging this write cannot tell which
834
+ * unit an `add_track` touched and falls back to contesting every unit that
835
+ * happens to have drifted.
836
+ */
837
+ export function resolveTimelineOpInput(input, before, state, result) {
838
+ const clips = [
839
+ ...before.clips.map((c) => ({ id: c.id, name: c.name })),
840
+ ...state.clips
841
+ ];
842
+ const tracks = [
843
+ ...before.tracks.map((t) => ({ id: t.id, name: t.name })),
844
+ ...state.tracks
845
+ ];
846
+ const resultIds = resultUnitIds(result);
847
+ const next = { ...input };
848
+ for (const [key, scope] of Object.entries(TIMELINE_OP_ID_KEYS)) {
849
+ const value = next[key];
850
+ if (typeof value !== "string" || value.length === 0)
851
+ continue;
852
+ if (value.toLowerCase() === "selected") {
853
+ if (resultIds[0])
854
+ next[key] = resultIds[0];
855
+ continue;
856
+ }
857
+ next[key] = resolveNamedUnit(value, clips, tracks, scope);
858
+ }
859
+ // An op that named no unit either created one or addressed the selection;
860
+ // the result says which, so stamp it.
861
+ if (next["id"] === undefined && resultIds.length > 0) {
862
+ next["id"] = resultIds.length === 1 ? resultIds[0] : resultIds;
863
+ }
864
+ return next;
865
+ }
866
+ const editTimeline = {
867
+ spec: editTimelineSpec,
868
+ impl: async (run, params) => {
869
+ const timelineId = params["timeline_id"];
870
+ if (!isString(timelineId) || !timelineId) {
871
+ return {
872
+ error: "timeline_id is required (use list_timelines to find one)."
873
+ };
874
+ }
875
+ const ops = parseOps(params["ops"]);
876
+ if (isError(ops))
877
+ return ops;
878
+ if (ops.length > 1 &&
879
+ ops.some((entry) => entry.op === `${TOOL_PREFIX}retarget_format`)) {
880
+ return {
881
+ error: "retarget_format creates a new sequence and must be the only op in " +
882
+ "an edit_timeline call. Call it once per target format, then edit " +
883
+ "the returned timeline id."
884
+ };
885
+ }
886
+ const { TimelineSequence, TimelineSequenceVersion } = await import("@nodetool-ai/models");
887
+ const { timelineMediaEditGenerator } = await import("./timeline-media-edit.js");
888
+ const generateMediaEdit = timelineMediaEditGenerator(run);
889
+ for (let attempt = 0; attempt < CAS_ATTEMPTS; attempt++) {
890
+ const sequence = await TimelineSequence.findById(timelineId);
891
+ // A sequence owned by someone else reads as missing — the rule the tRPC
892
+ // router's ownership check applies.
893
+ if (!sequence || sequence.user_id !== run.context.userId) {
894
+ return { error: `Timeline ${timelineId} was not found.` };
895
+ }
896
+ const document = sequence.toDocument();
897
+ const { records, state } = await applyOps(run, sequence, document, ops, { generateMediaEdit });
898
+ // The transcript rides along untouched — no timeline operation edits it,
899
+ // so the stored copy stays authoritative. Markers come back from the
900
+ // bridge, which seeded them and which the marker ops write to.
901
+ const next = {
902
+ ...document,
903
+ tracks: state.documentTracks,
904
+ clips: state.documentClips,
905
+ markers: state.markers
906
+ };
907
+ // `set_tempo` and the first midi track both write it. Without this the
908
+ // stored document keeps the old BPM while the clips carry the rescaled
909
+ // milliseconds, so the part plays at the wrong speed on the next read.
910
+ if (state.tempo)
911
+ next.tempo = state.tempo;
912
+ // The guided flow's stage and plan are document state like the rest: an
913
+ // op run that moved the flow on has to be what the row holds afterwards,
914
+ // or the next surface to open the sequence resumes at the old step.
915
+ if (state.setup) {
916
+ next.setup = state.setup;
917
+ }
918
+ // Subject/object tracks come back from the bridge the way markers do.
919
+ // A document that never carried one keeps the field absent rather than
920
+ // growing an empty array; one that did keeps what the ops left it with,
921
+ // including the empty array `delete_track_object` leaves behind.
922
+ if (state.mediaTracks.length > 0 || document.mediaTracks !== undefined) {
923
+ next.mediaTracks = state.mediaTracks;
924
+ }
925
+ const failed = records.filter((record) => !record.ok);
926
+ // Only the ops that landed describe the write, and a script where none
927
+ // landed is not a write at all: saving it would bump the revision and
928
+ // hand an open editor a merge with nothing in it.
929
+ const appliedOps = ops
930
+ .map((parsed, index) => ({ parsed, index }))
931
+ .filter(({ parsed, index }) => records[index]?.ok && !READ_ONLY_OPS.has(parsed.op));
932
+ if (appliedOps.length === 0) {
933
+ return {
934
+ timeline_id: timelineId,
935
+ updated_at: sequence.updated_at,
936
+ applied: records.filter((record) => record.ok).length,
937
+ failed: failed.length,
938
+ ops: records,
939
+ tracks: state.tracks,
940
+ clips: state.clips.map((clip) => ({
941
+ id: clip.id,
942
+ name: clip.name,
943
+ track_id: clip.trackId,
944
+ media_type: clip.mediaType,
945
+ start_ms: clip.startMs,
946
+ duration_ms: clip.durationMs,
947
+ animations: clip.animations
948
+ }))
949
+ };
950
+ }
951
+ // retarget_format has already created a derived row through the bridge's
952
+ // host callback. It deliberately leaves this source document untouched,
953
+ // including its revision and updated_at timestamp.
954
+ if (appliedOps[0]?.parsed.op === `${TOOL_PREFIX}retarget_format`) {
955
+ return {
956
+ timeline_id: timelineId,
957
+ updated_at: sequence.updated_at,
958
+ applied: 1,
959
+ failed: failed.length,
960
+ ops: records,
961
+ tracks: state.tracks,
962
+ clips: state.clips.map((clip) => ({
963
+ id: clip.id,
964
+ name: clip.name,
965
+ track_id: clip.trackId,
966
+ media_type: clip.mediaType,
967
+ start_ms: clip.startMs,
968
+ duration_ms: clip.durationMs,
969
+ animations: clip.animations
970
+ }))
971
+ };
972
+ }
973
+ const undo = appliedOps.some(({ parsed }) => parsed.op === `${TOOL_PREFIX}apply_take`)
974
+ ? await TimelineSequenceVersion.snapshot(sequence, { saveType: "manual", name: "Before applying AI edit take" })
975
+ : undefined;
976
+ const saved = await TimelineSequence.updateDocumentIfUnchanged(sequence.id, sequence.updated_at, next, {
977
+ ops: appliedOps.map(({ parsed, index }) => ({
978
+ tool: parsed.op,
979
+ input: resolveTimelineOpInput(parsed.input, document, state, records[index]?.result)
980
+ }))
981
+ }).catch(async (error) => {
982
+ await undo?.delete();
983
+ throw error;
984
+ });
985
+ if (!saved) {
986
+ await undo?.delete();
987
+ continue;
988
+ }
989
+ const response = {
990
+ timeline_id: timelineId,
991
+ updated_at: saved.updated_at,
992
+ applied: records.length - failed.length,
993
+ failed: failed.length,
994
+ ops: records,
995
+ tracks: state.tracks,
996
+ clips: state.clips.map((clip) => ({
997
+ id: clip.id,
998
+ name: clip.name,
999
+ track_id: clip.trackId,
1000
+ media_type: clip.mediaType,
1001
+ start_ms: clip.startMs,
1002
+ duration_ms: clip.durationMs,
1003
+ animations: clip.animations
1004
+ }))
1005
+ };
1006
+ if (undo) {
1007
+ Object.assign(response, { undo_version: undo.version });
1008
+ }
1009
+ return response;
1010
+ }
1011
+ return {
1012
+ error: `Timeline ${timelineId} is being modified concurrently; nothing was saved. Retry the call.`
1013
+ };
1014
+ }
1015
+ };
1016
+ // ---------------------------------------------------------------------------
1017
+ // validate_timeline
1018
+ // ---------------------------------------------------------------------------
1019
+ /**
1020
+ * The media ref a clip's `currentAssetId` names. Usually a bare asset id, but a
1021
+ * shipped example names its stills by `package://` URI, which resolves for
1022
+ * every user without an asset row; wrapping that in `asset://` made an id no
1023
+ * store holds.
1024
+ */
1025
+ function clipAssetRef(assetId) {
1026
+ return assetId.includes("://")
1027
+ ? { uri: assetId }
1028
+ : { uri: `asset://${assetId}`, asset_id: assetId };
1029
+ }
1030
+ /** A positive finite number from a tool param, or undefined. */
1031
+ function numberParam(value) {
1032
+ return isFiniteNumber(value) && value > 0
1033
+ ? value
1034
+ : undefined;
1035
+ }
1036
+ /**
1037
+ * Like {@link numberParam} but keeps 0, for a shutter angle: 0 degrees is a
1038
+ * closed shutter, a value the schema can express and `numberParam` would read
1039
+ * as unset and silently replace with the 180-degree default.
1040
+ */
1041
+ function angleParam(value) {
1042
+ return isFiniteNumber(value) && value >= 0 ? value : undefined;
1043
+ }
1044
+ /** Unwrap a stored document that may still be JSON text. */
1045
+ function parseStoredDocument(document) {
1046
+ if (!isString(document))
1047
+ return document;
1048
+ try {
1049
+ return JSON.parse(document);
1050
+ }
1051
+ catch {
1052
+ return undefined;
1053
+ }
1054
+ }
1055
+ const validateTimeline = {
1056
+ spec: validateTimelineSpec,
1057
+ // The timeline API is tRPC-only, so there is no REST route to fall back on.
1058
+ // A host may put a loader on the run — the MCP server does, to apply its own
1059
+ // ownership rule — and without one the row is read the way every other
1060
+ // capability in this module reads it. The "no loader" refusal this replaced
1061
+ // meant a chat belt could edit a sequence it could not then validate.
1062
+ impl: async (run, params) => {
1063
+ const tier = params["tier"];
1064
+ if (tier !== undefined && tier !== "standard" && tier !== "showcase") {
1065
+ return { error: "Unsupported validation tier. Use standard or showcase." };
1066
+ }
1067
+ const inline = params["document"];
1068
+ const timelineId = params["timeline_id"];
1069
+ let document = inline;
1070
+ // An inline document carries no stored render settings, so the caller
1071
+ // supplies them; the timeline_id path overwrites these from the row.
1072
+ let meta = {
1073
+ fps: numberParam(params["fps"]),
1074
+ width: numberParam(params["width"]),
1075
+ height: numberParam(params["height"])
1076
+ };
1077
+ let name;
1078
+ if (document === undefined && timelineId) {
1079
+ const loadRow = run.loaders?.timeline;
1080
+ const record = loadRow
1081
+ ? await loadRow(run.context, timelineId)
1082
+ : await (async () => {
1083
+ const seq = await loadTimeline(run, timelineId);
1084
+ return isError(seq) ? null : seq;
1085
+ })();
1086
+ if (!record) {
1087
+ return {
1088
+ error: `Timeline ${timelineId} was not found.`,
1089
+ validated: false
1090
+ };
1091
+ }
1092
+ document = parseStoredDocument(record.document);
1093
+ meta = { fps: record.fps, width: record.width, height: record.height };
1094
+ name = record.name;
1095
+ }
1096
+ if (document === undefined || document === null) {
1097
+ return {
1098
+ error: "No timeline to validate — pass an inline `document` ({tracks, clips, markers}) or a valid `timeline_id`."
1099
+ };
1100
+ }
1101
+ const { validateTimelineSequence } = await import("@nodetool-ai/execution/timeline-debug");
1102
+ const validationMeta = { ...meta };
1103
+ if (tier !== undefined) {
1104
+ validationMeta.tier = tier;
1105
+ }
1106
+ // Inline preflight must use the same authoring normalization as setDocument.
1107
+ if (inline !== undefined && params["normalize"] === true && isRecord(document)) {
1108
+ const normalized = documentToStore(document);
1109
+ document = normalized.document;
1110
+ meta = { ...normalized.settings, ...Object.fromEntries(Object.entries(meta).filter(([, value]) => value !== undefined)) };
1111
+ Object.assign(validationMeta, meta);
1112
+ }
1113
+ const validation = validateTimelineSequence(document, validationMeta);
1114
+ const report = { ...validation, summary: validationSummary(validation) };
1115
+ if (timelineId)
1116
+ report.timeline_id = timelineId;
1117
+ if (name)
1118
+ report.name = name;
1119
+ return report;
1120
+ }
1121
+ };
1122
+ // ---------------------------------------------------------------------------
1123
+ // set_timeline_document
1124
+ // ---------------------------------------------------------------------------
1125
+ /**
1126
+ * A document the caller sent, ready to validate.
1127
+ *
1128
+ * A hand-authored cut leaves out the bookkeeping the schema requires — track
1129
+ * `index`/`visible`/`locked`, clip `sourceType`/`status`/`locked`/`versions`,
1130
+ * animation ids, `markers` — and refusing it with two dozen schema errors
1131
+ * teaches the caller nothing. `normalizeAuthoredDocument` fills exactly what is
1132
+ * missing and lifts document-level `fps`/`width`/`height` out as sequence
1133
+ * settings; a value the caller sent is never replaced, because the point of a
1134
+ * whole-document write is that what was sent is what the sequence becomes.
1135
+ */
1136
+ function documentToStore(raw) {
1137
+ return normalizeAuthoredDocument(raw);
1138
+ }
1139
+ /** The end of the last clip — what the sequence's stored duration means. */
1140
+ function documentDurationMs(document) {
1141
+ const clips = document["clips"];
1142
+ if (!Array.isArray(clips))
1143
+ return 0;
1144
+ return clips.reduce((end, clip) => {
1145
+ if (!isRecord(clip))
1146
+ return end;
1147
+ const start = Number(clip["startMs"]) || 0;
1148
+ const length = Number(clip["durationMs"]) || 0;
1149
+ return Math.max(end, start + length);
1150
+ }, 0);
1151
+ }
1152
+ /**
1153
+ * Replace a sequence's whole document in one call.
1154
+ *
1155
+ * `edit_timeline` is a script of ops against what is already stored, which is
1156
+ * the wrong shape for authoring a cut from nothing: every clip costs an op,
1157
+ * and the ops only reach the fields the bridge exposes. This takes the
1158
+ * document itself.
1159
+ *
1160
+ * The order is validate → snapshot → CAS → validate again, and each step
1161
+ * exists for a failure the one before it cannot catch:
1162
+ *
1163
+ * 1. **Validate first.** A document that would not render must not reach the
1164
+ * database — a refusal that still wrote is worse than no capability at all.
1165
+ * Errors return the issues and nothing else happens, snapshot included: a
1166
+ * refused call that left a version row behind is still a write.
1167
+ * 2. **Snapshot.** The state being replaced becomes a manual version, so the
1168
+ * write is undoable with `restore_timeline_version` the way a restore is.
1169
+ * 3. **CAS.** The write lands only while the row still reads as it did, so a
1170
+ * concurrent edit is reported instead of overwritten. There is no retry
1171
+ * loop here, unlike `edit_timeline`: ops re-apply against a newer document
1172
+ * and compose, a whole-document replace does not — retrying it would clobber
1173
+ * exactly the change CAS caught.
1174
+ * 4. **Validate again.** The caller sees what it created rather than what it
1175
+ * intended. The two validations differ: the second runs against the stored
1176
+ * fps/width/height and the document as the row now holds it.
1177
+ */
1178
+ const setTimelineDocument = {
1179
+ spec: setTimelineDocumentSpec,
1180
+ impl: async (run, params) => {
1181
+ const sequence = await loadTimeline(run, params["timeline_id"]);
1182
+ if (isError(sequence))
1183
+ return sequence;
1184
+ const raw = params["document"];
1185
+ if (!isRecord(raw)) {
1186
+ return {
1187
+ error: "document is required and must be an object ({tracks, clips, markers}). Read the current one with get_timeline."
1188
+ };
1189
+ }
1190
+ const expected = params["expected_updated_at"];
1191
+ if (expected !== undefined && expected !== null) {
1192
+ if (!isString(expected)) {
1193
+ return { error: "expected_updated_at must be a string timestamp." };
1194
+ }
1195
+ if (expected !== sequence.updated_at) {
1196
+ return {
1197
+ error: `Timeline ${sequence.id} was modified since it was read at ${expected} (it now reads ${sequence.updated_at}); nothing was written. Read it again with get_timeline and re-apply your changes.`,
1198
+ written: false,
1199
+ conflict: true,
1200
+ timeline_id: sequence.id
1201
+ };
1202
+ }
1203
+ }
1204
+ const { document, settings } = documentToStore(raw);
1205
+ // Document-level fps/width/height are sequence settings, so opts win and a
1206
+ // document that carries them configures the sequence instead of having
1207
+ // them stripped with a `field_stripped` warning.
1208
+ const fps = sequenceSetting(params["fps"] ?? settings.fps, sequence.fps, "fps");
1209
+ if (isError(fps))
1210
+ return fps;
1211
+ const width = sequenceSetting(params["width"] ?? settings.width, sequence.width, "width");
1212
+ if (isError(width))
1213
+ return width;
1214
+ const height = sequenceSetting(params["height"] ?? settings.height, sequence.height, "height");
1215
+ if (isError(height))
1216
+ return height;
1217
+ const { validateTimelineSequence } = await import("@nodetool-ai/execution/timeline-debug");
1218
+ const before = validateTimelineSequence(document, {
1219
+ fps,
1220
+ width,
1221
+ height
1222
+ });
1223
+ if (!before.ok) {
1224
+ return {
1225
+ error: `The document has ${before.errors.length} error${before.errors.length === 1 ? "" : "s"} and was not written to timeline ${sequence.id}. Fix them and call again.`,
1226
+ written: false,
1227
+ timeline_id: sequence.id,
1228
+ validation: before,
1229
+ summary: validationSummary(before)
1230
+ };
1231
+ }
1232
+ const { TimelineSequence, TimelineSequenceVersion } = await import("@nodetool-ai/models");
1233
+ const snapshotName = isString(params["snapshot_name"]) && params["snapshot_name"]
1234
+ ? params["snapshot_name"]
1235
+ : "Before set_timeline_document";
1236
+ const undo = await TimelineSequenceVersion.snapshot(sequence, {
1237
+ saveType: "manual",
1238
+ name: snapshotName
1239
+ });
1240
+ const durationMs = documentDurationMs(document);
1241
+ let saved;
1242
+ try {
1243
+ saved = await TimelineSequence.updateFieldsIfUnchanged(sequence.id, sequence.updated_at, {
1244
+ document: JSON.stringify(document),
1245
+ fps,
1246
+ width,
1247
+ height,
1248
+ duration_ms: durationMs
1249
+ });
1250
+ }
1251
+ catch (error) {
1252
+ // The model rejects a document without tracks/clips/markers arrays. The
1253
+ // validation above already covers that, so reaching here means the two
1254
+ // disagree — report it rather than throwing out of the capability.
1255
+ return {
1256
+ error: `The document was refused by the store: ${error instanceof Error ? error.message : String(error)}`,
1257
+ written: false,
1258
+ timeline_id: sequence.id,
1259
+ undo_version: undo.version
1260
+ };
1261
+ }
1262
+ if (!saved) {
1263
+ return {
1264
+ error: `Timeline ${sequence.id} was modified concurrently; nothing was written. Read it again with get_timeline and re-apply your changes.`,
1265
+ written: false,
1266
+ conflict: true,
1267
+ timeline_id: sequence.id,
1268
+ undo_version: undo.version
1269
+ };
1270
+ }
1271
+ const after = validateTimelineSequence(saved.toDocument(), { fps: saved.fps, width: saved.width, height: saved.height });
1272
+ return {
1273
+ ok: true,
1274
+ written: true,
1275
+ timeline_id: saved.id,
1276
+ updated_at: saved.updated_at,
1277
+ undo_version: undo.version,
1278
+ fps: saved.fps,
1279
+ width: saved.width,
1280
+ height: saved.height,
1281
+ duration_ms: saved.duration_ms,
1282
+ track_count: Array.isArray(document["tracks"])
1283
+ ? document["tracks"].length
1284
+ : 0,
1285
+ clip_count: Array.isArray(document["clips"])
1286
+ ? document["clips"].length
1287
+ : 0,
1288
+ validation: after,
1289
+ summary: validationSummary(after)
1290
+ };
1291
+ }
1292
+ };
1293
+ /**
1294
+ * The timecodes to render when the caller names none: evenly spaced across the
1295
+ * sequence, avoiding both ends — the first and last frame of a cut are the two
1296
+ * least informative places to look.
1297
+ */
1298
+ function evenlySpacedTimes(durationMs, count) {
1299
+ const span = Math.max(1, durationMs);
1300
+ return Array.from({ length: count }, (_, i) => Math.round((span * (i + 1)) / (count + 1)));
1301
+ }
1302
+ /** A persisted PNG as the image reference `view_image` reads. */
1303
+ function imageHandle(saved) {
1304
+ return {
1305
+ type: "image",
1306
+ asset_id: saved.asset_id,
1307
+ asset_uri: saved.asset_uri,
1308
+ uri: saved.asset_uri ?? saved.path,
1309
+ path: saved.path,
1310
+ mime_type: saved.mime_type,
1311
+ bytes: saved.bytes
1312
+ };
1313
+ }
1314
+ /**
1315
+ * The timecodes a `range` names: `count` of them from `from_ms` to `to_ms`,
1316
+ * both ends included. Inclusive because a range is how a caller watches a move
1317
+ * play out, and a move's start and end are the two instants it is defined by —
1318
+ * the opposite of the default sweep, which avoids the ends of the whole cut.
1319
+ */
1320
+ function rangeTimes(raw) {
1321
+ if (!isRecord(raw)) {
1322
+ return { error: "range must be an object ({from_ms, to_ms, count})." };
1323
+ }
1324
+ const from = Number(raw["from_ms"]);
1325
+ const to = Number(raw["to_ms"]);
1326
+ if (!isFiniteNumber(from) || !isFiniteNumber(to) || from < 0 || to < 0) {
1327
+ return { error: "range needs a non-negative from_ms and to_ms." };
1328
+ }
1329
+ if (to < from) {
1330
+ return {
1331
+ error: `range runs backwards: from_ms ${from} is after to_ms ${to}.`
1332
+ };
1333
+ }
1334
+ const count = raw["count"] === undefined || raw["count"] === null
1335
+ ? DEFAULT_PREVIEW_COUNT
1336
+ : Math.round(Number(raw["count"]));
1337
+ if (!isFiniteNumber(count) || count < 1) {
1338
+ return { error: "range.count must be a whole number of 1 or more." };
1339
+ }
1340
+ if (count > MAX_PREVIEW_RANGE_COUNT) {
1341
+ return {
1342
+ error: `range.count is ${count}; at most ${MAX_PREVIEW_RANGE_COUNT} frames render per call.`
1343
+ };
1344
+ }
1345
+ if (count === 1)
1346
+ return [from];
1347
+ return Array.from({ length: count }, (_, i) => Math.round(from + ((to - from) * i) / (count - 1)));
1348
+ }
1349
+ /** The timecodes a preview or compare call asks for. */
1350
+ function requestedTimes(params, durationMs, maxTimes = MAX_PREVIEW_TIMES) {
1351
+ const raw = params["times_ms"];
1352
+ const range = params["range"];
1353
+ const hasRange = range !== undefined && range !== null;
1354
+ if (hasRange && raw !== undefined && raw !== null) {
1355
+ return {
1356
+ error: "Pass times_ms or range, not both — they name the timecodes two different ways."
1357
+ };
1358
+ }
1359
+ if (hasRange)
1360
+ return rangeTimes(range);
1361
+ if (raw === undefined || raw === null) {
1362
+ const count = Math.max(1, Math.min(MAX_PREVIEW_TIMES, Math.round(Number(params["count"]) || DEFAULT_PREVIEW_COUNT)));
1363
+ return evenlySpacedTimes(durationMs, count);
1364
+ }
1365
+ if (!Array.isArray(raw)) {
1366
+ return { error: "times_ms must be an array of milliseconds." };
1367
+ }
1368
+ if (raw.length === 0) {
1369
+ return { error: "times_ms was empty — omit it to sample evenly instead." };
1370
+ }
1371
+ if (raw.length > maxTimes) {
1372
+ return {
1373
+ error: `times_ms holds ${raw.length} timecodes; at most ${maxTimes} render per call. ` +
1374
+ `Split them across ${Math.ceil(raw.length / maxTimes)} calls of ${maxTimes} or fewer, ` +
1375
+ "or pass `range` with `count` to sample a span evenly in one call."
1376
+ };
1377
+ }
1378
+ const times = [];
1379
+ for (const value of raw) {
1380
+ if (!isFiniteNumber(value) || value < 0) {
1381
+ return {
1382
+ error: `times_ms must hold non-negative numbers; got ${JSON.stringify(value)}.`
1383
+ };
1384
+ }
1385
+ times.push(value);
1386
+ }
1387
+ return times;
1388
+ }
1389
+ /**
1390
+ * Render the composited frame at chosen timecodes.
1391
+ *
1392
+ * Frames are persisted as assets and returned as handles, not as pixels: this
1393
+ * follows the rule `view_image` exists for — a tool that produces an image
1394
+ * hands back a reference, and the model pulls the pixels into context only for
1395
+ * the frame it decides to look at. Three frames of inline base64 would be in
1396
+ * every subsequent turn of the conversation whether or not they were read.
1397
+ */
1398
+ const previewTimelineFrame = {
1399
+ spec: previewTimelineFrameSpec,
1400
+ impl: async (run, params) => {
1401
+ const timelineId = params["timeline_id"];
1402
+ const inline = params["document"];
1403
+ let document = inline;
1404
+ let meta = {
1405
+ fps: numberParam(params["fps"]) ?? 30,
1406
+ width: numberParam(params["width_px"]) ?? 1920,
1407
+ height: numberParam(params["height_px"]) ?? 1080
1408
+ };
1409
+ let durationMs = 0;
1410
+ let name = "Inline timeline";
1411
+ if (document === undefined || document === null) {
1412
+ const seq = await loadTimeline(run, timelineId);
1413
+ if (isError(seq))
1414
+ return seq;
1415
+ const resolved = seq.toTimelineSequence();
1416
+ document = resolved;
1417
+ meta = { fps: resolved.fps, width: resolved.width, height: resolved.height };
1418
+ durationMs = resolved.durationMs;
1419
+ name = resolved.name;
1420
+ }
1421
+ if (!isRecord(document)) {
1422
+ return {
1423
+ error: "No timeline to render — pass an inline `document` ({tracks, clips, markers}) or a valid `timeline_id`."
1424
+ };
1425
+ }
1426
+ const tracks = Array.isArray(document["tracks"]) ? document["tracks"] : [];
1427
+ const clips = Array.isArray(document["clips"]) ? document["clips"] : [];
1428
+ if (clips.length === 0) {
1429
+ return {
1430
+ error: `${name} has no clips to render.`,
1431
+ timeline_id: isString(timelineId) ? timelineId : undefined
1432
+ };
1433
+ }
1434
+ if (durationMs <= 0) {
1435
+ // An inline document carries no stored duration, so derive it from the
1436
+ // clips: the end of the last one is the end of the cut.
1437
+ durationMs = clips.reduce((end, clip) => {
1438
+ if (!isRecord(clip))
1439
+ return end;
1440
+ const start = Number(clip["startMs"]) || 0;
1441
+ const length = Number(clip["durationMs"]) || 0;
1442
+ return Math.max(end, start + length);
1443
+ }, 0);
1444
+ }
1445
+ const times = requestedTimes(params, durationMs);
1446
+ if (isError(times))
1447
+ return times;
1448
+ const { renderTimelineFrames } = await import("../timeline-preview/frames.js");
1449
+ const { loadMediaRefBytes } = await import("@nodetool-ai/runtime");
1450
+ const { persistOutput } = await import("../tools/asset-persist.js");
1451
+ let result;
1452
+ try {
1453
+ result = await renderTimelineFrames({
1454
+ sequence: {
1455
+ ...document,
1456
+ tracks,
1457
+ clips,
1458
+ fps: meta.fps,
1459
+ width: meta.width,
1460
+ height: meta.height,
1461
+ durationMs
1462
+ },
1463
+ timesMs: times,
1464
+ width: numberParam(params["width"]),
1465
+ motionBlur: {
1466
+ samplesPerFrame: numberParam(params["motion_blur_samples"]),
1467
+ shutterAngle: angleParam(params["shutter_angle"])
1468
+ },
1469
+ loadAsset: (assetId) => loadMediaRefBytes(clipAssetRef(assetId), run.context)
1470
+ });
1471
+ }
1472
+ catch (error) {
1473
+ return {
1474
+ error: `Could not render the timeline: ${error instanceof Error ? error.message : String(error)}`
1475
+ };
1476
+ }
1477
+ // With a sheet the pixels leave as one image, so no frame persists its
1478
+ // own: N handles the caller will never open cost N asset writes.
1479
+ const wantSheet = params["sheet"] === true;
1480
+ let sheet;
1481
+ if (wantSheet) {
1482
+ const { composeContactSheet } = await import("../timeline-preview/sheet.js");
1483
+ const tiled = await composeContactSheet(result.frames.map((frame) => ({
1484
+ label: `${frame.time_ms}ms`,
1485
+ png: frame.png
1486
+ })));
1487
+ const saved = await persistOutput(run.context, tiled.png, {
1488
+ namePrefix: "timeline-sheet",
1489
+ mime: "image/png"
1490
+ });
1491
+ sheet = {
1492
+ complete: result.complete,
1493
+ columns: tiled.columns,
1494
+ rows: tiled.rows,
1495
+ cells: tiled.cells,
1496
+ cell_width: tiled.cell_width,
1497
+ cell_height: tiled.cell_height,
1498
+ width: tiled.width,
1499
+ height: tiled.height,
1500
+ image: imageHandle(saved)
1501
+ };
1502
+ }
1503
+ const frames = [];
1504
+ for (const frame of result.frames) {
1505
+ const entry = {
1506
+ complete: frame.complete,
1507
+ time_ms: frame.time_ms,
1508
+ width: frame.width,
1509
+ height: frame.height,
1510
+ layers: frame.layers,
1511
+ failures: frame.failures,
1512
+ dropped: frame.dropped,
1513
+ degraded: frame.degraded,
1514
+ degradations: frame.degraded
1515
+ };
1516
+ if (!wantSheet) {
1517
+ const saved = await persistOutput(run.context, frame.png, {
1518
+ namePrefix: "timeline-frame",
1519
+ mime: "image/png"
1520
+ });
1521
+ entry.image = imageHandle(saved);
1522
+ }
1523
+ frames.push(entry);
1524
+ }
1525
+ return {
1526
+ complete: result.complete,
1527
+ visual_output_verified: false,
1528
+ timeline_id: isString(timelineId) ? timelineId : undefined,
1529
+ name,
1530
+ fps: meta.fps,
1531
+ sequence_width: meta.width,
1532
+ sequence_height: meta.height,
1533
+ duration_ms: durationMs,
1534
+ frames,
1535
+ sheet,
1536
+ effects_not_applied: result.effectsNotApplied,
1537
+ fonts_unavailable: result.fontsUnavailable,
1538
+ hint: (!result.complete
1539
+ ? "Incomplete preview: requested content was skipped or approximated. Inspect failures, dropped, degradations, skipped layers, effects_not_applied and fonts_unavailable. This image cannot verify the complete composition. "
1540
+ : "") + (wantSheet
1541
+ ? "Call view_image with the sheet's asset_id to see every frame at " +
1542
+ "once; the cells run left to right, labelled with their timecode. " +
1543
+ "Each frame's layers are listed top of the stack first."
1544
+ : "Call view_image with a frame's asset_id to see it. The layers are " +
1545
+ "listed top of the stack first — the first one covers the rest.")
1546
+ };
1547
+ }
1548
+ };
1549
+ /**
1550
+ * Resolve `a` or `b` — a timeline id, `{timeline_id}`, `{timeline_id,
1551
+ * version}`, `{document}`, or a bare document — to a renderable sequence.
1552
+ *
1553
+ * A version is read the way `get_timeline_version` reads one: the snapshot's
1554
+ * own document and its own frame geometry, since a sequence resized after the
1555
+ * snapshot would otherwise render the old cut at the new size and report every
1556
+ * frame as changed.
1557
+ */
1558
+ async function resolveCompareSide(run, raw, which) {
1559
+ const side = isString(raw) ? { timeline_id: raw } : raw;
1560
+ if (!isRecord(side)) {
1561
+ return {
1562
+ error: `${which} must be a timeline id, {timeline_id}, {timeline_id, version} or {document}.`
1563
+ };
1564
+ }
1565
+ if (side["timeline_id"] !== undefined && side["timeline_id"] !== null) {
1566
+ const seq = await loadTimeline(run, side["timeline_id"]);
1567
+ if (isError(seq))
1568
+ return seq;
1569
+ if (side["version"] === undefined || side["version"] === null) {
1570
+ const resolved = seq.toTimelineSequence();
1571
+ return {
1572
+ document: resolved,
1573
+ fps: resolved.fps,
1574
+ width: resolved.width,
1575
+ height: resolved.height,
1576
+ durationMs: resolved.durationMs,
1577
+ source: { timeline_id: seq.id, name: resolved.name }
1578
+ };
1579
+ }
1580
+ const number = versionNumber(side["version"]);
1581
+ if (isError(number))
1582
+ return number;
1583
+ const { TimelineSequenceVersion } = await import("@nodetool-ai/models");
1584
+ const version = await TimelineSequenceVersion.findByVersion(seq.id, number);
1585
+ if (!version) {
1586
+ return {
1587
+ error: `Timeline ${seq.id} has no version ${number}. Call list_timeline_versions to see the available ones.`
1588
+ };
1589
+ }
1590
+ const document = parseVersionDocument(version.document);
1591
+ if (isError(document))
1592
+ return document;
1593
+ if (!isRecord(document)) {
1594
+ return { error: `Version ${number} of timeline ${seq.id} is not a document.` };
1595
+ }
1596
+ return {
1597
+ document,
1598
+ fps: version.fps,
1599
+ width: version.width,
1600
+ height: version.height,
1601
+ durationMs: version.duration_ms || documentDurationMs(document),
1602
+ source: { timeline_id: seq.id, version: number, name: version.name }
1603
+ };
1604
+ }
1605
+ const inline = isRecord(side["document"]) ? side["document"] : side;
1606
+ if (!Array.isArray(inline["tracks"]) && !Array.isArray(inline["clips"])) {
1607
+ return {
1608
+ error: `${which} carries no timeline — pass a timeline id, {timeline_id, version} or {document: {tracks, clips}}.`
1609
+ };
1610
+ }
1611
+ return {
1612
+ document: inline,
1613
+ fps: numberParam(inline["fps"]) ?? 30,
1614
+ width: numberParam(inline["width"]) ?? 1920,
1615
+ height: numberParam(inline["height"]) ?? 1080,
1616
+ durationMs: documentDurationMs(inline),
1617
+ source: { document: true }
1618
+ };
1619
+ }
1620
+ /**
1621
+ * Difference two timelines frame by frame.
1622
+ *
1623
+ * The pixels are the measurement an agent has no other way to take: a
1624
+ * structural diff of two documents says a clip moved, not whether the picture
1625
+ * moved with it, and a clip nudged 2ms reads there exactly like one moved 2s.
1626
+ * Every frame gets a score, and the sheet is what makes a score readable —
1627
+ * 0.04 at 1500ms means nothing until the pair is next to each other.
1628
+ */
1629
+ const compareTimelineFrames = {
1630
+ spec: compareTimelineFramesSpec,
1631
+ impl: async (run, params) => {
1632
+ const a = await resolveCompareSide(run, params["a"], "a");
1633
+ if (isError(a))
1634
+ return a;
1635
+ const b = await resolveCompareSide(run, params["b"], "b");
1636
+ if (isError(b))
1637
+ return b;
1638
+ const times = requestedTimes(params, Math.max(a.durationMs, b.durationMs), MAX_PREVIEW_RANGE_COUNT);
1639
+ if (isError(times))
1640
+ return times;
1641
+ const { renderTimelineFrames } = await import("../timeline-preview/frames.js");
1642
+ const { loadMediaRefBytes } = await import("@nodetool-ai/runtime");
1643
+ const { frameDifference, sideBySide } = await import("../timeline-preview/compare.js");
1644
+ const { composeContactSheet } = await import("../timeline-preview/sheet.js");
1645
+ const { persistOutput } = await import("../tools/asset-persist.js");
1646
+ const width = numberParam(params["width"]) ?? DEFAULT_COMPARE_WIDTH;
1647
+ const renderSide = (side) => renderTimelineFrames({
1648
+ sequence: {
1649
+ ...side.document,
1650
+ tracks: Array.isArray(side.document["tracks"])
1651
+ ? side.document["tracks"]
1652
+ : [],
1653
+ clips: Array.isArray(side.document["clips"])
1654
+ ? side.document["clips"]
1655
+ : [],
1656
+ fps: side.fps,
1657
+ width: side.width,
1658
+ height: side.height,
1659
+ durationMs: side.durationMs
1660
+ },
1661
+ timesMs: times,
1662
+ width,
1663
+ loadAsset: (assetId) => loadMediaRefBytes(clipAssetRef(assetId), run.context)
1664
+ });
1665
+ let rendered;
1666
+ try {
1667
+ rendered = await Promise.all([renderSide(a), renderSide(b)]);
1668
+ }
1669
+ catch (error) {
1670
+ return {
1671
+ error: `Could not render the timelines: ${error instanceof Error ? error.message : String(error)}`
1672
+ };
1673
+ }
1674
+ const [left, right] = rendered;
1675
+ const frames = [];
1676
+ const cells = [];
1677
+ for (let i = 0; i < times.length; i++) {
1678
+ const complete = left.frames[i].complete && right.frames[i].complete;
1679
+ const difference = complete ? Number((await frameDifference(left.frames[i].png, right.frames[i].png)).toFixed(4)) : null;
1680
+ frames.push({
1681
+ time_ms: times[i], complete, difference,
1682
+ a: { failures: left.frames[i].failures, dropped: left.frames[i].dropped, degradations: left.frames[i].degraded, skipped: left.frames[i].layers.filter((layer) => layer.skipped) },
1683
+ b: { failures: right.frames[i].failures, dropped: right.frames[i].dropped, degradations: right.frames[i].degraded, skipped: right.frames[i].layers.filter((layer) => layer.skipped) }
1684
+ });
1685
+ cells.push({
1686
+ label: `${times[i]}ms ${difference === null ? "incomplete" : difference.toFixed(3)}`,
1687
+ png: await sideBySide(left.frames[i].png, right.frames[i].png)
1688
+ });
1689
+ }
1690
+ const tiled = await composeContactSheet(cells);
1691
+ const saved = await persistOutput(run.context, tiled.png, {
1692
+ namePrefix: "timeline-compare",
1693
+ mime: "image/png"
1694
+ });
1695
+ const complete = left.complete && right.complete;
1696
+ const differences = frames.flatMap((frame) => frame.difference === null ? [] : [frame.difference]);
1697
+ const changed = frames.filter((frame) => frame.difference !== null && frame.difference > 0);
1698
+ return {
1699
+ complete,
1700
+ visual_output_verified: false,
1701
+ a: a.source,
1702
+ b: b.source,
1703
+ frames,
1704
+ changed_times_ms: complete ? changed.map((frame) => frame.time_ms) : null,
1705
+ max_difference: complete ? Math.max(...differences) : null,
1706
+ mean_difference: complete ? Number((differences.reduce((sum, d) => sum + d, 0) / differences.length).toFixed(4)) : null,
1707
+ sheet: {
1708
+ complete,
1709
+ columns: tiled.columns,
1710
+ rows: tiled.rows,
1711
+ cells: tiled.cells,
1712
+ width: tiled.width,
1713
+ height: tiled.height,
1714
+ image: imageHandle(saved)
1715
+ },
1716
+ effects_not_applied: [
1717
+ ...new Set([...left.effectsNotApplied, ...right.effectsNotApplied])
1718
+ ].sort(),
1719
+ fonts_unavailable: [
1720
+ ...new Set([...left.fontsUnavailable, ...right.fontsUnavailable])
1721
+ ].sort(),
1722
+ hint: (!complete ? "Incomplete previews cannot establish visual equivalence. Difference scores are null for incomplete pairs and aggregate metrics are unavailable. " : "") +
1723
+ "difference is the mean absolute RGB difference, 0 (identical) to 1. " +
1724
+ "Each cell of the sheet is a pair: `a` on the left, `b` on the right, " +
1725
+ "labelled with its timecode and score."
1726
+ };
1727
+ }
1728
+ };
1729
+ /** The node id the one render node carries inside the graph this builds. */
1730
+ const RENDER_NODE_ID = "render";
1731
+ /** The Output node that turns the rendered bytes into an asset. */
1732
+ const RENDER_OUTPUT_NODE_ID = "output";
1733
+ /** The handle the render's asset comes back under. */
1734
+ const RENDER_OUTPUT_NAME = "video";
1735
+ /** The Output node a png_sequence's zip goes through. */
1736
+ const RENDER_FRAMES_OUTPUT_NODE_ID = "frames_output";
1737
+ /** The handle a png_sequence's zip comes back under. */
1738
+ const RENDER_FRAMES_OUTPUT_NAME = "frames";
1739
+ /**
1740
+ * Bits per second from a `bitrate` argument, or undefined when there is none
1741
+ * to read. The node takes a number; a caller writes what ffmpeg takes, so
1742
+ * "8M" and "800k" parse here rather than being dropped on the way to the graph.
1743
+ */
1744
+ export function parseBitrate(value) {
1745
+ if (typeof value === "number") {
1746
+ return Number.isFinite(value) && value > 0 ? Math.round(value) : undefined;
1747
+ }
1748
+ if (typeof value !== "string")
1749
+ return undefined;
1750
+ const match = /^\s*([0-9]*\.?[0-9]+)\s*([kKmM]?)\s*$/.exec(value);
1751
+ if (!match)
1752
+ return undefined;
1753
+ const scale = match[2]?.toLowerCase() === "m"
1754
+ ? 1_000_000
1755
+ : match[2]?.toLowerCase() === "k"
1756
+ ? 1_000
1757
+ : 1;
1758
+ const bits = Number(match[1]) * scale;
1759
+ return bits > 0 ? Math.round(bits) : undefined;
1760
+ }
1761
+ /** How often a `wait: true` render re-reads the job row. */
1762
+ const RENDER_POLL_INTERVAL_MS = 1000;
1763
+ /**
1764
+ * The call arguments that are render-node properties, passed through under the
1765
+ * same name. Everything else in the call — `wait`, `timeout_ms` — is how long
1766
+ * this capability watches the job, and never reaches the graph.
1767
+ */
1768
+ const RENDER_NODE_PROPS = [
1769
+ "format",
1770
+ "alpha",
1771
+ "video_codec",
1772
+ "bitrate",
1773
+ "motion_blur_samples",
1774
+ "shutter_angle",
1775
+ "preview_scale",
1776
+ "include_audio"
1777
+ ];
1778
+ /**
1779
+ * The graph a render runs as: the render node, and an Output node that turns
1780
+ * its bytes into an asset.
1781
+ *
1782
+ * The Output node is what makes the result addressable. `RenderTimeline` emits
1783
+ * a `VideoRef` carrying base64 and no asset id, so a graph ending at it leaves
1784
+ * the render inside the job row and nowhere else; `nodetool.output.Output`
1785
+ * stores the bytes and stamps the id `render_timeline` hands back.
1786
+ */
1787
+ export function buildRenderTimelineGraph(timelineId, params) {
1788
+ const properties = {
1789
+ timeline: { type: "timeline", id: timelineId, data: null }
1790
+ };
1791
+ for (const prop of RENDER_NODE_PROPS) {
1792
+ const value = params[prop];
1793
+ if (value === undefined || value === null)
1794
+ continue;
1795
+ if (prop === "bitrate") {
1796
+ const bitrate = parseBitrate(value);
1797
+ if (bitrate !== undefined)
1798
+ properties[prop] = bitrate;
1799
+ continue;
1800
+ }
1801
+ properties[prop] = value;
1802
+ }
1803
+ const nodes = [
1804
+ {
1805
+ id: RENDER_NODE_ID,
1806
+ type: "nodetool.timeline.RenderTimeline",
1807
+ data: properties
1808
+ },
1809
+ {
1810
+ id: RENDER_OUTPUT_NODE_ID,
1811
+ type: "nodetool.output.Output",
1812
+ data: { name: RENDER_OUTPUT_NAME }
1813
+ }
1814
+ ];
1815
+ const edges = [
1816
+ {
1817
+ id: "render-to-output",
1818
+ source: RENDER_NODE_ID,
1819
+ sourceHandle: "output",
1820
+ target: RENDER_OUTPUT_NODE_ID,
1821
+ targetHandle: "value"
1822
+ }
1823
+ ];
1824
+ // A png_sequence leaves the zip on the node's `frames` handle and an empty
1825
+ // ref on `output`, so a graph wired to `output` alone comes back with
1826
+ // nothing to open.
1827
+ if (params["format"] === "png_sequence") {
1828
+ nodes.push({
1829
+ id: RENDER_FRAMES_OUTPUT_NODE_ID,
1830
+ type: "nodetool.output.Output",
1831
+ data: { name: RENDER_FRAMES_OUTPUT_NAME }
1832
+ });
1833
+ edges.push({
1834
+ id: "render-to-frames-output",
1835
+ source: RENDER_NODE_ID,
1836
+ sourceHandle: "frames",
1837
+ target: RENDER_FRAMES_OUTPUT_NODE_ID,
1838
+ targetHandle: "value"
1839
+ });
1840
+ }
1841
+ return { nodes, edges };
1842
+ }
1843
+ /**
1844
+ * The ref a finished render left on the job row, wherever it sits — a video,
1845
+ * or the zipped document a png_sequence renders to. A png_sequence leaves an
1846
+ * empty ref on the video handle beside the zip, so a ref carrying an asset id
1847
+ * wins over one that carries none.
1848
+ */
1849
+ export function findRenderedVideo(outputs) {
1850
+ const found = [];
1851
+ const walk = (value) => {
1852
+ if (Array.isArray(value)) {
1853
+ for (const item of value)
1854
+ walk(item);
1855
+ return;
1856
+ }
1857
+ if (!isRecord(value))
1858
+ return;
1859
+ if (value["type"] === "video" || value["type"] === "document") {
1860
+ found.push(value);
1861
+ return;
1862
+ }
1863
+ for (const nested of Object.values(value))
1864
+ walk(nested);
1865
+ };
1866
+ walk(outputs);
1867
+ return (found.find((ref) => (isString(ref["asset_id"]) && ref["asset_id"].length > 0) ||
1868
+ (isString(ref["uri"]) && ref["uri"].length > 0)) ??
1869
+ found[0] ??
1870
+ null);
1871
+ }
1872
+ /** What a settled render reports beyond its job id. */
1873
+ export function renderResult(job) {
1874
+ const metadata = job.metadata_json ?? {};
1875
+ const video = findRenderedVideo(metadata["outputs"]);
1876
+ const refMetadata = video && isRecord(video["metadata"]) ? video["metadata"] : {};
1877
+ const duration = video ? Number(video["duration"]) : Number.NaN;
1878
+ return {
1879
+ status: job.status,
1880
+ asset_id: video && isString(video["asset_id"]) ? video["asset_id"] : null,
1881
+ uri: video && isString(video["uri"]) ? video["uri"] : null,
1882
+ render_mode: isString(refMetadata["render_mode"])
1883
+ ? refMetadata["render_mode"]
1884
+ : null,
1885
+ duration_ms: Number.isFinite(duration) ? Math.round(duration * 1000) : null,
1886
+ job_error: job.error_message ?? job.error ?? null
1887
+ };
1888
+ }
1889
+ /**
1890
+ * How long a `wait: true` render blocks, and what to say when the caller asked
1891
+ * for longer.
1892
+ *
1893
+ * A blocking call inside `execute_code` runs against the CodeAct action budget
1894
+ * (`DEFAULT_CODEACT_ACTION_TIMEOUT_MS`, 600_000 in
1895
+ * `codeact/codeact-executor.ts`). A wait at or near that number loses the race:
1896
+ * the sandbox aborts the whole action first and the caller reads the sandbox's
1897
+ * `Execution cancelled`, which names neither the render nor the job to come
1898
+ * back to. `MAX_RENDER_TIMEOUT_MS` sits well below it so this capability always
1899
+ * reports its own timeout — and says the wait was shortened, rather than
1900
+ * silently waiting for a different number than the one that was asked for.
1901
+ */
1902
+ export function renderWaitBudget(param) {
1903
+ const requestedMs = numberParam(param) ?? DEFAULT_RENDER_TIMEOUT_MS;
1904
+ const timeoutMs = Math.min(MAX_RENDER_TIMEOUT_MS, Math.max(RENDER_POLL_INTERVAL_MS, requestedMs));
1905
+ const clampNote = requestedMs > MAX_RENDER_TIMEOUT_MS
1906
+ ? `timeout_ms ${requestedMs} was clamped to ${MAX_RENDER_TIMEOUT_MS}, ` +
1907
+ "the longest a blocking render can wait before the surrounding " +
1908
+ "action budget kills the call. For a longer render, pass wait: false " +
1909
+ "and poll get_job, or draft it with preview_scale below 1."
1910
+ : null;
1911
+ return { timeoutMs, clampNote };
1912
+ }
1913
+ /**
1914
+ * Render a timeline sequence as a job (D12, docs/plans/motion-graphics.md).
1915
+ *
1916
+ * The run goes through the same execution service `run_workflow` uses, so the
1917
+ * render gets the job row, the logs, the `node_progress` messages and cancel
1918
+ * without a workflow being saved for it. Always detached: `wait` polls the job
1919
+ * row rather than blocking the service call, so a render that outlives the
1920
+ * caller's patience still hands back a `job_id` to come back to.
1921
+ */
1922
+ const renderTimeline = {
1923
+ spec: renderTimelineSpec,
1924
+ impl: async (run, params) => {
1925
+ const seq = await loadTimeline(run, params["timeline_id"]);
1926
+ if (isError(seq))
1927
+ return seq;
1928
+ const { resolveRunEnvironment, userIdOf, noRegistryError } = await import("../tools/mcp-tool-support.js");
1929
+ const environment = await resolveRunEnvironment(run.workflowEnvironment, run.nodeRegistry);
1930
+ if (!environment)
1931
+ return noRegistryError("render a timeline");
1932
+ const { runWorkflow } = await import("@nodetool-ai/execution/service");
1933
+ const userId = userIdOf(run.context);
1934
+ const outcome = await runWorkflow({
1935
+ workflowId: "",
1936
+ userId,
1937
+ environment,
1938
+ graph: buildRenderTimelineGraph(seq.id, params),
1939
+ jobName: `Render ${seq.name}`,
1940
+ background: true,
1941
+ projectId: run.projectId ?? null
1942
+ });
1943
+ if (outcome.kind !== "payload") {
1944
+ return { error: outcome.detail, status: outcome.status };
1945
+ }
1946
+ const jobId = outcome.payload["job_id"];
1947
+ if (!isString(jobId)) {
1948
+ return { error: "The render started but reported no job id." };
1949
+ }
1950
+ const receipt = { job_id: jobId, timeline_id: seq.id };
1951
+ const stillRunning = {
1952
+ ...receipt,
1953
+ status: "running",
1954
+ poll: `Poll get_job with job_id "${jobId}" until it settles. get_job_logs ` +
1955
+ "reports what the render is doing and cancel_job stops it."
1956
+ };
1957
+ if (params["wait"] !== true)
1958
+ return stillRunning;
1959
+ const { timeoutMs, clampNote } = renderWaitBudget(params["timeout_ms"]);
1960
+ const { Job } = await import("@nodetool-ai/models");
1961
+ const deadline = Date.now() + timeoutMs;
1962
+ for (;;) {
1963
+ const job = await Job.find(userId, jobId);
1964
+ if (job && job.status !== "running" && job.status !== "queued") {
1965
+ return { ...receipt, ...renderResult(job) };
1966
+ }
1967
+ if (Date.now() >= deadline) {
1968
+ return {
1969
+ ...stillRunning,
1970
+ timed_out: true,
1971
+ timeout_ms: timeoutMs,
1972
+ timeout_clamped: clampNote,
1973
+ note: `The render did not finish within ${timeoutMs}ms. It is still ` +
1974
+ "running — read it back with get_job." +
1975
+ (clampNote ? ` ${clampNote}` : "")
1976
+ };
1977
+ }
1978
+ await new Promise((resolve) => setTimeout(resolve, RENDER_POLL_INTERVAL_MS));
1979
+ }
1980
+ }
1981
+ };
1982
+ /** Every timeline capability, in the order the tool files declared them. */
1983
+ /**
1984
+ * Delete a timeline sequence the caller owns.
1985
+ *
1986
+ * The ownership check and the version cascade are `TimelineSequence.deleteOwned`, the
1987
+ * same function the tRPC route calls — a delete is not a place for two copies
1988
+ * of one rule, and version rows outliving their document would be unreachable
1989
+ * garbage. Missing and not-yours are one answer.
1990
+ */
1991
+ // ---------------------------------------------------------------------------
1992
+ // bake_audio_animation
1993
+ // ---------------------------------------------------------------------------
1994
+ /** A number param, or the default when it is absent or not finite. */
1995
+ function numberOr(value, fallback) {
1996
+ return isFiniteNumber(value) ? value : fallback;
1997
+ }
1998
+ /** The `[lo, hi]` a curve's values run between. */
1999
+ function outputRange(value) {
2000
+ if (!Array.isArray(value) ||
2001
+ value.length !== 2 ||
2002
+ !isFiniteNumber(value[0]) ||
2003
+ !isFiniteNumber(value[1])) {
2004
+ return {
2005
+ error: "output_range must be two numbers, [quiet, loud] — e.g. [1, 1.12] " +
2006
+ "for scale, [0.6, 1] for opacity."
2007
+ };
2008
+ }
2009
+ return [value[0], value[1]];
2010
+ }
2011
+ /** The clip a name, id or "selected" addresses, or a message naming the rest. */
2012
+ function findClip(clips, target, field) {
2013
+ if (!isString(target) || target.trim() === "") {
2014
+ return { error: `${field} is required (a clip id or name).` };
2015
+ }
2016
+ const lower = target.trim().toLowerCase();
2017
+ const clip = clips.find((c) => c.id === target.trim()) ??
2018
+ clips.find((c) => c.name.toLowerCase() === lower);
2019
+ if (clip)
2020
+ return clip;
2021
+ const known = clips
2022
+ .slice(0, 12)
2023
+ .map((c) => `${c.id} ("${c.name}")`)
2024
+ .join(", ");
2025
+ return {
2026
+ error: `No clip matching "${target}" for ${field}. Clips: ${known || "none"}.`
2027
+ };
2028
+ }
2029
+ const bakeAudioAnimation = {
2030
+ spec: bakeAudioAnimationSpec,
2031
+ impl: async (run, params) => {
2032
+ const timelineId = params["timeline_id"];
2033
+ if (!isString(timelineId) || !timelineId) {
2034
+ return {
2035
+ error: "timeline_id is required (use list_timelines to find one)."
2036
+ };
2037
+ }
2038
+ const property = params["property"];
2039
+ if (!isString(property)) {
2040
+ return { error: "property is required (scale, opacity, offsetX, offsetY)." };
2041
+ }
2042
+ const range = outputRange(params["output_range"]);
2043
+ if (isError(range))
2044
+ return range;
2045
+ const mode = params["mode"] === "beats" ? "beats" : "envelope";
2046
+ const attackMs = Math.max(0, numberOr(params["attack_ms"], DEFAULT_BAKE_ATTACK_MS));
2047
+ const releaseMs = Math.max(0, numberOr(params["release_ms"], DEFAULT_BAKE_RELEASE_MS));
2048
+ const offsetMs = numberOr(params["offset_ms"], 0);
2049
+ const tolerance = Math.max(0, numberOr(params["tolerance"], DEFAULT_BAKE_TOLERANCE));
2050
+ const maxPoints = Math.min(MAX_BAKE_POINTS, Math.max(2, Math.floor(numberOr(params["max_points"], DEFAULT_BAKE_MAX_POINTS))));
2051
+ const maxSeconds = Math.max(1, numberOr(params["max_seconds"], DEFAULT_BAKE_MAX_SECONDS));
2052
+ const frameMs = Math.max(1, numberOr(params["frame_ms"], 20));
2053
+ const replace = params["replace"] !== false;
2054
+ const { TimelineSequence } = await import("@nodetool-ai/models");
2055
+ const sequence = await TimelineSequence.findById(timelineId);
2056
+ if (!sequence || sequence.user_id !== run.context.userId) {
2057
+ return { error: `Timeline ${timelineId} was not found.` };
2058
+ }
2059
+ const document = sequence.toDocument();
2060
+ const audioClip = findClip(document.clips, params["audio_clip_id"], "audio_clip_id");
2061
+ if (isError(audioClip))
2062
+ return audioClip;
2063
+ const targetClip = findClip(document.clips, params["target_clip_id"], "target_clip_id");
2064
+ if (isError(targetClip))
2065
+ return targetClip;
2066
+ // Both hops are affine only while neither clip's source position is a
2067
+ // curve. A remap makes "which source ms plays here" normalized over the
2068
+ // clip's own window, so there is no inverse to map an onset through.
2069
+ for (const [clip, field] of [
2070
+ [audioClip, "audio_clip_id"],
2071
+ [targetClip, "target_clip_id"]
2072
+ ]) {
2073
+ if ((clip.timeRemap?.keyframes.length ?? 0) > 0) {
2074
+ return {
2075
+ error: `Clip "${clip.name}" (${field}) carries a time remap, so its ` +
2076
+ "source position is a curve over its own window and an audio " +
2077
+ "time cannot be placed in it. Clear `timeRemap` with " +
2078
+ "set_time_remap, or bake the remap into the media first."
2079
+ };
2080
+ }
2081
+ }
2082
+ const assetId = audioClip.currentAssetId;
2083
+ if (!isString(assetId) || !assetId) {
2084
+ return {
2085
+ error: `Clip "${audioClip.name}" has no asset to measure — it has not ` +
2086
+ "been generated or imported yet."
2087
+ };
2088
+ }
2089
+ const [analyzeFromMs, analyzeToMs] = clipSourceWindowMs(audioClip);
2090
+ const { loadMediaRefBytes } = await import("@nodetool-ai/runtime");
2091
+ let bytes;
2092
+ try {
2093
+ bytes = await loadMediaRefBytes({ uri: `asset://${assetId}`, asset_id: assetId }, run.context);
2094
+ }
2095
+ catch (error) {
2096
+ return {
2097
+ error: `Could not read the audio of "${audioClip.name}": ${error instanceof Error ? error.message : String(error)}`
2098
+ };
2099
+ }
2100
+ if (!bytes || bytes.byteLength === 0) {
2101
+ return {
2102
+ error: `The asset behind "${audioClip.name}" resolved to no bytes.`
2103
+ };
2104
+ }
2105
+ const { analyzeAudioFrames } = await import("./analysis.js");
2106
+ let envelope;
2107
+ try {
2108
+ envelope = await analyzeAudioFrames(bytes, {
2109
+ fromMs: analyzeFromMs,
2110
+ toMs: analyzeToMs,
2111
+ frameMs,
2112
+ maxSeconds,
2113
+ detectTempo: false
2114
+ });
2115
+ }
2116
+ catch (error) {
2117
+ return {
2118
+ error: `Could not analyze "${audioClip.name}": ${error instanceof Error ? error.message : String(error)}`
2119
+ };
2120
+ }
2121
+ const analyzed = envelope.truncated
2122
+ ? envelope.truncated.analyzed
2123
+ : [analyzeFromMs, analyzeToMs];
2124
+ const { beatCurve, envelopeCurve, mapAudioCurveToTarget } = await import("./timeline-audio-bake.js");
2125
+ const measured = mode === "beats"
2126
+ ? beatCurve(envelope.onsetsMs, {
2127
+ attackMs,
2128
+ releaseMs,
2129
+ outputRange: range,
2130
+ tolerance,
2131
+ maxPoints,
2132
+ windowMs: [analyzed[0], analyzed[1]]
2133
+ })
2134
+ : envelopeCurve(envelope.frames, {
2135
+ attackMs,
2136
+ releaseMs,
2137
+ outputRange: range,
2138
+ sensitivity: Math.max(0.01, numberOr(params["sensitivity"], 1)),
2139
+ tolerance,
2140
+ maxPoints
2141
+ });
2142
+ const keyframes = mapAudioCurveToTarget(measured, {
2143
+ audioClip,
2144
+ targetClip,
2145
+ offsetMs
2146
+ });
2147
+ if (keyframes.length === 0) {
2148
+ return {
2149
+ error: `Nothing to write: the stretch of "${audioClip.name}" that was ` +
2150
+ `analyzed does not overlap "${targetClip.name}" on the timeline` +
2151
+ (offsetMs === 0 ? "." : ` after the ${offsetMs}ms offset.`)
2152
+ };
2153
+ }
2154
+ const { records, state } = await applyOps(run, sequence, document, [
2155
+ {
2156
+ op: `${TOOL_PREFIX}set_baked_animation`,
2157
+ input: {
2158
+ target: targetClip.id,
2159
+ animation: {
2160
+ property,
2161
+ keyframes,
2162
+ timeBase: "source",
2163
+ replace,
2164
+ bakedFrom: {
2165
+ kind: AUDIO_BAKED_ANIMATION_KIND,
2166
+ clipId: audioClip.id,
2167
+ assetId,
2168
+ settings: {
2169
+ mode,
2170
+ attackMs,
2171
+ releaseMs,
2172
+ offsetMs,
2173
+ tolerance,
2174
+ maxPoints,
2175
+ frameMs,
2176
+ sensitivity: Math.max(0.01, numberOr(params["sensitivity"], 1)),
2177
+ outputLow: range[0],
2178
+ outputHigh: range[1]
2179
+ }
2180
+ }
2181
+ }
2182
+ }
2183
+ }
2184
+ ]);
2185
+ const record = records[0];
2186
+ if (!record || !record.ok) {
2187
+ return { error: record?.error ?? "The bake wrote nothing." };
2188
+ }
2189
+ const next = {
2190
+ ...document,
2191
+ tracks: state.documentTracks,
2192
+ clips: state.documentClips,
2193
+ markers: state.markers
2194
+ };
2195
+ const saved = await TimelineSequence.updateDocumentIfUnchanged(sequence.id, sequence.updated_at, next, {
2196
+ ops: [
2197
+ {
2198
+ tool: `${TOOL_PREFIX}set_baked_animation`,
2199
+ input: { id: targetClip.id, target: targetClip.id }
2200
+ }
2201
+ ]
2202
+ });
2203
+ if (!saved) {
2204
+ return {
2205
+ error: `Timeline ${timelineId} is being modified concurrently; nothing was saved. Retry the call.`
2206
+ };
2207
+ }
2208
+ const result = isRecord(record.result) ? record.result : {};
2209
+ return {
2210
+ timeline_id: timelineId,
2211
+ updated_at: saved.updated_at,
2212
+ clip_id: targetClip.id,
2213
+ property,
2214
+ mode,
2215
+ animationId: result["animationId"],
2216
+ keyframeCount: keyframes.length,
2217
+ analyzed: { fromMs: analyzed[0], toMs: analyzed[1] },
2218
+ truncated: envelope.truncated !== null,
2219
+ replaced: result["replaced"] === true
2220
+ };
2221
+ }
2222
+ };
2223
+ // ---------------------------------------------------------------------------
2224
+ // isolate_subject
2225
+ // ---------------------------------------------------------------------------
2226
+ /** One of `allowed`, or the default when the caller named none of them. */
2227
+ function enumOr(value, allowed, fallback) {
2228
+ if (value === undefined || value === null)
2229
+ return fallback;
2230
+ if (isString(value) && allowed.includes(value))
2231
+ return value;
2232
+ return {
2233
+ error: `"${String(value)}" is not one of: ${allowed.join(", ")}.`
2234
+ };
2235
+ }
2236
+ /**
2237
+ * Cut the subject out of a clip's own source and carry the mask on that clip.
2238
+ *
2239
+ * The document work is `isolateSubjectOnClip`; everything here is the wiring
2240
+ * it refuses to know about — the sequence row, the CAS save, the node registry
2241
+ * the provider call needs, and the background receipt. The save closure
2242
+ * carries `updated_at` forward, so the in-flight write and the settled write
2243
+ * are two CAS updates rather than one lost one.
2244
+ */
2245
+ const isolateSubject = {
2246
+ spec: isolateSubjectSpec,
2247
+ impl: async (run, params) => {
2248
+ const timelineId = params["timeline_id"];
2249
+ if (!isString(timelineId) || !timelineId) {
2250
+ return {
2251
+ error: "timeline_id is required (use list_timelines to find one)."
2252
+ };
2253
+ }
2254
+ const registry = run.nodeRegistry;
2255
+ if (!registry) {
2256
+ const { noRegistryError } = await import("../tools/mcp-tool-support.js");
2257
+ return noRegistryError("isolate a subject");
2258
+ }
2259
+ const model = enumOr(params["model"], ISOLATE_SUBJECT_MODELS, DEFAULT_ISOLATE_SUBJECT_MODEL);
2260
+ if (isError(model))
2261
+ return model;
2262
+ const resolution = enumOr(params["operating_resolution"], ISOLATE_SUBJECT_RESOLUTIONS, DEFAULT_ISOLATE_SUBJECT_RESOLUTION);
2263
+ if (isError(resolution))
2264
+ return resolution;
2265
+ const settings = {
2266
+ model,
2267
+ operating_resolution: resolution,
2268
+ refine_foreground: params["refine_foreground"] !== false
2269
+ };
2270
+ const { TimelineSequence } = await import("@nodetool-ai/models");
2271
+ const sequence = await TimelineSequence.findById(timelineId);
2272
+ if (!sequence || sequence.user_id !== run.context.userId) {
2273
+ return { error: `Timeline ${timelineId} was not found.` };
2274
+ }
2275
+ const document = sequence.toDocument();
2276
+ const clip = findClip(document.clips, params["clip_id"], "clip_id");
2277
+ if (isError(clip))
2278
+ return clip;
2279
+ // The asset row is the only statement of how long the source runs; a row
2280
+ // without one falls back to the clip's own window inside the state
2281
+ // machine, which is still an interval the generation covered.
2282
+ let sourceDurationMs;
2283
+ const userId = run.context.userId;
2284
+ if (isString(clip.currentAssetId) && clip.currentAssetId && userId) {
2285
+ const { Asset } = await import("@nodetool-ai/models");
2286
+ const asset = await Asset.find(userId, clip.currentAssetId);
2287
+ if (asset && isFiniteNumber(asset.duration) && asset.duration > 0) {
2288
+ sourceDurationMs = Math.round(asset.duration * 1000);
2289
+ }
2290
+ }
2291
+ const { contextMaskStore, falIsolateSubjectRunner, isolateSubjectOnClip } = await import("./timeline-isolate-subject.js");
2292
+ const { randomUUID } = await import("node:crypto");
2293
+ const generationId = randomUUID();
2294
+ let expectedUpdatedAt = sequence.updated_at;
2295
+ const persist = async (next) => {
2296
+ const clips = document.clips.map((c) => (c.id === next.id ? next : c));
2297
+ const saved = await TimelineSequence.updateDocumentIfUnchanged(timelineId, expectedUpdatedAt, { ...document, clips }, {
2298
+ ops: [
2299
+ {
2300
+ tool: `${TOOL_PREFIX}set_generated_matte`,
2301
+ input: { id: next.id, target: next.id }
2302
+ }
2303
+ ]
2304
+ });
2305
+ if (!saved)
2306
+ return false;
2307
+ document.clips = clips;
2308
+ expectedUpdatedAt = saved.updated_at;
2309
+ return true;
2310
+ };
2311
+ const deps = {
2312
+ runner: falIsolateSubjectRunner(run.context, registry, generationId),
2313
+ storeMask: contextMaskStore(run.context),
2314
+ persist
2315
+ };
2316
+ const input = {
2317
+ clip,
2318
+ settings,
2319
+ regenerate: params["regenerate"] === true
2320
+ };
2321
+ if (sourceDurationMs !== undefined) {
2322
+ input.sourceDurationMs = sourceDurationMs;
2323
+ }
2324
+ if (params["background"] === true) {
2325
+ const { startBackgroundGeneration, backgroundGenerationLimitError } = await import("./background-generation.js");
2326
+ const started = startBackgroundGeneration(run.context, () => isolateSubjectOnClip(deps, input));
2327
+ if (!started)
2328
+ return backgroundGenerationLimitError();
2329
+ return {
2330
+ timeline_id: timelineId,
2331
+ clip_id: clip.id,
2332
+ generation_id: generationId,
2333
+ // The clip's own matte status, which is what the caller reads back —
2334
+ // the generation row carries `running` for `await_generation`.
2335
+ status: "generating",
2336
+ background: true,
2337
+ next: "Call await_generation with this generation_id, or read the clip " +
2338
+ "back with get_timeline once it settles."
2339
+ };
2340
+ }
2341
+ const settled = await isolateSubjectOnClip(deps, input);
2342
+ // A refusal carries only `error`; an outcome always carries `status`,
2343
+ // including the failed one that kept the previous matte.
2344
+ if (!("status" in settled))
2345
+ return settled;
2346
+ const result = {
2347
+ timeline_id: timelineId,
2348
+ clip_id: clip.id,
2349
+ status: settled.status,
2350
+ source_range: settled.sourceRange,
2351
+ reused: settled.reused
2352
+ };
2353
+ if (settled.assetId !== undefined)
2354
+ result["asset_id"] = settled.assetId;
2355
+ if (settled.generationId !== undefined) {
2356
+ result["generation_id"] = settled.generationId;
2357
+ }
2358
+ if (settled.costUsd !== undefined)
2359
+ result["cost_usd"] = settled.costUsd;
2360
+ if (settled.error !== undefined)
2361
+ result["error"] = settled.error;
2362
+ return result;
2363
+ }
2364
+ };
2365
+ // ---------------------------------------------------------------------------
2366
+ // track_object
2367
+ // ---------------------------------------------------------------------------
2368
+ /**
2369
+ * Follow a subject through a clip's source. The document work is
2370
+ * `trackObjectOnDocument`; everything here is the wiring it refuses to know
2371
+ * about: the sequence row, provider selection and the CAS save.
2372
+ */
2373
+ const trackObject = {
2374
+ spec: trackObjectSpec,
2375
+ impl: async (run, params) => {
2376
+ const timelineId = params["timeline_id"];
2377
+ if (!isString(timelineId) || !timelineId) {
2378
+ return {
2379
+ error: "timeline_id is required (use list_timelines to find one)."
2380
+ };
2381
+ }
2382
+ const region = params["initial_region"];
2383
+ if (!isRecord(region)) {
2384
+ return { error: "initial_region is required: {x, y, width, height}." };
2385
+ }
2386
+ const regionFields = ["x", "y", "width", "height"];
2387
+ for (const field of regionFields) {
2388
+ if (!isFiniteNumber(region[field])) {
2389
+ return { error: `initial_region.${field} must be a number.` };
2390
+ }
2391
+ }
2392
+ const startMs = params["start_ms"];
2393
+ const endMs = params["end_ms"];
2394
+ if (!isFiniteNumber(startMs) || !isFiniteNumber(endMs)) {
2395
+ return { error: "start_ms and end_ms are required numbers." };
2396
+ }
2397
+ const directionRaw = params["direction"];
2398
+ const direction = isString(directionRaw) &&
2399
+ TRACK_OBJECT_DIRECTIONS.includes(directionRaw)
2400
+ ? directionRaw
2401
+ : "forward";
2402
+ const { TimelineSequence } = await import("@nodetool-ai/models");
2403
+ const sequence = await TimelineSequence.findById(timelineId);
2404
+ if (!sequence || sequence.user_id !== run.context.userId) {
2405
+ return { error: `Timeline ${timelineId} was not found.` };
2406
+ }
2407
+ const document = sequence.toDocument();
2408
+ const clip = findClip(document.clips, params["clip_id"], "clip_id");
2409
+ if (isError(clip))
2410
+ return clip;
2411
+ const { randomUUID } = await import("node:crypto");
2412
+ const trackId = isString(params["track_id"])
2413
+ ? params["track_id"]
2414
+ : `track_${randomUUID()}`;
2415
+ const name = isString(params["name"]) ? params["name"] : "Tracked subject";
2416
+ let expectedUpdatedAt = sequence.updated_at;
2417
+ let mediaTracks = document.mediaTracks ?? [];
2418
+ const persist = async (next) => {
2419
+ const saved = await TimelineSequence.updateDocumentIfUnchanged(timelineId, expectedUpdatedAt, { ...document, mediaTracks: next }, { ops: [{ tool: "track_object", input: { clip_id: clip.id, track_id: trackId } }] });
2420
+ if (!saved)
2421
+ return false;
2422
+ mediaTracks = next;
2423
+ expectedUpdatedAt = saved.updated_at;
2424
+ return true;
2425
+ };
2426
+ const { contextTrackObjectRunner, trackObjectOnDocument } = await import("./timeline-track-object.js");
2427
+ const runner = await contextTrackObjectRunner(run.context, isString(params["provider"]) ? params["provider"] : undefined, isString(params["model"]) ? params["model"] : undefined);
2428
+ const input = {
2429
+ clip,
2430
+ mediaTracks,
2431
+ name,
2432
+ initialRegion: {
2433
+ x: region["x"],
2434
+ y: region["y"],
2435
+ width: region["width"],
2436
+ height: region["height"]
2437
+ },
2438
+ startMs,
2439
+ endMs,
2440
+ direction,
2441
+ regenerate: params["regenerate"] === true,
2442
+ trackId
2443
+ };
2444
+ const settled = await trackObjectOnDocument({ runner, persist }, input);
2445
+ if (!("status" in settled))
2446
+ return settled;
2447
+ const result = {
2448
+ timeline_id: timelineId,
2449
+ clip_id: clip.id,
2450
+ track_id: settled.track.id,
2451
+ status: settled.status,
2452
+ reused: settled.reused
2453
+ };
2454
+ if (settled.generationId !== undefined) {
2455
+ result["generation_id"] = settled.generationId;
2456
+ }
2457
+ if (settled.costUsd !== undefined)
2458
+ result["cost_usd"] = settled.costUsd;
2459
+ if (settled.error !== undefined)
2460
+ result["error"] = settled.error;
2461
+ return result;
2462
+ }
2463
+ };
2464
+ /**
2465
+ * The report shape `get_timeline_code`, `set_timeline_code`, `edit_timeline_code`
2466
+ * and `rebake_timeline_code` all answer for `scenes`: `edited` means "kept
2467
+ * as-is rather than reflecting the code" — either the code has never been
2468
+ * baked into a current merge (`get`), or this call's own merge kept it as a
2469
+ * conflict (`set`/`edit`/`rebake`).
2470
+ */
2471
+ function sceneReport(scenes, editedNames) {
2472
+ return Object.entries(scenes).map(([name, recorded]) => ({
2473
+ name,
2474
+ group_id: recorded.groupId,
2475
+ edited: editedNames.has(name)
2476
+ }));
2477
+ }
2478
+ /** `force` is a boolean or an array of scene names; anything else is refused. */
2479
+ function normalizeForceOption(value) {
2480
+ if (value === undefined)
2481
+ return undefined;
2482
+ if (value === true)
2483
+ return true;
2484
+ if (value === false)
2485
+ return undefined;
2486
+ if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
2487
+ return value;
2488
+ }
2489
+ return { error: "force must be a boolean or an array of scene names." };
2490
+ }
2491
+ /**
2492
+ * Validate, snapshot, and CAS-write a document the way `set_timeline_document`
2493
+ * does (see its own docstring for why each step is there): validate first so
2494
+ * a document that would not render never reaches the database, snapshot the
2495
+ * state being replaced so the write is undoable, then a CAS write so a
2496
+ * concurrent edit is reported rather than clobbered.
2497
+ */
2498
+ export async function writeTimelineCodeDocument(sequence, document, snapshotName) {
2499
+ const { validateTimelineSequence } = await import("@nodetool-ai/execution/timeline-debug");
2500
+ const before = validateTimelineSequence(document, { fps: sequence.fps, width: sequence.width, height: sequence.height });
2501
+ const errors = before.errors.map((issue) => issue.message);
2502
+ const warnings = before.warnings.map((issue) => issue.message);
2503
+ if (!before.ok) {
2504
+ return {
2505
+ written: false,
2506
+ error: `The baked document has ${before.errors.length} error${before.errors.length === 1 ? "" : "s"} and was not written to timeline ${sequence.id}.`,
2507
+ errors,
2508
+ warnings
2509
+ };
2510
+ }
2511
+ const { TimelineSequence: TimelineSequenceModel, TimelineSequenceVersion } = await import("@nodetool-ai/models");
2512
+ await TimelineSequenceVersion.snapshot(sequence, {
2513
+ saveType: "manual",
2514
+ name: snapshotName
2515
+ });
2516
+ const saved = await TimelineSequenceModel.updateFieldsIfUnchanged(sequence.id, sequence.updated_at, {
2517
+ document: JSON.stringify(document),
2518
+ duration_ms: documentDurationMs(document)
2519
+ });
2520
+ if (!saved) {
2521
+ return {
2522
+ written: false,
2523
+ error: `Timeline ${sequence.id} was modified concurrently; nothing was written. Read it again and try again.`,
2524
+ errors,
2525
+ warnings
2526
+ };
2527
+ }
2528
+ return { written: true, timeline_id: saved.id, errors, warnings };
2529
+ }
2530
+ /**
2531
+ * Bake `code`, merge the result into `sequence`'s current document (see
2532
+ * `mergeTimelineSource` in `@nodetool-ai/timeline` for the merge rule), and
2533
+ * write it through the same path `set_timeline_document` uses. Shared by
2534
+ * `set_timeline_code`, `edit_timeline_code` and `rebake_timeline_code` — they
2535
+ * differ only in where `code` comes from.
2536
+ */
2537
+ async function bakeAndMergeTimelineCode(run, sequence, code, force) {
2538
+ const current = sequence.toDocument();
2539
+ const baked = await bakeTimelineCode(run.context, code);
2540
+ if (!baked.ok || !baked.document) {
2541
+ return {
2542
+ timeline_id: sequence.id,
2543
+ errors: [baked.error ?? "The code failed to build a document."],
2544
+ warnings: [],
2545
+ conflicts: [],
2546
+ scenes: []
2547
+ };
2548
+ }
2549
+ const previousScenes = current.source?.scenes ?? {};
2550
+ const merged = mergeTimelineSource(current, baked.document, previousScenes, force !== undefined ? { force } : {});
2551
+ const mergedWithSource = {
2552
+ ...merged.document,
2553
+ source: {
2554
+ lang: "js",
2555
+ code,
2556
+ bakedAt: new Date().toISOString(),
2557
+ scenes: merged.scenes
2558
+ }
2559
+ };
2560
+ const editedNames = new Set(merged.conflicts.map((c) => c.scene));
2561
+ const scenes = sceneReport(merged.scenes, editedNames);
2562
+ const write = await writeTimelineCodeDocument(sequence, mergedWithSource, "Before writing timeline code");
2563
+ if (!write.written) {
2564
+ return {
2565
+ timeline_id: sequence.id,
2566
+ errors: [write.error, ...write.errors],
2567
+ warnings: write.warnings,
2568
+ conflicts: merged.conflicts,
2569
+ scenes
2570
+ };
2571
+ }
2572
+ return {
2573
+ timeline_id: write.timeline_id,
2574
+ errors: write.errors,
2575
+ warnings: write.warnings,
2576
+ conflicts: merged.conflicts,
2577
+ scenes
2578
+ };
2579
+ }
2580
+ /**
2581
+ * Attach `code` as `sequence`'s authoring source only when a hermetic bake
2582
+ * of it gives exactly the document that is saved now. This is
2583
+ * `set_timeline_code` with `require_match: true`, which `v.save()` calls
2584
+ * with the retained program it printed (docs/timeline-code-capture.md).
2585
+ *
2586
+ * A mismatch writes nothing and returns a warning. The document stays as it
2587
+ * was saved, only without code, because code that does not rebuild it would
2588
+ * make a later rebake diverge from what the timeline shows.
2589
+ */
2590
+ async function attachMatchingTimelineCode(run, sequence, code) {
2591
+ const current = sequence.toDocument();
2592
+ const notEmbedded = (warning) => ({
2593
+ timeline_id: sequence.id,
2594
+ embedded: false,
2595
+ errors: [],
2596
+ warnings: [warning],
2597
+ conflicts: [],
2598
+ scenes: []
2599
+ });
2600
+ const baked = await bakeTimelineCode(run.context, code);
2601
+ if (!baked.ok || !baked.document) {
2602
+ return notEmbedded(`Code not embedded: the retained program failed to rebake (${baked.error ?? "unknown error"}).`);
2603
+ }
2604
+ if (!bakedDocumentMatchesSaved(current, baked.document)) {
2605
+ return notEmbedded("Code not embedded: the retained program rebakes to a different " +
2606
+ "timeline than the one saved. A scene clip probably changed after " +
2607
+ "v.series(), or a value came from Math.random() or Date.now().");
2608
+ }
2609
+ // Every scene is new here: the saved document was just written from this
2610
+ // same run, so there are no hand edits to keep.
2611
+ const merged = mergeTimelineSource(current, baked.document, {}, { force: true });
2612
+ const write = await writeTimelineCodeDocument(sequence, {
2613
+ ...merged.document,
2614
+ source: {
2615
+ lang: "js",
2616
+ code,
2617
+ bakedAt: new Date().toISOString(),
2618
+ scenes: merged.scenes
2619
+ }
2620
+ }, "Attach authoring code");
2621
+ if (!write.written) {
2622
+ return notEmbedded(`Code not embedded: ${write.error}`);
2623
+ }
2624
+ return {
2625
+ timeline_id: write.timeline_id,
2626
+ embedded: true,
2627
+ errors: write.errors,
2628
+ warnings: write.warnings,
2629
+ conflicts: [],
2630
+ scenes: sceneReport(merged.scenes, new Set())
2631
+ };
2632
+ }
2633
+ const getTimelineCode = {
2634
+ spec: getTimelineCodeSpec,
2635
+ impl: async (run, params) => {
2636
+ const sequence = await loadTimeline(run, params["timeline_id"]);
2637
+ if (isError(sequence))
2638
+ return sequence;
2639
+ const doc = sequence.toDocument();
2640
+ const source = doc.source;
2641
+ if (!source)
2642
+ return { code: null, baked_at: null, scenes: [] };
2643
+ const groupIdByScene = new Map();
2644
+ for (const clip of doc.clips) {
2645
+ if (typeof clip.sourceScene === "string" && clip.sourceScene) {
2646
+ groupIdByScene.set(clip.sourceScene, clip.id);
2647
+ }
2648
+ }
2649
+ const editedNames = new Set();
2650
+ for (const [name, recorded] of Object.entries(source.scenes)) {
2651
+ const groupId = groupIdByScene.get(name);
2652
+ const edited = groupId === undefined ||
2653
+ hashSceneSubtree(doc.clips, groupId) !== recorded.hash;
2654
+ if (edited)
2655
+ editedNames.add(name);
2656
+ }
2657
+ return {
2658
+ code: source.code,
2659
+ baked_at: source.bakedAt,
2660
+ scenes: sceneReport(source.scenes, editedNames)
2661
+ };
2662
+ }
2663
+ };
2664
+ const setTimelineCode = {
2665
+ spec: setTimelineCodeSpec,
2666
+ impl: async (run, params) => {
2667
+ const sequence = await loadTimeline(run, params["timeline_id"]);
2668
+ if (isError(sequence))
2669
+ return sequence;
2670
+ const code = params["code"];
2671
+ if (!isString(code) || !code.trim()) {
2672
+ return { error: "code is required and must be a non-empty script." };
2673
+ }
2674
+ if (params["require_match"] === true) {
2675
+ return attachMatchingTimelineCode(run, sequence, code);
2676
+ }
2677
+ const force = normalizeForceOption(params["force"]);
2678
+ if (isError(force))
2679
+ return force;
2680
+ return bakeAndMergeTimelineCode(run, sequence, code, force);
2681
+ }
2682
+ };
2683
+ const editTimelineCode = {
2684
+ spec: editTimelineCodeSpec,
2685
+ impl: async (run, params) => {
2686
+ const sequence = await loadTimeline(run, params["timeline_id"]);
2687
+ if (isError(sequence))
2688
+ return sequence;
2689
+ const source = sequence.toDocument().source;
2690
+ if (!source) {
2691
+ return {
2692
+ error: `Timeline ${sequence.id} has no authoring code to edit. Call set_timeline_code first.`
2693
+ };
2694
+ }
2695
+ const ops = parseJsScriptEditOps(params["edits"]);
2696
+ if (isError(ops))
2697
+ return ops;
2698
+ const applied = applyJsScriptEditOps(source.code, ops);
2699
+ if (isError(applied))
2700
+ return applied;
2701
+ const force = normalizeForceOption(params["force"]);
2702
+ if (isError(force))
2703
+ return force;
2704
+ return bakeAndMergeTimelineCode(run, sequence, applied.code, force);
2705
+ }
2706
+ };
2707
+ const rebakeTimelineCode = {
2708
+ spec: rebakeTimelineCodeSpec,
2709
+ impl: async (run, params) => {
2710
+ const sequence = await loadTimeline(run, params["timeline_id"]);
2711
+ if (isError(sequence))
2712
+ return sequence;
2713
+ const source = sequence.toDocument().source;
2714
+ if (!source) {
2715
+ return { error: `Timeline ${sequence.id} has no authoring code to rebake.` };
2716
+ }
2717
+ const force = normalizeForceOption(params["force"]);
2718
+ if (isError(force))
2719
+ return force;
2720
+ return bakeAndMergeTimelineCode(run, sequence, source.code, force);
2721
+ }
2722
+ };
2723
+ const detachTimelineCode = {
2724
+ spec: detachTimelineCodeSpec,
2725
+ impl: async (run, params) => {
2726
+ const sequence = await loadTimeline(run, params["timeline_id"]);
2727
+ if (isError(sequence))
2728
+ return sequence;
2729
+ const current = sequence.toDocument();
2730
+ const source = current.source;
2731
+ if (!source)
2732
+ return { scenes: [] };
2733
+ const scenesParam = params["scenes"];
2734
+ // "all" drops the code entirely — there is nothing left to track, and
2735
+ // nothing left worth rebaking. Naming every currently-tracked scene one
2736
+ // by one is a different request: those scenes stop being tracked, but
2737
+ // the code stays, so a later edit that reintroduces a scene (or adds a
2738
+ // new one) still has somewhere to bake into.
2739
+ const dropCode = scenesParam === "all";
2740
+ let detachedNames;
2741
+ if (dropCode) {
2742
+ detachedNames = Object.keys(source.scenes);
2743
+ }
2744
+ else if (Array.isArray(scenesParam) &&
2745
+ scenesParam.length > 0 &&
2746
+ scenesParam.every((s) => typeof s === "string")) {
2747
+ detachedNames = scenesParam.filter((name) => name in source.scenes);
2748
+ }
2749
+ else {
2750
+ return {
2751
+ error: 'scenes must be "all" or a non-empty array of scene names.'
2752
+ };
2753
+ }
2754
+ if (detachedNames.length === 0)
2755
+ return { scenes: [] };
2756
+ const remaining = { ...source.scenes };
2757
+ for (const name of detachedNames)
2758
+ delete remaining[name];
2759
+ const nextDocument = { ...current };
2760
+ if (dropCode) {
2761
+ delete nextDocument["source"];
2762
+ }
2763
+ else {
2764
+ nextDocument["source"] = { ...source, scenes: remaining };
2765
+ }
2766
+ const { TimelineSequence: TimelineSequenceModel, TimelineSequenceVersion } = await import("@nodetool-ai/models");
2767
+ await TimelineSequenceVersion.snapshot(sequence, {
2768
+ saveType: "manual",
2769
+ name: "Before detaching timeline code"
2770
+ });
2771
+ const saved = await TimelineSequenceModel.updateFieldsIfUnchanged(sequence.id, sequence.updated_at, { document: JSON.stringify(nextDocument) });
2772
+ if (!saved) {
2773
+ return {
2774
+ error: `Timeline ${sequence.id} was modified concurrently; nothing was written. Try again.`
2775
+ };
2776
+ }
2777
+ return { timeline_id: saved.id, scenes: detachedNames };
2778
+ }
2779
+ };
2780
+ const deleteTimeline = {
2781
+ spec: deleteTimelineSpec,
2782
+ impl: async (run, params) => {
2783
+ const userId = run.context.userId;
2784
+ if (!userId)
2785
+ return { error: "No user is bound to this session." };
2786
+ const { TimelineSequence } = await import("@nodetool-ai/models");
2787
+ const id = String(params["timeline_id"]);
2788
+ const deleted = await TimelineSequence.deleteOwned(userId, id);
2789
+ return deleted
2790
+ ? { timeline_id: id, deleted: true }
2791
+ : { error: `Timeline sequence ${id} was not found, or it is not yours.` };
2792
+ }
2793
+ };
2794
+ export const TIMELINE_CAPABILITIES = [
2795
+ listTimelines,
2796
+ createTimeline,
2797
+ getTimeline,
2798
+ listTimelineVersions,
2799
+ getTimelineVersion,
2800
+ createTimelineVersion,
2801
+ restoreTimelineVersion,
2802
+ deleteTimelineVersion,
2803
+ editTimeline,
2804
+ validateTimeline,
2805
+ setTimelineDocument,
2806
+ previewTimelineFrame,
2807
+ compareTimelineFrames,
2808
+ renderTimeline,
2809
+ bakeAudioAnimation,
2810
+ isolateSubject,
2811
+ trackObject,
2812
+ ...TIMELINE_NATIVE_MEDIA_CAPABILITIES,
2813
+ getTimelineCode,
2814
+ setTimelineCode,
2815
+ editTimelineCode,
2816
+ rebakeTimelineCode,
2817
+ detachTimelineCode,
2818
+ deleteTimeline
2819
+ ];
2820
+ export const module = {
2821
+ module: "timelines",
2822
+ exports: TIMELINE_CAPABILITIES
2823
+ };
2824
+ export { listTimelines, createTimeline, getTimeline, listTimelineVersions, getTimelineVersion, createTimelineVersion, restoreTimelineVersion, deleteTimelineVersion, editTimeline, validateTimeline, setTimelineDocument, previewTimelineFrame, compareTimelineFrames, renderTimeline, bakeAudioAnimation, isolateSubject, trackObject, getTimelineCode, setTimelineCode, editTimelineCode, rebakeTimelineCode, detachTimelineCode, deleteTimeline };
2825
+ //# sourceMappingURL=timelines.js.map