@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 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/tools/ai-products-tool.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SEO_LISTING_FIELDS } from '@aglyn/aglyn/app-utils/seo-listing-fields'\nimport {\n AI_CATALOG_DESCRIPTION_MAX_CHARS,\n AI_CATALOG_OPTION_VALUE_MAX_CHARS,\n AI_CATALOG_OPTION_VALUES_MAX,\n AI_CATALOG_OPTIONS_MAX,\n AI_CATALOG_PHOTO_MAX_CHARS,\n AI_CATALOG_PRODUCTS,\n AI_CATALOG_TAGS_MAX,\n AI_CATEGORIES_MAX,\n AI_CATEGORY_NAME_MAX_CHARS,\n AI_DISCOUNT_CODE,\n AI_DISCOUNT_MAX_FIXED_USD,\n AI_DISCOUNT_MAX_PERCENT,\n AI_DISCOUNTS_MAX,\n AI_PRODUCT_CATEGORIES_MAX,\n AI_PRODUCT_DESCRIPTION_MAX_CHARS,\n AI_PRODUCT_NAME_MAX_CHARS,\n AI_PRODUCT_OPTION_NAME_MAX_CHARS,\n AI_PRODUCT_TAG_MAX_CHARS,\n AI_PRODUCT_TAGS_MAX,\n AI_PRODUCT_TYPES,\n AI_PROPOSAL_WHY_MAX_CHARS,\n type AiCatalogProduct,\n type AiCategoriesProposal,\n type AiDiscountKind,\n type AiProductCopy,\n type AiProductOption,\n type AiProductType,\n type AiProposedDiscount,\n} from '../model/ai-products'\nimport {\n findInventedPrices,\n findStorefrontClaims,\n storefrontClaimViolations,\n type AiStorefrontCopySample,\n} from '../model/ai-storefront-claims'\nimport type { AiTool } from '../providers/contract'\nimport type { AiGenerationCheckResult } from '../runtime/ai-doctrine'\nimport { detectOffVoiceCopy, type AiDoctrineViolation } from '../runtime/ai-doctrine-validators'\n\n/**\n * The strict tools commerce by AI answers through (AGL-2916), and the checks\n * that hold each answer to the commerce editor it proposes for.\n *\n * - `propose_product_copy` — one product's description, search listing, tags,\n * categories and option names.\n * - `propose_catalog` — a store's first products, from a brief.\n * - `propose_categories_and_discounts` — store categories and a first set of\n * discounts, from a brief.\n *\n * Each schema is kept small, and no field is nullable: \"none\" is an empty\n * string, an empty list or zero. A strict schema accepts no length keyword,\n * so every bound is stated in a description and enforced here. A check\n * returns a value only when nothing in the answer is broken, and otherwise\n * the violations and the parts at fault, for the generation call's one\n * re-ask.\n */\n\nexport const AI_PRODUCT_COPY_TOOL_NAME = 'propose_product_copy'\nexport const AI_CATALOG_TOOL_NAME = 'propose_catalog'\nexport const AI_CATEGORIES_TOOL_NAME = 'propose_categories_and_discounts'\n\nconst SEO_TITLE_MAX = SEO_LISTING_FIELDS.title.maxLength\nconst SEO_DESCRIPTION_MAX = SEO_LISTING_FIELDS.description.maxLength\n\nconst string = (description: string) => ({ type: 'string', description })\nconst strings = (description: string) => ({ type: 'array', items: { type: 'string' }, description })\n\n/* ------------------------------------------------------------------------ *\n * Shared reads\n * ------------------------------------------------------------------------ */\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/** One line: runs of white space folded to one space. */\nconst line = (value: unknown): string => (typeof value === 'string' ? value.replace(/\\s+/g, ' ').trim() : '')\n\n/** Paragraphs: spaces folded within a line, at most one blank line between paragraphs. */\nconst paragraphs = (value: unknown): string =>\n typeof value === 'string'\n ? value\n .replace(/\\r\\n?/g, '\\n')\n .split('\\n')\n .map((part) => part.replace(/[ \\t\\f\\v]+/g, ' ').trim())\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n : ''\n\nconst MARKUP = /<\\/?[a-z][^>]*>/i\nconst MARKDOWN = /(^|\\n)\\s*#{1,6}\\s|\\*\\*[^*\\n]+\\*\\*|__[^_\\n]+__|!\\[[^\\]]*\\]\\(|\\[[^\\]]+\\]\\(https?:/\nconst EMOJI = /\\p{Extended_Pictographic}/u\nconst BRACKET = /[[\\]]/\nconst URL = /\\bhttps?:\\/\\/|\\bwww\\./i\n\ninterface Findings {\n violations: AiDoctrineViolation[]\n offending: Record<string, unknown>\n}\n\nfunction fail(findings: Findings, at: string, code: string, message: string, value: unknown): void {\n findings.violations.push({ rule: null, code, message, paths: [at] })\n if (!(at in findings.offending)) findings.offending[at] = value\n}\n\n/** A piece of copy a shopper reads: there, within its length, and plain text. */\nfunction checkCopyText(\n findings: Findings,\n at: string,\n raw: unknown,\n bounds: { label: string; max: number; multiline?: boolean; brackets?: boolean },\n): string {\n if (typeof raw !== 'string') {\n fail(findings, at, 'type', `${bounds.label} must be text.`, raw)\n return ''\n }\n const value = bounds.multiline ? paragraphs(raw) : line(raw)\n if (!value) {\n fail(findings, at, 'missing', `${bounds.label} is required.`, raw)\n return ''\n }\n if (value.length > bounds.max) {\n fail(findings, at, 'too-long', `${bounds.label} is ${value.length} characters; it may have ${bounds.max}.`, raw)\n }\n if (MARKUP.test(value) || MARKDOWN.test(value)) {\n fail(findings, at, 'markup', `${bounds.label} is plain text, with no markup or formatting marks.`, raw)\n }\n if (EMOJI.test(value)) fail(findings, at, 'emoji', `${bounds.label} holds no emoji.`, raw)\n if (URL.test(value)) fail(findings, at, 'link', `${bounds.label} holds no link.`, raw)\n if (bounds.brackets === false && BRACKET.test(value)) {\n fail(findings, at, 'bracket', `${bounds.label} is published as written, so it marks no missing fact in brackets.`, raw)\n }\n return value\n}\n\n/** Tags a shopper filters by: short, distinct, no `#`, no more than `max`. */\nfunction checkTags(findings: Findings, at: string, raw: unknown, max = AI_PRODUCT_TAGS_MAX): string[] {\n if (!Array.isArray(raw)) {\n fail(findings, at, 'type', 'Tags are a list of words or short phrases.', raw)\n return []\n }\n const seen = new Set<string>()\n const tags: string[] = []\n raw.forEach((entry, index) => {\n const tag = line(entry).replace(/^#+/, '').trim()\n if (!tag) return\n if (tag.length > AI_PRODUCT_TAG_MAX_CHARS || EMOJI.test(tag) || BRACKET.test(tag)) {\n fail(findings, `${at}[${index}]`, 'tag', `A tag is a plain word or phrase of at most ${AI_PRODUCT_TAG_MAX_CHARS} characters.`, entry)\n return\n }\n const key = tag.toLowerCase()\n if (seen.has(key)) return\n seen.add(key)\n tags.push(tag)\n })\n if (tags.length > max) {\n fail(findings, at, 'too-many', `A product carries at most ${max} tags.`, raw)\n }\n return tags\n}\n\n/** The claims and prices a set of copy may not make, as violations. */\nfunction claimViolations(samples: readonly AiStorefrontCopySample[], merchantWords: string): AiDoctrineViolation[] {\n return storefrontClaimViolations(\n findStorefrontClaims(samples, merchantWords),\n findInventedPrices(samples, merchantWords),\n )\n}\n\n/* ------------------------------------------------------------------------ *\n * One product's copy\n * ------------------------------------------------------------------------ */\n\nexport const AI_PRODUCT_COPY_TOOL: AiTool = {\n name: AI_PRODUCT_COPY_TOOL_NAME,\n description: 'Propose the storefront copy for one product. Every field is required.',\n strict: true,\n inputSchema: {\n type: 'object',\n additionalProperties: false,\n required: ['description', 'seoTitle', 'seoDescription', 'tags', 'categoryIds', 'optionNames'],\n properties: {\n description: string(\n `The product description shoppers read, in short paragraphs, at most ${AI_PRODUCT_DESCRIPTION_MAX_CHARS} characters.`,\n ),\n seoTitle: string(`The search result headline, published as written, at most ${SEO_TITLE_MAX} characters.`),\n seoDescription: string(`The search result summary, at most ${SEO_DESCRIPTION_MAX} characters.`),\n tags: strings(`At most ${AI_PRODUCT_TAGS_MAX} tags, each at most ${AI_PRODUCT_TAG_MAX_CHARS} characters.`),\n categoryIds: strings(\n `At most ${AI_PRODUCT_CATEGORIES_MAX} category ids from the list you were given; empty when none fits.`,\n ),\n optionNames: strings(\n `One name per option the product has, in order, each at most ${AI_PRODUCT_OPTION_NAME_MAX_CHARS} characters; empty when it has none.`,\n ),\n },\n },\n}\n\nexport interface AiProductCopyCheckContext {\n /** The ids of the site's categories the request listed. */\n categoryIds: readonly string[]\n /** How many options the product has. */\n optionCount: number\n /** The merchant's own words about the product: its name, text and tags. */\n merchantWords: string\n}\n\n/**\n * A product copy answer held to the editor: every field written and within\n * its length, plain text, the categories the request listed, one distinct\n * name per option, and no claim or price the copy may not make.\n */\nexport function checkAiProductCopy(\n answer: Record<string, unknown>,\n context: AiProductCopyCheckContext,\n): AiGenerationCheckResult<AiProductCopy> {\n const findings: Findings = { violations: [], offending: {} }\n const description = checkCopyText(findings, 'description', answer['description'], {\n label: 'The description',\n max: AI_PRODUCT_DESCRIPTION_MAX_CHARS,\n multiline: true,\n })\n const seoTitle = checkCopyText(findings, 'seoTitle', answer['seoTitle'], {\n label: 'The search title',\n max: SEO_TITLE_MAX,\n brackets: false,\n })\n const seoDescription = checkCopyText(findings, 'seoDescription', answer['seoDescription'], {\n label: 'The search description',\n max: SEO_DESCRIPTION_MAX,\n brackets: false,\n })\n const tags = checkTags(findings, 'tags', answer['tags'])\n\n const allowed = new Set(context.categoryIds)\n const categoryIds: string[] = []\n const rawCategories = answer['categoryIds']\n if (!Array.isArray(rawCategories)) {\n fail(findings, 'categoryIds', 'type', 'Categories are a list of ids.', rawCategories)\n } else {\n for (const entry of rawCategories) {\n const id = line(entry)\n if (!id || categoryIds.includes(id)) continue\n if (!allowed.has(id)) {\n fail(findings, 'categoryIds', 'category-unknown', 'Use only the category ids you were given.', rawCategories)\n continue\n }\n categoryIds.push(id)\n }\n if (categoryIds.length > AI_PRODUCT_CATEGORIES_MAX) {\n fail(findings, 'categoryIds', 'too-many', `A product goes in at most ${AI_PRODUCT_CATEGORIES_MAX} categories.`, rawCategories)\n }\n }\n\n const optionNames: string[] = []\n const rawOptions = answer['optionNames']\n if (!Array.isArray(rawOptions)) {\n fail(findings, 'optionNames', 'type', 'Option names are a list.', rawOptions)\n } else {\n if (rawOptions.length !== context.optionCount) {\n fail(\n findings,\n 'optionNames',\n 'option-count',\n `The product has ${context.optionCount} ${context.optionCount === 1 ? 'option' : 'options'}; give one name for each.`,\n rawOptions,\n )\n }\n rawOptions.slice(0, context.optionCount).forEach((entry, index) => {\n const name = line(entry)\n if (!name || name.length > AI_PRODUCT_OPTION_NAME_MAX_CHARS || BRACKET.test(name) || EMOJI.test(name)) {\n fail(findings, `optionNames[${index}]`, 'option-name', `An option name is a plain word or phrase of at most ${AI_PRODUCT_OPTION_NAME_MAX_CHARS} characters.`, entry)\n }\n optionNames.push(name)\n })\n if (new Set(optionNames.map((name) => name.toLowerCase())).size !== optionNames.length) {\n fail(findings, 'optionNames', 'option-duplicate', 'Each option needs its own name.', rawOptions)\n }\n }\n\n const samples: AiStorefrontCopySample[] = [\n { at: 'description', text: description },\n { at: 'seoTitle', text: seoTitle },\n { at: 'seoDescription', text: seoDescription },\n ...tags.map((tag, index) => ({ at: `tags[${index}]`, text: tag })),\n ]\n findings.violations.push(\n ...claimViolations(samples, context.merchantWords),\n ...detectOffVoiceCopy(samples, null),\n )\n const value = findings.violations.length\n ? null\n : { description, seoTitle, seoDescription, tags, categoryIds, optionNames }\n return { value, violations: findings.violations, offending: findings.offending }\n}\n\n/* ------------------------------------------------------------------------ *\n * A store's first products\n * ------------------------------------------------------------------------ */\n\nexport const AI_CATALOG_TOOL: AiTool = {\n name: AI_CATALOG_TOOL_NAME,\n description: 'Propose the products of a new store, each a draft its owner completes. Every field is required.',\n strict: true,\n inputSchema: {\n type: 'object',\n additionalProperties: false,\n required: ['products'],\n properties: {\n products: {\n type: 'array',\n description: `Between ${AI_CATALOG_PRODUCTS.min} and ${AI_CATALOG_PRODUCTS.max} products.`,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['name', 'type', 'description', 'tags', 'options', 'seoTitle', 'seoDescription', 'photo'],\n properties: {\n name: string(`Distinct within the list, at most ${AI_PRODUCT_NAME_MAX_CHARS} characters.`),\n type: { type: 'string', enum: [...AI_PRODUCT_TYPES] },\n description: string(`In short paragraphs, at most ${AI_CATALOG_DESCRIPTION_MAX_CHARS} characters.`),\n tags: strings(`At most ${AI_CATALOG_TAGS_MAX} tags, each at most ${AI_PRODUCT_TAG_MAX_CHARS} characters.`),\n options: {\n type: 'array',\n description: `The choices a shopper makes, at most ${AI_CATALOG_OPTIONS_MAX}; empty for a product with none.`,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['name', 'values'],\n properties: {\n name: string(`At most ${AI_PRODUCT_OPTION_NAME_MAX_CHARS} characters.`),\n values: strings(\n `At most ${AI_CATALOG_OPTION_VALUES_MAX} distinct values, each at most ${AI_CATALOG_OPTION_VALUE_MAX_CHARS} characters.`,\n ),\n },\n },\n },\n seoTitle: string(`At most ${SEO_TITLE_MAX} characters.`),\n seoDescription: string(`At most ${SEO_DESCRIPTION_MAX} characters.`),\n photo: string(`What the product photo should show, in one sentence of at most ${AI_CATALOG_PHOTO_MAX_CHARS} characters.`),\n },\n },\n },\n },\n },\n}\n\n/** A catalog answer held to the products editor and the storefront copy rules. */\nexport function checkAiCatalog(\n answer: Record<string, unknown>,\n context: { merchantWords: string },\n): AiGenerationCheckResult<AiCatalogProduct[]> {\n const findings: Findings = { violations: [], offending: {} }\n const raw = answer['products']\n if (!Array.isArray(raw)) {\n fail(findings, 'products', 'type', 'The products are a list.', raw)\n return { value: null, violations: findings.violations, offending: findings.offending }\n }\n if (raw.length < AI_CATALOG_PRODUCTS.min || raw.length > AI_CATALOG_PRODUCTS.max) {\n fail(findings, 'products', 'product-count', `Propose between ${AI_CATALOG_PRODUCTS.min} and ${AI_CATALOG_PRODUCTS.max} products.`, `${raw.length} products`)\n }\n const names = new Set<string>()\n const products: AiCatalogProduct[] = []\n const samples: AiStorefrontCopySample[] = []\n raw.slice(0, AI_CATALOG_PRODUCTS.max).forEach((entry, index) => {\n const at = `products[${index}]`\n if (!isRecord(entry)) {\n fail(findings, at, 'type', 'Each product is an object.', entry)\n return\n }\n const name = checkCopyText(findings, `${at}.name`, entry['name'], {\n label: 'A product name',\n max: AI_PRODUCT_NAME_MAX_CHARS,\n brackets: false,\n })\n if (name && names.has(name.toLowerCase())) {\n fail(findings, `${at}.name`, 'name-duplicate', 'Each product needs its own name.', entry['name'])\n }\n names.add(name.toLowerCase())\n const type = entry['type']\n if (!(AI_PRODUCT_TYPES as readonly unknown[]).includes(type)) {\n fail(findings, `${at}.type`, 'type', 'A product is physical, digital or a service.', type)\n }\n const description = checkCopyText(findings, `${at}.description`, entry['description'], {\n label: 'A product description',\n max: AI_CATALOG_DESCRIPTION_MAX_CHARS,\n multiline: true,\n })\n const tags = checkTags(findings, `${at}.tags`, entry['tags'], AI_CATALOG_TAGS_MAX)\n const options = checkCatalogOptions(findings, `${at}.options`, entry['options'])\n const seoTitle = checkCopyText(findings, `${at}.seoTitle`, entry['seoTitle'], {\n label: 'A search title',\n max: SEO_TITLE_MAX,\n brackets: false,\n })\n const seoDescription = checkCopyText(findings, `${at}.seoDescription`, entry['seoDescription'], {\n label: 'A search description',\n max: SEO_DESCRIPTION_MAX,\n brackets: false,\n })\n const photo = checkCopyText(findings, `${at}.photo`, entry['photo'], {\n label: 'What the photo shows',\n max: AI_CATALOG_PHOTO_MAX_CHARS,\n brackets: false,\n })\n samples.push(\n { at: `${at}.name`, text: name },\n { at: `${at}.description`, text: description },\n { at: `${at}.seoTitle`, text: seoTitle },\n { at: `${at}.seoDescription`, text: seoDescription },\n ...tags.map((tag, tagIndex) => ({ at: `${at}.tags[${tagIndex}]`, text: tag })),\n )\n products.push({\n name,\n type: type as AiProductType,\n description,\n tags,\n options,\n seoTitle,\n seoDescription,\n photo,\n })\n })\n findings.violations.push(...claimViolations(samples, context.merchantWords), ...detectOffVoiceCopy(samples, null))\n return {\n value: findings.violations.length ? null : products,\n violations: findings.violations,\n offending: findings.offending,\n }\n}\n\nfunction checkCatalogOptions(findings: Findings, at: string, raw: unknown): AiProductOption[] {\n if (!Array.isArray(raw)) {\n fail(findings, at, 'type', 'Options are a list.', raw)\n return []\n }\n if (raw.length > AI_CATALOG_OPTIONS_MAX) {\n fail(findings, at, 'too-many', `A proposed product has at most ${AI_CATALOG_OPTIONS_MAX} options.`, raw)\n }\n const options: AiProductOption[] = []\n raw.slice(0, AI_CATALOG_OPTIONS_MAX).forEach((entry, index) => {\n const here = `${at}[${index}]`\n const record = isRecord(entry) ? entry : {}\n const name = line(record['name'])\n if (!name || name.length > AI_PRODUCT_OPTION_NAME_MAX_CHARS || BRACKET.test(name)) {\n fail(findings, `${here}.name`, 'option-name', `An option name is a plain word or phrase of at most ${AI_PRODUCT_OPTION_NAME_MAX_CHARS} characters.`, record['name'])\n }\n const values = Array.isArray(record['values']) ? record['values'].map(line).filter(Boolean) : []\n if (!values.length || values.length > AI_CATALOG_OPTION_VALUES_MAX) {\n fail(findings, `${here}.values`, 'too-many', `An option has between 1 and ${AI_CATALOG_OPTION_VALUES_MAX} values.`, record['values'])\n }\n if (values.some((value) => value.length > AI_CATALOG_OPTION_VALUE_MAX_CHARS || BRACKET.test(value))) {\n fail(findings, `${here}.values`, 'option-values', `An option value is a plain word or phrase of at most ${AI_CATALOG_OPTION_VALUE_MAX_CHARS} characters.`, record['values'])\n }\n if (new Set(values.map((value) => value.toLowerCase())).size !== values.length) {\n fail(findings, `${here}.values`, 'option-values', 'An option’s values are all different.', record['values'])\n }\n options.push({ name, values: values.slice(0, AI_CATALOG_OPTION_VALUES_MAX) })\n })\n if (new Set(options.map((option) => option.name.toLowerCase())).size !== options.length) {\n fail(findings, at, 'option-duplicate', 'Each option needs its own name.', raw)\n }\n return options\n}\n\n/* ------------------------------------------------------------------------ *\n * Categories and discounts\n * ------------------------------------------------------------------------ */\n\nexport const AI_CATEGORIES_TOOL: AiTool = {\n name: AI_CATEGORIES_TOOL_NAME,\n description: 'Propose store categories and a first set of discounts, each created only if the owner accepts it. Every field is required.',\n strict: true,\n inputSchema: {\n type: 'object',\n additionalProperties: false,\n required: ['categories', 'discounts'],\n properties: {\n categories: {\n type: 'array',\n description: `At most ${AI_CATEGORIES_MAX} categories; empty when the brief gives no reason for any.`,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['name', 'why'],\n properties: {\n name: string(`At most ${AI_CATEGORY_NAME_MAX_CHARS} characters.`),\n why: string(`One sentence of at most ${AI_PROPOSAL_WHY_MAX_CHARS} characters.`),\n },\n },\n },\n discounts: {\n type: 'array',\n description: `At most ${AI_DISCOUNTS_MAX} discounts; empty when the brief gives no reason for any.`,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['name', 'code', 'kind', 'value', 'minimumOrderUsd', 'why'],\n properties: {\n name: string(`At most ${AI_CATEGORY_NAME_MAX_CHARS} characters.`),\n code: string('The code a shopper types: 3 to 20 capital letters, digits, dashes or underscores; empty for a discount that applies on its own.'),\n kind: { type: 'string', enum: ['percent', 'fixed', 'free_shipping'] },\n value: {\n type: 'number',\n description: `percent: the percentage, 1 to ${AI_DISCOUNT_MAX_PERCENT}; fixed: dollars off, at most ${AI_DISCOUNT_MAX_FIXED_USD}; free_shipping: 0.`,\n },\n minimumOrderUsd: { type: 'number', description: 'The smallest order it applies to, in dollars; 0 for any order.' },\n why: string(`One sentence of at most ${AI_PROPOSAL_WHY_MAX_CHARS} characters.`),\n },\n },\n },\n },\n },\n}\n\n/** A categories answer held to the catalog and discount editors and the storefront copy rules. */\nexport function checkAiCategories(\n answer: Record<string, unknown>,\n context: { existingCategoryNames: readonly string[]; merchantWords: string },\n): AiGenerationCheckResult<Pick<AiCategoriesProposal, 'categories' | 'discounts'>> {\n const findings: Findings = { violations: [], offending: {} }\n const existing = new Set(context.existingCategoryNames.map((name) => line(name).toLowerCase()))\n const samples: AiStorefrontCopySample[] = []\n\n const categories: AiCategoriesProposal['categories'] = []\n const rawCategories = answer['categories']\n if (!Array.isArray(rawCategories)) {\n fail(findings, 'categories', 'type', 'Categories are a list.', rawCategories)\n } else {\n if (rawCategories.length > AI_CATEGORIES_MAX) {\n fail(findings, 'categories', 'too-many', `Propose at most ${AI_CATEGORIES_MAX} categories.`, `${rawCategories.length} categories`)\n }\n const seen = new Set<string>()\n rawCategories.slice(0, AI_CATEGORIES_MAX).forEach((entry, index) => {\n const at = `categories[${index}]`\n const record = isRecord(entry) ? entry : {}\n const name = checkCopyText(findings, `${at}.name`, record['name'], {\n label: 'A category name',\n max: AI_CATEGORY_NAME_MAX_CHARS,\n brackets: false,\n })\n const key = name.toLowerCase()\n if (name && existing.has(key)) {\n fail(findings, `${at}.name`, 'category-exists', `The store already has a category named ${name}.`, record['name'])\n } else if (name && seen.has(key)) {\n fail(findings, `${at}.name`, 'category-duplicate', 'Each category needs its own name.', record['name'])\n }\n seen.add(key)\n const why = checkCopyText(findings, `${at}.why`, record['why'], {\n label: 'Why a category helps',\n max: AI_PROPOSAL_WHY_MAX_CHARS,\n brackets: false,\n })\n samples.push({ at: `${at}.name`, text: name }, { at: `${at}.why`, text: why })\n categories.push({ name, why })\n })\n }\n\n const discounts: AiProposedDiscount[] = []\n const rawDiscounts = answer['discounts']\n if (!Array.isArray(rawDiscounts)) {\n fail(findings, 'discounts', 'type', 'Discounts are a list.', rawDiscounts)\n } else {\n if (rawDiscounts.length > AI_DISCOUNTS_MAX) {\n fail(findings, 'discounts', 'too-many', `Propose at most ${AI_DISCOUNTS_MAX} discounts.`, `${rawDiscounts.length} discounts`)\n }\n const codes = new Set<string>()\n rawDiscounts.slice(0, AI_DISCOUNTS_MAX).forEach((entry, index) => {\n const at = `discounts[${index}]`\n const record = isRecord(entry) ? entry : {}\n const name = checkCopyText(findings, `${at}.name`, record['name'], {\n label: 'A discount name',\n max: AI_CATEGORY_NAME_MAX_CHARS,\n brackets: false,\n })\n const typedCode = line(record['code']).toUpperCase()\n if (typedCode && !AI_DISCOUNT_CODE.test(typedCode)) {\n fail(findings, `${at}.code`, 'code', 'A code is 3 to 20 capital letters, digits, dashes or underscores.', record['code'])\n } else if (typedCode && codes.has(typedCode)) {\n fail(findings, `${at}.code`, 'code-duplicate', 'Each discount needs its own code.', record['code'])\n }\n if (typedCode) codes.add(typedCode)\n const kind = record['kind']\n const value = Number(record['value'])\n const minimum = Number(record['minimumOrderUsd'])\n let valuePct: number | null = null\n let valueCents: number | null = null\n if (kind === 'percent') {\n if (!Number.isInteger(value) || value < 1 || value > AI_DISCOUNT_MAX_PERCENT) {\n fail(findings, `${at}.value`, 'discount-value', `A percentage is a whole number from 1 to ${AI_DISCOUNT_MAX_PERCENT}.`, record['value'])\n }\n valuePct = value\n } else if (kind === 'fixed') {\n if (!Number.isFinite(value) || value <= 0 || value > AI_DISCOUNT_MAX_FIXED_USD) {\n fail(findings, `${at}.value`, 'discount-value', `An amount off is more than 0 and at most ${AI_DISCOUNT_MAX_FIXED_USD} dollars.`, record['value'])\n }\n valueCents = Math.round(value * 100)\n } else if (kind !== 'free_shipping') {\n fail(findings, `${at}.kind`, 'type', 'A discount is a percentage, an amount off or free shipping.', kind)\n }\n if (!Number.isFinite(minimum) || minimum < 0 || minimum > 10_000) {\n fail(findings, `${at}.minimumOrderUsd`, 'discount-minimum', 'A minimum order is between 0 and 10,000 dollars.', record['minimumOrderUsd'])\n }\n const why = checkCopyText(findings, `${at}.why`, record['why'], {\n label: 'Why a discount helps',\n max: AI_PROPOSAL_WHY_MAX_CHARS,\n brackets: false,\n })\n // The discount's own amount is stated in its fields, so only its name\n // and reason are read for a claim: \"15% off\" is the discount, not a price.\n samples.push({ at: `${at}.name`, text: name }, { at: `${at}.why`, text: why })\n discounts.push({\n name,\n code: typedCode || null,\n kind: kind as AiDiscountKind,\n valuePct,\n valueCents,\n minSubtotalCents: minimum > 0 ? Math.round(minimum * 100) : null,\n why,\n })\n })\n }\n\n if (!categories.length && !discounts.length && !findings.violations.length) {\n fail(findings, 'categories', 'empty', 'Propose at least one category or one discount.', answer)\n }\n findings.violations.push(\n ...storefrontClaimViolations(findStorefrontClaims(samples, context.merchantWords)),\n ...detectOffVoiceCopy(samples, null),\n )\n return {\n value: findings.violations.length ? null : { categories, discounts },\n violations: findings.violations,\n offending: findings.offending,\n }\n}\n"],"names":["SEO_LISTING_FIELDS","AI_CATALOG_DESCRIPTION_MAX_CHARS","AI_CATALOG_OPTION_VALUE_MAX_CHARS","AI_CATALOG_OPTION_VALUES_MAX","AI_CATALOG_OPTIONS_MAX","AI_CATALOG_PHOTO_MAX_CHARS","AI_CATALOG_PRODUCTS","AI_CATALOG_TAGS_MAX","AI_CATEGORIES_MAX","AI_CATEGORY_NAME_MAX_CHARS","AI_DISCOUNT_CODE","AI_DISCOUNT_MAX_FIXED_USD","AI_DISCOUNT_MAX_PERCENT","AI_DISCOUNTS_MAX","AI_PRODUCT_CATEGORIES_MAX","AI_PRODUCT_DESCRIPTION_MAX_CHARS","AI_PRODUCT_NAME_MAX_CHARS","AI_PRODUCT_OPTION_NAME_MAX_CHARS","AI_PRODUCT_TAG_MAX_CHARS","AI_PRODUCT_TAGS_MAX","AI_PRODUCT_TYPES","AI_PROPOSAL_WHY_MAX_CHARS","findInventedPrices","findStorefrontClaims","storefrontClaimViolations","detectOffVoiceCopy","AI_PRODUCT_COPY_TOOL_NAME","AI_CATALOG_TOOL_NAME","AI_CATEGORIES_TOOL_NAME","SEO_TITLE_MAX","title","maxLength","SEO_DESCRIPTION_MAX","description","string","type","strings","items","isRecord","value","Array","isArray","line","replace","trim","paragraphs","split","map","part","join","MARKUP","MARKDOWN","EMOJI","BRACKET","URL","fail","findings","at","code","message","violations","push","rule","paths","offending","checkCopyText","raw","bounds","label","multiline","length","max","test","brackets","checkTags","seen","Set","tags","forEach","entry","index","tag","key","toLowerCase","has","add","claimViolations","samples","merchantWords","AI_PRODUCT_COPY_TOOL","name","strict","inputSchema","additionalProperties","required","properties","seoTitle","seoDescription","categoryIds","optionNames","checkAiProductCopy","answer","context","allowed","rawCategories","id","includes","rawOptions","optionCount","slice","size","text","AI_CATALOG_TOOL","products","min","enum","options","values","photo","checkAiCatalog","names","checkCatalogOptions","tagIndex","here","record","filter","Boolean","some","option","AI_CATEGORIES_TOOL","categories","why","discounts","kind","minimumOrderUsd","checkAiCategories","existing","existingCategoryNames","rawDiscounts","codes","typedCode","toUpperCase","Number","minimum","valuePct","valueCents","isInteger","isFinite","Math","round","minSubtotalCents"],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type SeoListingFieldKey } from '@aglyn/aglyn/app-utils/seo-listing-fields';
|
|
18
|
+
import type { AiSeoFieldValues, AiSeoFindingCode, AiSeoKeywordCoverage, AiSeoSiteFormField } from '../model/ai-seo';
|
|
19
|
+
import type { AiTool } from '../providers/contract';
|
|
20
|
+
import type { AiDoctrineViolation } from '../runtime/ai-doctrine-validators';
|
|
21
|
+
import type { AiSeoPageFacts } from '../runtime/seo-page-facts';
|
|
22
|
+
/**
|
|
23
|
+
* The strict tools SEO by AI answers through (AGL-2910), and the checks that
|
|
24
|
+
* hold each answer to the editor it proposes for.
|
|
25
|
+
*
|
|
26
|
+
* - `propose_search_listing` — one page's or one product's listing. BUILT
|
|
27
|
+
* from the editor's own field list, the `seo-listing-fields` catalog the
|
|
28
|
+
* SEO card draws its inputs from, so a field and its length are said once:
|
|
29
|
+
* `ai-seo-tool.spec.ts` asserts the parity in both directions.
|
|
30
|
+
* - `propose_seo_fixes` — one batch of a site audit's page fixes.
|
|
31
|
+
* - `propose_site_listing` — the site's structured data and its guidance
|
|
32
|
+
* for AI agents, the two fields `/llms.txt` leads with.
|
|
33
|
+
*
|
|
34
|
+
* A strict schema forbids extra keys, requires every key and says "no value"
|
|
35
|
+
* with `null`; it accepts no length keyword, so every length is stated in a
|
|
36
|
+
* description and enforced here. A check returns a value only when nothing
|
|
37
|
+
* in the answer is broken, and otherwise the violations and the parts at
|
|
38
|
+
* fault, for the generation call's one re-ask.
|
|
39
|
+
*/
|
|
40
|
+
/** Target keywords one listing may be asked to cover. */
|
|
41
|
+
export declare const AI_SEO_MAX_KEYWORDS = 5;
|
|
42
|
+
/** The most times one keyword may appear, per field, before it reads as stuffing. */
|
|
43
|
+
export declare const AI_SEO_KEYWORD_LIMITS: Readonly<Partial<Record<SeoListingFieldKey, number>>>;
|
|
44
|
+
/** How many times `keyword` appears in `text` as whole words, any case. */
|
|
45
|
+
export declare function aiSeoKeywordCount(text: string | null | undefined, keyword: string): number;
|
|
46
|
+
/** Keywords as a person typed them: trimmed, deduplicated, capped. */
|
|
47
|
+
export declare function aiSeoKeywordList(raw: unknown): string[];
|
|
48
|
+
/** Where a page already says each target keyword. */
|
|
49
|
+
export declare function aiSeoKeywordCoverage(keywords: readonly string[], sources: {
|
|
50
|
+
title?: string | null;
|
|
51
|
+
description?: string | null;
|
|
52
|
+
h1?: string | null;
|
|
53
|
+
body?: string | null;
|
|
54
|
+
}): AiSeoKeywordCoverage[];
|
|
55
|
+
export declare const AI_SEO_FIELDS_TOOL_NAME = "propose_search_listing";
|
|
56
|
+
/** The fields a listing proposal must fill; the image description may be left out. */
|
|
57
|
+
export declare const AI_SEO_REQUIRED_FIELDS: ReadonlySet<SeoListingFieldKey>;
|
|
58
|
+
/** Fields in the catalog's order, whatever order a caller named them in. */
|
|
59
|
+
export declare function orderedSeoListingFields(fields: readonly SeoListingFieldKey[]): SeoListingFieldKey[];
|
|
60
|
+
/** The strict tool for a listing with exactly these fields, each required and nullable. */
|
|
61
|
+
export declare function aiSeoFieldsTool(fields: readonly SeoListingFieldKey[]): AiTool;
|
|
62
|
+
export interface AiSeoFieldsCheckContext {
|
|
63
|
+
fields: readonly SeoListingFieldKey[];
|
|
64
|
+
/** Whether the listing has a social image; without one, an image description is dropped. */
|
|
65
|
+
hasImage: boolean;
|
|
66
|
+
keywords?: readonly string[];
|
|
67
|
+
/** Titles other pages of the site use, which this listing must not repeat. */
|
|
68
|
+
otherTitles?: readonly string[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A listing answer held to the editor: every requested text field written,
|
|
72
|
+
* each within its length, no keyword past its per-field count, no word
|
|
73
|
+
* repeated to rank, no title another page uses.
|
|
74
|
+
*/
|
|
75
|
+
export declare function checkAiSeoFields(answer: Record<string, unknown>, context: AiSeoFieldsCheckContext): {
|
|
76
|
+
value: AiSeoFieldValues | null;
|
|
77
|
+
violations: AiDoctrineViolation[];
|
|
78
|
+
offending?: Record<string, unknown>;
|
|
79
|
+
};
|
|
80
|
+
export declare const AI_SEO_FIXES_TOOL_NAME = "propose_seo_fixes";
|
|
81
|
+
/**
|
|
82
|
+
* How long an image description a batch proposes may be. Shorter than the
|
|
83
|
+
* `alt` ceiling: a description read aloud is better short, and it keeps the
|
|
84
|
+
* largest batch answer inside its measured budget.
|
|
85
|
+
*/
|
|
86
|
+
export declare const AI_SEO_FIX_ALT_MAX_CHARS: number;
|
|
87
|
+
/** Undescribed images one page of a batch gets descriptions for; the rest wait for the next audit. */
|
|
88
|
+
export declare const AI_SEO_FIX_IMAGES_PER_PAGE = 3;
|
|
89
|
+
/** The undescribed images a batch asks about for a page, in page order. */
|
|
90
|
+
export declare function aiSeoFixImages(page: Pick<AiSeoBatchPage, 'facts'>): AiSeoPageFacts['imagesMissingAlt'];
|
|
91
|
+
/** The strict tool for one batch: a title, description, heading and image descriptions per page. */
|
|
92
|
+
export declare function aiSeoFixesTool(screenIds: readonly string[]): AiTool;
|
|
93
|
+
/** A batch page as the fixes prompt and check read it. */
|
|
94
|
+
export interface AiSeoBatchPage {
|
|
95
|
+
screenId: string;
|
|
96
|
+
path: string;
|
|
97
|
+
name: string;
|
|
98
|
+
codes: ReadonlySet<AiSeoFindingCode>;
|
|
99
|
+
keywords: readonly string[];
|
|
100
|
+
seo: {
|
|
101
|
+
title?: string;
|
|
102
|
+
description?: string;
|
|
103
|
+
breadcrumb?: string;
|
|
104
|
+
image?: string;
|
|
105
|
+
imageAlt?: string;
|
|
106
|
+
} | undefined;
|
|
107
|
+
facts: AiSeoPageFacts;
|
|
108
|
+
}
|
|
109
|
+
/** The findings that let a batch answer propose each value. */
|
|
110
|
+
export declare const AI_SEO_FIX_CODES: {
|
|
111
|
+
readonly title: readonly ["title-missing", "title-too-long", "title-duplicate", "keyword-missing"];
|
|
112
|
+
readonly description: readonly ["description-missing", "description-too-long", "description-duplicate", "keyword-missing"];
|
|
113
|
+
readonly h1: readonly ["h1-missing", "h1-thin"];
|
|
114
|
+
};
|
|
115
|
+
export interface AiSeoBatchAnswer {
|
|
116
|
+
title: string | null;
|
|
117
|
+
description: string | null;
|
|
118
|
+
h1: string | null;
|
|
119
|
+
imageAlts: Array<{
|
|
120
|
+
nodeId: string;
|
|
121
|
+
alt: string;
|
|
122
|
+
}>;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A batch answer held to the audit and the editor: values only where a
|
|
126
|
+
* finding asked for them, each within its length, no keyword past its count,
|
|
127
|
+
* no title another page uses, and image descriptions only for this page's
|
|
128
|
+
* undescribed images.
|
|
129
|
+
*/
|
|
130
|
+
export declare function checkAiSeoFixes(answer: Record<string, unknown>, pages: readonly AiSeoBatchPage[], titlesElsewhere: readonly string[]): {
|
|
131
|
+
value: Record<string, AiSeoBatchAnswer> | null;
|
|
132
|
+
violations: AiDoctrineViolation[];
|
|
133
|
+
offending?: Record<string, unknown>;
|
|
134
|
+
};
|
|
135
|
+
export declare const AI_SEO_SITE_TOOL_NAME = "propose_site_listing";
|
|
136
|
+
/** The longest structured-data description the site SEO form accepts. */
|
|
137
|
+
export declare const AI_SEO_ENTITY_DESCRIPTION_MAX_CHARS = 300;
|
|
138
|
+
/** The longest agent guidance the site SEO form accepts. */
|
|
139
|
+
export declare const AI_SEO_AGENT_GUIDANCE_MAX_CHARS = 1000;
|
|
140
|
+
/** The entity types the tool offers, and the value the site SEO form stores for each. */
|
|
141
|
+
export declare const AI_SEO_ENTITY_TYPE_VALUES: Readonly<Record<string, string>>;
|
|
142
|
+
/** The site-wide proposal's strict tool: structured data and agent guidance, each nullable. */
|
|
143
|
+
export declare function aiSeoSiteTool(): AiTool;
|
|
144
|
+
export interface AiSeoSiteCheckContext {
|
|
145
|
+
/** The form fields that are blank on the site now; only these may be proposed. */
|
|
146
|
+
blank: ReadonlySet<AiSeoSiteFormField>;
|
|
147
|
+
/** Every word the site's pages show, for the contact details to be found in. */
|
|
148
|
+
siteText: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The site proposal held to the form and to the site: lengths, and a contact
|
|
152
|
+
* detail only when a page shows it. A detail no page shows is left out with
|
|
153
|
+
* a note rather than asked for again — asking again invites composing one.
|
|
154
|
+
*/
|
|
155
|
+
export declare function checkAiSeoSite(answer: Record<string, unknown>, context: AiSeoSiteCheckContext): {
|
|
156
|
+
value: {
|
|
157
|
+
values: Partial<Record<AiSeoSiteFormField, string>>;
|
|
158
|
+
notes: string[];
|
|
159
|
+
} | null;
|
|
160
|
+
violations: AiDoctrineViolation[];
|
|
161
|
+
offending?: Record<string, unknown>;
|
|
162
|
+
};
|