@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.
- package/LICENSE +201 -0
- package/README.md +25 -0
- package/package.json +60 -0
- package/src/index.d.ts +21 -0
- package/src/index.js +22 -0
- package/src/index.js.map +1 -0
- package/src/lib/activity/ai-activity-actions.d.ts +106 -0
- package/src/lib/activity/ai-activity-actions.js +209 -0
- package/src/lib/activity/ai-activity-actions.js.map +1 -0
- package/src/lib/activity/ai-activity.d.ts +219 -0
- package/src/lib/activity/ai-activity.js +251 -0
- package/src/lib/activity/ai-activity.js.map +1 -0
- package/src/lib/billing/ai-overage-charge.d.ts +102 -0
- package/src/lib/billing/ai-overage-charge.js +258 -0
- package/src/lib/billing/ai-overage-charge.js.map +1 -0
- package/src/lib/billing/ai-overage-close.d.ts +62 -0
- package/src/lib/billing/ai-overage-close.js +129 -0
- package/src/lib/billing/ai-overage-close.js.map +1 -0
- package/src/lib/billing/ai-overage-cutover.d.ts +63 -0
- package/src/lib/billing/ai-overage-cutover.js +114 -0
- package/src/lib/billing/ai-overage-cutover.js.map +1 -0
- package/src/lib/billing/ai-overage-events.d.ts +77 -0
- package/src/lib/billing/ai-overage-events.js +174 -0
- package/src/lib/billing/ai-overage-events.js.map +1 -0
- package/src/lib/billing/ai-overage-gate.d.ts +147 -0
- package/src/lib/billing/ai-overage-gate.js +177 -0
- package/src/lib/billing/ai-overage-gate.js.map +1 -0
- package/src/lib/billing/ai-overage-ledger.d.ts +135 -0
- package/src/lib/billing/ai-overage-ledger.js +278 -0
- package/src/lib/billing/ai-overage-ledger.js.map +1 -0
- package/src/lib/billing/ai-overage-standing-writes.d.ts +110 -0
- package/src/lib/billing/ai-overage-standing-writes.js +205 -0
- package/src/lib/billing/ai-overage-standing-writes.js.map +1 -0
- package/src/lib/billing/ai-overage-standing.d.ts +168 -0
- package/src/lib/billing/ai-overage-standing.js +215 -0
- package/src/lib/billing/ai-overage-standing.js.map +1 -0
- package/src/lib/billing/ai-overage-trigger.d.ts +30 -0
- package/src/lib/billing/ai-overage-trigger.js +76 -0
- package/src/lib/billing/ai-overage-trigger.js.map +1 -0
- package/src/lib/components/ai-allotment-editor.component.d.ts +40 -0
- package/src/lib/components/ai-allotment-editor.component.js +213 -0
- package/src/lib/components/ai-allotment-editor.component.js.map +1 -0
- package/src/lib/components/ai-assist-actions-context.d.ts +13 -0
- package/src/lib/components/ai-assist-actions-context.js +21 -0
- package/src/lib/components/ai-assist-actions-context.js.map +1 -0
- package/src/lib/components/ai-assist-provider.component.d.ts +51 -0
- package/src/lib/components/ai-assist-provider.component.js +519 -0
- package/src/lib/components/ai-assist-provider.component.js.map +1 -0
- package/src/lib/components/ai-brief-dialog.component.d.ts +56 -0
- package/src/lib/components/ai-brief-dialog.component.js +319 -0
- package/src/lib/components/ai-brief-dialog.component.js.map +1 -0
- package/src/lib/components/ai-collaborator-permissions-column.component.d.ts +32 -0
- package/src/lib/components/ai-collaborator-permissions-column.component.js +132 -0
- package/src/lib/components/ai-collaborator-permissions-column.component.js.map +1 -0
- package/src/lib/components/ai-credits-card.component.d.ts +34 -0
- package/src/lib/components/ai-credits-card.component.js +131 -0
- package/src/lib/components/ai-credits-card.component.js.map +1 -0
- package/src/lib/components/ai-credits-columns.component.d.ts +56 -0
- package/src/lib/components/ai-credits-columns.component.js +118 -0
- package/src/lib/components/ai-credits-columns.component.js.map +1 -0
- package/src/lib/components/ai-crm-email-draft.component.d.ts +17 -0
- package/src/lib/components/ai-crm-email-draft.component.js +159 -0
- package/src/lib/components/ai-crm-email-draft.component.js.map +1 -0
- package/src/lib/components/ai-crm-import-mapping.component.d.ts +20 -0
- package/src/lib/components/ai-crm-import-mapping.component.js +167 -0
- package/src/lib/components/ai-crm-import-mapping.component.js.map +1 -0
- package/src/lib/components/ai-crm-record-card.component.d.ts +27 -0
- package/src/lib/components/ai-crm-record-card.component.js +263 -0
- package/src/lib/components/ai-crm-record-card.component.js.map +1 -0
- package/src/lib/components/ai-describe-automation.component.d.ts +31 -0
- package/src/lib/components/ai-describe-automation.component.js +226 -0
- package/src/lib/components/ai-describe-automation.component.js.map +1 -0
- package/src/lib/components/ai-describe-button.component.d.ts +39 -0
- package/src/lib/components/ai-describe-button.component.js +87 -0
- package/src/lib/components/ai-describe-button.component.js.map +1 -0
- package/src/lib/components/ai-describe-page.component.d.ts +26 -0
- package/src/lib/components/ai-describe-page.component.js +18 -0
- package/src/lib/components/ai-describe-page.component.js.map +1 -0
- package/src/lib/components/ai-experiment-cards.component.d.ts +75 -0
- package/src/lib/components/ai-experiment-cards.component.js +573 -0
- package/src/lib/components/ai-experiment-cards.component.js.map +1 -0
- package/src/lib/components/ai-explain-automation.component.d.ts +31 -0
- package/src/lib/components/ai-explain-automation.component.js +265 -0
- package/src/lib/components/ai-explain-automation.component.js.map +1 -0
- package/src/lib/components/ai-insight-dialog.component.d.ts +37 -0
- package/src/lib/components/ai-insight-dialog.component.js +441 -0
- package/src/lib/components/ai-insight-dialog.component.js.map +1 -0
- package/src/lib/components/ai-job-plan.component.d.ts +46 -0
- package/src/lib/components/ai-job-plan.component.js +192 -0
- package/src/lib/components/ai-job-plan.component.js.map +1 -0
- package/src/lib/components/ai-model-selector.component.d.ts +21 -0
- package/src/lib/components/ai-model-selector.component.js +109 -0
- package/src/lib/components/ai-model-selector.component.js.map +1 -0
- package/src/lib/components/ai-page-brief-dialog.component.d.ts +29 -0
- package/src/lib/components/ai-page-brief-dialog.component.js +27 -0
- package/src/lib/components/ai-page-brief-dialog.component.js.map +1 -0
- package/src/lib/components/ai-permissions-on-host.component.d.ts +55 -0
- package/src/lib/components/ai-permissions-on-host.component.js +91 -0
- package/src/lib/components/ai-permissions-on-host.component.js.map +1 -0
- package/src/lib/components/ai-product-copy-card.component.d.ts +25 -0
- package/src/lib/components/ai-product-copy-card.component.js +328 -0
- package/src/lib/components/ai-product-copy-card.component.js.map +1 -0
- package/src/lib/components/ai-product-import-option.component.d.ts +14 -0
- package/src/lib/components/ai-product-import-option.component.js +58 -0
- package/src/lib/components/ai-product-import-option.component.js.map +1 -0
- package/src/lib/components/ai-products-hub-card.component.d.ts +15 -0
- package/src/lib/components/ai-products-hub-card.component.js +418 -0
- package/src/lib/components/ai-products-hub-card.component.js.map +1 -0
- package/src/lib/components/ai-products-proposals.component.d.ts +19 -0
- package/src/lib/components/ai-products-proposals.component.js +547 -0
- package/src/lib/components/ai-products-proposals.component.js.map +1 -0
- package/src/lib/components/ai-save-as-component.component.d.ts +38 -0
- package/src/lib/components/ai-save-as-component.component.js +231 -0
- package/src/lib/components/ai-save-as-component.component.js.map +1 -0
- package/src/lib/components/ai-seo-audit-card.component.d.ts +9 -0
- package/src/lib/components/ai-seo-audit-card.component.js +620 -0
- package/src/lib/components/ai-seo-audit-card.component.js.map +1 -0
- package/src/lib/components/ai-seo-fields-card.component.d.ts +10 -0
- package/src/lib/components/ai-seo-fields-card.component.js +453 -0
- package/src/lib/components/ai-seo-fields-card.component.js.map +1 -0
- package/src/lib/components/ai-site-batch-card.component.d.ts +32 -0
- package/src/lib/components/ai-site-batch-card.component.js +531 -0
- package/src/lib/components/ai-site-batch-card.component.js.map +1 -0
- package/src/lib/components/ai-site-seo-start-card.component.d.ts +26 -0
- package/src/lib/components/ai-site-seo-start-card.component.js +178 -0
- package/src/lib/components/ai-site-seo-start-card.component.js.map +1 -0
- package/src/lib/components/ai-site-start-card.component.d.ts +19 -0
- package/src/lib/components/ai-site-start-card.component.js +348 -0
- package/src/lib/components/ai-site-start-card.component.js.map +1 -0
- package/src/lib/components/ai-template-collection-field.component.d.ts +32 -0
- package/src/lib/components/ai-template-collection-field.component.js +63 -0
- package/src/lib/components/ai-template-collection-field.component.js.map +1 -0
- package/src/lib/components/ai-theme-proposal-card.component.d.ts +6 -0
- package/src/lib/components/ai-theme-proposal-card.component.js +619 -0
- package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -0
- package/src/lib/components/ai-usage-strip.component.d.ts +27 -0
- package/src/lib/components/ai-usage-strip.component.js +145 -0
- package/src/lib/components/ai-usage-strip.component.js.map +1 -0
- package/src/lib/components/assist-edit-canvas.d.ts +169 -0
- package/src/lib/components/assist-edit-canvas.js +636 -0
- package/src/lib/components/assist-edit-canvas.js.map +1 -0
- package/src/lib/components/assist-edit-card.component.d.ts +16 -0
- package/src/lib/components/assist-edit-card.component.js +181 -0
- package/src/lib/components/assist-edit-card.component.js.map +1 -0
- package/src/lib/components/assist-jobs-drawer.component.d.ts +72 -0
- package/src/lib/components/assist-jobs-drawer.component.js +626 -0
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -0
- package/src/lib/components/assist-panel.component.d.ts +136 -0
- package/src/lib/components/assist-panel.component.js +1099 -0
- package/src/lib/components/assist-panel.component.js.map +1 -0
- package/src/lib/components/assist-signals-page.component.d.ts +3 -0
- package/src/lib/components/assist-signals-page.component.js +1017 -0
- package/src/lib/components/assist-signals-page.component.js.map +1 -0
- package/src/lib/components/besigner-ai-controls.component.d.ts +29 -0
- package/src/lib/components/besigner-ai-controls.component.js +81 -0
- package/src/lib/components/besigner-ai-controls.component.js.map +1 -0
- package/src/lib/components/billing-ai-allotments.component.d.ts +36 -0
- package/src/lib/components/billing-ai-allotments.component.js +486 -0
- package/src/lib/components/billing-ai-allotments.component.js.map +1 -0
- package/src/lib/components/billing-ai-top-users.component.d.ts +44 -0
- package/src/lib/components/billing-ai-top-users.component.js +304 -0
- package/src/lib/components/billing-ai-top-users.component.js.map +1 -0
- package/src/lib/components/billing-assist-overage-card.component.d.ts +69 -0
- package/src/lib/components/billing-assist-overage-card.component.js +437 -0
- package/src/lib/components/billing-assist-overage-card.component.js.map +1 -0
- package/src/lib/components/host-ai-allotments.component.d.ts +40 -0
- package/src/lib/components/host-ai-allotments.component.js +239 -0
- package/src/lib/components/host-ai-allotments.component.js.map +1 -0
- package/src/lib/components/member-ai-allotment-card.component.d.ts +28 -0
- package/src/lib/components/member-ai-allotment-card.component.js +172 -0
- package/src/lib/components/member-ai-allotment-card.component.js.map +1 -0
- package/src/lib/components/member-ai-usage-card.component.d.ts +28 -0
- package/src/lib/components/member-ai-usage-card.component.js +240 -0
- package/src/lib/components/member-ai-usage-card.component.js.map +1 -0
- package/src/lib/components/staff-org-ai-card.component.d.ts +17 -0
- package/src/lib/components/staff-org-ai-card.component.js +739 -0
- package/src/lib/components/staff-org-ai-card.component.js.map +1 -0
- package/src/lib/components/staff-org-usage-ai-columns.component.d.ts +41 -0
- package/src/lib/components/staff-org-usage-ai-columns.component.js +65 -0
- package/src/lib/components/staff-org-usage-ai-columns.component.js.map +1 -0
- package/src/lib/components/staff-orgs-ai-spend-column.component.d.ts +28 -0
- package/src/lib/components/staff-orgs-ai-spend-column.component.js +89 -0
- package/src/lib/components/staff-orgs-ai-spend-column.component.js.map +1 -0
- package/src/lib/components/staff-user-ai-usage-card.component.d.ts +27 -0
- package/src/lib/components/staff-user-ai-usage-card.component.js +183 -0
- package/src/lib/components/staff-user-ai-usage-card.component.js.map +1 -0
- package/src/lib/components/use-ai-allotments.d.ts +49 -0
- package/src/lib/components/use-ai-allotments.js +171 -0
- package/src/lib/components/use-ai-allotments.js.map +1 -0
- package/src/lib/components/use-ai-crm-answer.d.ts +50 -0
- package/src/lib/components/use-ai-crm-answer.js +220 -0
- package/src/lib/components/use-ai-crm-answer.js.map +1 -0
- package/src/lib/components/use-ai-job-run.d.ts +51 -0
- package/src/lib/components/use-ai-job-run.js +176 -0
- package/src/lib/components/use-ai-job-run.js.map +1 -0
- package/src/lib/components/use-ai-model-choice.d.ts +47 -0
- package/src/lib/components/use-ai-model-choice.js +150 -0
- package/src/lib/components/use-ai-model-choice.js.map +1 -0
- package/src/lib/components/use-ai-products-jobs.d.ts +36 -0
- package/src/lib/components/use-ai-products-jobs.js +190 -0
- package/src/lib/components/use-ai-products-jobs.js.map +1 -0
- package/src/lib/components/use-ai-usage-meter.d.ts +11 -0
- package/src/lib/components/use-ai-usage-meter.js +96 -0
- package/src/lib/components/use-ai-usage-meter.js.map +1 -0
- package/src/lib/components/use-org-ai-usage.d.ts +42 -0
- package/src/lib/components/use-org-ai-usage.js +181 -0
- package/src/lib/components/use-org-ai-usage.js.map +1 -0
- package/src/lib/components/use-staff-orgs-ai-spend.d.ts +18 -0
- package/src/lib/components/use-staff-orgs-ai-spend.js +127 -0
- package/src/lib/components/use-staff-orgs-ai-spend.js.map +1 -0
- package/src/lib/constants.d.ts +24 -0
- package/src/lib/constants.js +23 -0
- package/src/lib/constants.js.map +1 -0
- package/src/lib/declarations.d.ts +48 -0
- package/src/lib/declarations.js +129 -0
- package/src/lib/declarations.js.map +1 -0
- package/src/lib/declarations.server.d.ts +35 -0
- package/src/lib/declarations.server.js +138 -0
- package/src/lib/declarations.server.js.map +1 -0
- package/src/lib/insights/ai-figure-readers.d.ts +90 -0
- package/src/lib/insights/ai-figure-readers.js +863 -0
- package/src/lib/insights/ai-figure-readers.js.map +1 -0
- package/src/lib/insights/ai-insight-digest.d.ts +165 -0
- package/src/lib/insights/ai-insight-digest.js +363 -0
- package/src/lib/insights/ai-insight-digest.js.map +1 -0
- package/src/lib/insights/ai-insight-readers.d.ts +71 -0
- package/src/lib/insights/ai-insight-readers.js +141 -0
- package/src/lib/insights/ai-insight-readers.js.map +1 -0
- package/src/lib/jobs/ai-crm-access.d.ts +61 -0
- package/src/lib/jobs/ai-crm-access.js +94 -0
- package/src/lib/jobs/ai-crm-access.js.map +1 -0
- package/src/lib/jobs/ai-email-bindings.d.ts +97 -0
- package/src/lib/jobs/ai-email-bindings.js +147 -0
- package/src/lib/jobs/ai-email-bindings.js.map +1 -0
- package/src/lib/jobs/ai-job-admission.d.ts +82 -0
- package/src/lib/jobs/ai-job-admission.js +45 -0
- package/src/lib/jobs/ai-job-admission.js.map +1 -0
- package/src/lib/jobs/ai-job-budget.d.ts +167 -0
- package/src/lib/jobs/ai-job-budget.js +161 -0
- package/src/lib/jobs/ai-job-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-campaign-step.d.ts +108 -0
- package/src/lib/jobs/ai-job-campaign-step.js +340 -0
- package/src/lib/jobs/ai-job-campaign-step.js.map +1 -0
- package/src/lib/jobs/ai-job-component-checks.d.ts +74 -0
- package/src/lib/jobs/ai-job-component-checks.js +442 -0
- package/src/lib/jobs/ai-job-component-checks.js.map +1 -0
- package/src/lib/jobs/ai-job-component-step.d.ts +75 -0
- package/src/lib/jobs/ai-job-component-step.js +262 -0
- package/src/lib/jobs/ai-job-component-step.js.map +1 -0
- package/src/lib/jobs/ai-job-crm-step.d.ts +192 -0
- package/src/lib/jobs/ai-job-crm-step.js +734 -0
- package/src/lib/jobs/ai-job-crm-step.js.map +1 -0
- package/src/lib/jobs/ai-job-draft-ids.d.ts +62 -0
- package/src/lib/jobs/ai-job-draft-ids.js +132 -0
- package/src/lib/jobs/ai-job-draft-ids.js.map +1 -0
- package/src/lib/jobs/ai-job-drafts.d.ts +304 -0
- package/src/lib/jobs/ai-job-drafts.js +557 -0
- package/src/lib/jobs/ai-job-drafts.js.map +1 -0
- package/src/lib/jobs/ai-job-email-step.d.ts +195 -0
- package/src/lib/jobs/ai-job-email-step.js +547 -0
- package/src/lib/jobs/ai-job-email-step.js.map +1 -0
- package/src/lib/jobs/ai-job-experiment-step.d.ts +105 -0
- package/src/lib/jobs/ai-job-experiment-step.js +445 -0
- package/src/lib/jobs/ai-job-experiment-step.js.map +1 -0
- package/src/lib/jobs/ai-job-form-step.d.ts +250 -0
- package/src/lib/jobs/ai-job-form-step.js +634 -0
- package/src/lib/jobs/ai-job-form-step.js.map +1 -0
- package/src/lib/jobs/ai-job-generation.d.ts +114 -0
- package/src/lib/jobs/ai-job-generation.js +384 -0
- package/src/lib/jobs/ai-job-generation.js.map +1 -0
- package/src/lib/jobs/ai-job-insight-budget.d.ts +41 -0
- package/src/lib/jobs/ai-job-insight-budget.js +46 -0
- package/src/lib/jobs/ai-job-insight-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-insight-step.d.ts +58 -0
- package/src/lib/jobs/ai-job-insight-step.js +350 -0
- package/src/lib/jobs/ai-job-insight-step.js.map +1 -0
- package/src/lib/jobs/ai-job-layout-step.d.ts +103 -0
- package/src/lib/jobs/ai-job-layout-step.js +340 -0
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -0
- package/src/lib/jobs/ai-job-page-budget.d.ts +57 -0
- package/src/lib/jobs/ai-job-page-budget.js +60 -0
- package/src/lib/jobs/ai-job-page-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-page-sections.d.ts +150 -0
- package/src/lib/jobs/ai-job-page-sections.js +450 -0
- package/src/lib/jobs/ai-job-page-sections.js.map +1 -0
- package/src/lib/jobs/ai-job-page-step.d.ts +198 -0
- package/src/lib/jobs/ai-job-page-step.js +667 -0
- package/src/lib/jobs/ai-job-page-step.js.map +1 -0
- package/src/lib/jobs/ai-job-plan-conformance.d.ts +107 -0
- package/src/lib/jobs/ai-job-plan-conformance.js +164 -0
- package/src/lib/jobs/ai-job-plan-conformance.js.map +1 -0
- package/src/lib/jobs/ai-job-plan-step.d.ts +196 -0
- package/src/lib/jobs/ai-job-plan-step.js +458 -0
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -0
- package/src/lib/jobs/ai-job-plugin-drafts.d.ts +76 -0
- package/src/lib/jobs/ai-job-plugin-drafts.js +91 -0
- package/src/lib/jobs/ai-job-plugin-drafts.js.map +1 -0
- package/src/lib/jobs/ai-job-products-step.d.ts +106 -0
- package/src/lib/jobs/ai-job-products-step.js +436 -0
- package/src/lib/jobs/ai-job-products-step.js.map +1 -0
- package/src/lib/jobs/ai-job-seo-budget.d.ts +52 -0
- package/src/lib/jobs/ai-job-seo-budget.js +63 -0
- package/src/lib/jobs/ai-job-seo-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-seo-step.d.ts +145 -0
- package/src/lib/jobs/ai-job-seo-step.js +809 -0
- package/src/lib/jobs/ai-job-seo-step.js.map +1 -0
- package/src/lib/jobs/ai-job-site-step.d.ts +252 -0
- package/src/lib/jobs/ai-job-site-step.js +538 -0
- package/src/lib/jobs/ai-job-site-step.js.map +1 -0
- package/src/lib/jobs/ai-job-template-step.d.ts +105 -0
- package/src/lib/jobs/ai-job-template-step.js +391 -0
- package/src/lib/jobs/ai-job-template-step.js.map +1 -0
- package/src/lib/jobs/ai-job-text-step.d.ts +125 -0
- package/src/lib/jobs/ai-job-text-step.js +128 -0
- package/src/lib/jobs/ai-job-text-step.js.map +1 -0
- package/src/lib/jobs/ai-job-theme-budget.d.ts +38 -0
- package/src/lib/jobs/ai-job-theme-budget.js +43 -0
- package/src/lib/jobs/ai-job-theme-budget.js.map +1 -0
- package/src/lib/jobs/ai-job-theme-step.d.ts +115 -0
- package/src/lib/jobs/ai-job-theme-step.js +337 -0
- package/src/lib/jobs/ai-job-theme-step.js.map +1 -0
- package/src/lib/jobs/ai-job-workflow-step.d.ts +139 -0
- package/src/lib/jobs/ai-job-workflow-step.js +530 -0
- package/src/lib/jobs/ai-job-workflow-step.js.map +1 -0
- package/src/lib/jobs/ai-jobs-beat.d.ts +78 -0
- package/src/lib/jobs/ai-jobs-beat.js +93 -0
- package/src/lib/jobs/ai-jobs-beat.js.map +1 -0
- package/src/lib/jobs/ai-jobs-pause.d.ts +38 -0
- package/src/lib/jobs/ai-jobs-pause.js +45 -0
- package/src/lib/jobs/ai-jobs-pause.js.map +1 -0
- package/src/lib/jobs/ai-jobs.d.ts +558 -0
- package/src/lib/jobs/ai-jobs.js +1410 -0
- package/src/lib/jobs/ai-jobs.js.map +1 -0
- package/src/lib/jobs/ai-media-asset-server.d.ts +34 -0
- package/src/lib/jobs/ai-media-asset-server.js +34 -0
- package/src/lib/jobs/ai-media-asset-server.js.map +1 -0
- package/src/lib/jobs/ai-media-asset.d.ts +59 -0
- package/src/lib/jobs/ai-media-asset.js +86 -0
- package/src/lib/jobs/ai-media-asset.js.map +1 -0
- package/src/lib/jobs/ai-product-image.d.ts +78 -0
- package/src/lib/jobs/ai-product-image.js +113 -0
- package/src/lib/jobs/ai-product-image.js.map +1 -0
- package/src/lib/jobs/ai-theme-brand-inputs.d.ts +125 -0
- package/src/lib/jobs/ai-theme-brand-inputs.js +378 -0
- package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -0
- package/src/lib/jobs/ai-theme-brand-server.d.ts +33 -0
- package/src/lib/jobs/ai-theme-brand-server.js +33 -0
- package/src/lib/jobs/ai-theme-brand-server.js.map +1 -0
- package/src/lib/jobs/ai-workflow-records.d.ts +84 -0
- package/src/lib/jobs/ai-workflow-records.js +158 -0
- package/src/lib/jobs/ai-workflow-records.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-free-page-built-recording.d.ts +31 -0
- package/src/lib/jobs/fixtures/ai-free-page-built-recording.js +367 -0
- package/src/lib/jobs/fixtures/ai-free-page-built-recording.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-free-page-recording.d.ts +69 -0
- package/src/lib/jobs/fixtures/ai-free-page-recording.js +442 -0
- package/src/lib/jobs/fixtures/ai-free-page-recording.js.map +1 -0
- package/src/lib/jobs/fixtures/ai-page-briefs.d.ts +146 -0
- package/src/lib/jobs/fixtures/ai-page-briefs.js +1850 -0
- package/src/lib/jobs/fixtures/ai-page-briefs.js.map +1 -0
- package/src/lib/model/ai-allotments.d.ts +208 -0
- package/src/lib/model/ai-allotments.js +269 -0
- package/src/lib/model/ai-allotments.js.map +1 -0
- package/src/lib/model/ai-automation-draft.d.ts +74 -0
- package/src/lib/model/ai-automation-draft.js +310 -0
- package/src/lib/model/ai-automation-draft.js.map +1 -0
- package/src/lib/model/ai-automation-outline.d.ts +50 -0
- package/src/lib/model/ai-automation-outline.js +262 -0
- package/src/lib/model/ai-automation-outline.js.map +1 -0
- package/src/lib/model/ai-build-plan.d.ts +197 -0
- package/src/lib/model/ai-build-plan.js +438 -0
- package/src/lib/model/ai-build-plan.js.map +1 -0
- package/src/lib/model/ai-crm.d.ts +237 -0
- package/src/lib/model/ai-crm.js +225 -0
- package/src/lib/model/ai-crm.js.map +1 -0
- package/src/lib/model/ai-experiment-proposal.d.ts +68 -0
- package/src/lib/model/ai-experiment-proposal.js +146 -0
- package/src/lib/model/ai-experiment-proposal.js.map +1 -0
- package/src/lib/model/ai-experiment.d.ts +309 -0
- package/src/lib/model/ai-experiment.js +395 -0
- package/src/lib/model/ai-experiment.js.map +1 -0
- package/src/lib/model/ai-insight.d.ts +178 -0
- package/src/lib/model/ai-insight.js +201 -0
- package/src/lib/model/ai-insight.js.map +1 -0
- package/src/lib/model/ai-jobs.types.d.ts +412 -0
- package/src/lib/model/ai-jobs.types.js +42 -0
- package/src/lib/model/ai-jobs.types.js.map +1 -0
- package/src/lib/model/ai-page-job.d.ts +92 -0
- package/src/lib/model/ai-page-job.js +159 -0
- package/src/lib/model/ai-page-job.js.map +1 -0
- package/src/lib/model/ai-permissions.d.ts +49 -0
- package/src/lib/model/ai-permissions.js +97 -0
- package/src/lib/model/ai-permissions.js.map +1 -0
- package/src/lib/model/ai-plan-capabilities.d.ts +139 -0
- package/src/lib/model/ai-plan-capabilities.js +149 -0
- package/src/lib/model/ai-plan-capabilities.js.map +1 -0
- package/src/lib/model/ai-products.d.ts +251 -0
- package/src/lib/model/ai-products.js +253 -0
- package/src/lib/model/ai-products.js.map +1 -0
- package/src/lib/model/ai-seo.d.ts +208 -0
- package/src/lib/model/ai-seo.js +150 -0
- package/src/lib/model/ai-seo.js.map +1 -0
- package/src/lib/model/ai-site-inventory.d.ts +164 -0
- package/src/lib/model/ai-site-inventory.js +145 -0
- package/src/lib/model/ai-site-inventory.js.map +1 -0
- package/src/lib/model/ai-site-job.d.ts +247 -0
- package/src/lib/model/ai-site-job.js +314 -0
- package/src/lib/model/ai-site-job.js.map +1 -0
- package/src/lib/model/ai-site-start-seo.d.ts +103 -0
- package/src/lib/model/ai-site-start-seo.js +154 -0
- package/src/lib/model/ai-site-start-seo.js.map +1 -0
- package/src/lib/model/ai-site-start.d.ts +122 -0
- package/src/lib/model/ai-site-start.js +159 -0
- package/src/lib/model/ai-site-start.js.map +1 -0
- package/src/lib/model/ai-site-switch.d.ts +56 -0
- package/src/lib/model/ai-site-switch.js +73 -0
- package/src/lib/model/ai-site-switch.js.map +1 -0
- package/src/lib/model/ai-storefront-claims.d.ts +70 -0
- package/src/lib/model/ai-storefront-claims.js +130 -0
- package/src/lib/model/ai-storefront-claims.js.map +1 -0
- package/src/lib/model/ai-template-subjects.d.ts +82 -0
- package/src/lib/model/ai-template-subjects.js +136 -0
- package/src/lib/model/ai-template-subjects.js.map +1 -0
- package/src/lib/model/ai-theme-proposal.d.ts +210 -0
- package/src/lib/model/ai-theme-proposal.js +506 -0
- package/src/lib/model/ai-theme-proposal.js.map +1 -0
- package/src/lib/model/ai-tokens.d.ts +96 -0
- package/src/lib/model/ai-tokens.js +117 -0
- package/src/lib/model/ai-tokens.js.map +1 -0
- package/src/lib/model/ai-usage-by-user.d.ts +120 -0
- package/src/lib/model/ai-usage-by-user.js +139 -0
- package/src/lib/model/ai-usage-by-user.js.map +1 -0
- package/src/lib/model/ai-workflow-job.d.ts +111 -0
- package/src/lib/model/ai-workflow-job.js +183 -0
- package/src/lib/model/ai-workflow-job.js.map +1 -0
- package/src/lib/model/assist-edit.d.ts +261 -0
- package/src/lib/model/assist-edit.js +175 -0
- package/src/lib/model/assist-edit.js.map +1 -0
- package/src/lib/plugin-config.d.ts +33 -0
- package/src/lib/plugin-config.js +118 -0
- package/src/lib/plugin-config.js.map +1 -0
- package/src/lib/plugin.d.ts +30 -0
- package/src/lib/plugin.js +525 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/providers/anthropic.d.ts +84 -0
- package/src/lib/providers/anthropic.js +432 -0
- package/src/lib/providers/anthropic.js.map +1 -0
- package/src/lib/providers/catalog.d.ts +197 -0
- package/src/lib/providers/catalog.js +312 -0
- package/src/lib/providers/catalog.js.map +1 -0
- package/src/lib/providers/contract.d.ts +464 -0
- package/src/lib/providers/contract.js +274 -0
- package/src/lib/providers/contract.js.map +1 -0
- package/src/lib/providers/model-choice.d.ts +119 -0
- package/src/lib/providers/model-choice.js +416 -0
- package/src/lib/providers/model-choice.js.map +1 -0
- package/src/lib/providers/openai-compatible.d.ts +58 -0
- package/src/lib/providers/openai-compatible.js +361 -0
- package/src/lib/providers/openai-compatible.js.map +1 -0
- package/src/lib/providers/registry.d.ts +49 -0
- package/src/lib/providers/registry.js +71 -0
- package/src/lib/providers/registry.js.map +1 -0
- package/src/lib/providers/routing.d.ts +98 -0
- package/src/lib/providers/routing.js +450 -0
- package/src/lib/providers/routing.js.map +1 -0
- package/src/lib/runtime/ai-abuse-guards.d.ts +113 -0
- package/src/lib/runtime/ai-abuse-guards.js +148 -0
- package/src/lib/runtime/ai-abuse-guards.js.map +1 -0
- package/src/lib/runtime/ai-component-bindings.d.ts +67 -0
- package/src/lib/runtime/ai-component-bindings.js +106 -0
- package/src/lib/runtime/ai-component-bindings.js.map +1 -0
- package/src/lib/runtime/ai-device-audit.d.ts +109 -0
- package/src/lib/runtime/ai-device-audit.js +97 -0
- package/src/lib/runtime/ai-device-audit.js.map +1 -0
- package/src/lib/runtime/ai-doctrine-validators.d.ts +720 -0
- package/src/lib/runtime/ai-doctrine-validators.js +3133 -0
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -0
- package/src/lib/runtime/ai-doctrine.d.ts +372 -0
- package/src/lib/runtime/ai-doctrine.js +944 -0
- package/src/lib/runtime/ai-doctrine.js.map +1 -0
- package/src/lib/runtime/ai-eval-live.d.ts +321 -0
- package/src/lib/runtime/ai-eval-live.js +1257 -0
- package/src/lib/runtime/ai-eval-live.js.map +1 -0
- package/src/lib/runtime/ai-eval-memory-firestore.d.ts +51 -0
- package/src/lib/runtime/ai-eval-memory-firestore.js +183 -0
- package/src/lib/runtime/ai-eval-memory-firestore.js.map +1 -0
- package/src/lib/runtime/ai-eval.d.ts +441 -0
- package/src/lib/runtime/ai-eval.js +1151 -0
- package/src/lib/runtime/ai-eval.js.map +1 -0
- package/src/lib/runtime/ai-gate.d.ts +130 -0
- package/src/lib/runtime/ai-gate.js +272 -0
- package/src/lib/runtime/ai-gate.js.map +1 -0
- package/src/lib/runtime/ai-generation-bounds.d.ts +24 -0
- package/src/lib/runtime/ai-generation-bounds.js +23 -0
- package/src/lib/runtime/ai-generation-bounds.js.map +1 -0
- package/src/lib/runtime/ai-insight-check.d.ts +76 -0
- package/src/lib/runtime/ai-insight-check.js +281 -0
- package/src/lib/runtime/ai-insight-check.js.map +1 -0
- package/src/lib/runtime/ai-node-tree.d.ts +181 -0
- package/src/lib/runtime/ai-node-tree.js +931 -0
- package/src/lib/runtime/ai-node-tree.js.map +1 -0
- package/src/lib/runtime/ai-page-links.d.ts +79 -0
- package/src/lib/runtime/ai-page-links.js +135 -0
- package/src/lib/runtime/ai-page-links.js.map +1 -0
- package/src/lib/runtime/ai-palette.d.ts +252 -0
- package/src/lib/runtime/ai-palette.generated.d.ts +34 -0
- package/src/lib/runtime/ai-palette.generated.js +5263 -0
- package/src/lib/runtime/ai-palette.generated.js.map +1 -0
- package/src/lib/runtime/ai-palette.js +187 -0
- package/src/lib/runtime/ai-palette.js.map +1 -0
- package/src/lib/runtime/ai-products-generation.d.ts +107 -0
- package/src/lib/runtime/ai-products-generation.js +250 -0
- package/src/lib/runtime/ai-products-generation.js.map +1 -0
- package/src/lib/runtime/ai-repeated-items.d.ts +95 -0
- package/src/lib/runtime/ai-repeated-items.js +397 -0
- package/src/lib/runtime/ai-repeated-items.js.map +1 -0
- package/src/lib/runtime/ai-runtime.d.ts +148 -0
- package/src/lib/runtime/ai-runtime.js +237 -0
- package/src/lib/runtime/ai-runtime.js.map +1 -0
- package/src/lib/runtime/ai-template-examples.d.ts +71 -0
- package/src/lib/runtime/ai-template-examples.js +135 -0
- package/src/lib/runtime/ai-template-examples.js.map +1 -0
- package/src/lib/runtime/assist-answer-cache.d.ts +80 -0
- package/src/lib/runtime/assist-answer-cache.js +184 -0
- package/src/lib/runtime/assist-answer-cache.js.map +1 -0
- package/src/lib/runtime/seo-audit.d.ts +93 -0
- package/src/lib/runtime/seo-audit.js +260 -0
- package/src/lib/runtime/seo-audit.js.map +1 -0
- package/src/lib/runtime/seo-content-fixes.d.ts +41 -0
- package/src/lib/runtime/seo-content-fixes.js +168 -0
- package/src/lib/runtime/seo-content-fixes.js.map +1 -0
- package/src/lib/runtime/seo-fields.d.ts +152 -0
- package/src/lib/runtime/seo-fields.js +215 -0
- package/src/lib/runtime/seo-fields.js.map +1 -0
- package/src/lib/runtime/seo-page-facts.d.ts +61 -0
- package/src/lib/runtime/seo-page-facts.js +150 -0
- package/src/lib/runtime/seo-page-facts.js.map +1 -0
- package/src/lib/runtime/site-inventory.d.ts +63 -0
- package/src/lib/runtime/site-inventory.js +230 -0
- package/src/lib/runtime/site-inventory.js.map +1 -0
- package/src/lib/server/ai-admin-org.d.ts +33 -0
- package/src/lib/server/ai-admin-org.js +381 -0
- package/src/lib/server/ai-admin-org.js.map +1 -0
- package/src/lib/server/ai-admin-orgs-spend.d.ts +40 -0
- package/src/lib/server/ai-admin-orgs-spend.js +129 -0
- package/src/lib/server/ai-admin-orgs-spend.js.map +1 -0
- package/src/lib/server/ai-admin-overage.d.ts +19 -0
- package/src/lib/server/ai-admin-overage.js +246 -0
- package/src/lib/server/ai-admin-overage.js.map +1 -0
- package/src/lib/server/ai-admin-signals.d.ts +34 -0
- package/src/lib/server/ai-admin-signals.js +330 -0
- package/src/lib/server/ai-admin-signals.js.map +1 -0
- package/src/lib/server/ai-admin-user.d.ts +27 -0
- package/src/lib/server/ai-admin-user.js +128 -0
- package/src/lib/server/ai-admin-user.js.map +1 -0
- package/src/lib/server/ai-allotments.d.ts +27 -0
- package/src/lib/server/ai-allotments.js +544 -0
- package/src/lib/server/ai-allotments.js.map +1 -0
- package/src/lib/server/ai-assist-prompts.d.ts +102 -0
- package/src/lib/server/ai-assist-prompts.js +207 -0
- package/src/lib/server/ai-assist-prompts.js.map +1 -0
- package/src/lib/server/ai-assist.d.ts +119 -0
- package/src/lib/server/ai-assist.js +517 -0
- package/src/lib/server/ai-assist.js.map +1 -0
- package/src/lib/server/ai-crm-answer.d.ts +30 -0
- package/src/lib/server/ai-crm-answer.js +98 -0
- package/src/lib/server/ai-crm-answer.js.map +1 -0
- package/src/lib/server/ai-generate-component.d.ts +111 -0
- package/src/lib/server/ai-generate-component.js +643 -0
- package/src/lib/server/ai-generate-component.js.map +1 -0
- package/src/lib/server/ai-host-permissions.d.ts +46 -0
- package/src/lib/server/ai-host-permissions.js +204 -0
- package/src/lib/server/ai-host-permissions.js.map +1 -0
- package/src/lib/server/ai-insight-answer.d.ts +30 -0
- package/src/lib/server/ai-insight-answer.js +83 -0
- package/src/lib/server/ai-insight-answer.js.map +1 -0
- package/src/lib/server/ai-insight-digest-route.d.ts +30 -0
- package/src/lib/server/ai-insight-digest-route.js +156 -0
- package/src/lib/server/ai-insight-digest-route.js.map +1 -0
- package/src/lib/server/ai-jobs-batch.d.ts +48 -0
- package/src/lib/server/ai-jobs-batch.js +306 -0
- package/src/lib/server/ai-jobs-batch.js.map +1 -0
- package/src/lib/server/ai-jobs-beat-route.d.ts +36 -0
- package/src/lib/server/ai-jobs-beat-route.js +86 -0
- package/src/lib/server/ai-jobs-beat-route.js.map +1 -0
- package/src/lib/server/ai-jobs-cancel.d.ts +30 -0
- package/src/lib/server/ai-jobs-cancel.js +74 -0
- package/src/lib/server/ai-jobs-cancel.js.map +1 -0
- package/src/lib/server/ai-jobs-events-route.d.ts +31 -0
- package/src/lib/server/ai-jobs-events-route.js +51 -0
- package/src/lib/server/ai-jobs-events-route.js.map +1 -0
- package/src/lib/server/ai-jobs-events.d.ts +55 -0
- package/src/lib/server/ai-jobs-events.js +144 -0
- package/src/lib/server/ai-jobs-events.js.map +1 -0
- package/src/lib/server/ai-jobs-gate.d.ts +47 -0
- package/src/lib/server/ai-jobs-gate.js +106 -0
- package/src/lib/server/ai-jobs-gate.js.map +1 -0
- package/src/lib/server/ai-jobs-resume.d.ts +23 -0
- package/src/lib/server/ai-jobs-resume.js +209 -0
- package/src/lib/server/ai-jobs-resume.js.map +1 -0
- package/src/lib/server/ai-jobs-route.d.ts +32 -0
- package/src/lib/server/ai-jobs-route.js +307 -0
- package/src/lib/server/ai-jobs-route.js.map +1 -0
- package/src/lib/server/ai-models.d.ts +18 -0
- package/src/lib/server/ai-models.js +134 -0
- package/src/lib/server/ai-models.js.map +1 -0
- package/src/lib/server/ai-seo-apply.d.ts +53 -0
- package/src/lib/server/ai-seo-apply.js +294 -0
- package/src/lib/server/ai-seo-apply.js.map +1 -0
- package/src/lib/server/ai-usage.d.ts +18 -0
- package/src/lib/server/ai-usage.js +220 -0
- package/src/lib/server/ai-usage.js.map +1 -0
- package/src/lib/server/assist-chat.d.ts +234 -0
- package/src/lib/server/assist-chat.js +1446 -0
- package/src/lib/server/assist-chat.js.map +1 -0
- package/src/lib/server/assist-edit-applied.d.ts +22 -0
- package/src/lib/server/assist-edit-applied.js +239 -0
- package/src/lib/server/assist-edit-applied.js.map +1 -0
- package/src/lib/server/assist-edit.d.ts +124 -0
- package/src/lib/server/assist-edit.js +1000 -0
- package/src/lib/server/assist-edit.js.map +1 -0
- package/src/lib/server/assist-feedback.d.ts +31 -0
- package/src/lib/server/assist-feedback.js +115 -0
- package/src/lib/server/assist-feedback.js.map +1 -0
- package/src/lib/server/assist-view-context.d.ts +343 -0
- package/src/lib/server/assist-view-context.js +690 -0
- package/src/lib/server/assist-view-context.js.map +1 -0
- package/src/lib/server/billing-credits.d.ts +59 -0
- package/src/lib/server/billing-credits.js +146 -0
- package/src/lib/server/billing-credits.js.map +1 -0
- package/src/lib/server/billing-overage.d.ts +19 -0
- package/src/lib/server/billing-overage.js +337 -0
- package/src/lib/server/billing-overage.js.map +1 -0
- package/src/lib/server.d.ts +32 -0
- package/src/lib/server.js +265 -0
- package/src/lib/server.js.map +1 -0
- package/src/lib/subprocessors.d.ts +18 -0
- package/src/lib/subprocessors.js +52 -0
- package/src/lib/subprocessors.js.map +1 -0
- package/src/lib/tools/ai-component-tool.d.ts +99 -0
- package/src/lib/tools/ai-component-tool.js +369 -0
- package/src/lib/tools/ai-component-tool.js.map +1 -0
- package/src/lib/tools/ai-crm-tool.d.ts +106 -0
- package/src/lib/tools/ai-crm-tool.js +488 -0
- package/src/lib/tools/ai-crm-tool.js.map +1 -0
- package/src/lib/tools/ai-duplicate-resource-tool.d.ts +71 -0
- package/src/lib/tools/ai-duplicate-resource-tool.js +164 -0
- package/src/lib/tools/ai-duplicate-resource-tool.js.map +1 -0
- package/src/lib/tools/ai-experiment-tool.d.ts +40 -0
- package/src/lib/tools/ai-experiment-tool.js +155 -0
- package/src/lib/tools/ai-experiment-tool.js.map +1 -0
- package/src/lib/tools/ai-insight-tool.d.ts +46 -0
- package/src/lib/tools/ai-insight-tool.js +200 -0
- package/src/lib/tools/ai-insight-tool.js.map +1 -0
- package/src/lib/tools/ai-inventory-lookup-tool.d.ts +86 -0
- package/src/lib/tools/ai-inventory-lookup-tool.js +164 -0
- package/src/lib/tools/ai-inventory-lookup-tool.js.map +1 -0
- package/src/lib/tools/ai-products-tool.d.ts +65 -0
- package/src/lib/tools/ai-products-tool.js +644 -0
- package/src/lib/tools/ai-products-tool.js.map +1 -0
- package/src/lib/tools/ai-seo-tool.d.ts +162 -0
- package/src/lib/tools/ai-seo-tool.js +546 -0
- package/src/lib/tools/ai-seo-tool.js.map +1 -0
- package/src/lib/tools/ai-theme-tool.d.ts +101 -0
- package/src/lib/tools/ai-theme-tool.js +562 -0
- package/src/lib/tools/ai-theme-tool.js.map +1 -0
- package/src/lib/tools/ai-workflow-tool.d.ts +166 -0
- package/src/lib/tools/ai-workflow-tool.js +860 -0
- package/src/lib/tools/ai-workflow-tool.js.map +1 -0
- package/src/lib/usage/ai-allotment-alerts.d.ts +72 -0
- package/src/lib/usage/ai-allotment-alerts.js +157 -0
- package/src/lib/usage/ai-allotment-alerts.js.map +1 -0
- package/src/lib/usage/ai-allotments.d.ts +125 -0
- package/src/lib/usage/ai-allotments.js +239 -0
- package/src/lib/usage/ai-allotments.js.map +1 -0
- package/src/lib/usage/ai-model-sample.d.ts +36 -0
- package/src/lib/usage/ai-model-sample.js +68 -0
- package/src/lib/usage/ai-model-sample.js.map +1 -0
- package/src/lib/usage/ai-usage-alerts.d.ts +55 -0
- package/src/lib/usage/ai-usage-alerts.js +114 -0
- package/src/lib/usage/ai-usage-alerts.js.map +1 -0
- package/src/lib/usage/ai-usage-by-user.d.ts +161 -0
- package/src/lib/usage/ai-usage-by-user.js +211 -0
- package/src/lib/usage/ai-usage-by-user.js.map +1 -0
- package/src/lib/usage/ai-usage-eraser.d.ts +29 -0
- package/src/lib/usage/ai-usage-eraser.js +40 -0
- package/src/lib/usage/ai-usage-eraser.js.map +1 -0
- package/src/lib/usage/ai-usage-meter.d.ts +39 -0
- package/src/lib/usage/ai-usage-meter.js +85 -0
- package/src/lib/usage/ai-usage-meter.js.map +1 -0
- package/src/lib/usage/ai-usage-wire.d.ts +184 -0
- package/src/lib/usage/ai-usage-wire.js +98 -0
- package/src/lib/usage/ai-usage-wire.js.map +1 -0
- package/src/lib/usage/assist-ceiling.d.ts +87 -0
- package/src/lib/usage/assist-ceiling.js +110 -0
- package/src/lib/usage/assist-ceiling.js.map +1 -0
- package/src/lib/usage/assist-free-taste.d.ts +225 -0
- package/src/lib/usage/assist-free-taste.js +308 -0
- package/src/lib/usage/assist-free-taste.js.map +1 -0
- package/src/lib/usage/assist-refusals.d.ts +69 -0
- package/src/lib/usage/assist-refusals.js +79 -0
- package/src/lib/usage/assist-refusals.js.map +1 -0
- package/src/lib/usage/assist-signal-mining.d.ts +375 -0
- package/src/lib/usage/assist-signal-mining.js +344 -0
- package/src/lib/usage/assist-signal-mining.js.map +1 -0
- package/src/lib/usage/assist-usage.d.ts +571 -0
- package/src/lib/usage/assist-usage.js +978 -0
- package/src/lib/usage/assist-usage.js.map +1 -0
- package/src/lib/usage/staff-org-ai.d.ts +242 -0
- package/src/lib/usage/staff-org-ai.js +173 -0
- package/src/lib/usage/staff-org-ai.js.map +1 -0
- package/src/lib/usage/staff-org-usage-ai.d.ts +83 -0
- package/src/lib/usage/staff-org-usage-ai.js +59 -0
- package/src/lib/usage/staff-org-usage-ai.js.map +1 -0
- package/src/lib/usage/staff-orgs-ai-spend.d.ts +83 -0
- package/src/lib/usage/staff-orgs-ai-spend.js +114 -0
- package/src/lib/usage/staff-orgs-ai-spend.js.map +1 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type AiExperimentReading, type AiExperimentTarget } from '../model/ai-experiment';
|
|
18
|
+
import { type AiSystemBlock } from '../runtime/ai-runtime';
|
|
19
|
+
import { type AiJobAdmissionContext, type AiJobAdmissionRefusal } from './ai-job-admission';
|
|
20
|
+
import type { AiJobStepRunner } from './ai-job-text-step';
|
|
21
|
+
/**
|
|
22
|
+
* The `experiment` step (AGL-2914): A/B tests by AI.
|
|
23
|
+
*
|
|
24
|
+
* A/B testing already exists — the marketing plugin models the experiment,
|
|
25
|
+
* buckets visitors, counts exposures and conversions and compares the arms.
|
|
26
|
+
* This step is the AI layer over it, and it does two things:
|
|
27
|
+
*
|
|
28
|
+
* 1. **Variants.** From the copy under test, it proposes between two and four
|
|
29
|
+
* variants of it. It proposes COPY and nothing else: no weight, no traffic
|
|
30
|
+
* split, no goal, no schedule and no winner. A person puts them into the
|
|
31
|
+
* A/B testing card, which is the only thing that creates or starts a test.
|
|
32
|
+
* 2. **The result.** Code reads the test's figures through the reader
|
|
33
|
+
* marketing registers for them, decides what they support, and only then
|
|
34
|
+
* asks the model for the words. The verdict is never the model's, and an
|
|
35
|
+
* answer that claims more than the verdict is cut back to it.
|
|
36
|
+
*
|
|
37
|
+
* ## Nothing here writes a test
|
|
38
|
+
*
|
|
39
|
+
* Both answers are proposals, like a theme's or a listing's. The experiment
|
|
40
|
+
* document, its variants' screen versions and its traffic are marketing's and
|
|
41
|
+
* the besigner's, and a job that could write them could start an experiment on
|
|
42
|
+
* live visitors without anyone deciding to.
|
|
43
|
+
*
|
|
44
|
+
* ## What reaches the model
|
|
45
|
+
*
|
|
46
|
+
* For variants: the brief, what the test varies, and the copy under test as
|
|
47
|
+
* the surface handed it over. For a result: the test's name, its arms' counts
|
|
48
|
+
* and rates as the results reader published them, and the verdict code
|
|
49
|
+
* reached. No visitor, no session and no assignment is read, because the
|
|
50
|
+
* reader publishes none — it answers in aggregates, which is the whole reason
|
|
51
|
+
* a figure reader is what this reads.
|
|
52
|
+
*/
|
|
53
|
+
/** The reader whose figures a result is explained from, and the plugin that owns it. */
|
|
54
|
+
export declare const AI_EXPERIMENT_READER_ID = "marketing.experiments";
|
|
55
|
+
/** The window a result is read over: a test's figures are totals since it started. */
|
|
56
|
+
export declare const AI_EXPERIMENT_READ_DAYS = 0;
|
|
57
|
+
export declare const AI_EXPERIMENT_NO_TASK_COPY = "Start this from the A/B testing card, which says whether you want variants or an explanation.";
|
|
58
|
+
export declare const AI_EXPERIMENT_NO_TARGET_COPY = "Say whether the test varies a screen, a section or an email.";
|
|
59
|
+
export declare const AI_EXPERIMENT_NO_SITE_COPY = "Open the site whose test this is.";
|
|
60
|
+
export declare const AI_EXPERIMENT_NO_READER_COPY = "A/B testing is not available on this workspace, so there is no test to work on.";
|
|
61
|
+
export declare const AI_EXPERIMENT_NO_SUBJECT_COPY = "Give the copy the test varies, so there is something to write variants of.";
|
|
62
|
+
export declare const AI_EXPERIMENT_NO_TEST_COPY = "Name the test to explain, as A/B testing lists it.";
|
|
63
|
+
export declare const AI_EXPERIMENT_NO_FIGURES_COPY = "That test\u2019s figures could not be read. Try again in a moment.";
|
|
64
|
+
export declare const AI_EXPERIMENT_UNREADABLE_RESULT_COPY = "That test has no first variant and something to compare against it yet, so there is nothing to explain.";
|
|
65
|
+
export declare const AI_EXPERIMENT_NO_VARIANTS_COPY = "The AI did not write variants that could be used. Try the brief in different words.";
|
|
66
|
+
export declare const AI_EXPERIMENT_NO_EXPLANATION_COPY = "The AI did not explain the result in words that match its figures. Try again.";
|
|
67
|
+
/** The step's answer ceiling, from the routing table. */
|
|
68
|
+
export declare const AI_JOB_EXPERIMENT_MAX_TOKENS: number;
|
|
69
|
+
/**
|
|
70
|
+
* The step's time: at most one re-ask at the routing ceiling, plus the one
|
|
71
|
+
* figure read an explanation makes. Variants read nothing.
|
|
72
|
+
*/
|
|
73
|
+
export declare const AI_JOB_EXPERIMENT_STEP_BUDGET: import("./ai-job-budget").AiJobStepBudget;
|
|
74
|
+
export declare const AI_JOB_EXPERIMENT_STEP_MINIMUM_MS: number;
|
|
75
|
+
/** The rules both tasks are sent: static, byte-identical for every workspace. */
|
|
76
|
+
export declare const AI_EXPERIMENT_RULES: string;
|
|
77
|
+
export declare const AI_JOB_EXPERIMENT_SYSTEM: AiSystemBlock[];
|
|
78
|
+
/** The user turn for variants: the brief, what varies, and the copy as it stands. */
|
|
79
|
+
export declare function aiExperimentVariantsPrompt(input: {
|
|
80
|
+
brief: string;
|
|
81
|
+
target: AiExperimentTarget;
|
|
82
|
+
subject: string;
|
|
83
|
+
goal: string;
|
|
84
|
+
}): string;
|
|
85
|
+
/** What the verdict tells the model it may say. */
|
|
86
|
+
export declare function aiExperimentVerdictText(reading: AiExperimentReading): string;
|
|
87
|
+
/** The user turn for an explanation: the test, its arms, and the verdict. */
|
|
88
|
+
export declare function aiExperimentExplainPrompt(input: {
|
|
89
|
+
brief: string;
|
|
90
|
+
reading: AiExperimentReading;
|
|
91
|
+
}): string;
|
|
92
|
+
export declare const runAiJobExperimentStep: AiJobStepRunner;
|
|
93
|
+
/**
|
|
94
|
+
* Whether an experiment job may run here: a site of the job's own org, a task
|
|
95
|
+
* the step runs, and A/B testing available on it — which is the results
|
|
96
|
+
* reader being one this workspace may read, asked of the owning plugin rather
|
|
97
|
+
* than restated.
|
|
98
|
+
*/
|
|
99
|
+
export declare function aiExperimentAdmissionRefusal(context: AiJobAdmissionContext): Promise<AiJobAdmissionRefusal | null>;
|
|
100
|
+
/**
|
|
101
|
+
* The experiment kind's registrations, called by the console surface
|
|
102
|
+
* (`registerAiJobKinds` in `server.ts`), never made by importing this module
|
|
103
|
+
* (AGL-3025).
|
|
104
|
+
*/
|
|
105
|
+
export declare function registerAiExperimentJob(): void;
|
|
@@ -0,0 +1,445 @@
|
|
|
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 { AI_EXPERIMENT_FIGURE_READER, AI_EXPERIMENT_MAX_VARIANTS, AI_EXPERIMENT_MIN_VARIANTS, AI_EXPERIMENT_SUBJECT_MAX_CHARS, aiExperimentNextStep, aiExperimentTarget, aiExperimentTask, aiExperimentVerdictNamesWinner, checkAiExperimentExplanation, checkAiExperimentVariants, readAiExperimentArms, readAiExperimentResult } from "../model/ai-experiment.js";
|
|
18
|
+
import { AI_STEP_TIERS } from "../providers/catalog.js";
|
|
19
|
+
import { AI_ROUTING_TABLE, aiModelForStep } from "../providers/routing.js";
|
|
20
|
+
import { AI_ACCEPTABLE_USE_BLOCK, runAiRequest } from "../runtime/ai-runtime.js";
|
|
21
|
+
import { AI_GENERATION_MAX_ATTEMPTS } from "../runtime/ai-generation-bounds.js";
|
|
22
|
+
import { aiInsightReaders, readAiInsightTables } from "../insights/ai-insight-readers.js";
|
|
23
|
+
import { registerAiJobAdmission } from "./ai-job-admission.js";
|
|
24
|
+
import { aiJobStepBudget } from "./ai-job-budget.js";
|
|
25
|
+
import { registerAiJobStep } from "./ai-jobs.js";
|
|
26
|
+
import { AI_EXPERIMENT_EXPLAIN_TOOL_NAME, AI_EXPERIMENT_VARIANTS_TOOL_NAME, aiExperimentExplainTool, aiExperimentVariantsTool, parseAiExperimentExplanation, parseAiExperimentVariants } from "../tools/ai-experiment-tool.js";
|
|
27
|
+
/**
|
|
28
|
+
* The `experiment` step (AGL-2914): A/B tests by AI.
|
|
29
|
+
*
|
|
30
|
+
* A/B testing already exists — the marketing plugin models the experiment,
|
|
31
|
+
* buckets visitors, counts exposures and conversions and compares the arms.
|
|
32
|
+
* This step is the AI layer over it, and it does two things:
|
|
33
|
+
*
|
|
34
|
+
* 1. **Variants.** From the copy under test, it proposes between two and four
|
|
35
|
+
* variants of it. It proposes COPY and nothing else: no weight, no traffic
|
|
36
|
+
* split, no goal, no schedule and no winner. A person puts them into the
|
|
37
|
+
* A/B testing card, which is the only thing that creates or starts a test.
|
|
38
|
+
* 2. **The result.** Code reads the test's figures through the reader
|
|
39
|
+
* marketing registers for them, decides what they support, and only then
|
|
40
|
+
* asks the model for the words. The verdict is never the model's, and an
|
|
41
|
+
* answer that claims more than the verdict is cut back to it.
|
|
42
|
+
*
|
|
43
|
+
* ## Nothing here writes a test
|
|
44
|
+
*
|
|
45
|
+
* Both answers are proposals, like a theme's or a listing's. The experiment
|
|
46
|
+
* document, its variants' screen versions and its traffic are marketing's and
|
|
47
|
+
* the besigner's, and a job that could write them could start an experiment on
|
|
48
|
+
* live visitors without anyone deciding to.
|
|
49
|
+
*
|
|
50
|
+
* ## What reaches the model
|
|
51
|
+
*
|
|
52
|
+
* For variants: the brief, what the test varies, and the copy under test as
|
|
53
|
+
* the surface handed it over. For a result: the test's name, its arms' counts
|
|
54
|
+
* and rates as the results reader published them, and the verdict code
|
|
55
|
+
* reached. No visitor, no session and no assignment is read, because the
|
|
56
|
+
* reader publishes none — it answers in aggregates, which is the whole reason
|
|
57
|
+
* a figure reader is what this reads.
|
|
58
|
+
*/ /** The reader whose figures a result is explained from, and the plugin that owns it. */ export const AI_EXPERIMENT_READER_ID = AI_EXPERIMENT_FIGURE_READER;
|
|
59
|
+
/** The window a result is read over: a test's figures are totals since it started. */ export const AI_EXPERIMENT_READ_DAYS = 0;
|
|
60
|
+
export const AI_EXPERIMENT_NO_TASK_COPY = 'Start this from the A/B testing card, which says whether you want variants or an explanation.';
|
|
61
|
+
export const AI_EXPERIMENT_NO_TARGET_COPY = 'Say whether the test varies a screen, a section or an email.';
|
|
62
|
+
export const AI_EXPERIMENT_NO_SITE_COPY = 'Open the site whose test this is.';
|
|
63
|
+
export const AI_EXPERIMENT_NO_READER_COPY = 'A/B testing is not available on this workspace, so there is no test to work on.';
|
|
64
|
+
export const AI_EXPERIMENT_NO_SUBJECT_COPY = 'Give the copy the test varies, so there is something to write variants of.';
|
|
65
|
+
export const AI_EXPERIMENT_NO_TEST_COPY = 'Name the test to explain, as A/B testing lists it.';
|
|
66
|
+
export const AI_EXPERIMENT_NO_FIGURES_COPY = 'That test’s figures could not be read. Try again in a moment.';
|
|
67
|
+
export const AI_EXPERIMENT_UNREADABLE_RESULT_COPY = 'That test has no first variant and something to compare against it yet, so there is nothing to explain.';
|
|
68
|
+
export const AI_EXPERIMENT_NO_VARIANTS_COPY = 'The AI did not write variants that could be used. Try the brief in different words.';
|
|
69
|
+
export const AI_EXPERIMENT_NO_EXPLANATION_COPY = 'The AI did not explain the result in words that match its figures. Try again.';
|
|
70
|
+
/** The step's answer ceiling, from the routing table. */ export const AI_JOB_EXPERIMENT_MAX_TOKENS = AI_ROUTING_TABLE['job.experiment'].maxTokens;
|
|
71
|
+
/**
|
|
72
|
+
* The step's time: at most one re-ask at the routing ceiling, plus the one
|
|
73
|
+
* figure read an explanation makes. Variants read nothing.
|
|
74
|
+
*/ export const AI_JOB_EXPERIMENT_STEP_BUDGET = aiJobStepBudget({
|
|
75
|
+
tier: AI_STEP_TIERS['job.experiment'],
|
|
76
|
+
maxTokens: AI_JOB_EXPERIMENT_MAX_TOKENS,
|
|
77
|
+
attempts: AI_GENERATION_MAX_ATTEMPTS,
|
|
78
|
+
lookups: 1
|
|
79
|
+
});
|
|
80
|
+
export const AI_JOB_EXPERIMENT_STEP_MINIMUM_MS = AI_JOB_EXPERIMENT_STEP_BUDGET.minimumMs;
|
|
81
|
+
/** The rules both tasks are sent: static, byte-identical for every workspace. */ export const AI_EXPERIMENT_RULES = [
|
|
82
|
+
'You work on A/B tests for a website builder. A test shows visitors one of several variants of the same thing and counts which converts best. You never start, stop or change a test: you write variants for a person to put into the A/B testing card, and you put a result someone else measured into plain words.',
|
|
83
|
+
'',
|
|
84
|
+
`When you are given copy under test, call ${AI_EXPERIMENT_VARIANTS_TOOL_NAME} once:`,
|
|
85
|
+
`- Answer with between ${AI_EXPERIMENT_MIN_VARIANTS} and ${AI_EXPERIMENT_MAX_VARIANTS} variants. The first is the copy as it stands, unchanged, so the test has something to measure against.`,
|
|
86
|
+
'- Each later variant changes ONE idea — the promise, the specificity, the length, the call to action — so a result says which idea won.',
|
|
87
|
+
'- No two variants say the same thing in different words.',
|
|
88
|
+
'- Write plain text: no HTML, no markdown, no emoji, no fences.',
|
|
89
|
+
'- Never invent a fact, a price, a name, a statistic or a guarantee the copy under test did not give you.',
|
|
90
|
+
'- Write in the language of the copy under test.',
|
|
91
|
+
'',
|
|
92
|
+
`When you are given a result, call ${AI_EXPERIMENT_EXPLAIN_TOOL_NAME} once:`,
|
|
93
|
+
'- The request states the verdict. It was decided from the counts before you were asked, and it is not yours to revise.',
|
|
94
|
+
'- Where the verdict names no winner, write nothing that says or implies one: no variant is ahead, none is better, nothing is significant, and you recommend nothing. Say what the figures show and why they do not settle it.',
|
|
95
|
+
'- Where the verdict names a winner, name that variant and no other.',
|
|
96
|
+
'- Every number you write appears in the figures you were given, as they show it or rounded. Never compute one.',
|
|
97
|
+
'- Plain sentences: no markdown, no headings, no lists.',
|
|
98
|
+
'- Write in the language of the brief.'
|
|
99
|
+
].join('\n');
|
|
100
|
+
export const AI_JOB_EXPERIMENT_SYSTEM = [
|
|
101
|
+
{
|
|
102
|
+
text: `${AI_EXPERIMENT_RULES}\n\n${AI_ACCEPTABLE_USE_BLOCK}`,
|
|
103
|
+
cacheBreakpoint: true
|
|
104
|
+
}
|
|
105
|
+
];
|
|
106
|
+
const str = (value)=>typeof value === 'string' ? value.trim() : '';
|
|
107
|
+
/** What the test varies, in the words the prompt names it by. */ const TARGET_NOUN = {
|
|
108
|
+
screen: 'a page',
|
|
109
|
+
section: 'one section of a page',
|
|
110
|
+
email: 'an email'
|
|
111
|
+
};
|
|
112
|
+
/** The user turn for variants: the brief, what varies, and the copy as it stands. */ export function aiExperimentVariantsPrompt(input) {
|
|
113
|
+
return [
|
|
114
|
+
`Brief: ${input.brief}`,
|
|
115
|
+
`The test varies ${TARGET_NOUN[input.target]}.`,
|
|
116
|
+
...input.goal ? [
|
|
117
|
+
`It is trying to move: ${input.goal}`
|
|
118
|
+
] : [],
|
|
119
|
+
'',
|
|
120
|
+
'The copy under test, as it stands:',
|
|
121
|
+
input.subject
|
|
122
|
+
].join('\n');
|
|
123
|
+
}
|
|
124
|
+
/** One arm as the explanation prompt shows it. */ function armText(arm, index) {
|
|
125
|
+
const rate = arm.rate === null ? 'no rate' : `${arm.rate}%`;
|
|
126
|
+
const against = index === 0 ? 'the first variant, which the others are compared against' : [
|
|
127
|
+
arm.lift === null ? 'lift not measurable' : `lift ${arm.lift}%`,
|
|
128
|
+
arm.confidence === null ? 'confidence not measurable' : `confidence ${arm.confidence}%`
|
|
129
|
+
].join(', ');
|
|
130
|
+
return `- ${arm.id}: shown ${arm.exposures}, converted ${arm.conversions}, rate ${rate} (${against})`;
|
|
131
|
+
}
|
|
132
|
+
/** What the verdict tells the model it may say. */ export function aiExperimentVerdictText(reading) {
|
|
133
|
+
if (reading.verdict === 'winner') {
|
|
134
|
+
return `VERDICT: ${reading.winnerId} is ahead of the first variant by more than chance explains, at the ${reading.threshold}% confidence this test is called at. Name ${reading.winnerId} and no other variant.`;
|
|
135
|
+
}
|
|
136
|
+
if (reading.verdict === 'control') {
|
|
137
|
+
return `VERDICT: every other variant is behind the first one, ${reading.winnerId}, by more than chance explains. Name ${reading.winnerId} and no other variant.`;
|
|
138
|
+
}
|
|
139
|
+
return [
|
|
140
|
+
`VERDICT: THERE IS NO WINNER — ${reading.reasons.join('; ')}.`,
|
|
141
|
+
'Say what the figures show and why they do not settle it. Name no winner, say no variant is ahead, better, winning or significant, and recommend no variant.',
|
|
142
|
+
`Leave winner and next empty; what to do next is already decided: ${aiExperimentNextStep(reading.verdict)}`
|
|
143
|
+
].join('\n');
|
|
144
|
+
}
|
|
145
|
+
/** The user turn for an explanation: the test, its arms, and the verdict. */ export function aiExperimentExplainPrompt(input) {
|
|
146
|
+
return [
|
|
147
|
+
...input.brief ? [
|
|
148
|
+
`Brief: ${input.brief}`
|
|
149
|
+
] : [],
|
|
150
|
+
`Test: ${input.reading.test}`,
|
|
151
|
+
'Figures, totals since the test started:',
|
|
152
|
+
...input.reading.arms.map(armText),
|
|
153
|
+
'',
|
|
154
|
+
aiExperimentVerdictText(input.reading)
|
|
155
|
+
].join('\n');
|
|
156
|
+
}
|
|
157
|
+
/** The proposal an answer becomes, as the job's output carries it. */ function experimentOutput(job, label, proposal) {
|
|
158
|
+
var _job_hostId;
|
|
159
|
+
var _job_inputs, _job_inputs1;
|
|
160
|
+
return {
|
|
161
|
+
resource: 'experiment',
|
|
162
|
+
// The test the surface named, so a person opens the one they asked about;
|
|
163
|
+
// a variants job for a test that does not exist yet names the job itself.
|
|
164
|
+
id: str((_job_inputs = job.inputs) == null ? void 0 : _job_inputs['experimentId']) || job.$id,
|
|
165
|
+
versionId: null,
|
|
166
|
+
hostId: (_job_hostId = job.hostId) != null ? _job_hostId : null,
|
|
167
|
+
hostSubdomain: str((_job_inputs1 = job.inputs) == null ? void 0 : _job_inputs1['hostSubdomain']) || null,
|
|
168
|
+
label,
|
|
169
|
+
proposal
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The A/B test results for this job's site, or `null` when the workspace has
|
|
174
|
+
* no such reader. The insight path's own resolver is what decides whether a
|
|
175
|
+
* reader may be read here — the plan's entitlement, the owning plugin's
|
|
176
|
+
* release flag, and whether that plugin runs on this workspace and this site
|
|
177
|
+
* — so this asks it rather than restating any of it.
|
|
178
|
+
*/ async function readExperimentFigures(context, place) {
|
|
179
|
+
var _snapshot_data, _context_org, _read_tables_;
|
|
180
|
+
if (!place.hostId) return null;
|
|
181
|
+
const snapshot = await context.firestore.collection('hosts').doc(place.hostId).get();
|
|
182
|
+
const host = snapshot.exists ? (_snapshot_data = snapshot.data()) != null ? _snapshot_data : {} : null;
|
|
183
|
+
if (!host || host['orgId'] !== place.orgId) return null;
|
|
184
|
+
const readers = await aiInsightReaders({
|
|
185
|
+
orgId: place.orgId,
|
|
186
|
+
hostId: place.hostId,
|
|
187
|
+
org: (_context_org = context.org) != null ? _context_org : null,
|
|
188
|
+
host,
|
|
189
|
+
surface: 'analytics'
|
|
190
|
+
});
|
|
191
|
+
const experiments = readers.filter(({ reader })=>reader.id === AI_EXPERIMENT_READER_ID);
|
|
192
|
+
if (!experiments.length) return null;
|
|
193
|
+
const read = await readAiInsightTables(experiments, [
|
|
194
|
+
{
|
|
195
|
+
reader: AI_EXPERIMENT_READER_ID,
|
|
196
|
+
days: AI_EXPERIMENT_READ_DAYS,
|
|
197
|
+
params: {}
|
|
198
|
+
}
|
|
199
|
+
], {
|
|
200
|
+
orgId: place.orgId,
|
|
201
|
+
hostId: place.hostId,
|
|
202
|
+
uid: place.uid,
|
|
203
|
+
now: context.now
|
|
204
|
+
}, 1);
|
|
205
|
+
return {
|
|
206
|
+
table: (_read_tables_ = read.tables[0]) != null ? _read_tables_ : null,
|
|
207
|
+
refusals: read.refusals
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
export const runAiJobExperimentStep = async (context)=>{
|
|
211
|
+
var _ref;
|
|
212
|
+
var _job_inputs, _result_toolUse_find;
|
|
213
|
+
const { job, signal } = context;
|
|
214
|
+
const model = (_ref = context.modelFor == null ? void 0 : context.modelFor.call(context, 'job.experiment')) != null ? _ref : aiModelForStep('job.experiment');
|
|
215
|
+
const maxTokens = AI_JOB_EXPERIMENT_STEP_BUDGET.maxTokens(model);
|
|
216
|
+
const task = aiExperimentTask(job.inputs);
|
|
217
|
+
const spent = (result)=>({
|
|
218
|
+
usage: result.usage,
|
|
219
|
+
estCostUsd: result.estCostUsd,
|
|
220
|
+
model,
|
|
221
|
+
stopReason: result.stopReason,
|
|
222
|
+
effort: null
|
|
223
|
+
});
|
|
224
|
+
const stop = (failure)=>({
|
|
225
|
+
outputs: [],
|
|
226
|
+
usage: {
|
|
227
|
+
inputTokens: 0,
|
|
228
|
+
outputTokens: 0,
|
|
229
|
+
cacheReadTokens: 0,
|
|
230
|
+
cacheWriteTokens: 0
|
|
231
|
+
},
|
|
232
|
+
estCostUsd: 0,
|
|
233
|
+
model,
|
|
234
|
+
stopReason: null,
|
|
235
|
+
failure
|
|
236
|
+
});
|
|
237
|
+
if (!task) return stop(AI_EXPERIMENT_NO_TASK_COPY);
|
|
238
|
+
if (!job.hostId) return stop(AI_EXPERIMENT_NO_SITE_COPY);
|
|
239
|
+
const ask = (messages, tool)=>runAiRequest(_extends({
|
|
240
|
+
model,
|
|
241
|
+
system: AI_JOB_EXPERIMENT_SYSTEM,
|
|
242
|
+
messages,
|
|
243
|
+
tools: [
|
|
244
|
+
tool
|
|
245
|
+
],
|
|
246
|
+
maxTokens
|
|
247
|
+
}, AI_ROUTING_TABLE['job.experiment'].thinking ? {
|
|
248
|
+
thinking: AI_ROUTING_TABLE['job.experiment'].thinking
|
|
249
|
+
} : {}, {
|
|
250
|
+
stream: false
|
|
251
|
+
}, signal ? {
|
|
252
|
+
signal
|
|
253
|
+
} : {}));
|
|
254
|
+
if (task === 'variants') {
|
|
255
|
+
var _job_inputs1, _job_inputs2;
|
|
256
|
+
const target = aiExperimentTarget(job.inputs);
|
|
257
|
+
if (!target) return stop(AI_EXPERIMENT_NO_TARGET_COPY);
|
|
258
|
+
const subject = str((_job_inputs1 = job.inputs) == null ? void 0 : _job_inputs1['subject']).slice(0, AI_EXPERIMENT_SUBJECT_MAX_CHARS);
|
|
259
|
+
if (!subject) return stop(AI_EXPERIMENT_NO_SUBJECT_COPY);
|
|
260
|
+
const tool = aiExperimentVariantsTool(target);
|
|
261
|
+
let messages = [
|
|
262
|
+
{
|
|
263
|
+
role: 'user',
|
|
264
|
+
content: aiExperimentVariantsPrompt({
|
|
265
|
+
brief: job.brief,
|
|
266
|
+
target,
|
|
267
|
+
subject,
|
|
268
|
+
goal: str((_job_inputs2 = job.inputs) == null ? void 0 : _job_inputs2['goal'])
|
|
269
|
+
})
|
|
270
|
+
}
|
|
271
|
+
];
|
|
272
|
+
let last = null;
|
|
273
|
+
for(let attempt = 0; attempt < AI_GENERATION_MAX_ATTEMPTS; attempt += 1){
|
|
274
|
+
var _result_toolUse_find1;
|
|
275
|
+
const result = await ask(messages, tool);
|
|
276
|
+
if (result.kind === 'refusal') {
|
|
277
|
+
return _extends({
|
|
278
|
+
outputs: []
|
|
279
|
+
}, spent(result), {
|
|
280
|
+
refused: true
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
const parsed = parseAiExperimentVariants((_result_toolUse_find1 = result.toolUse.find((use)=>use.name === AI_EXPERIMENT_VARIANTS_TOOL_NAME)) == null ? void 0 : _result_toolUse_find1.input);
|
|
284
|
+
const checked = checkAiExperimentVariants(parsed, target);
|
|
285
|
+
last = _extends({
|
|
286
|
+
outputs: []
|
|
287
|
+
}, spent(result), {
|
|
288
|
+
failure: AI_EXPERIMENT_NO_VARIANTS_COPY
|
|
289
|
+
});
|
|
290
|
+
if (checked) {
|
|
291
|
+
if (checked.findings.length) {
|
|
292
|
+
console.info('ai experiment variants dropped', {
|
|
293
|
+
jobId: job.$id,
|
|
294
|
+
findings: checked.findings
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
return _extends({
|
|
298
|
+
outputs: [
|
|
299
|
+
variantsOutput(job, target, checked.proposal)
|
|
300
|
+
]
|
|
301
|
+
}, spent(result));
|
|
302
|
+
}
|
|
303
|
+
messages = [
|
|
304
|
+
...messages,
|
|
305
|
+
{
|
|
306
|
+
role: 'assistant',
|
|
307
|
+
content: `Answered with ${AI_EXPERIMENT_VARIANTS_TOOL_NAME}.`
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
role: 'user',
|
|
311
|
+
content: `Those variants could not be used. Answer again with ${AI_EXPERIMENT_VARIANTS_TOOL_NAME}: ` + `at least ${AI_EXPERIMENT_MIN_VARIANTS} variants, each with copy of its own, none repeating ` + 'another, and plain text throughout.'
|
|
312
|
+
}
|
|
313
|
+
];
|
|
314
|
+
}
|
|
315
|
+
return last != null ? last : stop(AI_EXPERIMENT_NO_VARIANTS_COPY);
|
|
316
|
+
}
|
|
317
|
+
const test = str((_job_inputs = job.inputs) == null ? void 0 : _job_inputs['test']);
|
|
318
|
+
if (!test) return stop(AI_EXPERIMENT_NO_TEST_COPY);
|
|
319
|
+
const figures = await readExperimentFigures(context, {
|
|
320
|
+
orgId: job.orgId,
|
|
321
|
+
hostId: job.hostId,
|
|
322
|
+
uid: job.createdBy
|
|
323
|
+
});
|
|
324
|
+
if (!figures) return stop(AI_EXPERIMENT_NO_READER_COPY);
|
|
325
|
+
if (!figures.table) {
|
|
326
|
+
if (figures.refusals.length) {
|
|
327
|
+
console.warn('ai experiment figures refused', {
|
|
328
|
+
jobId: job.$id,
|
|
329
|
+
refusals: figures.refusals
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
return stop(AI_EXPERIMENT_NO_FIGURES_COPY);
|
|
333
|
+
}
|
|
334
|
+
const reading = readAiExperimentResult(test, readAiExperimentArms(figures.table, test));
|
|
335
|
+
// Nothing to explain, and nothing spent finding that out: the verdict was
|
|
336
|
+
// reached from the figures alone.
|
|
337
|
+
if (reading.verdict === 'unreadable') return stop(AI_EXPERIMENT_UNREADABLE_RESULT_COPY);
|
|
338
|
+
const result = await ask([
|
|
339
|
+
{
|
|
340
|
+
role: 'user',
|
|
341
|
+
content: aiExperimentExplainPrompt({
|
|
342
|
+
brief: job.brief,
|
|
343
|
+
reading
|
|
344
|
+
})
|
|
345
|
+
}
|
|
346
|
+
], aiExperimentExplainTool());
|
|
347
|
+
if (result.kind === 'refusal') return _extends({
|
|
348
|
+
outputs: []
|
|
349
|
+
}, spent(result), {
|
|
350
|
+
refused: true
|
|
351
|
+
});
|
|
352
|
+
const explained = checkAiExperimentExplanation(parseAiExperimentExplanation((_result_toolUse_find = result.toolUse.find((use)=>use.name === AI_EXPERIMENT_EXPLAIN_TOOL_NAME)) == null ? void 0 : _result_toolUse_find.input), reading);
|
|
353
|
+
if (!explained) {
|
|
354
|
+
return _extends({
|
|
355
|
+
outputs: []
|
|
356
|
+
}, spent(result), {
|
|
357
|
+
failure: AI_EXPERIMENT_NO_EXPLANATION_COPY
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
if (explained.findings.length) {
|
|
361
|
+
console.info('ai experiment explanation cut back to its reading', {
|
|
362
|
+
jobId: job.$id,
|
|
363
|
+
verdict: reading.verdict,
|
|
364
|
+
findings: explained.findings
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
return _extends({
|
|
368
|
+
outputs: [
|
|
369
|
+
explanationOutput(job, reading, explained)
|
|
370
|
+
]
|
|
371
|
+
}, spent(result));
|
|
372
|
+
};
|
|
373
|
+
/** A variants answer as the job's output. */ function variantsOutput(job, target, proposal) {
|
|
374
|
+
return _extends({}, experimentOutput(job, `${proposal.variants.length} variants to test`, {
|
|
375
|
+
task: 'variants',
|
|
376
|
+
target,
|
|
377
|
+
goal: proposal.goal,
|
|
378
|
+
variants: proposal.variants
|
|
379
|
+
}), {
|
|
380
|
+
note: 'Put these into A/B testing to start the test; nothing has been changed on the site.'
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
/** An explanation as the job's output, carrying the verdict code reached. */ function explanationOutput(job, reading, explained) {
|
|
384
|
+
return experimentOutput(job, explained.test || 'A/B test result', {
|
|
385
|
+
task: 'explain',
|
|
386
|
+
verdict: explained.verdict,
|
|
387
|
+
headline: explained.headline,
|
|
388
|
+
points: explained.points,
|
|
389
|
+
// Only ever the reading's arm: an explanation carries no winner the
|
|
390
|
+
// figures did not support, whatever the answer said.
|
|
391
|
+
winnerId: aiExperimentVerdictNamesWinner(reading.verdict) ? explained.winnerId : null,
|
|
392
|
+
next: explained.next,
|
|
393
|
+
threshold: reading.threshold,
|
|
394
|
+
arms: reading.arms
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Whether an experiment job may run here: a site of the job's own org, a task
|
|
399
|
+
* the step runs, and A/B testing available on it — which is the results
|
|
400
|
+
* reader being one this workspace may read, asked of the owning plugin rather
|
|
401
|
+
* than restated.
|
|
402
|
+
*/ export async function aiExperimentAdmissionRefusal(context) {
|
|
403
|
+
var _snapshot_data;
|
|
404
|
+
if (!aiExperimentTask(context.inputs)) {
|
|
405
|
+
return {
|
|
406
|
+
status: 400,
|
|
407
|
+
error: AI_EXPERIMENT_NO_TASK_COPY
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
if (!context.hostId) return {
|
|
411
|
+
status: 400,
|
|
412
|
+
error: AI_EXPERIMENT_NO_SITE_COPY
|
|
413
|
+
};
|
|
414
|
+
const snapshot = await context.firestore.collection('hosts').doc(context.hostId).get();
|
|
415
|
+
const host = snapshot.exists ? (_snapshot_data = snapshot.data()) != null ? _snapshot_data : {} : null;
|
|
416
|
+
if (!host || host['orgId'] !== context.orgId) {
|
|
417
|
+
return {
|
|
418
|
+
status: 404,
|
|
419
|
+
error: 'Unknown site'
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
const readers = await aiInsightReaders({
|
|
423
|
+
orgId: context.orgId,
|
|
424
|
+
hostId: context.hostId,
|
|
425
|
+
org: context.org,
|
|
426
|
+
host,
|
|
427
|
+
surface: 'analytics'
|
|
428
|
+
});
|
|
429
|
+
return readers.some(({ reader })=>reader.id === AI_EXPERIMENT_READER_ID) ? null : {
|
|
430
|
+
status: 403,
|
|
431
|
+
error: AI_EXPERIMENT_NO_READER_COPY
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* The experiment kind's registrations, called by the console surface
|
|
436
|
+
* (`registerAiJobKinds` in `server.ts`), never made by importing this module
|
|
437
|
+
* (AGL-3025).
|
|
438
|
+
*/ export function registerAiExperimentJob() {
|
|
439
|
+
registerAiJobStep('experiment', runAiJobExperimentStep, {
|
|
440
|
+
minimumMs: AI_JOB_EXPERIMENT_STEP_MINIMUM_MS
|
|
441
|
+
});
|
|
442
|
+
registerAiJobAdmission('experiment', aiExperimentAdmissionRefusal);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
//# sourceMappingURL=ai-job-experiment-step.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-experiment-step.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n AI_EXPERIMENT_FIGURE_READER,\n AI_EXPERIMENT_MAX_VARIANTS,\n AI_EXPERIMENT_MIN_VARIANTS,\n AI_EXPERIMENT_SUBJECT_MAX_CHARS,\n aiExperimentNextStep,\n aiExperimentTarget,\n aiExperimentTask,\n aiExperimentVerdictNamesWinner,\n checkAiExperimentExplanation,\n checkAiExperimentVariants,\n readAiExperimentArms,\n readAiExperimentResult,\n type AiExperimentArm,\n type AiExperimentExplanation,\n type AiExperimentReading,\n type AiExperimentTarget,\n type AiExperimentVariantsProposal,\n} from '../model/ai-experiment'\nimport type { AiJob, AiJobOutput } from '../model/ai-jobs.types'\nimport { AI_STEP_TIERS } from '../providers/catalog'\nimport { AI_ROUTING_TABLE, aiModelForStep } from '../providers/routing'\nimport {\n AI_ACCEPTABLE_USE_BLOCK,\n runAiRequest,\n type AiMessage,\n type AiSystemBlock,\n} from '../runtime/ai-runtime'\nimport { AI_GENERATION_MAX_ATTEMPTS } from '../runtime/ai-generation-bounds'\nimport { aiInsightReaders, readAiInsightTables } from '../insights/ai-insight-readers'\nimport {\n registerAiJobAdmission,\n type AiJobAdmissionContext,\n type AiJobAdmissionRefusal,\n} from './ai-job-admission'\nimport { aiJobStepBudget } from './ai-job-budget'\nimport type { AiJobStepContext, AiJobStepOutcome, AiJobStepRunner } from './ai-job-text-step'\nimport { registerAiJobStep } from './ai-jobs'\nimport {\n AI_EXPERIMENT_EXPLAIN_TOOL_NAME,\n AI_EXPERIMENT_VARIANTS_TOOL_NAME,\n aiExperimentExplainTool,\n aiExperimentVariantsTool,\n parseAiExperimentExplanation,\n parseAiExperimentVariants,\n} from '../tools/ai-experiment-tool'\n\n/**\n * The `experiment` step (AGL-2914): A/B tests by AI.\n *\n * A/B testing already exists — the marketing plugin models the experiment,\n * buckets visitors, counts exposures and conversions and compares the arms.\n * This step is the AI layer over it, and it does two things:\n *\n * 1. **Variants.** From the copy under test, it proposes between two and four\n * variants of it. It proposes COPY and nothing else: no weight, no traffic\n * split, no goal, no schedule and no winner. A person puts them into the\n * A/B testing card, which is the only thing that creates or starts a test.\n * 2. **The result.** Code reads the test's figures through the reader\n * marketing registers for them, decides what they support, and only then\n * asks the model for the words. The verdict is never the model's, and an\n * answer that claims more than the verdict is cut back to it.\n *\n * ## Nothing here writes a test\n *\n * Both answers are proposals, like a theme's or a listing's. The experiment\n * document, its variants' screen versions and its traffic are marketing's and\n * the besigner's, and a job that could write them could start an experiment on\n * live visitors without anyone deciding to.\n *\n * ## What reaches the model\n *\n * For variants: the brief, what the test varies, and the copy under test as\n * the surface handed it over. For a result: the test's name, its arms' counts\n * and rates as the results reader published them, and the verdict code\n * reached. No visitor, no session and no assignment is read, because the\n * reader publishes none — it answers in aggregates, which is the whole reason\n * a figure reader is what this reads.\n */\n\n/** The reader whose figures a result is explained from, and the plugin that owns it. */\nexport const AI_EXPERIMENT_READER_ID = AI_EXPERIMENT_FIGURE_READER\n\n/** The window a result is read over: a test's figures are totals since it started. */\nexport const AI_EXPERIMENT_READ_DAYS = 0\n\nexport const AI_EXPERIMENT_NO_TASK_COPY =\n 'Start this from the A/B testing card, which says whether you want variants or an explanation.'\nexport const AI_EXPERIMENT_NO_TARGET_COPY =\n 'Say whether the test varies a screen, a section or an email.'\nexport const AI_EXPERIMENT_NO_SITE_COPY = 'Open the site whose test this is.'\nexport const AI_EXPERIMENT_NO_READER_COPY =\n 'A/B testing is not available on this workspace, so there is no test to work on.'\nexport const AI_EXPERIMENT_NO_SUBJECT_COPY =\n 'Give the copy the test varies, so there is something to write variants of.'\nexport const AI_EXPERIMENT_NO_TEST_COPY =\n 'Name the test to explain, as A/B testing lists it.'\nexport const AI_EXPERIMENT_NO_FIGURES_COPY =\n 'That test’s figures could not be read. Try again in a moment.'\nexport const AI_EXPERIMENT_UNREADABLE_RESULT_COPY =\n 'That test has no first variant and something to compare against it yet, so there is nothing to explain.'\nexport const AI_EXPERIMENT_NO_VARIANTS_COPY =\n 'The AI did not write variants that could be used. Try the brief in different words.'\nexport const AI_EXPERIMENT_NO_EXPLANATION_COPY =\n 'The AI did not explain the result in words that match its figures. Try again.'\n\n/** The step's answer ceiling, from the routing table. */\nexport const AI_JOB_EXPERIMENT_MAX_TOKENS = AI_ROUTING_TABLE['job.experiment'].maxTokens\n\n/**\n * The step's time: at most one re-ask at the routing ceiling, plus the one\n * figure read an explanation makes. Variants read nothing.\n */\nexport const AI_JOB_EXPERIMENT_STEP_BUDGET = aiJobStepBudget({\n tier: AI_STEP_TIERS['job.experiment'],\n maxTokens: AI_JOB_EXPERIMENT_MAX_TOKENS,\n attempts: AI_GENERATION_MAX_ATTEMPTS,\n lookups: 1,\n})\n\nexport const AI_JOB_EXPERIMENT_STEP_MINIMUM_MS = AI_JOB_EXPERIMENT_STEP_BUDGET.minimumMs\n\n/** The rules both tasks are sent: static, byte-identical for every workspace. */\nexport const AI_EXPERIMENT_RULES = [\n 'You work on A/B tests for a website builder. A test shows visitors one of several variants of the same thing and counts which converts best. You never start, stop or change a test: you write variants for a person to put into the A/B testing card, and you put a result someone else measured into plain words.',\n '',\n `When you are given copy under test, call ${AI_EXPERIMENT_VARIANTS_TOOL_NAME} once:`,\n `- Answer with between ${AI_EXPERIMENT_MIN_VARIANTS} and ${AI_EXPERIMENT_MAX_VARIANTS} variants. The first is the copy as it stands, unchanged, so the test has something to measure against.`,\n '- Each later variant changes ONE idea — the promise, the specificity, the length, the call to action — so a result says which idea won.',\n '- No two variants say the same thing in different words.',\n '- Write plain text: no HTML, no markdown, no emoji, no fences.',\n '- Never invent a fact, a price, a name, a statistic or a guarantee the copy under test did not give you.',\n '- Write in the language of the copy under test.',\n '',\n `When you are given a result, call ${AI_EXPERIMENT_EXPLAIN_TOOL_NAME} once:`,\n '- The request states the verdict. It was decided from the counts before you were asked, and it is not yours to revise.',\n '- Where the verdict names no winner, write nothing that says or implies one: no variant is ahead, none is better, nothing is significant, and you recommend nothing. Say what the figures show and why they do not settle it.',\n '- Where the verdict names a winner, name that variant and no other.',\n '- Every number you write appears in the figures you were given, as they show it or rounded. Never compute one.',\n '- Plain sentences: no markdown, no headings, no lists.',\n '- Write in the language of the brief.',\n].join('\\n')\n\nexport const AI_JOB_EXPERIMENT_SYSTEM: AiSystemBlock[] = [\n { text: `${AI_EXPERIMENT_RULES}\\n\\n${AI_ACCEPTABLE_USE_BLOCK}`, cacheBreakpoint: true },\n]\n\nconst str = (value: unknown): string => (typeof value === 'string' ? value.trim() : '')\n\n/** What the test varies, in the words the prompt names it by. */\nconst TARGET_NOUN: Record<AiExperimentTarget, string> = {\n screen: 'a page',\n section: 'one section of a page',\n email: 'an email',\n}\n\n/** The user turn for variants: the brief, what varies, and the copy as it stands. */\nexport function aiExperimentVariantsPrompt(input: {\n brief: string\n target: AiExperimentTarget\n subject: string\n goal: string\n}): string {\n return [\n `Brief: ${input.brief}`,\n `The test varies ${TARGET_NOUN[input.target]}.`,\n ...(input.goal ? [`It is trying to move: ${input.goal}`] : []),\n '',\n 'The copy under test, as it stands:',\n input.subject,\n ].join('\\n')\n}\n\n/** One arm as the explanation prompt shows it. */\nfunction armText(arm: AiExperimentArm, index: number): string {\n const rate = arm.rate === null ? 'no rate' : `${arm.rate}%`\n const against =\n index === 0\n ? 'the first variant, which the others are compared against'\n : [\n arm.lift === null ? 'lift not measurable' : `lift ${arm.lift}%`,\n arm.confidence === null\n ? 'confidence not measurable'\n : `confidence ${arm.confidence}%`,\n ].join(', ')\n return `- ${arm.id}: shown ${arm.exposures}, converted ${arm.conversions}, rate ${rate} (${against})`\n}\n\n/** What the verdict tells the model it may say. */\nexport function aiExperimentVerdictText(reading: AiExperimentReading): string {\n if (reading.verdict === 'winner') {\n return `VERDICT: ${reading.winnerId} is ahead of the first variant by more than chance explains, at the ${reading.threshold}% confidence this test is called at. Name ${reading.winnerId} and no other variant.`\n }\n if (reading.verdict === 'control') {\n return `VERDICT: every other variant is behind the first one, ${reading.winnerId}, by more than chance explains. Name ${reading.winnerId} and no other variant.`\n }\n return [\n `VERDICT: THERE IS NO WINNER — ${reading.reasons.join('; ')}.`,\n 'Say what the figures show and why they do not settle it. Name no winner, say no variant is ahead, better, winning or significant, and recommend no variant.',\n `Leave winner and next empty; what to do next is already decided: ${aiExperimentNextStep(reading.verdict)}`,\n ].join('\\n')\n}\n\n/** The user turn for an explanation: the test, its arms, and the verdict. */\nexport function aiExperimentExplainPrompt(input: {\n brief: string\n reading: AiExperimentReading\n}): string {\n return [\n ...(input.brief ? [`Brief: ${input.brief}`] : []),\n `Test: ${input.reading.test}`,\n 'Figures, totals since the test started:',\n ...input.reading.arms.map(armText),\n '',\n aiExperimentVerdictText(input.reading),\n ].join('\\n')\n}\n\n/** The proposal an answer becomes, as the job's output carries it. */\nfunction experimentOutput(\n job: Pick<AiJob, '$id' | 'hostId' | 'inputs'>,\n label: string,\n proposal: Record<string, unknown>,\n): AiJobOutput {\n return {\n resource: 'experiment',\n // The test the surface named, so a person opens the one they asked about;\n // a variants job for a test that does not exist yet names the job itself.\n id: str(job.inputs?.['experimentId']) || job.$id,\n versionId: null,\n hostId: job.hostId ?? null,\n hostSubdomain: str(job.inputs?.['hostSubdomain']) || null,\n label,\n proposal,\n }\n}\n\n/**\n * The A/B test results for this job's site, or `null` when the workspace has\n * no such reader. The insight path's own resolver is what decides whether a\n * reader may be read here — the plan's entitlement, the owning plugin's\n * release flag, and whether that plugin runs on this workspace and this site\n * — so this asks it rather than restating any of it.\n */\nasync function readExperimentFigures(\n context: Pick<AiJobStepContext, 'firestore' | 'org' | 'now'>,\n place: { orgId: string; hostId: string | null; uid: string | null },\n): Promise<{ table: Parameters<typeof readAiExperimentArms>[0]; refusals: string[] } | null> {\n if (!place.hostId) return null\n const snapshot = await context.firestore.collection('hosts').doc(place.hostId).get()\n const host = snapshot.exists ? ((snapshot.data() ?? {}) as Record<string, unknown>) : null\n if (!host || host['orgId'] !== place.orgId) return null\n const readers = await aiInsightReaders({\n orgId: place.orgId,\n hostId: place.hostId,\n org: context.org ?? null,\n host,\n surface: 'analytics',\n })\n const experiments = readers.filter(({ reader }) => reader.id === AI_EXPERIMENT_READER_ID)\n if (!experiments.length) return null\n const read = await readAiInsightTables(\n experiments,\n [{ reader: AI_EXPERIMENT_READER_ID, days: AI_EXPERIMENT_READ_DAYS, params: {} }],\n { orgId: place.orgId, hostId: place.hostId, uid: place.uid, now: context.now },\n 1,\n )\n return { table: read.tables[0] ?? null, refusals: read.refusals }\n}\n\nexport const runAiJobExperimentStep: AiJobStepRunner = async (\n context: AiJobStepContext,\n) => {\n const { job, signal } = context\n const model = context.modelFor?.('job.experiment') ?? aiModelForStep('job.experiment')\n const maxTokens = AI_JOB_EXPERIMENT_STEP_BUDGET.maxTokens(model)\n const task = aiExperimentTask(job.inputs)\n const spent = (result: { usage: unknown; estCostUsd: number; stopReason: string | null }) => ({\n usage: result.usage as AiJobStepOutcome['usage'],\n estCostUsd: result.estCostUsd,\n model,\n stopReason: result.stopReason,\n effort: null,\n })\n const stop = (failure: string): AiJobStepOutcome => ({\n outputs: [],\n usage: { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 },\n estCostUsd: 0,\n model,\n stopReason: null,\n failure,\n })\n\n if (!task) return stop(AI_EXPERIMENT_NO_TASK_COPY)\n if (!job.hostId) return stop(AI_EXPERIMENT_NO_SITE_COPY)\n\n const ask = (messages: AiMessage[], tool: ReturnType<typeof aiExperimentExplainTool>) =>\n runAiRequest({\n model,\n system: AI_JOB_EXPERIMENT_SYSTEM,\n messages,\n tools: [tool],\n maxTokens,\n ...(AI_ROUTING_TABLE['job.experiment'].thinking\n ? { thinking: AI_ROUTING_TABLE['job.experiment'].thinking }\n : {}),\n stream: false,\n ...(signal ? { signal } : {}),\n })\n\n if (task === 'variants') {\n const target = aiExperimentTarget(job.inputs)\n if (!target) return stop(AI_EXPERIMENT_NO_TARGET_COPY)\n const subject = str(job.inputs?.['subject']).slice(0, AI_EXPERIMENT_SUBJECT_MAX_CHARS)\n if (!subject) return stop(AI_EXPERIMENT_NO_SUBJECT_COPY)\n const tool = aiExperimentVariantsTool(target)\n let messages: AiMessage[] = [\n {\n role: 'user',\n content: aiExperimentVariantsPrompt({\n brief: job.brief,\n target,\n subject,\n goal: str(job.inputs?.['goal']),\n }),\n },\n ]\n let last: AiJobStepOutcome | null = null\n for (let attempt = 0; attempt < AI_GENERATION_MAX_ATTEMPTS; attempt += 1) {\n const result = await ask(messages, tool)\n if (result.kind === 'refusal') {\n return { outputs: [], ...spent(result), refused: true }\n }\n const parsed = parseAiExperimentVariants(\n result.toolUse.find((use) => use.name === AI_EXPERIMENT_VARIANTS_TOOL_NAME)?.input,\n )\n const checked = checkAiExperimentVariants(parsed, target)\n last = { outputs: [], ...spent(result), failure: AI_EXPERIMENT_NO_VARIANTS_COPY }\n if (checked) {\n if (checked.findings.length) {\n console.info('ai experiment variants dropped', {\n jobId: job.$id,\n findings: checked.findings,\n })\n }\n return {\n outputs: [variantsOutput(job, target, checked.proposal)],\n ...spent(result),\n }\n }\n messages = [\n ...messages,\n { role: 'assistant', content: `Answered with ${AI_EXPERIMENT_VARIANTS_TOOL_NAME}.` },\n {\n role: 'user',\n content:\n `Those variants could not be used. Answer again with ${AI_EXPERIMENT_VARIANTS_TOOL_NAME}: ` +\n `at least ${AI_EXPERIMENT_MIN_VARIANTS} variants, each with copy of its own, none repeating ` +\n 'another, and plain text throughout.',\n },\n ]\n }\n return last ?? stop(AI_EXPERIMENT_NO_VARIANTS_COPY)\n }\n\n const test = str(job.inputs?.['test'])\n if (!test) return stop(AI_EXPERIMENT_NO_TEST_COPY)\n const figures = await readExperimentFigures(context, {\n orgId: job.orgId,\n hostId: job.hostId,\n uid: job.createdBy,\n })\n if (!figures) return stop(AI_EXPERIMENT_NO_READER_COPY)\n if (!figures.table) {\n if (figures.refusals.length) {\n console.warn('ai experiment figures refused', { jobId: job.$id, refusals: figures.refusals })\n }\n return stop(AI_EXPERIMENT_NO_FIGURES_COPY)\n }\n const reading = readAiExperimentResult(test, readAiExperimentArms(figures.table, test))\n // Nothing to explain, and nothing spent finding that out: the verdict was\n // reached from the figures alone.\n if (reading.verdict === 'unreadable') return stop(AI_EXPERIMENT_UNREADABLE_RESULT_COPY)\n\n const result = await ask(\n [{ role: 'user', content: aiExperimentExplainPrompt({ brief: job.brief, reading }) }],\n aiExperimentExplainTool(),\n )\n if (result.kind === 'refusal') return { outputs: [], ...spent(result), refused: true }\n const explained = checkAiExperimentExplanation(\n parseAiExperimentExplanation(\n result.toolUse.find((use) => use.name === AI_EXPERIMENT_EXPLAIN_TOOL_NAME)?.input,\n ),\n reading,\n )\n if (!explained) {\n return { outputs: [], ...spent(result), failure: AI_EXPERIMENT_NO_EXPLANATION_COPY }\n }\n if (explained.findings.length) {\n console.info('ai experiment explanation cut back to its reading', {\n jobId: job.$id,\n verdict: reading.verdict,\n findings: explained.findings,\n })\n }\n return { outputs: [explanationOutput(job, reading, explained)], ...spent(result) }\n}\n\n/** A variants answer as the job's output. */\nfunction variantsOutput(\n job: Pick<AiJob, '$id' | 'hostId' | 'inputs'>,\n target: AiExperimentTarget,\n proposal: AiExperimentVariantsProposal,\n): AiJobOutput {\n return {\n ...experimentOutput(job, `${proposal.variants.length} variants to test`, {\n task: 'variants',\n target,\n goal: proposal.goal,\n variants: proposal.variants,\n }),\n note: 'Put these into A/B testing to start the test; nothing has been changed on the site.',\n }\n}\n\n/** An explanation as the job's output, carrying the verdict code reached. */\nfunction explanationOutput(\n job: Pick<AiJob, '$id' | 'hostId' | 'inputs'>,\n reading: AiExperimentReading,\n explained: AiExperimentExplanation,\n): AiJobOutput {\n return experimentOutput(job, explained.test || 'A/B test result', {\n task: 'explain',\n verdict: explained.verdict,\n headline: explained.headline,\n points: explained.points,\n // Only ever the reading's arm: an explanation carries no winner the\n // figures did not support, whatever the answer said.\n winnerId: aiExperimentVerdictNamesWinner(reading.verdict) ? explained.winnerId : null,\n next: explained.next,\n threshold: reading.threshold,\n arms: reading.arms,\n })\n}\n\n/**\n * Whether an experiment job may run here: a site of the job's own org, a task\n * the step runs, and A/B testing available on it — which is the results\n * reader being one this workspace may read, asked of the owning plugin rather\n * than restated.\n */\nexport async function aiExperimentAdmissionRefusal(\n context: AiJobAdmissionContext,\n): Promise<AiJobAdmissionRefusal | null> {\n if (!aiExperimentTask(context.inputs)) {\n return { status: 400, error: AI_EXPERIMENT_NO_TASK_COPY }\n }\n if (!context.hostId) return { status: 400, error: AI_EXPERIMENT_NO_SITE_COPY }\n const snapshot = await context.firestore.collection('hosts').doc(context.hostId).get()\n const host = snapshot.exists ? ((snapshot.data() ?? {}) as Record<string, unknown>) : null\n if (!host || host['orgId'] !== context.orgId) {\n return { status: 404, error: 'Unknown site' }\n }\n const readers = await aiInsightReaders({\n orgId: context.orgId,\n hostId: context.hostId,\n org: context.org,\n host,\n surface: 'analytics',\n })\n return readers.some(({ reader }) => reader.id === AI_EXPERIMENT_READER_ID)\n ? null\n : { status: 403, error: AI_EXPERIMENT_NO_READER_COPY }\n}\n\n/**\n * The experiment kind's registrations, called by the console surface\n * (`registerAiJobKinds` in `server.ts`), never made by importing this module\n * (AGL-3025).\n */\nexport function registerAiExperimentJob(): void {\n registerAiJobStep('experiment', runAiJobExperimentStep, {\n minimumMs: AI_JOB_EXPERIMENT_STEP_MINIMUM_MS,\n })\n registerAiJobAdmission('experiment', aiExperimentAdmissionRefusal)\n}\n"],"names":["AI_EXPERIMENT_FIGURE_READER","AI_EXPERIMENT_MAX_VARIANTS","AI_EXPERIMENT_MIN_VARIANTS","AI_EXPERIMENT_SUBJECT_MAX_CHARS","aiExperimentNextStep","aiExperimentTarget","aiExperimentTask","aiExperimentVerdictNamesWinner","checkAiExperimentExplanation","checkAiExperimentVariants","readAiExperimentArms","readAiExperimentResult","AI_STEP_TIERS","AI_ROUTING_TABLE","aiModelForStep","AI_ACCEPTABLE_USE_BLOCK","runAiRequest","AI_GENERATION_MAX_ATTEMPTS","aiInsightReaders","readAiInsightTables","registerAiJobAdmission","aiJobStepBudget","registerAiJobStep","AI_EXPERIMENT_EXPLAIN_TOOL_NAME","AI_EXPERIMENT_VARIANTS_TOOL_NAME","aiExperimentExplainTool","aiExperimentVariantsTool","parseAiExperimentExplanation","parseAiExperimentVariants","AI_EXPERIMENT_READER_ID","AI_EXPERIMENT_READ_DAYS","AI_EXPERIMENT_NO_TASK_COPY","AI_EXPERIMENT_NO_TARGET_COPY","AI_EXPERIMENT_NO_SITE_COPY","AI_EXPERIMENT_NO_READER_COPY","AI_EXPERIMENT_NO_SUBJECT_COPY","AI_EXPERIMENT_NO_TEST_COPY","AI_EXPERIMENT_NO_FIGURES_COPY","AI_EXPERIMENT_UNREADABLE_RESULT_COPY","AI_EXPERIMENT_NO_VARIANTS_COPY","AI_EXPERIMENT_NO_EXPLANATION_COPY","AI_JOB_EXPERIMENT_MAX_TOKENS","maxTokens","AI_JOB_EXPERIMENT_STEP_BUDGET","tier","attempts","lookups","AI_JOB_EXPERIMENT_STEP_MINIMUM_MS","minimumMs","AI_EXPERIMENT_RULES","join","AI_JOB_EXPERIMENT_SYSTEM","text","cacheBreakpoint","str","value","trim","TARGET_NOUN","screen","section","email","aiExperimentVariantsPrompt","input","brief","target","goal","subject","armText","arm","index","rate","against","lift","confidence","id","exposures","conversions","aiExperimentVerdictText","reading","verdict","winnerId","threshold","reasons","aiExperimentExplainPrompt","test","arms","map","experimentOutput","job","label","proposal","resource","inputs","$id","versionId","hostId","hostSubdomain","readExperimentFigures","context","place","snapshot","read","firestore","collection","doc","get","host","exists","data","orgId","readers","org","surface","experiments","filter","reader","length","days","params","uid","now","table","tables","refusals","runAiJobExperimentStep","result","signal","model","modelFor","task","spent","usage","estCostUsd","stopReason","effort","stop","failure","outputs","inputTokens","outputTokens","cacheReadTokens","cacheWriteTokens","ask","messages","tool","system","tools","thinking","stream","slice","role","content","last","attempt","kind","refused","parsed","toolUse","find","use","name","checked","findings","console","info","jobId","variantsOutput","figures","createdBy","warn","explained","explanationOutput","variants","note","headline","points","next","aiExperimentAdmissionRefusal","status","error","some","registerAiExperimentJob"],"mappings":"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"}
|