@aglyn/plugins-ai 1.0.0-beta.229 → 1.0.0-beta.231

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 (340) hide show
  1. package/README.md +3 -3
  2. package/package.json +17 -17
  3. package/src/lib/activity/ai-activity-actions.js +7 -1
  4. package/src/lib/activity/ai-activity-actions.js.map +1 -1
  5. package/src/lib/components/ai-assist-provider-on-host.component.d.ts +66 -0
  6. package/src/lib/components/ai-assist-provider-on-host.component.js +78 -0
  7. package/src/lib/components/ai-assist-provider-on-host.component.js.map +1 -0
  8. package/src/lib/components/ai-assist-provider.component.js +9 -10
  9. package/src/lib/components/ai-assist-provider.component.js.map +1 -1
  10. package/src/lib/components/ai-automation-zones.d.ts +38 -0
  11. package/src/lib/components/ai-automation-zones.js +5 -1
  12. package/src/lib/components/ai-automation-zones.js.map +1 -1
  13. package/src/lib/components/ai-brief-dialog.component.d.ts +20 -2
  14. package/src/lib/components/ai-brief-dialog.component.js +87 -8
  15. package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
  16. package/src/lib/components/ai-campaign-create.component.d.ts +54 -0
  17. package/src/lib/components/ai-campaign-create.component.js +270 -0
  18. package/src/lib/components/ai-campaign-create.component.js.map +1 -0
  19. package/src/lib/components/ai-describe-automation.component.d.ts +8 -3
  20. package/src/lib/components/ai-describe-automation.component.js +15 -6
  21. package/src/lib/components/ai-describe-automation.component.js.map +1 -1
  22. package/src/lib/components/ai-describe-button.component.d.ts +20 -8
  23. package/src/lib/components/ai-describe-button.component.js +19 -36
  24. package/src/lib/components/ai-describe-button.component.js.map +1 -1
  25. package/src/lib/components/ai-describe-email.component.d.ts +31 -0
  26. package/src/lib/components/ai-describe-email.component.js +22 -0
  27. package/src/lib/components/ai-describe-email.component.js.map +1 -0
  28. package/src/lib/components/ai-describe-org-automation.component.d.ts +36 -0
  29. package/src/lib/components/ai-describe-org-automation.component.js +238 -0
  30. package/src/lib/components/ai-describe-org-automation.component.js.map +1 -0
  31. package/src/lib/components/ai-experiment-cards.component.d.ts +9 -1
  32. package/src/lib/components/ai-experiment-cards.component.js +104 -18
  33. package/src/lib/components/ai-experiment-cards.component.js.map +1 -1
  34. package/src/lib/components/ai-explain-automation.component.js +1 -5
  35. package/src/lib/components/ai-explain-automation.component.js.map +1 -1
  36. package/src/lib/components/ai-funnel-zones.component.d.ts +61 -0
  37. package/src/lib/components/ai-funnel-zones.component.js +178 -0
  38. package/src/lib/components/ai-funnel-zones.component.js.map +1 -0
  39. package/src/lib/components/ai-insight-card.component.d.ts +42 -0
  40. package/src/lib/components/ai-insight-card.component.js +137 -0
  41. package/src/lib/components/ai-insight-card.component.js.map +1 -0
  42. package/src/lib/components/ai-insight-dialog.component.d.ts +6 -0
  43. package/src/lib/components/ai-insight-dialog.component.js +9 -3
  44. package/src/lib/components/ai-insight-dialog.component.js.map +1 -1
  45. package/src/lib/components/ai-job-plan.component.d.ts +7 -2
  46. package/src/lib/components/ai-job-plan.component.js +38 -6
  47. package/src/lib/components/ai-job-plan.component.js.map +1 -1
  48. package/src/lib/components/ai-job-requests.d.ts +17 -1
  49. package/src/lib/components/ai-job-requests.js +39 -3
  50. package/src/lib/components/ai-job-requests.js.map +1 -1
  51. package/src/lib/components/ai-logic-zones.d.ts +64 -0
  52. package/src/lib/components/ai-logic-zones.js +18 -0
  53. package/src/lib/components/ai-logic-zones.js.map +1 -0
  54. package/src/lib/components/ai-logic.component.d.ts +77 -0
  55. package/src/lib/components/ai-logic.component.js +553 -0
  56. package/src/lib/components/ai-logic.component.js.map +1 -0
  57. package/src/lib/components/ai-marketing-insight.component.d.ts +30 -0
  58. package/src/lib/components/ai-marketing-insight.component.js +80 -0
  59. package/src/lib/components/ai-marketing-insight.component.js.map +1 -0
  60. package/src/lib/components/ai-media-create.component.d.ts +55 -0
  61. package/src/lib/components/ai-media-create.component.js +433 -0
  62. package/src/lib/components/ai-media-create.component.js.map +1 -0
  63. package/src/lib/components/ai-overlay-cards.component.d.ts +83 -0
  64. package/src/lib/components/ai-overlay-cards.component.js +505 -0
  65. package/src/lib/components/ai-overlay-cards.component.js.map +1 -0
  66. package/src/lib/components/ai-permissions-on-host.component.d.ts +3 -46
  67. package/src/lib/components/ai-permissions-on-host.component.js +5 -53
  68. package/src/lib/components/ai-permissions-on-host.component.js.map +1 -1
  69. package/src/lib/components/ai-product-zones.d.ts +5 -0
  70. package/src/lib/components/ai-product-zones.js +1 -1
  71. package/src/lib/components/ai-product-zones.js.map +1 -1
  72. package/src/lib/components/ai-products-create-button.component.d.ts +42 -0
  73. package/src/lib/components/ai-products-create-button.component.js +67 -0
  74. package/src/lib/components/ai-products-create-button.component.js.map +1 -0
  75. package/src/lib/components/ai-products-hub-card.component.js +100 -81
  76. package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
  77. package/src/lib/components/ai-revise-automation.component.d.ts +16 -0
  78. package/src/lib/components/ai-revise-automation.component.js +207 -0
  79. package/src/lib/components/ai-revise-automation.component.js.map +1 -0
  80. package/src/lib/components/ai-site-build-page.component.js +160 -24
  81. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  82. package/src/lib/components/ai-upsell-dialog.component.d.ts +53 -0
  83. package/src/lib/components/ai-upsell-dialog.component.js +177 -0
  84. package/src/lib/components/ai-upsell-dialog.component.js.map +1 -0
  85. package/src/lib/components/assist-build-card.component.d.ts +42 -0
  86. package/src/lib/components/assist-build-card.component.js +183 -0
  87. package/src/lib/components/assist-build-card.component.js.map +1 -0
  88. package/src/lib/components/assist-edit-canvas.d.ts +2 -0
  89. package/src/lib/components/assist-edit-canvas.js +56 -1
  90. package/src/lib/components/assist-edit-canvas.js.map +1 -1
  91. package/src/lib/components/assist-jobs-drawer.component.js +48 -3
  92. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
  93. package/src/lib/components/assist-panel.component.js +51 -2
  94. package/src/lib/components/assist-panel.component.js.map +1 -1
  95. package/src/lib/components/use-ai-job-run.d.ts +3 -14
  96. package/src/lib/components/use-ai-job-run.js +0 -50
  97. package/src/lib/components/use-ai-job-run.js.map +1 -1
  98. package/src/lib/jobs/ai-build-capabilities.d.ts +58 -0
  99. package/src/lib/jobs/ai-build-capabilities.js +256 -0
  100. package/src/lib/jobs/ai-build-capabilities.js.map +1 -0
  101. package/src/lib/jobs/ai-build-unit-outcome.d.ts +52 -0
  102. package/src/lib/jobs/ai-build-unit-outcome.js +140 -0
  103. package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -0
  104. package/src/lib/jobs/ai-job-auto-confirm.d.ts +8 -0
  105. package/src/lib/jobs/ai-job-auto-confirm.js +30 -6
  106. package/src/lib/jobs/ai-job-auto-confirm.js.map +1 -1
  107. package/src/lib/jobs/ai-job-build-step.d.ts +144 -0
  108. package/src/lib/jobs/ai-job-build-step.js +668 -0
  109. package/src/lib/jobs/ai-job-build-step.js.map +1 -0
  110. package/src/lib/jobs/ai-job-draft-ids.js +9 -1
  111. package/src/lib/jobs/ai-job-draft-ids.js.map +1 -1
  112. package/src/lib/jobs/ai-job-drafts.d.ts +14 -4
  113. package/src/lib/jobs/ai-job-drafts.js +25 -4
  114. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  115. package/src/lib/jobs/ai-job-generation.d.ts +8 -0
  116. package/src/lib/jobs/ai-job-generation.js +13 -2
  117. package/src/lib/jobs/ai-job-generation.js.map +1 -1
  118. package/src/lib/jobs/ai-job-insight-step.js +8 -1
  119. package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
  120. package/src/lib/jobs/ai-job-layout-language.d.ts +73 -0
  121. package/src/lib/jobs/ai-job-layout-language.js +194 -0
  122. package/src/lib/jobs/ai-job-layout-language.js.map +1 -0
  123. package/src/lib/jobs/ai-job-layout-site-pages.d.ts +13 -2
  124. package/src/lib/jobs/ai-job-layout-site-pages.js +18 -2
  125. package/src/lib/jobs/ai-job-layout-site-pages.js.map +1 -1
  126. package/src/lib/jobs/ai-job-layout-step.d.ts +5 -0
  127. package/src/lib/jobs/ai-job-layout-step.js +105 -5
  128. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  129. package/src/lib/jobs/ai-job-logic-step.d.ts +107 -0
  130. package/src/lib/jobs/ai-job-logic-step.js +395 -0
  131. package/src/lib/jobs/ai-job-logic-step.js.map +1 -0
  132. package/src/lib/jobs/ai-job-overlay-copy.d.ts +70 -0
  133. package/src/lib/jobs/ai-job-overlay-copy.js +178 -0
  134. package/src/lib/jobs/ai-job-overlay-copy.js.map +1 -0
  135. package/src/lib/jobs/ai-job-page-language.d.ts +149 -0
  136. package/src/lib/jobs/ai-job-page-language.js +355 -0
  137. package/src/lib/jobs/ai-job-page-language.js.map +1 -0
  138. package/src/lib/jobs/ai-job-page-sections.d.ts +37 -1
  139. package/src/lib/jobs/ai-job-page-sections.js +93 -11
  140. package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
  141. package/src/lib/jobs/ai-job-page-step.d.ts +4 -4
  142. package/src/lib/jobs/ai-job-page-step.js +111 -20
  143. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  144. package/src/lib/jobs/ai-job-plan-step.d.ts +27 -2
  145. package/src/lib/jobs/ai-job-plan-step.js +87 -13
  146. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  147. package/src/lib/jobs/ai-job-site-step.d.ts +19 -1
  148. package/src/lib/jobs/ai-job-site-step.js +220 -61
  149. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  150. package/src/lib/jobs/ai-job-text-step.d.ts +22 -1
  151. package/src/lib/jobs/ai-job-text-step.js +12 -0
  152. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  153. package/src/lib/jobs/ai-job-workflow-step.d.ts +54 -4
  154. package/src/lib/jobs/ai-job-workflow-step.js +320 -15
  155. package/src/lib/jobs/ai-job-workflow-step.js.map +1 -1
  156. package/src/lib/jobs/ai-jobs.d.ts +80 -2
  157. package/src/lib/jobs/ai-jobs.js +391 -18
  158. package/src/lib/jobs/ai-jobs.js.map +1 -1
  159. package/src/lib/jobs/ai-layout-full-height.d.ts +40 -0
  160. package/src/lib/jobs/ai-layout-full-height.js +82 -0
  161. package/src/lib/jobs/ai-layout-full-height.js.map +1 -0
  162. package/src/lib/jobs/ai-layout-site-facts.d.ts +54 -0
  163. package/src/lib/jobs/ai-layout-site-facts.js +153 -0
  164. package/src/lib/jobs/ai-layout-site-facts.js.map +1 -0
  165. package/src/lib/jobs/ai-logic-records.d.ts +40 -0
  166. package/src/lib/jobs/ai-logic-records.js +55 -0
  167. package/src/lib/jobs/ai-logic-records.js.map +1 -0
  168. package/src/lib/jobs/ai-site-publish.d.ts +7 -0
  169. package/src/lib/jobs/ai-site-publish.js +9 -0
  170. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  171. package/src/lib/jobs/ai-workflow-records.d.ts +4 -0
  172. package/src/lib/jobs/ai-workflow-records.js +40 -1
  173. package/src/lib/jobs/ai-workflow-records.js.map +1 -1
  174. package/src/lib/layout-language/ai-layout-compiler.d.ts +145 -0
  175. package/src/lib/layout-language/ai-layout-compiler.js +1148 -0
  176. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -0
  177. package/src/lib/layout-language/ai-layout-copy.d.ts +73 -0
  178. package/src/lib/layout-language/ai-layout-copy.js +137 -0
  179. package/src/lib/layout-language/ai-layout-copy.js.map +1 -0
  180. package/src/lib/layout-language/ai-layout-frame.d.ts +52 -0
  181. package/src/lib/layout-language/ai-layout-frame.js +457 -0
  182. package/src/lib/layout-language/ai-layout-frame.js.map +1 -0
  183. package/src/lib/layout-language/ai-layout-gaps.d.ts +63 -0
  184. package/src/lib/layout-language/ai-layout-gaps.js +345 -0
  185. package/src/lib/layout-language/ai-layout-gaps.js.map +1 -0
  186. package/src/lib/layout-language/ai-layout-language.d.ts +161 -0
  187. package/src/lib/layout-language/ai-layout-language.js +446 -0
  188. package/src/lib/layout-language/ai-layout-language.js.map +1 -0
  189. package/src/lib/layout-language/ai-layout-links.d.ts +80 -0
  190. package/src/lib/layout-language/ai-layout-links.js +109 -0
  191. package/src/lib/layout-language/ai-layout-links.js.map +1 -0
  192. package/src/lib/layout-language/ai-layout-store.d.ts +39 -0
  193. package/src/lib/layout-language/ai-layout-store.js +69 -0
  194. package/src/lib/layout-language/ai-layout-store.js.map +1 -0
  195. package/src/lib/layout-language/ai-layout-tree.d.ts +59 -0
  196. package/src/lib/layout-language/ai-layout-tree.js +84 -0
  197. package/src/lib/layout-language/ai-layout-tree.js.map +1 -0
  198. package/src/lib/lazy-widget.d.ts +45 -0
  199. package/src/lib/lazy-widget.js +53 -0
  200. package/src/lib/lazy-widget.js.map +1 -0
  201. package/src/lib/model/ai-automation-draft.d.ts +18 -0
  202. package/src/lib/model/ai-automation-draft.js +86 -0
  203. package/src/lib/model/ai-automation-draft.js.map +1 -1
  204. package/src/lib/model/ai-build-job.d.ts +201 -0
  205. package/src/lib/model/ai-build-job.js +472 -0
  206. package/src/lib/model/ai-build-job.js.map +1 -0
  207. package/src/lib/model/ai-build-plan.d.ts +61 -0
  208. package/src/lib/model/ai-build-plan.js +154 -9
  209. package/src/lib/model/ai-build-plan.js.map +1 -1
  210. package/src/lib/model/ai-build-progress.d.ts +73 -0
  211. package/src/lib/model/ai-build-progress.js +170 -0
  212. package/src/lib/model/ai-build-progress.js.map +1 -0
  213. package/src/lib/model/ai-host-publish-context.d.ts +51 -0
  214. package/src/lib/model/ai-host-publish-context.js +104 -0
  215. package/src/lib/model/ai-host-publish-context.js.map +1 -0
  216. package/src/lib/model/ai-insight.d.ts +20 -10
  217. package/src/lib/model/ai-insight.js +72 -9
  218. package/src/lib/model/ai-insight.js.map +1 -1
  219. package/src/lib/model/ai-job-activity.d.ts +22 -0
  220. package/src/lib/model/ai-job-activity.js +25 -2
  221. package/src/lib/model/ai-job-activity.js.map +1 -1
  222. package/src/lib/model/ai-job-failure-copy.d.ts +38 -1
  223. package/src/lib/model/ai-job-failure-copy.js +56 -1
  224. package/src/lib/model/ai-job-failure-copy.js.map +1 -1
  225. package/src/lib/model/ai-job-notice.d.ts +3 -1
  226. package/src/lib/model/ai-job-notice.js +31 -9
  227. package/src/lib/model/ai-job-notice.js.map +1 -1
  228. package/src/lib/model/ai-jobs.types.d.ts +99 -2
  229. package/src/lib/model/ai-jobs.types.js +3 -1
  230. package/src/lib/model/ai-jobs.types.js.map +1 -1
  231. package/src/lib/model/ai-logic-job.d.ts +108 -0
  232. package/src/lib/model/ai-logic-job.js +327 -0
  233. package/src/lib/model/ai-logic-job.js.map +1 -0
  234. package/src/lib/model/ai-media-credits.d.ts +52 -0
  235. package/src/lib/model/ai-media-credits.js +61 -0
  236. package/src/lib/model/ai-media-credits.js.map +1 -0
  237. package/src/lib/model/ai-overlay-copy.d.ts +114 -0
  238. package/src/lib/model/ai-overlay-copy.js +175 -0
  239. package/src/lib/model/ai-overlay-copy.js.map +1 -0
  240. package/src/lib/model/ai-site-build-progress.d.ts +25 -4
  241. package/src/lib/model/ai-site-build-progress.js +194 -11
  242. package/src/lib/model/ai-site-build-progress.js.map +1 -1
  243. package/src/lib/model/ai-site-job.d.ts +8 -0
  244. package/src/lib/model/ai-site-job.js +9 -0
  245. package/src/lib/model/ai-site-job.js.map +1 -1
  246. package/src/lib/model/ai-site-start-seo.d.ts +1 -1
  247. package/src/lib/model/ai-site-start.d.ts +5 -2
  248. package/src/lib/model/ai-site-start.js +5 -2
  249. package/src/lib/model/ai-site-start.js.map +1 -1
  250. package/src/lib/model/ai-svg.d.ts +69 -0
  251. package/src/lib/model/ai-svg.js +265 -0
  252. package/src/lib/model/ai-svg.js.map +1 -0
  253. package/src/lib/model/ai-usage-by-user.d.ts +3 -2
  254. package/src/lib/model/ai-usage-by-user.js.map +1 -1
  255. package/src/lib/model/ai-workflow-job.d.ts +92 -4
  256. package/src/lib/model/ai-workflow-job.js +124 -7
  257. package/src/lib/model/ai-workflow-job.js.map +1 -1
  258. package/src/lib/model/assist-build.d.ts +58 -0
  259. package/src/lib/model/assist-build.js +52 -0
  260. package/src/lib/model/assist-build.js.map +1 -0
  261. package/src/lib/model/assist-edit.d.ts +48 -3
  262. package/src/lib/model/assist-edit.js +48 -4
  263. package/src/lib/model/assist-edit.js.map +1 -1
  264. package/src/lib/plugin-config.js +2 -0
  265. package/src/lib/plugin-config.js.map +1 -1
  266. package/src/lib/plugin.js +308 -47
  267. package/src/lib/plugin.js.map +1 -1
  268. package/src/lib/providers/catalog.d.ts +82 -5
  269. package/src/lib/providers/catalog.js +83 -12
  270. package/src/lib/providers/catalog.js.map +1 -1
  271. package/src/lib/providers/image-contract.d.ts +116 -0
  272. package/src/lib/providers/image-contract.js +74 -0
  273. package/src/lib/providers/image-contract.js.map +1 -0
  274. package/src/lib/providers/model-choice.js +11 -0
  275. package/src/lib/providers/model-choice.js.map +1 -1
  276. package/src/lib/providers/routing.js +18 -0
  277. package/src/lib/providers/routing.js.map +1 -1
  278. package/src/lib/providers/vertex-image.d.ts +121 -0
  279. package/src/lib/providers/vertex-image.js +312 -0
  280. package/src/lib/providers/vertex-image.js.map +1 -0
  281. package/src/lib/runtime/ai-doctrine-validators.d.ts +101 -0
  282. package/src/lib/runtime/ai-doctrine-validators.js +525 -4
  283. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  284. package/src/lib/runtime/ai-doctrine.js +21 -6
  285. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  286. package/src/lib/runtime/ai-eval-live.js +4 -0
  287. package/src/lib/runtime/ai-eval-live.js.map +1 -1
  288. package/src/lib/runtime/ai-eval.d.ts +15 -1
  289. package/src/lib/runtime/ai-eval.js +52 -1
  290. package/src/lib/runtime/ai-eval.js.map +1 -1
  291. package/src/lib/runtime/ai-icon-library.d.ts +257 -0
  292. package/src/lib/runtime/ai-icon-library.js +254 -0
  293. package/src/lib/runtime/ai-icon-library.js.map +1 -0
  294. package/src/lib/runtime/ai-node-tree.d.ts +9 -0
  295. package/src/lib/runtime/ai-node-tree.js +30 -4
  296. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  297. package/src/lib/runtime/ai-palette.d.ts +6 -0
  298. package/src/lib/runtime/ai-palette.generated.js +70 -0
  299. package/src/lib/runtime/ai-palette.generated.js.map +1 -1
  300. package/src/lib/runtime/ai-palette.js.map +1 -1
  301. package/src/lib/runtime/experiment-variant-copy.d.ts +34 -0
  302. package/src/lib/runtime/experiment-variant-copy.js +102 -0
  303. package/src/lib/runtime/experiment-variant-copy.js.map +1 -0
  304. package/src/lib/server/ai-experiment-versions.d.ts +51 -0
  305. package/src/lib/server/ai-experiment-versions.js +270 -0
  306. package/src/lib/server/ai-experiment-versions.js.map +1 -0
  307. package/src/lib/server/ai-jobs-resume.js +74 -4
  308. package/src/lib/server/ai-jobs-resume.js.map +1 -1
  309. package/src/lib/server/ai-media-image.d.ts +66 -0
  310. package/src/lib/server/ai-media-image.js +521 -0
  311. package/src/lib/server/ai-media-image.js.map +1 -0
  312. package/src/lib/server/ai-media-svg.d.ts +91 -0
  313. package/src/lib/server/ai-media-svg.js +186 -0
  314. package/src/lib/server/ai-media-svg.js.map +1 -0
  315. package/src/lib/server/assist-build.d.ts +54 -0
  316. package/src/lib/server/assist-build.js +121 -0
  317. package/src/lib/server/assist-build.js.map +1 -0
  318. package/src/lib/server/assist-chat.js +108 -12
  319. package/src/lib/server/assist-chat.js.map +1 -1
  320. package/src/lib/server/assist-edit.js +213 -3
  321. package/src/lib/server/assist-edit.js.map +1 -1
  322. package/src/lib/server/assist-view-context.js +242 -4
  323. package/src/lib/server/assist-view-context.js.map +1 -1
  324. package/src/lib/server.js +26 -0
  325. package/src/lib/server.js.map +1 -1
  326. package/src/lib/tools/ai-logic-tool.d.ts +27 -0
  327. package/src/lib/tools/ai-logic-tool.js +207 -0
  328. package/src/lib/tools/ai-logic-tool.js.map +1 -0
  329. package/src/lib/tools/ai-overlay-tool.d.ts +35 -0
  330. package/src/lib/tools/ai-overlay-tool.js +107 -0
  331. package/src/lib/tools/ai-overlay-tool.js.map +1 -0
  332. package/src/lib/tools/ai-workflow-tool.d.ts +17 -2
  333. package/src/lib/tools/ai-workflow-tool.js +47 -14
  334. package/src/lib/tools/ai-workflow-tool.js.map +1 -1
  335. package/src/lib/usage/assist-job-refund.d.ts +28 -1
  336. package/src/lib/usage/assist-job-refund.js +44 -9
  337. package/src/lib/usage/assist-job-refund.js.map +1 -1
  338. package/src/lib/usage/assist-usage.d.ts +5 -0
  339. package/src/lib/usage/assist-usage.js +2 -0
  340. package/src/lib/usage/assist-usage.js.map +1 -1
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { ConsoleHostScreensZoneProps } from '@aglyn/aglyn/plugin-manager/feature-plugins';
18
+ /**
19
+ * "Create with AI" for email (AGL-3596): the same button and dialog as a
20
+ * page's, a form's or a template's, beside New template on the email
21
+ * plugin's `hostEmailTemplates` zone (the `hostScreens` contract: the site
22
+ * and its org). The Campaigns section's door is a widget of its own
23
+ * (`ai-campaign-create.component`), on the marketing plugin's `hostCampaigns`.
24
+ */
25
+ /**
26
+ * An email design from a brief, on a site's email templates
27
+ * (`hostEmailTemplates`). Its dialog also offers to draft the campaign that
28
+ * would send it.
29
+ */
30
+ export declare function AiDescribeEmailButton(props: ConsoleHostScreensZoneProps): import("react").JSX.Element;
31
+ export default AiDescribeEmailButton;
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+ import { _ as _extends } from "@swc/helpers/_/_extends";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ import { AiDescribeButton } from "./ai-describe-button.component.js";
5
+ /**
6
+ * "Create with AI" for email (AGL-3596): the same button and dialog as a
7
+ * page's, a form's or a template's, beside New template on the email
8
+ * plugin's `hostEmailTemplates` zone (the `hostScreens` contract: the site
9
+ * and its org). The Campaigns section's door is a widget of its own
10
+ * (`ai-campaign-create.component`), on the marketing plugin's `hostCampaigns`.
11
+ */ /**
12
+ * An email design from a brief, on a site's email templates
13
+ * (`hostEmailTemplates`). Its dialog also offers to draft the campaign that
14
+ * would send it.
15
+ */ export function AiDescribeEmailButton(props) {
16
+ return /*#__PURE__*/ _jsx(AiDescribeButton, _extends({}, props, {
17
+ kind: "email"
18
+ }));
19
+ }
20
+ export default AiDescribeEmailButton;
21
+
22
+ //# sourceMappingURL=ai-describe-email.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-describe-email.component.tsx"],"sourcesContent":["'use client'\n\n/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConsoleHostScreensZoneProps } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { AiDescribeButton } from './ai-describe-button.component'\n\n/**\n * \"Create with AI\" for email (AGL-3596): the same button and dialog as a\n * page's, a form's or a template's, beside New template on the email\n * plugin's `hostEmailTemplates` zone (the `hostScreens` contract: the site\n * and its org). The Campaigns section's door is a widget of its own\n * (`ai-campaign-create.component`), on the marketing plugin's `hostCampaigns`.\n */\n\n/**\n * An email design from a brief, on a site's email templates\n * (`hostEmailTemplates`). Its dialog also offers to draft the campaign that\n * would send it.\n */\nexport function AiDescribeEmailButton(props: ConsoleHostScreensZoneProps) {\n return <AiDescribeButton {...props} kind=\"email\" />\n}\n\nexport default AiDescribeEmailButton\n"],"names":["AiDescribeButton","AiDescribeEmailButton","props","kind"],"mappings":"AAAA;;;AAoBA,SAASA,gBAAgB,QAAQ,oCAAgC;AAEjE;;;;;;CAMC,GAED;;;;CAIC,GACD,OAAO,SAASC,sBAAsBC,KAAkC;IACtE,qBAAO,KAACF,+BAAqBE;QAAOC,MAAK;;AAC3C;AAEA,eAAeF,sBAAqB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { ConsoleWidgetEntitlementProps } from '@aglyn/aglyn/plugin-manager/feature-plugins';
18
+ import type { ConsoleOrgAutomationsZoneProps } from './ai-automation-zones';
19
+ export declare const AI_ORG_AUTOMATION_COPY: {
20
+ readonly create: "Create with AI";
21
+ readonly title: "Describe an org automation";
22
+ readonly label: "What should happen, and when?";
23
+ readonly placeholder: "When someone books on any of our sites, make them a contact, tag them booked and send them a welcome email";
24
+ readonly next: "It is drafted from what an org automation can start on and do, and opens in the editor switched off, where you choose its sites and save it. Lists, campaigns or datasets your workspace does not have are left for you to pick.";
25
+ readonly submit: "Draft the automation";
26
+ readonly running: "Drafting it. This can take a few minutes.";
27
+ readonly ready: "Drafted";
28
+ readonly open: "Open in the editor";
29
+ readonly notOpened: "It could not be opened in the editor. Check the page for why, then try again.";
30
+ readonly failed: "The automation could not be drafted. Try again.";
31
+ };
32
+ export declare function AiDescribeOrgAutomationButton({ orgId, triggers, steps, propose, entitled, upgrade, }: ConsoleOrgAutomationsZoneProps & ConsoleWidgetEntitlementProps): import("react").JSX.Element;
33
+ export declare namespace AiDescribeOrgAutomationButton {
34
+ var displayName: string;
35
+ }
36
+ export default AiDescribeOrgAutomationButton;
@@ -0,0 +1,238 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { pluginDocsHelp } from "@aglyn/aglyn/app-utils/docs-help";
4
+ import { mdiCreation } from "@aglyn/shared-data-mdi";
5
+ import { MdiIcon } from "@aglyn/shared-ui-jsx";
6
+ import { useUser } from "@aglyn/tenant-feature-instance";
7
+ import { Alert, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, Link, Stack, TextField, Typography } from "@mui/material";
8
+ import { useEffect, useState } from "react";
9
+ import { AI_ORG_AUTOMATION_RESOURCE, aiOrgAutomationInputs, readAiOrgAutomationProposal } from "../model/ai-workflow-job.js";
10
+ import { openAiJobs } from "./ai-jobs-store.js";
11
+ import { AiUpsellButton } from "./ai-upsell-dialog.component.js";
12
+ import { aiJobProblem, useAiJobRun } from "./use-ai-job-run.js";
13
+ /**
14
+ * "Create with AI" on the workspace's Org automations (AGL-3603), in that
15
+ * section's card header through the `orgAutomations` zone: a description
16
+ * becomes a `workflow` job drafting one of the WORKSPACE's automations, held
17
+ * to the triggers and steps the zone says an org automation may use.
18
+ *
19
+ * Nothing is written. The job's proposal opens in the section's editor as a
20
+ * new automation, unsaved and switched off; the person picks the sites it
21
+ * runs on and saves it with the editor's own Save, through the section's
22
+ * route — or closes the editor, and nothing changes.
23
+ */ const BRIEF_MAX_CHARS = 4000;
24
+ export const AI_ORG_AUTOMATION_COPY = {
25
+ create: 'Create with AI',
26
+ title: 'Describe an org automation',
27
+ label: 'What should happen, and when?',
28
+ placeholder: 'When someone books on any of our sites, make them a contact, tag them booked and send them a welcome email',
29
+ next: 'It is drafted from what an org automation can start on and do, and opens in the editor switched off, where you choose its sites and save it. Lists, campaigns or datasets your workspace does not have are left for you to pick.',
30
+ submit: 'Draft the automation',
31
+ running: 'Drafting it. This can take a few minutes.',
32
+ ready: 'Drafted',
33
+ open: 'Open in the editor',
34
+ notOpened: 'It could not be opened in the editor. Check the page for why, then try again.',
35
+ failed: 'The automation could not be drafted. Try again.'
36
+ };
37
+ /** The proposal a finished job wrote, with what to decide, or `null`. */ function proposalOf(job) {
38
+ var _output_note;
39
+ if ((job == null ? void 0 : job.status) !== 'done') return null;
40
+ const output = job.outputs.find((one)=>one.resource === AI_ORG_AUTOMATION_RESOURCE);
41
+ const automation = readAiOrgAutomationProposal(output == null ? void 0 : output.proposal);
42
+ return automation && output ? {
43
+ automation,
44
+ label: output.label,
45
+ note: (_output_note = output.note) != null ? _output_note : null
46
+ } : null;
47
+ }
48
+ export function AiDescribeOrgAutomationButton({ orgId, triggers, steps, propose, entitled, upgrade }) {
49
+ var _aiJobProblem;
50
+ const copy = AI_ORG_AUTOMATION_COPY;
51
+ const help = pluginDocsHelp('aiAutomations', {
52
+ anchor: '#org-automations'
53
+ });
54
+ const { data: user } = useUser();
55
+ const run = useAiJobRun(user, copy.failed);
56
+ const { job, starting, running, notice, reset } = run;
57
+ const [open, setOpen] = useState(false);
58
+ const [brief, setBrief] = useState('');
59
+ const [notOpened, setNotOpened] = useState(false);
60
+ // Opening or closing starts over and stops following: a job still drafting
61
+ // carries on in AI jobs.
62
+ useEffect(()=>{
63
+ reset();
64
+ setNotOpened(false);
65
+ }, [
66
+ open,
67
+ reset
68
+ ]);
69
+ // Drawn from the shell's gates alone (AGL-3601): nothing asks a server
70
+ // until it is used, and a plan without the add-on gets the add-on's dialog.
71
+ if (entitled === false) return upgrade ? /*#__PURE__*/ _jsx(AiUpsellButton, {
72
+ kind: "workflow",
73
+ upgrade: upgrade
74
+ }) : null;
75
+ const ready = proposalOf(job);
76
+ const problem = (_aiJobProblem = aiJobProblem(job, copy.failed)) != null ? _aiJobProblem : (job == null ? void 0 : job.status) === 'done' && !ready ? copy.failed : null;
77
+ const asking = !job || Boolean(notice);
78
+ const close = ()=>setOpen(false);
79
+ const start = async ()=>{
80
+ const trimmed = brief.trim();
81
+ if (!orgId || !trimmed) return;
82
+ setNotOpened(false);
83
+ const inputs = aiOrgAutomationInputs({
84
+ triggers,
85
+ steps
86
+ });
87
+ if (await run.start({
88
+ orgId,
89
+ hostId: null,
90
+ kind: 'workflow',
91
+ brief: trimmed,
92
+ inputs
93
+ })) setBrief('');
94
+ };
95
+ const apply = ()=>{
96
+ if (!ready) return;
97
+ if (propose(ready.automation)) close();
98
+ else setNotOpened(true);
99
+ };
100
+ return /*#__PURE__*/ _jsxs(_Fragment, {
101
+ children: [
102
+ /*#__PURE__*/ _jsx(Button, {
103
+ size: "small",
104
+ variant: "outlined",
105
+ startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
106
+ path: mdiCreation.path
107
+ }),
108
+ onClick: ()=>setOpen(true),
109
+ children: copy.create
110
+ }),
111
+ /*#__PURE__*/ _jsxs(Dialog, {
112
+ open: open,
113
+ onClose: starting ? undefined : close,
114
+ fullWidth: true,
115
+ maxWidth: "sm",
116
+ children: [
117
+ /*#__PURE__*/ _jsx(DialogTitle, {
118
+ children: copy.title
119
+ }),
120
+ /*#__PURE__*/ _jsx(DialogContent, {
121
+ children: asking ? /*#__PURE__*/ _jsxs(Stack, {
122
+ spacing: 2,
123
+ sx: {
124
+ pt: 1
125
+ },
126
+ children: [
127
+ /*#__PURE__*/ _jsx(TextField, {
128
+ label: copy.label,
129
+ placeholder: copy.placeholder,
130
+ multiline: true,
131
+ minRows: 4,
132
+ value: brief,
133
+ onChange: (event)=>setBrief(event.target.value.slice(0, BRIEF_MAX_CHARS)),
134
+ helperText: `${brief.length.toLocaleString('en-US')} / ${BRIEF_MAX_CHARS.toLocaleString('en-US')}`,
135
+ disabled: starting,
136
+ autoFocus: true
137
+ }),
138
+ /*#__PURE__*/ _jsxs(Typography, {
139
+ variant: "body2",
140
+ color: "text.secondary",
141
+ children: [
142
+ copy.next,
143
+ ' ',
144
+ /*#__PURE__*/ _jsx(Link, {
145
+ href: help.href,
146
+ target: "_blank",
147
+ rel: "noopener",
148
+ title: help.excerpt,
149
+ children: 'How it works'
150
+ })
151
+ ]
152
+ }),
153
+ notice ? /*#__PURE__*/ _jsx(Alert, {
154
+ severity: "warning",
155
+ children: notice
156
+ }) : null
157
+ ]
158
+ }) : /*#__PURE__*/ _jsxs(Stack, {
159
+ spacing: 2,
160
+ sx: {
161
+ pt: 1
162
+ },
163
+ children: [
164
+ running && job ? /*#__PURE__*/ _jsx(Alert, {
165
+ severity: "info",
166
+ icon: /*#__PURE__*/ _jsx(CircularProgress, {
167
+ size: 18,
168
+ "aria-label": "Drafting"
169
+ }),
170
+ action: /*#__PURE__*/ _jsx(Button, {
171
+ color: "inherit",
172
+ size: "small",
173
+ variant: "outlined",
174
+ onClick: ()=>{
175
+ openAiJobs({
176
+ jobId: job.id
177
+ });
178
+ close();
179
+ },
180
+ children: 'Open AI jobs'
181
+ }),
182
+ children: copy.running
183
+ }) : null,
184
+ ready ? /*#__PURE__*/ _jsxs(Alert, {
185
+ severity: "success",
186
+ children: [
187
+ /*#__PURE__*/ _jsx(Typography, {
188
+ variant: "body2",
189
+ sx: {
190
+ fontWeight: 600
191
+ },
192
+ children: `${copy.ready}: ${ready.label}`
193
+ }),
194
+ ready.note ? /*#__PURE__*/ _jsx(Typography, {
195
+ variant: "body2",
196
+ children: ready.note
197
+ }) : null
198
+ ]
199
+ }) : null,
200
+ problem ? /*#__PURE__*/ _jsx(Alert, {
201
+ severity: (job == null ? void 0 : job.status) === 'failed' ? 'error' : 'warning',
202
+ children: problem
203
+ }) : null,
204
+ notOpened ? /*#__PURE__*/ _jsx(Alert, {
205
+ severity: "warning",
206
+ children: copy.notOpened
207
+ }) : null
208
+ ]
209
+ })
210
+ }),
211
+ /*#__PURE__*/ _jsxs(DialogActions, {
212
+ children: [
213
+ /*#__PURE__*/ _jsx(Button, {
214
+ onClick: close,
215
+ disabled: starting,
216
+ children: asking ? 'Cancel' : 'Close'
217
+ }),
218
+ asking ? /*#__PURE__*/ _jsx(Button, {
219
+ variant: "contained",
220
+ onClick: ()=>void start(),
221
+ disabled: starting || !orgId || !brief.trim(),
222
+ children: copy.submit
223
+ }) : ready ? /*#__PURE__*/ _jsx(Button, {
224
+ variant: "contained",
225
+ onClick: apply,
226
+ children: copy.open
227
+ }) : null
228
+ ]
229
+ })
230
+ ]
231
+ })
232
+ ]
233
+ });
234
+ }
235
+ AiDescribeOrgAutomationButton.displayName = 'AiDescribeOrgAutomationButton';
236
+ export default AiDescribeOrgAutomationButton;
237
+
238
+ //# sourceMappingURL=ai-describe-org-automation.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-describe-org-automation.component.tsx"],"sourcesContent":["'use client'\n\n/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { ConsoleWidgetEntitlementProps } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { mdiCreation } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n CircularProgress,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Link,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useEffect, useState } from 'react'\nimport type { AiJobSummary } from '../model/ai-jobs.types'\nimport {\n AI_ORG_AUTOMATION_RESOURCE,\n aiOrgAutomationInputs,\n readAiOrgAutomationProposal,\n type AiOrgAutomationProposal,\n} from '../model/ai-workflow-job'\nimport type { ConsoleOrgAutomationsZoneProps } from './ai-automation-zones'\nimport { openAiJobs } from './ai-jobs-store'\nimport { AiUpsellButton } from './ai-upsell-dialog.component'\nimport { aiJobProblem, useAiJobRun } from './use-ai-job-run'\n\n/**\n * \"Create with AI\" on the workspace's Org automations (AGL-3603), in that\n * section's card header through the `orgAutomations` zone: a description\n * becomes a `workflow` job drafting one of the WORKSPACE's automations, held\n * to the triggers and steps the zone says an org automation may use.\n *\n * Nothing is written. The job's proposal opens in the section's editor as a\n * new automation, unsaved and switched off; the person picks the sites it\n * runs on and saves it with the editor's own Save, through the section's\n * route — or closes the editor, and nothing changes.\n */\n\nconst BRIEF_MAX_CHARS = 4_000\n\nexport const AI_ORG_AUTOMATION_COPY = {\n create: 'Create with AI',\n title: 'Describe an org automation',\n label: 'What should happen, and when?',\n placeholder:\n 'When someone books on any of our sites, make them a contact, tag them booked and send them a welcome email',\n next:\n 'It is drafted from what an org automation can start on and do, and opens in the editor switched off, where you choose its sites and save it. Lists, campaigns or datasets your workspace does not have are left for you to pick.',\n submit: 'Draft the automation',\n running: 'Drafting it. This can take a few minutes.',\n ready: 'Drafted',\n open: 'Open in the editor',\n notOpened: 'It could not be opened in the editor. Check the page for why, then try again.',\n failed: 'The automation could not be drafted. Try again.',\n} as const\n\n/** The proposal a finished job wrote, with what to decide, or `null`. */\nfunction proposalOf(job: AiJobSummary | null): { automation: AiOrgAutomationProposal; label: string; note: string | null } | null {\n if (job?.status !== 'done') return null\n const output = job.outputs.find((one) => one.resource === AI_ORG_AUTOMATION_RESOURCE)\n const automation = readAiOrgAutomationProposal(output?.proposal)\n return automation && output ? { automation, label: output.label, note: output.note ?? null } : null\n}\n\nexport function AiDescribeOrgAutomationButton({\n orgId,\n triggers,\n steps,\n propose,\n entitled,\n upgrade,\n}: ConsoleOrgAutomationsZoneProps & ConsoleWidgetEntitlementProps) {\n const copy = AI_ORG_AUTOMATION_COPY\n const help = pluginDocsHelp('aiAutomations', { anchor: '#org-automations' })\n const { data: user } = useUser()\n const run = useAiJobRun(user, copy.failed)\n const { job, starting, running, notice, reset } = run\n const [open, setOpen] = useState(false)\n const [brief, setBrief] = useState('')\n const [notOpened, setNotOpened] = useState(false)\n\n // Opening or closing starts over and stops following: a job still drafting\n // carries on in AI jobs.\n useEffect(() => {\n reset()\n setNotOpened(false)\n }, [open, reset])\n\n // Drawn from the shell's gates alone (AGL-3601): nothing asks a server\n // until it is used, and a plan without the add-on gets the add-on's dialog.\n if (entitled === false) return upgrade ? <AiUpsellButton kind=\"workflow\" upgrade={upgrade} /> : null\n const ready = proposalOf(job)\n const problem = aiJobProblem(job, copy.failed) ?? (job?.status === 'done' && !ready ? copy.failed : null)\n const asking = !job || Boolean(notice)\n const close = () => setOpen(false)\n\n const start = async () => {\n const trimmed = brief.trim()\n if (!orgId || !trimmed) return\n setNotOpened(false)\n const inputs = aiOrgAutomationInputs({ triggers, steps })\n if (await run.start({ orgId, hostId: null, kind: 'workflow', brief: trimmed, inputs })) setBrief('')\n }\n const apply = () => {\n if (!ready) return\n if (propose(ready.automation)) close()\n else setNotOpened(true)\n }\n\n return (\n <>\n <Button size=\"small\" variant=\"outlined\" startIcon={<MdiIcon path={mdiCreation.path} />} onClick={() => setOpen(true)}>\n {copy.create}\n </Button>\n <Dialog open={open} onClose={starting ? undefined : close} fullWidth maxWidth=\"sm\">\n <DialogTitle>{copy.title}</DialogTitle>\n <DialogContent>\n {asking ? (\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n label={copy.label}\n placeholder={copy.placeholder}\n multiline\n minRows={4}\n value={brief}\n onChange={(event) => setBrief(event.target.value.slice(0, BRIEF_MAX_CHARS))}\n helperText={`${brief.length.toLocaleString('en-US')} / ${BRIEF_MAX_CHARS.toLocaleString('en-US')}`}\n disabled={starting}\n autoFocus\n />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {copy.next}{' '}\n <Link href={help.href} target=\"_blank\" rel=\"noopener\" title={help.excerpt}>\n {'How it works'}\n </Link>\n </Typography>\n {notice ? <Alert severity=\"warning\">{notice}</Alert> : null}\n </Stack>\n ) : (\n <Stack spacing={2} sx={{ pt: 1 }}>\n {running && job ? (\n <Alert\n severity=\"info\"\n icon={<CircularProgress size={18} aria-label=\"Drafting\" />}\n action={\n <Button\n color=\"inherit\"\n size=\"small\"\n variant=\"outlined\"\n onClick={() => {\n openAiJobs({ jobId: job.id })\n close()\n }}\n >\n {'Open AI jobs'}\n </Button>\n }\n >\n {copy.running}\n </Alert>\n ) : null}\n {ready ? (\n <Alert severity=\"success\">\n <Typography variant=\"body2\" sx={{ fontWeight: 600 }}>\n {`${copy.ready}: ${ready.label}`}\n </Typography>\n {ready.note ? <Typography variant=\"body2\">{ready.note}</Typography> : null}\n </Alert>\n ) : null}\n {problem ? <Alert severity={job?.status === 'failed' ? 'error' : 'warning'}>{problem}</Alert> : null}\n {notOpened ? <Alert severity=\"warning\">{copy.notOpened}</Alert> : null}\n </Stack>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={close} disabled={starting}>\n {asking ? 'Cancel' : 'Close'}\n </Button>\n {asking ? (\n <Button variant=\"contained\" onClick={() => void start()} disabled={starting || !orgId || !brief.trim()}>\n {copy.submit}\n </Button>\n ) : ready ? (\n <Button variant=\"contained\" onClick={apply}>\n {copy.open}\n </Button>\n ) : null}\n </DialogActions>\n </Dialog>\n </>\n )\n}\nAiDescribeOrgAutomationButton.displayName = 'AiDescribeOrgAutomationButton'\n\nexport default AiDescribeOrgAutomationButton\n"],"names":["pluginDocsHelp","mdiCreation","MdiIcon","useUser","Alert","Button","CircularProgress","Dialog","DialogActions","DialogContent","DialogTitle","Link","Stack","TextField","Typography","useEffect","useState","AI_ORG_AUTOMATION_RESOURCE","aiOrgAutomationInputs","readAiOrgAutomationProposal","openAiJobs","AiUpsellButton","aiJobProblem","useAiJobRun","BRIEF_MAX_CHARS","AI_ORG_AUTOMATION_COPY","create","title","label","placeholder","next","submit","running","ready","open","notOpened","failed","proposalOf","job","output","status","outputs","find","one","resource","automation","proposal","note","AiDescribeOrgAutomationButton","orgId","triggers","steps","propose","entitled","upgrade","copy","help","anchor","data","user","run","starting","notice","reset","setOpen","brief","setBrief","setNotOpened","kind","problem","asking","Boolean","close","start","trimmed","trim","inputs","hostId","apply","size","variant","startIcon","path","onClick","onClose","undefined","fullWidth","maxWidth","spacing","sx","pt","multiline","minRows","value","onChange","event","target","slice","helperText","length","toLocaleString","disabled","autoFocus","color","href","rel","excerpt","severity","icon","aria-label","action","jobId","id","fontWeight","displayName"],"mappings":"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"}
@@ -6,6 +6,8 @@ export interface AiExperimentZoneVariant {
6
6
  name: string;
7
7
  subject: string;
8
8
  body: string;
9
+ /** The screen version a page or section variant pins; empty for the published one. */
10
+ versionId?: string;
9
11
  }
