@koda-sl/baker-cli 0.39.29-dev.994437bd → 0.66.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 (323) hide show
  1. package/README.md +1754 -7
  2. package/canvas/avocado-tutorial.json +89 -0
  3. package/canvas/hello-world-composition/index.html +83 -0
  4. package/canvas/hello-world-composition/meta.json +41 -0
  5. package/canvas/hello-world-overlay.json +37 -0
  6. package/canvas/phone-scroll-composition/index.html +141 -0
  7. package/canvas/phone-scroll-composition/meta.json +39 -0
  8. package/canvas/tiktok-captions-composition/index.html +126 -0
  9. package/canvas/tiktok-captions-composition/meta.json +46 -0
  10. package/canvas/video-overlay-composition/index.html +239 -0
  11. package/canvas/video-overlay-composition/meta.json +29 -0
  12. package/dist/cli.js +2 -0
  13. package/dist/cli.js.map +1 -1
  14. package/dist/commands/ads/meta/creatives.js +1 -1
  15. package/dist/commands/canvas/catalog.d.ts +2 -0
  16. package/dist/commands/canvas/catalog.d.ts.map +1 -0
  17. package/dist/commands/canvas/catalog.js +13 -0
  18. package/dist/commands/canvas/catalog.js.map +1 -0
  19. package/dist/commands/canvas/index.d.ts +2 -0
  20. package/dist/commands/canvas/index.d.ts.map +1 -0
  21. package/dist/commands/canvas/index.js +32 -0
  22. package/dist/commands/canvas/index.js.map +1 -0
  23. package/dist/commands/canvas/inspect.d.ts +16 -0
  24. package/dist/commands/canvas/inspect.d.ts.map +1 -0
  25. package/dist/commands/canvas/inspect.js +115 -0
  26. package/dist/commands/canvas/inspect.js.map +1 -0
  27. package/dist/commands/canvas/run.d.ts +24 -0
  28. package/dist/commands/canvas/run.d.ts.map +1 -0
  29. package/dist/commands/canvas/run.js +56 -0
  30. package/dist/commands/canvas/run.js.map +1 -0
  31. package/dist/commands/canvas/scaffold-static-ad.d.ts +40 -0
  32. package/dist/commands/canvas/scaffold-static-ad.d.ts.map +1 -0
  33. package/dist/commands/canvas/scaffold-static-ad.js +265 -0
  34. package/dist/commands/canvas/scaffold-static-ad.js.map +1 -0
  35. package/dist/commands/canvas/scaffold-video.d.ts +44 -0
  36. package/dist/commands/canvas/scaffold-video.d.ts.map +1 -0
  37. package/dist/commands/canvas/scaffold-video.js +235 -0
  38. package/dist/commands/canvas/scaffold-video.js.map +1 -0
  39. package/dist/commands/canvas/validate.d.ts +8 -0
  40. package/dist/commands/canvas/validate.d.ts.map +1 -0
  41. package/dist/commands/canvas/validate.js +37 -0
  42. package/dist/commands/canvas/validate.js.map +1 -0
  43. package/dist/commands/images/find.d.ts +1 -1
  44. package/dist/commands/images/find.d.ts.map +1 -1
  45. package/dist/commands/images/find.js +12 -3
  46. package/dist/commands/images/find.js.map +1 -1
  47. package/dist/commands/images/google.d.ts +1 -1
  48. package/dist/commands/images/google.d.ts.map +1 -1
  49. package/dist/commands/images/google.js +12 -3
  50. package/dist/commands/images/google.js.map +1 -1
  51. package/dist/commands/images/stock.d.ts +1 -1
  52. package/dist/commands/images/stock.d.ts.map +1 -1
  53. package/dist/commands/images/stock.js +7 -3
  54. package/dist/commands/images/stock.js.map +1 -1
  55. package/dist/commands/testimonials/list.d.ts.map +1 -1
  56. package/dist/commands/testimonials/list.js +21 -6
  57. package/dist/commands/testimonials/list.js.map +1 -1
  58. package/dist/commands/testimonials/search.d.ts.map +1 -1
  59. package/dist/commands/testimonials/search.js +21 -6
  60. package/dist/commands/testimonials/search.js.map +1 -1
  61. package/dist/commands/testimonials/search.test.js +3 -3
  62. package/dist/commands/testimonials/search.test.js.map +1 -1
  63. package/dist/engine/client/backend-client.d.ts +50 -0
  64. package/dist/engine/client/backend-client.d.ts.map +1 -0
  65. package/dist/engine/client/backend-client.js +20 -0
  66. package/dist/engine/client/backend-client.js.map +1 -0
  67. package/dist/engine/client/env.d.ts +7 -0
  68. package/dist/engine/client/env.d.ts.map +1 -0
  69. package/dist/engine/client/env.js +18 -0
  70. package/dist/engine/client/env.js.map +1 -0
  71. package/dist/engine/client/http.d.ts +56 -0
  72. package/dist/engine/client/http.d.ts.map +1 -0
  73. package/dist/engine/client/http.js +168 -0
  74. package/dist/engine/client/http.js.map +1 -0
  75. package/dist/engine/engine/cache-key.d.ts +19 -0
  76. package/dist/engine/engine/cache-key.d.ts.map +1 -0
  77. package/dist/engine/engine/cache-key.js +33 -0
  78. package/dist/engine/engine/cache-key.js.map +1 -0
  79. package/dist/engine/engine/canonical.d.ts +14 -0
  80. package/dist/engine/engine/canonical.d.ts.map +1 -0
  81. package/dist/engine/engine/canonical.js +53 -0
  82. package/dist/engine/engine/canonical.js.map +1 -0
  83. package/dist/engine/engine/composition-hash.d.ts +14 -0
  84. package/dist/engine/engine/composition-hash.d.ts.map +1 -0
  85. package/dist/engine/engine/composition-hash.js +51 -0
  86. package/dist/engine/engine/composition-hash.js.map +1 -0
  87. package/dist/engine/engine/composition-meta.d.ts +77 -0
  88. package/dist/engine/engine/composition-meta.d.ts.map +1 -0
  89. package/dist/engine/engine/composition-meta.js +199 -0
  90. package/dist/engine/engine/composition-meta.js.map +1 -0
  91. package/dist/engine/engine/context.d.ts +16 -0
  92. package/dist/engine/engine/context.d.ts.map +1 -0
  93. package/dist/engine/engine/context.js +2 -0
  94. package/dist/engine/engine/context.js.map +1 -0
  95. package/dist/engine/engine/define.d.ts +69 -0
  96. package/dist/engine/engine/define.d.ts.map +1 -0
  97. package/dist/engine/engine/define.js +9 -0
  98. package/dist/engine/engine/define.js.map +1 -0
  99. package/dist/engine/engine/didyoumean.d.ts +2 -0
  100. package/dist/engine/engine/didyoumean.d.ts.map +1 -0
  101. package/dist/engine/engine/didyoumean.js +58 -0
  102. package/dist/engine/engine/didyoumean.js.map +1 -0
  103. package/dist/engine/engine/errors.d.ts +41 -0
  104. package/dist/engine/engine/errors.d.ts.map +1 -0
  105. package/dist/engine/engine/errors.js +45 -0
  106. package/dist/engine/engine/errors.js.map +1 -0
  107. package/dist/engine/engine/executor.d.ts +72 -0
  108. package/dist/engine/engine/executor.d.ts.map +1 -0
  109. package/dist/engine/engine/executor.js +445 -0
  110. package/dist/engine/engine/executor.js.map +1 -0
  111. package/dist/engine/engine/refs.d.ts +12 -0
  112. package/dist/engine/engine/refs.d.ts.map +1 -0
  113. package/dist/engine/engine/refs.js +48 -0
  114. package/dist/engine/engine/refs.js.map +1 -0
  115. package/dist/engine/engine/registry.d.ts +11 -0
  116. package/dist/engine/engine/registry.d.ts.map +1 -0
  117. package/dist/engine/engine/registry.js +26 -0
  118. package/dist/engine/engine/registry.js.map +1 -0
  119. package/dist/engine/engine/scheduler.d.ts +10 -0
  120. package/dist/engine/engine/scheduler.d.ts.map +1 -0
  121. package/dist/engine/engine/scheduler.js +89 -0
  122. package/dist/engine/engine/scheduler.js.map +1 -0
  123. package/dist/engine/engine/validator.d.ts +31 -0
  124. package/dist/engine/engine/validator.d.ts.map +1 -0
  125. package/dist/engine/engine/validator.js +501 -0
  126. package/dist/engine/engine/validator.js.map +1 -0
  127. package/dist/engine/index.d.ts +33 -0
  128. package/dist/engine/index.d.ts.map +1 -0
  129. package/dist/engine/index.js +104 -0
  130. package/dist/engine/index.js.map +1 -0
  131. package/dist/engine/lib/ulid.d.ts +3 -0
  132. package/dist/engine/lib/ulid.d.ts.map +1 -0
  133. package/dist/engine/lib/ulid.js +36 -0
  134. package/dist/engine/lib/ulid.js.map +1 -0
  135. package/dist/engine/models/canvas-ad-params.test.d.ts +2 -0
  136. package/dist/engine/models/canvas-ad-params.test.d.ts.map +1 -0
  137. package/dist/engine/models/canvas-ad-params.test.js +60 -0
  138. package/dist/engine/models/canvas-ad-params.test.js.map +1 -0
  139. package/dist/engine/models/registry.d.ts +63 -0
  140. package/dist/engine/models/registry.d.ts.map +1 -0
  141. package/dist/engine/models/registry.js +432 -0
  142. package/dist/engine/models/registry.js.map +1 -0
  143. package/dist/engine/models/validateParams.d.ts +38 -0
  144. package/dist/engine/models/validateParams.d.ts.map +1 -0
  145. package/dist/engine/models/validateParams.js +166 -0
  146. package/dist/engine/models/validateParams.js.map +1 -0
  147. package/dist/engine/nodes/ingest.d.ts +113 -0
  148. package/dist/engine/nodes/ingest.d.ts.map +1 -0
  149. package/dist/engine/nodes/ingest.js +555 -0
  150. package/dist/engine/nodes/ingest.js.map +1 -0
  151. package/dist/engine/nodes/ingest.svg.test.d.ts +2 -0
  152. package/dist/engine/nodes/ingest.svg.test.d.ts.map +1 -0
  153. package/dist/engine/nodes/ingest.svg.test.js +30 -0
  154. package/dist/engine/nodes/ingest.svg.test.js.map +1 -0
  155. package/dist/engine/nodes/local/audioTimeline.d.ts +82 -0
  156. package/dist/engine/nodes/local/audioTimeline.d.ts.map +1 -0
  157. package/dist/engine/nodes/local/audioTimeline.js +97 -0
  158. package/dist/engine/nodes/local/audioTimeline.js.map +1 -0
  159. package/dist/engine/nodes/local/ffmpeg.d.ts +56 -0
  160. package/dist/engine/nodes/local/ffmpeg.d.ts.map +1 -0
  161. package/dist/engine/nodes/local/ffmpeg.js +50 -0
  162. package/dist/engine/nodes/local/ffmpeg.js.map +1 -0
  163. package/dist/engine/nodes/local/fontSpecimen.d.ts +50 -0
  164. package/dist/engine/nodes/local/fontSpecimen.d.ts.map +1 -0
  165. package/dist/engine/nodes/local/fontSpecimen.js +198 -0
  166. package/dist/engine/nodes/local/fontSpecimen.js.map +1 -0
  167. package/dist/engine/nodes/local/hyperframe-snapshot.d.ts +116 -0
  168. package/dist/engine/nodes/local/hyperframe-snapshot.d.ts.map +1 -0
  169. package/dist/engine/nodes/local/hyperframe-snapshot.js +230 -0
  170. package/dist/engine/nodes/local/hyperframe-snapshot.js.map +1 -0
  171. package/dist/engine/nodes/local/hyperframe.d.ts +123 -0
  172. package/dist/engine/nodes/local/hyperframe.d.ts.map +1 -0
  173. package/dist/engine/nodes/local/hyperframe.js +367 -0
  174. package/dist/engine/nodes/local/hyperframe.js.map +1 -0
  175. package/dist/engine/nodes/local/imagemagick.d.ts +56 -0
  176. package/dist/engine/nodes/local/imagemagick.d.ts.map +1 -0
  177. package/dist/engine/nodes/local/imagemagick.js +71 -0
  178. package/dist/engine/nodes/local/imagemagick.js.map +1 -0
  179. package/dist/engine/nodes/local/lib/assets.d.ts +20 -0
  180. package/dist/engine/nodes/local/lib/assets.d.ts.map +1 -0
  181. package/dist/engine/nodes/local/lib/assets.js +40 -0
  182. package/dist/engine/nodes/local/lib/assets.js.map +1 -0
  183. package/dist/engine/nodes/local/lib/cli-runner.d.ts +78 -0
  184. package/dist/engine/nodes/local/lib/cli-runner.d.ts.map +1 -0
  185. package/dist/engine/nodes/local/lib/cli-runner.js +254 -0
  186. package/dist/engine/nodes/local/lib/cli-runner.js.map +1 -0
  187. package/dist/engine/nodes/local/lib/ffmpeg.d.ts +23 -0
  188. package/dist/engine/nodes/local/lib/ffmpeg.d.ts.map +1 -0
  189. package/dist/engine/nodes/local/lib/ffmpeg.js +75 -0
  190. package/dist/engine/nodes/local/lib/ffmpeg.js.map +1 -0
  191. package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts +2 -0
  192. package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts.map +1 -0
  193. package/dist/engine/nodes/local/lib/hyperframe-errors.js +47 -0
  194. package/dist/engine/nodes/local/lib/hyperframe-errors.js.map +1 -0
  195. package/dist/engine/nodes/local/lib/templating.d.ts +22 -0
  196. package/dist/engine/nodes/local/lib/templating.d.ts.map +1 -0
  197. package/dist/engine/nodes/local/lib/templating.js +85 -0
  198. package/dist/engine/nodes/local/lib/templating.js.map +1 -0
  199. package/dist/engine/nodes/local/text.d.ts +6 -0
  200. package/dist/engine/nodes/local/text.d.ts.map +1 -0
  201. package/dist/engine/nodes/local/text.js +15 -0
  202. package/dist/engine/nodes/local/text.js.map +1 -0
  203. package/dist/engine/nodes/remote/delegate.d.ts +25 -0
  204. package/dist/engine/nodes/remote/delegate.d.ts.map +1 -0
  205. package/dist/engine/nodes/remote/delegate.js +160 -0
  206. package/dist/engine/nodes/remote/delegate.js.map +1 -0
  207. package/dist/engine/nodes/remote/dialogue.d.ts +34 -0
  208. package/dist/engine/nodes/remote/dialogue.d.ts.map +1 -0
  209. package/dist/engine/nodes/remote/dialogue.js +54 -0
  210. package/dist/engine/nodes/remote/dialogue.js.map +1 -0
  211. package/dist/engine/nodes/remote/image.d.ts +42 -0
  212. package/dist/engine/nodes/remote/image.d.ts.map +1 -0
  213. package/dist/engine/nodes/remote/image.js +43 -0
  214. package/dist/engine/nodes/remote/image.js.map +1 -0
  215. package/dist/engine/nodes/remote/imageAspectAdapt.d.ts +30 -0
  216. package/dist/engine/nodes/remote/imageAspectAdapt.d.ts.map +1 -0
  217. package/dist/engine/nodes/remote/imageAspectAdapt.js +42 -0
  218. package/dist/engine/nodes/remote/imageAspectAdapt.js.map +1 -0
  219. package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts +39 -0
  220. package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts.map +1 -0
  221. package/dist/engine/nodes/remote/imageBackgroundRemove.js +37 -0
  222. package/dist/engine/nodes/remote/imageBackgroundRemove.js.map +1 -0
  223. package/dist/engine/nodes/remote/imageDescribe.d.ts +29 -0
  224. package/dist/engine/nodes/remote/imageDescribe.d.ts.map +1 -0
  225. package/dist/engine/nodes/remote/imageDescribe.js +25 -0
  226. package/dist/engine/nodes/remote/imageDescribe.js.map +1 -0
  227. package/dist/engine/nodes/remote/imageReferenceSheet.d.ts +34 -0
  228. package/dist/engine/nodes/remote/imageReferenceSheet.d.ts.map +1 -0
  229. package/dist/engine/nodes/remote/imageReferenceSheet.js +38 -0
  230. package/dist/engine/nodes/remote/imageReferenceSheet.js.map +1 -0
  231. package/dist/engine/nodes/remote/imageSearch.d.ts +18 -0
  232. package/dist/engine/nodes/remote/imageSearch.d.ts.map +1 -0
  233. package/dist/engine/nodes/remote/imageSearch.js +22 -0
  234. package/dist/engine/nodes/remote/imageSearch.js.map +1 -0
  235. package/dist/engine/nodes/remote/imageSelect.d.ts +39 -0
  236. package/dist/engine/nodes/remote/imageSelect.d.ts.map +1 -0
  237. package/dist/engine/nodes/remote/imageSelect.js +45 -0
  238. package/dist/engine/nodes/remote/imageSelect.js.map +1 -0
  239. package/dist/engine/nodes/remote/music.d.ts +45 -0
  240. package/dist/engine/nodes/remote/music.d.ts.map +1 -0
  241. package/dist/engine/nodes/remote/music.js +73 -0
  242. package/dist/engine/nodes/remote/music.js.map +1 -0
  243. package/dist/engine/nodes/remote/soundEffect.d.ts +21 -0
  244. package/dist/engine/nodes/remote/soundEffect.d.ts.map +1 -0
  245. package/dist/engine/nodes/remote/soundEffect.js +41 -0
  246. package/dist/engine/nodes/remote/soundEffect.js.map +1 -0
  247. package/dist/engine/nodes/remote/textGenerate.d.ts +21 -0
  248. package/dist/engine/nodes/remote/textGenerate.d.ts.map +1 -0
  249. package/dist/engine/nodes/remote/textGenerate.js +27 -0
  250. package/dist/engine/nodes/remote/textGenerate.js.map +1 -0
  251. package/dist/engine/nodes/remote/tts.d.ts +45 -0
  252. package/dist/engine/nodes/remote/tts.d.ts.map +1 -0
  253. package/dist/engine/nodes/remote/tts.js +66 -0
  254. package/dist/engine/nodes/remote/tts.js.map +1 -0
  255. package/dist/engine/nodes/remote/video.d.ts +58 -0
  256. package/dist/engine/nodes/remote/video.d.ts.map +1 -0
  257. package/dist/engine/nodes/remote/video.js +44 -0
  258. package/dist/engine/nodes/remote/video.js.map +1 -0
  259. package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts +30 -0
  260. package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts.map +1 -0
  261. package/dist/engine/nodes/remote/videoBackgroundRemove.js +29 -0
  262. package/dist/engine/nodes/remote/videoBackgroundRemove.js.map +1 -0
  263. package/dist/engine/nodes/remote/videoDeconstruct.d.ts +61 -0
  264. package/dist/engine/nodes/remote/videoDeconstruct.d.ts.map +1 -0
  265. package/dist/engine/nodes/remote/videoDeconstruct.js +40 -0
  266. package/dist/engine/nodes/remote/videoDeconstruct.js.map +1 -0
  267. package/dist/engine/nodes/remote/videoLipsync.d.ts +37 -0
  268. package/dist/engine/nodes/remote/videoLipsync.d.ts.map +1 -0
  269. package/dist/engine/nodes/remote/videoLipsync.js +26 -0
  270. package/dist/engine/nodes/remote/videoLipsync.js.map +1 -0
  271. package/dist/engine/nodes/remote/videoTranscribe.d.ts +116 -0
  272. package/dist/engine/nodes/remote/videoTranscribe.d.ts.map +1 -0
  273. package/dist/engine/nodes/remote/videoTranscribe.js +123 -0
  274. package/dist/engine/nodes/remote/videoTranscribe.js.map +1 -0
  275. package/dist/engine/nodes/remote/voiceSelect.d.ts +28 -0
  276. package/dist/engine/nodes/remote/voiceSelect.d.ts.map +1 -0
  277. package/dist/engine/nodes/remote/voiceSelect.js +25 -0
  278. package/dist/engine/nodes/remote/voiceSelect.js.map +1 -0
  279. package/dist/engine/scaffold/staticAd.d.ts +44 -0
  280. package/dist/engine/scaffold/staticAd.d.ts.map +1 -0
  281. package/dist/engine/scaffold/staticAd.js +243 -0
  282. package/dist/engine/scaffold/staticAd.js.map +1 -0
  283. package/dist/engine/scaffold/video.d.ts +56 -0
  284. package/dist/engine/scaffold/video.d.ts.map +1 -0
  285. package/dist/engine/scaffold/video.js +709 -0
  286. package/dist/engine/scaffold/video.js.map +1 -0
  287. package/dist/engine/schema/canvas.d.ts +41 -0
  288. package/dist/engine/schema/canvas.d.ts.map +1 -0
  289. package/dist/engine/schema/canvas.js +67 -0
  290. package/dist/engine/schema/canvas.js.map +1 -0
  291. package/dist/engine/schema/catalog.d.ts +25 -0
  292. package/dist/engine/schema/catalog.d.ts.map +1 -0
  293. package/dist/engine/schema/catalog.js +48 -0
  294. package/dist/engine/schema/catalog.js.map +1 -0
  295. package/dist/engine/schema/primitives.d.ts +6 -0
  296. package/dist/engine/schema/primitives.d.ts.map +1 -0
  297. package/dist/engine/schema/primitives.js +4 -0
  298. package/dist/engine/schema/primitives.js.map +1 -0
  299. package/dist/engine/schema/prompts.d.ts +4 -0
  300. package/dist/engine/schema/prompts.d.ts.map +1 -0
  301. package/dist/engine/schema/prompts.js +23 -0
  302. package/dist/engine/schema/prompts.js.map +1 -0
  303. package/dist/engine/schema/refs.d.ts +113 -0
  304. package/dist/engine/schema/refs.d.ts.map +1 -0
  305. package/dist/engine/schema/refs.js +35 -0
  306. package/dist/engine/schema/refs.js.map +1 -0
  307. package/dist/engine/storage/asset-store.d.ts +48 -0
  308. package/dist/engine/storage/asset-store.d.ts.map +1 -0
  309. package/dist/engine/storage/asset-store.js +166 -0
  310. package/dist/engine/storage/asset-store.js.map +1 -0
  311. package/dist/engine/storage/cache-store.d.ts +21 -0
  312. package/dist/engine/storage/cache-store.d.ts.map +1 -0
  313. package/dist/engine/storage/cache-store.js +31 -0
  314. package/dist/engine/storage/cache-store.js.map +1 -0
  315. package/dist/engine/storage/output-writer.d.ts +18 -0
  316. package/dist/engine/storage/output-writer.d.ts.map +1 -0
  317. package/dist/engine/storage/output-writer.js +52 -0
  318. package/dist/engine/storage/output-writer.js.map +1 -0
  319. package/dist/engine/storage/sha256.d.ts +2 -0
  320. package/dist/engine/storage/sha256.d.ts.map +1 -0
  321. package/dist/engine/storage/sha256.js +7 -0
  322. package/dist/engine/storage/sha256.js.map +1 -0
  323. package/package.json +15 -3
