@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,1151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
17
|
+
import { validateHostAction } from "@aglyn/aglyn/app-utils/actions";
|
|
18
|
+
import { aiAutomationDraft, emptyAiAutomationRecords } from "../model/ai-automation-draft.js";
|
|
19
|
+
import { AI_BUILD_PLAN_CREATE_KINDS } from "../model/ai-build-plan.js";
|
|
20
|
+
import { aiUnrestrictedPlanCapabilities } from "../model/ai-plan-capabilities.js";
|
|
21
|
+
import { AI_EXPERIMENT_BODY_MAX_CHARS, AI_EXPERIMENT_HEADLINE_MAX_CHARS, AI_EXPERIMENT_LINE_MAX_CHARS, AI_EXPERIMENT_MAX_POINTS, AI_EXPERIMENT_NAME_MAX_CHARS, AI_EXPERIMENT_NEXT_MAX_CHARS, AI_EXPERIMENT_POINT_MAX_CHARS, AI_EXPERIMENT_RATIONALE_MAX_CHARS, aiExperimentVariantFields, checkAiExperimentExplanation, checkAiExperimentVariants, readAiExperimentResult } from "../model/ai-experiment.js";
|
|
22
|
+
import { parseAiExperimentExplanation, parseAiExperimentVariants } from "../tools/ai-experiment-tool.js";
|
|
23
|
+
import { aiComponentCheck } from "../jobs/ai-job-component-checks.js";
|
|
24
|
+
import { aiProductMerchantWords } from "../model/ai-products.js";
|
|
25
|
+
import { checkAiCatalog, checkAiCategories, checkAiProductCopy } from "../tools/ai-products-tool.js";
|
|
26
|
+
import { aiCrmEmailMergeFields, aiCrmImportFields, aiCrmRecordCheckContext, checkAiCrmEmail, checkAiCrmMapping, checkAiCrmRecord } from "../tools/ai-crm-tool.js";
|
|
27
|
+
import { parseAiThemeToolInput } from "../tools/ai-theme-tool.js";
|
|
28
|
+
import { AI_AUTOMATION_OVERSIZE_CODES, AI_AUTOMATION_UNREADABLE_CODES, readAiAutomationAnswer, readAiWorkflowExplanation } from "../tools/ai-workflow-tool.js";
|
|
29
|
+
import { parseAiInsightAnswer } from "../tools/ai-insight-tool.js";
|
|
30
|
+
import { checkAiInsightAnswer } from "./ai-insight-check.js";
|
|
31
|
+
import { aiDeviceAuditFindings } from "./ai-device-audit.js";
|
|
32
|
+
import { aiAnswerTree, aiDoctrinePlanCheck, aiDoctrineTreeCheck, aiDoctrineTreeContext } from "./ai-doctrine.js";
|
|
33
|
+
import { AI_SEO_DESCRIPTION_MAX, AI_SEO_TITLE_MAX, detectOffVoiceCopy, detectPublishIntent } from "./ai-doctrine-validators.js";
|
|
34
|
+
import { AI_TEXT_LIMITS } from "./ai-palette.js";
|
|
35
|
+
import { expandAiRepeatedItems } from "./ai-repeated-items.js";
|
|
36
|
+
export const AI_EVAL_KINDS = [
|
|
37
|
+
'page',
|
|
38
|
+
'template',
|
|
39
|
+
'component',
|
|
40
|
+
'layout',
|
|
41
|
+
'form',
|
|
42
|
+
'email',
|
|
43
|
+
'section',
|
|
44
|
+
'seo',
|
|
45
|
+
'product',
|
|
46
|
+
'catalog',
|
|
47
|
+
'categories',
|
|
48
|
+
'theme',
|
|
49
|
+
'element',
|
|
50
|
+
'blog',
|
|
51
|
+
'text',
|
|
52
|
+
'chat',
|
|
53
|
+
'workflow',
|
|
54
|
+
'insight',
|
|
55
|
+
'crm',
|
|
56
|
+
'experiment'
|
|
57
|
+
];
|
|
58
|
+
/** The document kind a tree kind is held to; a section rewrite is one reusable block. */ export const AI_EVAL_TREE_OUTPUT = {
|
|
59
|
+
page: 'page',
|
|
60
|
+
template: 'template',
|
|
61
|
+
component: 'component',
|
|
62
|
+
layout: 'layout',
|
|
63
|
+
form: 'form',
|
|
64
|
+
email: 'email',
|
|
65
|
+
section: 'component'
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Whether a kind's answer is a document a site renders, and so is held to
|
|
69
|
+
* every device width (AGL-3020). An email is not: its column is fixed at 600px
|
|
70
|
+
* by the medium, which rule 12 exempts it for.
|
|
71
|
+
*/ export function aiEvalRendersAtDeviceWidths(kind) {
|
|
72
|
+
const output = AI_EVAL_TREE_OUTPUT[kind];
|
|
73
|
+
return output !== undefined && output !== 'email';
|
|
74
|
+
}
|
|
75
|
+
/** The site a case's job runs on when the case describes no inventory. */ export const AI_EVAL_SITE_ID = 'eval-site';
|
|
76
|
+
/** What an automation brief's workspace can run when the case does not say: everything. */ export const AI_EVAL_AUTOMATION_CAPABILITIES = {
|
|
77
|
+
crm: true,
|
|
78
|
+
webhooks: true,
|
|
79
|
+
bookings: true
|
|
80
|
+
};
|
|
81
|
+
/** A fixture file a case's media names: a relative path to a picture, never out of its folder. */ const AI_EVAL_MEDIA_FILE = /^(?!.*(?:^|\/)\.\.?(?:\/|$))[A-Za-z0-9][A-Za-z0-9._/-]*\.(?:jpe?g|png|webp|gif|avif)$/;
|
|
82
|
+
/**
|
|
83
|
+
* The floors, per kind. Every reference answer must pass, because each was
|
|
84
|
+
* written to; the mean floor leaves room for a rubric grade of four on an
|
|
85
|
+
* answer that passes every mechanical check. Recorded answers are held to
|
|
86
|
+
* the same floors, and a lever that lowers a kind below its floor does not
|
|
87
|
+
* ship.
|
|
88
|
+
*/ export const AI_EVAL_FLOORS = {
|
|
89
|
+
page: {
|
|
90
|
+
passRate: 1,
|
|
91
|
+
meanScore: 0.9
|
|
92
|
+
},
|
|
93
|
+
template: {
|
|
94
|
+
passRate: 1,
|
|
95
|
+
meanScore: 0.9
|
|
96
|
+
},
|
|
97
|
+
component: {
|
|
98
|
+
passRate: 1,
|
|
99
|
+
meanScore: 0.9
|
|
100
|
+
},
|
|
101
|
+
layout: {
|
|
102
|
+
passRate: 1,
|
|
103
|
+
meanScore: 0.9
|
|
104
|
+
},
|
|
105
|
+
form: {
|
|
106
|
+
passRate: 1,
|
|
107
|
+
meanScore: 0.9
|
|
108
|
+
},
|
|
109
|
+
email: {
|
|
110
|
+
passRate: 1,
|
|
111
|
+
meanScore: 0.9
|
|
112
|
+
},
|
|
113
|
+
section: {
|
|
114
|
+
passRate: 1,
|
|
115
|
+
meanScore: 0.9
|
|
116
|
+
},
|
|
117
|
+
seo: {
|
|
118
|
+
passRate: 1,
|
|
119
|
+
meanScore: 0.9
|
|
120
|
+
},
|
|
121
|
+
product: {
|
|
122
|
+
passRate: 1,
|
|
123
|
+
meanScore: 0.9
|
|
124
|
+
},
|
|
125
|
+
catalog: {
|
|
126
|
+
passRate: 1,
|
|
127
|
+
meanScore: 0.9
|
|
128
|
+
},
|
|
129
|
+
categories: {
|
|
130
|
+
passRate: 1,
|
|
131
|
+
meanScore: 0.9
|
|
132
|
+
},
|
|
133
|
+
theme: {
|
|
134
|
+
passRate: 1,
|
|
135
|
+
meanScore: 0.9
|
|
136
|
+
},
|
|
137
|
+
element: {
|
|
138
|
+
passRate: 1,
|
|
139
|
+
meanScore: 0.9
|
|
140
|
+
},
|
|
141
|
+
blog: {
|
|
142
|
+
passRate: 1,
|
|
143
|
+
meanScore: 0.9
|
|
144
|
+
},
|
|
145
|
+
text: {
|
|
146
|
+
passRate: 1,
|
|
147
|
+
meanScore: 0.9
|
|
148
|
+
},
|
|
149
|
+
chat: {
|
|
150
|
+
passRate: 1,
|
|
151
|
+
meanScore: 0.9
|
|
152
|
+
},
|
|
153
|
+
workflow: {
|
|
154
|
+
passRate: 1,
|
|
155
|
+
meanScore: 0.9
|
|
156
|
+
},
|
|
157
|
+
insight: {
|
|
158
|
+
passRate: 1,
|
|
159
|
+
meanScore: 0.9
|
|
160
|
+
},
|
|
161
|
+
crm: {
|
|
162
|
+
passRate: 1,
|
|
163
|
+
meanScore: 0.9
|
|
164
|
+
},
|
|
165
|
+
experiment: {
|
|
166
|
+
passRate: 1,
|
|
167
|
+
meanScore: 0.9
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
/** A rubric passes at this mean, with no criterion below three. */ export const AI_EVAL_RUBRIC_PASS_MEAN = 3.5;
|
|
171
|
+
/** How long a blog body may run: the blog mode's output ceiling, at four characters a token. */ export const AI_EVAL_BLOG_MAX_CHARS = 8000;
|
|
172
|
+
/** How long a job's copy may run when the brief implies no length: the text step's own rule. */ export const AI_EVAL_TEXT_MAX_WORDS = 150;
|
|
173
|
+
/** How long a chat answer may run: the chat door's output ceiling, at four characters a token. */ export const AI_EVAL_CHAT_MAX_CHARS = 4000;
|
|
174
|
+
const isRecord = (value)=>typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
175
|
+
const codes = (violations)=>violations.map((violation)=>violation.code);
|
|
176
|
+
/**
|
|
177
|
+
* The sections a page answer's plan lays out, by name, which a link on the
|
|
178
|
+
* page may take a visitor to as the page step lets it (AGL-3097); empty for an
|
|
179
|
+
* answer of another kind, or with no plan to read them from.
|
|
180
|
+
*/ function planSections(evalCase, plan) {
|
|
181
|
+
const screens = evalCase.kind === 'page' && isRecord(plan) && Array.isArray(plan['screens']) ? plan['screens'] : [];
|
|
182
|
+
const sections = isRecord(screens[0]) && Array.isArray(screens[0]['sections']) ? screens[0]['sections'] : [];
|
|
183
|
+
return sections.flatMap((section)=>isRecord(section) && typeof section['name'] === 'string' ? [
|
|
184
|
+
section['name']
|
|
185
|
+
] : []);
|
|
186
|
+
}
|
|
187
|
+
function readTree(evalCase, outputKind, answer, plan) {
|
|
188
|
+
var _evalCase_capabilities;
|
|
189
|
+
const inline = ((_evalCase_capabilities = evalCase.capabilities) == null ? void 0 : _evalCase_capabilities.reusableComponents) === false;
|
|
190
|
+
let input = isRecord(answer) ? answer : {
|
|
191
|
+
tree: answer
|
|
192
|
+
};
|
|
193
|
+
// A component answer that declares its properties binds them in its tree,
|
|
194
|
+
// and is held to the component step's own checks as that step holds it
|
|
195
|
+
// (AGL-3054).
|
|
196
|
+
const declaresProps = evalCase.kind === 'component' && Array.isArray(input['props']);
|
|
197
|
+
const sections = planSections(evalCase, plan);
|
|
198
|
+
const check = aiDoctrineTreeCheck(outputKind, aiDoctrineTreeContext(evalCase.inventory, _extends({}, evalCase.assets ? {
|
|
199
|
+
assets: evalCase.assets
|
|
200
|
+
} : {}, {
|
|
201
|
+
framing: evalCase.framing
|
|
202
|
+
}, inline ? {
|
|
203
|
+
reusableComponents: false
|
|
204
|
+
} : {}, declaresProps ? {
|
|
205
|
+
definesComponent: true
|
|
206
|
+
} : {}, sections.length ? {
|
|
207
|
+
pageSections: sections
|
|
208
|
+
} : {})));
|
|
209
|
+
// A page's repeated item written once is drawn into its copies first, as the
|
|
210
|
+
// page step draws it, and refused as the page step refuses it (AGL-3053).
|
|
211
|
+
if (evalCase.kind === 'page') {
|
|
212
|
+
const drawn = expandAiRepeatedItems(aiAnswerTree(input), {
|
|
213
|
+
inline,
|
|
214
|
+
noun: 'page'
|
|
215
|
+
});
|
|
216
|
+
if (drawn.ok === false) return {
|
|
217
|
+
input,
|
|
218
|
+
declaresProps,
|
|
219
|
+
undrawn: drawn.violations,
|
|
220
|
+
result: null
|
|
221
|
+
};
|
|
222
|
+
if (drawn.items) input = {
|
|
223
|
+
tree: drawn.tree
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
input,
|
|
228
|
+
declaresProps,
|
|
229
|
+
undrawn: null,
|
|
230
|
+
result: check(input)
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* The tree an answer of a tree kind is checked as — a page's repeated items
|
|
235
|
+
* drawn into their copies — or `null` when it cannot be read as one. The
|
|
236
|
+
* device audit renders exactly this tree (AGL-3020).
|
|
237
|
+
*/ export function aiEvalAnswerTree(evalCase, answer) {
|
|
238
|
+
var _ref;
|
|
239
|
+
var _readTree_result;
|
|
240
|
+
const outputKind = AI_EVAL_TREE_OUTPUT[evalCase.kind];
|
|
241
|
+
return outputKind ? (_ref = (_readTree_result = readTree(evalCase, outputKind, answer).result) == null ? void 0 : _readTree_result.value) != null ? _ref : null : null;
|
|
242
|
+
}
|
|
243
|
+
function checkTree(evalCase, outputKind, answer, plan) {
|
|
244
|
+
const { input, declaresProps, undrawn, result } = readTree(evalCase, outputKind, answer, plan);
|
|
245
|
+
if (undrawn || !result) {
|
|
246
|
+
return {
|
|
247
|
+
readable: false,
|
|
248
|
+
rules: false,
|
|
249
|
+
budget: false,
|
|
250
|
+
findings: codes(undrawn != null ? undrawn : [])
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const violations = [
|
|
254
|
+
...result.violations,
|
|
255
|
+
...declaresProps && result.value ? aiComponentCheck({
|
|
256
|
+
inventory: evalCase.inventory,
|
|
257
|
+
plan: null,
|
|
258
|
+
onProps: ()=>undefined
|
|
259
|
+
})(result.value, input) : []
|
|
260
|
+
];
|
|
261
|
+
const budget = violations.filter((violation)=>violation.rule === 17);
|
|
262
|
+
const rules = violations.filter((violation)=>violation.rule !== 17);
|
|
263
|
+
return {
|
|
264
|
+
readable: result.value !== null,
|
|
265
|
+
rules: result.value !== null && rules.length === 0,
|
|
266
|
+
budget: result.value !== null && budget.length === 0,
|
|
267
|
+
findings: codes(violations)
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
const FENCE = /```/;
|
|
271
|
+
const PREAMBLE = /^\s*(?:sure|certainly|of course|here(?:'s| is| are))\b/i;
|
|
272
|
+
const QUOTED = RegExp("^\\s*[\"“'].*[\"”']\\s*$", "s");
|
|
273
|
+
const MARKUP = /<\/?[a-z][^>]*>/i;
|
|
274
|
+
function words(text) {
|
|
275
|
+
return text.trim().split(/\s+/).filter(Boolean).length;
|
|
276
|
+
}
|
|
277
|
+
/** Copy answered as text: there, unwrapped, in the site's voice, within its ceiling. */ function checkCopy(evalCase, answer, limits, own = ()=>[]) {
|
|
278
|
+
var _evalCase_maxChars, _evalCase_maxWords;
|
|
279
|
+
if (typeof answer !== 'string' || !answer.trim()) {
|
|
280
|
+
return {
|
|
281
|
+
readable: false,
|
|
282
|
+
rules: false,
|
|
283
|
+
budget: false,
|
|
284
|
+
findings: [
|
|
285
|
+
'copy-missing'
|
|
286
|
+
]
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
const text = answer.trim();
|
|
290
|
+
const unreadable = [
|
|
291
|
+
...FENCE.test(text) ? [
|
|
292
|
+
'copy-fenced'
|
|
293
|
+
] : [],
|
|
294
|
+
...PREAMBLE.test(text) ? [
|
|
295
|
+
'copy-preamble'
|
|
296
|
+
] : [],
|
|
297
|
+
...QUOTED.test(text) ? [
|
|
298
|
+
'copy-quoted'
|
|
299
|
+
] : []
|
|
300
|
+
];
|
|
301
|
+
const broken = [
|
|
302
|
+
...codes(detectOffVoiceCopy([
|
|
303
|
+
{
|
|
304
|
+
at: 'answer',
|
|
305
|
+
text
|
|
306
|
+
}
|
|
307
|
+
], evalCase.framing)),
|
|
308
|
+
...MARKUP.test(text) ? [
|
|
309
|
+
'copy-markup'
|
|
310
|
+
] : [],
|
|
311
|
+
...own(text)
|
|
312
|
+
];
|
|
313
|
+
const maxChars = (_evalCase_maxChars = evalCase.maxChars) != null ? _evalCase_maxChars : limits.maxChars;
|
|
314
|
+
const maxWords = (_evalCase_maxWords = evalCase.maxWords) != null ? _evalCase_maxWords : limits.maxWords;
|
|
315
|
+
const over = [
|
|
316
|
+
...maxChars !== undefined && text.length > maxChars ? [
|
|
317
|
+
'copy-over-chars'
|
|
318
|
+
] : [],
|
|
319
|
+
...maxWords !== undefined && words(text) > maxWords ? [
|
|
320
|
+
'copy-over-words'
|
|
321
|
+
] : []
|
|
322
|
+
];
|
|
323
|
+
return {
|
|
324
|
+
readable: unreadable.length === 0,
|
|
325
|
+
rules: broken.length === 0,
|
|
326
|
+
budget: over.length === 0,
|
|
327
|
+
findings: [
|
|
328
|
+
...unreadable,
|
|
329
|
+
...broken,
|
|
330
|
+
...over
|
|
331
|
+
]
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
const MARKDOWN_LINK = /\[[^\]]*\]\(([^)\s]+)\)/g;
|
|
335
|
+
/** A chat answer links only the documentation it was given and console paths. */ function chatLinks(evalCase) {
|
|
336
|
+
var _evalCase_docsUrls;
|
|
337
|
+
const allowed = new Set((_evalCase_docsUrls = evalCase.docsUrls) != null ? _evalCase_docsUrls : []);
|
|
338
|
+
return (text)=>[
|
|
339
|
+
...text.matchAll(MARKDOWN_LINK)
|
|
340
|
+
].map((match)=>match[1]).filter((url)=>!url.startsWith('/') && !allowed.has(url)).map((url)=>`chat-link-not-given:${url}`);
|
|
341
|
+
}
|
|
342
|
+
function checkBlog(evalCase, answer) {
|
|
343
|
+
const checked = checkCopy(evalCase, answer, {
|
|
344
|
+
maxChars: AI_EVAL_BLOG_MAX_CHARS
|
|
345
|
+
});
|
|
346
|
+
if (typeof answer !== 'string') return checked;
|
|
347
|
+
const head = answer.trimStart();
|
|
348
|
+
const extra = [
|
|
349
|
+
...head.startsWith('---') ? [
|
|
350
|
+
'blog-front-matter'
|
|
351
|
+
] : [],
|
|
352
|
+
.../^#\s/.test(head) ? [
|
|
353
|
+
'blog-title-line'
|
|
354
|
+
] : []
|
|
355
|
+
];
|
|
356
|
+
return extra.length ? _extends({}, checked, {
|
|
357
|
+
readable: false,
|
|
358
|
+
findings: [
|
|
359
|
+
...checked.findings,
|
|
360
|
+
...extra
|
|
361
|
+
]
|
|
362
|
+
}) : checked;
|
|
363
|
+
}
|
|
364
|
+
function checkSeo(evalCase, answer) {
|
|
365
|
+
const title = isRecord(answer) && typeof answer['title'] === 'string' ? answer['title'].trim() : '';
|
|
366
|
+
const description = isRecord(answer) && typeof answer['description'] === 'string' ? answer['description'].trim() : '';
|
|
367
|
+
if (!title || !description) {
|
|
368
|
+
return {
|
|
369
|
+
readable: false,
|
|
370
|
+
rules: false,
|
|
371
|
+
budget: false,
|
|
372
|
+
findings: [
|
|
373
|
+
'seo-field-missing'
|
|
374
|
+
]
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
const broken = [
|
|
378
|
+
...codes(detectPublishIntent(answer)),
|
|
379
|
+
...codes(detectOffVoiceCopy([
|
|
380
|
+
{
|
|
381
|
+
at: 'title',
|
|
382
|
+
text: title
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
at: 'description',
|
|
386
|
+
text: description
|
|
387
|
+
}
|
|
388
|
+
], evalCase.framing)),
|
|
389
|
+
...MARKUP.test(title) || MARKUP.test(description) ? [
|
|
390
|
+
'seo-markup'
|
|
391
|
+
] : []
|
|
392
|
+
];
|
|
393
|
+
const over = [
|
|
394
|
+
...title.length > AI_SEO_TITLE_MAX ? [
|
|
395
|
+
'seo-title-over'
|
|
396
|
+
] : [],
|
|
397
|
+
...description.length > AI_SEO_DESCRIPTION_MAX ? [
|
|
398
|
+
'seo-description-over'
|
|
399
|
+
] : []
|
|
400
|
+
];
|
|
401
|
+
return {
|
|
402
|
+
readable: true,
|
|
403
|
+
rules: broken.length === 0,
|
|
404
|
+
budget: over.length === 0,
|
|
405
|
+
findings: [
|
|
406
|
+
...broken,
|
|
407
|
+
...over
|
|
408
|
+
]
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
/** What a products check refuses an answer for, by the check it fails. */ const PRODUCTS_UNREADABLE = new Set([
|
|
412
|
+
'type',
|
|
413
|
+
'missing',
|
|
414
|
+
'option-count'
|
|
415
|
+
]);
|
|
416
|
+
const PRODUCTS_OVER_BUDGET = new Set([
|
|
417
|
+
'too-long',
|
|
418
|
+
'too-many',
|
|
419
|
+
'product-count'
|
|
420
|
+
]);
|
|
421
|
+
/**
|
|
422
|
+
* A products answer (AGL-2916), held by the check its generation is held by:
|
|
423
|
+
* a product's copy, a catalog, or categories with discounts. A finding about
|
|
424
|
+
* the answer's shape makes it unreadable, one about a length or a count is
|
|
425
|
+
* over its budget, and every other one — a claim, a price, markup, a category
|
|
426
|
+
* the request did not list — breaks a rule.
|
|
427
|
+
*/ function checkProducts(evalCase, answer) {
|
|
428
|
+
var _ref, _ref1, _evalCase_existingCategoryNames;
|
|
429
|
+
var _evalCase_product, _evalCase_product1;
|
|
430
|
+
if (!isRecord(answer)) {
|
|
431
|
+
return {
|
|
432
|
+
readable: false,
|
|
433
|
+
rules: false,
|
|
434
|
+
budget: false,
|
|
435
|
+
findings: [
|
|
436
|
+
'products-not-a-call'
|
|
437
|
+
]
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
const result = evalCase.kind === 'product' ? checkAiProductCopy(answer, {
|
|
441
|
+
categoryIds: ((_ref = (_evalCase_product = evalCase.product) == null ? void 0 : _evalCase_product.categories) != null ? _ref : []).map((category)=>category.id),
|
|
442
|
+
optionCount: (_ref1 = (_evalCase_product1 = evalCase.product) == null ? void 0 : _evalCase_product1.facts.options.length) != null ? _ref1 : 0,
|
|
443
|
+
merchantWords: evalCase.product ? aiProductMerchantWords(evalCase.product.facts) : evalCase.brief
|
|
444
|
+
}) : evalCase.kind === 'catalog' ? checkAiCatalog(answer, {
|
|
445
|
+
merchantWords: evalCase.brief
|
|
446
|
+
}) : checkAiCategories(answer, {
|
|
447
|
+
existingCategoryNames: (_evalCase_existingCategoryNames = evalCase.existingCategoryNames) != null ? _evalCase_existingCategoryNames : [],
|
|
448
|
+
merchantWords: evalCase.brief
|
|
449
|
+
});
|
|
450
|
+
const found = [
|
|
451
|
+
...codes(result.violations),
|
|
452
|
+
...codes(detectPublishIntent(answer))
|
|
453
|
+
];
|
|
454
|
+
return {
|
|
455
|
+
readable: !found.some((code)=>PRODUCTS_UNREADABLE.has(code)),
|
|
456
|
+
rules: !found.some((code)=>!PRODUCTS_UNREADABLE.has(code) && !PRODUCTS_OVER_BUDGET.has(code)),
|
|
457
|
+
budget: !found.some((code)=>PRODUCTS_OVER_BUDGET.has(code)),
|
|
458
|
+
findings: found
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
function checkTheme(evalCase, answer) {
|
|
462
|
+
if (!isRecord(answer)) {
|
|
463
|
+
return {
|
|
464
|
+
readable: false,
|
|
465
|
+
rules: false,
|
|
466
|
+
budget: false,
|
|
467
|
+
findings: [
|
|
468
|
+
'theme-not-a-call'
|
|
469
|
+
]
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
const parse = parseAiThemeToolInput(answer);
|
|
473
|
+
const changes = parse.changes.length + parse.components.length + (parse.resetComponents ? 1 : 0);
|
|
474
|
+
const broken = [
|
|
475
|
+
...codes(detectPublishIntent(answer)),
|
|
476
|
+
...codes(detectOffVoiceCopy([
|
|
477
|
+
{
|
|
478
|
+
at: 'summary',
|
|
479
|
+
text: parse.summary
|
|
480
|
+
}
|
|
481
|
+
], evalCase.framing))
|
|
482
|
+
];
|
|
483
|
+
return {
|
|
484
|
+
readable: changes > 0 && parse.dropped.length === 0,
|
|
485
|
+
rules: broken.length === 0,
|
|
486
|
+
budget: true,
|
|
487
|
+
findings: [
|
|
488
|
+
...parse.dropped.map((reason)=>`theme-dropped:${reason}`),
|
|
489
|
+
...broken
|
|
490
|
+
]
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* An automation (AGL-2919), or an explanation of one: read through the tool's
|
|
495
|
+
* own reader, and an automation also made into the document the workflows
|
|
496
|
+
* plugin stores and held to the Actions editor's validator.
|
|
497
|
+
*/ function checkWorkflow(evalCase, answer) {
|
|
498
|
+
var _evalCase_automationCapabilities, _evalCase_automationRecords;
|
|
499
|
+
if (!isRecord(answer)) {
|
|
500
|
+
return {
|
|
501
|
+
readable: false,
|
|
502
|
+
rules: false,
|
|
503
|
+
budget: false,
|
|
504
|
+
findings: [
|
|
505
|
+
'workflow-not-a-call'
|
|
506
|
+
]
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
const publish = codes(detectPublishIntent(answer));
|
|
510
|
+
if ('summary' in answer) {
|
|
511
|
+
var _answer_summary;
|
|
512
|
+
const read = readAiWorkflowExplanation(answer);
|
|
513
|
+
const lines = [
|
|
514
|
+
String((_answer_summary = answer['summary']) != null ? _answer_summary : ''),
|
|
515
|
+
...Array.isArray(answer['points']) ? answer['points'] : [],
|
|
516
|
+
...Array.isArray(answer['suggestions']) ? answer['suggestions'] : []
|
|
517
|
+
].map(String);
|
|
518
|
+
const offVoice = codes(detectOffVoiceCopy(lines.map((text, index)=>({
|
|
519
|
+
at: `line[${index}]`,
|
|
520
|
+
text
|
|
521
|
+
})), evalCase.framing));
|
|
522
|
+
const found = codes(read.violations);
|
|
523
|
+
return {
|
|
524
|
+
readable: !found.includes('explanation-shape'),
|
|
525
|
+
rules: read.value !== null && publish.length === 0 && offVoice.length === 0,
|
|
526
|
+
budget: true,
|
|
527
|
+
findings: [
|
|
528
|
+
...found,
|
|
529
|
+
...publish,
|
|
530
|
+
...offVoice
|
|
531
|
+
]
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
const capabilities = (_evalCase_automationCapabilities = evalCase.automationCapabilities) != null ? _evalCase_automationCapabilities : AI_EVAL_AUTOMATION_CAPABILITIES;
|
|
535
|
+
const read = readAiAutomationAnswer(answer, capabilities);
|
|
536
|
+
const found = codes(read.violations);
|
|
537
|
+
const unreadable = found.filter((code)=>AI_AUTOMATION_UNREADABLE_CODES.includes(code));
|
|
538
|
+
const oversize = found.filter((code)=>AI_AUTOMATION_OVERSIZE_CODES.includes(code));
|
|
539
|
+
const broken = found.filter((code)=>!unreadable.includes(code) && !oversize.includes(code));
|
|
540
|
+
const invalid = read.value && !read.value.unsupported ? validateHostAction(aiAutomationDraft(read.value, (_evalCase_automationRecords = evalCase.automationRecords) != null ? _evalCase_automationRecords : emptyAiAutomationRecords()).action) : null;
|
|
541
|
+
return {
|
|
542
|
+
readable: unreadable.length === 0,
|
|
543
|
+
rules: broken.length === 0 && publish.length === 0 && invalid === null,
|
|
544
|
+
budget: oversize.length === 0,
|
|
545
|
+
findings: [
|
|
546
|
+
...found,
|
|
547
|
+
...publish,
|
|
548
|
+
...invalid ? [
|
|
549
|
+
`workflow-invalid:${invalid}`
|
|
550
|
+
] : []
|
|
551
|
+
]
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* An insight answer held to the trace (AGL-2915): readable when it is a
|
|
556
|
+
* `submit_insights` call that keeps an insight, within the rules when no
|
|
557
|
+
* insight is left out for its numbers, its citations or its words, and within
|
|
558
|
+
* the budget when no insight runs long and there are no more than five.
|
|
559
|
+
*/ function checkInsight(evalCase, answer) {
|
|
560
|
+
var _evalCase_tables;
|
|
561
|
+
const parsed = parseAiInsightAnswer(answer);
|
|
562
|
+
if (!parsed || !parsed.insights.length) {
|
|
563
|
+
return {
|
|
564
|
+
readable: false,
|
|
565
|
+
rules: false,
|
|
566
|
+
budget: false,
|
|
567
|
+
findings: [
|
|
568
|
+
'insight-no-answer'
|
|
569
|
+
]
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
const check = checkAiInsightAnswer(parsed, (_evalCase_tables = evalCase.tables) != null ? _evalCase_tables : []);
|
|
573
|
+
const findings = check.findings.map((finding)=>finding.split(':')[0]);
|
|
574
|
+
const over = findings.filter((code)=>code === 'insight-too-long' || code === 'insight-too-many');
|
|
575
|
+
return {
|
|
576
|
+
readable: check.kept.length > 0,
|
|
577
|
+
rules: findings.length === over.length,
|
|
578
|
+
budget: over.length === 0,
|
|
579
|
+
findings: check.findings
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
/** The CRM findings that mean the answer could not be read as one, and the ones over a length. */ const CRM_UNREADABLE = new Set([
|
|
583
|
+
'type',
|
|
584
|
+
'missing'
|
|
585
|
+
]);
|
|
586
|
+
const CRM_OVER = new Set([
|
|
587
|
+
'too-long'
|
|
588
|
+
]);
|
|
589
|
+
/**
|
|
590
|
+
* A CRM answer, held by the checks the `crm` step holds it to (AGL-2917),
|
|
591
|
+
* with rule 13 and the site's voice on everything a person reads.
|
|
592
|
+
*/ function checkCrm(evalCase, answer) {
|
|
593
|
+
var _context_facts, _context_record, _context_columns;
|
|
594
|
+
const context = evalCase.crm;
|
|
595
|
+
if (!context || !isRecord(answer)) {
|
|
596
|
+
return {
|
|
597
|
+
readable: false,
|
|
598
|
+
rules: false,
|
|
599
|
+
budget: false,
|
|
600
|
+
findings: [
|
|
601
|
+
'crm-not-a-call'
|
|
602
|
+
]
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
const facts = (_context_facts = context.facts) != null ? _context_facts : {};
|
|
606
|
+
const kind = (_context_record = context.record) != null ? _context_record : 'contact';
|
|
607
|
+
const result = context.task === 'mapping' ? checkAiCrmMapping(answer, {
|
|
608
|
+
columns: (_context_columns = context.columns) != null ? _context_columns : [],
|
|
609
|
+
fields: aiCrmImportFields(facts)
|
|
610
|
+
}) : context.task === 'email' ? checkAiCrmEmail(answer, {
|
|
611
|
+
mergeFields: aiCrmEmailMergeFields(kind)
|
|
612
|
+
}) : checkAiCrmRecord(answer, aiCrmRecordCheckContext(kind, facts));
|
|
613
|
+
const own = codes(result.violations);
|
|
614
|
+
const read = (path)=>{
|
|
615
|
+
let value = answer;
|
|
616
|
+
for (const key of path)value = isRecord(value) ? value[key] : undefined;
|
|
617
|
+
return typeof value === 'string' ? value : '';
|
|
618
|
+
};
|
|
619
|
+
const samples = [
|
|
620
|
+
[
|
|
621
|
+
'summary'
|
|
622
|
+
],
|
|
623
|
+
[
|
|
624
|
+
'standing'
|
|
625
|
+
],
|
|
626
|
+
[
|
|
627
|
+
'nextStep',
|
|
628
|
+
'title'
|
|
629
|
+
],
|
|
630
|
+
[
|
|
631
|
+
'nextStep',
|
|
632
|
+
'reason'
|
|
633
|
+
],
|
|
634
|
+
[
|
|
635
|
+
'stage',
|
|
636
|
+
'reason'
|
|
637
|
+
],
|
|
638
|
+
[
|
|
639
|
+
'subject'
|
|
640
|
+
],
|
|
641
|
+
[
|
|
642
|
+
'body'
|
|
643
|
+
]
|
|
644
|
+
].map((path)=>({
|
|
645
|
+
at: path.join('.'),
|
|
646
|
+
text: read(path)
|
|
647
|
+
})).filter((sample)=>sample.text);
|
|
648
|
+
const broken = [
|
|
649
|
+
...codes(detectPublishIntent(answer)),
|
|
650
|
+
...codes(detectOffVoiceCopy(samples, evalCase.framing)),
|
|
651
|
+
...own.filter((code)=>!CRM_UNREADABLE.has(code) && !CRM_OVER.has(code))
|
|
652
|
+
];
|
|
653
|
+
return {
|
|
654
|
+
readable: !own.some((code)=>CRM_UNREADABLE.has(code)),
|
|
655
|
+
rules: broken.length === 0,
|
|
656
|
+
budget: !own.some((code)=>CRM_OVER.has(code)),
|
|
657
|
+
findings: [
|
|
658
|
+
...new Set([
|
|
659
|
+
...own,
|
|
660
|
+
...broken
|
|
661
|
+
])
|
|
662
|
+
]
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
/** What an experiment answer is refused for, by the check it fails. */ const EXPERIMENT_RULE_FINDINGS = new Set([
|
|
666
|
+
'variant-carries-markup',
|
|
667
|
+
'variant-fills-another-targets-fields',
|
|
668
|
+
'variant-repeats-another',
|
|
669
|
+
'variant-has-no-copy'
|
|
670
|
+
]);
|
|
671
|
+
/**
|
|
672
|
+
* An A/B test answer (AGL-2914), held by the checks its step holds it by.
|
|
673
|
+
*
|
|
674
|
+
* A variants answer is readable when at least two variants survive, breaks a
|
|
675
|
+
* rule when one carried markup, repeated another or answered a different
|
|
676
|
+
* target, and is over budget when a field ran past the length the card
|
|
677
|
+
* stores. A result answer is readable when an explanation survives its
|
|
678
|
+
* reading, and breaks a rule when the reading had to take a winner out of it
|
|
679
|
+
* — which is the whole point of the kind: an explanation that claims more
|
|
680
|
+
* than the figures support does not pass here.
|
|
681
|
+
*/ function checkExperiment(evalCase, answer) {
|
|
682
|
+
var _brief_test, _brief_arms;
|
|
683
|
+
const brief = evalCase.experiment;
|
|
684
|
+
if (!brief) {
|
|
685
|
+
return {
|
|
686
|
+
readable: false,
|
|
687
|
+
rules: false,
|
|
688
|
+
budget: false,
|
|
689
|
+
findings: [
|
|
690
|
+
'experiment-brief-missing'
|
|
691
|
+
]
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
if (brief.task === 'variants') {
|
|
695
|
+
var _brief_target;
|
|
696
|
+
const target = (_brief_target = brief.target) != null ? _brief_target : 'screen';
|
|
697
|
+
const parsed = parseAiExperimentVariants(answer);
|
|
698
|
+
const checked = checkAiExperimentVariants(parsed, target);
|
|
699
|
+
if (!parsed || !checked) {
|
|
700
|
+
return {
|
|
701
|
+
readable: false,
|
|
702
|
+
rules: false,
|
|
703
|
+
budget: false,
|
|
704
|
+
findings: [
|
|
705
|
+
'experiment-no-variants'
|
|
706
|
+
]
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
const fields = aiExperimentVariantFields(target);
|
|
710
|
+
const over = parsed.variants.flatMap((variant)=>[
|
|
711
|
+
...variant.name.length > AI_EXPERIMENT_NAME_MAX_CHARS ? [
|
|
712
|
+
'experiment-name-over'
|
|
713
|
+
] : [],
|
|
714
|
+
...variant.rationale.length > AI_EXPERIMENT_RATIONALE_MAX_CHARS ? [
|
|
715
|
+
'experiment-rationale-over'
|
|
716
|
+
] : [],
|
|
717
|
+
...fields.flatMap((field)=>{
|
|
718
|
+
var _variant_field;
|
|
719
|
+
return String((_variant_field = variant[field]) != null ? _variant_field : '').length > (field === 'body' ? AI_EXPERIMENT_BODY_MAX_CHARS : AI_EXPERIMENT_LINE_MAX_CHARS) ? [
|
|
720
|
+
`experiment-${field}-over`
|
|
721
|
+
] : [];
|
|
722
|
+
})
|
|
723
|
+
]);
|
|
724
|
+
const samples = checked.proposal.variants.flatMap((variant)=>fields.map((field)=>{
|
|
725
|
+
var _variant_field;
|
|
726
|
+
return {
|
|
727
|
+
at: `${variant.name}.${field}`,
|
|
728
|
+
text: String((_variant_field = variant[field]) != null ? _variant_field : '')
|
|
729
|
+
};
|
|
730
|
+
}));
|
|
731
|
+
const broken = [
|
|
732
|
+
...checked.findings.filter((finding)=>EXPERIMENT_RULE_FINDINGS.has(finding)),
|
|
733
|
+
...codes(detectPublishIntent(answer)),
|
|
734
|
+
...codes(detectOffVoiceCopy(samples.filter((sample)=>sample.text), evalCase.framing))
|
|
735
|
+
];
|
|
736
|
+
return {
|
|
737
|
+
readable: true,
|
|
738
|
+
rules: broken.length === 0,
|
|
739
|
+
budget: over.length === 0,
|
|
740
|
+
findings: [
|
|
741
|
+
...new Set([
|
|
742
|
+
...broken,
|
|
743
|
+
...over
|
|
744
|
+
])
|
|
745
|
+
]
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
const reading = readAiExperimentResult((_brief_test = brief.test) != null ? _brief_test : '', (_brief_arms = brief.arms) != null ? _brief_arms : []);
|
|
749
|
+
const parsed = parseAiExperimentExplanation(answer);
|
|
750
|
+
const explained = checkAiExperimentExplanation(parsed, reading);
|
|
751
|
+
if (!parsed || !explained) {
|
|
752
|
+
return {
|
|
753
|
+
readable: false,
|
|
754
|
+
rules: false,
|
|
755
|
+
budget: false,
|
|
756
|
+
findings: [
|
|
757
|
+
'experiment-no-explanation'
|
|
758
|
+
]
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
const over = [
|
|
762
|
+
...parsed.headline.length > AI_EXPERIMENT_HEADLINE_MAX_CHARS ? [
|
|
763
|
+
'experiment-headline-over'
|
|
764
|
+
] : [],
|
|
765
|
+
...parsed.points.length > AI_EXPERIMENT_MAX_POINTS ? [
|
|
766
|
+
'experiment-points-over'
|
|
767
|
+
] : [],
|
|
768
|
+
...parsed.points.flatMap((point)=>point.length > AI_EXPERIMENT_POINT_MAX_CHARS ? [
|
|
769
|
+
'experiment-point-over'
|
|
770
|
+
] : []),
|
|
771
|
+
...parsed.next.length > AI_EXPERIMENT_NEXT_MAX_CHARS ? [
|
|
772
|
+
'experiment-next-over'
|
|
773
|
+
] : []
|
|
774
|
+
];
|
|
775
|
+
const broken = [
|
|
776
|
+
...explained.findings,
|
|
777
|
+
...codes(detectPublishIntent(answer)),
|
|
778
|
+
...codes(detectOffVoiceCopy([
|
|
779
|
+
{
|
|
780
|
+
at: 'headline',
|
|
781
|
+
text: explained.headline
|
|
782
|
+
},
|
|
783
|
+
...explained.points.map((point, index)=>({
|
|
784
|
+
at: `points.${index}`,
|
|
785
|
+
text: point
|
|
786
|
+
}))
|
|
787
|
+
], evalCase.framing))
|
|
788
|
+
];
|
|
789
|
+
return {
|
|
790
|
+
readable: true,
|
|
791
|
+
rules: broken.length === 0,
|
|
792
|
+
budget: over.length === 0,
|
|
793
|
+
findings: [
|
|
794
|
+
...new Set([
|
|
795
|
+
...broken,
|
|
796
|
+
...over
|
|
797
|
+
])
|
|
798
|
+
]
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
/** An answer held to its kind's checks; a page's links to the sections of the plan it was built from. */ function checkAnswer(evalCase, answer, plan) {
|
|
802
|
+
const outputKind = AI_EVAL_TREE_OUTPUT[evalCase.kind];
|
|
803
|
+
if (outputKind) return checkTree(evalCase, outputKind, answer, plan);
|
|
804
|
+
switch(evalCase.kind){
|
|
805
|
+
case 'seo':
|
|
806
|
+
return checkSeo(evalCase, answer);
|
|
807
|
+
case 'product':
|
|
808
|
+
case 'catalog':
|
|
809
|
+
case 'categories':
|
|
810
|
+
return checkProducts(evalCase, answer);
|
|
811
|
+
case 'theme':
|
|
812
|
+
return checkTheme(evalCase, answer);
|
|
813
|
+
case 'element':
|
|
814
|
+
return checkCopy(evalCase, answer, {
|
|
815
|
+
maxChars: AI_TEXT_LIMITS.body
|
|
816
|
+
});
|
|
817
|
+
case 'blog':
|
|
818
|
+
return checkBlog(evalCase, answer);
|
|
819
|
+
case 'text':
|
|
820
|
+
return checkCopy(evalCase, answer, {
|
|
821
|
+
maxWords: AI_EVAL_TEXT_MAX_WORDS
|
|
822
|
+
});
|
|
823
|
+
case 'chat':
|
|
824
|
+
return checkCopy(evalCase, answer, {
|
|
825
|
+
maxChars: AI_EVAL_CHAT_MAX_CHARS
|
|
826
|
+
}, chatLinks(evalCase));
|
|
827
|
+
case 'workflow':
|
|
828
|
+
return checkWorkflow(evalCase, answer);
|
|
829
|
+
case 'insight':
|
|
830
|
+
return checkInsight(evalCase, answer);
|
|
831
|
+
case 'crm':
|
|
832
|
+
return checkCrm(evalCase, answer);
|
|
833
|
+
case 'experiment':
|
|
834
|
+
return checkExperiment(evalCase, answer);
|
|
835
|
+
default:
|
|
836
|
+
return {
|
|
837
|
+
readable: false,
|
|
838
|
+
rules: false,
|
|
839
|
+
budget: false,
|
|
840
|
+
findings: [
|
|
841
|
+
'kind-unknown'
|
|
842
|
+
]
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
/** The plan held to the plan rules, then to the shape the case expects. */ export function checkAiEvalPlan(evalCase, plan) {
|
|
847
|
+
var _evalCase_capabilities, _shape_reuse;
|
|
848
|
+
var _evalCase_expected;
|
|
849
|
+
const shape = (_evalCase_expected = evalCase.expected) == null ? void 0 : _evalCase_expected.plan;
|
|
850
|
+
if (!shape) return {
|
|
851
|
+
pass: true,
|
|
852
|
+
findings: []
|
|
853
|
+
};
|
|
854
|
+
const result = aiDoctrinePlanCheck(evalCase.inventory, evalCase.framing, (_evalCase_capabilities = evalCase.capabilities) != null ? _evalCase_capabilities : null)(isRecord(plan) ? plan : {});
|
|
855
|
+
if (!result.value) return {
|
|
856
|
+
pass: false,
|
|
857
|
+
findings: [
|
|
858
|
+
'plan-unreadable',
|
|
859
|
+
...codes(result.violations)
|
|
860
|
+
]
|
|
861
|
+
};
|
|
862
|
+
const value = result.value;
|
|
863
|
+
const shapeFindings = [
|
|
864
|
+
...value.screens.length < shape.screens[0] || value.screens.length > shape.screens[1] ? [
|
|
865
|
+
`plan-screens:${value.screens.length}`
|
|
866
|
+
] : [],
|
|
867
|
+
...((_shape_reuse = shape.reuse) != null ? _shape_reuse : []).filter((id)=>!value.reuse.some((entry)=>entry.id === id)).map((id)=>`plan-reuse-missing:${id}`),
|
|
868
|
+
...shape.layout ? value.screens.filter((screen)=>screen.layout !== shape.layout).map((screen)=>`plan-layout:${screen.slug}`) : [],
|
|
869
|
+
...shape.maxCreate !== undefined && value.create.length > shape.maxCreate ? [
|
|
870
|
+
`plan-create:${value.create.length}`
|
|
871
|
+
] : [],
|
|
872
|
+
...shape.createKinds ? value.create.filter((entry)=>{
|
|
873
|
+
var _shape_createKinds;
|
|
874
|
+
return !((_shape_createKinds = shape.createKinds) == null ? void 0 : _shape_createKinds.includes(entry.kind));
|
|
875
|
+
}).map((entry)=>`plan-create-kind:${entry.kind}`) : []
|
|
876
|
+
];
|
|
877
|
+
const findings = [
|
|
878
|
+
...codes(result.violations),
|
|
879
|
+
...shapeFindings
|
|
880
|
+
];
|
|
881
|
+
return {
|
|
882
|
+
pass: findings.length === 0,
|
|
883
|
+
findings
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
const clampGrade = (value)=>{
|
|
887
|
+
if (value === null || value === undefined) return null;
|
|
888
|
+
const parsed = Number(value);
|
|
889
|
+
return Number.isFinite(parsed) ? Math.min(5, Math.max(1, parsed)) : null;
|
|
890
|
+
};
|
|
891
|
+
/** A rubric's mean and whether it passes: the mean at `AI_EVAL_RUBRIC_PASS_MEAN`, nothing under three. */ export function aiEvalRubricVerdict(rubric) {
|
|
892
|
+
const grades = [
|
|
893
|
+
rubric == null ? void 0 : rubric.structure,
|
|
894
|
+
rubric == null ? void 0 : rubric.copy,
|
|
895
|
+
rubric == null ? void 0 : rubric.reuse
|
|
896
|
+
].map(clampGrade).filter((grade)=>grade !== null);
|
|
897
|
+
if (!grades.length) return {
|
|
898
|
+
mean: 1,
|
|
899
|
+
pass: false
|
|
900
|
+
};
|
|
901
|
+
const mean = grades.reduce((sum, grade)=>sum + grade, 0) / grades.length;
|
|
902
|
+
return {
|
|
903
|
+
mean,
|
|
904
|
+
pass: mean >= AI_EVAL_RUBRIC_PASS_MEAN && Math.min(...grades) >= 3
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* The widths a readable document of a rendered kind is held to, from its
|
|
909
|
+
* recorded device audit: `null` when the answer is not such a document or no
|
|
910
|
+
* audits were given; failing, with `widths-unrecorded`, when none was recorded
|
|
911
|
+
* from this answer.
|
|
912
|
+
*/ function checkWidths(evalCase, answer, checked, audits) {
|
|
913
|
+
if (!audits || !(checked == null ? void 0 : checked.readable) || !aiEvalRendersAtDeviceWidths(evalCase.kind)) return null;
|
|
914
|
+
const audit = audits(evalCase, answer);
|
|
915
|
+
if (!audit) return {
|
|
916
|
+
pass: false,
|
|
917
|
+
findings: [
|
|
918
|
+
'widths-unrecorded'
|
|
919
|
+
]
|
|
920
|
+
};
|
|
921
|
+
const findings = aiDeviceAuditFindings(audit);
|
|
922
|
+
return {
|
|
923
|
+
pass: findings.length === 0,
|
|
924
|
+
findings
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
/** One answer to one golden brief, scored. */ export function scoreAiEvalCandidate(evalCase, candidate, audits) {
|
|
928
|
+
var _candidate_scope, _ref, _ref1, _ref2, _ref3, _ref4;
|
|
929
|
+
var _evalCase_expected;
|
|
930
|
+
const scope = (_candidate_scope = candidate.scope) != null ? _candidate_scope : 'full';
|
|
931
|
+
const checked = scope === 'full' ? checkAnswer(evalCase, candidate.answer, candidate.plan) : null;
|
|
932
|
+
const widths = checkWidths(evalCase, candidate.answer, checked, audits);
|
|
933
|
+
const plan = ((_evalCase_expected = evalCase.expected) == null ? void 0 : _evalCase_expected.plan) ? checkAiEvalPlan(evalCase, candidate.plan) : null;
|
|
934
|
+
const rubric = aiEvalRubricVerdict(candidate.rubric);
|
|
935
|
+
const rubricScore = (rubric.mean - 1) / 4;
|
|
936
|
+
const parts = [
|
|
937
|
+
...checked ? [
|
|
938
|
+
checked.readable ? 1 : 0,
|
|
939
|
+
checked.rules ? 1 : 0,
|
|
940
|
+
checked.budget ? 1 : 0
|
|
941
|
+
] : [],
|
|
942
|
+
...plan ? [
|
|
943
|
+
plan.pass ? 1 : 0
|
|
944
|
+
] : [],
|
|
945
|
+
rubricScore
|
|
946
|
+
];
|
|
947
|
+
const score = Math.round(parts.reduce((sum, part)=>sum + part, 0) / parts.length * 10000) / 10000;
|
|
948
|
+
const documentPasses = checked ? checked.readable && checked.rules && checked.budget : true;
|
|
949
|
+
return {
|
|
950
|
+
caseId: evalCase.id,
|
|
951
|
+
kind: evalCase.kind,
|
|
952
|
+
source: candidate.source,
|
|
953
|
+
scope,
|
|
954
|
+
model: candidate.model,
|
|
955
|
+
checks: {
|
|
956
|
+
readable: checked ? checked.readable : null,
|
|
957
|
+
rules: checked ? checked.rules : null,
|
|
958
|
+
budget: checked ? checked.budget : null,
|
|
959
|
+
plan: plan ? plan.pass : null,
|
|
960
|
+
responsive: widths ? widths.pass : null,
|
|
961
|
+
rubric: rubric.pass
|
|
962
|
+
},
|
|
963
|
+
rubricScore: Math.round(rubricScore * 10000) / 10000,
|
|
964
|
+
score,
|
|
965
|
+
// A plan answer to a brief with no expected plan has nothing to pass.
|
|
966
|
+
pass: documentPasses && ((_ref = widths == null ? void 0 : widths.pass) != null ? _ref : true) && ((_ref1 = plan == null ? void 0 : plan.pass) != null ? _ref1 : scope === 'full') && rubric.pass,
|
|
967
|
+
findings: [
|
|
968
|
+
...(_ref2 = checked == null ? void 0 : checked.findings) != null ? _ref2 : [],
|
|
969
|
+
...(_ref3 = widths == null ? void 0 : widths.findings) != null ? _ref3 : [],
|
|
970
|
+
...(_ref4 = plan == null ? void 0 : plan.findings) != null ? _ref4 : []
|
|
971
|
+
]
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* The checks a control failed; the harness requires every one it names. A
|
|
976
|
+
* control whose widths were never recorded fails none of them.
|
|
977
|
+
*/ export function scoreAiEvalControl(evalCase, control, audits) {
|
|
978
|
+
var _control_plan;
|
|
979
|
+
var _evalCase_candidates_, _evalCase_expected;
|
|
980
|
+
// A control is the case's first answer with one thing wrong, built from its plan unless it carries its own.
|
|
981
|
+
const checked = checkAnswer(evalCase, control.answer, (_control_plan = control.plan) != null ? _control_plan : (_evalCase_candidates_ = evalCase.candidates[0]) == null ? void 0 : _evalCase_candidates_.plan);
|
|
982
|
+
const widths = (audits == null ? void 0 : audits(evalCase, control.answer)) ? checkWidths(evalCase, control.answer, checked, audits) : null;
|
|
983
|
+
const plan = control.plan !== undefined && ((_evalCase_expected = evalCase.expected) == null ? void 0 : _evalCase_expected.plan) ? checkAiEvalPlan(evalCase, control.plan) : null;
|
|
984
|
+
return [
|
|
985
|
+
...checked.readable ? [] : [
|
|
986
|
+
'readable'
|
|
987
|
+
],
|
|
988
|
+
...checked.rules ? [] : [
|
|
989
|
+
'rules'
|
|
990
|
+
],
|
|
991
|
+
...checked.budget ? [] : [
|
|
992
|
+
'budget'
|
|
993
|
+
],
|
|
994
|
+
...plan && !plan.pass ? [
|
|
995
|
+
'plan'
|
|
996
|
+
] : [],
|
|
997
|
+
...widths && !widths.pass ? [
|
|
998
|
+
'responsive'
|
|
999
|
+
] : []
|
|
1000
|
+
];
|
|
1001
|
+
}
|
|
1002
|
+
/** Every kind's pass rate and mean score against its floor; a kind with no candidate is below it. */ export function summarizeAiEval(scores) {
|
|
1003
|
+
return AI_EVAL_KINDS.map((kind)=>{
|
|
1004
|
+
const own = scores.filter((score)=>score.kind === kind && score.scope === 'full');
|
|
1005
|
+
const passed = own.filter((score)=>score.pass).length;
|
|
1006
|
+
const passRate = own.length ? passed / own.length : null;
|
|
1007
|
+
const meanScore = own.length ? Math.round(own.reduce((sum, score)=>sum + score.score, 0) / own.length * 10000) / 10000 : null;
|
|
1008
|
+
const floor = AI_EVAL_FLOORS[kind];
|
|
1009
|
+
return {
|
|
1010
|
+
kind,
|
|
1011
|
+
candidates: own.length,
|
|
1012
|
+
passed,
|
|
1013
|
+
passRate,
|
|
1014
|
+
meanScore,
|
|
1015
|
+
floor,
|
|
1016
|
+
belowFloor: passRate === null || meanScore === null || passRate < floor.passRate || meanScore < floor.meanScore
|
|
1017
|
+
};
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* The plan step's own score: every answer that carried a plan checked
|
|
1022
|
+
* against its brief's expected shape, whole answers and plan answers alike.
|
|
1023
|
+
*/ export function summarizeAiEvalPlans(scores) {
|
|
1024
|
+
const plans = scores.filter((score)=>score.checks.plan !== null);
|
|
1025
|
+
const passed = plans.filter((score)=>score.checks.plan && score.checks.rubric).length;
|
|
1026
|
+
return {
|
|
1027
|
+
plans: plans.length,
|
|
1028
|
+
passed,
|
|
1029
|
+
passRate: plans.length ? passed / plans.length : null
|
|
1030
|
+
};
|
|
1031
|
+
}
|
|
1032
|
+
/** A recording file read and checked for shape; throws naming the field at fault. */ export function readAiEvalRecording(raw, file) {
|
|
1033
|
+
if (!isRecord(raw) || typeof raw['caseId'] !== 'string' || !isRecord(raw['candidate'])) {
|
|
1034
|
+
throw new Error(`${file}: a recording holds a caseId and a candidate`);
|
|
1035
|
+
}
|
|
1036
|
+
const candidate = raw['candidate'];
|
|
1037
|
+
// `null` says the grader failed and this answer was kept ungraded
|
|
1038
|
+
// (AGL-3143); a missing key is a recording written by something that does
|
|
1039
|
+
// not know what a grade is.
|
|
1040
|
+
if (candidate['source'] !== 'recorded' || !(isRecord(candidate['rubric']) || candidate['rubric'] === null)) {
|
|
1041
|
+
throw new Error(`${file}: a recording's candidate is recorded, and graded or explicitly ungraded`);
|
|
1042
|
+
}
|
|
1043
|
+
return raw;
|
|
1044
|
+
}
|
|
1045
|
+
// ── Reading a case file ───────────────────────────────────────────────────
|
|
1046
|
+
/** A case file read and checked for shape; throws naming the field at fault. */ export function readAiEvalCase(raw, file) {
|
|
1047
|
+
const fail = (why)=>{
|
|
1048
|
+
throw new Error(`${file}: ${why}`);
|
|
1049
|
+
};
|
|
1050
|
+
if (!isRecord(raw)) return fail('not an object');
|
|
1051
|
+
const kind = raw['kind'];
|
|
1052
|
+
if (typeof raw['id'] !== 'string' || !raw['id']) fail('no id');
|
|
1053
|
+
if (typeof kind !== 'string' || !AI_EVAL_KINDS.includes(kind)) {
|
|
1054
|
+
fail(`kind "${String(kind)}" is not one of ${AI_EVAL_KINDS.join(', ')}`);
|
|
1055
|
+
}
|
|
1056
|
+
if (typeof raw['brief'] !== 'string' || !raw['brief'].trim()) fail('no brief');
|
|
1057
|
+
if (raw['siteName'] !== undefined && (typeof raw['siteName'] !== 'string' || !raw['siteName'].trim())) {
|
|
1058
|
+
fail('siteName, where given, is the site’s name');
|
|
1059
|
+
}
|
|
1060
|
+
const automation = raw['automation'];
|
|
1061
|
+
if (automation !== undefined) {
|
|
1062
|
+
const action = isRecord(automation) ? automation['action'] : undefined;
|
|
1063
|
+
const problem = isRecord(action) ? validateHostAction(action) : 'it holds no action';
|
|
1064
|
+
if (problem) fail(`automation.action is not an action the Actions editor would save: ${problem}`);
|
|
1065
|
+
if (isRecord(automation) && automation['run'] !== undefined && !isRecord(automation['run'])) {
|
|
1066
|
+
fail('automation.run, where given, is what the run history recorded');
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
const media = raw['media'];
|
|
1070
|
+
if (media !== undefined) {
|
|
1071
|
+
if (!isRecord(media) || !Object.keys(media).length) fail('media, where given, names at least one asset');
|
|
1072
|
+
for (const [mediaId, file] of Object.entries(media)){
|
|
1073
|
+
if (typeof file !== 'string' || !AI_EVAL_MEDIA_FILE.test(file)) {
|
|
1074
|
+
fail(`media.${mediaId} is not a picture's path under tools/ai-eval/fixtures`);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
const candidates = raw['candidates'];
|
|
1079
|
+
const controls = raw['controls'];
|
|
1080
|
+
if (!Array.isArray(candidates) || !candidates.length) fail('no candidates');
|
|
1081
|
+
if (!Array.isArray(controls) || !controls.length) fail('no controls: every case proves it can fail');
|
|
1082
|
+
for (const [index, candidate] of candidates.entries()){
|
|
1083
|
+
if (!isRecord(candidate)) fail(`candidates[${index}] is not an object`);
|
|
1084
|
+
const source = candidate['source'];
|
|
1085
|
+
if (source !== 'authored' && source !== 'recorded') {
|
|
1086
|
+
fail(`candidates[${index}].source is neither authored nor recorded`);
|
|
1087
|
+
}
|
|
1088
|
+
if (!isRecord(candidate['rubric'])) {
|
|
1089
|
+
fail(`candidates[${index}] has no rubric`);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
for (const [index, control] of controls.entries()){
|
|
1093
|
+
const fails = isRecord(control) ? control['fails'] : undefined;
|
|
1094
|
+
if (!Array.isArray(fails) || !fails.length) fail(`controls[${index}] names no check it fails`);
|
|
1095
|
+
}
|
|
1096
|
+
const capabilities = raw['capabilities'] === undefined ? undefined : readAiEvalCapabilities(raw['capabilities'], fail);
|
|
1097
|
+
return _extends({
|
|
1098
|
+
framing: null,
|
|
1099
|
+
inventory: null
|
|
1100
|
+
}, raw, capabilities ? {
|
|
1101
|
+
capabilities
|
|
1102
|
+
} : {});
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* A case's capabilities read and checked for shape. A creation kind the case
|
|
1106
|
+
* leaves out may be created, so a case names only what its workspace lacks;
|
|
1107
|
+
* a Free workspace's case says so with `freeTaste`, which holds its plan to
|
|
1108
|
+
* the sections the Free wall pays for (AGL-3070).
|
|
1109
|
+
*/ function readAiEvalCapabilities(raw, fail) {
|
|
1110
|
+
if (!isRecord(raw) || typeof raw['reusableComponents'] !== 'boolean') {
|
|
1111
|
+
return fail('capabilities.reusableComponents is not true or false');
|
|
1112
|
+
}
|
|
1113
|
+
const create = isRecord(raw['create']) ? raw['create'] : {};
|
|
1114
|
+
const unrestricted = aiUnrestrictedPlanCapabilities();
|
|
1115
|
+
const entries = AI_BUILD_PLAN_CREATE_KINDS.map((kind)=>{
|
|
1116
|
+
const entry = create[kind];
|
|
1117
|
+
if (entry === undefined) return [
|
|
1118
|
+
kind,
|
|
1119
|
+
unrestricted.create[kind]
|
|
1120
|
+
];
|
|
1121
|
+
if (!isRecord(entry) || typeof entry['allowed'] !== 'boolean') {
|
|
1122
|
+
return fail(`capabilities.create.${kind}.allowed is not true or false`);
|
|
1123
|
+
}
|
|
1124
|
+
const left = entry['left'];
|
|
1125
|
+
const reason = entry['reason'];
|
|
1126
|
+
return [
|
|
1127
|
+
kind,
|
|
1128
|
+
{
|
|
1129
|
+
allowed: entry['allowed'],
|
|
1130
|
+
left: typeof left === 'number' ? left : null,
|
|
1131
|
+
reason: typeof reason === 'string' ? reason : null
|
|
1132
|
+
}
|
|
1133
|
+
];
|
|
1134
|
+
});
|
|
1135
|
+
for (const kind of Object.keys(create)){
|
|
1136
|
+
if (!AI_BUILD_PLAN_CREATE_KINDS.includes(kind)) {
|
|
1137
|
+
fail(`capabilities.create.${kind} is not a creation kind`);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
if (raw['freeTaste'] !== undefined && typeof raw['freeTaste'] !== 'boolean') {
|
|
1141
|
+
return fail('capabilities.freeTaste is not true or false');
|
|
1142
|
+
}
|
|
1143
|
+
return _extends({
|
|
1144
|
+
reusableComponents: raw['reusableComponents'],
|
|
1145
|
+
create: Object.fromEntries(entries)
|
|
1146
|
+
}, raw['freeTaste'] === true ? {
|
|
1147
|
+
freeTaste: true
|
|
1148
|
+
} : {});
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
//# sourceMappingURL=ai-eval.js.map
|