@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,1257 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { assistCreditsFromUsd } from "@aglyn/aglyn/app-utils/assist-credits";
18
+ import { LAYOUT_SLOT_COMPONENT_ID } from "@aglyn/aglyn/app-utils/compose-layout-nodes";
19
+ import { stampDocumentLandmark } from "@aglyn/aglyn/app-utils/document-landmark";
20
+ import { decodeStoredNodes } from "@aglyn/aglyn/app-utils/stored-nodes";
21
+ import { CANVAS_ROOT_ELEMENT_ID } from "@aglyn/aglyn/foundation/constants/canvas";
22
+ import { createAiJobComponentStep } from "../jobs/ai-job-component-step.js";
23
+ import { aiJobDraftId, aiMintJobDraftIds } from "../jobs/ai-job-draft-ids.js";
24
+ import { createAiJobFormStep } from "../jobs/ai-job-form-step.js";
25
+ import { createAiJobLayoutStep } from "../jobs/ai-job-layout-step.js";
26
+ import { aiPageJobUnits, createAiJobPageStep } from "../jobs/ai-job-page-step.js";
27
+ import { AI_JOB_PLAN_SCOPES, createAiJobPlanStep } from "../jobs/ai-job-plan-step.js";
28
+ import { createAiJobProductsStep } from "../jobs/ai-job-products-step.js";
29
+ import { aiSitePendingUnits } from "../jobs/ai-job-site-step.js";
30
+ import { runAiJobTextStep } from "../jobs/ai-job-text-step.js";
31
+ import { aiJobThemeCheck, aiJobThemeGeneration, aiJobThemeMode } from "../jobs/ai-job-theme-step.js";
32
+ import { aiJobWorkflowDraftGeneration, aiJobWorkflowExplainGeneration, aiJobWorkflowModel } from "../jobs/ai-job-workflow-step.js";
33
+ import { readAiProductImage } from "../jobs/ai-product-image.js";
34
+ import { emptyAiAutomationRecords } from "../model/ai-automation-draft.js";
35
+ import { aiActionOutline, aiActionRecordKinds, aiRunOutline } from "../model/ai-automation-outline.js";
36
+ import { aiPlanCapabilitiesForJob, aiPlanCapabilityLines } from "../model/ai-plan-capabilities.js";
37
+ import { aiProductsJobInputs, aiProductsProposalOf } from "../model/ai-products.js";
38
+ import { aiDefaultModelFor } from "../providers/catalog.js";
39
+ import { aiModelForStep, resolveAiProvider } from "../providers/routing.js";
40
+ import { aiSiteInventoryBlock, runValidatedGeneration } from "./ai-doctrine.js";
41
+ import { AI_EVAL_AUTOMATION_CAPABILITIES, AI_EVAL_SITE_ID, AI_EVAL_TREE_OUTPUT } from "./ai-eval.js";
42
+ import { aiEvalMemoryFirestore, aiEvalMemoryInventory } from "./ai-eval-memory-firestore.js";
43
+ import { aiCategoriesPrompt, aiProductCopyPrompt } from "./ai-products-generation.js";
44
+ import { aiModelReadsImages } from "./ai-runtime.js";
45
+ /**
46
+ * THE EVAL HARNESS, LIVE (AGL-2937): recording new answers from the model.
47
+ *
48
+ * Offline scoring reads fixtures and costs nothing. A live run asks the
49
+ * provider for real answers to the golden briefs, grades each with a
50
+ * stronger model, and hands back recordings the offline harness then scores
51
+ * like any fixture. It spends real money, so it runs only when
52
+ * `AI_EVAL_LIVE=1` names it, and it is never part of CI or a deployment.
53
+ *
54
+ * A recording is only worth having if it measures what production sends. So
55
+ * each recorder answers a brief through the door that answers that kind in
56
+ * production — the plan step's runner, the text step's runner, the products
57
+ * step's runner, the theme and workflow steps' own generation calls — with
58
+ * the case's site handed in where the door would read one. Nothing here
59
+ * writes a prompt of its own for a kind.
60
+ *
61
+ * A kind with no recorder is skipped before any request, saying where
62
+ * production answers it (`AI_EVAL_UNRECORDED_DOORS`): a request route no job
63
+ * runs (the copy assistant's section, element and blog modes, the chat door),
64
+ * or a job step no recorder drives yet. A planned kind's document records the
65
+ * plan alone until its generator is recorded. A door that gains a recorder
66
+ * registers it with `registerAiEvalRecorder`.
67
+ *
68
+ * An automation brief is recorded through the workflow step's own generation
69
+ * call (AGL-3074) — a draft from the workspace's reach and the site's records,
70
+ * an explanation from the outline of the saved automation — because the
71
+ * step's runner keeps the tool's input nowhere: it writes the draft it makes
72
+ * of it, or the text it reads out of it, and the harness scores the input. A
73
+ * product brief is recorded through the products step's runner, against the
74
+ * case's store in memory, its photo read from the case's fixtures through the
75
+ * step's own resize-and-strip path, and its answer read back off the proposal
76
+ * the runner makes.
77
+ *
78
+ * A page brief is recorded END TO END (AGL-3030): the plan step's runner,
79
+ * the plan confirmed as a member confirms it, and every pass of the page
80
+ * step's runner against a site kept in memory — the layout, forms and
81
+ * components its plan creates built first by their own steps (AGL-3031) —
82
+ * each exchange's spend kept as the machine meters it. That is what proves
83
+ * what one page costs, on the workspace the case describes. Beside the page's
84
+ * tree it keeps the draft's screen — its address, its listing and the layout
85
+ * it renders inside — which the page's grader is shown with the plan
86
+ * (AGL-3073).
87
+ */ /** The environment variable a live run must be named by. */ export const AI_EVAL_LIVE_ENV = 'AI_EVAL_LIVE';
88
+ export const AI_EVAL_LIVE_REFUSAL = `A live eval run asks the AI provider for real answers and spends real money. It runs only when ${AI_EVAL_LIVE_ENV}=1 is set, from a machine that holds a provider key, and never in CI or on a deployment.`;
89
+ export class AiEvalLiveRefusedError extends Error {
90
+ constructor(){
91
+ super(AI_EVAL_LIVE_REFUSAL);
92
+ this.name = 'AiEvalLiveRefusedError';
93
+ }
94
+ }
95
+ /** Whether the environment names a live run. */ export function aiEvalLiveAllowed(env) {
96
+ return env[AI_EVAL_LIVE_ENV] === '1';
97
+ }
98
+ /**
99
+ * The variable a live run names the briefs it records by: case ids, comma
100
+ * separated. Unset records every brief a recorder covers.
101
+ */ export const AI_EVAL_CASES_ENV = 'AI_EVAL_CASES';
102
+ /** The briefs a run records: the ones `AI_EVAL_CASES` names, else every one. */ export function aiEvalCasesNamed(cases, env) {
103
+ var _env_AI_EVAL_CASES_ENV;
104
+ const named = ((_env_AI_EVAL_CASES_ENV = env[AI_EVAL_CASES_ENV]) != null ? _env_AI_EVAL_CASES_ENV : '').split(',').map((id)=>id.trim()).filter(Boolean);
105
+ if (!named.length) return [
106
+ ...cases
107
+ ];
108
+ const unknown = named.filter((id)=>!cases.some((evalCase)=>evalCase.id === id));
109
+ if (unknown.length) throw new Error(`${AI_EVAL_CASES_ENV} names no golden brief: ${unknown.join(', ')}`);
110
+ return cases.filter((evalCase)=>named.includes(evalCase.id));
111
+ }
112
+ const recorders = new Map();
113
+ /** Idempotent per kind; last registration wins. */ export function registerAiEvalRecorder(kind, recorder) {
114
+ recorders.set(kind, recorder);
115
+ }
116
+ export function aiEvalRecorderFor(kind) {
117
+ var _recorders_get;
118
+ return (_recorders_get = recorders.get(kind)) != null ? _recorders_get : null;
119
+ }
120
+ const EVAL_ORG = 'eval-org';
121
+ /** A job for a golden brief, in the shape a step runner reads: its drafts named as a created job's are. */ function evalJob(evalCase, kind) {
122
+ var _ref;
123
+ var _evalCase_inventory;
124
+ const now = new Date(0);
125
+ const draftIds = aiMintJobDraftIds(kind);
126
+ return {
127
+ $id: `eval-${evalCase.id}`,
128
+ orgId: EVAL_ORG,
129
+ hostId: (_ref = (_evalCase_inventory = evalCase.inventory) == null ? void 0 : _evalCase_inventory.hostId) != null ? _ref : null,
130
+ kind,
131
+ status: 'running',
132
+ brief: evalCase.brief,
133
+ inputs: {},
134
+ steps: draftIds ? [
135
+ {
136
+ name: 'generate',
137
+ status: 'running',
138
+ creditsSpent: 0,
139
+ draftIds
140
+ }
141
+ ] : [],
142
+ outputs: [],
143
+ creditsReserved: 0,
144
+ creditsSpent: 0,
145
+ createdBy: 'eval',
146
+ createdAt: now,
147
+ updatedAt: now,
148
+ expiresAt: now
149
+ };
150
+ }
151
+ /**
152
+ * The model a step runner is handed: the one the run names, else the routing
153
+ * table's. A runner reaches its provider through the runtime's registry.
154
+ */ function modelFor(options) {
155
+ return (step)=>{
156
+ var _options_model;
157
+ return (_options_model = options.model) != null ? _options_model : aiModelForStep(step);
158
+ };
159
+ }
160
+ /** Runs the doctrine's call with the provider a live run chose, when it chose one. */ function withProvider(input, options) {
161
+ return options.provider ? _extends({}, input, {
162
+ provider: options.provider
163
+ }) : input;
164
+ }
165
+ /** The case's site, as a reader the step runners are handed. */ function inventoryOf(evalCase) {
166
+ return async ()=>{
167
+ if (!evalCase.inventory) throw new Error(`${evalCase.id} has no inventory to build from`);
168
+ return evalCase.inventory;
169
+ };
170
+ }
171
+ /**
172
+ * The plan step's runner for a brief, on the case's site and the case's
173
+ * workspace. No plan reuse in a recording (AGL-2937): the point of a live run
174
+ * is to measure what the model answers for this brief, and a reused plan
175
+ * would record someone else's answer as this case's. No admission either: a
176
+ * recording writes to no workspace a door would count against.
177
+ */ function evalPlanStep(evalCase) {
178
+ return createAiJobPlanStep({
179
+ readInventory: inventoryOf(evalCase),
180
+ findPlansByKey: null,
181
+ readCapabilities: async ()=>{
182
+ var _evalCase_capabilities;
183
+ return (_evalCase_capabilities = evalCase.capabilities) != null ? _evalCase_capabilities : null;
184
+ },
185
+ admissionRefusal: async ()=>null
186
+ });
187
+ }
188
+ /** A plan outcome's plan, as a candidate records it. */ function planOf(outcome) {
189
+ return outcome.plan ? {
190
+ reuse: outcome.plan.reuse,
191
+ create: outcome.plan.create,
192
+ screens: outcome.plan.screens
193
+ } : null;
194
+ }
195
+ /** A planned kind's brief, recorded through the plan step: the plan alone. */ const recordPlan = async (evalCase, options)=>{
196
+ var _options_now, _outcome_effort;
197
+ var _outcome_review;
198
+ const kind = evalCase.kind;
199
+ const outcome = await evalPlanStep(evalCase)({
200
+ job: evalJob(evalCase, kind),
201
+ stepIndex: 0,
202
+ now: (_options_now = options.now) != null ? _options_now : new Date(),
203
+ firestore: {},
204
+ modelFor: modelFor(options)
205
+ });
206
+ return {
207
+ source: 'recorded',
208
+ scope: 'plan',
209
+ step: 'job.plan',
210
+ model: outcome.model,
211
+ effort: (_outcome_effort = outcome.effort) != null ? _outcome_effort : null,
212
+ plan: planOf(outcome),
213
+ answer: null,
214
+ usage: outcome.usage,
215
+ note: ((_outcome_review = outcome.review) == null ? void 0 : _outcome_review.reason) === 'doctrine' ? `needs review: ${outcome.review.message}` : undefined
216
+ };
217
+ };
218
+ /** The most passes a recorded page may take: the plan limit's sections and the listing, with room. */ const AI_EVAL_PAGE_MAX_PASSES = 64;
219
+ /** One exchange's spend, as the machine meters a step. */ function recordedStep(step, outcome) {
220
+ return {
221
+ step,
222
+ model: outcome.model,
223
+ usage: outcome.usage,
224
+ estCostUsd: outcome.estCostUsd,
225
+ credits: assistCreditsFromUsd(outcome.estCostUsd)
226
+ };
227
+ }
228
+ /** Several exchanges' tokens, added. */ function totalUsage(steps) {
229
+ return steps.reduce((sum, step)=>({
230
+ inputTokens: sum.inputTokens + step.usage.inputTokens,
231
+ outputTokens: sum.outputTokens + step.usage.outputTokens,
232
+ cacheReadTokens: sum.cacheReadTokens + step.usage.cacheReadTokens,
233
+ cacheWriteTokens: sum.cacheWriteTokens + step.usage.cacheWriteTokens
234
+ }), {
235
+ inputTokens: 0,
236
+ outputTokens: 0,
237
+ cacheReadTokens: 0,
238
+ cacheWriteTokens: 0
239
+ });
240
+ }
241
+ /**
242
+ * The workspace a case describes, as the org document the page step reads:
243
+ * a workspace that keeps no reusable components is the Free plan's shape,
244
+ * and any other is a plan that keeps them.
245
+ */ function evalOrgDocument(evalCase) {
246
+ var _evalCase_capabilities;
247
+ return ((_evalCase_capabilities = evalCase.capabilities) == null ? void 0 : _evalCase_capabilities.reusableComponents) === false ? {
248
+ plan: 'free'
249
+ } : {
250
+ plan: 'business',
251
+ billingStatus: 'active'
252
+ };
253
+ }
254
+ /**
255
+ * A page brief, recorded end to end (AGL-3030): the plan, confirmed, then the
256
+ * page step's passes until it reports the draft or stops for a person. What
257
+ * it answers is the page as the draft holds it, and what it spent is every
258
+ * exchange, each metered as the machine meters a step. A plan that stops for
259
+ * review records the plan alone, as a plan answer.
260
+ */ const recordPage = async (evalCase, options)=>{
261
+ var _options_now, _ref, _ref1;
262
+ var _evalCase_inventory, _planned_review, _steps_find;
263
+ const now = (_options_now = options.now) != null ? _options_now : new Date();
264
+ const job = evalJob(evalCase, 'page');
265
+ const hostId = job.hostId;
266
+ const org = evalOrgDocument(evalCase);
267
+ // The page step names the site in the listing request by its host
268
+ // document, so the site is named only as the case names it (AGL-3077).
269
+ const site = aiEvalMemoryFirestore({
270
+ [`orgs/${EVAL_ORG}`]: org,
271
+ [`hosts/${hostId}`]: _extends({}, evalCase.siteName ? {
272
+ displayName: evalCase.siteName
273
+ } : {}, {
274
+ screens: Object.fromEntries(((_ref = (_evalCase_inventory = evalCase.inventory) == null ? void 0 : _evalCase_inventory.screens) != null ? _ref : []).map((row)=>[
275
+ row.id,
276
+ row.slug
277
+ ]))
278
+ })
279
+ });
280
+ const context = {
281
+ stepIndex: 0,
282
+ now,
283
+ firestore: site.firestore,
284
+ modelFor: modelFor(options),
285
+ org
286
+ };
287
+ const planned = await evalPlanStep(evalCase)(_extends({}, context, {
288
+ job
289
+ }));
290
+ const steps = [
291
+ recordedStep('job.plan', planned)
292
+ ];
293
+ const planOnly = (note)=>{
294
+ var _planned_effort;
295
+ return _extends({
296
+ source: 'recorded',
297
+ scope: 'plan',
298
+ step: 'job.plan',
299
+ model: planned.model,
300
+ effort: (_planned_effort = planned.effort) != null ? _planned_effort : null,
301
+ plan: planOf(planned),
302
+ answer: null,
303
+ usage: planned.usage
304
+ }, note ? {
305
+ note
306
+ } : {});
307
+ };
308
+ if (!planned.plan || ((_planned_review = planned.review) == null ? void 0 : _planned_review.reason) !== 'plan') {
309
+ return planOnly(planned.failure ? `refused before confirm: ${planned.failure}` : planned.review ? `needs review: ${planned.review.message}` : undefined);
310
+ }
311
+ const confirmed = _extends({}, job, {
312
+ plan: _extends({}, planned.plan, {
313
+ status: 'confirmed',
314
+ confirmedAt: now,
315
+ confirmedBy: 'eval'
316
+ })
317
+ });
318
+ // The site as the steps read it: the case's rows, and what the job has
319
+ // built there so far. A case's site holds no documents to copy, so a plan
320
+ // that starts from a copy is built from its brief, as a step builds one
321
+ // whose source is gone.
322
+ const readers = {
323
+ readInventory: async ()=>{
324
+ if (!evalCase.inventory) throw new Error(`${evalCase.id} has no inventory to build from`);
325
+ return aiEvalMemoryInventory(evalCase.inventory, site.docs);
326
+ },
327
+ duplicate: async ()=>({
328
+ ok: false,
329
+ status: 404,
330
+ error: 'A recording copies nothing'
331
+ })
332
+ };
333
+ const creations = {
334
+ layout: createAiJobLayoutStep(readers),
335
+ form: createAiJobFormStep(readers),
336
+ component: createAiJobComponentStep(readers)
337
+ };
338
+ const generate = createAiJobPageStep(_extends({}, readers, {
339
+ runnerFor: (kind)=>kind in creations ? creations[kind] : null
340
+ }));
341
+ const units = aiPageJobUnits(confirmed.plan);
342
+ let outputs = [];
343
+ let stopped;
344
+ for(let pass = 0; pass < AI_EVAL_PAGE_MAX_PASSES; pass += 1){
345
+ const [unit] = aiSitePendingUnits(units, outputs);
346
+ const outcome = await generate(_extends({}, context, {
347
+ stepIndex: 1,
348
+ job: _extends({}, confirmed, {
349
+ outputs
350
+ })
351
+ }));
352
+ // A creation's pass is its own step's; the pass that reports the draft
353
+ // asks for the listing, on the SEO step's model.
354
+ const kind = unit ? `job.${unit.jobKind}` : outcome.outputs.some((output)=>output.resource === 'screen') ? 'job.seo' : 'job.page';
355
+ steps.push(recordedStep(kind, outcome));
356
+ outputs = [
357
+ ...outputs,
358
+ ...outcome.outputs
359
+ ];
360
+ if (outcome.refused || outcome.failure || outcome.review) {
361
+ var _outcome_failure;
362
+ var _outcome_review;
363
+ stopped = outcome.refused ? 'refused' : (_outcome_failure = outcome.failure) != null ? _outcome_failure : (_outcome_review = outcome.review) == null ? void 0 : _outcome_review.message;
364
+ break;
365
+ }
366
+ if (!outcome.continue) break;
367
+ }
368
+ const screenPath = `hosts/${hostId}/screens/${aiJobDraftId(confirmed, 'screen')}`;
369
+ const nodes = storedTree(site.docs, screenPath);
370
+ const built = outputs.some((output)=>output.resource === 'screen');
371
+ const screen = built && nodes ? recordedScreen(evalCase, site.docs, screenPath, outputs) : undefined;
372
+ return _extends({
373
+ source: 'recorded',
374
+ scope: built && nodes ? 'full' : 'plan',
375
+ step: 'job.page',
376
+ model: (_ref1 = (_steps_find = steps.find((entry)=>entry.step === 'job.page')) == null ? void 0 : _steps_find.model) != null ? _ref1 : planned.model,
377
+ effort: null,
378
+ plan: planOf(planned),
379
+ answer: built && nodes ? {
380
+ tree: {
381
+ rootId: CANVAS_ROOT_ELEMENT_ID,
382
+ nodes
383
+ }
384
+ } : null,
385
+ usage: totalUsage(steps),
386
+ steps
387
+ }, screen ? {
388
+ screen
389
+ } : {}, stopped ? {
390
+ note: `stopped: ${stopped}`
391
+ } : {});
392
+ };
393
+ /** A string a stored document holds, trimmed; `null` for none. */ function storedText(value) {
394
+ return typeof value === 'string' && value.trim() ? value.trim() : null;
395
+ }
396
+ /** The node map a versioned draft's first version holds, decoded; `null` when there is none. */ function storedTree(docs, draftPath) {
397
+ const draft = docs.get(draftPath);
398
+ const version = draft ? docs.get(`${draftPath}/versions/${String(draft['versionId'])}`) : undefined;
399
+ return version ? decodeStoredNodes(version['nodes']) : null;
400
+ }
401
+ /**
402
+ * The draft screen a page job wrote, as its grader reads it beside the tree
403
+ * (AGL-3073): the address and listing the draft holds, whether its output
404
+ * proposes a navigation entry, and the layout its version renders inside —
405
+ * one this job built, with its tree, or one the case's site lists by name.
406
+ */ function recordedScreen(evalCase, docs, screenPath, outputs) {
407
+ var _screen_seo, _screen_slug, _ref, _storedText;
408
+ var _evalCase_inventory;
409
+ const screen = docs.get(screenPath);
410
+ const version = screen ? docs.get(`${screenPath}/versions/${String(screen['versionId'])}`) : undefined;
411
+ if (!screen || !version) return undefined;
412
+ const seo = (_screen_seo = screen['seo']) != null ? _screen_seo : {};
413
+ const layoutId = storedText(version['layoutId']);
414
+ const layoutPath = `${screenPath.split('/').slice(0, 2).join('/')}/layouts/${layoutId}`;
415
+ const built = layoutId ? docs.get(layoutPath) : undefined;
416
+ const listed = layoutId ? (_evalCase_inventory = evalCase.inventory) == null ? void 0 : _evalCase_inventory.layouts.find((row)=>row.id === layoutId) : undefined;
417
+ const nodes = built ? storedTree(docs, layoutPath) : null;
418
+ return {
419
+ slug: String((_screen_slug = screen['slug']) != null ? _screen_slug : ''),
420
+ seoTitle: storedText(seo['title']),
421
+ seoDescription: storedText(seo['description']),
422
+ nav: outputs.some((output)=>{
423
+ var _output_proposal;
424
+ return output.resource === 'screen' && ((_output_proposal = output.proposal) == null ? void 0 : _output_proposal['navigation']) != null;
425
+ }),
426
+ layout: layoutId && (built || listed) ? {
427
+ id: layoutId,
428
+ name: (_ref = (_storedText = storedText(built == null ? void 0 : built['displayName'])) != null ? _storedText : listed == null ? void 0 : listed.name) != null ? _ref : layoutId,
429
+ built: Boolean(built),
430
+ tree: nodes ? {
431
+ rootId: CANVAS_ROOT_ELEMENT_ID,
432
+ nodes
433
+ } : null
434
+ } : null
435
+ };
436
+ }
437
+ /** A text brief, recorded through the text step. */ const recordText = async (evalCase, options)=>{
438
+ var _options_now, _outcome_effort, _ref;
439
+ var _outcome_outputs_;
440
+ const outcome = await runAiJobTextStep({
441
+ job: evalJob(evalCase, 'text'),
442
+ stepIndex: 0,
443
+ now: (_options_now = options.now) != null ? _options_now : new Date(),
444
+ firestore: {},
445
+ modelFor: modelFor(options)
446
+ });
447
+ return {
448
+ source: 'recorded',
449
+ scope: 'full',
450
+ step: 'job.text',
451
+ model: outcome.model,
452
+ effort: (_outcome_effort = outcome.effort) != null ? _outcome_effort : null,
453
+ plan: null,
454
+ answer: (_ref = (_outcome_outputs_ = outcome.outputs[0]) == null ? void 0 : _outcome_outputs_.text) != null ? _ref : null,
455
+ usage: outcome.usage
456
+ };
457
+ };
458
+ /**
459
+ * A theme brief, recorded through the theme step's own generation call. The
460
+ * tool's raw input is kept, because that is what the harness scores; the
461
+ * site's theme comes from the case rather than a host document.
462
+ */ const recordTheme = async (evalCase, options)=>{
463
+ var _options_model, _evalCase_themeSource;
464
+ const model = (_options_model = options.model) != null ? _options_model : aiModelForStep('job.theme');
465
+ let raw = null;
466
+ const generation = aiJobThemeGeneration({
467
+ brief: evalCase.brief,
468
+ mode: aiJobThemeMode(undefined),
469
+ theme: evalCase.siteTheme,
470
+ source: (_evalCase_themeSource = evalCase.themeSource) != null ? _evalCase_themeSource : 'default',
471
+ brand: [],
472
+ model
473
+ });
474
+ const result = await runValidatedGeneration('theme', withProvider(_extends({}, generation, {
475
+ check: (answer)=>{
476
+ raw = answer;
477
+ return aiJobThemeCheck(answer);
478
+ }
479
+ }), options));
480
+ return {
481
+ source: 'recorded',
482
+ scope: 'full',
483
+ step: 'job.theme',
484
+ model: result.model,
485
+ effort: result.effort,
486
+ plan: null,
487
+ answer: result.status === 'refused' ? null : raw,
488
+ usage: result.usage
489
+ };
490
+ };
491
+ /**
492
+ * The workflow step's generation for an automation brief (AGL-3074), from
493
+ * the case as the step's runner builds it from a site: a draft from what the
494
+ * workspace can run and the site's forms and datasets; or, for a brief about
495
+ * a saved action, an explanation from the action's outline, told whether the
496
+ * records its steps name exist as the runner reads only those, with a failed
497
+ * run's outline where the case gives one.
498
+ */ export function aiEvalWorkflowGeneration(evalCase, model) {
499
+ var _evalCase_automationRecords;
500
+ const records = (_evalCase_automationRecords = evalCase.automationRecords) != null ? _evalCase_automationRecords : emptyAiAutomationRecords();
501
+ const automation = evalCase.automation;
502
+ if (!automation) {
503
+ var _evalCase_automationCapabilities;
504
+ return aiJobWorkflowDraftGeneration({
505
+ brief: evalCase.brief,
506
+ capabilities: (_evalCase_automationCapabilities = evalCase.automationCapabilities) != null ? _evalCase_automationCapabilities : AI_EVAL_AUTOMATION_CAPABILITIES,
507
+ records,
508
+ model
509
+ });
510
+ }
511
+ const named = aiActionRecordKinds(automation.action);
512
+ const read = Object.fromEntries(Object.entries(records).map(([kind, rows])=>[
513
+ kind,
514
+ named.includes(kind) ? rows : []
515
+ ]));
516
+ return aiJobWorkflowExplainGeneration({
517
+ brief: evalCase.brief,
518
+ mode: automation.run ? 'diagnose' : 'explain',
519
+ outline: aiActionOutline(automation.action, read),
520
+ run: automation.run ? aiRunOutline(automation.run) : null,
521
+ model
522
+ });
523
+ }
524
+ /**
525
+ * An automation brief, recorded through the workflow step's own generation
526
+ * call (AGL-3074). The tool's raw input is kept, because that is what the
527
+ * harness scores: the step's runner turns a draft into the action it writes,
528
+ * and an explanation into the text it reports, and keeps the input nowhere.
529
+ */ const recordWorkflow = async (evalCase, options)=>{
530
+ var _options_model;
531
+ const generation = aiEvalWorkflowGeneration(evalCase, (_options_model = options.model) != null ? _options_model : aiJobWorkflowModel());
532
+ let raw = null;
533
+ const result = await runValidatedGeneration('workflow', withProvider(_extends({}, generation, {
534
+ check: (answer)=>{
535
+ raw = answer;
536
+ return generation.check(answer);
537
+ }
538
+ }), options));
539
+ return _extends({
540
+ source: 'recorded',
541
+ scope: 'full',
542
+ step: 'job.workflow',
543
+ model: result.model,
544
+ effort: result.effort,
545
+ plan: null,
546
+ answer: result.status === 'refused' ? null : raw,
547
+ usage: result.usage,
548
+ steps: [
549
+ recordedStep('job.workflow', result)
550
+ ]
551
+ }, result.status === 'needs_input' ? _extends({
552
+ note: `needs review: ${result.message}`
553
+ }, result.rawOutput ? {
554
+ rawOutput: result.rawOutput
555
+ } : {}) : {});
556
+ };
557
+ /** The site a case's job runs on: its inventory's, or the harness's own. */ function aiEvalSiteId(evalCase) {
558
+ var _ref;
559
+ var _evalCase_inventory;
560
+ return (_ref = (_evalCase_inventory = evalCase.inventory) == null ? void 0 : _evalCase_inventory.hostId) != null ? _ref : AI_EVAL_SITE_ID;
561
+ }
562
+ /** A products brief's job inputs, as the editor or a products card hands them over. */ function aiEvalProductsInputs(evalCase) {
563
+ if (evalCase.kind === 'catalog') return aiProductsJobInputs({
564
+ target: 'catalog'
565
+ });
566
+ if (evalCase.kind === 'categories') return aiProductsJobInputs({
567
+ target: 'categories'
568
+ });
569
+ if (!evalCase.product) throw new Error(`${evalCase.id} names no product to write copy for`);
570
+ return aiProductsJobInputs({
571
+ target: 'product',
572
+ product: evalCase.product.facts
573
+ });
574
+ }
575
+ /** A picture's content type, from the extension of the fixture that holds it. */ function fixtureContentType(file) {
576
+ const extension = file.slice(file.lastIndexOf('.') + 1).toLowerCase();
577
+ return `image/${extension === 'jpg' ? 'jpeg' : extension}`;
578
+ }
579
+ /**
580
+ * The storage read of a case's media library (AGL-3074): the fixture the case
581
+ * names for an asset of its own site's library, and nothing for any other. It
582
+ * stands in for the download alone, so the products step's own path still
583
+ * locates the photo, decodes it, turns it upright, resizes it and encodes the
584
+ * JPEG the model is sent.
585
+ */ function aiEvalMediaSeams(evalCase, options) {
586
+ return {
587
+ readBytes: async (_firestore, location, hostId)=>{
588
+ var _evalCase_media;
589
+ const own = !location.scope.isOrg && location.scope.scopeId === hostId;
590
+ const file = own ? (_evalCase_media = evalCase.media) == null ? void 0 : _evalCase_media[location.mediaId] : undefined;
591
+ if (!file || !options.readFixture) return null;
592
+ return {
593
+ buffer: await options.readFixture(file),
594
+ contentType: fixtureContentType(file)
595
+ };
596
+ }
597
+ };
598
+ }
599
+ /**
600
+ * A product case's photo, as the products step sends it (AGL-3074): read
601
+ * through `ai-product-image.ts` from the case's fixtures. `null` for a case
602
+ * whose product has none, or whose photo cannot be read.
603
+ */ export async function aiEvalCasePhoto(evalCase, options) {
604
+ var _evalCase_product;
605
+ const value = (_evalCase_product = evalCase.product) == null ? void 0 : _evalCase_product.facts.imageUrl;
606
+ if (!value) return null;
607
+ const read = await readAiProductImage({}, {
608
+ value,
609
+ hostId: aiEvalSiteId(evalCase),
610
+ orgId: EVAL_ORG
611
+ }, aiEvalMediaSeams(evalCase, options));
612
+ return read.status === 'read' ? read.image : null;
613
+ }
614
+ /**
615
+ * A products proposal read back as the tool input the harness scores
616
+ * (AGL-3074): a product's copy as its check kept it, a catalog's products,
617
+ * and categories with each discount in the tool's own terms — a percentage or
618
+ * dollars, a minimum order in dollars, and an empty code for a discount that
619
+ * applies on its own.
620
+ */ export function aiEvalProductsAnswer(proposal) {
621
+ if (proposal.kind === 'copy') return proposal.values ? _extends({}, proposal.values) : null;
622
+ if (proposal.kind === 'catalog') return {
623
+ products: proposal.products
624
+ };
625
+ return {
626
+ categories: proposal.categories,
627
+ discounts: proposal.discounts.map((discount)=>{
628
+ var _discount_code, _discount_valuePct, _discount_valueCents, _discount_minSubtotalCents;
629
+ return {
630
+ name: discount.name,
631
+ code: (_discount_code = discount.code) != null ? _discount_code : '',
632
+ kind: discount.kind,
633
+ value: discount.kind === 'percent' ? (_discount_valuePct = discount.valuePct) != null ? _discount_valuePct : 0 : discount.kind === 'fixed' ? ((_discount_valueCents = discount.valueCents) != null ? _discount_valueCents : 0) / 100 : 0,
634
+ minimumOrderUsd: ((_discount_minSubtotalCents = discount.minSubtotalCents) != null ? _discount_minSubtotalCents : 0) / 100,
635
+ why: discount.why
636
+ };
637
+ })
638
+ };
639
+ }
640
+ /**
641
+ * A products brief — one product's copy, a store's first catalog, or its
642
+ * categories and discounts — recorded through the products step's runner
643
+ * (AGL-3074), against the case's store kept in memory: its name, its
644
+ * categories, and the photo its media names. What it answers is read back off
645
+ * the proposal the runner makes.
646
+ */ const recordProducts = async (evalCase, options)=>{
647
+ var _ref, _evalCase_existingCategoryNames, _options_now, _outcome_effort;
648
+ var _evalCase_product;
649
+ const hostId = aiEvalSiteId(evalCase);
650
+ const categories = evalCase.kind === 'product' ? (_ref = (_evalCase_product = evalCase.product) == null ? void 0 : _evalCase_product.categories) != null ? _ref : [] : ((_evalCase_existingCategoryNames = evalCase.existingCategoryNames) != null ? _evalCase_existingCategoryNames : []).map((name, index)=>({
651
+ id: `category-${index + 1}`,
652
+ name
653
+ }));
654
+ const store = aiEvalMemoryFirestore(_extends({
655
+ [`hosts/${hostId}`]: _extends({
656
+ orgId: EVAL_ORG
657
+ }, evalCase.siteName ? {
658
+ displayName: evalCase.siteName
659
+ } : {})
660
+ }, Object.fromEntries(categories.map((category)=>[
661
+ `hosts/${hostId}/productCategories/${category.id}`,
662
+ {
663
+ name: category.name
664
+ }
665
+ ]))));
666
+ const outcome = await createAiJobProductsStep({
667
+ image: aiEvalMediaSeams(evalCase, options)
668
+ })({
669
+ job: _extends({}, evalJob(evalCase, 'products'), {
670
+ hostId,
671
+ inputs: aiEvalProductsInputs(evalCase)
672
+ }),
673
+ stepIndex: 0,
674
+ now: (_options_now = options.now) != null ? _options_now : new Date(),
675
+ firestore: store.firestore,
676
+ modelFor: modelFor(options)
677
+ });
678
+ const proposal = aiProductsProposalOf(outcome.outputs[0]);
679
+ const stopped = outcome.refused ? 'refused' : outcome.failure;
680
+ return _extends({
681
+ source: 'recorded',
682
+ scope: 'full',
683
+ step: 'job.products',
684
+ model: outcome.model,
685
+ effort: (_outcome_effort = outcome.effort) != null ? _outcome_effort : null,
686
+ plan: null,
687
+ answer: proposal ? aiEvalProductsAnswer(proposal) : null,
688
+ usage: outcome.usage,
689
+ steps: [
690
+ recordedStep('job.products', outcome)
691
+ ]
692
+ }, (proposal == null ? void 0 : proposal.kind) === 'copy' ? {
693
+ photo: proposal.photo
694
+ } : {}, stopped ? {
695
+ note: `stopped: ${stopped}`
696
+ } : {});
697
+ };
698
+ /**
699
+ * Every kind no recorder covers, and the door that answers it in production
700
+ * (AGL-3074), so a skipped brief says why truthfully. Modules are named from
701
+ * the plugin's `src/lib`.
702
+ */ export const AI_EVAL_UNRECORDED_DOORS = {
703
+ section: {
704
+ route: 'the copy assistant’s section mode',
705
+ file: 'server/ai-assist.ts'
706
+ },
707
+ element: {
708
+ route: 'the copy assistant’s element mode',
709
+ file: 'server/ai-assist.ts'
710
+ },
711
+ blog: {
712
+ route: 'the copy assistant’s blog mode',
713
+ file: 'server/ai-assist.ts'
714
+ },
715
+ chat: {
716
+ route: 'the console assistant',
717
+ file: 'server/assist-chat.ts'
718
+ },
719
+ email: {
720
+ step: 'email',
721
+ file: 'jobs/ai-job-email-step.ts'
722
+ },
723
+ seo: {
724
+ step: 'seo',
725
+ file: 'jobs/ai-job-seo-step.ts'
726
+ },
727
+ insight: {
728
+ step: 'insight',
729
+ file: 'jobs/ai-job-insight-step.ts'
730
+ },
731
+ crm: {
732
+ step: 'crm',
733
+ file: 'jobs/ai-job-crm-step.ts'
734
+ },
735
+ experiment: {
736
+ step: 'experiment',
737
+ file: 'jobs/ai-job-experiment-step.ts'
738
+ }
739
+ };
740
+ /** Why a brief of this kind is skipped: where its door is, and that no recorder drives it. */ export function aiEvalSkipReason(kind) {
741
+ const door = AI_EVAL_UNRECORDED_DOORS[kind];
742
+ if (!door) return 'no recorder: none is registered for this kind';
743
+ return 'route' in door ? `no recorder: the door that answers this kind is a request route (${door.route}, ${door.file}), not a job step` : `no recorder yet: this kind is answered by the ${door.step} job step (${door.file}), which no recorder drives`;
744
+ }
745
+ for (const kind of Object.keys(AI_EVAL_TREE_OUTPUT)){
746
+ // A section rewrite is the copy assistant's, a request route: no plan step.
747
+ if (kind !== 'section' && kind !== 'email') registerAiEvalRecorder(kind, recordPlan);
748
+ }
749
+ registerAiEvalRecorder('page', recordPage);
750
+ registerAiEvalRecorder('text', recordText);
751
+ registerAiEvalRecorder('theme', recordTheme);
752
+ registerAiEvalRecorder('workflow', recordWorkflow);
753
+ for (const kind of [
754
+ 'product',
755
+ 'catalog',
756
+ 'categories'
757
+ ])registerAiEvalRecorder(kind, recordProducts);
758
+ // ── The grader ────────────────────────────────────────────────────────────
759
+ export const AI_EVAL_RUBRIC_TOOL = {
760
+ name: 'grade_output',
761
+ description: 'Grade the output against the brief it was built from.',
762
+ strict: true,
763
+ inputSchema: {
764
+ type: 'object',
765
+ additionalProperties: false,
766
+ required: [
767
+ 'structure',
768
+ 'copy',
769
+ 'reuse',
770
+ 'notes'
771
+ ],
772
+ properties: {
773
+ structure: {
774
+ type: 'integer',
775
+ description: 'From 1 (fails) to 5 (excellent): organized the way the brief needs, with nothing missing or extra.'
776
+ },
777
+ copy: {
778
+ type: 'integer',
779
+ description: 'From 1 to 5: the words fit the brief, the site and its audience, with no filler.'
780
+ },
781
+ reuse: {
782
+ anyOf: [
783
+ {
784
+ type: 'integer'
785
+ },
786
+ {
787
+ type: 'null'
788
+ }
789
+ ],
790
+ description: 'From 1 to 5: reuses what the site inventory lists before creating, and creates only what nothing listed can do. Null when the output places nothing.'
791
+ },
792
+ notes: {
793
+ type: 'string',
794
+ description: 'One or two sentences on the lowest grade.'
795
+ }
796
+ }
797
+ }
798
+ };
799
+ export const AI_EVAL_GRADER_INSTRUCTIONS = [
800
+ {
801
+ text: 'You grade an output an AI produced for a website builder, against the brief it was built from and the site it was built for. ' + 'Grade three things from 1 to 5: structure, copy and reuse, as the grade_output tool describes them. ' + 'A 3 is usable as it is; a 5 is what a careful professional would have made. Judge only what you are shown, and answer through grade_output.'
802
+ }
803
+ ];
804
+ /**
805
+ * What a build plan is, for the grader that grades one (AGL-3022).
806
+ *
807
+ * A plan is the proposal a member confirms, not the document the generation
808
+ * step writes afterwards, and `AI_BUILD_PLAN_TOOL` gives it nowhere to put a
809
+ * node tree, a heading order, a landmark or a line of body copy. Graded
810
+ * against a finished page it loses marks for every one of those, on structure
811
+ * and on copy alike, and the grade then measures the schema rather than the
812
+ * answer. So the grader is told the shape it is reading, and that the only
813
+ * words a plan writes are the ones `aiPlanCopy` collects.
814
+ *
815
+ * Two facts it cannot read off the schema are stated as well. Only a page or
816
+ * site job plans screens: the plan step tells a component, layout, template,
817
+ * form or email job to plan none, so an empty `screens` on one of those is the
818
+ * answer working, and a grader that does not know it marks the plan down for
819
+ * doing what it was told. And a search is an element, never a form: a form
820
+ * collects submissions, and a grader that does not know the platform has
821
+ * search elements rewards a plan for creating a form to search with.
822
+ */ export const AI_EVAL_PLAN_GRADER_NOTE = 'A build plan is not the finished output: it is the proposal a member confirms before anything is generated. ' + 'It holds only what it reuses by inventory id, what it creates and why, and its screens — each with a title, ' + 'slug, layout, template, nav flag, search title and description, and sections named with what they place and ' + 'how many items they hold. Only a page or site job plans screens: the plan of a component, layout, template, ' + 'form or email job has an empty screens list by design, and is never marked down for it. ' + 'A plan has no node tree, no heading order, no landmarks, no theme tokens, no field ' + 'labels or validation, and no body copy; all of those belong to the generation step that runs once the plan is ' + 'confirmed. Grade structure on whether the plan proposes the right screens, sections, fields and creations for ' + 'the brief. A search box is a Search Box element, or a Collection Search element over a collection\'s entries, ' + 'and never a new form, because a form collects submissions: a plan that creates a form to search with has ' + 'proposed the wrong creation. Grade copy on the only words a plan writes: screen titles, search titles and ' + 'descriptions, and the names and rationales of what it creates. Do not mark a plan down for anything a plan ' + 'cannot hold.';
823
+ /**
824
+ * What the grader of a case with capabilities is told beside them (AGL-3040).
825
+ *
826
+ * A case that describes its workspace had its plan told what that workspace
827
+ * may create, and a workspace that keeps no reusable components or saved
828
+ * forms builds the only way it can: a list's repeated items drawn in one
829
+ * section, the form carried by the page. A grader told none of that grades
830
+ * the doctrine whole, and marks reuse down for exactly the build the workspace
831
+ * required, as it marked down the first live recording of the Free brief.
832
+ */ export const AI_EVAL_CAPABILITIES_GRADER_NOTE = 'Grade reuse against what this workspace may create, as listed above: never mark an output down for not creating what the workspace may not make.';
833
+ /**
834
+ * Beside that, where the workspace keeps no reusable components or saved
835
+ * forms, which the capability lines have already said.
836
+ */ export const AI_EVAL_INLINE_GRADER_NOTE = "On this workspace, a list's repeated items drawn in one section and a form drawn on the page, as a Form element holding its Form Fields, are the correct build and never a missed reuse.";
837
+ /**
838
+ * What a section's `uses` can hold on such a workspace (AGL-3143).
839
+ *
840
+ * A section's `uses` names what the section PLACES, and the only things it
841
+ * can name are an inventory id and a `new:<name>` creation. A workspace that
842
+ * keeps no reusable components or saved forms has neither to name, and the
843
+ * capability lines above have already refused the job the creations — so
844
+ * every inline section leaves `uses` empty because it is the only answer it
845
+ * can give. A grader that does not know it reads the empty list as a section
846
+ * that places nothing and marks the plan down for being correct, which drags
847
+ * the floors down for a reason that has nothing to do with the answer.
848
+ */ export const AI_EVAL_INLINE_USES_GRADER_NOTE = "A section's `uses` names what it places, and can name only an inventory id or a creation. This workspace has neither to place and may create neither, so an empty `uses` on a section drawn inline is the only answer there is: never mark a plan or a section down for it.";
849
+ /**
850
+ * The workspace a case describes, as its grader reads it: the capability
851
+ * lines the plan step was sent, narrowed to what the job builds the way the
852
+ * step narrows them, and the notes on grading against them. `null` for a
853
+ * case that describes no workspace, whose output is held to the doctrine
854
+ * whole.
855
+ */ export function aiEvalGraderCapabilities(evalCase) {
856
+ var _AI_JOB_PLAN_SCOPES_evalCase_kind;
857
+ if (!evalCase.capabilities) return null;
858
+ const scope = (_AI_JOB_PLAN_SCOPES_evalCase_kind = AI_JOB_PLAN_SCOPES[evalCase.kind]) != null ? _AI_JOB_PLAN_SCOPES_evalCase_kind : null;
859
+ const capabilities = aiPlanCapabilitiesForJob(evalCase.capabilities, scope);
860
+ return [
861
+ ...aiPlanCapabilityLines(capabilities),
862
+ AI_EVAL_CAPABILITIES_GRADER_NOTE,
863
+ ...capabilities.reusableComponents ? [] : [
864
+ AI_EVAL_INLINE_GRADER_NOTE,
865
+ AI_EVAL_INLINE_USES_GRADER_NOTE
866
+ ]
867
+ ].join('\n');
868
+ }
869
+ /**
870
+ * What the grader of a built page is told beside it (AGL-3073).
871
+ *
872
+ * A page's tree holds only what the page adds. The site's header, navigation
873
+ * and footer are its layout's; the one main landmark is placed when the page
874
+ * is composed (`stampDocumentLandmark`), on the layout's slot where the page
875
+ * renders, or on the page's root when it renders inside none; and its address
876
+ * and listing are fields of its screen. A grader shown the tree alone marks a
877
+ * page down for a layout, a landmark and a listing the page has.
878
+ */ export const AI_EVAL_PAGE_GRADER_NOTE = 'A page is built inside its layout and published as a screen, so its tree holds only what the page adds: ' + "the site's header, navigation and footer are the layout's; the page's one main landmark is placed when it is " + "published, on the layout's slot where the page renders, or on the page's root when it has no layout; and its " + 'address, search title and description are fields of its screen. Grade the page as built with all of them, as ' + 'listed above, and never mark it down for a layout, a landmark, an address or a listing its tree does not repeat.';
879
+ /** The most elements a layout's outline lists; the rest are counted. */ export const AI_EVAL_LAYOUT_OUTLINE_MAX_LINES = 40;
880
+ /** The most characters of an element's own text an outline quotes. */ const AI_EVAL_OUTLINE_TEXT_MAX_CHARS = 48;
881
+ const isLoose = (value)=>typeof value === 'object' && value !== null && !Array.isArray(value);
882
+ const looseList = (value)=>Array.isArray(value) ? value.filter(isLoose) : [];
883
+ const looseText = (value)=>typeof value === 'string' ? value.replace(/\s+/g, ' ').trim() : '';
884
+ /** An element of an outline: what it renders as, its component, and its own text, quoted short. */ function outlineLine(node) {
885
+ var _node_componentId;
886
+ const props = isLoose(node['props']) ? node['props'] : {};
887
+ const element = looseText(props['component']) || looseText(props['element']);
888
+ const text = looseText(props['children']);
889
+ const quoted = text ? ` "${text.length > AI_EVAL_OUTLINE_TEXT_MAX_CHARS ? `${text.slice(0, AI_EVAL_OUTLINE_TEXT_MAX_CHARS)}…` : text}"` : '';
890
+ const slot = node['componentId'] === LAYOUT_SLOT_COMPONENT_ID ? ' ← the page renders here' : '';
891
+ return `${element ? `${element} · ` : ''}${String((_node_componentId = node['componentId']) != null ? _node_componentId : '?')}${quoted}${slot}`;
892
+ }
893
+ /**
894
+ * A layout as its page's grader reads it (AGL-3073): an element a line,
895
+ * indented by depth, named by the element it renders as and its component,
896
+ * with its own text quoted short. The main landmark is placed where a
897
+ * published page places it, by the function that places it there.
898
+ */ export function aiEvalLayoutOutline(tree) {
899
+ const nodes = stampDocumentLandmark(tree.nodes);
900
+ const lines = [];
901
+ const seen = new Set();
902
+ let unlisted = 0;
903
+ const visit = (id, depth)=>{
904
+ const node = nodes[id];
905
+ if (!isLoose(node) || seen.has(id)) return;
906
+ seen.add(id);
907
+ if (lines.length < AI_EVAL_LAYOUT_OUTLINE_MAX_LINES) lines.push(`${' '.repeat(depth)}${outlineLine(node)}`);
908
+ else unlisted += 1;
909
+ for (const child of Array.isArray(node['nodes']) ? node['nodes'] : []){
910
+ if (typeof child === 'string') visit(child, depth + 1);
911
+ }
912
+ };
913
+ visit(tree.rootId, 0);
914
+ return [
915
+ ...lines,
916
+ ...unlisted ? [
917
+ `… and ${unlisted} more elements`
918
+ ] : []
919
+ ].join('\n');
920
+ }
921
+ /**
922
+ * The plan a built answer came from, as its grader reads it (AGL-3073): what
923
+ * it reuses and creates, and each screen's sections in order, with what each
924
+ * places and how many items it shows. `null` for an answer with no plan.
925
+ */ export function aiEvalPlanOutline(plan) {
926
+ if (!isLoose(plan)) return null;
927
+ const lines = [
928
+ 'The plan it was built from, as the member confirmed it:'
929
+ ];
930
+ for (const entry of looseList(plan['reuse'])){
931
+ lines.push(`- reuses the ${looseText(entry['kind'])} ${looseText(entry['id'])}: ${looseText(entry['purpose'])}`);
932
+ }
933
+ for (const entry of looseList(plan['create'])){
934
+ const fields = Array.isArray(entry['fields']) ? entry['fields'].map(looseText).filter(Boolean) : [];
935
+ lines.push(`- creates the ${looseText(entry['kind'])} "${looseText(entry['name'])}": ${looseText(entry['why'])}${fields.length ? ` Holds: ${fields.join('; ')}.` : ''}`);
936
+ }
937
+ for (const screen of looseList(plan['screens'])){
938
+ lines.push(`- the screen "${looseText(screen['title'])}", its sections in order:`);
939
+ looseList(screen['sections']).forEach((section, index)=>{
940
+ const uses = Array.isArray(section['uses']) ? section['uses'].map(looseText).filter(Boolean) : [];
941
+ const items = Number(section['items']);
942
+ lines.push(` ${index + 1}. ${looseText(section['name'])}${uses.length ? `, placing ${uses.join(', ')}` : ''}${items > 0 ? `, ${items} ${items === 1 ? 'item' : 'items'}` : ''}`);
943
+ });
944
+ }
945
+ return lines.length > 1 ? lines.join('\n') : null;
946
+ }
947
+ /** A screen's address as a visitor reads it. */ function addressOf(slug) {
948
+ return slug.startsWith('/') ? slug : `/${slug}`;
949
+ }
950
+ /** A listing value quoted, or said to be missing. */ function listingValue(value) {
951
+ return value ? `"${value}"` : 'none';
952
+ }
953
+ /**
954
+ * A built page's screen and layout, as its grader reads them (AGL-3073). A
955
+ * recording that kept the draft's screen gives its stored address and listing
956
+ * and the layout it renders inside, outlined from its tree. One made before
957
+ * that was kept gives its plan's screen instead, which is what the page step
958
+ * builds from, and says so.
959
+ */ export function aiEvalBuiltPage(answer) {
960
+ var _answer_steps;
961
+ const recorded = answer.screen;
962
+ const plan = isLoose(answer.plan) ? answer.plan : null;
963
+ const planned = looseList(plan == null ? void 0 : plan['screens'])[0];
964
+ if (!recorded && !planned) return null;
965
+ if (recorded) {
966
+ const layout = recorded.layout;
967
+ return [
968
+ 'The page as built:',
969
+ `- address: ${addressOf(recorded.slug)}`,
970
+ `- search title: ${listingValue(recorded.seoTitle)}`,
971
+ `- search description: ${listingValue(recorded.seoDescription)}`,
972
+ `- navigation: ${recorded.nav ? 'an entry for the page is proposed' : 'no entry is proposed'}`,
973
+ !layout ? "- layout: none, so the page's root is its main landmark" : layout.tree ? `- layout: "${layout.name}", ${layout.built ? 'built by this job before the page' : 'which the site already had'}. Its outline:\n${aiEvalLayoutOutline(layout.tree).split('\n').map((line)=>` ${line}`).join('\n')}` : `- layout: "${layout.name}", which the site already has; the page renders in its slot`
974
+ ].join('\n');
975
+ }
976
+ const reference = looseText(planned['layout']);
977
+ const created = reference.startsWith('new:') ? looseList(plan == null ? void 0 : plan['create']).find((entry)=>entry['kind'] === 'layout' && looseText(entry['name']) === reference.slice('new:'.length)) : undefined;
978
+ const builtByJob = ((_answer_steps = answer.steps) != null ? _answer_steps : []).some((step)=>step.step === 'job.layout');
979
+ // What the layout holds is on the plan's own line above; it is not repeated.
980
+ const layout = !reference ? "- layout: none, so the page's root is its main landmark" : created ? `- layout: "${looseText(created['name'])}", which the plan creates${builtByJob ? ' and this job built before the page' : ''}. A layout this job builds holds one Layout Slot, where the page renders, and the slot is the page's main landmark; the recording kept no tree of it` : `- layout: ${reference}, which the site already has; the page renders in its slot`;
981
+ return [
982
+ "The page as its plan built it (the recording kept no record of the draft's screen):",
983
+ `- address: ${addressOf(looseText(planned['slug']))}`,
984
+ `- search title, as planned: ${listingValue(looseText(planned['seoTitle']))}`,
985
+ `- search description, as planned: ${listingValue(looseText(planned['seoDescription']))}`,
986
+ `- navigation: ${planned['nav'] === true ? 'an entry for the page is proposed' : 'no entry is proposed'}`,
987
+ layout
988
+ ].join('\n');
989
+ }
990
+ /** Keys a stored node keeps for the store: its own id, its parent, its node type and its plugin. */ function graderNode(id, node) {
991
+ if (!isLoose(node)) return node;
992
+ const kept = {};
993
+ for (const [key, value] of Object.entries(node)){
994
+ if (key === 'parentId' || key === 'pluginId') continue;
995
+ if (key === '$id' && value === id) continue;
996
+ if (key === 'type' && value === 'node') continue;
997
+ kept[key] = value;
998
+ }
999
+ return kept;
1000
+ }
1001
+ /**
1002
+ * An answer's output as its grader reads it: copy as written, and anything
1003
+ * else as JSON, a tree's nodes without the keys the store keeps for itself
1004
+ * (AGL-3073). Those are about a third of a recorded page, and a grade reads
1005
+ * none of them: a node's id is its key and its parent is the node that lists
1006
+ * it.
1007
+ */ export function aiEvalGraderOutput(output) {
1008
+ if (typeof output === 'string') return output;
1009
+ const tree = isLoose(output) && isLoose(output['tree']) ? output['tree'] : null;
1010
+ if (!isLoose(output) || !tree || !isLoose(tree['nodes'])) return JSON.stringify(output);
1011
+ const nodes = Object.fromEntries(Object.entries(tree['nodes']).map(([id, node])=>[
1012
+ id,
1013
+ graderNode(id, node)
1014
+ ]));
1015
+ return JSON.stringify(_extends({}, output, {
1016
+ tree: _extends({}, tree, {
1017
+ nodes
1018
+ })
1019
+ }));
1020
+ }
1021
+ /**
1022
+ * What the grader of an answer written from more than its brief is shown of
1023
+ * the request (AGL-3074): the user turn the kind's step sends, built from the
1024
+ * case by the step's own prompt builder — a product and the categories it may
1025
+ * go in, the categories a store already has, or what an automation draft or
1026
+ * explanation was asked from. A grader that is not shown them grades copy
1027
+ * against a product it never saw, and an explanation against an automation it
1028
+ * never read. `null` for a kind whose request is its brief and its site.
1029
+ */ export function aiEvalGraderRequest(evalCase, answer) {
1030
+ if (evalCase.kind === 'product') {
1031
+ var _evalCase_siteName;
1032
+ return evalCase.product ? aiProductCopyPrompt({
1033
+ store: (_evalCase_siteName = evalCase.siteName) != null ? _evalCase_siteName : '',
1034
+ product: evalCase.product.facts,
1035
+ categories: evalCase.product.categories,
1036
+ photo: answer.photo === 'read'
1037
+ }) : null;
1038
+ }
1039
+ if (evalCase.kind === 'categories') {
1040
+ var _evalCase_siteName1, _evalCase_existingCategoryNames;
1041
+ return aiCategoriesPrompt({
1042
+ store: (_evalCase_siteName1 = evalCase.siteName) != null ? _evalCase_siteName1 : '',
1043
+ brief: evalCase.brief,
1044
+ existingCategoryNames: (_evalCase_existingCategoryNames = evalCase.existingCategoryNames) != null ? _evalCase_existingCategoryNames : []
1045
+ });
1046
+ }
1047
+ if (evalCase.kind === 'workflow') {
1048
+ var _answer_model;
1049
+ const [turn] = aiEvalWorkflowGeneration(evalCase, (_answer_model = answer.model) != null ? _answer_model : aiJobWorkflowModel()).messages;
1050
+ return typeof (turn == null ? void 0 : turn.content) === 'string' ? turn.content : null;
1051
+ }
1052
+ return null;
1053
+ }
1054
+ /** What the grader of product copy written with its photo in view is told beside the photo (AGL-3074). */ export const AI_EVAL_PHOTO_GRADER_NOTE = "The product's photo is attached, as the job sent it. Copy may state what the photo plainly shows and is never marked down for it; it is marked down for what neither the photo nor the product's words show.";
1055
+ /** What the grader is told when the photo the copy was written with cannot be shown to it. */ export const AI_EVAL_PHOTO_UNSHOWN_GRADER_NOTE = "The copy was written with the product's photo in view, and this grader is not shown it: never mark copy down for a detail only the photo could show.";
1056
+ /**
1057
+ * The grader's user turn: the brief, its site, the workspace where the case
1058
+ * describes one, the request beyond the brief, the plan a built answer came
1059
+ * from, the screen and layout a built page was built as, and the answer.
1060
+ * `shown.photo` says the product's photo rides beside this turn.
1061
+ */ export function aiEvalGraderPrompt(evalCase, answer, shown = {}) {
1062
+ const planScope = answer.scope === 'plan';
1063
+ const output = planScope ? answer.plan : answer.answer;
1064
+ const workspace = aiEvalGraderCapabilities(evalCase);
1065
+ const request = planScope ? null : aiEvalGraderRequest(evalCase, answer);
1066
+ const plan = planScope ? null : aiEvalPlanOutline(answer.plan);
1067
+ const page = !planScope && evalCase.kind === 'page' ? aiEvalBuiltPage(answer) : null;
1068
+ return [
1069
+ `Output kind: ${evalCase.kind}${planScope ? ' (its build plan)' : ''}`,
1070
+ ...planScope ? [
1071
+ AI_EVAL_PLAN_GRADER_NOTE
1072
+ ] : [],
1073
+ `Brief: ${evalCase.brief}`,
1074
+ aiSiteInventoryBlock(evalCase.inventory),
1075
+ ...workspace ? [
1076
+ workspace
1077
+ ] : [],
1078
+ ...request ? [
1079
+ `The request the answer was written from:\n${request}`
1080
+ ] : [],
1081
+ ...answer.photo === 'read' ? [
1082
+ shown.photo ? AI_EVAL_PHOTO_GRADER_NOTE : AI_EVAL_PHOTO_UNSHOWN_GRADER_NOTE
1083
+ ] : [],
1084
+ ...plan ? [
1085
+ plan
1086
+ ] : [],
1087
+ ...page ? [
1088
+ page,
1089
+ AI_EVAL_PAGE_GRADER_NOTE
1090
+ ] : [],
1091
+ `Output:\n${aiEvalGraderOutput(output)}`
1092
+ ].join('\n\n');
1093
+ }
1094
+ /** A grade tool call read as a rubric; `null` when a grade is missing. */ export function readAiEvalGrade(answer, grader) {
1095
+ const grade = (value)=>{
1096
+ const parsed = Number(value);
1097
+ return Number.isInteger(parsed) && parsed >= 1 && parsed <= 5 ? parsed : null;
1098
+ };
1099
+ const structure = grade(answer['structure']);
1100
+ const copy = grade(answer['copy']);
1101
+ if (structure === null || copy === null) return null;
1102
+ return _extends({
1103
+ structure,
1104
+ copy,
1105
+ reuse: answer['reuse'] === null ? null : grade(answer['reuse']),
1106
+ grader
1107
+ }, typeof answer['notes'] === 'string' && answer['notes'] ? {
1108
+ notes: answer['notes']
1109
+ } : {});
1110
+ }
1111
+ /** Grade one recorded answer with a stronger model, through the doctrine's loop. */ export async function gradeAiEvalCandidate(evalCase, answer, options) {
1112
+ var _options_provider, _options_graderModel;
1113
+ const provider = (_options_provider = options.provider) != null ? _options_provider : resolveAiProvider();
1114
+ const model = (_options_graderModel = options.graderModel) != null ? _options_graderModel : provider ? aiDefaultModelFor(provider.id, 'deep') : undefined;
1115
+ if (!model) throw new Error('no grader model: the provider serves no deep tier and none was named');
1116
+ // Copy written with the product's photo in view is graded with the same
1117
+ // picture, where the grader's model reads one (AGL-3074).
1118
+ const photo = answer.photo === 'read' && provider && aiModelReadsImages(provider, model) ? await aiEvalCasePhoto(evalCase, options) : null;
1119
+ const prompt = aiEvalGraderPrompt(evalCase, answer, {
1120
+ photo: Boolean(photo)
1121
+ });
1122
+ const result = await runValidatedGeneration('eval-grade', withProvider({
1123
+ model,
1124
+ instructions: AI_EVAL_GRADER_INSTRUCTIONS,
1125
+ messages: [
1126
+ {
1127
+ role: 'user',
1128
+ content: photo ? [
1129
+ photo,
1130
+ {
1131
+ type: 'text',
1132
+ text: prompt
1133
+ }
1134
+ ] : prompt
1135
+ }
1136
+ ],
1137
+ tool: AI_EVAL_RUBRIC_TOOL,
1138
+ maxTokens: 2000,
1139
+ thinking: 'adaptive',
1140
+ check: (raw)=>{
1141
+ const rubric = readAiEvalGrade(raw, model);
1142
+ return rubric ? {
1143
+ value: rubric,
1144
+ violations: []
1145
+ } : {
1146
+ value: null,
1147
+ violations: [
1148
+ {
1149
+ rule: null,
1150
+ code: 'grade-missing',
1151
+ message: 'Every grade is a whole number from 1 to 5.'
1152
+ }
1153
+ ]
1154
+ };
1155
+ }
1156
+ }, options));
1157
+ if (result.status !== 'ok') {
1158
+ return {
1159
+ structure: 1,
1160
+ copy: 1,
1161
+ reuse: null,
1162
+ grader: model,
1163
+ notes: `the grader returned ${result.status}`
1164
+ };
1165
+ }
1166
+ return result.value;
1167
+ }
1168
+ /** The vendor's request id off a thrown `UpstreamServiceError`, when it carried one. */ function requestIdOfThrown(error) {
1169
+ const id = error == null ? void 0 : error.requestId;
1170
+ return typeof id === 'string' && id ? id : null;
1171
+ }
1172
+ function messageOfThrown(error) {
1173
+ return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
1174
+ }
1175
+ /**
1176
+ * Record and grade an answer for every brief a recorder covers. Refused
1177
+ * before anything else unless `AI_EVAL_LIVE=1` names the run, and before any
1178
+ * request when a brief it would record names media the run cannot read.
1179
+ *
1180
+ * ONE BRIEF'S FAILURE IS NOT THE RUN'S (AGL-3143). A run is owner-approved
1181
+ * spend, and a provider that refuses one brief — a tool it will not compile,
1182
+ * a rate limit — used to end the whole run with the answers already paid for
1183
+ * still in memory and never written. Each brief is run on its own instead:
1184
+ * one that throws is kept as a failure naming what was thrown, the vendor's
1185
+ * request id and which half of its run threw, and the briefs behind it are
1186
+ * still recorded. The caller writes what came back and decides what a
1187
+ * non-empty `failed` means for its exit status.
1188
+ *
1189
+ * A brief whose GRADE threw is in both halves: recorded, with its grade
1190
+ * marked missing, and failed, naming what the grader threw.
1191
+ */ export async function recordAiEvalLive(cases, options) {
1192
+ if (!aiEvalLiveAllowed(options.env)) throw new AiEvalLiveRefusedError();
1193
+ const unreadable = cases.filter((evalCase)=>evalCase.media && aiEvalRecorderFor(evalCase.kind) && !options.readFixture);
1194
+ if (unreadable.length) {
1195
+ throw new Error(`${unreadable.map((evalCase)=>evalCase.id).join(', ')} name media, and this run was given no readFixture to read them with`);
1196
+ }
1197
+ const report = {
1198
+ recorded: [],
1199
+ skipped: [],
1200
+ failed: []
1201
+ };
1202
+ for (const evalCase of cases){
1203
+ const recorder = aiEvalRecorderFor(evalCase.kind);
1204
+ if (!recorder) {
1205
+ report.skipped.push({
1206
+ caseId: evalCase.id,
1207
+ kind: evalCase.kind,
1208
+ why: aiEvalSkipReason(evalCase.kind)
1209
+ });
1210
+ continue;
1211
+ }
1212
+ const failure = (step, error)=>{
1213
+ report.failed.push({
1214
+ caseId: evalCase.id,
1215
+ kind: evalCase.kind,
1216
+ step,
1217
+ error: messageOfThrown(error),
1218
+ requestId: requestIdOfThrown(error)
1219
+ });
1220
+ };
1221
+ let answer;
1222
+ try {
1223
+ answer = await recorder(evalCase, options);
1224
+ } catch (error) {
1225
+ failure('record', error);
1226
+ continue;
1227
+ }
1228
+ // A GRADER THAT THROWS DOES NOT TAKE THE ANSWER WITH IT (AGL-3143). The
1229
+ // brief is already paid for by here, and grading is a second request that
1230
+ // can fail on its own — a rate limit, a tool the provider will not
1231
+ // compile. The answer is recorded with its grade marked missing, and the
1232
+ // throw is still reported, so the run exits non-zero without the next
1233
+ // one having to buy this answer again.
1234
+ try {
1235
+ const rubric = await gradeAiEvalCandidate(evalCase, answer, options);
1236
+ report.recorded.push({
1237
+ caseId: evalCase.id,
1238
+ kind: evalCase.kind,
1239
+ candidate: _extends({}, answer, {
1240
+ rubric
1241
+ })
1242
+ });
1243
+ } catch (error) {
1244
+ report.recorded.push({
1245
+ caseId: evalCase.id,
1246
+ kind: evalCase.kind,
1247
+ candidate: _extends({}, answer, {
1248
+ rubric: null
1249
+ })
1250
+ });
1251
+ failure('grade', error);
1252
+ }
1253
+ }
1254
+ return report;
1255
+ }
1256
+
1257
+ //# sourceMappingURL=ai-eval-live.js.map