@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,381 @@
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 { isLiveSubscriptionStatus, ORG_BILLING_DOC_ID, ORG_BILLING_SUBCOLLECTION, orgCogsInputFrom, pluginRequestFromWeb } from "@aglyn/aglyn/server";
18
+ import { emailUnverifiedResponse, firebaseAdmin, isImpersonationSession, readOrgBilling } from "@aglyn/tenant-data-admin";
19
+ import { assistUsageMonth } from "../usage/assist-usage.js";
20
+ import { assistRefusalCounts } from "../usage/assist-refusals.js";
21
+ import { readOrgAiUsageByUser } from "../usage/ai-usage-by-user.js";
22
+ import { recordAdminAudit } from "@aglyn/tenant-data-admin/server/admin-audit";
23
+ import { invalidIdTokenResponse } from "@aglyn/tenant-data-admin/server/id-token-refusal";
24
+ import { addonKindFromPriceId } from "@aglyn/tenant-data-admin/server/billing-addons";
25
+ import { orgMarginRow } from "@aglyn/aglyn/app-utils/margin-utilization";
26
+ import { assistCogsAlertThresholdUsd, assistMarginMultiple } from "@aglyn/aglyn/app-utils/usage-budget";
27
+ import { composeStaffOrgAiAddon, composeStaffOrgAiMargin, composeStaffOrgAiOverage, composeStaffOrgAiPool, composeStaffOrgAiTokens, emptyJobCounts, STAFF_ORG_AI_JOB_STATUSES } from "../usage/staff-org-ai.js";
28
+ /**
29
+ * THE STAFF AI CARD'S BACKING READ (AGL-2930).
30
+ *
31
+ * One request composes everything the card on the staff org page shows: the
32
+ * add-on and when it was bought, the credit pool and its parts, the month's
33
+ * overage and the org's own ceilings, the refusal counter, the generation
34
+ * jobs, the per-user rollup and the margin. Staff-gated exactly as
35
+ * `/api/admin/org-usage` is, and read-only — every access below is a `get()`.
36
+ *
37
+ * ## The reads, stated
38
+ *
39
+ * The org document and its billing mirror; this month's `assistUsage`
40
+ * document; the newest usage rollup (for the contribution margin, the same
41
+ * read the margin route makes); a bounded page of `aiJobs`; the per-user
42
+ * rollup for the month; and, when the add-on is on, ONE Stripe subscription
43
+ * lookup that is cached in-process — see `addonSinceFor`.
44
+ *
45
+ * ## The `access` audit row
46
+ *
47
+ * Opening the card reads per-user attribution, which is the one thing on it
48
+ * that is about a person rather than a workspace. So the open is recorded to
49
+ * `adminAudit` as an ACCESS — `org.ai-viewed`, target the org's assist usage
50
+ * path — through the same writer that records a staff member opening a
51
+ * customer's email. No `subjectUid`: the row is about the org, and naming
52
+ * every uid on the leaderboard would put a row on ten people's pages for one
53
+ * staff glance at a table.
54
+ */ /** Generation jobs read per request; the counts are a floor past it. */ const JOBS_SCAN = 200;
55
+ /** How many jobs the card lists. */ const JOBS_RECENT = 10;
56
+ /** How many people the leaderboard names. */ const TOP_USERS = 10;
57
+ /**
58
+ * How long a Stripe answer to "when was the add-on bought" is kept.
59
+ *
60
+ * The date does not move once the item exists, and the card is opened far
61
+ * more often than an add-on is bought, so the only cost of a stale entry is
62
+ * a card that says "since —" for up to this long after a purchase. The
63
+ * alternative — a Stripe round trip on every render — is the thing the brief
64
+ * forbade.
65
+ */ const ADDON_SINCE_TTL_MS = 15 * 60 * 1000;
66
+ const addonSinceCache = new Map();
67
+ /** Test seam: drop every cached Stripe answer. */ export function resetAddonSinceCache() {
68
+ addonSinceCache.clear();
69
+ }
70
+ /**
71
+ * The instant the add-on's subscription item was created, from Stripe.
72
+ *
73
+ * The org document carries the add-on as a quantity (`seatAddons.aiAddon`)
74
+ * and nothing about WHEN — the webhook mirrors items, not their dates. Stripe
75
+ * has it as `created` on the subscription item, found by the price id the
76
+ * add-on sells at (`addonKindFromPriceId`), so a rename or a price change
77
+ * does not lose it.
78
+ */ async function addonSinceFor(orgId) {
79
+ const cached = addonSinceCache.get(orgId);
80
+ if (cached && Date.now() - cached.at < ADDON_SINCE_TTL_MS) return cached;
81
+ const answer = await readAddonSince(orgId);
82
+ addonSinceCache.set(orgId, answer);
83
+ return answer;
84
+ }
85
+ async function readAddonSince(orgId) {
86
+ const at = Date.now();
87
+ const stripeKey = process.env.STRIPE_SECRET_KEY;
88
+ if (!stripeKey) return {
89
+ since: null,
90
+ sinceSource: 'unavailable',
91
+ at
92
+ };
93
+ try {
94
+ var _ref;
95
+ const customerId = (await readOrgBilling(orgId)).stripeCustomerId;
96
+ if (!customerId) return {
97
+ since: null,
98
+ sinceSource: 'no-subscription',
99
+ at
100
+ };
101
+ const response = await fetch(`https://api.stripe.com/v1/subscriptions?customer=${encodeURIComponent(String(customerId))}&status=all&limit=10`, {
102
+ headers: {
103
+ Authorization: `Bearer ${stripeKey}`
104
+ }
105
+ });
106
+ const payload = await response.json().catch(()=>null);
107
+ if (!response.ok) {
108
+ var _ref1;
109
+ var _payload_error;
110
+ console.error('[ai/admin/org] Stripe subscription lookup failed', {
111
+ orgId,
112
+ status: response.status,
113
+ detail: (_ref1 = payload == null ? void 0 : (_payload_error = payload.error) == null ? void 0 : _payload_error.message) != null ? _ref1 : null
114
+ });
115
+ return {
116
+ since: null,
117
+ sinceSource: 'unavailable',
118
+ at
119
+ };
120
+ }
121
+ const subscriptions = (_ref = payload == null ? void 0 : payload.data) != null ? _ref : [];
122
+ // The LIVE subscription's item, when one exists: an add-on on a canceled
123
+ // subscription is not an add-on the org has, and `hasAiAddon` already
124
+ // says so — the date beside "off" would only confuse.
125
+ const live = subscriptions.filter((subscription)=>isLiveSubscriptionStatus(subscription.status));
126
+ for (const subscription of live.length ? live : subscriptions){
127
+ var _ref2;
128
+ var _subscription_items;
129
+ for (const item of (_ref2 = (_subscription_items = subscription.items) == null ? void 0 : _subscription_items.data) != null ? _ref2 : []){
130
+ var _item_price;
131
+ if (addonKindFromPriceId((_item_price = item.price) == null ? void 0 : _item_price.id) !== 'aiAddon') continue;
132
+ const created = Number(item.created);
133
+ if (Number.isFinite(created) && created > 0) {
134
+ return {
135
+ since: new Date(created * 1000).toISOString(),
136
+ sinceSource: 'stripe',
137
+ at
138
+ };
139
+ }
140
+ }
141
+ }
142
+ return {
143
+ since: null,
144
+ sinceSource: 'stripe',
145
+ at
146
+ };
147
+ } catch (error) {
148
+ console.error('[ai/admin/org] Stripe subscription lookup threw', error);
149
+ return {
150
+ since: null,
151
+ sinceSource: 'unavailable',
152
+ at
153
+ };
154
+ }
155
+ }
156
+ const toIso = (value)=>{
157
+ var _value_toDate;
158
+ const converted = value == null ? void 0 : (_value_toDate = value.toDate) == null ? void 0 : _value_toDate.call(value);
159
+ if (converted instanceof Date) return converted.toISOString();
160
+ if (value instanceof Date) return value.toISOString();
161
+ return null;
162
+ };
163
+ /**
164
+ * The month's generation jobs, summarized (AGL-2904's collection).
165
+ *
166
+ * Reads `orgs/{orgId}/aiJobs` by `createdAt` from the first instant of the
167
+ * month, newest first, up to `JOBS_SCAN`. An org with no such collection
168
+ * answers an empty snapshot, which is the honest "no generation jobs yet";
169
+ * a read that FAILED answers `null`, which the card renders as a failure
170
+ * rather than as an idle org. The field names are the ones `AiJob` declares
171
+ * in `ai-jobs.types.ts`: `kind`, `status`, `creditsReserved`, `creditsSpent`,
172
+ * `createdAt`, `createdBy`.
173
+ */ export async function readOrgAiJobsSummary(firestore, orgId, month) {
174
+ try {
175
+ const monthStart = new Date(`${month}-01T00:00:00.000Z`);
176
+ const snapshot = await firestore.collection('orgs').doc(orgId).collection('aiJobs').where('createdAt', '>=', monthStart).orderBy('createdAt', 'desc').limit(JOBS_SCAN + 1).get();
177
+ const truncated = snapshot.docs.length > JOBS_SCAN;
178
+ const docs = truncated ? snapshot.docs.slice(0, JOBS_SCAN) : snapshot.docs;
179
+ const counts = emptyJobCounts();
180
+ const recent = [];
181
+ for (const doc of docs){
182
+ var _doc_get;
183
+ const status = String((_doc_get = doc.get('status')) != null ? _doc_get : '');
184
+ if (STAFF_ORG_AI_JOB_STATUSES.includes(status)) {
185
+ counts[status] += 1;
186
+ }
187
+ if (recent.length < JOBS_RECENT) {
188
+ var _doc_get1, _doc_get2, _doc_get3;
189
+ recent.push({
190
+ id: doc.id,
191
+ kind: String((_doc_get1 = doc.get('kind')) != null ? _doc_get1 : ''),
192
+ status,
193
+ creditsReserved: Number((_doc_get2 = doc.get('creditsReserved')) != null ? _doc_get2 : 0) || 0,
194
+ creditsSpent: Number((_doc_get3 = doc.get('creditsSpent')) != null ? _doc_get3 : 0) || 0,
195
+ createdAt: toIso(doc.get('createdAt')),
196
+ createdBy: typeof doc.get('createdBy') === 'string' ? String(doc.get('createdBy')) : null
197
+ });
198
+ }
199
+ }
200
+ return {
201
+ counts,
202
+ recent,
203
+ truncated
204
+ };
205
+ } catch (error) {
206
+ console.error('[ai/admin/org] jobs read failed', error);
207
+ return null;
208
+ }
209
+ }
210
+ /**
211
+ * The month's per-user rollup, dearest first (AGL-2928).
212
+ *
213
+ * `readOrgAiUsageByUser` is the one reader of
214
+ * `orgs/{orgId}/aiUsageByUser/{uid}/months/{month}` — the customer's Usage
215
+ * table reads through it too — joined to the roster for names and carrying
216
+ * each person's share of the org's measured spend. The card keeps the
217
+ * dearest `TOP_USERS`.
218
+ */ async function readOrgAiTopUsers(firestore, orgId, month) {
219
+ try {
220
+ const usage = await readOrgAiUsageByUser(firestore, orgId, month);
221
+ return usage.rows.slice(0, TOP_USERS).map((row)=>({
222
+ uid: row.uid,
223
+ name: row.name,
224
+ credits: row.credits,
225
+ estCostUsd: row.estCostUsd,
226
+ share: row.share,
227
+ requests: row.requests,
228
+ refusals: row.refusals,
229
+ byKind: row.byKind,
230
+ byHost: row.byHost
231
+ }));
232
+ } catch (error) {
233
+ console.error('[ai/admin/org] per-user read failed', error);
234
+ return [];
235
+ }
236
+ }
237
+ async function handler(request) {
238
+ var _headers_authorization, _query_orgId;
239
+ const { method, query, headers: rawHeaders } = await pluginRequestFromWeb(request);
240
+ const headers = rawHeaders;
241
+ if (method !== 'GET') {
242
+ return Response.json({
243
+ error: 'Method not allowed'
244
+ }, {
245
+ status: 405
246
+ });
247
+ }
248
+ const authorization = (_headers_authorization = headers.authorization) != null ? _headers_authorization : '';
249
+ const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
250
+ if (!idToken) return Response.json({
251
+ error: 'Unauthenticated'
252
+ }, {
253
+ status: 401
254
+ });
255
+ const orgId = String((_query_orgId = query.orgId) != null ? _query_orgId : '');
256
+ if (!orgId) return Response.json({
257
+ error: 'Missing orgId'
258
+ }, {
259
+ status: 400
260
+ });
261
+ try {
262
+ var _orgSnap_data, _monthSnap_data, _org_name, _rollupDoc_get, _ref, _ref1, _ref2;
263
+ const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
264
+ if (!decoded.email_verified && !isImpersonationSession(decoded)) {
265
+ return emailUnverifiedResponse();
266
+ }
267
+ if (!decoded['staff']) {
268
+ return Response.json({
269
+ error: 'Staff only'
270
+ }, {
271
+ status: 403
272
+ });
273
+ }
274
+ const now = new Date();
275
+ const month = assistUsageMonth(now);
276
+ const db = firebaseAdmin.app().firestore();
277
+ const orgRef = db.collection('orgs').doc(orgId);
278
+ const [orgSnap, billingSnap, monthSnap, rollupSnap] = await Promise.all([
279
+ orgRef.get(),
280
+ orgRef.collection(ORG_BILLING_SUBCOLLECTION).doc(ORG_BILLING_DOC_ID).get(),
281
+ orgRef.collection('assistUsage').doc(month).get(),
282
+ orgRef.collection('usage').orderBy('month', 'desc').limit(1).get()
283
+ ]);
284
+ if (!orgSnap.exists) {
285
+ return Response.json({
286
+ error: 'No such organization'
287
+ }, {
288
+ status: 404
289
+ });
290
+ }
291
+ // Org doc FIRST so a stale inline `subscription` loses to the billing
292
+ // mirror — the same merge the margin route and the org detail read make.
293
+ const org = _extends({}, (_orgSnap_data = orgSnap.data()) != null ? _orgSnap_data : {}, billingSnap.exists ? billingSnap.data() : {});
294
+ const monthDoc = monthSnap.exists ? (_monthSnap_data = monthSnap.data()) != null ? _monthSnap_data : {} : null;
295
+ /*
296
+ * The row is written BEFORE the person-shaped read is served, and it is
297
+ * awaited: a card that rendered the leaderboard and then failed to
298
+ * record the look would be the access this collection exists to never
299
+ * lose. A failed write logs and still serves — the card is not a closed
300
+ * collection the way the delivery log is — but the order is the point.
301
+ */ try {
302
+ await recordAdminAudit({
303
+ actorUid: decoded.uid,
304
+ action: 'org.ai-viewed',
305
+ target: `orgs/${orgId}/assistUsage`,
306
+ note: `AI card opened for ${month}`
307
+ });
308
+ } catch (error) {
309
+ console.error('[ai/admin/org] audit write failed', error);
310
+ }
311
+ const [jobs, users, since] = await Promise.all([
312
+ readOrgAiJobsSummary(db, orgId, month),
313
+ readOrgAiTopUsers(db, orgId, month),
314
+ addonSinceFor(orgId)
315
+ ]);
316
+ const pool = composeStaffOrgAiPool(org, monthDoc, now);
317
+ // The overage line is an invoice, so it is priced off what the month
318
+ // DREW; everything below it is our bill, so it reads what the month
319
+ // COST (AGL-3015).
320
+ const overage = composeStaffOrgAiOverage(org, pool.billedUsd);
321
+ const addon = composeStaffOrgAiAddon(org, {
322
+ since: since.since,
323
+ sinceSource: since.sinceSource
324
+ });
325
+ const thresholdUsd = assistCogsAlertThresholdUsd(process.env.ASSIST_ORG_MONTHLY_COGS_ALERT_USD);
326
+ const rollupDoc = rollupSnap.docs[0];
327
+ // The whole-org contribution margin, on the same row the margin
328
+ // utilization page builds — with THIS month's live assist spend in
329
+ // place of the figure frozen onto the rollup, as that route does.
330
+ const contributionRow = rollupDoc ? orgMarginRow({
331
+ orgId,
332
+ name: (_org_name = org['name']) != null ? _org_name : null,
333
+ org: org,
334
+ month: String((_rollupDoc_get = rollupDoc.get('month')) != null ? _rollupDoc_get : rollupDoc.id),
335
+ rollup: _extends({}, orgCogsInputFrom(rollupDoc.data()), {
336
+ assistCostUsd: pool.providerUsd
337
+ })
338
+ }) : null;
339
+ const margin = composeStaffOrgAiMargin({
340
+ org: org,
341
+ pool,
342
+ overage,
343
+ addon,
344
+ thresholdUsd,
345
+ multiple: assistMarginMultiple(pool.providerUsd, thresholdUsd),
346
+ contribution: {
347
+ month: (_ref = contributionRow == null ? void 0 : contributionRow.month) != null ? _ref : null,
348
+ marginPct: (_ref1 = contributionRow == null ? void 0 : contributionRow.marginPct) != null ? _ref1 : null,
349
+ rating: (_ref2 = contributionRow == null ? void 0 : contributionRow.rating) != null ? _ref2 : null
350
+ }
351
+ });
352
+ const body = {
353
+ month,
354
+ addon,
355
+ pool,
356
+ overage,
357
+ refusals: assistRefusalCounts(monthDoc == null ? void 0 : monthDoc['refusals']),
358
+ jobs,
359
+ users,
360
+ margin,
361
+ tokens: composeStaffOrgAiTokens(monthDoc)
362
+ };
363
+ return Response.json(body, {
364
+ status: 200
365
+ });
366
+ } catch (error) {
367
+ // An unverifiable credential is a 401, not a fault of ours
368
+ // (AGL-1993). Null for anything else, so a real failure keeps its 500.
369
+ const unauthenticated = invalidIdTokenResponse(error);
370
+ if (unauthenticated) return unauthenticated;
371
+ console.error('[ai/admin/org]', error);
372
+ return Response.json({
373
+ error: 'AI lookup failed'
374
+ }, {
375
+ status: 500
376
+ });
377
+ }
378
+ }
379
+ export { handler as GET };
380
+
381
+ //# sourceMappingURL=ai-admin-org.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/server/ai-admin-org.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n isLiveSubscriptionStatus,\n ORG_BILLING_DOC_ID,\n ORG_BILLING_SUBCOLLECTION,\n orgCogsInputFrom,\n pluginRequestFromWeb,\n} from '@aglyn/aglyn/server'\nimport {\n emailUnverifiedResponse,\n firebaseAdmin,\n isImpersonationSession,\n readOrgBilling,\n} from '@aglyn/tenant-data-admin'\nimport { assistUsageMonth } from '../usage/assist-usage'\nimport { assistRefusalCounts } from '../usage/assist-refusals'\nimport { readOrgAiUsageByUser } from '../usage/ai-usage-by-user'\nimport { recordAdminAudit } from '@aglyn/tenant-data-admin/server/admin-audit'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport { addonKindFromPriceId } from '@aglyn/tenant-data-admin/server/billing-addons'\nimport { orgMarginRow } from '@aglyn/aglyn/app-utils/margin-utilization'\nimport {\n assistCogsAlertThresholdUsd,\n assistMarginMultiple,\n} from '@aglyn/aglyn/app-utils/usage-budget'\nimport {\n composeStaffOrgAiAddon,\n composeStaffOrgAiMargin,\n composeStaffOrgAiOverage,\n composeStaffOrgAiPool,\n composeStaffOrgAiTokens,\n emptyJobCounts,\n STAFF_ORG_AI_JOB_STATUSES,\n type StaffOrgAiAddon,\n type StaffOrgAiJob,\n type StaffOrgAiJobs,\n type StaffOrgAiResponse,\n type StaffOrgAiUser,\n} from '../usage/staff-org-ai'\n\n/**\n * THE STAFF AI CARD'S BACKING READ (AGL-2930).\n *\n * One request composes everything the card on the staff org page shows: the\n * add-on and when it was bought, the credit pool and its parts, the month's\n * overage and the org's own ceilings, the refusal counter, the generation\n * jobs, the per-user rollup and the margin. Staff-gated exactly as\n * `/api/admin/org-usage` is, and read-only — every access below is a `get()`.\n *\n * ## The reads, stated\n *\n * The org document and its billing mirror; this month's `assistUsage`\n * document; the newest usage rollup (for the contribution margin, the same\n * read the margin route makes); a bounded page of `aiJobs`; the per-user\n * rollup for the month; and, when the add-on is on, ONE Stripe subscription\n * lookup that is cached in-process — see `addonSinceFor`.\n *\n * ## The `access` audit row\n *\n * Opening the card reads per-user attribution, which is the one thing on it\n * that is about a person rather than a workspace. So the open is recorded to\n * `adminAudit` as an ACCESS — `org.ai-viewed`, target the org's assist usage\n * path — through the same writer that records a staff member opening a\n * customer's email. No `subjectUid`: the row is about the org, and naming\n * every uid on the leaderboard would put a row on ten people's pages for one\n * staff glance at a table.\n */\n\n/** Generation jobs read per request; the counts are a floor past it. */\nconst JOBS_SCAN = 200\n\n/** How many jobs the card lists. */\nconst JOBS_RECENT = 10\n\n/** How many people the leaderboard names. */\nconst TOP_USERS = 10\n\n/**\n * How long a Stripe answer to \"when was the add-on bought\" is kept.\n *\n * The date does not move once the item exists, and the card is opened far\n * more often than an add-on is bought, so the only cost of a stale entry is\n * a card that says \"since —\" for up to this long after a purchase. The\n * alternative — a Stripe round trip on every render — is the thing the brief\n * forbade.\n */\nconst ADDON_SINCE_TTL_MS = 15 * 60 * 1000\n\ninterface AddonSince {\n since: string | null\n sinceSource: StaffOrgAiAddon['sinceSource']\n at: number\n}\n\nconst addonSinceCache = new Map<string, AddonSince>()\n\n/** Test seam: drop every cached Stripe answer. */\nexport function resetAddonSinceCache(): void {\n addonSinceCache.clear()\n}\n\n/**\n * The instant the add-on's subscription item was created, from Stripe.\n *\n * The org document carries the add-on as a quantity (`seatAddons.aiAddon`)\n * and nothing about WHEN — the webhook mirrors items, not their dates. Stripe\n * has it as `created` on the subscription item, found by the price id the\n * add-on sells at (`addonKindFromPriceId`), so a rename or a price change\n * does not lose it.\n */\nasync function addonSinceFor(orgId: string): Promise<AddonSince> {\n const cached = addonSinceCache.get(orgId)\n if (cached && Date.now() - cached.at < ADDON_SINCE_TTL_MS) return cached\n const answer = await readAddonSince(orgId)\n addonSinceCache.set(orgId, answer)\n return answer\n}\n\nasync function readAddonSince(orgId: string): Promise<AddonSince> {\n const at = Date.now()\n const stripeKey = process.env.STRIPE_SECRET_KEY\n if (!stripeKey) return { since: null, sinceSource: 'unavailable', at }\n try {\n const customerId = (await readOrgBilling(orgId)).stripeCustomerId\n if (!customerId) return { since: null, sinceSource: 'no-subscription', at }\n const response = await fetch(\n `https://api.stripe.com/v1/subscriptions?customer=${encodeURIComponent(\n String(customerId),\n )}&status=all&limit=10`,\n { headers: { Authorization: `Bearer ${stripeKey}` } },\n )\n const payload = await response.json().catch(() => null)\n if (!response.ok) {\n console.error('[ai/admin/org] Stripe subscription lookup failed', {\n orgId,\n status: response.status,\n detail: payload?.error?.message ?? null,\n })\n return { since: null, sinceSource: 'unavailable', at }\n }\n const subscriptions = (payload?.data ?? []) as Array<{\n status?: string\n items?: { data?: Array<{ created?: number; price?: { id?: string } }> }\n }>\n // The LIVE subscription's item, when one exists: an add-on on a canceled\n // subscription is not an add-on the org has, and `hasAiAddon` already\n // says so — the date beside \"off\" would only confuse.\n const live = subscriptions.filter((subscription) =>\n isLiveSubscriptionStatus(subscription.status),\n )\n for (const subscription of live.length ? live : subscriptions) {\n for (const item of subscription.items?.data ?? []) {\n if (addonKindFromPriceId(item.price?.id) !== 'aiAddon') continue\n const created = Number(item.created)\n if (Number.isFinite(created) && created > 0) {\n return {\n since: new Date(created * 1000).toISOString(),\n sinceSource: 'stripe',\n at,\n }\n }\n }\n }\n return { since: null, sinceSource: 'stripe', at }\n } catch (error) {\n console.error('[ai/admin/org] Stripe subscription lookup threw', error)\n return { since: null, sinceSource: 'unavailable', at }\n }\n}\n\nconst toIso = (value: unknown): string | null => {\n const converted = (value as { toDate?: () => Date } | null)?.toDate?.()\n if (converted instanceof Date) return converted.toISOString()\n if (value instanceof Date) return value.toISOString()\n return null\n}\n\n/**\n * The month's generation jobs, summarized (AGL-2904's collection).\n *\n * Reads `orgs/{orgId}/aiJobs` by `createdAt` from the first instant of the\n * month, newest first, up to `JOBS_SCAN`. An org with no such collection\n * answers an empty snapshot, which is the honest \"no generation jobs yet\";\n * a read that FAILED answers `null`, which the card renders as a failure\n * rather than as an idle org. The field names are the ones `AiJob` declares\n * in `ai-jobs.types.ts`: `kind`, `status`, `creditsReserved`, `creditsSpent`,\n * `createdAt`, `createdBy`.\n */\nexport async function readOrgAiJobsSummary(\n firestore: FirebaseFirestore.Firestore,\n orgId: string,\n month: string,\n): Promise<StaffOrgAiJobs | null> {\n try {\n const monthStart = new Date(`${month}-01T00:00:00.000Z`)\n const snapshot = await firestore\n .collection('orgs')\n .doc(orgId)\n .collection('aiJobs')\n .where('createdAt', '>=', monthStart)\n .orderBy('createdAt', 'desc')\n .limit(JOBS_SCAN + 1)\n .get()\n const truncated = snapshot.docs.length > JOBS_SCAN\n const docs = truncated ? snapshot.docs.slice(0, JOBS_SCAN) : snapshot.docs\n const counts = emptyJobCounts()\n const recent: StaffOrgAiJob[] = []\n for (const doc of docs) {\n const status = String(doc.get('status') ?? '')\n if ((STAFF_ORG_AI_JOB_STATUSES as readonly string[]).includes(status)) {\n counts[status as keyof typeof counts] += 1\n }\n if (recent.length < JOBS_RECENT) {\n recent.push({\n id: doc.id,\n kind: String(doc.get('kind') ?? ''),\n status,\n creditsReserved: Number(doc.get('creditsReserved') ?? 0) || 0,\n creditsSpent: Number(doc.get('creditsSpent') ?? 0) || 0,\n createdAt: toIso(doc.get('createdAt')),\n createdBy:\n typeof doc.get('createdBy') === 'string'\n ? String(doc.get('createdBy'))\n : null,\n })\n }\n }\n return { counts, recent, truncated }\n } catch (error) {\n console.error('[ai/admin/org] jobs read failed', error)\n return null\n }\n}\n\n/**\n * The month's per-user rollup, dearest first (AGL-2928).\n *\n * `readOrgAiUsageByUser` is the one reader of\n * `orgs/{orgId}/aiUsageByUser/{uid}/months/{month}` — the customer's Usage\n * table reads through it too — joined to the roster for names and carrying\n * each person's share of the org's measured spend. The card keeps the\n * dearest `TOP_USERS`.\n */\nasync function readOrgAiTopUsers(\n firestore: FirebaseFirestore.Firestore,\n orgId: string,\n month: string,\n): Promise<StaffOrgAiUser[]> {\n try {\n const usage = await readOrgAiUsageByUser(firestore, orgId, month)\n return usage.rows.slice(0, TOP_USERS).map((row) => ({\n uid: row.uid,\n name: row.name,\n credits: row.credits,\n estCostUsd: row.estCostUsd,\n share: row.share,\n requests: row.requests,\n refusals: row.refusals,\n byKind: row.byKind,\n byHost: row.byHost,\n }))\n } catch (error) {\n console.error('[ai/admin/org] per-user read failed', error)\n return []\n }\n}\n\nasync function handler(request: Request): Promise<Response> {\n const {\n method,\n query,\n headers: rawHeaders,\n } = await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n if (method !== 'GET') {\n return Response.json({ error: 'Method not allowed' }, { status: 405 })\n }\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ')\n ? authorization.slice('Bearer '.length)\n : undefined\n if (!idToken)\n return Response.json({ error: 'Unauthenticated' }, { status: 401 })\n const orgId = String(query.orgId ?? '')\n if (!orgId) return Response.json({ error: 'Missing orgId' }, { status: 400 })\n\n try {\n const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) {\n return emailUnverifiedResponse()\n }\n if (!decoded['staff']) {\n return Response.json({ error: 'Staff only' }, { status: 403 })\n }\n\n const now = new Date()\n const month = assistUsageMonth(now)\n const db = firebaseAdmin.app().firestore()\n const orgRef = db.collection('orgs').doc(orgId)\n\n const [orgSnap, billingSnap, monthSnap, rollupSnap] = await Promise.all([\n orgRef.get(),\n orgRef.collection(ORG_BILLING_SUBCOLLECTION).doc(ORG_BILLING_DOC_ID).get(),\n orgRef.collection('assistUsage').doc(month).get(),\n orgRef.collection('usage').orderBy('month', 'desc').limit(1).get(),\n ])\n if (!orgSnap.exists) {\n return Response.json({ error: 'No such organization' }, { status: 404 })\n }\n // Org doc FIRST so a stale inline `subscription` loses to the billing\n // mirror — the same merge the margin route and the org detail read make.\n const org = {\n ...(orgSnap.data() ?? {}),\n ...(billingSnap.exists ? billingSnap.data() : {}),\n } as Record<string, unknown>\n const monthDoc = monthSnap.exists ? (monthSnap.data() ?? {}) : null\n\n /*\n * The row is written BEFORE the person-shaped read is served, and it is\n * awaited: a card that rendered the leaderboard and then failed to\n * record the look would be the access this collection exists to never\n * lose. A failed write logs and still serves — the card is not a closed\n * collection the way the delivery log is — but the order is the point.\n */\n try {\n await recordAdminAudit({\n actorUid: decoded.uid,\n action: 'org.ai-viewed',\n target: `orgs/${orgId}/assistUsage`,\n note: `AI card opened for ${month}`,\n })\n } catch (error) {\n console.error('[ai/admin/org] audit write failed', error)\n }\n\n const [jobs, users, since] = await Promise.all([\n readOrgAiJobsSummary(db, orgId, month),\n readOrgAiTopUsers(db, orgId, month),\n addonSinceFor(orgId),\n ])\n\n const pool = composeStaffOrgAiPool(org as never, monthDoc, now)\n // The overage line is an invoice, so it is priced off what the month\n // DREW; everything below it is our bill, so it reads what the month\n // COST (AGL-3015).\n const overage = composeStaffOrgAiOverage(org as never, pool.billedUsd)\n const addon = composeStaffOrgAiAddon(org as never, {\n since: since.since,\n sinceSource: since.sinceSource,\n })\n const thresholdUsd = assistCogsAlertThresholdUsd(\n process.env.ASSIST_ORG_MONTHLY_COGS_ALERT_USD,\n )\n const rollupDoc = rollupSnap.docs[0]\n // The whole-org contribution margin, on the same row the margin\n // utilization page builds — with THIS month's live assist spend in\n // place of the figure frozen onto the rollup, as that route does.\n const contributionRow = rollupDoc\n ? orgMarginRow({\n orgId,\n name: (org['name'] as string | undefined) ?? null,\n org: org as never,\n month: String(rollupDoc.get('month') ?? rollupDoc.id),\n rollup: {\n ...orgCogsInputFrom(rollupDoc.data()),\n assistCostUsd: pool.providerUsd,\n },\n })\n : null\n const margin = composeStaffOrgAiMargin({\n org: org as never,\n pool,\n overage,\n addon,\n thresholdUsd,\n multiple: assistMarginMultiple(pool.providerUsd, thresholdUsd),\n contribution: {\n month: contributionRow?.month ?? null,\n marginPct: contributionRow?.marginPct ?? null,\n rating: contributionRow?.rating ?? null,\n },\n })\n\n const body: StaffOrgAiResponse = {\n month,\n addon,\n pool,\n overage,\n refusals: assistRefusalCounts(monthDoc?.['refusals']),\n jobs,\n users,\n margin,\n tokens: composeStaffOrgAiTokens(monthDoc),\n }\n return Response.json(body, { status: 200 })\n } catch (error) {\n // An unverifiable credential is a 401, not a fault of ours\n // (AGL-1993). Null for anything else, so a real failure keeps its 500.\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error('[ai/admin/org]', error)\n return Response.json({ error: 'AI lookup failed' }, { status: 500 })\n }\n}\n\nexport { handler as GET }\n"],"names":["isLiveSubscriptionStatus","ORG_BILLING_DOC_ID","ORG_BILLING_SUBCOLLECTION","orgCogsInputFrom","pluginRequestFromWeb","emailUnverifiedResponse","firebaseAdmin","isImpersonationSession","readOrgBilling","assistUsageMonth","assistRefusalCounts","readOrgAiUsageByUser","recordAdminAudit","invalidIdTokenResponse","addonKindFromPriceId","orgMarginRow","assistCogsAlertThresholdUsd","assistMarginMultiple","composeStaffOrgAiAddon","composeStaffOrgAiMargin","composeStaffOrgAiOverage","composeStaffOrgAiPool","composeStaffOrgAiTokens","emptyJobCounts","STAFF_ORG_AI_JOB_STATUSES","JOBS_SCAN","JOBS_RECENT","TOP_USERS","ADDON_SINCE_TTL_MS","addonSinceCache","Map","resetAddonSinceCache","clear","addonSinceFor","orgId","cached","get","Date","now","at","answer","readAddonSince","set","stripeKey","process","env","STRIPE_SECRET_KEY","since","sinceSource","customerId","stripeCustomerId","response","fetch","encodeURIComponent","String","headers","Authorization","payload","json","catch","ok","console","error","status","detail","message","subscriptions","data","live","filter","subscription","length","item","items","price","id","created","Number","isFinite","toISOString","toIso","value","converted","toDate","readOrgAiJobsSummary","firestore","month","monthStart","snapshot","collection","doc","where","orderBy","limit","truncated","docs","slice","counts","recent","includes","push","kind","creditsReserved","creditsSpent","createdAt","createdBy","readOrgAiTopUsers","usage","rows","map","row","uid","name","credits","estCostUsd","share","requests","refusals","byKind","byHost","handler","request","query","method","rawHeaders","Response","authorization","idToken","startsWith","undefined","orgSnap","monthSnap","org","rollupDoc","decoded","app","auth","verifyIdToken","email_verified","db","orgRef","billingSnap","rollupSnap","Promise","all","exists","monthDoc","actorUid","action","target","note","jobs","users","pool","overage","billedUsd","addon","thresholdUsd","ASSIST_ORG_MONTHLY_COGS_ALERT_USD","contributionRow","rollup","assistCostUsd","providerUsd","margin","multiple","contribution","marginPct","rating","body","tokens","unauthenticated","GET"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * THE STAFF ORGANIZATIONS LIST'S AI SPEND (AGL-2984).
19
+ *
20
+ * `GET /api/ai/admin/orgs-spend?orgIds=a,b,…` answers this month's provider
21
+ * spend for each org the list's page shows — the figures its AI spend column
22
+ * draws and sorts by. Staff-gated exactly as `/api/ai/admin/org` is, and
23
+ * read-only.
24
+ *
25
+ * ## The read
26
+ *
27
+ * ONE `getAll` over each named org's usage document for the current UTC
28
+ * month, the key the usage writer files spend under — a single bounded
29
+ * round trip for the page, never a read per row, and at most
30
+ * `STAFF_ORGS_AI_SPEND_MAX_IDS` ids per request.
31
+ *
32
+ * An org with no document for the month answers `null`, never `0`, and a
33
+ * read that FAILS answers `null` for every id: the list renders with the
34
+ * column blank rather than failing because this read did.
35
+ *
36
+ * No `adminAudit` row: the answer is one dollar figure per workspace, with
37
+ * nothing in it about a person.
38
+ */
39
+ declare function handler(request: Request): Promise<Response>;
40
+ export { handler as GET };
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { pluginRequestFromWeb } from "@aglyn/aglyn/server";
17
+ import { emailUnverifiedResponse, firebaseAdmin, isImpersonationSession } from "@aglyn/tenant-data-admin";
18
+ import { invalidIdTokenResponse } from "@aglyn/tenant-data-admin/server/id-token-refusal";
19
+ import { ASSIST_PROVIDER_COST_FIELD, assistProviderCostUsd } from "@aglyn/aglyn/app-utils/assist-credits";
20
+ import { assistUsageMonth } from "../usage/assist-usage.js";
21
+ import { parseStaffOrgIds } from "../usage/staff-orgs-ai-spend.js";
22
+ /**
23
+ * THE STAFF ORGANIZATIONS LIST'S AI SPEND (AGL-2984).
24
+ *
25
+ * `GET /api/ai/admin/orgs-spend?orgIds=a,b,…` answers this month's provider
26
+ * spend for each org the list's page shows — the figures its AI spend column
27
+ * draws and sorts by. Staff-gated exactly as `/api/ai/admin/org` is, and
28
+ * read-only.
29
+ *
30
+ * ## The read
31
+ *
32
+ * ONE `getAll` over each named org's usage document for the current UTC
33
+ * month, the key the usage writer files spend under — a single bounded
34
+ * round trip for the page, never a read per row, and at most
35
+ * `STAFF_ORGS_AI_SPEND_MAX_IDS` ids per request.
36
+ *
37
+ * An org with no document for the month answers `null`, never `0`, and a
38
+ * read that FAILS answers `null` for every id: the list renders with the
39
+ * column blank rather than failing because this read did.
40
+ *
41
+ * No `adminAudit` row: the answer is one dollar figure per workspace, with
42
+ * nothing in it about a person.
43
+ */ async function handler(request) {
44
+ var _headers_authorization;
45
+ const { method, query, headers: rawHeaders } = await pluginRequestFromWeb(request);
46
+ const headers = rawHeaders;
47
+ if (method !== 'GET') {
48
+ return Response.json({
49
+ error: 'Method not allowed'
50
+ }, {
51
+ status: 405
52
+ });
53
+ }
54
+ const authorization = (_headers_authorization = headers.authorization) != null ? _headers_authorization : '';
55
+ const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
56
+ if (!idToken) return Response.json({
57
+ error: 'Unauthenticated'
58
+ }, {
59
+ status: 401
60
+ });
61
+ const asked = parseStaffOrgIds(query['orgIds']);
62
+ if (asked.error) {
63
+ return Response.json({
64
+ error: asked.error
65
+ }, {
66
+ status: 400
67
+ });
68
+ }
69
+ try {
70
+ const app = firebaseAdmin.app();
71
+ const decoded = await app.auth().verifyIdToken(idToken);
72
+ if (!decoded.email_verified && !isImpersonationSession(decoded)) {
73
+ return emailUnverifiedResponse();
74
+ }
75
+ if (!decoded['staff']) {
76
+ return Response.json({
77
+ error: 'Staff only'
78
+ }, {
79
+ status: 403
80
+ });
81
+ }
82
+ const month = assistUsageMonth();
83
+ const db = app.firestore();
84
+ const orgs = db.collection('orgs');
85
+ const snapshots = await db.getAll(...asked.orgIds.map((orgId)=>orgs.doc(orgId).collection('assistUsage').doc(month))).catch((error)=>{
86
+ console.error('[ai/admin/orgs-spend] read failed', error);
87
+ return null;
88
+ });
89
+ const body = {
90
+ month,
91
+ // `fromEntries`, so an id is always an own key of the answer.
92
+ spendUsd: Object.fromEntries(asked.orgIds.map((orgId, index)=>[
93
+ orgId,
94
+ spendOf(snapshots == null ? void 0 : snapshots[index])
95
+ ]))
96
+ };
97
+ return Response.json(body, {
98
+ status: 200
99
+ });
100
+ } catch (error) {
101
+ // An unverifiable credential is a 401, not a fault of ours
102
+ // (AGL-1993). Null for anything else, so a real failure keeps its 500.
103
+ const unauthenticated = invalidIdTokenResponse(error);
104
+ if (unauthenticated) return unauthenticated;
105
+ console.error('[ai/admin/orgs-spend]', error);
106
+ return Response.json({
107
+ error: 'AI spend lookup failed'
108
+ }, {
109
+ status: 500
110
+ });
111
+ }
112
+ }
113
+ /**
114
+ * A month document's PROVIDER spend, or `null` when there is no document to
115
+ * read.
116
+ *
117
+ * The column this feeds is named for our money and is sorted on to find the
118
+ * workspace spending it, so it is the provider figure and not what the
119
+ * workspace drew (AGL-3015). A month closed before the two were split
120
+ * answers with what it drew, which over-states the bill rather than hiding
121
+ * it — the direction that still surfaces the workspace worth looking at.
122
+ */ function spendOf(snapshot) {
123
+ if (!(snapshot == null ? void 0 : snapshot.exists)) return null;
124
+ const cost = assistProviderCostUsd(snapshot.get('estCostUsd'), snapshot.get(ASSIST_PROVIDER_COST_FIELD));
125
+ return Number.isFinite(cost) ? cost : null;
126
+ }
127
+ export { handler as GET };
128
+
129
+ //# sourceMappingURL=ai-admin-orgs-spend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/server/ai-admin-orgs-spend.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { pluginRequestFromWeb } from '@aglyn/aglyn/server'\nimport {\n emailUnverifiedResponse,\n firebaseAdmin,\n isImpersonationSession,\n} from '@aglyn/tenant-data-admin'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport {\n ASSIST_PROVIDER_COST_FIELD,\n assistProviderCostUsd,\n} from '@aglyn/aglyn/app-utils/assist-credits'\nimport { assistUsageMonth } from '../usage/assist-usage'\nimport {\n parseStaffOrgIds,\n type StaffOrgsAiSpendWire,\n} from '../usage/staff-orgs-ai-spend'\n\n/**\n * THE STAFF ORGANIZATIONS LIST'S AI SPEND (AGL-2984).\n *\n * `GET /api/ai/admin/orgs-spend?orgIds=a,b,…` answers this month's provider\n * spend for each org the list's page shows — the figures its AI spend column\n * draws and sorts by. Staff-gated exactly as `/api/ai/admin/org` is, and\n * read-only.\n *\n * ## The read\n *\n * ONE `getAll` over each named org's usage document for the current UTC\n * month, the key the usage writer files spend under — a single bounded\n * round trip for the page, never a read per row, and at most\n * `STAFF_ORGS_AI_SPEND_MAX_IDS` ids per request.\n *\n * An org with no document for the month answers `null`, never `0`, and a\n * read that FAILS answers `null` for every id: the list renders with the\n * column blank rather than failing because this read did.\n *\n * No `adminAudit` row: the answer is one dollar figure per workspace, with\n * nothing in it about a person.\n */\nasync function handler(request: Request): Promise<Response> {\n const {\n method,\n query,\n headers: rawHeaders,\n } = await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n if (method !== 'GET') {\n return Response.json({ error: 'Method not allowed' }, { status: 405 })\n }\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ')\n ? authorization.slice('Bearer '.length)\n : undefined\n if (!idToken)\n return Response.json({ error: 'Unauthenticated' }, { status: 401 })\n const asked = parseStaffOrgIds(query['orgIds'])\n if (asked.error) {\n return Response.json({ error: asked.error }, { status: 400 })\n }\n\n try {\n const app = firebaseAdmin.app()\n const decoded = await app.auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) {\n return emailUnverifiedResponse()\n }\n if (!decoded['staff']) {\n return Response.json({ error: 'Staff only' }, { status: 403 })\n }\n\n const month = assistUsageMonth()\n const db = app.firestore()\n const orgs = db.collection('orgs')\n const snapshots = await db\n .getAll(\n ...asked.orgIds.map((orgId) =>\n orgs.doc(orgId).collection('assistUsage').doc(month),\n ),\n )\n .catch((error: unknown) => {\n console.error('[ai/admin/orgs-spend] read failed', error)\n return null\n })\n const body: StaffOrgsAiSpendWire = {\n month,\n // `fromEntries`, so an id is always an own key of the answer.\n spendUsd: Object.fromEntries(\n asked.orgIds.map((orgId, index) => [\n orgId,\n spendOf(snapshots?.[index]),\n ]),\n ),\n }\n return Response.json(body, { status: 200 })\n } catch (error) {\n // An unverifiable credential is a 401, not a fault of ours\n // (AGL-1993). Null for anything else, so a real failure keeps its 500.\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error('[ai/admin/orgs-spend]', error)\n return Response.json({ error: 'AI spend lookup failed' }, { status: 500 })\n }\n}\n\n/**\n * A month document's PROVIDER spend, or `null` when there is no document to\n * read.\n *\n * The column this feeds is named for our money and is sorted on to find the\n * workspace spending it, so it is the provider figure and not what the\n * workspace drew (AGL-3015). A month closed before the two were split\n * answers with what it drew, which over-states the bill rather than hiding\n * it — the direction that still surfaces the workspace worth looking at.\n */\nfunction spendOf(\n snapshot: FirebaseFirestore.DocumentSnapshot | undefined,\n): number | null {\n if (!snapshot?.exists) return null\n const cost = assistProviderCostUsd(\n snapshot.get('estCostUsd'),\n snapshot.get(ASSIST_PROVIDER_COST_FIELD),\n )\n return Number.isFinite(cost) ? cost : null\n}\n\nexport { handler as GET }\n"],"names":["pluginRequestFromWeb","emailUnverifiedResponse","firebaseAdmin","isImpersonationSession","invalidIdTokenResponse","ASSIST_PROVIDER_COST_FIELD","assistProviderCostUsd","assistUsageMonth","parseStaffOrgIds","handler","request","headers","method","query","rawHeaders","Response","json","error","status","authorization","idToken","startsWith","slice","length","undefined","asked","app","decoded","auth","verifyIdToken","email_verified","month","db","firestore","orgs","collection","snapshots","getAll","orgIds","map","orgId","doc","catch","console","body","spendUsd","Object","fromEntries","index","spendOf","unauthenticated","snapshot","exists","cost","get","Number","isFinite","GET"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ declare function handler(request: Request): Promise<Response>;
18
+ export declare const dynamic = "force-dynamic";
19
+ export { handler as POST };