@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/runtime/ai-template-examples.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n STARTER_TEMPLATES,\n type StarterTemplate,\n} from '@aglyn/aglyn/app-utils/starter-templates'\nimport { CANVAS_ROOT_ELEMENT_ID } from '@aglyn/aglyn/foundation/constants/canvas'\nimport {\n validateAiDoctrineTree,\n type AiDoctrineNode,\n type AiDoctrineTree,\n} from './ai-doctrine-validators'\nimport { isHeadlineVariant } from './ai-palette'\nimport { AI_PALETTE, AI_SURFACES } from './ai-palette.generated'\nimport type { AiSystemBlock } from './ai-runtime'\n\n/**\n * The page examples a template generation is shown (AGL-2909): pages from\n * the platform's own starter sites (`STARTER_TEMPLATES`), in the node-map\n * shape the tool takes, as one cached block that is the same bytes for every\n * org.\n *\n * Three things about a starter predate the building rules, and every example\n * is brought up to them the same way rather than shown as it stands:\n *\n * - HEADINGS. A starter picks a heading's look with its variant, and rule 11\n * reads its level from the element. The page's first heading renders as\n * its h1, each later one as an h2, and a sixth-level subtitle as a\n * paragraph.\n * - FORMS. A starter draws its contact form inline, and rule 3 places a form\n * built on the Forms page by id, so the form is left out.\n * - LINKS. A starter's call to action points nowhere until a member picks\n * where it goes, and rule 10 refuses a Button or a Screen Link with no\n * destination (AGL-3072), so such a link is left out.\n *\n * Only props the palette declares are kept, since the model is held to the\n * same palette, and none that holds a px, rem or em length, which rule 5\n * names as a length never to write. A page that still breaks a rule, that\n * the palette validator would change in any way, or that places an element\n * the page surface does not offer (a commerce block) is not shown, and two\n * pages of one shape are shown once: an example the model imitates is one\n * the doctrine accepts exactly as written.\n */\n\nexport interface AiTemplateExample {\n /** The starter site's name. */\n starter: string\n /** The page's name within it. */\n page: string\n tree: AiDoctrineTree\n}\n\n/** The block's ceiling: 1,500 tokens at four characters a token. */\nexport const AI_TEMPLATE_EXAMPLES_MAX_CHARS = 6_000\n\nconst FORM_COMPONENTS = new Set(['form', 'formField'])\n\n/** The elements a page links with, which go where their `screenId` or `href` says. */\nconst LINK_COMPONENTS = new Set(['muiButton', 'muiScreenLink'])\n\n/** Whether a starter node is a link that names nowhere to go. */\nfunction linksNowhere(componentId: string, props: Record<string, unknown> | undefined): boolean {\n if (!LINK_COMPONENTS.has(componentId)) return false\n const named = (value: unknown) => typeof value === 'string' && value.trim() !== ''\n return !named(props?.['screenId']) && !named(props?.['href'])\n}\n\n/** A CSS length in the units rule 5 forbids. */\nconst CSS_LENGTH = /\\d(?:\\.\\d+)?(?:px|rem|em)\\b/i\n\ntype StarterNode = {\n componentId?: string\n props?: Record<string, unknown>\n sx?: Record<string, unknown>\n nodes?: unknown\n}\n\n/** A starter page as the tool's node map, brought up to the rules above; `null` when it cannot be shown. */\nexport function aiStarterExampleTree(nodes: Record<string, StarterNode>): AiDoctrineTree | null {\n if (!nodes[CANVAS_ROOT_ELEMENT_ID]) return null\n const allowed = new Set(AI_SURFACES.screen.allow)\n const out: Record<string, AiDoctrineNode> = {}\n let headings = 0\n let unavailable = false\n const visit = (id: string): string | null => {\n const node = nodes[id]\n const componentId = String(node?.componentId ?? '')\n if (!node || FORM_COMPONENTS.has(componentId) || linksNowhere(componentId, node.props)) return null\n const root = id === CANVAS_ROOT_ELEMENT_ID\n if (!root && !allowed.has(componentId)) {\n unavailable = true\n return null\n }\n // Inserted before the children, so the map reads top-down.\n const shaped: AiDoctrineNode = { componentId: root ? 'div' : componentId }\n out[id] = shaped\n const declared = AI_PALETTE[componentId]?.propsSchema.properties ?? {}\n const props: Record<string, unknown> = {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (!declared[name] || value === undefined) continue\n if (typeof value === 'string' && CSS_LENGTH.test(value)) continue\n props[name] = value\n }\n if (componentId === 'muiTypography') {\n const variant = props['variant']\n if (variant === 'h6') props['component'] = 'p'\n else if (isHeadlineVariant(variant)) props['component'] = headings++ === 0 ? 'h1' : 'h2'\n }\n if (Object.keys(props).length) shaped.props = props\n if (node.sx && Object.keys(node.sx).length) shaped.sx = node.sx\n const children = (Array.isArray(node.nodes) ? (node.nodes as unknown[]) : [])\n .map((child) => (typeof child === 'string' ? visit(child) : null))\n .filter((child): child is string => child !== null)\n if (children.length) shaped.nodes = children\n return id\n }\n visit(CANVAS_ROOT_ELEMENT_ID)\n return unavailable ? null : { rootId: CANVAS_ROOT_ELEMENT_ID, nodes: out }\n}\n\n/** A tree's element structure without its copy or ids, to show one shape once. */\nfunction shapeOf(tree: AiDoctrineTree, id = tree.rootId): string {\n const node = tree.nodes[id]\n return `${node.componentId}(${(node.nodes ?? []).map((child) => shapeOf(tree, child)).join(',')})`\n}\n\n/** Every starter page the doctrine accepts as a template exactly as the example shows it. */\nexport function aiStarterTemplateExamples(\n starters: readonly StarterTemplate[] = STARTER_TEMPLATES,\n): AiTemplateExample[] {\n const examples: AiTemplateExample[] = []\n const shapes = new Set<string>()\n for (const starter of starters) {\n for (const screen of starter.screens) {\n const tree = aiStarterExampleTree(screen.nodes as Record<string, StarterNode>)\n if (!tree) continue\n const report = validateAiDoctrineTree(tree, 'template')\n if (!report.ok || !report.tree || report.tree.repairs.length) continue\n const shape = shapeOf(tree)\n if (shapes.has(shape)) continue\n shapes.add(shape)\n examples.push({ starter: starter.displayName, page: screen.displayName, tree })\n }\n }\n return examples\n}\n\nexport const AI_TEMPLATE_EXAMPLES_PREAMBLE = [\n 'Examples: pages from the platform’s starter sites, in the node-map shape the tool takes.',\n 'Build the way they are built: each band a Container at a stock width (xl for a marketing band, lg for an interactive one, md for prose) with vertical padding on the spacing scale, its content in a Stack, and one h1 for the page.',\n 'Their copy is the starter’s own; a template binds its subject’s tokens wherever a record’s own words, links or pictures go.',\n].join(' ')\n\n/** The examples as one cached system block, held to its ceiling an example at a time. */\nexport function aiTemplateExamplesBlock(\n examples: readonly AiTemplateExample[] = aiStarterTemplateExamples(),\n): AiSystemBlock {\n const parts = [AI_TEMPLATE_EXAMPLES_PREAMBLE]\n let used = AI_TEMPLATE_EXAMPLES_PREAMBLE.length\n for (const example of examples) {\n const text = `Starter \"${example.starter}\", page \"${example.page}\":\\n${JSON.stringify(example.tree)}`\n if (used + text.length + 2 > AI_TEMPLATE_EXAMPLES_MAX_CHARS) continue\n parts.push(text)\n used += text.length + 2\n }\n return { text: parts.join('\\n\\n'), cacheBreakpoint: true }\n}\n\nlet examplesBlock: AiSystemBlock | null = null\n\n/** The block a template generation sends, built once per process from the starters. */\nexport function aiTemplateExamplesSystemBlock(): AiSystemBlock {\n examplesBlock ??= aiTemplateExamplesBlock()\n return examplesBlock\n}\n"],"names":["STARTER_TEMPLATES","CANVAS_ROOT_ELEMENT_ID","validateAiDoctrineTree","isHeadlineVariant","AI_PALETTE","AI_SURFACES","AI_TEMPLATE_EXAMPLES_MAX_CHARS","FORM_COMPONENTS","Set","LINK_COMPONENTS","linksNowhere","componentId","props","has","named","value","trim","CSS_LENGTH","aiStarterExampleTree","nodes","allowed","screen","allow","out","headings","unavailable","visit","id","node","String","root","shaped","declared","propsSchema","properties","name","Object","entries","undefined","test","variant","keys","length","sx","children","Array","isArray","map","child","filter","rootId","shapeOf","tree","join","aiStarterTemplateExamples","starters","examples","shapes","starter","screens","report","ok","repairs","shape","add","push","displayName","page","AI_TEMPLATE_EXAMPLES_PREAMBLE","aiTemplateExamplesBlock","parts","used","example","text","JSON","stringify","cacheBreakpoint","examplesBlock","aiTemplateExamplesSystemBlock"],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
export interface AssistCachedAnswer {
|
|
18
|
+
answer: string;
|
|
19
|
+
docs: {
|
|
20
|
+
title: string;
|
|
21
|
+
url: string;
|
|
22
|
+
}[];
|
|
23
|
+
/** Epoch ms the entry was written. */
|
|
24
|
+
at: number;
|
|
25
|
+
}
|
|
26
|
+
export interface AssistAnswerCacheInputs {
|
|
27
|
+
question: string;
|
|
28
|
+
/** 'free' or 'entitled' — different capability levels, different answers. */
|
|
29
|
+
tier: string;
|
|
30
|
+
/** The console route the question was asked from ('' when none). */
|
|
31
|
+
route: string;
|
|
32
|
+
/** The serving model id. */
|
|
33
|
+
model: string;
|
|
34
|
+
/** The product name the assistant answers under (white-label aware). */
|
|
35
|
+
productName: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Normalise a question so trivially different phrasings share an entry.
|
|
39
|
+
*
|
|
40
|
+
* Case, surrounding whitespace, internal runs of whitespace and trailing
|
|
41
|
+
* punctuation only. Deliberately NOT stemming, stop-word removal or token
|
|
42
|
+
* sorting: those would make "how do I turn OFF maintenance mode" and "how do
|
|
43
|
+
* I turn ON maintenance mode" the same key, and serving one for the other is
|
|
44
|
+
* a wrong answer rather than a missed saving. A cache key may only ever
|
|
45
|
+
* collapse differences that cannot change the answer.
|
|
46
|
+
*/
|
|
47
|
+
export declare function normaliseAssistQuestion(question: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* The cache key: a hash over EVERY input that can change the answer.
|
|
50
|
+
*
|
|
51
|
+
* Joined on {@link CACHE_KEY_DELIMITER}, which no part can contain.
|
|
52
|
+
*/
|
|
53
|
+
export declare function assistAnswerCacheKey(inputs: AssistAnswerCacheInputs): string;
|
|
54
|
+
/** Whether an entry is still inside the freshness window. */
|
|
55
|
+
export declare function assistCacheEntryIsFresh(entry: AssistCachedAnswer | null | undefined, now?: number): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Read one cached answer, or `null`.
|
|
58
|
+
*
|
|
59
|
+
* Never throws: a cache is an optimisation, and an unavailable one must cost
|
|
60
|
+
* a model call rather than the user's answer. The caller therefore cannot
|
|
61
|
+
* tell a miss from an outage, which is correct — both mean "call the model".
|
|
62
|
+
*/
|
|
63
|
+
export declare function readAssistAnswerCache(firestore: FirebaseFirestore.Firestore, orgId: string, key: string, now?: number): Promise<AssistCachedAnswer | null>;
|
|
64
|
+
/**
|
|
65
|
+
* Store one answer, pruning the document back to {@link MAX_CACHE_ENTRIES}.
|
|
66
|
+
*
|
|
67
|
+
* Read-then-write rather than a blind merging set, because pruning needs to
|
|
68
|
+
* see what is already there. Not a transaction: two concurrent writers can
|
|
69
|
+
* lose one entry to each other, and losing a cache entry costs one model call
|
|
70
|
+
* later — a transaction would cost a contended write on every escalation to
|
|
71
|
+
* prevent that. The counters this module must never race are in
|
|
72
|
+
* `reserveAssistMessage`, and none of them are here.
|
|
73
|
+
*
|
|
74
|
+
* Never throws, for the same reason the read does not.
|
|
75
|
+
*/
|
|
76
|
+
export declare function writeAssistAnswerCache(firestore: FirebaseFirestore.Firestore, orgId: string, key: string, value: Omit<AssistCachedAnswer, 'at'>, now?: number): Promise<void>;
|
|
77
|
+
/** Exported for the spec — the bound the pruning enforces. */
|
|
78
|
+
export declare const ASSIST_ANSWER_CACHE_LIMIT = 60;
|
|
79
|
+
/** Exported for the spec — the freshness window in ms. */
|
|
80
|
+
export declare const ASSIST_ANSWER_CACHE_TTL_MS: number;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ import { createHash } from "node:crypto";
|
|
18
|
+
/**
|
|
19
|
+
* The answer cache for Aglyn Assist escalations (AGL-2486).
|
|
20
|
+
*
|
|
21
|
+
* An identical question asked twice must not buy two completions. Retrieval
|
|
22
|
+
* deflection already takes most of the repeats — the questions people ask over
|
|
23
|
+
* and over are exactly the ones the documentation answers — so what reaches
|
|
24
|
+
* here is the residue: the docs-shaped questions retrieval was not confident
|
|
25
|
+
* enough about, asked again a week later in the same words. The yield is
|
|
26
|
+
* therefore modest by construction, and saying so is the honest framing: this
|
|
27
|
+
* is the second lever, not the first.
|
|
28
|
+
*
|
|
29
|
+
* ## Scoped to ONE workspace, deliberately
|
|
30
|
+
*
|
|
31
|
+
* A cross-tenant cache would hit far more often, and it is the wrong trade.
|
|
32
|
+
* An entitled answer is composed against that workspace's own name, plan and
|
|
33
|
+
* current screen, and every deployment can carry white-label orgs whose
|
|
34
|
+
* assistant answers under their own product name. Sharing an entry between
|
|
35
|
+
* two workspaces means one workspace's facts reaching the other's panel the
|
|
36
|
+
* first time a key collides, and a cache is the last place anyone looks for
|
|
37
|
+
* that. `orgs/{orgId}/…` makes it impossible rather than unlikely.
|
|
38
|
+
*
|
|
39
|
+
* The key still carries every input that varies the answer — see
|
|
40
|
+
* {@link assistAnswerCacheKey}. Scoping alone is not enough: within one
|
|
41
|
+
* workspace a free member and a Pro member get different capability levels,
|
|
42
|
+
* and two people on different screens get different guidance.
|
|
43
|
+
*
|
|
44
|
+
* ## One document, self-pruning — and why not a TTL
|
|
45
|
+
*
|
|
46
|
+
* Entries live in a single `counters/assistAnswerCache` document as a map,
|
|
47
|
+
* pruned to {@link MAX_CACHE_ENTRIES} newest on every write. That shape was
|
|
48
|
+
* chosen against a per-document collection with a TTL field, which is the
|
|
49
|
+
* more obvious design and the worse one here:
|
|
50
|
+
*
|
|
51
|
+
* - A Firestore TTL policy is MANUAL gcloud configuration, not repo state
|
|
52
|
+
* (see `docs/FIRESTORE_MANUAL_CONFIG.md`). A new collection that assumes one
|
|
53
|
+
* grows without bound on every deployment where nobody ran the command —
|
|
54
|
+
* including every self-hoster, none of whom will know it exists.
|
|
55
|
+
* - Pruning on write needs no policy, no index and no operator step, and it
|
|
56
|
+
* bounds the document on the deployment that is actually using it.
|
|
57
|
+
*
|
|
58
|
+
* Write contention is the cost, and it is affordable: escalations are bounded
|
|
59
|
+
* by the message caps (ten a day free, a thousand a month entitled), which is
|
|
60
|
+
* orders of magnitude under the per-document write ceiling.
|
|
61
|
+
*
|
|
62
|
+
* ## Staleness
|
|
63
|
+
*
|
|
64
|
+
* An entry expires after {@link CACHE_TTL_MS}. The bound exists because the
|
|
65
|
+
* product moves: an answer describing a screen that has since been rebuilt is
|
|
66
|
+
* worse than no cache, and unlike a docs deflection there is no live citation
|
|
67
|
+
* for the user to check it against. Expiry is evaluated on READ as well as
|
|
68
|
+
* pruned on write, so a stale entry cannot be served by a deployment that has
|
|
69
|
+
* stopped writing.
|
|
70
|
+
*/ /** Cached answers kept per workspace. */ const MAX_CACHE_ENTRIES = 60;
|
|
71
|
+
/**
|
|
72
|
+
* How long a cached answer may be served — seven days.
|
|
73
|
+
*
|
|
74
|
+
* Long enough that a question asked on Monday and again the following Monday
|
|
75
|
+
* hits, which is the recurrence pattern this exists for; short enough that an
|
|
76
|
+
* answer never outlives a release cycle by much. The failure it bounds is an
|
|
77
|
+
* answer that was right when it was written and is now confidently describing
|
|
78
|
+
* a screen that changed.
|
|
79
|
+
*/ const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
80
|
+
/** One doc per org, beside the other `counters/*` documents. */ const CACHE_DOC = 'assistAnswerCache';
|
|
81
|
+
/**
|
|
82
|
+
* Normalise a question so trivially different phrasings share an entry.
|
|
83
|
+
*
|
|
84
|
+
* Case, surrounding whitespace, internal runs of whitespace and trailing
|
|
85
|
+
* punctuation only. Deliberately NOT stemming, stop-word removal or token
|
|
86
|
+
* sorting: those would make "how do I turn OFF maintenance mode" and "how do
|
|
87
|
+
* I turn ON maintenance mode" the same key, and serving one for the other is
|
|
88
|
+
* a wrong answer rather than a missed saving. A cache key may only ever
|
|
89
|
+
* collapse differences that cannot change the answer.
|
|
90
|
+
*/ export function normaliseAssistQuestion(question) {
|
|
91
|
+
return String(question != null ? question : '').toLowerCase().replace(/\s+/g, ' ').replace(/[\s?!.,;:]+$/g, '').trim();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The delimiter the key parts are joined on: NUL, written as an ESCAPE rather
|
|
95
|
+
* than as a literal byte.
|
|
96
|
+
*
|
|
97
|
+
* NUL because it is the one character that cannot appear in a question, a
|
|
98
|
+
* route, a model id or a product name, so no pair of different inputs can
|
|
99
|
+
* concatenate into the same string — the classic way a hashed composite key
|
|
100
|
+
* develops collisions that read as cache bugs.
|
|
101
|
+
*
|
|
102
|
+
* As an escape because a literal NUL in the source makes git classify the
|
|
103
|
+
* whole file as BINARY: no diff, no review, no blame. It shipped that way once
|
|
104
|
+
* and the commit carried `Bin 0 -> 9601 bytes` where the file should have been.
|
|
105
|
+
*/ const CACHE_KEY_DELIMITER = '\u0000';
|
|
106
|
+
/**
|
|
107
|
+
* The cache key: a hash over EVERY input that can change the answer.
|
|
108
|
+
*
|
|
109
|
+
* Joined on {@link CACHE_KEY_DELIMITER}, which no part can contain.
|
|
110
|
+
*/ export function assistAnswerCacheKey(inputs) {
|
|
111
|
+
var _inputs_tier, _inputs_route, _inputs_model, _inputs_productName;
|
|
112
|
+
const parts = [
|
|
113
|
+
normaliseAssistQuestion(inputs.question),
|
|
114
|
+
String((_inputs_tier = inputs.tier) != null ? _inputs_tier : ''),
|
|
115
|
+
String((_inputs_route = inputs.route) != null ? _inputs_route : ''),
|
|
116
|
+
String((_inputs_model = inputs.model) != null ? _inputs_model : ''),
|
|
117
|
+
String((_inputs_productName = inputs.productName) != null ? _inputs_productName : '')
|
|
118
|
+
];
|
|
119
|
+
return createHash('sha256').update(parts.join(CACHE_KEY_DELIMITER)).digest('hex').slice(0, 32);
|
|
120
|
+
}
|
|
121
|
+
/** Whether an entry is still inside the freshness window. */ export function assistCacheEntryIsFresh(entry, now = Date.now()) {
|
|
122
|
+
if (!entry || typeof entry.answer !== 'string' || !entry.answer) return false;
|
|
123
|
+
const at = Number(entry.at);
|
|
124
|
+
// `strictNullChecks` is off repo-wide, so a missing `at` reads as NaN rather
|
|
125
|
+
// than failing a null check. NaN fails every comparison, which is the right
|
|
126
|
+
// way round: an entry that cannot say when it was written is not fresh.
|
|
127
|
+
if (!Number.isFinite(at)) return false;
|
|
128
|
+
return now - at < CACHE_TTL_MS;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Read one cached answer, or `null`.
|
|
132
|
+
*
|
|
133
|
+
* Never throws: a cache is an optimisation, and an unavailable one must cost
|
|
134
|
+
* a model call rather than the user's answer. The caller therefore cannot
|
|
135
|
+
* tell a miss from an outage, which is correct — both mean "call the model".
|
|
136
|
+
*/ export async function readAssistAnswerCache(firestore, orgId, key, now = Date.now()) {
|
|
137
|
+
try {
|
|
138
|
+
const snapshot = await firestore.collection('orgs').doc(orgId).collection('counters').doc(CACHE_DOC).get();
|
|
139
|
+
const entry = snapshot.get(key);
|
|
140
|
+
return assistCacheEntryIsFresh(entry, now) ? entry : null;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error('assist answer cache read failed', error);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Store one answer, pruning the document back to {@link MAX_CACHE_ENTRIES}.
|
|
148
|
+
*
|
|
149
|
+
* Read-then-write rather than a blind merging set, because pruning needs to
|
|
150
|
+
* see what is already there. Not a transaction: two concurrent writers can
|
|
151
|
+
* lose one entry to each other, and losing a cache entry costs one model call
|
|
152
|
+
* later — a transaction would cost a contended write on every escalation to
|
|
153
|
+
* prevent that. The counters this module must never race are in
|
|
154
|
+
* `reserveAssistMessage`, and none of them are here.
|
|
155
|
+
*
|
|
156
|
+
* Never throws, for the same reason the read does not.
|
|
157
|
+
*/ export async function writeAssistAnswerCache(firestore, orgId, key, value, now = Date.now()) {
|
|
158
|
+
try {
|
|
159
|
+
var _snapshot_data, _value_docs;
|
|
160
|
+
const ref = firestore.collection('orgs').doc(orgId).collection('counters').doc(CACHE_DOC);
|
|
161
|
+
const snapshot = await ref.get();
|
|
162
|
+
const existing = (_snapshot_data = snapshot.data()) != null ? _snapshot_data : {};
|
|
163
|
+
const next = _extends({}, existing, {
|
|
164
|
+
[key]: {
|
|
165
|
+
answer: value.answer,
|
|
166
|
+
docs: (_value_docs = value.docs) != null ? _value_docs : [],
|
|
167
|
+
at: now
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
const fresh = Object.entries(next).filter(([, entry])=>assistCacheEntryIsFresh(entry, now));
|
|
171
|
+
fresh.sort((a, b)=>Number(b[1].at) - Number(a[1].at));
|
|
172
|
+
// A full `set` without merge, so pruning actually REMOVES entries. A
|
|
173
|
+
// merging set can only ever add: the document would keep every key it had
|
|
174
|
+
// and the cap would be a comment. This is the one place a non-merging
|
|
175
|
+
// write is correct, and it is safe only because nothing else writes here.
|
|
176
|
+
await ref.set(Object.fromEntries(fresh.slice(0, MAX_CACHE_ENTRIES)));
|
|
177
|
+
} catch (error) {
|
|
178
|
+
console.error('assist answer cache write failed', error);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Exported for the spec — the bound the pruning enforces. */ export const ASSIST_ANSWER_CACHE_LIMIT = MAX_CACHE_ENTRIES;
|
|
182
|
+
/** Exported for the spec — the freshness window in ms. */ export const ASSIST_ANSWER_CACHE_TTL_MS = CACHE_TTL_MS;
|
|
183
|
+
|
|
184
|
+
//# sourceMappingURL=assist-answer-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/assist-answer-cache.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 { createHash } from 'node:crypto'\n\n/**\n * The answer cache for Aglyn Assist escalations (AGL-2486).\n *\n * An identical question asked twice must not buy two completions. Retrieval\n * deflection already takes most of the repeats — the questions people ask over\n * and over are exactly the ones the documentation answers — so what reaches\n * here is the residue: the docs-shaped questions retrieval was not confident\n * enough about, asked again a week later in the same words. The yield is\n * therefore modest by construction, and saying so is the honest framing: this\n * is the second lever, not the first.\n *\n * ## Scoped to ONE workspace, deliberately\n *\n * A cross-tenant cache would hit far more often, and it is the wrong trade.\n * An entitled answer is composed against that workspace's own name, plan and\n * current screen, and every deployment can carry white-label orgs whose\n * assistant answers under their own product name. Sharing an entry between\n * two workspaces means one workspace's facts reaching the other's panel the\n * first time a key collides, and a cache is the last place anyone looks for\n * that. `orgs/{orgId}/…` makes it impossible rather than unlikely.\n *\n * The key still carries every input that varies the answer — see\n * {@link assistAnswerCacheKey}. Scoping alone is not enough: within one\n * workspace a free member and a Pro member get different capability levels,\n * and two people on different screens get different guidance.\n *\n * ## One document, self-pruning — and why not a TTL\n *\n * Entries live in a single `counters/assistAnswerCache` document as a map,\n * pruned to {@link MAX_CACHE_ENTRIES} newest on every write. That shape was\n * chosen against a per-document collection with a TTL field, which is the\n * more obvious design and the worse one here:\n *\n * - A Firestore TTL policy is MANUAL gcloud configuration, not repo state\n * (see `docs/FIRESTORE_MANUAL_CONFIG.md`). A new collection that assumes one\n * grows without bound on every deployment where nobody ran the command —\n * including every self-hoster, none of whom will know it exists.\n * - Pruning on write needs no policy, no index and no operator step, and it\n * bounds the document on the deployment that is actually using it.\n *\n * Write contention is the cost, and it is affordable: escalations are bounded\n * by the message caps (ten a day free, a thousand a month entitled), which is\n * orders of magnitude under the per-document write ceiling.\n *\n * ## Staleness\n *\n * An entry expires after {@link CACHE_TTL_MS}. The bound exists because the\n * product moves: an answer describing a screen that has since been rebuilt is\n * worse than no cache, and unlike a docs deflection there is no live citation\n * for the user to check it against. Expiry is evaluated on READ as well as\n * pruned on write, so a stale entry cannot be served by a deployment that has\n * stopped writing.\n */\n\n/** Cached answers kept per workspace. */\nconst MAX_CACHE_ENTRIES = 60\n\n/**\n * How long a cached answer may be served — seven days.\n *\n * Long enough that a question asked on Monday and again the following Monday\n * hits, which is the recurrence pattern this exists for; short enough that an\n * answer never outlives a release cycle by much. The failure it bounds is an\n * answer that was right when it was written and is now confidently describing\n * a screen that changed.\n */\nconst CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000\n\n/** One doc per org, beside the other `counters/*` documents. */\nconst CACHE_DOC = 'assistAnswerCache'\n\nexport interface AssistCachedAnswer {\n answer: string\n docs: { title: string; url: string }[]\n /** Epoch ms the entry was written. */\n at: number\n}\n\nexport interface AssistAnswerCacheInputs {\n question: string\n /** 'free' or 'entitled' — different capability levels, different answers. */\n tier: string\n /** The console route the question was asked from ('' when none). */\n route: string\n /** The serving model id. */\n model: string\n /** The product name the assistant answers under (white-label aware). */\n productName: string\n}\n\n/**\n * Normalise a question so trivially different phrasings share an entry.\n *\n * Case, surrounding whitespace, internal runs of whitespace and trailing\n * punctuation only. Deliberately NOT stemming, stop-word removal or token\n * sorting: those would make \"how do I turn OFF maintenance mode\" and \"how do\n * I turn ON maintenance mode\" the same key, and serving one for the other is\n * a wrong answer rather than a missed saving. A cache key may only ever\n * collapse differences that cannot change the answer.\n */\nexport function normaliseAssistQuestion(question: string): string {\n return String(question ?? '')\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .replace(/[\\s?!.,;:]+$/g, '')\n .trim()\n}\n\n/**\n * The delimiter the key parts are joined on: NUL, written as an ESCAPE rather\n * than as a literal byte.\n *\n * NUL because it is the one character that cannot appear in a question, a\n * route, a model id or a product name, so no pair of different inputs can\n * concatenate into the same string — the classic way a hashed composite key\n * develops collisions that read as cache bugs.\n *\n * As an escape because a literal NUL in the source makes git classify the\n * whole file as BINARY: no diff, no review, no blame. It shipped that way once\n * and the commit carried `Bin 0 -> 9601 bytes` where the file should have been.\n */\nconst CACHE_KEY_DELIMITER = '\\u0000'\n\n/**\n * The cache key: a hash over EVERY input that can change the answer.\n *\n * Joined on {@link CACHE_KEY_DELIMITER}, which no part can contain.\n */\nexport function assistAnswerCacheKey(inputs: AssistAnswerCacheInputs): string {\n const parts = [\n normaliseAssistQuestion(inputs.question),\n String(inputs.tier ?? ''),\n String(inputs.route ?? ''),\n String(inputs.model ?? ''),\n String(inputs.productName ?? ''),\n ]\n return createHash('sha256')\n .update(parts.join(CACHE_KEY_DELIMITER))\n .digest('hex')\n .slice(0, 32)\n}\n\n/** Whether an entry is still inside the freshness window. */\nexport function assistCacheEntryIsFresh(\n entry: AssistCachedAnswer | null | undefined,\n now = Date.now(),\n): boolean {\n if (!entry || typeof entry.answer !== 'string' || !entry.answer) return false\n const at = Number(entry.at)\n // `strictNullChecks` is off repo-wide, so a missing `at` reads as NaN rather\n // than failing a null check. NaN fails every comparison, which is the right\n // way round: an entry that cannot say when it was written is not fresh.\n if (!Number.isFinite(at)) return false\n return now - at < CACHE_TTL_MS\n}\n\n/**\n * Read one cached answer, or `null`.\n *\n * Never throws: a cache is an optimisation, and an unavailable one must cost\n * a model call rather than the user's answer. The caller therefore cannot\n * tell a miss from an outage, which is correct — both mean \"call the model\".\n */\nexport async function readAssistAnswerCache(\n firestore: FirebaseFirestore.Firestore,\n orgId: string,\n key: string,\n now = Date.now(),\n): Promise<AssistCachedAnswer | null> {\n try {\n const snapshot = await firestore\n .collection('orgs')\n .doc(orgId)\n .collection('counters')\n .doc(CACHE_DOC)\n .get()\n const entry = snapshot.get(key) as AssistCachedAnswer | undefined\n return assistCacheEntryIsFresh(entry, now) ? entry : null\n } catch (error) {\n console.error('assist answer cache read failed', error)\n return null\n }\n}\n\n/**\n * Store one answer, pruning the document back to {@link MAX_CACHE_ENTRIES}.\n *\n * Read-then-write rather than a blind merging set, because pruning needs to\n * see what is already there. Not a transaction: two concurrent writers can\n * lose one entry to each other, and losing a cache entry costs one model call\n * later — a transaction would cost a contended write on every escalation to\n * prevent that. The counters this module must never race are in\n * `reserveAssistMessage`, and none of them are here.\n *\n * Never throws, for the same reason the read does not.\n */\nexport async function writeAssistAnswerCache(\n firestore: FirebaseFirestore.Firestore,\n orgId: string,\n key: string,\n value: Omit<AssistCachedAnswer, 'at'>,\n now = Date.now(),\n): Promise<void> {\n try {\n const ref = firestore\n .collection('orgs')\n .doc(orgId)\n .collection('counters')\n .doc(CACHE_DOC)\n const snapshot = await ref.get()\n const existing = (snapshot.data() ?? {}) as Record<\n string,\n AssistCachedAnswer\n >\n const next: Record<string, AssistCachedAnswer> = {\n ...existing,\n [key]: { answer: value.answer, docs: value.docs ?? [], at: now },\n }\n const fresh = Object.entries(next).filter(([, entry]) =>\n assistCacheEntryIsFresh(entry, now),\n )\n fresh.sort((a, b) => Number(b[1].at) - Number(a[1].at))\n // A full `set` without merge, so pruning actually REMOVES entries. A\n // merging set can only ever add: the document would keep every key it had\n // and the cap would be a comment. This is the one place a non-merging\n // write is correct, and it is safe only because nothing else writes here.\n await ref.set(Object.fromEntries(fresh.slice(0, MAX_CACHE_ENTRIES)))\n } catch (error) {\n console.error('assist answer cache write failed', error)\n }\n}\n\n/** Exported for the spec — the bound the pruning enforces. */\nexport const ASSIST_ANSWER_CACHE_LIMIT = MAX_CACHE_ENTRIES\n/** Exported for the spec — the freshness window in ms. */\nexport const ASSIST_ANSWER_CACHE_TTL_MS = CACHE_TTL_MS\n"],"names":["createHash","MAX_CACHE_ENTRIES","CACHE_TTL_MS","CACHE_DOC","normaliseAssistQuestion","question","String","toLowerCase","replace","trim","CACHE_KEY_DELIMITER","assistAnswerCacheKey","inputs","parts","tier","route","model","productName","update","join","digest","slice","assistCacheEntryIsFresh","entry","now","Date","answer","at","Number","isFinite","readAssistAnswerCache","firestore","orgId","key","snapshot","collection","doc","get","error","console","writeAssistAnswerCache","value","ref","existing","data","next","docs","fresh","Object","entries","filter","sort","a","b","set","fromEntries","ASSIST_ANSWER_CACHE_LIMIT","ASSIST_ANSWER_CACHE_TTL_MS"],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
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 { AiSeoAuditReport, AiSeoContentFix } from '../model/ai-seo';
|
|
18
|
+
import type { AiSeoPageFacts } from './seo-page-facts';
|
|
19
|
+
/**
|
|
20
|
+
* The site SEO audit's scoring (AGL-2910): every audited page held to what a
|
|
21
|
+
* search result and a crawler need, with nothing asked of a model. Pure, so
|
|
22
|
+
* the audit is proved against fixtures and a job only spends tokens on the
|
|
23
|
+
* fixes it cannot make without writing.
|
|
24
|
+
*
|
|
25
|
+
* Per page: a title and a description of its own, within their lengths and
|
|
26
|
+
* used on no other page; one main heading that says something; a description
|
|
27
|
+
* on every image; a link from somewhere else on the site; and the target
|
|
28
|
+
* keywords a person named, reported where the page already says them.
|
|
29
|
+
* Per site: whether search engines are told to stay away, whether the
|
|
30
|
+
* structured data names and describes the publisher, and whether agents get
|
|
31
|
+
* guidance of the author's own.
|
|
32
|
+
*
|
|
33
|
+
* Keyword coverage is reported, never forced. A page that does not say a
|
|
34
|
+
* keyword is told so; the fix a job proposes uses the keyword only where the
|
|
35
|
+
* page is about it, and the listing check refuses a keyword used past its
|
|
36
|
+
* per-field count.
|
|
37
|
+
*/
|
|
38
|
+
/** Pages one audit covers. A larger site is audited on its first pages by path, and says how many it left. */
|
|
39
|
+
export declare const AI_SEO_AUDIT_MAX_PAGES = 150;
|
|
40
|
+
/** Pages one batch of fixes carries: one model call a batch. */
|
|
41
|
+
export declare const AI_SEO_AUDIT_BATCH_SIZE = 8;
|
|
42
|
+
/** One page as the audit reads it. */
|
|
43
|
+
export interface AiSeoAuditPage {
|
|
44
|
+
screenId: string;
|
|
45
|
+
/** The public path, `/` for the home page. */
|
|
46
|
+
path: string;
|
|
47
|
+
name: string;
|
|
48
|
+
versionId: string | null;
|
|
49
|
+
seo: {
|
|
50
|
+
title?: string | null;
|
|
51
|
+
description?: string | null;
|
|
52
|
+
breadcrumb?: string | null;
|
|
53
|
+
image?: string | null;
|
|
54
|
+
imageAlt?: string | null;
|
|
55
|
+
};
|
|
56
|
+
/** The screen's own description, which the head falls back to. */
|
|
57
|
+
description?: string | null;
|
|
58
|
+
facts: AiSeoPageFacts;
|
|
59
|
+
/** Whether another audited page or a shared layout links here. */
|
|
60
|
+
linkedFrom: boolean;
|
|
61
|
+
keywords: readonly string[];
|
|
62
|
+
}
|
|
63
|
+
/** The site as the audit reads it. */
|
|
64
|
+
export interface AiSeoAuditSite {
|
|
65
|
+
discouraged: boolean;
|
|
66
|
+
entity: {
|
|
67
|
+
name?: string | null;
|
|
68
|
+
description?: string | null;
|
|
69
|
+
};
|
|
70
|
+
agent: {
|
|
71
|
+
whenToUse?: string | null;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** A path as the keyword lines and the routing map both spell it: leading slash, no trailing one. */
|
|
75
|
+
export declare function aiSeoNormalizePath(path: string): string;
|
|
76
|
+
/**
|
|
77
|
+
* Target keywords per page, one line a page: `/pricing: plans, pricing`.
|
|
78
|
+
* A line without a path, or with a path the site does not have, names no
|
|
79
|
+
* page; the step reports the paths it could not match.
|
|
80
|
+
*/
|
|
81
|
+
export declare function parseAiSeoKeywordLines(raw: unknown): Record<string, string[]>;
|
|
82
|
+
/** Audit the pages and the site; nothing here reads, writes or generates. */
|
|
83
|
+
export declare function aiSeoAudit(pages: readonly AiSeoAuditPage[], site: AiSeoAuditSite, options?: {
|
|
84
|
+
skipped?: number;
|
|
85
|
+
batchSize?: number;
|
|
86
|
+
}): AiSeoAuditReport;
|
|
87
|
+
/**
|
|
88
|
+
* The content fixes that need no model: every main heading after the first
|
|
89
|
+
* editable one becomes an `h2`, so the page keeps one.
|
|
90
|
+
*/
|
|
91
|
+
export declare function aiSeoHeadingDemotions(facts: AiSeoPageFacts): AiSeoContentFix[];
|
|
92
|
+
/** The queue's batches, in order. */
|
|
93
|
+
export declare function aiSeoAuditBatches(report: Pick<AiSeoAuditReport, 'queue' | 'batchSize'>): string[][];
|