@aglyn/plugins-ai 1.0.0-beta.143

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 (717) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +25 -0
  3. package/package.json +60 -0
  4. package/src/index.d.ts +21 -0
  5. package/src/index.js +22 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/activity/ai-activity-actions.d.ts +106 -0
  8. package/src/lib/activity/ai-activity-actions.js +209 -0
  9. package/src/lib/activity/ai-activity-actions.js.map +1 -0
  10. package/src/lib/activity/ai-activity.d.ts +219 -0
  11. package/src/lib/activity/ai-activity.js +251 -0
  12. package/src/lib/activity/ai-activity.js.map +1 -0
  13. package/src/lib/billing/ai-overage-charge.d.ts +102 -0
  14. package/src/lib/billing/ai-overage-charge.js +258 -0
  15. package/src/lib/billing/ai-overage-charge.js.map +1 -0
  16. package/src/lib/billing/ai-overage-close.d.ts +62 -0
  17. package/src/lib/billing/ai-overage-close.js +129 -0
  18. package/src/lib/billing/ai-overage-close.js.map +1 -0
  19. package/src/lib/billing/ai-overage-cutover.d.ts +63 -0
  20. package/src/lib/billing/ai-overage-cutover.js +114 -0
  21. package/src/lib/billing/ai-overage-cutover.js.map +1 -0
  22. package/src/lib/billing/ai-overage-events.d.ts +77 -0
  23. package/src/lib/billing/ai-overage-events.js +174 -0
  24. package/src/lib/billing/ai-overage-events.js.map +1 -0
  25. package/src/lib/billing/ai-overage-gate.d.ts +147 -0
  26. package/src/lib/billing/ai-overage-gate.js +177 -0
  27. package/src/lib/billing/ai-overage-gate.js.map +1 -0
  28. package/src/lib/billing/ai-overage-ledger.d.ts +135 -0
  29. package/src/lib/billing/ai-overage-ledger.js +278 -0
  30. package/src/lib/billing/ai-overage-ledger.js.map +1 -0
  31. package/src/lib/billing/ai-overage-standing-writes.d.ts +110 -0
  32. package/src/lib/billing/ai-overage-standing-writes.js +205 -0
  33. package/src/lib/billing/ai-overage-standing-writes.js.map +1 -0
  34. package/src/lib/billing/ai-overage-standing.d.ts +168 -0
  35. package/src/lib/billing/ai-overage-standing.js +215 -0
  36. package/src/lib/billing/ai-overage-standing.js.map +1 -0
  37. package/src/lib/billing/ai-overage-trigger.d.ts +30 -0
  38. package/src/lib/billing/ai-overage-trigger.js +76 -0
  39. package/src/lib/billing/ai-overage-trigger.js.map +1 -0
  40. package/src/lib/components/ai-allotment-editor.component.d.ts +40 -0
  41. package/src/lib/components/ai-allotment-editor.component.js +213 -0
  42. package/src/lib/components/ai-allotment-editor.component.js.map +1 -0
  43. package/src/lib/components/ai-assist-actions-context.d.ts +13 -0
  44. package/src/lib/components/ai-assist-actions-context.js +21 -0
  45. package/src/lib/components/ai-assist-actions-context.js.map +1 -0
  46. package/src/lib/components/ai-assist-provider.component.d.ts +51 -0
  47. package/src/lib/components/ai-assist-provider.component.js +519 -0
  48. package/src/lib/components/ai-assist-provider.component.js.map +1 -0
  49. package/src/lib/components/ai-brief-dialog.component.d.ts +56 -0
  50. package/src/lib/components/ai-brief-dialog.component.js +319 -0
  51. package/src/lib/components/ai-brief-dialog.component.js.map +1 -0
  52. package/src/lib/components/ai-collaborator-permissions-column.component.d.ts +32 -0
  53. package/src/lib/components/ai-collaborator-permissions-column.component.js +132 -0
  54. package/src/lib/components/ai-collaborator-permissions-column.component.js.map +1 -0
  55. package/src/lib/components/ai-credits-card.component.d.ts +34 -0
  56. package/src/lib/components/ai-credits-card.component.js +131 -0
  57. package/src/lib/components/ai-credits-card.component.js.map +1 -0
  58. package/src/lib/components/ai-credits-columns.component.d.ts +56 -0
  59. package/src/lib/components/ai-credits-columns.component.js +118 -0
  60. package/src/lib/components/ai-credits-columns.component.js.map +1 -0
  61. package/src/lib/components/ai-crm-email-draft.component.d.ts +17 -0
  62. package/src/lib/components/ai-crm-email-draft.component.js +159 -0
  63. package/src/lib/components/ai-crm-email-draft.component.js.map +1 -0
  64. package/src/lib/components/ai-crm-import-mapping.component.d.ts +20 -0
  65. package/src/lib/components/ai-crm-import-mapping.component.js +167 -0
  66. package/src/lib/components/ai-crm-import-mapping.component.js.map +1 -0
  67. package/src/lib/components/ai-crm-record-card.component.d.ts +27 -0
  68. package/src/lib/components/ai-crm-record-card.component.js +263 -0
  69. package/src/lib/components/ai-crm-record-card.component.js.map +1 -0
  70. package/src/lib/components/ai-describe-automation.component.d.ts +31 -0
  71. package/src/lib/components/ai-describe-automation.component.js +226 -0
  72. package/src/lib/components/ai-describe-automation.component.js.map +1 -0
  73. package/src/lib/components/ai-describe-button.component.d.ts +39 -0
  74. package/src/lib/components/ai-describe-button.component.js +87 -0
  75. package/src/lib/components/ai-describe-button.component.js.map +1 -0
  76. package/src/lib/components/ai-describe-page.component.d.ts +26 -0
  77. package/src/lib/components/ai-describe-page.component.js +18 -0
  78. package/src/lib/components/ai-describe-page.component.js.map +1 -0
  79. package/src/lib/components/ai-experiment-cards.component.d.ts +75 -0
  80. package/src/lib/components/ai-experiment-cards.component.js +573 -0
  81. package/src/lib/components/ai-experiment-cards.component.js.map +1 -0
  82. package/src/lib/components/ai-explain-automation.component.d.ts +31 -0
  83. package/src/lib/components/ai-explain-automation.component.js +265 -0
  84. package/src/lib/components/ai-explain-automation.component.js.map +1 -0
  85. package/src/lib/components/ai-insight-dialog.component.d.ts +37 -0
  86. package/src/lib/components/ai-insight-dialog.component.js +441 -0
  87. package/src/lib/components/ai-insight-dialog.component.js.map +1 -0
  88. package/src/lib/components/ai-job-plan.component.d.ts +46 -0
  89. package/src/lib/components/ai-job-plan.component.js +192 -0
  90. package/src/lib/components/ai-job-plan.component.js.map +1 -0
  91. package/src/lib/components/ai-model-selector.component.d.ts +21 -0
  92. package/src/lib/components/ai-model-selector.component.js +109 -0
  93. package/src/lib/components/ai-model-selector.component.js.map +1 -0
  94. package/src/lib/components/ai-page-brief-dialog.component.d.ts +29 -0
  95. package/src/lib/components/ai-page-brief-dialog.component.js +27 -0
  96. package/src/lib/components/ai-page-brief-dialog.component.js.map +1 -0
  97. package/src/lib/components/ai-permissions-on-host.component.d.ts +55 -0
  98. package/src/lib/components/ai-permissions-on-host.component.js +91 -0
  99. package/src/lib/components/ai-permissions-on-host.component.js.map +1 -0
  100. package/src/lib/components/ai-product-copy-card.component.d.ts +25 -0
  101. package/src/lib/components/ai-product-copy-card.component.js +328 -0
  102. package/src/lib/components/ai-product-copy-card.component.js.map +1 -0
  103. package/src/lib/components/ai-product-import-option.component.d.ts +14 -0
  104. package/src/lib/components/ai-product-import-option.component.js +58 -0
  105. package/src/lib/components/ai-product-import-option.component.js.map +1 -0
  106. package/src/lib/components/ai-products-hub-card.component.d.ts +15 -0
  107. package/src/lib/components/ai-products-hub-card.component.js +418 -0
  108. package/src/lib/components/ai-products-hub-card.component.js.map +1 -0
  109. package/src/lib/components/ai-products-proposals.component.d.ts +19 -0
  110. package/src/lib/components/ai-products-proposals.component.js +547 -0
  111. package/src/lib/components/ai-products-proposals.component.js.map +1 -0
  112. package/src/lib/components/ai-save-as-component.component.d.ts +38 -0
  113. package/src/lib/components/ai-save-as-component.component.js +231 -0
  114. package/src/lib/components/ai-save-as-component.component.js.map +1 -0
  115. package/src/lib/components/ai-seo-audit-card.component.d.ts +9 -0
  116. package/src/lib/components/ai-seo-audit-card.component.js +620 -0
  117. package/src/lib/components/ai-seo-audit-card.component.js.map +1 -0
  118. package/src/lib/components/ai-seo-fields-card.component.d.ts +10 -0
  119. package/src/lib/components/ai-seo-fields-card.component.js +453 -0
  120. package/src/lib/components/ai-seo-fields-card.component.js.map +1 -0
  121. package/src/lib/components/ai-site-batch-card.component.d.ts +32 -0
  122. package/src/lib/components/ai-site-batch-card.component.js +531 -0
  123. package/src/lib/components/ai-site-batch-card.component.js.map +1 -0
  124. package/src/lib/components/ai-site-seo-start-card.component.d.ts +26 -0
  125. package/src/lib/components/ai-site-seo-start-card.component.js +178 -0
  126. package/src/lib/components/ai-site-seo-start-card.component.js.map +1 -0
  127. package/src/lib/components/ai-site-start-card.component.d.ts +19 -0
  128. package/src/lib/components/ai-site-start-card.component.js +348 -0
  129. package/src/lib/components/ai-site-start-card.component.js.map +1 -0
  130. package/src/lib/components/ai-template-collection-field.component.d.ts +32 -0
  131. package/src/lib/components/ai-template-collection-field.component.js +63 -0
  132. package/src/lib/components/ai-template-collection-field.component.js.map +1 -0
  133. package/src/lib/components/ai-theme-proposal-card.component.d.ts +6 -0
  134. package/src/lib/components/ai-theme-proposal-card.component.js +619 -0
  135. package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -0
  136. package/src/lib/components/ai-usage-strip.component.d.ts +27 -0
  137. package/src/lib/components/ai-usage-strip.component.js +145 -0
  138. package/src/lib/components/ai-usage-strip.component.js.map +1 -0
  139. package/src/lib/components/assist-edit-canvas.d.ts +169 -0
  140. package/src/lib/components/assist-edit-canvas.js +636 -0
  141. package/src/lib/components/assist-edit-canvas.js.map +1 -0
  142. package/src/lib/components/assist-edit-card.component.d.ts +16 -0
  143. package/src/lib/components/assist-edit-card.component.js +181 -0
  144. package/src/lib/components/assist-edit-card.component.js.map +1 -0
  145. package/src/lib/components/assist-jobs-drawer.component.d.ts +72 -0
  146. package/src/lib/components/assist-jobs-drawer.component.js +626 -0
  147. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -0
  148. package/src/lib/components/assist-panel.component.d.ts +136 -0
  149. package/src/lib/components/assist-panel.component.js +1099 -0
  150. package/src/lib/components/assist-panel.component.js.map +1 -0
  151. package/src/lib/components/assist-signals-page.component.d.ts +3 -0
  152. package/src/lib/components/assist-signals-page.component.js +1017 -0
  153. package/src/lib/components/assist-signals-page.component.js.map +1 -0
  154. package/src/lib/components/besigner-ai-controls.component.d.ts +29 -0
  155. package/src/lib/components/besigner-ai-controls.component.js +81 -0
  156. package/src/lib/components/besigner-ai-controls.component.js.map +1 -0
  157. package/src/lib/components/billing-ai-allotments.component.d.ts +36 -0
  158. package/src/lib/components/billing-ai-allotments.component.js +486 -0
  159. package/src/lib/components/billing-ai-allotments.component.js.map +1 -0
  160. package/src/lib/components/billing-ai-top-users.component.d.ts +44 -0
  161. package/src/lib/components/billing-ai-top-users.component.js +304 -0
  162. package/src/lib/components/billing-ai-top-users.component.js.map +1 -0
  163. package/src/lib/components/billing-assist-overage-card.component.d.ts +69 -0
  164. package/src/lib/components/billing-assist-overage-card.component.js +437 -0
  165. package/src/lib/components/billing-assist-overage-card.component.js.map +1 -0
  166. package/src/lib/components/host-ai-allotments.component.d.ts +40 -0
  167. package/src/lib/components/host-ai-allotments.component.js +239 -0
  168. package/src/lib/components/host-ai-allotments.component.js.map +1 -0
  169. package/src/lib/components/member-ai-allotment-card.component.d.ts +28 -0
  170. package/src/lib/components/member-ai-allotment-card.component.js +172 -0
  171. package/src/lib/components/member-ai-allotment-card.component.js.map +1 -0
  172. package/src/lib/components/member-ai-usage-card.component.d.ts +28 -0
  173. package/src/lib/components/member-ai-usage-card.component.js +240 -0
  174. package/src/lib/components/member-ai-usage-card.component.js.map +1 -0
  175. package/src/lib/components/staff-org-ai-card.component.d.ts +17 -0
  176. package/src/lib/components/staff-org-ai-card.component.js +739 -0
  177. package/src/lib/components/staff-org-ai-card.component.js.map +1 -0
  178. package/src/lib/components/staff-org-usage-ai-columns.component.d.ts +41 -0
  179. package/src/lib/components/staff-org-usage-ai-columns.component.js +65 -0
  180. package/src/lib/components/staff-org-usage-ai-columns.component.js.map +1 -0
  181. package/src/lib/components/staff-orgs-ai-spend-column.component.d.ts +28 -0
  182. package/src/lib/components/staff-orgs-ai-spend-column.component.js +89 -0
  183. package/src/lib/components/staff-orgs-ai-spend-column.component.js.map +1 -0
  184. package/src/lib/components/staff-user-ai-usage-card.component.d.ts +27 -0
  185. package/src/lib/components/staff-user-ai-usage-card.component.js +183 -0
  186. package/src/lib/components/staff-user-ai-usage-card.component.js.map +1 -0
  187. package/src/lib/components/use-ai-allotments.d.ts +49 -0
  188. package/src/lib/components/use-ai-allotments.js +171 -0
  189. package/src/lib/components/use-ai-allotments.js.map +1 -0
  190. package/src/lib/components/use-ai-crm-answer.d.ts +50 -0
  191. package/src/lib/components/use-ai-crm-answer.js +220 -0
  192. package/src/lib/components/use-ai-crm-answer.js.map +1 -0
  193. package/src/lib/components/use-ai-job-run.d.ts +51 -0
  194. package/src/lib/components/use-ai-job-run.js +176 -0
  195. package/src/lib/components/use-ai-job-run.js.map +1 -0
  196. package/src/lib/components/use-ai-model-choice.d.ts +47 -0
  197. package/src/lib/components/use-ai-model-choice.js +150 -0
  198. package/src/lib/components/use-ai-model-choice.js.map +1 -0
  199. package/src/lib/components/use-ai-products-jobs.d.ts +36 -0
  200. package/src/lib/components/use-ai-products-jobs.js +190 -0
  201. package/src/lib/components/use-ai-products-jobs.js.map +1 -0
  202. package/src/lib/components/use-ai-usage-meter.d.ts +11 -0
  203. package/src/lib/components/use-ai-usage-meter.js +96 -0
  204. package/src/lib/components/use-ai-usage-meter.js.map +1 -0
  205. package/src/lib/components/use-org-ai-usage.d.ts +42 -0
  206. package/src/lib/components/use-org-ai-usage.js +181 -0
  207. package/src/lib/components/use-org-ai-usage.js.map +1 -0
  208. package/src/lib/components/use-staff-orgs-ai-spend.d.ts +18 -0
  209. package/src/lib/components/use-staff-orgs-ai-spend.js +127 -0
  210. package/src/lib/components/use-staff-orgs-ai-spend.js.map +1 -0
  211. package/src/lib/constants.d.ts +24 -0
  212. package/src/lib/constants.js +23 -0
  213. package/src/lib/constants.js.map +1 -0
  214. package/src/lib/declarations.d.ts +48 -0
  215. package/src/lib/declarations.js +129 -0
  216. package/src/lib/declarations.js.map +1 -0
  217. package/src/lib/declarations.server.d.ts +35 -0
  218. package/src/lib/declarations.server.js +138 -0
  219. package/src/lib/declarations.server.js.map +1 -0
  220. package/src/lib/insights/ai-figure-readers.d.ts +90 -0
  221. package/src/lib/insights/ai-figure-readers.js +863 -0
  222. package/src/lib/insights/ai-figure-readers.js.map +1 -0
  223. package/src/lib/insights/ai-insight-digest.d.ts +165 -0
  224. package/src/lib/insights/ai-insight-digest.js +363 -0
  225. package/src/lib/insights/ai-insight-digest.js.map +1 -0
  226. package/src/lib/insights/ai-insight-readers.d.ts +71 -0
  227. package/src/lib/insights/ai-insight-readers.js +141 -0
  228. package/src/lib/insights/ai-insight-readers.js.map +1 -0
  229. package/src/lib/jobs/ai-crm-access.d.ts +61 -0
  230. package/src/lib/jobs/ai-crm-access.js +94 -0
  231. package/src/lib/jobs/ai-crm-access.js.map +1 -0
  232. package/src/lib/jobs/ai-email-bindings.d.ts +97 -0
  233. package/src/lib/jobs/ai-email-bindings.js +147 -0
  234. package/src/lib/jobs/ai-email-bindings.js.map +1 -0
  235. package/src/lib/jobs/ai-job-admission.d.ts +82 -0
  236. package/src/lib/jobs/ai-job-admission.js +45 -0
  237. package/src/lib/jobs/ai-job-admission.js.map +1 -0
  238. package/src/lib/jobs/ai-job-budget.d.ts +167 -0
  239. package/src/lib/jobs/ai-job-budget.js +161 -0
  240. package/src/lib/jobs/ai-job-budget.js.map +1 -0
  241. package/src/lib/jobs/ai-job-campaign-step.d.ts +108 -0
  242. package/src/lib/jobs/ai-job-campaign-step.js +340 -0
  243. package/src/lib/jobs/ai-job-campaign-step.js.map +1 -0
  244. package/src/lib/jobs/ai-job-component-checks.d.ts +74 -0
  245. package/src/lib/jobs/ai-job-component-checks.js +442 -0
  246. package/src/lib/jobs/ai-job-component-checks.js.map +1 -0
  247. package/src/lib/jobs/ai-job-component-step.d.ts +75 -0
  248. package/src/lib/jobs/ai-job-component-step.js +262 -0
  249. package/src/lib/jobs/ai-job-component-step.js.map +1 -0
  250. package/src/lib/jobs/ai-job-crm-step.d.ts +192 -0
  251. package/src/lib/jobs/ai-job-crm-step.js +734 -0
  252. package/src/lib/jobs/ai-job-crm-step.js.map +1 -0
  253. package/src/lib/jobs/ai-job-draft-ids.d.ts +62 -0
  254. package/src/lib/jobs/ai-job-draft-ids.js +132 -0
  255. package/src/lib/jobs/ai-job-draft-ids.js.map +1 -0
  256. package/src/lib/jobs/ai-job-drafts.d.ts +304 -0
  257. package/src/lib/jobs/ai-job-drafts.js +557 -0
  258. package/src/lib/jobs/ai-job-drafts.js.map +1 -0
  259. package/src/lib/jobs/ai-job-email-step.d.ts +195 -0
  260. package/src/lib/jobs/ai-job-email-step.js +547 -0
  261. package/src/lib/jobs/ai-job-email-step.js.map +1 -0
  262. package/src/lib/jobs/ai-job-experiment-step.d.ts +105 -0
  263. package/src/lib/jobs/ai-job-experiment-step.js +445 -0
  264. package/src/lib/jobs/ai-job-experiment-step.js.map +1 -0
  265. package/src/lib/jobs/ai-job-form-step.d.ts +250 -0
  266. package/src/lib/jobs/ai-job-form-step.js +634 -0
  267. package/src/lib/jobs/ai-job-form-step.js.map +1 -0
  268. package/src/lib/jobs/ai-job-generation.d.ts +114 -0
  269. package/src/lib/jobs/ai-job-generation.js +384 -0
  270. package/src/lib/jobs/ai-job-generation.js.map +1 -0
  271. package/src/lib/jobs/ai-job-insight-budget.d.ts +41 -0
  272. package/src/lib/jobs/ai-job-insight-budget.js +46 -0
  273. package/src/lib/jobs/ai-job-insight-budget.js.map +1 -0
  274. package/src/lib/jobs/ai-job-insight-step.d.ts +58 -0
  275. package/src/lib/jobs/ai-job-insight-step.js +350 -0
  276. package/src/lib/jobs/ai-job-insight-step.js.map +1 -0
  277. package/src/lib/jobs/ai-job-layout-step.d.ts +103 -0
  278. package/src/lib/jobs/ai-job-layout-step.js +340 -0
  279. package/src/lib/jobs/ai-job-layout-step.js.map +1 -0
  280. package/src/lib/jobs/ai-job-page-budget.d.ts +57 -0
  281. package/src/lib/jobs/ai-job-page-budget.js +60 -0
  282. package/src/lib/jobs/ai-job-page-budget.js.map +1 -0
  283. package/src/lib/jobs/ai-job-page-sections.d.ts +150 -0
  284. package/src/lib/jobs/ai-job-page-sections.js +450 -0
  285. package/src/lib/jobs/ai-job-page-sections.js.map +1 -0
  286. package/src/lib/jobs/ai-job-page-step.d.ts +198 -0
  287. package/src/lib/jobs/ai-job-page-step.js +667 -0
  288. package/src/lib/jobs/ai-job-page-step.js.map +1 -0
  289. package/src/lib/jobs/ai-job-plan-conformance.d.ts +107 -0
  290. package/src/lib/jobs/ai-job-plan-conformance.js +164 -0
  291. package/src/lib/jobs/ai-job-plan-conformance.js.map +1 -0
  292. package/src/lib/jobs/ai-job-plan-step.d.ts +196 -0
  293. package/src/lib/jobs/ai-job-plan-step.js +458 -0
  294. package/src/lib/jobs/ai-job-plan-step.js.map +1 -0
  295. package/src/lib/jobs/ai-job-plugin-drafts.d.ts +76 -0
  296. package/src/lib/jobs/ai-job-plugin-drafts.js +91 -0
  297. package/src/lib/jobs/ai-job-plugin-drafts.js.map +1 -0
  298. package/src/lib/jobs/ai-job-products-step.d.ts +106 -0
  299. package/src/lib/jobs/ai-job-products-step.js +436 -0
  300. package/src/lib/jobs/ai-job-products-step.js.map +1 -0
  301. package/src/lib/jobs/ai-job-seo-budget.d.ts +52 -0
  302. package/src/lib/jobs/ai-job-seo-budget.js +63 -0
  303. package/src/lib/jobs/ai-job-seo-budget.js.map +1 -0
  304. package/src/lib/jobs/ai-job-seo-step.d.ts +145 -0
  305. package/src/lib/jobs/ai-job-seo-step.js +809 -0
  306. package/src/lib/jobs/ai-job-seo-step.js.map +1 -0
  307. package/src/lib/jobs/ai-job-site-step.d.ts +252 -0
  308. package/src/lib/jobs/ai-job-site-step.js +538 -0
  309. package/src/lib/jobs/ai-job-site-step.js.map +1 -0
  310. package/src/lib/jobs/ai-job-template-step.d.ts +105 -0
  311. package/src/lib/jobs/ai-job-template-step.js +391 -0
  312. package/src/lib/jobs/ai-job-template-step.js.map +1 -0
  313. package/src/lib/jobs/ai-job-text-step.d.ts +125 -0
  314. package/src/lib/jobs/ai-job-text-step.js +128 -0
  315. package/src/lib/jobs/ai-job-text-step.js.map +1 -0
  316. package/src/lib/jobs/ai-job-theme-budget.d.ts +38 -0
  317. package/src/lib/jobs/ai-job-theme-budget.js +43 -0
  318. package/src/lib/jobs/ai-job-theme-budget.js.map +1 -0
  319. package/src/lib/jobs/ai-job-theme-step.d.ts +115 -0
  320. package/src/lib/jobs/ai-job-theme-step.js +337 -0
  321. package/src/lib/jobs/ai-job-theme-step.js.map +1 -0
  322. package/src/lib/jobs/ai-job-workflow-step.d.ts +139 -0
  323. package/src/lib/jobs/ai-job-workflow-step.js +530 -0
  324. package/src/lib/jobs/ai-job-workflow-step.js.map +1 -0
  325. package/src/lib/jobs/ai-jobs-beat.d.ts +78 -0
  326. package/src/lib/jobs/ai-jobs-beat.js +93 -0
  327. package/src/lib/jobs/ai-jobs-beat.js.map +1 -0
  328. package/src/lib/jobs/ai-jobs-pause.d.ts +38 -0
  329. package/src/lib/jobs/ai-jobs-pause.js +45 -0
  330. package/src/lib/jobs/ai-jobs-pause.js.map +1 -0
  331. package/src/lib/jobs/ai-jobs.d.ts +558 -0
  332. package/src/lib/jobs/ai-jobs.js +1410 -0
  333. package/src/lib/jobs/ai-jobs.js.map +1 -0
  334. package/src/lib/jobs/ai-media-asset-server.d.ts +34 -0
  335. package/src/lib/jobs/ai-media-asset-server.js +34 -0
  336. package/src/lib/jobs/ai-media-asset-server.js.map +1 -0
  337. package/src/lib/jobs/ai-media-asset.d.ts +59 -0
  338. package/src/lib/jobs/ai-media-asset.js +86 -0
  339. package/src/lib/jobs/ai-media-asset.js.map +1 -0
  340. package/src/lib/jobs/ai-product-image.d.ts +78 -0
  341. package/src/lib/jobs/ai-product-image.js +113 -0
  342. package/src/lib/jobs/ai-product-image.js.map +1 -0
  343. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +125 -0
  344. package/src/lib/jobs/ai-theme-brand-inputs.js +378 -0
  345. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -0
  346. package/src/lib/jobs/ai-theme-brand-server.d.ts +33 -0
  347. package/src/lib/jobs/ai-theme-brand-server.js +33 -0
  348. package/src/lib/jobs/ai-theme-brand-server.js.map +1 -0
  349. package/src/lib/jobs/ai-workflow-records.d.ts +84 -0
  350. package/src/lib/jobs/ai-workflow-records.js +158 -0
  351. package/src/lib/jobs/ai-workflow-records.js.map +1 -0
  352. package/src/lib/jobs/fixtures/ai-free-page-built-recording.d.ts +31 -0
  353. package/src/lib/jobs/fixtures/ai-free-page-built-recording.js +367 -0
  354. package/src/lib/jobs/fixtures/ai-free-page-built-recording.js.map +1 -0
  355. package/src/lib/jobs/fixtures/ai-free-page-recording.d.ts +69 -0
  356. package/src/lib/jobs/fixtures/ai-free-page-recording.js +442 -0
  357. package/src/lib/jobs/fixtures/ai-free-page-recording.js.map +1 -0
  358. package/src/lib/jobs/fixtures/ai-page-briefs.d.ts +146 -0
  359. package/src/lib/jobs/fixtures/ai-page-briefs.js +1850 -0
  360. package/src/lib/jobs/fixtures/ai-page-briefs.js.map +1 -0
  361. package/src/lib/model/ai-allotments.d.ts +208 -0
  362. package/src/lib/model/ai-allotments.js +269 -0
  363. package/src/lib/model/ai-allotments.js.map +1 -0
  364. package/src/lib/model/ai-automation-draft.d.ts +74 -0
  365. package/src/lib/model/ai-automation-draft.js +310 -0
  366. package/src/lib/model/ai-automation-draft.js.map +1 -0
  367. package/src/lib/model/ai-automation-outline.d.ts +50 -0
  368. package/src/lib/model/ai-automation-outline.js +262 -0
  369. package/src/lib/model/ai-automation-outline.js.map +1 -0
  370. package/src/lib/model/ai-build-plan.d.ts +197 -0
  371. package/src/lib/model/ai-build-plan.js +438 -0
  372. package/src/lib/model/ai-build-plan.js.map +1 -0
  373. package/src/lib/model/ai-crm.d.ts +237 -0
  374. package/src/lib/model/ai-crm.js +225 -0
  375. package/src/lib/model/ai-crm.js.map +1 -0
  376. package/src/lib/model/ai-experiment-proposal.d.ts +68 -0
  377. package/src/lib/model/ai-experiment-proposal.js +146 -0
  378. package/src/lib/model/ai-experiment-proposal.js.map +1 -0
  379. package/src/lib/model/ai-experiment.d.ts +309 -0
  380. package/src/lib/model/ai-experiment.js +395 -0
  381. package/src/lib/model/ai-experiment.js.map +1 -0
  382. package/src/lib/model/ai-insight.d.ts +178 -0
  383. package/src/lib/model/ai-insight.js +201 -0
  384. package/src/lib/model/ai-insight.js.map +1 -0
  385. package/src/lib/model/ai-jobs.types.d.ts +412 -0
  386. package/src/lib/model/ai-jobs.types.js +42 -0
  387. package/src/lib/model/ai-jobs.types.js.map +1 -0
  388. package/src/lib/model/ai-page-job.d.ts +92 -0
  389. package/src/lib/model/ai-page-job.js +159 -0
  390. package/src/lib/model/ai-page-job.js.map +1 -0
  391. package/src/lib/model/ai-permissions.d.ts +49 -0
  392. package/src/lib/model/ai-permissions.js +97 -0
  393. package/src/lib/model/ai-permissions.js.map +1 -0
  394. package/src/lib/model/ai-plan-capabilities.d.ts +139 -0
  395. package/src/lib/model/ai-plan-capabilities.js +149 -0
  396. package/src/lib/model/ai-plan-capabilities.js.map +1 -0
  397. package/src/lib/model/ai-products.d.ts +251 -0
  398. package/src/lib/model/ai-products.js +253 -0
  399. package/src/lib/model/ai-products.js.map +1 -0
  400. package/src/lib/model/ai-seo.d.ts +208 -0
  401. package/src/lib/model/ai-seo.js +150 -0
  402. package/src/lib/model/ai-seo.js.map +1 -0
  403. package/src/lib/model/ai-site-inventory.d.ts +164 -0
  404. package/src/lib/model/ai-site-inventory.js +145 -0
  405. package/src/lib/model/ai-site-inventory.js.map +1 -0
  406. package/src/lib/model/ai-site-job.d.ts +247 -0
  407. package/src/lib/model/ai-site-job.js +314 -0
  408. package/src/lib/model/ai-site-job.js.map +1 -0
  409. package/src/lib/model/ai-site-start-seo.d.ts +103 -0
  410. package/src/lib/model/ai-site-start-seo.js +154 -0
  411. package/src/lib/model/ai-site-start-seo.js.map +1 -0
  412. package/src/lib/model/ai-site-start.d.ts +122 -0
  413. package/src/lib/model/ai-site-start.js +159 -0
  414. package/src/lib/model/ai-site-start.js.map +1 -0
  415. package/src/lib/model/ai-site-switch.d.ts +56 -0
  416. package/src/lib/model/ai-site-switch.js +73 -0
  417. package/src/lib/model/ai-site-switch.js.map +1 -0
  418. package/src/lib/model/ai-storefront-claims.d.ts +70 -0
  419. package/src/lib/model/ai-storefront-claims.js +130 -0
  420. package/src/lib/model/ai-storefront-claims.js.map +1 -0
  421. package/src/lib/model/ai-template-subjects.d.ts +82 -0
  422. package/src/lib/model/ai-template-subjects.js +136 -0
  423. package/src/lib/model/ai-template-subjects.js.map +1 -0
  424. package/src/lib/model/ai-theme-proposal.d.ts +210 -0
  425. package/src/lib/model/ai-theme-proposal.js +506 -0
  426. package/src/lib/model/ai-theme-proposal.js.map +1 -0
  427. package/src/lib/model/ai-tokens.d.ts +96 -0
  428. package/src/lib/model/ai-tokens.js +117 -0
  429. package/src/lib/model/ai-tokens.js.map +1 -0
  430. package/src/lib/model/ai-usage-by-user.d.ts +120 -0
  431. package/src/lib/model/ai-usage-by-user.js +139 -0
  432. package/src/lib/model/ai-usage-by-user.js.map +1 -0
  433. package/src/lib/model/ai-workflow-job.d.ts +111 -0
  434. package/src/lib/model/ai-workflow-job.js +183 -0
  435. package/src/lib/model/ai-workflow-job.js.map +1 -0
  436. package/src/lib/model/assist-edit.d.ts +261 -0
  437. package/src/lib/model/assist-edit.js +175 -0
  438. package/src/lib/model/assist-edit.js.map +1 -0
  439. package/src/lib/plugin-config.d.ts +33 -0
  440. package/src/lib/plugin-config.js +118 -0
  441. package/src/lib/plugin-config.js.map +1 -0
  442. package/src/lib/plugin.d.ts +30 -0
  443. package/src/lib/plugin.js +525 -0
  444. package/src/lib/plugin.js.map +1 -0
  445. package/src/lib/providers/anthropic.d.ts +84 -0
  446. package/src/lib/providers/anthropic.js +432 -0
  447. package/src/lib/providers/anthropic.js.map +1 -0
  448. package/src/lib/providers/catalog.d.ts +197 -0
  449. package/src/lib/providers/catalog.js +312 -0
  450. package/src/lib/providers/catalog.js.map +1 -0
  451. package/src/lib/providers/contract.d.ts +464 -0
  452. package/src/lib/providers/contract.js +274 -0
  453. package/src/lib/providers/contract.js.map +1 -0
  454. package/src/lib/providers/model-choice.d.ts +119 -0
  455. package/src/lib/providers/model-choice.js +416 -0
  456. package/src/lib/providers/model-choice.js.map +1 -0
  457. package/src/lib/providers/openai-compatible.d.ts +58 -0
  458. package/src/lib/providers/openai-compatible.js +361 -0
  459. package/src/lib/providers/openai-compatible.js.map +1 -0
  460. package/src/lib/providers/registry.d.ts +49 -0
  461. package/src/lib/providers/registry.js +71 -0
  462. package/src/lib/providers/registry.js.map +1 -0
  463. package/src/lib/providers/routing.d.ts +98 -0
  464. package/src/lib/providers/routing.js +450 -0
  465. package/src/lib/providers/routing.js.map +1 -0
  466. package/src/lib/runtime/ai-abuse-guards.d.ts +113 -0
  467. package/src/lib/runtime/ai-abuse-guards.js +148 -0
  468. package/src/lib/runtime/ai-abuse-guards.js.map +1 -0
  469. package/src/lib/runtime/ai-component-bindings.d.ts +67 -0
  470. package/src/lib/runtime/ai-component-bindings.js +106 -0
  471. package/src/lib/runtime/ai-component-bindings.js.map +1 -0
  472. package/src/lib/runtime/ai-device-audit.d.ts +109 -0
  473. package/src/lib/runtime/ai-device-audit.js +97 -0
  474. package/src/lib/runtime/ai-device-audit.js.map +1 -0
  475. package/src/lib/runtime/ai-doctrine-validators.d.ts +720 -0
  476. package/src/lib/runtime/ai-doctrine-validators.js +3133 -0
  477. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -0
  478. package/src/lib/runtime/ai-doctrine.d.ts +372 -0
  479. package/src/lib/runtime/ai-doctrine.js +944 -0
  480. package/src/lib/runtime/ai-doctrine.js.map +1 -0
  481. package/src/lib/runtime/ai-eval-live.d.ts +321 -0
  482. package/src/lib/runtime/ai-eval-live.js +1257 -0
  483. package/src/lib/runtime/ai-eval-live.js.map +1 -0
  484. package/src/lib/runtime/ai-eval-memory-firestore.d.ts +51 -0
  485. package/src/lib/runtime/ai-eval-memory-firestore.js +183 -0
  486. package/src/lib/runtime/ai-eval-memory-firestore.js.map +1 -0
  487. package/src/lib/runtime/ai-eval.d.ts +441 -0
  488. package/src/lib/runtime/ai-eval.js +1151 -0
  489. package/src/lib/runtime/ai-eval.js.map +1 -0
  490. package/src/lib/runtime/ai-gate.d.ts +130 -0
  491. package/src/lib/runtime/ai-gate.js +272 -0
  492. package/src/lib/runtime/ai-gate.js.map +1 -0
  493. package/src/lib/runtime/ai-generation-bounds.d.ts +24 -0
  494. package/src/lib/runtime/ai-generation-bounds.js +23 -0
  495. package/src/lib/runtime/ai-generation-bounds.js.map +1 -0
  496. package/src/lib/runtime/ai-insight-check.d.ts +76 -0
  497. package/src/lib/runtime/ai-insight-check.js +281 -0
  498. package/src/lib/runtime/ai-insight-check.js.map +1 -0
  499. package/src/lib/runtime/ai-node-tree.d.ts +181 -0
  500. package/src/lib/runtime/ai-node-tree.js +931 -0
  501. package/src/lib/runtime/ai-node-tree.js.map +1 -0
  502. package/src/lib/runtime/ai-page-links.d.ts +79 -0
  503. package/src/lib/runtime/ai-page-links.js +135 -0
  504. package/src/lib/runtime/ai-page-links.js.map +1 -0
  505. package/src/lib/runtime/ai-palette.d.ts +252 -0
  506. package/src/lib/runtime/ai-palette.generated.d.ts +34 -0
  507. package/src/lib/runtime/ai-palette.generated.js +5263 -0
  508. package/src/lib/runtime/ai-palette.generated.js.map +1 -0
  509. package/src/lib/runtime/ai-palette.js +187 -0
  510. package/src/lib/runtime/ai-palette.js.map +1 -0
  511. package/src/lib/runtime/ai-products-generation.d.ts +107 -0
  512. package/src/lib/runtime/ai-products-generation.js +250 -0
  513. package/src/lib/runtime/ai-products-generation.js.map +1 -0
  514. package/src/lib/runtime/ai-repeated-items.d.ts +95 -0
  515. package/src/lib/runtime/ai-repeated-items.js +397 -0
  516. package/src/lib/runtime/ai-repeated-items.js.map +1 -0
  517. package/src/lib/runtime/ai-runtime.d.ts +148 -0
  518. package/src/lib/runtime/ai-runtime.js +237 -0
  519. package/src/lib/runtime/ai-runtime.js.map +1 -0
  520. package/src/lib/runtime/ai-template-examples.d.ts +71 -0
  521. package/src/lib/runtime/ai-template-examples.js +135 -0
  522. package/src/lib/runtime/ai-template-examples.js.map +1 -0
  523. package/src/lib/runtime/assist-answer-cache.d.ts +80 -0
  524. package/src/lib/runtime/assist-answer-cache.js +184 -0
  525. package/src/lib/runtime/assist-answer-cache.js.map +1 -0
  526. package/src/lib/runtime/seo-audit.d.ts +93 -0
  527. package/src/lib/runtime/seo-audit.js +260 -0
  528. package/src/lib/runtime/seo-audit.js.map +1 -0
  529. package/src/lib/runtime/seo-content-fixes.d.ts +41 -0
  530. package/src/lib/runtime/seo-content-fixes.js +168 -0
  531. package/src/lib/runtime/seo-content-fixes.js.map +1 -0
  532. package/src/lib/runtime/seo-fields.d.ts +152 -0
  533. package/src/lib/runtime/seo-fields.js +215 -0
  534. package/src/lib/runtime/seo-fields.js.map +1 -0
  535. package/src/lib/runtime/seo-page-facts.d.ts +61 -0
  536. package/src/lib/runtime/seo-page-facts.js +150 -0
  537. package/src/lib/runtime/seo-page-facts.js.map +1 -0
  538. package/src/lib/runtime/site-inventory.d.ts +63 -0
  539. package/src/lib/runtime/site-inventory.js +230 -0
  540. package/src/lib/runtime/site-inventory.js.map +1 -0
  541. package/src/lib/server/ai-admin-org.d.ts +33 -0
  542. package/src/lib/server/ai-admin-org.js +381 -0
  543. package/src/lib/server/ai-admin-org.js.map +1 -0
  544. package/src/lib/server/ai-admin-orgs-spend.d.ts +40 -0
  545. package/src/lib/server/ai-admin-orgs-spend.js +129 -0
  546. package/src/lib/server/ai-admin-orgs-spend.js.map +1 -0
  547. package/src/lib/server/ai-admin-overage.d.ts +19 -0
  548. package/src/lib/server/ai-admin-overage.js +246 -0
  549. package/src/lib/server/ai-admin-overage.js.map +1 -0
  550. package/src/lib/server/ai-admin-signals.d.ts +34 -0
  551. package/src/lib/server/ai-admin-signals.js +330 -0
  552. package/src/lib/server/ai-admin-signals.js.map +1 -0
  553. package/src/lib/server/ai-admin-user.d.ts +27 -0
  554. package/src/lib/server/ai-admin-user.js +128 -0
  555. package/src/lib/server/ai-admin-user.js.map +1 -0
  556. package/src/lib/server/ai-allotments.d.ts +27 -0
  557. package/src/lib/server/ai-allotments.js +544 -0
  558. package/src/lib/server/ai-allotments.js.map +1 -0
  559. package/src/lib/server/ai-assist-prompts.d.ts +102 -0
  560. package/src/lib/server/ai-assist-prompts.js +207 -0
  561. package/src/lib/server/ai-assist-prompts.js.map +1 -0
  562. package/src/lib/server/ai-assist.d.ts +119 -0
  563. package/src/lib/server/ai-assist.js +517 -0
  564. package/src/lib/server/ai-assist.js.map +1 -0
  565. package/src/lib/server/ai-crm-answer.d.ts +30 -0
  566. package/src/lib/server/ai-crm-answer.js +98 -0
  567. package/src/lib/server/ai-crm-answer.js.map +1 -0
  568. package/src/lib/server/ai-generate-component.d.ts +111 -0
  569. package/src/lib/server/ai-generate-component.js +643 -0
  570. package/src/lib/server/ai-generate-component.js.map +1 -0
  571. package/src/lib/server/ai-host-permissions.d.ts +46 -0
  572. package/src/lib/server/ai-host-permissions.js +204 -0
  573. package/src/lib/server/ai-host-permissions.js.map +1 -0
  574. package/src/lib/server/ai-insight-answer.d.ts +30 -0
  575. package/src/lib/server/ai-insight-answer.js +83 -0
  576. package/src/lib/server/ai-insight-answer.js.map +1 -0
  577. package/src/lib/server/ai-insight-digest-route.d.ts +30 -0
  578. package/src/lib/server/ai-insight-digest-route.js +156 -0
  579. package/src/lib/server/ai-insight-digest-route.js.map +1 -0
  580. package/src/lib/server/ai-jobs-batch.d.ts +48 -0
  581. package/src/lib/server/ai-jobs-batch.js +306 -0
  582. package/src/lib/server/ai-jobs-batch.js.map +1 -0
  583. package/src/lib/server/ai-jobs-beat-route.d.ts +36 -0
  584. package/src/lib/server/ai-jobs-beat-route.js +86 -0
  585. package/src/lib/server/ai-jobs-beat-route.js.map +1 -0
  586. package/src/lib/server/ai-jobs-cancel.d.ts +30 -0
  587. package/src/lib/server/ai-jobs-cancel.js +74 -0
  588. package/src/lib/server/ai-jobs-cancel.js.map +1 -0
  589. package/src/lib/server/ai-jobs-events-route.d.ts +31 -0
  590. package/src/lib/server/ai-jobs-events-route.js +51 -0
  591. package/src/lib/server/ai-jobs-events-route.js.map +1 -0
  592. package/src/lib/server/ai-jobs-events.d.ts +55 -0
  593. package/src/lib/server/ai-jobs-events.js +144 -0
  594. package/src/lib/server/ai-jobs-events.js.map +1 -0
  595. package/src/lib/server/ai-jobs-gate.d.ts +47 -0
  596. package/src/lib/server/ai-jobs-gate.js +106 -0
  597. package/src/lib/server/ai-jobs-gate.js.map +1 -0
  598. package/src/lib/server/ai-jobs-resume.d.ts +23 -0
  599. package/src/lib/server/ai-jobs-resume.js +209 -0
  600. package/src/lib/server/ai-jobs-resume.js.map +1 -0
  601. package/src/lib/server/ai-jobs-route.d.ts +32 -0
  602. package/src/lib/server/ai-jobs-route.js +307 -0
  603. package/src/lib/server/ai-jobs-route.js.map +1 -0
  604. package/src/lib/server/ai-models.d.ts +18 -0
  605. package/src/lib/server/ai-models.js +134 -0
  606. package/src/lib/server/ai-models.js.map +1 -0
  607. package/src/lib/server/ai-seo-apply.d.ts +53 -0
  608. package/src/lib/server/ai-seo-apply.js +294 -0
  609. package/src/lib/server/ai-seo-apply.js.map +1 -0
  610. package/src/lib/server/ai-usage.d.ts +18 -0
  611. package/src/lib/server/ai-usage.js +220 -0
  612. package/src/lib/server/ai-usage.js.map +1 -0
  613. package/src/lib/server/assist-chat.d.ts +234 -0
  614. package/src/lib/server/assist-chat.js +1446 -0
  615. package/src/lib/server/assist-chat.js.map +1 -0
  616. package/src/lib/server/assist-edit-applied.d.ts +22 -0
  617. package/src/lib/server/assist-edit-applied.js +239 -0
  618. package/src/lib/server/assist-edit-applied.js.map +1 -0
  619. package/src/lib/server/assist-edit.d.ts +124 -0
  620. package/src/lib/server/assist-edit.js +1000 -0
  621. package/src/lib/server/assist-edit.js.map +1 -0
  622. package/src/lib/server/assist-feedback.d.ts +31 -0
  623. package/src/lib/server/assist-feedback.js +115 -0
  624. package/src/lib/server/assist-feedback.js.map +1 -0
  625. package/src/lib/server/assist-view-context.d.ts +343 -0
  626. package/src/lib/server/assist-view-context.js +690 -0
  627. package/src/lib/server/assist-view-context.js.map +1 -0
  628. package/src/lib/server/billing-credits.d.ts +59 -0
  629. package/src/lib/server/billing-credits.js +146 -0
  630. package/src/lib/server/billing-credits.js.map +1 -0
  631. package/src/lib/server/billing-overage.d.ts +19 -0
  632. package/src/lib/server/billing-overage.js +337 -0
  633. package/src/lib/server/billing-overage.js.map +1 -0
  634. package/src/lib/server.d.ts +32 -0
  635. package/src/lib/server.js +265 -0
  636. package/src/lib/server.js.map +1 -0
  637. package/src/lib/subprocessors.d.ts +18 -0
  638. package/src/lib/subprocessors.js +52 -0
  639. package/src/lib/subprocessors.js.map +1 -0
  640. package/src/lib/tools/ai-component-tool.d.ts +99 -0
  641. package/src/lib/tools/ai-component-tool.js +369 -0
  642. package/src/lib/tools/ai-component-tool.js.map +1 -0
  643. package/src/lib/tools/ai-crm-tool.d.ts +106 -0
  644. package/src/lib/tools/ai-crm-tool.js +488 -0
  645. package/src/lib/tools/ai-crm-tool.js.map +1 -0
  646. package/src/lib/tools/ai-duplicate-resource-tool.d.ts +71 -0
  647. package/src/lib/tools/ai-duplicate-resource-tool.js +164 -0
  648. package/src/lib/tools/ai-duplicate-resource-tool.js.map +1 -0
  649. package/src/lib/tools/ai-experiment-tool.d.ts +40 -0
  650. package/src/lib/tools/ai-experiment-tool.js +155 -0
  651. package/src/lib/tools/ai-experiment-tool.js.map +1 -0
  652. package/src/lib/tools/ai-insight-tool.d.ts +46 -0
  653. package/src/lib/tools/ai-insight-tool.js +200 -0
  654. package/src/lib/tools/ai-insight-tool.js.map +1 -0
  655. package/src/lib/tools/ai-inventory-lookup-tool.d.ts +86 -0
  656. package/src/lib/tools/ai-inventory-lookup-tool.js +164 -0
  657. package/src/lib/tools/ai-inventory-lookup-tool.js.map +1 -0
  658. package/src/lib/tools/ai-products-tool.d.ts +65 -0
  659. package/src/lib/tools/ai-products-tool.js +644 -0
  660. package/src/lib/tools/ai-products-tool.js.map +1 -0
  661. package/src/lib/tools/ai-seo-tool.d.ts +162 -0
  662. package/src/lib/tools/ai-seo-tool.js +546 -0
  663. package/src/lib/tools/ai-seo-tool.js.map +1 -0
  664. package/src/lib/tools/ai-theme-tool.d.ts +101 -0
  665. package/src/lib/tools/ai-theme-tool.js +562 -0
  666. package/src/lib/tools/ai-theme-tool.js.map +1 -0
  667. package/src/lib/tools/ai-workflow-tool.d.ts +166 -0
  668. package/src/lib/tools/ai-workflow-tool.js +860 -0
  669. package/src/lib/tools/ai-workflow-tool.js.map +1 -0
  670. package/src/lib/usage/ai-allotment-alerts.d.ts +72 -0
  671. package/src/lib/usage/ai-allotment-alerts.js +157 -0
  672. package/src/lib/usage/ai-allotment-alerts.js.map +1 -0
  673. package/src/lib/usage/ai-allotments.d.ts +125 -0
  674. package/src/lib/usage/ai-allotments.js +239 -0
  675. package/src/lib/usage/ai-allotments.js.map +1 -0
  676. package/src/lib/usage/ai-model-sample.d.ts +36 -0
  677. package/src/lib/usage/ai-model-sample.js +68 -0
  678. package/src/lib/usage/ai-model-sample.js.map +1 -0
  679. package/src/lib/usage/ai-usage-alerts.d.ts +55 -0
  680. package/src/lib/usage/ai-usage-alerts.js +114 -0
  681. package/src/lib/usage/ai-usage-alerts.js.map +1 -0
  682. package/src/lib/usage/ai-usage-by-user.d.ts +161 -0
  683. package/src/lib/usage/ai-usage-by-user.js +211 -0
  684. package/src/lib/usage/ai-usage-by-user.js.map +1 -0
  685. package/src/lib/usage/ai-usage-eraser.d.ts +29 -0
  686. package/src/lib/usage/ai-usage-eraser.js +40 -0
  687. package/src/lib/usage/ai-usage-eraser.js.map +1 -0
  688. package/src/lib/usage/ai-usage-meter.d.ts +39 -0
  689. package/src/lib/usage/ai-usage-meter.js +85 -0
  690. package/src/lib/usage/ai-usage-meter.js.map +1 -0
  691. package/src/lib/usage/ai-usage-wire.d.ts +184 -0
  692. package/src/lib/usage/ai-usage-wire.js +98 -0
  693. package/src/lib/usage/ai-usage-wire.js.map +1 -0
  694. package/src/lib/usage/assist-ceiling.d.ts +87 -0
  695. package/src/lib/usage/assist-ceiling.js +110 -0
  696. package/src/lib/usage/assist-ceiling.js.map +1 -0
  697. package/src/lib/usage/assist-free-taste.d.ts +225 -0
  698. package/src/lib/usage/assist-free-taste.js +308 -0
  699. package/src/lib/usage/assist-free-taste.js.map +1 -0
  700. package/src/lib/usage/assist-refusals.d.ts +69 -0
  701. package/src/lib/usage/assist-refusals.js +79 -0
  702. package/src/lib/usage/assist-refusals.js.map +1 -0
  703. package/src/lib/usage/assist-signal-mining.d.ts +375 -0
  704. package/src/lib/usage/assist-signal-mining.js +344 -0
  705. package/src/lib/usage/assist-signal-mining.js.map +1 -0
  706. package/src/lib/usage/assist-usage.d.ts +571 -0
  707. package/src/lib/usage/assist-usage.js +978 -0
  708. package/src/lib/usage/assist-usage.js.map +1 -0
  709. package/src/lib/usage/staff-org-ai.d.ts +242 -0
  710. package/src/lib/usage/staff-org-ai.js +173 -0
  711. package/src/lib/usage/staff-org-ai.js.map +1 -0
  712. package/src/lib/usage/staff-org-usage-ai.d.ts +83 -0
  713. package/src/lib/usage/staff-org-usage-ai.js +59 -0
  714. package/src/lib/usage/staff-org-usage-ai.js.map +1 -0
  715. package/src/lib/usage/staff-orgs-ai-spend.d.ts +83 -0
  716. package/src/lib/usage/staff-orgs-ai-spend.js +114 -0
  717. package/src/lib/usage/staff-orgs-ai-spend.js.map +1 -0