10
12
  /** What the variants zone hands this widget. */
11
13
  export interface AiExperimentVariantsCardProps {
@@ -14,6 +16,10 @@ export interface AiExperimentVariantsCardProps {
14
16
  name: string;
15
17
  target: AiExperimentTarget;
16
18
  goal: string;
19
+ /** A page or section test's page; empty until one is picked (AGL-3603). */
20
+ screenId?: string;
21
+ /** A section test's element; empty until one is picked. */
22
+ nodeId?: string;
17
23
  variants: AiExperimentZoneVariant[];
18
24
  proposeVariants: (variants: readonly AiExperimentZoneVariant[], key: string) => void;
19
25
  }
@@ -36,7 +42,9 @@ export declare function aiExperimentSubjectFrom(target: AiExperimentTarget, vari
36
42
  * body, and a screen or a section varies a screen version, so there only the
37
43
  * name is filled and the copy is read on the card.
38
44
  */
39
- export declare function aiExperimentVariantDrafts(target: AiExperimentTarget, variants: readonly AiExperimentZoneVariant[], proposal: AiExperimentVariantsProposalView): AiExperimentZoneVariant[];
45
+ export declare function aiExperimentVariantDrafts(target: AiExperimentTarget, variants: readonly AiExperimentZoneVariant[], proposal: AiExperimentVariantsProposalView,
46
+ /** Draft versions made for a page or section test (AGL-3603), by the proposal's index. */
47
+ versions?: ReadonlyMap<number, string>): AiExperimentZoneVariant[];
40
48
  /** Where a proposed variant's copy lands, said before the person presses the button. */
41
49
  export declare function aiExperimentApplyCopy(target: AiExperimentTarget): string;
42
50
  /**
@@ -17,13 +17,14 @@
17
17
  import { _ as _extends } from "@swc/helpers/_/_extends";
18
18
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
19
  import { pluginDocsHelp } from "@aglyn/aglyn/app-utils/docs-help";
20
+ import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
20
21
  import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
21
22
  import { useHostOrgId, useUser } from "@aglyn/tenant-feature-instance";
22
23
  import { Alert, Box, Button, Chip, CircularProgress, Link, Stack, TableBody, TableCell, TableHead, TableRow, TextField, Typography } from "@mui/material";
23
24
  import { useEffect, useMemo, useState } from "react";
24
25
  import { AI_EXPERIMENT_SUBJECT_MAX_CHARS } from "../model/ai-experiment.js";
25
26
  import { aiExperimentArmIsNamed, aiExperimentVerdictDisplay, readAiExperimentExplanation, readAiExperimentVariants } from "../model/ai-experiment-proposal.js";
26
- import { aiJobProblem, useAiJobRun, useAiJobsVerdict } from "./use-ai-job-run.js";
27
+ import { aiJobProblem, useAiJobRun } from "./use-ai-job-run.js";
27
28
  /**
28
29
  * A/B tests by AI in the console (AGL-2914): the two doors a person reaches
29
30
  * the `experiment` job through, and the surfaces that render what it answers.
@@ -84,28 +85,32 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
84
85
  * that target has a place for are filled: an email varies its subject and
85
86
  * body, and a screen or a section varies a screen version, so there only the
86
87
  * name is filled and the copy is read on the card.
87
- */ export function aiExperimentVariantDrafts(target, variants, proposal) {
88
+ */ export function aiExperimentVariantDrafts(target, variants, proposal, /** Draft versions made for a page or section test (AGL-3603), by the proposal's index. */ versions = new Map()) {
88
89
  return variants.map((variant, index)=>{
89
90
  const proposed = proposal.variants[index];
90
91
  if (!proposed) return variant;
91
- return {
92
+ const versionId = target === 'email' ? undefined : versions.get(index);
93
+ return _extends({
92
94
  id: variant.id,
93
95
  name: proposed.name,
94
96
  subject: target === 'email' ? proposed.subject : '',
95
97
  body: target === 'email' ? proposed.body : ''
96
- };
98
+ }, versionId ? {
99
+ versionId
100
+ } : {});
97
101
  });
98
102
  }
99
103
  /** Where a proposed variant's copy lands, said before the person presses the button. */ export function aiExperimentApplyCopy(target) {
100
- return target === 'email' ? 'Each variant above takes its name, subject and body. Nothing is saved until you save the experiment.' : 'Each variant above takes its name. The copy itself is a page version — make one per variant in the editor and pin it above.';
104
+ return target === 'email' ? 'Each variant above takes its name, subject and body. Nothing is saved until you save the experiment.' : 'Each variant above takes its name. Make draft versions to put each variant’s copy into a new unpublished version of the page, pinned to its variant; the first stays on the published page as the control.';
101
105
  }
106
+ const VERSIONS_FAILED_COPY = 'The draft versions could not be made. Try again.';
102
107
  /**
103
108
  * "Write variants with AI", in the experiment editor beneath the variants it
104
109
  * writes for. It proposes COPY: no weight, no traffic split, no goal and no
105
110
  * schedule, and the first variant it writes is the copy as it stands so the
106
111
  * test has something to measure against.
107
112
  */ export function AiExperimentVariantsCard(props) {
108
- var _useHostOrgId, _aiJobProblem;
113
+ var _useHostOrgId, _aiJobProblem, _props_screenId, _props_nodeId;
109
114
  var _run_job, _run_job1, _run_job2, _run_job3;
110
115
  const { hostId, target, variants, proposeVariants } = props;
111
116
  // The zone hands the SITE, which is what the card it is drawn in knows. The
@@ -113,7 +118,6 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
113
118
  // plugin's zone resolves it.
114
119
  const orgId = (_useHostOrgId = useHostOrgId(hostId)) != null ? _useHostOrgId : undefined;
115
120
  const { data: user } = useUser();
116
- const verdict = useAiJobsVerdict(user, orgId);
117
121
  const run = useAiJobRun(user, VARIANTS_FAILED_COPY);
118
122
  const prefill = useMemo(()=>aiExperimentSubjectFrom(target, variants), [
119
123
  target,
@@ -121,6 +125,8 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
121
125
  ]);
122
126
  const [subject, setSubject] = useState(prefill);
123
127
  const [applied, setApplied] = useState(null);
128
+ const [versioning, setVersioning] = useState(false);
129
+ const [versionsNote, setVersionsNote] = useState(null);
124
130
  // The control's copy follows the editor until the person edits this field,
125
131
  // so switching a draft test from a page to an email fills it rather than
126
132
  // leaving the earlier target's copy under a question about a new one.
@@ -135,7 +141,6 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
135
141
  run.job
136
142
  ]);
137
143
  const problem = (_aiJobProblem = aiJobProblem(run.job, VARIANTS_FAILED_COPY)) != null ? _aiJobProblem : ((_run_job = run.job) == null ? void 0 : _run_job.status) === 'done' && !proposal ? VARIANTS_FAILED_COPY : null;
138
- if (verdict !== 'ready') return null;
139
144
  const busy = run.starting || run.running;
140
145
  const noun = TARGET_NOUN[target];
141
146
  const variantsHelp = pluginDocsHelp('aiExperiments', {
@@ -165,6 +170,67 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
165
170
  proposeVariants(aiExperimentVariantDrafts(target, variants, proposal), run.job.id);
166
171
  setApplied(run.job.id);
167
172
  };
173
+ /*
174
+ * A page or a section varies a VERSION of the page (AGL-3603): the door
175
+ * copies the published version once per variant past the control, puts
176
+ * the variant's copy into it, and stores it unpublished; the versions are
177
+ * then pinned to the variants here as unsaved edits.
178
+ */ const screenId = (_props_screenId = props.screenId) != null ? _props_screenId : '';
179
+ const nodeId = (_props_nodeId = props.nodeId) != null ? _props_nodeId : '';
180
+ const versionsBlocked = target === 'email' ? null : !screenId ? 'Pick the page under test above to make draft versions.' : target === 'section' && !nodeId ? 'Pick the section under test above to make draft versions.' : null;
181
+ const makeVersions = async ()=>{
182
+ if (!proposal || !run.job || !orgId || versionsBlocked) return;
183
+ const jobId = run.job.id;
184
+ setVersioning(true);
185
+ setVersionsNote(null);
186
+ try {
187
+ var _ref, _answer_versions, _answer_versions1, _answer_skipped;
188
+ const response = await authorizedFetch(user, '/api/ai/experiments/versions', {
189
+ method: 'POST',
190
+ headers: {
191
+ 'Content-Type': 'application/json'
192
+ },
193
+ body: JSON.stringify(_extends({
194
+ orgId,
195
+ hostId,
196
+ jobId,
197
+ screenId
198
+ }, nodeId ? {
199
+ nodeId
200
+ } : {}))
201
+ });
202
+ const answer = (_ref = await response.json().catch(()=>null)) != null ? _ref : {};
203
+ if (!response.ok) {
204
+ setVersionsNote({
205
+ ok: false,
206
+ text: answer.error || VERSIONS_FAILED_COPY
207
+ });
208
+ return;
209
+ }
210
+ const made = new Map(((_answer_versions = answer.versions) != null ? _answer_versions : []).map((entry)=>[
211
+ entry.index,
212
+ entry.versionId
213
+ ]));
214
+ proposeVariants(aiExperimentVariantDrafts(target, variants, proposal, made), jobId);
215
+ setApplied(jobId);
216
+ const names = ((_answer_versions1 = answer.versions) != null ? _answer_versions1 : []).map((entry)=>entry.name);
217
+ const skipped = (_answer_skipped = answer.skipped) != null ? _answer_skipped : [];
218
+ setVersionsNote({
219
+ ok: names.length > 0,
220
+ text: [
221
+ names.length ? `Draft versions made and pinned above: ${names.join(', ')}. Open each in the editor to check it, then Save the experiment. Nothing is published.` : 'No draft version could be made.',
222
+ ...skipped.map((entry)=>`Variant ${entry.index + 1}: ${entry.reason}`)
223
+ ].join(' ')
224
+ });
225
+ } catch (unused) {
226
+ setVersionsNote({
227
+ ok: false,
228
+ text: VERSIONS_FAILED_COPY
229
+ });
230
+ } finally{
231
+ setVersioning(false);
232
+ }
233
+ };
168
234
  return /*#__PURE__*/ _jsx(Box, {
169
235
  sx: {
170
236
  border: 1,
@@ -298,17 +364,39 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
298
364
  color: "text.secondary",
299
365
  children: aiExperimentApplyCopy(target)
300
366
  }),
301
- /*#__PURE__*/ _jsx(Stack, {
367
+ /*#__PURE__*/ _jsxs(Stack, {
302
368
  direction: "row",
303
369
  spacing: 1,
304
- children: /*#__PURE__*/ _jsx(Button, {
305
- size: "small",
306
- variant: "contained",
307
- disabled: applied === ((_run_job2 = run.job) == null ? void 0 : _run_job2.id),
308
- onClick: apply,
309
- children: 'Put into the variants'
310
- })
370
+ children: [
371
+ /*#__PURE__*/ _jsx(Button, {
372
+ size: "small",
373
+ variant: "contained",
374
+ disabled: applied === ((_run_job2 = run.job) == null ? void 0 : _run_job2.id),
375
+ onClick: apply,
376
+ children: 'Put into the variants'
377
+ }),
378
+ target === 'email' ? null : /*#__PURE__*/ _jsx(Button, {
379
+ size: "small",
380
+ variant: "outlined",
381
+ disabled: versioning || Boolean(versionsBlocked),
382
+ onClick: ()=>void makeVersions(),
383
+ children: 'Make draft versions'
384
+ }),
385
+ versioning ? /*#__PURE__*/ _jsx(CircularProgress, {
386
+ size: 16,
387
+ "aria-label": "Making draft versions"
388
+ }) : null
389
+ ]
311
390
  }),
391
+ versionsBlocked && target !== 'email' ? /*#__PURE__*/ _jsx(Typography, {
392
+ variant: "caption",
393
+ color: "text.secondary",
394
+ children: versionsBlocked
395
+ }) : null,
396
+ versionsNote ? /*#__PURE__*/ _jsx(Alert, {
397
+ severity: versionsNote.ok ? 'success' : 'warning',
398
+ children: versionsNote.text
399
+ }) : null,
312
400
  applied === ((_run_job3 = run.job) == null ? void 0 : _run_job3.id) ? /*#__PURE__*/ _jsx(Alert, {
313
401
  severity: "success",
314
402
  children: 'In the variants above. Review them, then Save the experiment — or Cancel to leave it as it was.'
@@ -464,13 +552,11 @@ AiExperimentExplanation.displayName = 'AiExperimentExplanation';
464
552
  const { hostId, test } = props;
465
553
  const orgId = (_useHostOrgId = useHostOrgId(hostId)) != null ? _useHostOrgId : undefined;
466
554
  const { data: user } = useUser();
467
- const verdict = useAiJobsVerdict(user, orgId);
468
555
  const run = useAiJobRun(user, EXPLAIN_FAILED_COPY);
469
556
  const explanation = useMemo(()=>readAiExperimentExplanation(proposalOf(run.job)), [
470
557
  run.job
471
558
  ]);
472
559
  const problem = (_aiJobProblem = aiJobProblem(run.job, EXPLAIN_FAILED_COPY)) != null ? _aiJobProblem : ((_run_job = run.job) == null ? void 0 : _run_job.status) === 'done' && !explanation ? EXPLAIN_FAILED_COPY : null;
473
- if (verdict !== 'ready') return null;
474
560
  const busy = run.starting || run.running;
475
561
  const resultHelp = pluginDocsHelp('aiExperiments', {
476
562
  anchor: '#the-verdict',