@@ -0,0 +1,85 @@
1
+ // Single-substitution model used by the composition pipeline.
2
+ //
3
+ // {{var}} in HTML, embedded <style>, embedded <script>
4
+ // ─────► replaced before render by `substituteVariables`
5
+ //
6
+ // String values are inlined as JS-safe literals (`JSON.stringify`-style for
7
+ // numbers, booleans, null, and complex structures; raw text in HTML attribute
8
+ // or text contexts). The engine does the safe stringify — composition authors
9
+ // never call `JSON.parse` again.
10
+ const PATTERN = /\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
11
+ /**
12
+ * Replace every `{{name}}` token in `source` with the JS literal form of
13
+ * `values[name]`. Strings render as their plain text (no surrounding quotes
14
+ * — convenient for both `font-size: {{size_px}}px` and `var X = {{name}};`).
15
+ *
16
+ * Complex values (arrays/objects/numbers/booleans) render via JSON.stringify
17
+ * so the result is a syntactically valid JS literal **and** valid JSON.
18
+ *
19
+ * Missing keys are reported in the returned `missing` array; the engine
20
+ * collects these and surfaces a single aggregated error.
21
+ */
22
+ export function substituteVariables(source, values) {
23
+ const missing = [];
24
+ const replaced = [];
25
+ const seenMissing = new Set();
26
+ const seenReplaced = new Set();
27
+ const output = source.replace(PATTERN, (_full, name) => {
28
+ if (!Object.hasOwn(values, name)) {
29
+ if (!seenMissing.has(name)) {
30
+ missing.push(name);
31
+ seenMissing.add(name);
32
+ }
33
+ return `{{${name}}}`;
34
+ }
35
+ if (!seenReplaced.has(name)) {
36
+ replaced.push(name);
37
+ seenReplaced.add(name);
38
+ }
39
+ return literalize(values[name]);
40
+ });
41
+ return { output, missing, replaced };
42
+ }
43
+ /**
44
+ * Render a value as a JS-safe literal embeddable in source code.
45
+ *
46
+ * string → plain text (no quotes — embed inside `"…"` if you need a string literal)
47
+ * number → toString() (NaN/Infinity → "0")
48
+ * boolean → "true" / "false"
49
+ * null → "null"
50
+ * array/object → JSON.stringify (also valid JS literal)
51
+ * undefined → "null"
52
+ *
53
+ * The plain-text behavior for strings is deliberate: most composition uses
54
+ * are HTML attributes or CSS values where surrounding quotes are author-supplied.
55
+ * Authors who need a JS string literal write `"{{name}}"` themselves.
56
+ */
57
+ function literalize(value) {
58
+ if (value === undefined || value === null)
59
+ return "null";
60
+ if (typeof value === "string")
61
+ return value;
62
+ if (typeof value === "number") {
63
+ if (!Number.isFinite(value))
64
+ return "0";
65
+ return String(value);
66
+ }
67
+ if (typeof value === "boolean")
68
+ return value ? "true" : "false";
69
+ // Arrays, objects: JSON.stringify produces valid JS *and* JSON.
70
+ return JSON.stringify(value);
71
+ }
72
+ /**
73
+ * List every `{{name}}` token referenced in `source`. Used by validators to
74
+ * cross-check declared params vs. tokens actually present in the composition.
75
+ */
76
+ export function extractReferencedTokens(source) {
77
+ const out = new Set();
78
+ for (const m of source.matchAll(PATTERN)) {
79
+ const name = m[1];
80
+ if (name)
81
+ out.add(name);
82
+ }
83
+ return [...out];
84
+ }
85
+ //# sourceMappingURL=templating.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templating.js","sourceRoot":"","sources":["../../../../../src/engine/nodes/local/lib/templating.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,2DAA2D;AAC3D,6DAA6D;AAC7D,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,iCAAiC;AAEjC,MAAM,OAAO,GAAG,yCAAyC,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,MAA+B;IAE/B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAEvC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;QAC7D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;YACD,OAAO,KAAK,IAAI,IAAI,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC;QACxC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,gEAAgE;IAChE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,IAAI;YAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const textNode: import("../../engine/define.ts").NodeDefinition<Record<string, never>, {
2
+ value: string;
3
+ }, {
4
+ text: string;
5
+ }>;
6
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../../src/engine/nodes/local/text.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ;;;;EAWnB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ import { defineNode } from "../../engine/define.js";
3
+ export const textNode = defineNode({
4
+ id: "text",
5
+ version: "1.0.0",
6
+ category: "data",
7
+ location: "local",
8
+ summary: "A literal text value. Use for prompts, descriptions, copy.",
9
+ inputs: z.object({}).strict(),
10
+ params: z.object({ value: z.string() }).strict(),
11
+ outputs: z.object({ text: z.string() }).strict(),
12
+ cost: () => ({ credits: 0, seconds_estimate: 0 }),
13
+ execute: ({ params }) => Promise.resolve({ text: params.value }),
14
+ });
15
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../../src/engine/nodes/local/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IACjC,EAAE,EAAE,MAAM;IACV,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,4DAA4D;IACrE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IAC7B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IAChD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IAChD,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;IACjD,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;CACjE,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { ExecCtx } from "../../engine/context.ts";
2
+ import type { NodeDefinition } from "../../engine/define.ts";
3
+ import type { AssetRef } from "../../schema/refs.ts";
4
+ type RemoteSpec<I, P, O> = Omit<NodeDefinition<I, P, O>, "execute" | "location">;
5
+ /**
6
+ * Build a `defineNode`-shaped remote node that POSTs to /api/canvas/nodes/exec
7
+ * and ingests any returned asset bytes locally via ctx.assets.ingestRemote.
8
+ */
9
+ export declare function delegated<I, P, O>(spec: RemoteSpec<I, P, O>): NodeDefinition<I, P, O>;
10
+ /**
11
+ * Shared "POST to /api/canvas/nodes/exec and ingest the returned assets"
12
+ * pipeline. Used by `delegated()` for remote nodes, and by the `ingest` node
13
+ * which dispatches its `direct_fetch` and `handinger` strategies through the
14
+ * same backend channel even though the node itself is registered as local.
15
+ */
16
+ export declare function callBackendExec(args: {
17
+ nodeType: string;
18
+ nodeVersion: string;
19
+ params: unknown;
20
+ inputs: unknown;
21
+ outputKinds: Record<string, AssetRef["kind"]>;
22
+ ctx: ExecCtx;
23
+ }): Promise<Record<string, unknown>>;
24
+ export {};
25
+ //# sourceMappingURL=delegate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../../../../src/engine/nodes/remote/delegate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAerF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,GAAG,EAAE,OAAO,CAAC;CACd,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAqBnC"}
@@ -0,0 +1,160 @@
1
+ import { BackendHttpError } from "../../client/http.js";
2
+ import { resolveOutputKinds } from "../../engine/define.js";
3
+ import { NodeExecutionError } from "../../engine/errors.js";
4
+ /**
5
+ * Build a `defineNode`-shaped remote node that POSTs to /api/canvas/nodes/exec
6
+ * and ingests any returned asset bytes locally via ctx.assets.ingestRemote.
7
+ */
8
+ export function delegated(spec) {
9
+ return {
10
+ ...spec,
11
+ location: "remote",
12
+ execute: async ({ inputs, params, ctx }) => {
13
+ return (await callBackendExec({
14
+ nodeType: spec.id,
15
+ nodeVersion: spec.version,
16
+ params,
17
+ inputs,
18
+ outputKinds: resolveOutputKinds(spec.outputKinds, params),
19
+ ctx,
20
+ }));
21
+ },
22
+ };
23
+ }
24
+ /**
25
+ * Shared "POST to /api/canvas/nodes/exec and ingest the returned assets"
26
+ * pipeline. Used by `delegated()` for remote nodes, and by the `ingest` node
27
+ * which dispatches its `direct_fetch` and `handinger` strategies through the
28
+ * same backend channel even though the node itself is registered as local.
29
+ */
30
+ export async function callBackendExec(args) {
31
+ try {
32
+ const serialized = serializeInputs(args.inputs);
33
+ // Scoped to the run so a deliberate re-run (e.g. cache bypass) generates
34
+ // fresh, while HTTP-level retries within one execution replay the stored
35
+ // backend response instead of dispatching (and charging) twice.
36
+ const idempotencyKey = args.ctx.cacheKey ? `${args.ctx.canvasRunId}:${args.ctx.cacheKey}` : undefined;
37
+ const res = await args.ctx.client.exec({
38
+ nodeType: args.nodeType,
39
+ nodeVersion: args.nodeVersion,
40
+ params: args.params,
41
+ inputs: serialized,
42
+ idempotency_key: idempotencyKey,
43
+ }, args.ctx.signal);
44
+ return await ingestOutputs(res.outputs, args.ctx, args.outputKinds);
45
+ }
46
+ catch (e) {
47
+ throw mapClientError(args.ctx, e);
48
+ }
49
+ }
50
+ function serializeInputs(inputs) {
51
+ if (!inputs || typeof inputs !== "object")
52
+ return {};
53
+ const out = {};
54
+ for (const [k, v] of Object.entries(inputs)) {
55
+ out[k] = stripLocalRefs(v);
56
+ }
57
+ return out;
58
+ }
59
+ function stripLocalRefs(value) {
60
+ if (Array.isArray(value))
61
+ return value.map(stripLocalRefs);
62
+ if (value && typeof value === "object") {
63
+ if ("kind" in value && "sha256" in value && "mime" in value) {
64
+ const ref = value;
65
+ // Strip local-only `path` and pass through what the backend can consume.
66
+ return {
67
+ kind: ref.kind,
68
+ url: ref.url,
69
+ sha256: ref.sha256,
70
+ mime: ref.mime,
71
+ metadata: ref.metadata,
72
+ };
73
+ }
74
+ const out = {};
75
+ for (const [k, v] of Object.entries(value))
76
+ out[k] = stripLocalRefs(v);
77
+ return out;
78
+ }
79
+ return value;
80
+ }
81
+ async function ingestOutputs(outputs, ctx, kinds) {
82
+ const result = {};
83
+ for (const [name, value] of Object.entries(outputs)) {
84
+ const declaredKind = kinds[name];
85
+ result[name] = await ingestValue(value, ctx, declaredKind);
86
+ }
87
+ return result;
88
+ }
89
+ async function ingestValue(value, ctx, declaredKind) {
90
+ if (Array.isArray(value)) {
91
+ const out = [];
92
+ for (const v of value)
93
+ out.push(await ingestValue(v, ctx, declaredKind));
94
+ return out;
95
+ }
96
+ if (isRawAsset(value)) {
97
+ const kind = value.kind ?? declaredKind ?? "json";
98
+ return ctx.assets.ingestRemote({
99
+ kind,
100
+ url: value.url,
101
+ sha256: value.sha256,
102
+ mime: value.mime,
103
+ metadata: value.metadata,
104
+ });
105
+ }
106
+ return value;
107
+ }
108
+ function isRawAsset(v) {
109
+ return Boolean(v &&
110
+ typeof v === "object" &&
111
+ "url" in v &&
112
+ "sha256" in v &&
113
+ "mime" in v &&
114
+ typeof v.url === "string" &&
115
+ typeof v.sha256 === "string");
116
+ }
117
+ function mapClientError(ctx, e) {
118
+ if (e instanceof BackendHttpError) {
119
+ const d = e.detail;
120
+ if (d.kind === "provider") {
121
+ return new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
122
+ kind: "remote",
123
+ status: d.status,
124
+ code: d.code,
125
+ message: d.message,
126
+ provider: d.provider,
127
+ });
128
+ }
129
+ if (d.kind === "timeout") {
130
+ return new NodeExecutionError(ctx.nodeId, ctx.nodeType, { kind: "timeout", provider: d.provider });
131
+ }
132
+ if (d.kind === "validation") {
133
+ return new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
134
+ kind: "remote",
135
+ status: d.status,
136
+ code: "invalid_params",
137
+ message: d.message,
138
+ });
139
+ }
140
+ if (d.kind === "unauthorized") {
141
+ return new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
142
+ kind: "remote",
143
+ status: d.status,
144
+ code: "unauthorized",
145
+ message: d.message,
146
+ });
147
+ }
148
+ if (d.kind === "network") {
149
+ return new NodeExecutionError(ctx.nodeId, ctx.nodeType, { kind: "network", cause: d.cause });
150
+ }
151
+ return new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
152
+ kind: "remote",
153
+ status: d.status,
154
+ code: "server_error",
155
+ message: d.message,
156
+ });
157
+ }
158
+ return new NodeExecutionError(ctx.nodeId, ctx.nodeType, { kind: "local", cause: e });
159
+ }
160
+ //# sourceMappingURL=delegate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegate.js","sourceRoot":"","sources":["../../../../src/engine/nodes/remote/delegate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export declare const dialogueNode: import("../../engine/define.ts").NodeDefinition<{
2
+ [x: string]: unknown;
3
+ }, {
4
+ model: "elevenlabs/eleven_v3";
5
+ inputs: {
6
+ text: string;
7
+ voice_id: string;
8
+ }[];
9
+ language_code?: string | undefined;
10
+ settings?: Record<string, unknown> | undefined;
11
+ seed?: number | undefined;
12
+ apply_text_normalization?: "off" | "on" | "auto" | undefined;
13
+ with_timestamps?: boolean | undefined;
14
+ output_format?: "mp3_22050_32" | "mp3_44100_32" | "mp3_44100_64" | "mp3_44100_96" | "mp3_44100_128" | "mp3_44100_192" | undefined;
15
+ }, {
16
+ audio: {
17
+ sha256: string;
18
+ mime: string;
19
+ kind: "audio";
20
+ url?: string | undefined;
21
+ path?: string | undefined;
22
+ metadata?: Record<string, unknown> | undefined;
23
+ duration_ms?: number | undefined;
24
+ };
25
+ timestamps?: {
26
+ sha256: string;
27
+ mime: string;
28
+ kind: "json";
29
+ url?: string | undefined;
30
+ path?: string | undefined;
31
+ metadata?: Record<string, unknown> | undefined;
32
+ } | undefined;
33
+ }>;
34
+ //# sourceMappingURL=dialogue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialogue.d.ts","sourceRoot":"","sources":["../../../../src/engine/nodes/remote/dialogue.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBvB,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ import { ELEVENLABS_MAX_TEXT_CHARS, ELEVENLABS_OUTPUT_FORMATS } from "../../models/registry.js";
3
+ import { AudioRef, JsonRef } from "../../schema/refs.js";
4
+ import { delegated } from "./delegate.js";
5
+ const DialogueInput = z.object({
6
+ text: z.string().min(1),
7
+ voice_id: z.string().min(1),
8
+ });
9
+ const DIALOGUE_MODELS = ["elevenlabs/eleven_v3"];
10
+ const DialogueParams = z
11
+ .object({
12
+ model: z.enum(DIALOGUE_MODELS),
13
+ /**
14
+ * Ordered list of lines, each tagged with the voice that should speak it.
15
+ * Up to 10 unique voice_ids; total text across all lines should stay under
16
+ * ~2000 characters for best quality (ElevenLabs guidance).
17
+ */
18
+ inputs: z.array(DialogueInput).min(1).max(50),
19
+ language_code: z.string().optional(),
20
+ /** ElevenLabs voice/model settings passthrough (e.g. `{ stability: 0.5 }`). */
21
+ settings: z.record(z.string(), z.unknown()).optional(),
22
+ seed: z.number().int().min(0).max(4_294_967_295).optional(),
23
+ apply_text_normalization: z.enum(["auto", "on", "off"]).optional(),
24
+ /**
25
+ * When true, hits `/v1/text-to-dialogue/with-timestamps` and emits a
26
+ * separate `timestamps` output — character-level alignment plus
27
+ * per-voice segment markers usable for captions, lipsync, or
28
+ * beat-matched cuts in ad creatives.
29
+ */
30
+ with_timestamps: z.boolean().optional(),
31
+ output_format: z.enum(ELEVENLABS_OUTPUT_FORMATS).optional(),
32
+ })
33
+ .strict()
34
+ // Above this the backend's $10 cost cap always rejects at dispatch.
35
+ .refine((p) => p.inputs.reduce((sum, line) => sum + line.text.length, 0) <= ELEVENLABS_MAX_TEXT_CHARS, {
36
+ message: `total dialogue text exceeds ${ELEVENLABS_MAX_TEXT_CHARS} characters`,
37
+ path: ["inputs"],
38
+ });
39
+ export const dialogueNode = delegated({
40
+ id: "dialogue",
41
+ version: "1.1.0",
42
+ category: "audio",
43
+ summary: "Multi-voice dialogue / VO with ElevenLabs Eleven v3. Each line is tagged with a `voice_id`, so you can render two-character scripts (e.g. ad VO + customer testimonial reaction) in a single call. Setting `with_timestamps: true` adds character-level alignment for caption rendering and lipsync-friendly cuts.",
44
+ when_to_use: "Use for any ad creative or website video VO that needs more than narration — interviews, two-actor scripts, character ads, testimonial reads. For single-voice flat reads the existing `tts` node is cheaper and simpler; reach for `dialogue` when you need multiple speakers in one stitched track or word-level timing for downstream lipsync / captions.",
45
+ inputs: z.object({}).loose(),
46
+ params: DialogueParams,
47
+ outputs: z.object({ audio: AudioRef, timestamps: JsonRef.optional() }).strict(),
48
+ outputKinds: { audio: "audio", timestamps: "json" },
49
+ cost: ({ params }) => {
50
+ const chars = params.inputs.reduce((sum, line) => sum + line.text.length, 0);
51
+ return { credits: Math.max(1, Math.ceil(chars * 0.0015)), seconds_estimate: 8 };
52
+ },
53
+ });
54
+ //# sourceMappingURL=dialogue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialogue.js","sourceRoot":"","sources":["../../../../src/engine/nodes/remote/dialogue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export declare const imageGenerateNode: import("../../engine/define.ts").NodeDefinition<{
2
+ [x: string]: unknown;
3
+ reference?: {
4
+ sha256: string;
5
+ mime: string;
6
+ kind: "image";
7
+ url?: string | undefined;
8
+ path?: string | undefined;
9
+ metadata?: Record<string, unknown> | undefined;
10
+ width?: number | undefined;
11
+ height?: number | undefined;
12
+ } | {
13
+ sha256: string;
14
+ mime: string;
15
+ kind: "image";
16
+ url?: string | undefined;
17
+ path?: string | undefined;
18
+ metadata?: Record<string, unknown> | undefined;
19
+ width?: number | undefined;
20
+ height?: number | undefined;
21
+ }[] | undefined;
22
+ }, {
23
+ model: "openai/gpt-5.4-image-2" | "google/gemini-3.5-flash" | "google/gemini-3.1-flash-image-preview" | "google/gemini-3-pro-image-preview" | "recraft/recraft-v4.1-pro-vector";
24
+ prompt: string;
25
+ aspect_ratio?: "1:1" | "16:9" | "9:16" | "2:3" | "3:4" | "4:5" | "3:2" | "4:3" | "5:4" | "21:9" | "1:4" | "4:1" | "1:8" | "8:1" | undefined;
26
+ image_size?: "1K" | "2K" | "4K" | "0.5K" | undefined;
27
+ strength?: number | undefined;
28
+ rgb_colors?: number[][] | undefined;
29
+ background_rgb_color?: number[] | undefined;
30
+ }, {
31
+ images: {
32
+ sha256: string;
33
+ mime: string;
34
+ kind: "image";
35
+ url?: string | undefined;
36
+ path?: string | undefined;
37
+ metadata?: Record<string, unknown> | undefined;
38
+ width?: number | undefined;
39
+ height?: number | undefined;
40
+ }[];
41
+ }>;
42
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../../src/engine/nodes/remote/image.ts"],"names":[],"mappings":"AA+BA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe5B,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ import { ImageRef } from "../../schema/refs.js";
3
+ import { delegated } from "./delegate.js";
4
+ const IMAGE_GENERATE_MODELS = [
5
+ "openai/gpt-5.4-image-2",
6
+ "google/gemini-3.5-flash",
7
+ "google/gemini-3.1-flash-image-preview",
8
+ "google/gemini-3-pro-image-preview",
9
+ "recraft/recraft-v4.1-pro-vector",
10
+ ];
11
+ // Permissive union of every param accepted by any curated model. The model
12
+ // registry (`models/registry.ts`) is the strict per-model gate — it rejects
13
+ // params that a specific model doesn't support and validates enum values.
14
+ const ImageGenerateParams = z
15
+ .object({
16
+ model: z.enum(IMAGE_GENERATE_MODELS),
17
+ prompt: z.string().min(1),
18
+ aspect_ratio: z
19
+ .enum(["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3", "4:5", "5:4", "21:9", "1:4", "4:1", "1:8", "8:1"])
20
+ .optional(),
21
+ image_size: z.enum(["0.5K", "1K", "2K", "4K"]).optional(),
22
+ // Recraft v4 vector controls — forwarded into `image_config`. Registry
23
+ // rejects them on non-Recraft models.
24
+ strength: z.number().min(0).max(1).optional(),
25
+ rgb_colors: z.array(z.array(z.number().int().min(0).max(255))).optional(),
26
+ background_rgb_color: z.array(z.number().int().min(0).max(255)).optional(),
27
+ })
28
+ .strict();
29
+ export const imageGenerateNode = delegated({
30
+ id: "image_generate",
31
+ version: "2.1.0",
32
+ category: "image",
33
+ summary: "Generate images for ad creatives. Curated model set: GPT-5.4 Image, Gemini 3.5 Flash, Gemini 3.1 Flash Image Preview, Gemini 3 Pro Image, Recraft v4.1 Pro Vector. Per-model param support comes from the canvas-engine model registry.",
34
+ when_to_use: "Use for hero shots, product photography, illustrations, and vector logos. `recraft/recraft-v4.1-pro-vector` for crisp vector / logo work; `openai/gpt-5.4-image-2` for photorealistic; Gemini variants for fast iteration and editing via the `reference` input. `reference` accepts ONE image or an ARRAY of images — wire several to combine references in a single generation (e.g. a subject sheet + a font specimen + the original ad). Every reference is forwarded to the model in array order.",
35
+ // `reference` is one image or an ordered array of images. The backend forwards
36
+ // each as a separate `image_url` to the provider (OpenRouter accepts many).
37
+ inputs: z.object({ reference: z.union([ImageRef, z.array(ImageRef).min(1)]).optional() }).loose(),
38
+ params: ImageGenerateParams,
39
+ outputs: z.object({ images: z.array(ImageRef).min(1) }).strict(),
40
+ outputKinds: { images: "image" },
41
+ cost: () => ({ credits: 5, seconds_estimate: 10 }),
42
+ });
43
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../../../../src/engine/nodes/remote/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,qBAAqB,GAAG;IAC5B,wBAAwB;IACxB,yBAAyB;IACzB,uCAAuC;IACvC,mCAAmC;IACnC,iCAAiC;CACzB,CAAC;AAEX,2EAA2E;AAC3E,4EAA4E;AAC5E,0EAA0E;AAC1E,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,YAAY,EAAE,CAAC;SACZ,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;SAC3G,QAAQ,EAAE;IACb,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzD,uEAAuE;IACvE,sCAAsC;IACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC7C,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzE,oBAAoB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC3E,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;IACzC,EAAE,EAAE,gBAAgB;IACpB,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,OAAO;IACjB,OAAO,EACL,yOAAyO;IAC3O,WAAW,EACT,weAAwe;IAC1e,+EAA+E;IAC/E,4EAA4E;IAC5E,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE;IACjG,MAAM,EAAE,mBAAmB;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IAChE,WAAW,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;IAChC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC;CACnD,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ export declare const imageAspectAdaptNode: import("../../engine/define.ts").NodeDefinition<{
2
+ [x: string]: unknown;
3
+ source: {
4
+ sha256: string;
5
+ mime: string;
6
+ kind: "image";
7
+ url?: string | undefined;
8
+ path?: string | undefined;
9
+ metadata?: Record<string, unknown> | undefined;
10
+ width?: number | undefined;
11
+ height?: number | undefined;
12
+ };
13
+ }, {
14
+ model: "google/gemini-3.1-flash-image-preview" | "google/gemini-3-pro-image-preview";
15
+ formats: ("1:1" | "16:9" | "9:16" | "2:3" | "3:4" | "4:5" | "3:2" | "4:3" | "5:4" | "21:9")[];
16
+ guidance?: string | undefined;
17
+ image_size?: "1K" | "2K" | "4K" | "0.5K" | undefined;
18
+ }, {
19
+ images: {
20
+ sha256: string;
21
+ mime: string;
22
+ kind: "image";
23
+ url?: string | undefined;
24
+ path?: string | undefined;
25
+ metadata?: Record<string, unknown> | undefined;
26
+ width?: number | undefined;
27
+ height?: number | undefined;
28
+ }[];
29
+ }>;
30
+ //# sourceMappingURL=imageAspectAdapt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageAspectAdapt.d.ts","sourceRoot":"","sources":["../../../../src/engine/nodes/remote/imageAspectAdapt.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoB/B,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ import { ImageRef } from "../../schema/refs.js";
3
+ import { delegated } from "./delegate.js";
4
+ const ASPECT_ADAPT_MODELS = ["google/gemini-3-pro-image-preview", "google/gemini-3.1-flash-image-preview"];
5
+ // Ad-format ratios only — shared by both models. The extreme banner ratios
6
+ // (1:8, 8:1…) are deliberately excluded: this node adapts ad creatives, and
7
+ // the registry cannot gate array elements per model.
8
+ const ASPECT_ADAPT_FORMATS = ["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"];
9
+ // The adaptation prompt is baked into the backend handler (consistency-first,
10
+ // direction-aware recomposition); `guidance` appends hints, never replaces it.
11
+ const ImageAspectAdaptParams = z
12
+ .object({
13
+ model: z.enum(ASPECT_ADAPT_MODELS),
14
+ formats: z
15
+ .array(z.enum(ASPECT_ADAPT_FORMATS))
16
+ .min(1)
17
+ .max(6)
18
+ .refine((formats) => new Set(formats).size === formats.length, { message: "formats must be unique" }),
19
+ guidance: z.string().min(1).optional(),
20
+ image_size: z.enum(["0.5K", "1K", "2K", "4K"]).optional(),
21
+ })
22
+ .strict();
23
+ export const imageAspectAdaptNode = delegated({
24
+ id: "image_aspect_adapt",
25
+ version: "1.0.0",
26
+ category: "image",
27
+ summary: "Adapt ONE creative into multiple aspect ratios (Meta: 9:16 stories, 1:1 feed, 4:5, 16:9…) in a single step. AI recomposes the layout per format — identical subject, text, logos, colors, and style; the scene is extended/restructured, never stretched or cropped. Formats that already match the source ratio pass through unchanged at zero cost. Outputs are ordered exactly as `formats`.",
28
+ when_to_use: "Use after a hero creative exists (image_generate, ingest, image_search) to fan it out to every placement format — wire the creative into `source` and list the target ratios in `formats`. Cost is estimated per format; formats matching the source ratio are free pass-throughs. Pick `google/gemini-3.1-flash-image-preview` (Nano Banana flash) while iterating, `google/gemini-3-pro-image-preview` (Nano Banana Pro) for final-quality adaptation.",
29
+ inputs: z.object({ source: ImageRef }).loose(),
30
+ params: ImageAspectAdaptParams,
31
+ outputs: z.object({ images: z.array(ImageRef).min(1) }).strict(),
32
+ outputKinds: { images: "image" },
33
+ cost: ({ params }) => {
34
+ const p = params;
35
+ const count = Array.isArray(p?.formats) ? p.formats.length : 1;
36
+ return {
37
+ credits: count * (p?.model === "google/gemini-3-pro-image-preview" ? 20 : 5),
38
+ seconds_estimate: 30 + 30 * count,
39
+ };
40
+ },
41
+ });
42
+ //# sourceMappingURL=imageAspectAdapt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageAspectAdapt.js","sourceRoot":"","sources":["../../../../src/engine/nodes/remote/imageAspectAdapt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,mBAAmB,GAAG,CAAC,mCAAmC,EAAE,uCAAuC,CAAU,CAAC;AAEpH,2EAA2E;AAC3E,4EAA4E;AAC5E,qDAAqD;AACrD,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAEhH,8EAA8E;AAC9E,+EAA+E;AAC/E,MAAM,sBAAsB,GAAG,CAAC;KAC7B,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;IAClC,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;SACnC,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACvG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACtC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC1D,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;IAC5C,EAAE,EAAE,oBAAoB;IACxB,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,OAAO;IACjB,OAAO,EACL,iYAAiY;IACnY,WAAW,EACT,0bAA0b;IAC5b,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE;IAC9C,MAAM,EAAE,sBAAsB;IAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IAChE,WAAW,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;IAChC,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,CAAC,GAAG,MAA6D,CAAC;QACxE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,OAAO;YACL,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,KAAK,mCAAmC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5E,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,KAAK;SAClC,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}