@@ -0,0 +1,547 @@
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
+ */ import { _ as _extends } from "@swc/helpers/_/_extends";
17
+ import { AI_STEP_TIERS } from "../providers/catalog.js";
18
+ import { AI_ROUTING_TABLE, aiModelForStep } from "../providers/routing.js";
19
+ import { aiDoctrineTreeTool, runValidatedGeneration } from "../runtime/ai-doctrine.js";
20
+ import { walkTree } from "../runtime/ai-doctrine-validators.js";
21
+ import { AI_TEXT_LIMITS } from "../runtime/ai-palette.js";
22
+ import { readSiteInventory } from "../runtime/site-inventory.js";
23
+ import { aiEmailProductNote, resolveAiEmailProducts } from "./ai-email-bindings.js";
24
+ import { registerAiJobAdmission } from "./ai-job-admission.js";
25
+ import { aiJobStepBudget } from "./ai-job-budget.js";
26
+ import { aiJobDraftId } from "./ai-job-draft-ids.js";
27
+ import { aiSiteSubdomain } from "./ai-job-drafts.js";
28
+ import { aiConfirmedPlan, aiDoctrineReview, aiGenerationSpent, aiJobBriefLine, aiLimitReview, aiModelNodeIds, aiPlanCreation, aiPlanReferenceLines, aiUnspentOutcome } from "./ai-job-generation.js";
29
+ import { aiPluginDraftAdmissionRefusal, aiPluginDraftWriter } from "./ai-job-plugin-drafts.js";
30
+ import { registerAiJobStep } from "./ai-jobs.js";
31
+ /**
32
+ * The email step (AGL-2912): the generation step of an `email` job, run once a
33
+ * member confirmed the job's plan, and the generation the campaign step
34
+ * drafts its email with.
35
+ *
36
+ * It builds ONE email design from the email palette — sections holding text,
37
+ * buttons, images, dividers, spacers and product blocks, never hand-written
38
+ * HTML, which is not on the email surface — through
39
+ * `runValidatedGeneration('email', …)`, so every building rule holds on the
40
+ * tree, rule 6's brand and rule 17's clip size included. Beside the design the
41
+ * answer carries three subject lines and three preheaders. The door's checks
42
+ * ride `extend`:
43
+ *
44
+ * - every block sits in a section, every button links somewhere, and the
45
+ * copy's only merge tokens are the recipient's own, in text;
46
+ * - exactly as many product blocks as the job binds products;
47
+ * - three different subject lines and preheaders, within their lengths and
48
+ * free of merge tokens, which a subject line does not fill;
49
+ * - and the design RENDERS: the email plugin's writer checks it through the
50
+ * send path's own renderer, reached through the core's resource-drafts
51
+ * seam, and a problem it names is a violation the model is re-asked with.
52
+ *
53
+ * What the model is sent is the brief, the email's name and kind, the
54
+ * confirmed plan and the site inventory, and how many product blocks to place.
55
+ * The products themselves are bound by id after it answers
56
+ * (`ai-email-bindings.ts`); a link to one of the site's pages is completed
57
+ * with the site's address token, which the send fills.
58
+ *
59
+ * The design lands through that same writer: a draft email screen, listed on
60
+ * the Emails page's templates, that no campaign sends until a member picks it.
61
+ * The job never sends, schedules or publishes anything.
62
+ *
63
+ * Like the other generation steps, it runs on the job beat, never at an inline
64
+ * door: it registers the least time its lookup rounds, its answer and its
65
+ * re-ask need (AGL-3035), and runs without extended thinking under a tighter
66
+ * answer ceiling than the doctrine's default for an email, lowered on a tier
67
+ * too slow to answer it inside that time.
68
+ */ /** The resource the email plugin writes an email design under. */ export const AI_EMAIL_DESIGN_RESOURCE = 'emailDesign';
69
+ /** The id the email plugin is registered under. */ export const AI_EMAIL_PLUGIN_ID = 'email';
70
+ /** The longest answer an email may run to; the tree is held to the email budget either way. */ export const AI_JOB_EMAIL_MAX_TOKENS = AI_ROUTING_TABLE['job.email'].maxTokens;
71
+ /**
72
+ * The time an email generation takes (AGL-3035, AGL-3036), for each step kind
73
+ * that runs one: its two inventory-lookup rounds, its answer and its re-ask at
74
+ * the kind's routing ceiling on the tier the kind is served from, fitted to
75
+ * what a beat can give a step. The email step registers the first, and the
76
+ * campaign step — whose email is this same generation — the second.
77
+ */ export const AI_JOB_EMAIL_STEP_BUDGETS = {
78
+ 'job.email': aiJobStepBudget({
79
+ tier: AI_STEP_TIERS['job.email'],
80
+ maxTokens: AI_ROUTING_TABLE['job.email'].maxTokens
81
+ }),
82
+ 'job.campaign': aiJobStepBudget({
83
+ tier: AI_STEP_TIERS['job.campaign'],
84
+ maxTokens: AI_ROUTING_TABLE['job.campaign'].maxTokens
85
+ })
86
+ };
87
+ /** The least time one email step needs before it starts. */ export const AI_JOB_EMAIL_STEP_MINIMUM_MS = AI_JOB_EMAIL_STEP_BUDGETS['job.email'].minimumMs;
88
+ /** How many subject lines, and how many preheaders, an email is written with. */ export const AI_EMAIL_VARIANTS = 3;
89
+ /** A subject line is a headline. */ export const AI_EMAIL_SUBJECT_MAX_CHARS = AI_TEXT_LIMITS.headline;
90
+ /** The longest preheader the campaign send route stores. */ export const AI_EMAIL_PREHEADER_MAX_CHARS = 200;
91
+ /** An email's name when neither the plan nor the job names one. */ export const AI_JOB_EMAIL_DEFAULT_NAME = 'New email';
92
+ /** A job's failure when the site has no email design writer. */ export const AI_EMAIL_UNAVAILABLE_COPY = 'Email is not available on this site.';
93
+ /** A job's failure when a design that passed every check could not be stored. */ export const AI_EMAIL_SAVE_FAILURE_COPY = 'The email was written but could not be saved. Try the job again.';
94
+ /**
95
+ * The kinds of email a job may carry, as `inputs.emailType`, and how the
96
+ * prompt says each.
97
+ *
98
+ * A member picks one for an email of their own; a job the platform composes
99
+ * sets one for itself, which is what `reply` is for (AGL-2918, named by the
100
+ * site model's `AI_SITE_EMAIL_TYPE`). A scaffold's email answers one person
101
+ * who wrote in, and none of the five campaign kinds says that: the nearest,
102
+ * `welcome`, names a signup the site has not had, and a kind that
103
+ * misdescribes the email is worse than no kind at all, because this line is
104
+ * what the model reads first.
105
+ *
106
+ * Every label is the step's own words, so none of them may name a list, a
107
+ * recipient or the people an email is sent to — the same rule the step's
108
+ * instructions keep, held over the whole catalog by `ai-job-email-step.spec`.
109
+ */ export const AI_EMAIL_TYPES = {
110
+ welcome: 'a welcome email for someone who just signed up',
111
+ newsletter: 'a newsletter',
112
+ launch: 'a launch announcement',
113
+ abandonedCart: 'a reminder about items left in a cart',
114
+ eventReminder: 'a reminder about an upcoming event',
115
+ reply: 'a reply to somebody who got in touch through the site'
116
+ };
117
+ /** The merge tokens a generated email's copy may carry: the recipient's own, which each send fills. */ export const AI_EMAIL_TEXT_MERGE_TOKENS = [
118
+ 'contact.firstName',
119
+ 'contact.name',
120
+ 'contact.email'
121
+ ];
122
+ /** The token the send fills with the site's address, set in front of a link to one of its pages. */ export const AI_EMAIL_SITE_URL_TOKEN = '{{site.url}}';
123
+ /** The email step's own instructions, cached after the doctrine. */ export const AI_JOB_EMAIL_INSTRUCTIONS = [
124
+ {
125
+ text: [
126
+ 'You write one marketing email for the owner of a website: its design as one flat node map, three subject lines and three preheaders. Answer with submit_email.',
127
+ 'The root is the document wrapper (div, id "_@_") and holds only Email sections (emailSection). Each section is a band holding the email’s blocks from top to bottom: Email text (emailText), Email buttons (emailButton), Email images (emailImage), Email dividers (emailDivider), Email spacers (emailSpacer) and, only when the job binds products, Email product blocks (emailProduct).',
128
+ 'Open with a heading (emailText with variant heading), keep each paragraph short, and give the email one main call to action as a button. Greet the reader by first name with {{contact.firstName}} where a greeting fits. The only merge tokens are {{contact.firstName}}, {{contact.name}} and {{contact.email}}, and only in text: never in a link, a subject line or a preheader.',
129
+ 'Every button links somewhere: a page of the site by its address from the site inventory, such as /menu, which is completed with the site’s domain when the email is sent, or a full https address the brief gives.',
130
+ 'An image has an empty src for the owner to fill from the media library, alt text describing the picture it should show, and a width of 600 or less.',
131
+ 'Place exactly as many Email product blocks as the job binds products, one for each, in the order the brief names them. Each shows its product’s current name, price and picture when the email is sent, so never type a product’s price.',
132
+ 'Leave out an unsubscribe link and a postal address: the platform adds the unsubscribe link to every campaign email. A fact the brief does not give, such as a date or a place, goes in square brackets.',
133
+ `Subject lines: three that take different approaches, such as direct, curious and benefit-led, each at most ${AI_EMAIL_SUBJECT_MAX_CHARS} characters and best under 60, with no merge token. Preheaders: three, each extending the subject line in the same position, at most ${AI_EMAIL_PREHEADER_MAX_CHARS} characters and best between 40 and 110.`
134
+ ].join('\n')
135
+ }
136
+ ];
137
+ const DOCTRINE_EMAIL_TOOL = aiDoctrineTreeTool('email');
138
+ /** The doctrine's email tree tool, with the subject lines and preheaders beside the tree. */ export const AI_JOB_EMAIL_TOOL = {
139
+ name: DOCTRINE_EMAIL_TOOL.name,
140
+ description: 'Submit the email: its design as one flat node map, three subject lines and three preheaders.',
141
+ strict: true,
142
+ inputSchema: {
143
+ type: 'object',
144
+ additionalProperties: false,
145
+ required: [
146
+ 'tree',
147
+ 'subjects',
148
+ 'preheaders'
149
+ ],
150
+ properties: {
151
+ tree: DOCTRINE_EMAIL_TOOL.inputSchema['properties']['tree'],
152
+ subjects: {
153
+ type: 'array',
154
+ items: {
155
+ type: 'string'
156
+ },
157
+ description: 'Three subject lines that take different approaches, the strongest first.'
158
+ },
159
+ preheaders: {
160
+ type: 'array',
161
+ items: {
162
+ type: 'string'
163
+ },
164
+ description: 'Three preheaders, each extending the subject line in the same position.'
165
+ }
166
+ }
167
+ }
168
+ };
169
+ /** How the prompt names the kind of email a member picked; `null` for none or an unknown one. */ export function aiEmailTypeLabel(value) {
170
+ return typeof value === 'string' && Object.prototype.hasOwnProperty.call(AI_EMAIL_TYPES, value) ? AI_EMAIL_TYPES[value] : null;
171
+ }
172
+ /** A name the member gave the job, on one line and bounded; empty when none. */ export function aiJobInputName(job) {
173
+ var _job_inputs;
174
+ const raw = (_job_inputs = job.inputs) == null ? void 0 : _job_inputs['name'];
175
+ return typeof raw === 'string' ? raw.replace(/\s+/g, ' ').trim().slice(0, 120) : '';
176
+ }
177
+ /** The email job as the generation's user turn. */ export function aiJobEmailPrompt(job, plan, heading, products) {
178
+ var _job_inputs;
179
+ const lines = heading ? [
180
+ heading
181
+ ] : [];
182
+ const type = aiEmailTypeLabel((_job_inputs = job.inputs) == null ? void 0 : _job_inputs['emailType']);
183
+ if (type) lines.push(`Kind of email: ${type}`);
184
+ lines.push(aiJobBriefLine(job), ...aiPlanReferenceLines(plan));
185
+ lines.push(products > 0 ? `Products bound to this email: ${products}. Place exactly ${products} Email product ${products === 1 ? 'block' : 'blocks'}.` : 'No products are bound to this email: place no Email product block.');
186
+ return lines.join('\n');
187
+ }
188
+ function oneLine(value) {
189
+ return value.replace(/\s+/g, ' ').trim();
190
+ }
191
+ export function parseAiEmailCopy(answer) {
192
+ const lines = (value)=>Array.isArray(value) ? value.filter((entry)=>typeof entry === 'string').map(oneLine) : [];
193
+ return {
194
+ subjects: lines(answer['subjects']),
195
+ preheaders: lines(answer['preheaders'])
196
+ };
197
+ }
198
+ /** The copy's own rules: three different lines of each, within their lengths, with no merge token. */ export function aiEmailCopyViolations(copy) {
199
+ const violations = [];
200
+ const distinct = (lines)=>new Set(lines.filter(Boolean).map((line)=>line.toLowerCase())).size;
201
+ if (copy.subjects.length !== AI_EMAIL_VARIANTS || distinct(copy.subjects) !== AI_EMAIL_VARIANTS) {
202
+ violations.push({
203
+ rule: null,
204
+ code: 'email-subjects',
205
+ message: `Write exactly ${AI_EMAIL_VARIANTS} different subject lines.`
206
+ });
207
+ }
208
+ if (copy.preheaders.length !== AI_EMAIL_VARIANTS || distinct(copy.preheaders) !== AI_EMAIL_VARIANTS) {
209
+ violations.push({
210
+ rule: null,
211
+ code: 'email-preheaders',
212
+ message: `Write exactly ${AI_EMAIL_VARIANTS} different preheaders, one for each subject line.`
213
+ });
214
+ }
215
+ if (copy.subjects.some((line)=>line.length > AI_EMAIL_SUBJECT_MAX_CHARS)) {
216
+ violations.push({
217
+ rule: null,
218
+ code: 'email-subject-length',
219
+ message: `A subject line is over ${AI_EMAIL_SUBJECT_MAX_CHARS} characters. Keep each within ${AI_EMAIL_SUBJECT_MAX_CHARS}, and best under 60.`
220
+ });
221
+ }
222
+ if (copy.preheaders.some((line)=>line.length > AI_EMAIL_PREHEADER_MAX_CHARS)) {
223
+ violations.push({
224
+ rule: null,
225
+ code: 'email-preheader-length',
226
+ message: `A preheader is over ${AI_EMAIL_PREHEADER_MAX_CHARS} characters. Keep each within ${AI_EMAIL_PREHEADER_MAX_CHARS}.`
227
+ });
228
+ }
229
+ if ([
230
+ ...copy.subjects,
231
+ ...copy.preheaders
232
+ ].some((line)=>line.includes('{{'))) {
233
+ violations.push({
234
+ rule: null,
235
+ code: 'email-header-token',
236
+ message: 'A subject line or preheader carries a merge token, which is not filled there. Write them without {{…}}.'
237
+ });
238
+ }
239
+ return violations;
240
+ }
241
+ const MERGE_TOKEN = /\{\{\s*([^}]*?)\s*\}\}/g;
242
+ function visitsOf(tree) {
243
+ return walkTree({
244
+ rootId: tree.rootId,
245
+ nodes: tree.nodes
246
+ });
247
+ }
248
+ /** The design's own rules, on a tree the doctrine admitted. */ export function aiEmailTreeViolations(tree, products) {
249
+ var _ref;
250
+ var _tree_nodes_tree_rootId;
251
+ const violations = [];
252
+ const loose = ((_ref = (_tree_nodes_tree_rootId = tree.nodes[tree.rootId]) == null ? void 0 : _tree_nodes_tree_rootId.nodes) != null ? _ref : []).filter((id)=>{
253
+ var _tree_nodes_id;
254
+ return ((_tree_nodes_id = tree.nodes[id]) == null ? void 0 : _tree_nodes_id.componentId) !== 'emailSection';
255
+ });
256
+ if (loose.length) {
257
+ violations.push({
258
+ rule: null,
259
+ code: 'email-loose-block',
260
+ message: 'A block sits outside every Email section. Put each block inside a section.',
261
+ nodeIds: aiModelNodeIds(loose, tree.sourceIds)
262
+ });
263
+ }
264
+ const tokens = new Set();
265
+ const tokenNodes = [];
266
+ const unlinked = [];
267
+ let placed = 0;
268
+ for (const { id, node } of visitsOf(tree)){
269
+ var _node_props;
270
+ var _node_props1;
271
+ for (const value of Object.values((_node_props = node.props) != null ? _node_props : {})){
272
+ if (typeof value !== 'string') continue;
273
+ for (const match of value.matchAll(MERGE_TOKEN)){
274
+ if (!AI_EMAIL_TEXT_MERGE_TOKENS.includes(match[1])) {
275
+ tokens.add(`{{${match[1]}}}`);
276
+ tokenNodes.push(id);
277
+ }
278
+ }
279
+ }
280
+ if (node.componentId === 'emailButton' && typeof ((_node_props1 = node.props) == null ? void 0 : _node_props1['href']) !== 'string') {
281
+ unlinked.push(id);
282
+ }
283
+ if (node.componentId === 'emailProduct') placed += 1;
284
+ }
285
+ if (tokens.size) {
286
+ violations.push({
287
+ rule: null,
288
+ code: 'email-merge-token',
289
+ message: `This email writes ${[
290
+ ...tokens
291
+ ].slice(0, 3).join(', ')}, which a generated email may not use. Use only {{contact.firstName}}, {{contact.name}} or {{contact.email}}, and only in text.`,
292
+ nodeIds: aiModelNodeIds([
293
+ ...new Set(tokenNodes)
294
+ ], tree.sourceIds)
295
+ });
296
+ }
297
+ if (unlinked.length) {
298
+ violations.push({
299
+ rule: null,
300
+ code: 'email-button-link',
301
+ message: 'An Email button links nowhere. Link each to a page of the site by its address, such as /menu, or to a full https address the brief gives.',
302
+ nodeIds: aiModelNodeIds(unlinked, tree.sourceIds)
303
+ });
304
+ }
305
+ if (placed !== products) {
306
+ violations.push({
307
+ rule: null,
308
+ code: 'email-product-count',
309
+ message: products ? `This email binds ${products} ${products === 1 ? 'product' : 'products'}: place exactly ${products} Email product ${products === 1 ? 'block' : 'blocks'}.` : 'No products are bound to this email: remove the Email product blocks.'
310
+ });
311
+ }
312
+ return violations;
313
+ }
314
+ /**
315
+ * The design as it is stored: a link to one of the site's pages completed with
316
+ * the site's address token, and each product block bound, in document order,
317
+ * to the next product the job binds.
318
+ */ export function aiEmailDesignNodes(tree, productIds) {
319
+ const nodes = _extends({}, tree.nodes);
320
+ let next = 0;
321
+ for (const { id, node } of visitsOf(tree)){
322
+ var _node_props;
323
+ const props = _extends({}, (_node_props = node.props) != null ? _node_props : {});
324
+ let changed = false;
325
+ const href = props['href'];
326
+ if (typeof href === 'string' && href.startsWith('/') && !href.startsWith('//')) {
327
+ props['href'] = `${AI_EMAIL_SITE_URL_TOKEN}${href}`;
328
+ changed = true;
329
+ }
330
+ if (node.componentId === 'emailProduct') {
331
+ const productId = productIds[next];
332
+ next += 1;
333
+ if (productId) {
334
+ props['productId'] = productId;
335
+ changed = true;
336
+ }
337
+ }
338
+ if (changed) nodes[id] = _extends({}, nodes[id], {
339
+ props
340
+ });
341
+ }
342
+ return nodes;
343
+ }
344
+ /** The content the email plugin's writer stores a design from. */ export function aiEmailDesignContent(nodes, copy) {
345
+ var _copy_subjects_, _copy_preheaders_;
346
+ return {
347
+ nodes,
348
+ subject: (_copy_subjects_ = copy.subjects[0]) != null ? _copy_subjects_ : '',
349
+ preheader: (_copy_preheaders_ = copy.preheaders[0]) != null ? _copy_preheaders_ : '',
350
+ subjectVariants: copy.subjects,
351
+ preheaderVariants: copy.preheaders
352
+ };
353
+ }
354
+ /** What the email plugin's renderer says about the design, as violations the model is re-asked with. */ export function aiEmailRenderViolations(design, hostId, nodes, copy) {
355
+ const checked = design.check(aiEmailDesignContent(nodes, copy), {
356
+ hostId
357
+ });
358
+ if (checked.ok === true) return [];
359
+ return [
360
+ ...new Set(checked.problems)
361
+ ].map((problem)=>({
362
+ rule: null,
363
+ code: 'email-render',
364
+ message: `The email does not render as written: ${problem}.`
365
+ }));
366
+ }
367
+ /** Generates one email under the doctrine, with the email's own checks riding `extend`. */ export async function generateAiEmail(input) {
368
+ var _ref, _ref1;
369
+ // The answer `extend` saw last is the one the doctrine kept when it keeps one.
370
+ let last = null;
371
+ const result = await runValidatedGeneration('email', _extends({
372
+ step: input.step,
373
+ model: input.model,
374
+ instructions: AI_JOB_EMAIL_INSTRUCTIONS,
375
+ inventory: input.inventory,
376
+ messages: [
377
+ {
378
+ role: 'user',
379
+ content: aiJobEmailPrompt(input.job, input.plan, input.heading, input.products.ids.length)
380
+ }
381
+ ],
382
+ tool: AI_JOB_EMAIL_TOOL,
383
+ maxTokens: AI_JOB_EMAIL_STEP_BUDGETS[input.step].maxTokens(input.model),
384
+ thinking: 'off',
385
+ extend: (tree, answer)=>{
386
+ const copy = parseAiEmailCopy(answer);
387
+ const nodes = aiEmailDesignNodes(tree, input.products.ids);
388
+ last = {
389
+ copy,
390
+ nodes
391
+ };
392
+ const violations = [
393
+ ...aiEmailTreeViolations(tree, input.products.ids.length),
394
+ ...aiEmailCopyViolations(copy)
395
+ ];
396
+ // Rendered once the design's own rules hold, so a problem is named once.
397
+ return violations.length ? violations : aiEmailRenderViolations(input.design, input.hostId, nodes, copy);
398
+ }
399
+ }, input.signal ? {
400
+ signal: input.signal
401
+ } : {}));
402
+ const kept = result.status === 'ok' ? last : null;
403
+ return {
404
+ result,
405
+ copy: (_ref = kept == null ? void 0 : kept.copy) != null ? _ref : null,
406
+ nodes: (_ref1 = kept == null ? void 0 : kept.nodes) != null ? _ref1 : null
407
+ };
408
+ }
409
+ /** An email design as the job's output. */ export function aiEmailDesignOutput(record, place, note) {
410
+ return _extends({
411
+ resource: 'emailScreen',
412
+ id: record.id,
413
+ versionId: record.versionId,
414
+ hostId: place.hostId,
415
+ hostSubdomain: place.hostSubdomain,
416
+ label: record.name
417
+ }, note ? {
418
+ note
419
+ } : {});
420
+ }
421
+ /** An email job is admitted for a site of its org with email on and room for a design. */ export const aiEmailJobAdmission = (context)=>aiPluginDraftAdmissionRefusal(context, {
422
+ kind: 'email',
423
+ drafts: [
424
+ {
425
+ resource: AI_EMAIL_DESIGN_RESOURCE,
426
+ pluginId: AI_EMAIL_PLUGIN_ID,
427
+ label: 'Email'
428
+ }
429
+ ]
430
+ });
431
+ export function createAiJobEmailStep(deps = {}) {
432
+ var _deps_readInventory, _deps_writerFor;
433
+ const readInventory = (_deps_readInventory = deps.readInventory) != null ? _deps_readInventory : readSiteInventory;
434
+ const writerFor = (_deps_writerFor = deps.writerFor) != null ? _deps_writerFor : aiPluginDraftWriter;
435
+ return async ({ job, now, signal, firestore, modelFor })=>{
436
+ var _ref, _orgSnapshot_data;
437
+ var _aiPlanCreation;
438
+ const hostId = job.hostId;
439
+ if (!hostId) throw new Error('an email job names no site, and its admission refuses one');
440
+ // The switch's answer for this job, else the routing table's (AGL-2942).
441
+ const model = (_ref = modelFor == null ? void 0 : modelFor('job.email')) != null ? _ref : aiModelForStep('job.email');
442
+ const design = writerFor(AI_EMAIL_DESIGN_RESOURCE);
443
+ if (!design) return _extends({}, aiUnspentOutcome(model), {
444
+ failure: AI_EMAIL_UNAVAILABLE_COPY
445
+ });
446
+ // A run cut off after its design was written reports that design, found by the id the job recorded.
447
+ const draftId = aiJobDraftId(job, 'email');
448
+ const written = await design.read({
449
+ hostId,
450
+ id: draftId
451
+ });
452
+ if (written) {
453
+ const hostSubdomain = await aiSiteSubdomain(firestore, hostId);
454
+ return aiUnspentOutcome(model, {
455
+ outputs: [
456
+ aiEmailDesignOutput(written, {
457
+ hostId,
458
+ hostSubdomain
459
+ }, null)
460
+ ]
461
+ });
462
+ }
463
+ const [inventory, orgSnapshot, products, hostSubdomain] = await Promise.all([
464
+ readInventory(job.orgId, hostId, {
465
+ firestore
466
+ }),
467
+ firestore.collection('orgs').doc(job.orgId).get(),
468
+ resolveAiEmailProducts(firestore, {
469
+ hostId,
470
+ brief: job.brief,
471
+ inputs: job.inputs
472
+ }),
473
+ aiSiteSubdomain(firestore, hostId)
474
+ ]);
475
+ const org = (_orgSnapshot_data = orgSnapshot.data()) != null ? _orgSnapshot_data : null;
476
+ const context = {
477
+ orgId: job.orgId,
478
+ hostId,
479
+ uid: job.createdBy,
480
+ org,
481
+ now
482
+ };
483
+ const refusal = await design.refusal(context);
484
+ if (refusal) {
485
+ return refusal.status === 403 ? aiUnspentOutcome(model, {
486
+ review: aiLimitReview(refusal.error)
487
+ }) : _extends({}, aiUnspentOutcome(model), {
488
+ failure: refusal.error
489
+ });
490
+ }
491
+ const plan = aiConfirmedPlan(job);
492
+ const name = ((_aiPlanCreation = aiPlanCreation(plan, 'email')) == null ? void 0 : _aiPlanCreation.name) || aiJobInputName(job) || AI_JOB_EMAIL_DEFAULT_NAME;
493
+ const generated = await generateAiEmail(_extends({
494
+ job,
495
+ step: 'job.email',
496
+ model,
497
+ heading: `Email name: ${name}`,
498
+ plan,
499
+ inventory,
500
+ hostId,
501
+ products,
502
+ design
503
+ }, signal ? {
504
+ signal
505
+ } : {}));
506
+ const { result } = generated;
507
+ const spent = aiGenerationSpent(result);
508
+ if (result.status === 'refused') return _extends({}, spent, {
509
+ refused: true
510
+ });
511
+ if (result.status === 'needs_input') return _extends({}, spent, {
512
+ review: aiDoctrineReview(result)
513
+ });
514
+ if (!generated.copy || !generated.nodes) return _extends({}, spent, {
515
+ failure: AI_EMAIL_SAVE_FAILURE_COPY
516
+ });
517
+ const write = await design.write(_extends({}, context, {
518
+ id: draftId,
519
+ name,
520
+ content: aiEmailDesignContent(generated.nodes, generated.copy)
521
+ }));
522
+ if (write.ok === false) {
523
+ return write.status === 403 ? _extends({}, spent, {
524
+ review: aiLimitReview(write.error)
525
+ }) : _extends({}, spent, {
526
+ failure: AI_EMAIL_SAVE_FAILURE_COPY
527
+ });
528
+ }
529
+ return _extends({}, spent, {
530
+ outputs: [
531
+ aiEmailDesignOutput(write, {
532
+ hostId,
533
+ hostSubdomain
534
+ }, aiEmailProductNote(products))
535
+ ]
536
+ });
537
+ };
538
+ }
539
+ export const runAiJobEmailStep = createAiJobEmailStep();
540
+ /** Registers the email step and the check a email job passes before it is created or resumed. */ export function registerAiEmailJob() {
541
+ registerAiJobStep('email', runAiJobEmailStep, {
542
+ minimumMs: AI_JOB_EMAIL_STEP_MINIMUM_MS
543
+ });
544
+ registerAiJobAdmission('email', aiEmailJobAdmission);
545
+ }
546
+
547
+ //# sourceMappingURL=ai-job-email-step.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-email-step.ts"],"sourcesContent":["/**\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 {\n PluginDraftRecord,\n PluginResourceDraftWriter,\n} from '@aglyn/aglyn/plugin-manager/plugin-resource-drafts'\nimport type { NodesMap } from '@aglyn/aglyn/types/nodes'\nimport type { AiJob, AiJobOutput, AiJobPlan } from '../model/ai-jobs.types'\nimport type { AiSiteInventory } from '../model/ai-site-inventory'\nimport { AI_STEP_TIERS, type AiStepKind } from '../providers/catalog'\nimport { AI_ROUTING_TABLE, aiModelForStep } from '../providers/routing'\nimport {\n aiDoctrineTreeTool,\n runValidatedGeneration,\n type AiValidatedGeneration,\n type AiValidatedTree,\n} from '../runtime/ai-doctrine'\nimport {\n walkTree,\n type AiDoctrineNode,\n type AiDoctrineViolation,\n} from '../runtime/ai-doctrine-validators'\nimport { AI_TEXT_LIMITS } from '../runtime/ai-palette'\nimport type { AiSystemBlock, AiTool } from '../runtime/ai-runtime'\nimport { readSiteInventory } from '../runtime/site-inventory'\nimport {\n aiEmailProductNote,\n resolveAiEmailProducts,\n type AiEmailProductBinding,\n} from './ai-email-bindings'\nimport { registerAiJobAdmission, type AiJobAdmission } from './ai-job-admission'\nimport { aiJobStepBudget, type AiJobStepBudget } from './ai-job-budget'\nimport { aiJobDraftId } from './ai-job-draft-ids'\nimport { aiSiteSubdomain } from './ai-job-drafts'\nimport {\n aiConfirmedPlan,\n aiDoctrineReview,\n aiGenerationSpent,\n aiJobBriefLine,\n aiLimitReview,\n aiModelNodeIds,\n aiPlanCreation,\n aiPlanReferenceLines,\n aiUnspentOutcome,\n} from './ai-job-generation'\nimport {\n aiPluginDraftAdmissionRefusal,\n aiPluginDraftWriter,\n type AiPluginDraftWriterLookup,\n} from './ai-job-plugin-drafts'\nimport type { AiJobStepOutcome, AiJobStepRunner } from './ai-job-text-step'\nimport { registerAiJobStep } from './ai-jobs'\n\n/**\n * The email step (AGL-2912): the generation step of an `email` job, run once a\n * member confirmed the job's plan, and the generation the campaign step\n * drafts its email with.\n *\n * It builds ONE email design from the email palette — sections holding text,\n * buttons, images, dividers, spacers and product blocks, never hand-written\n * HTML, which is not on the email surface — through\n * `runValidatedGeneration('email', …)`, so every building rule holds on the\n * tree, rule 6's brand and rule 17's clip size included. Beside the design the\n * answer carries three subject lines and three preheaders. The door's checks\n * ride `extend`:\n *\n * - every block sits in a section, every button links somewhere, and the\n * copy's only merge tokens are the recipient's own, in text;\n * - exactly as many product blocks as the job binds products;\n * - three different subject lines and preheaders, within their lengths and\n * free of merge tokens, which a subject line does not fill;\n * - and the design RENDERS: the email plugin's writer checks it through the\n * send path's own renderer, reached through the core's resource-drafts\n * seam, and a problem it names is a violation the model is re-asked with.\n *\n * What the model is sent is the brief, the email's name and kind, the\n * confirmed plan and the site inventory, and how many product blocks to place.\n * The products themselves are bound by id after it answers\n * (`ai-email-bindings.ts`); a link to one of the site's pages is completed\n * with the site's address token, which the send fills.\n *\n * The design lands through that same writer: a draft email screen, listed on\n * the Emails page's templates, that no campaign sends until a member picks it.\n * The job never sends, schedules or publishes anything.\n *\n * Like the other generation steps, it runs on the job beat, never at an inline\n * door: it registers the least time its lookup rounds, its answer and its\n * re-ask need (AGL-3035), and runs without extended thinking under a tighter\n * answer ceiling than the doctrine's default for an email, lowered on a tier\n * too slow to answer it inside that time.\n */\n\n/** The resource the email plugin writes an email design under. */\nexport const AI_EMAIL_DESIGN_RESOURCE = 'emailDesign'\n\n/** The id the email plugin is registered under. */\nexport const AI_EMAIL_PLUGIN_ID = 'email'\n\n/** The longest answer an email may run to; the tree is held to the email budget either way. */\nexport const AI_JOB_EMAIL_MAX_TOKENS = AI_ROUTING_TABLE['job.email'].maxTokens\n\n/**\n * The time an email generation takes (AGL-3035, AGL-3036), for each step kind\n * that runs one: its two inventory-lookup rounds, its answer and its re-ask at\n * the kind's routing ceiling on the tier the kind is served from, fitted to\n * what a beat can give a step. The email step registers the first, and the\n * campaign step — whose email is this same generation — the second.\n */\nexport const AI_JOB_EMAIL_STEP_BUDGETS: Readonly<\n Record<AiEmailGenerationInput['step'], AiJobStepBudget>\n> = {\n 'job.email': aiJobStepBudget({\n tier: AI_STEP_TIERS['job.email'],\n maxTokens: AI_ROUTING_TABLE['job.email'].maxTokens,\n }),\n 'job.campaign': aiJobStepBudget({\n tier: AI_STEP_TIERS['job.campaign'],\n maxTokens: AI_ROUTING_TABLE['job.campaign'].maxTokens,\n }),\n}\n\n/** The least time one email step needs before it starts. */\nexport const AI_JOB_EMAIL_STEP_MINIMUM_MS = AI_JOB_EMAIL_STEP_BUDGETS['job.email'].minimumMs\n\n/** How many subject lines, and how many preheaders, an email is written with. */\nexport const AI_EMAIL_VARIANTS = 3\n\n/** A subject line is a headline. */\nexport const AI_EMAIL_SUBJECT_MAX_CHARS = AI_TEXT_LIMITS.headline\n\n/** The longest preheader the campaign send route stores. */\nexport const AI_EMAIL_PREHEADER_MAX_CHARS = 200\n\n/** An email's name when neither the plan nor the job names one. */\nexport const AI_JOB_EMAIL_DEFAULT_NAME = 'New email'\n\n/** A job's failure when the site has no email design writer. */\nexport const AI_EMAIL_UNAVAILABLE_COPY = 'Email is not available on this site.'\n\n/** A job's failure when a design that passed every check could not be stored. */\nexport const AI_EMAIL_SAVE_FAILURE_COPY =\n 'The email was written but could not be saved. Try the job again.'\n\n/**\n * The kinds of email a job may carry, as `inputs.emailType`, and how the\n * prompt says each.\n *\n * A member picks one for an email of their own; a job the platform composes\n * sets one for itself, which is what `reply` is for (AGL-2918, named by the\n * site model's `AI_SITE_EMAIL_TYPE`). A scaffold's email answers one person\n * who wrote in, and none of the five campaign kinds says that: the nearest,\n * `welcome`, names a signup the site has not had, and a kind that\n * misdescribes the email is worse than no kind at all, because this line is\n * what the model reads first.\n *\n * Every label is the step's own words, so none of them may name a list, a\n * recipient or the people an email is sent to — the same rule the step's\n * instructions keep, held over the whole catalog by `ai-job-email-step.spec`.\n */\nexport const AI_EMAIL_TYPES = {\n welcome: 'a welcome email for someone who just signed up',\n newsletter: 'a newsletter',\n launch: 'a launch announcement',\n abandonedCart: 'a reminder about items left in a cart',\n eventReminder: 'a reminder about an upcoming event',\n reply: 'a reply to somebody who got in touch through the site',\n} as const\n\nexport type AiEmailType = keyof typeof AI_EMAIL_TYPES\n\n/** The merge tokens a generated email's copy may carry: the recipient's own, which each send fills. */\nexport const AI_EMAIL_TEXT_MERGE_TOKENS: readonly string[] = [\n 'contact.firstName',\n 'contact.name',\n 'contact.email',\n]\n\n/** The token the send fills with the site's address, set in front of a link to one of its pages. */\nexport const AI_EMAIL_SITE_URL_TOKEN = '{{site.url}}'\n\n/** The email step's own instructions, cached after the doctrine. */\nexport const AI_JOB_EMAIL_INSTRUCTIONS: readonly AiSystemBlock[] = [\n {\n text: [\n 'You write one marketing email for the owner of a website: its design as one flat node map, three subject lines and three preheaders. Answer with submit_email.',\n 'The root is the document wrapper (div, id \"_@_\") and holds only Email sections (emailSection). Each section is a band holding the email’s blocks from top to bottom: Email text (emailText), Email buttons (emailButton), Email images (emailImage), Email dividers (emailDivider), Email spacers (emailSpacer) and, only when the job binds products, Email product blocks (emailProduct).',\n 'Open with a heading (emailText with variant heading), keep each paragraph short, and give the email one main call to action as a button. Greet the reader by first name with {{contact.firstName}} where a greeting fits. The only merge tokens are {{contact.firstName}}, {{contact.name}} and {{contact.email}}, and only in text: never in a link, a subject line or a preheader.',\n 'Every button links somewhere: a page of the site by its address from the site inventory, such as /menu, which is completed with the site’s domain when the email is sent, or a full https address the brief gives.',\n 'An image has an empty src for the owner to fill from the media library, alt text describing the picture it should show, and a width of 600 or less.',\n 'Place exactly as many Email product blocks as the job binds products, one for each, in the order the brief names them. Each shows its product’s current name, price and picture when the email is sent, so never type a product’s price.',\n 'Leave out an unsubscribe link and a postal address: the platform adds the unsubscribe link to every campaign email. A fact the brief does not give, such as a date or a place, goes in square brackets.',\n `Subject lines: three that take different approaches, such as direct, curious and benefit-led, each at most ${AI_EMAIL_SUBJECT_MAX_CHARS} characters and best under 60, with no merge token. Preheaders: three, each extending the subject line in the same position, at most ${AI_EMAIL_PREHEADER_MAX_CHARS} characters and best between 40 and 110.`,\n ].join('\\n'),\n },\n]\n\nconst DOCTRINE_EMAIL_TOOL = aiDoctrineTreeTool('email')\n\n/** The doctrine's email tree tool, with the subject lines and preheaders beside the tree. */\nexport const AI_JOB_EMAIL_TOOL: AiTool = {\n name: DOCTRINE_EMAIL_TOOL.name,\n description:\n 'Submit the email: its design as one flat node map, three subject lines and three preheaders.',\n strict: true,\n inputSchema: {\n type: 'object',\n additionalProperties: false,\n required: ['tree', 'subjects', 'preheaders'],\n properties: {\n tree: (DOCTRINE_EMAIL_TOOL.inputSchema['properties'] as Record<string, unknown>)['tree'],\n subjects: {\n type: 'array',\n items: { type: 'string' },\n description: 'Three subject lines that take different approaches, the strongest first.',\n },\n preheaders: {\n type: 'array',\n items: { type: 'string' },\n description: 'Three preheaders, each extending the subject line in the same position.',\n },\n },\n },\n}\n\n/** How the prompt names the kind of email a member picked; `null` for none or an unknown one. */\nexport function aiEmailTypeLabel(value: unknown): string | null {\n return typeof value === 'string' && Object.prototype.hasOwnProperty.call(AI_EMAIL_TYPES, value)\n ? AI_EMAIL_TYPES[value as AiEmailType]\n : null\n}\n\n/** A name the member gave the job, on one line and bounded; empty when none. */\nexport function aiJobInputName(job: Pick<AiJob, 'inputs'>): string {\n const raw = job.inputs?.['name']\n return typeof raw === 'string' ? raw.replace(/\\s+/g, ' ').trim().slice(0, 120) : ''\n}\n\n/** The email job as the generation's user turn. */\nexport function aiJobEmailPrompt(\n job: Pick<AiJob, 'brief' | 'inputs'>,\n plan: AiJobPlan | null,\n heading: string | null,\n products: number,\n): string {\n const lines = heading ? [heading] : []\n const type = aiEmailTypeLabel(job.inputs?.['emailType'])\n if (type) lines.push(`Kind of email: ${type}`)\n lines.push(aiJobBriefLine(job), ...aiPlanReferenceLines(plan))\n lines.push(\n products > 0\n ? `Products bound to this email: ${products}. Place exactly ${products} Email product ${\n products === 1 ? 'block' : 'blocks'\n }.`\n : 'No products are bound to this email: place no Email product block.',\n )\n return lines.join('\\n')\n}\n\n/** The subject lines and preheaders an answer carries. */\nexport interface AiEmailCopy {\n subjects: string[]\n preheaders: string[]\n}\n\nfunction oneLine(value: string): string {\n return value.replace(/\\s+/g, ' ').trim()\n}\n\nexport function parseAiEmailCopy(answer: Readonly<Record<string, unknown>>): AiEmailCopy {\n const lines = (value: unknown) =>\n Array.isArray(value)\n ? value.filter((entry): entry is string => typeof entry === 'string').map(oneLine)\n : []\n return { subjects: lines(answer['subjects']), preheaders: lines(answer['preheaders']) }\n}\n\n/** The copy's own rules: three different lines of each, within their lengths, with no merge token. */\nexport function aiEmailCopyViolations(copy: AiEmailCopy): AiDoctrineViolation[] {\n const violations: AiDoctrineViolation[] = []\n const distinct = (lines: string[]) =>\n new Set(lines.filter(Boolean).map((line) => line.toLowerCase())).size\n if (copy.subjects.length !== AI_EMAIL_VARIANTS || distinct(copy.subjects) !== AI_EMAIL_VARIANTS) {\n violations.push({\n rule: null,\n code: 'email-subjects',\n message: `Write exactly ${AI_EMAIL_VARIANTS} different subject lines.`,\n })\n }\n if (copy.preheaders.length !== AI_EMAIL_VARIANTS || distinct(copy.preheaders) !== AI_EMAIL_VARIANTS) {\n violations.push({\n rule: null,\n code: 'email-preheaders',\n message: `Write exactly ${AI_EMAIL_VARIANTS} different preheaders, one for each subject line.`,\n })\n }\n if (copy.subjects.some((line) => line.length > AI_EMAIL_SUBJECT_MAX_CHARS)) {\n violations.push({\n rule: null,\n code: 'email-subject-length',\n message: `A subject line is over ${AI_EMAIL_SUBJECT_MAX_CHARS} characters. Keep each within ${AI_EMAIL_SUBJECT_MAX_CHARS}, and best under 60.`,\n })\n }\n if (copy.preheaders.some((line) => line.length > AI_EMAIL_PREHEADER_MAX_CHARS)) {\n violations.push({\n rule: null,\n code: 'email-preheader-length',\n message: `A preheader is over ${AI_EMAIL_PREHEADER_MAX_CHARS} characters. Keep each within ${AI_EMAIL_PREHEADER_MAX_CHARS}.`,\n })\n }\n if ([...copy.subjects, ...copy.preheaders].some((line) => line.includes('{{'))) {\n violations.push({\n rule: null,\n code: 'email-header-token',\n message:\n 'A subject line or preheader carries a merge token, which is not filled there. Write them without {{…}}.',\n })\n }\n return violations\n}\n\nconst MERGE_TOKEN = /\\{\\{\\s*([^}]*?)\\s*\\}\\}/g\n\nfunction visitsOf(tree: Pick<AiValidatedTree, 'rootId' | 'nodes'>) {\n return walkTree({\n rootId: tree.rootId,\n nodes: tree.nodes as unknown as Record<string, AiDoctrineNode>,\n })\n}\n\n/** The design's own rules, on a tree the doctrine admitted. */\nexport function aiEmailTreeViolations(tree: AiValidatedTree, products: number): AiDoctrineViolation[] {\n const violations: AiDoctrineViolation[] = []\n const loose = (tree.nodes[tree.rootId]?.nodes ?? []).filter(\n (id) => tree.nodes[id]?.componentId !== 'emailSection',\n )\n if (loose.length) {\n violations.push({\n rule: null,\n code: 'email-loose-block',\n message: 'A block sits outside every Email section. Put each block inside a section.',\n nodeIds: aiModelNodeIds(loose, tree.sourceIds),\n })\n }\n const tokens = new Set<string>()\n const tokenNodes: string[] = []\n const unlinked: string[] = []\n let placed = 0\n for (const { id, node } of visitsOf(tree)) {\n for (const value of Object.values(node.props ?? {})) {\n if (typeof value !== 'string') continue\n for (const match of value.matchAll(MERGE_TOKEN)) {\n if (!AI_EMAIL_TEXT_MERGE_TOKENS.includes(match[1])) {\n tokens.add(`{{${match[1]}}}`)\n tokenNodes.push(id)\n }\n }\n }\n if (node.componentId === 'emailButton' && typeof node.props?.['href'] !== 'string') {\n unlinked.push(id)\n }\n if (node.componentId === 'emailProduct') placed += 1\n }\n if (tokens.size) {\n violations.push({\n rule: null,\n code: 'email-merge-token',\n message: `This email writes ${[...tokens].slice(0, 3).join(', ')}, which a generated email may not use. Use only {{contact.firstName}}, {{contact.name}} or {{contact.email}}, and only in text.`,\n nodeIds: aiModelNodeIds([...new Set(tokenNodes)], tree.sourceIds),\n })\n }\n if (unlinked.length) {\n violations.push({\n rule: null,\n code: 'email-button-link',\n message:\n 'An Email button links nowhere. Link each to a page of the site by its address, such as /menu, or to a full https address the brief gives.',\n nodeIds: aiModelNodeIds(unlinked, tree.sourceIds),\n })\n }\n if (placed !== products) {\n violations.push({\n rule: null,\n code: 'email-product-count',\n message: products\n ? `This email binds ${products} ${products === 1 ? 'product' : 'products'}: place exactly ${products} Email product ${\n products === 1 ? 'block' : 'blocks'\n }.`\n : 'No products are bound to this email: remove the Email product blocks.',\n })\n }\n return violations\n}\n\n/**\n * The design as it is stored: a link to one of the site's pages completed with\n * the site's address token, and each product block bound, in document order,\n * to the next product the job binds.\n */\nexport function aiEmailDesignNodes(\n tree: Pick<AiValidatedTree, 'rootId' | 'nodes'>,\n productIds: readonly string[],\n): NodesMap {\n const nodes: NodesMap = { ...tree.nodes }\n let next = 0\n for (const { id, node } of visitsOf(tree)) {\n const props: Record<string, unknown> = { ...(node.props ?? {}) }\n let changed = false\n const href = props['href']\n if (typeof href === 'string' && href.startsWith('/') && !href.startsWith('//')) {\n props['href'] = `${AI_EMAIL_SITE_URL_TOKEN}${href}`\n changed = true\n }\n if (node.componentId === 'emailProduct') {\n const productId = productIds[next]\n next += 1\n if (productId) {\n props['productId'] = productId\n changed = true\n }\n }\n if (changed) nodes[id] = { ...nodes[id], props } as NodesMap[string]\n }\n return nodes\n}\n\n/** The content the email plugin's writer stores a design from. */\nexport function aiEmailDesignContent(nodes: NodesMap, copy: AiEmailCopy): Record<string, unknown> {\n return {\n nodes,\n subject: copy.subjects[0] ?? '',\n preheader: copy.preheaders[0] ?? '',\n subjectVariants: copy.subjects,\n preheaderVariants: copy.preheaders,\n }\n}\n\n/** What the email plugin's renderer says about the design, as violations the model is re-asked with. */\nexport function aiEmailRenderViolations(\n design: PluginResourceDraftWriter,\n hostId: string,\n nodes: NodesMap,\n copy: AiEmailCopy,\n): AiDoctrineViolation[] {\n const checked = design.check(aiEmailDesignContent(nodes, copy), { hostId })\n if (checked.ok === true) return []\n return [...new Set(checked.problems)].map((problem) => ({\n rule: null,\n code: 'email-render',\n message: `The email does not render as written: ${problem}.`,\n }))\n}\n\nexport interface AiEmailGenerationInput {\n job: AiJob\n step: Extract<AiStepKind, 'job.email' | 'job.campaign'>\n model: string\n /** The line naming what is built, such as `Email name: …`; `null` for none. */\n heading: string | null\n plan: AiJobPlan | null\n inventory: AiSiteInventory | null\n hostId: string\n products: AiEmailProductBinding\n /** The email plugin's design writer, whose check the design must pass. */\n design: PluginResourceDraftWriter\n signal?: AbortSignal\n}\n\nexport interface AiEmailGeneration {\n result: AiValidatedGeneration<AiValidatedTree>\n /** The copy of the answer the doctrine kept; `null` unless it kept one. */\n copy: AiEmailCopy | null\n /** The kept design as it is stored; `null` unless the doctrine kept one. */\n nodes: NodesMap | null\n}\n\n/** Generates one email under the doctrine, with the email's own checks riding `extend`. */\nexport async function generateAiEmail(input: AiEmailGenerationInput): Promise<AiEmailGeneration> {\n // The answer `extend` saw last is the one the doctrine kept when it keeps one.\n let last = null as { copy: AiEmailCopy; nodes: NodesMap } | null\n const result = await runValidatedGeneration('email', {\n step: input.step,\n model: input.model,\n instructions: AI_JOB_EMAIL_INSTRUCTIONS,\n inventory: input.inventory,\n messages: [\n {\n role: 'user',\n content: aiJobEmailPrompt(input.job, input.plan, input.heading, input.products.ids.length),\n },\n ],\n tool: AI_JOB_EMAIL_TOOL,\n maxTokens: AI_JOB_EMAIL_STEP_BUDGETS[input.step].maxTokens(input.model),\n thinking: 'off',\n extend: (tree, answer) => {\n const copy = parseAiEmailCopy(answer)\n const nodes = aiEmailDesignNodes(tree, input.products.ids)\n last = { copy, nodes }\n const violations = [\n ...aiEmailTreeViolations(tree, input.products.ids.length),\n ...aiEmailCopyViolations(copy),\n ]\n // Rendered once the design's own rules hold, so a problem is named once.\n return violations.length\n ? violations\n : aiEmailRenderViolations(input.design, input.hostId, nodes, copy)\n },\n ...(input.signal ? { signal: input.signal } : {}),\n })\n const kept = result.status === 'ok' ? last : null\n return { result, copy: kept?.copy ?? null, nodes: kept?.nodes ?? null }\n}\n\n/** An email design as the job's output. */\nexport function aiEmailDesignOutput(\n record: PluginDraftRecord,\n place: { hostId: string; hostSubdomain: string | null },\n note: string | null,\n): AiJobOutput {\n return {\n resource: 'emailScreen',\n id: record.id,\n versionId: record.versionId,\n hostId: place.hostId,\n hostSubdomain: place.hostSubdomain,\n label: record.name,\n ...(note ? { note } : {}),\n }\n}\n\n/** An email job is admitted for a site of its org with email on and room for a design. */\nexport const aiEmailJobAdmission: AiJobAdmission = (context) =>\n aiPluginDraftAdmissionRefusal(context, {\n kind: 'email',\n drafts: [{ resource: AI_EMAIL_DESIGN_RESOURCE, pluginId: AI_EMAIL_PLUGIN_ID, label: 'Email' }],\n })\n\nexport interface AiJobEmailStepDeps {\n /** The inventory reader; specs hand in a fake. */\n readInventory?: typeof readSiteInventory\n /** How a resource's draft writer is found; the core's registry otherwise. */\n writerFor?: AiPluginDraftWriterLookup\n}\n\nexport function createAiJobEmailStep(deps: AiJobEmailStepDeps = {}): AiJobStepRunner {\n const readInventory = deps.readInventory ?? readSiteInventory\n const writerFor = deps.writerFor ?? aiPluginDraftWriter\n return async ({ job, now, signal, firestore, modelFor }): Promise<AiJobStepOutcome> => {\n const hostId = job.hostId\n if (!hostId) throw new Error('an email job names no site, and its admission refuses one')\n // The switch's answer for this job, else the routing table's (AGL-2942).\n const model = modelFor?.('job.email') ?? aiModelForStep('job.email')\n const design = writerFor(AI_EMAIL_DESIGN_RESOURCE)\n if (!design) return { ...aiUnspentOutcome(model), failure: AI_EMAIL_UNAVAILABLE_COPY }\n\n // A run cut off after its design was written reports that design, found by the id the job recorded.\n const draftId = aiJobDraftId(job, 'email')\n const written = await design.read({ hostId, id: draftId })\n if (written) {\n const hostSubdomain = await aiSiteSubdomain(firestore, hostId)\n return aiUnspentOutcome(model, {\n outputs: [aiEmailDesignOutput(written, { hostId, hostSubdomain }, null)],\n })\n }\n\n const [inventory, orgSnapshot, products, hostSubdomain] = await Promise.all([\n readInventory(job.orgId, hostId, { firestore }),\n firestore.collection('orgs').doc(job.orgId).get(),\n resolveAiEmailProducts(firestore, { hostId, brief: job.brief, inputs: job.inputs }),\n aiSiteSubdomain(firestore, hostId),\n ])\n const org = (orgSnapshot.data() ?? null) as Record<string, unknown> | null\n const context = { orgId: job.orgId, hostId, uid: job.createdBy, org, now }\n const refusal = await design.refusal(context)\n if (refusal) {\n return refusal.status === 403\n ? aiUnspentOutcome(model, { review: aiLimitReview(refusal.error) })\n : { ...aiUnspentOutcome(model), failure: refusal.error }\n }\n\n const plan = aiConfirmedPlan(job)\n const name =\n aiPlanCreation(plan, 'email')?.name || aiJobInputName(job) || AI_JOB_EMAIL_DEFAULT_NAME\n const generated = await generateAiEmail({\n job,\n step: 'job.email',\n model,\n heading: `Email name: ${name}`,\n plan,\n inventory,\n hostId,\n products,\n design,\n ...(signal ? { signal } : {}),\n })\n const { result } = generated\n const spent = aiGenerationSpent(result)\n if (result.status === 'refused') return { ...spent, refused: true }\n if (result.status === 'needs_input') return { ...spent, review: aiDoctrineReview(result) }\n if (!generated.copy || !generated.nodes) return { ...spent, failure: AI_EMAIL_SAVE_FAILURE_COPY }\n\n const write = await design.write({\n ...context,\n id: draftId,\n name,\n content: aiEmailDesignContent(generated.nodes, generated.copy),\n })\n if (write.ok === false) {\n return write.status === 403\n ? { ...spent, review: aiLimitReview(write.error) }\n : { ...spent, failure: AI_EMAIL_SAVE_FAILURE_COPY }\n }\n return {\n ...spent,\n outputs: [aiEmailDesignOutput(write, { hostId, hostSubdomain }, aiEmailProductNote(products))],\n }\n }\n}\n\nexport const runAiJobEmailStep = createAiJobEmailStep()\n\n/** Registers the email step and the check a email job passes before it is created or resumed. */\nexport function registerAiEmailJob(): void {\n registerAiJobStep('email', runAiJobEmailStep, { minimumMs: AI_JOB_EMAIL_STEP_MINIMUM_MS })\n registerAiJobAdmission('email', aiEmailJobAdmission)\n}\n"],"names":["AI_STEP_TIERS","AI_ROUTING_TABLE","aiModelForStep","aiDoctrineTreeTool","runValidatedGeneration","walkTree","AI_TEXT_LIMITS","readSiteInventory","aiEmailProductNote","resolveAiEmailProducts","registerAiJobAdmission","aiJobStepBudget","aiJobDraftId","aiSiteSubdomain","aiConfirmedPlan","aiDoctrineReview","aiGenerationSpent","aiJobBriefLine","aiLimitReview","aiModelNodeIds","aiPlanCreation","aiPlanReferenceLines","aiUnspentOutcome","aiPluginDraftAdmissionRefusal","aiPluginDraftWriter","registerAiJobStep","AI_EMAIL_DESIGN_RESOURCE","AI_EMAIL_PLUGIN_ID","AI_JOB_EMAIL_MAX_TOKENS","maxTokens","AI_JOB_EMAIL_STEP_BUDGETS","tier","AI_JOB_EMAIL_STEP_MINIMUM_MS","minimumMs","AI_EMAIL_VARIANTS","AI_EMAIL_SUBJECT_MAX_CHARS","headline","AI_EMAIL_PREHEADER_MAX_CHARS","AI_JOB_EMAIL_DEFAULT_NAME","AI_EMAIL_UNAVAILABLE_COPY","AI_EMAIL_SAVE_FAILURE_COPY","AI_EMAIL_TYPES","welcome","newsletter","launch","abandonedCart","eventReminder","reply","AI_EMAIL_TEXT_MERGE_TOKENS","AI_EMAIL_SITE_URL_TOKEN","AI_JOB_EMAIL_INSTRUCTIONS","text","join","DOCTRINE_EMAIL_TOOL","AI_JOB_EMAIL_TOOL","name","description","strict","inputSchema","type","additionalProperties","required","properties","tree","subjects","items","preheaders","aiEmailTypeLabel","value","Object","prototype","hasOwnProperty","call","aiJobInputName","job","raw","inputs","replace","trim","slice","aiJobEmailPrompt","plan","heading","products","lines","push","oneLine","parseAiEmailCopy","answer","Array","isArray","filter","entry","map","aiEmailCopyViolations","copy","violations","distinct","Set","Boolean","line","toLowerCase","size","length","rule","code","message","some","includes","MERGE_TOKEN","visitsOf","rootId","nodes","aiEmailTreeViolations","loose","id","componentId","nodeIds","sourceIds","tokens","tokenNodes","unlinked","placed","node","values","props","match","matchAll","add","aiEmailDesignNodes","productIds","next","changed","href","startsWith","productId","aiEmailDesignContent","subject","preheader","subjectVariants","preheaderVariants","aiEmailRenderViolations","design","hostId","checked","check","ok","problems","problem","generateAiEmail","input","last","result","step","model","instructions","inventory","messages","role","content","ids","tool","thinking","extend","signal","kept","status","aiEmailDesignOutput","record","place","note","resource","versionId","hostSubdomain","label","aiEmailJobAdmission","context","kind","drafts","pluginId","createAiJobEmailStep","deps","readInventory","writerFor","now","firestore","modelFor","orgSnapshot","Error","failure","draftId","written","read","outputs","Promise","all","orgId","collection","doc","get","brief","org","data","uid","createdBy","refusal","review","error","generated","spent","refused","write","runAiJobEmailStep","registerAiEmailJob"],"mappings":"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"}