@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,488 @@
|
|
|
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 { CRM_MERGE_FIELDS, crmMergeFieldsIn } from "@aglyn/aglyn/app-utils/crm-email-templates";
|
|
18
|
+
import { AI_CRM_LIMITS } from "../model/ai-crm.js";
|
|
19
|
+
/**
|
|
20
|
+
* The strict tools CRM by AI answers through (AGL-2917), and the checks that
|
|
21
|
+
* hold each answer to what the CRM can take.
|
|
22
|
+
*
|
|
23
|
+
* - `propose_record_insight` — a record's summary, and by kind: the next step
|
|
24
|
+
* as a task (a contact, company or deal), a stage (a deal), a lead's
|
|
25
|
+
* standing. One schema per kind, so no answer carries a field its record
|
|
26
|
+
* cannot use, and each keeps its nullable fields to the one or two a member
|
|
27
|
+
* may legitimately be offered nothing for.
|
|
28
|
+
* - `propose_email_draft` — a subject and a plain-text message.
|
|
29
|
+
* - `propose_column_matches` — the columns of a file matched to import fields.
|
|
30
|
+
*
|
|
31
|
+
* A strict schema forbids extra keys, requires every key, says "no value" with
|
|
32
|
+
* `null`, and accepts no length keyword, so every length is stated in a
|
|
33
|
+
* description and enforced here. A check returns a value only when nothing in
|
|
34
|
+
* the answer is broken, and otherwise the violations and the parts at fault,
|
|
35
|
+
* for the generation call's one re-ask.
|
|
36
|
+
*/ export const AI_CRM_RECORD_TOOL_NAME = 'propose_record_insight';
|
|
37
|
+
export const AI_CRM_EMAIL_TOOL_NAME = 'propose_email_draft';
|
|
38
|
+
export const AI_CRM_MAPPING_TOOL_NAME = 'propose_column_matches';
|
|
39
|
+
const TASK_KINDS = [
|
|
40
|
+
'call',
|
|
41
|
+
'email',
|
|
42
|
+
'meeting',
|
|
43
|
+
'todo'
|
|
44
|
+
];
|
|
45
|
+
const PRIORITIES = [
|
|
46
|
+
'low',
|
|
47
|
+
'normal',
|
|
48
|
+
'high'
|
|
49
|
+
];
|
|
50
|
+
const string = (description)=>({
|
|
51
|
+
type: 'string',
|
|
52
|
+
description
|
|
53
|
+
});
|
|
54
|
+
const NEXT_STEP_SCHEMA = {
|
|
55
|
+
anyOf: [
|
|
56
|
+
{
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {
|
|
59
|
+
title: string(`The task, starting with a verb. At most ${AI_CRM_LIMITS.taskTitle} characters.`),
|
|
60
|
+
kind: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
enum: [
|
|
63
|
+
...TASK_KINDS
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
priority: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
enum: [
|
|
69
|
+
...PRIORITIES
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
dueInDays: {
|
|
73
|
+
type: 'integer',
|
|
74
|
+
description: `Days from today it is due, from 0 to ${AI_CRM_LIMITS.dueInDays}.`
|
|
75
|
+
},
|
|
76
|
+
reason: string(`Why, naming the fact behind it. At most ${AI_CRM_LIMITS.reason} characters.`)
|
|
77
|
+
},
|
|
78
|
+
required: [
|
|
79
|
+
'title',
|
|
80
|
+
'kind',
|
|
81
|
+
'priority',
|
|
82
|
+
'dueInDays',
|
|
83
|
+
'reason'
|
|
84
|
+
],
|
|
85
|
+
additionalProperties: false
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
type: 'null'
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
};
|
|
92
|
+
const STAGE_SCHEMA = {
|
|
93
|
+
anyOf: [
|
|
94
|
+
{
|
|
95
|
+
type: 'object',
|
|
96
|
+
properties: {
|
|
97
|
+
stageId: string('The id of an open stage the facts list, other than the current one.'),
|
|
98
|
+
reason: string(`The fact that shows the deal moved. At most ${AI_CRM_LIMITS.reason} characters.`)
|
|
99
|
+
},
|
|
100
|
+
required: [
|
|
101
|
+
'stageId',
|
|
102
|
+
'reason'
|
|
103
|
+
],
|
|
104
|
+
additionalProperties: false
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: 'null'
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
};
|
|
111
|
+
/** The record tool for one kind of record. */ export function aiCrmRecordTool(kind) {
|
|
112
|
+
const summary = string(`Where the relationship stands. At most ${AI_CRM_LIMITS.summary} characters and two sentences.`);
|
|
113
|
+
const properties = kind === 'lead' ? {
|
|
114
|
+
summary,
|
|
115
|
+
standing: string(`Why the lead stands where it does. At most ${AI_CRM_LIMITS.standing} characters and two sentences.`)
|
|
116
|
+
} : kind === 'deal' ? {
|
|
117
|
+
summary,
|
|
118
|
+
nextStep: NEXT_STEP_SCHEMA,
|
|
119
|
+
stage: STAGE_SCHEMA
|
|
120
|
+
} : {
|
|
121
|
+
summary,
|
|
122
|
+
nextStep: NEXT_STEP_SCHEMA
|
|
123
|
+
};
|
|
124
|
+
return {
|
|
125
|
+
name: AI_CRM_RECORD_TOOL_NAME,
|
|
126
|
+
description: 'Propose what a team member reads about one CRM record, and what to do next. Every field is required.',
|
|
127
|
+
strict: true,
|
|
128
|
+
inputSchema: {
|
|
129
|
+
type: 'object',
|
|
130
|
+
properties,
|
|
131
|
+
required: Object.keys(properties),
|
|
132
|
+
additionalProperties: false
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
export const AI_CRM_EMAIL_TOOL = {
|
|
137
|
+
name: AI_CRM_EMAIL_TOOL_NAME,
|
|
138
|
+
description: 'Propose one email for a team member to review, edit and send themselves.',
|
|
139
|
+
strict: true,
|
|
140
|
+
inputSchema: {
|
|
141
|
+
type: 'object',
|
|
142
|
+
properties: {
|
|
143
|
+
subject: string(`One line. At most ${AI_CRM_LIMITS.subject} characters.`),
|
|
144
|
+
body: string(`Plain text in short paragraphs separated by a blank line. At most ${AI_CRM_LIMITS.body.toLocaleString('en-US')} characters.`)
|
|
145
|
+
},
|
|
146
|
+
required: [
|
|
147
|
+
'subject',
|
|
148
|
+
'body'
|
|
149
|
+
],
|
|
150
|
+
additionalProperties: false
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
export const AI_CRM_MAPPING_TOOL = {
|
|
154
|
+
name: AI_CRM_MAPPING_TOOL_NAME,
|
|
155
|
+
description: 'Propose which columns of the file fill which fields. Leave out a column no field fits.',
|
|
156
|
+
strict: true,
|
|
157
|
+
inputSchema: {
|
|
158
|
+
type: 'object',
|
|
159
|
+
properties: {
|
|
160
|
+
matches: {
|
|
161
|
+
type: 'array',
|
|
162
|
+
items: {
|
|
163
|
+
type: 'object',
|
|
164
|
+
properties: {
|
|
165
|
+
column: {
|
|
166
|
+
type: 'integer',
|
|
167
|
+
description: 'The column’s number, as the request lists it.'
|
|
168
|
+
},
|
|
169
|
+
field: {
|
|
170
|
+
type: 'integer',
|
|
171
|
+
description: 'The field’s number, as the request lists it.'
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
required: [
|
|
175
|
+
'column',
|
|
176
|
+
'field'
|
|
177
|
+
],
|
|
178
|
+
additionalProperties: false
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
required: [
|
|
183
|
+
'matches'
|
|
184
|
+
],
|
|
185
|
+
additionalProperties: false
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const violation = (code, message, path)=>_extends({
|
|
189
|
+
rule: null,
|
|
190
|
+
code,
|
|
191
|
+
message
|
|
192
|
+
}, path ? {
|
|
193
|
+
paths: [
|
|
194
|
+
path
|
|
195
|
+
]
|
|
196
|
+
} : {});
|
|
197
|
+
const collapse = (value)=>typeof value === 'string' ? value.replace(/\s+/g, ' ').trim() : '';
|
|
198
|
+
/** A required text field held to its length; the value, or a violation. */ function textField(answer, key, label, max, violations, offending) {
|
|
199
|
+
const raw = answer[key];
|
|
200
|
+
if (typeof raw !== 'string') {
|
|
201
|
+
violations.push(violation('type', `${label} must be text.`, key));
|
|
202
|
+
offending[key] = raw;
|
|
203
|
+
return '';
|
|
204
|
+
}
|
|
205
|
+
const text = collapse(raw);
|
|
206
|
+
if (!text) {
|
|
207
|
+
violations.push(violation('missing', `${label} is empty.`, key));
|
|
208
|
+
offending[key] = raw;
|
|
209
|
+
} else if (text.length > max) {
|
|
210
|
+
violations.push(violation('too-long', `${label} is ${text.length} characters; at most ${max}.`, key));
|
|
211
|
+
offending[key] = raw;
|
|
212
|
+
}
|
|
213
|
+
return text;
|
|
214
|
+
}
|
|
215
|
+
const asText = (value)=>typeof value === 'string' ? value : '';
|
|
216
|
+
const asList = (value)=>Array.isArray(value) ? value.filter((entry)=>Boolean(entry) && typeof entry === 'object') : [];
|
|
217
|
+
function checkNextStep(raw, context, violations, offending) {
|
|
218
|
+
var _context_openTaskTitles;
|
|
219
|
+
if (raw === null) return null;
|
|
220
|
+
const step = raw;
|
|
221
|
+
if (typeof step !== 'object' || Array.isArray(step)) {
|
|
222
|
+
violations.push(violation('type', 'The next step must be a task or null.', 'nextStep'));
|
|
223
|
+
offending['nextStep'] = raw;
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const before = violations.length;
|
|
227
|
+
const title = textField(step, 'title', 'The next step’s title', AI_CRM_LIMITS.taskTitle, violations, {});
|
|
228
|
+
const reason = textField(step, 'reason', 'The next step’s reason', AI_CRM_LIMITS.reason, violations, {});
|
|
229
|
+
const kind = TASK_KINDS.find((entry)=>entry === step['kind']);
|
|
230
|
+
const priority = PRIORITIES.find((entry)=>entry === step['priority']);
|
|
231
|
+
if (!kind || !priority) violations.push(violation('type', 'The next step’s kind or priority is not one the CRM has.', 'nextStep'));
|
|
232
|
+
const due = step['dueInDays'];
|
|
233
|
+
if (typeof due !== 'number' || !Number.isInteger(due) || due < 0 || due > AI_CRM_LIMITS.dueInDays) {
|
|
234
|
+
violations.push(violation('next-step-due', `The next step must be due in 0 to ${AI_CRM_LIMITS.dueInDays} days.`, 'nextStep.dueInDays'));
|
|
235
|
+
}
|
|
236
|
+
const open = new Set(((_context_openTaskTitles = context.openTaskTitles) != null ? _context_openTaskTitles : []).map((entry)=>collapse(entry).toLowerCase()));
|
|
237
|
+
if (title && open.has(title.toLowerCase())) {
|
|
238
|
+
violations.push(violation('next-step-open', 'The next step repeats a task that is already open. Propose another, or null.', 'nextStep.title'));
|
|
239
|
+
}
|
|
240
|
+
if (violations.length > before) {
|
|
241
|
+
offending['nextStep'] = raw;
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
title,
|
|
246
|
+
kind: kind,
|
|
247
|
+
priority: priority,
|
|
248
|
+
dueInDays: due,
|
|
249
|
+
reason
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function checkStage(raw, context, violations, offending) {
|
|
253
|
+
var _context_stages;
|
|
254
|
+
if (raw === null) return null;
|
|
255
|
+
const stage = raw;
|
|
256
|
+
if (typeof stage !== 'object' || Array.isArray(stage)) {
|
|
257
|
+
violations.push(violation('type', 'The stage must be a move or null.', 'stage'));
|
|
258
|
+
offending['stage'] = raw;
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
const before = violations.length;
|
|
262
|
+
const reason = textField(stage, 'reason', 'The stage’s reason', AI_CRM_LIMITS.reason, violations, {});
|
|
263
|
+
const target = ((_context_stages = context.stages) != null ? _context_stages : []).find((entry)=>entry.id === stage['stageId']);
|
|
264
|
+
if (context.status && context.status !== 'open') {
|
|
265
|
+
violations.push(violation('stage-closed', 'The deal is already closed, so its stage must be null.', 'stage'));
|
|
266
|
+
} else if (!target) {
|
|
267
|
+
violations.push(violation('stage-unknown', 'The stage is not one the deal’s pipeline lists.', 'stage.stageId'));
|
|
268
|
+
} else if (target.kind !== 'open') {
|
|
269
|
+
violations.push(violation('stage-won-lost', 'Winning or losing a deal is the team’s call. Propose an open stage, or null.', 'stage.stageId'));
|
|
270
|
+
} else if (target.id === context.stageId) {
|
|
271
|
+
violations.push(violation('stage-current', 'The deal is already in that stage. Propose another, or null.', 'stage.stageId'));
|
|
272
|
+
}
|
|
273
|
+
if (violations.length > before || !target) {
|
|
274
|
+
offending['stage'] = raw;
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
stageId: target.id,
|
|
279
|
+
stageName: target.name,
|
|
280
|
+
reason
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/** What a record's facts say its check needs. */ export function aiCrmRecordCheckContext(kind, facts) {
|
|
284
|
+
return _extends({
|
|
285
|
+
kind,
|
|
286
|
+
openTaskTitles: asList(facts['openTasks']).map((task)=>asText(task['title']))
|
|
287
|
+
}, kind === 'deal' ? {
|
|
288
|
+
stageId: asText(facts['stageId']),
|
|
289
|
+
status: asText(facts['status']),
|
|
290
|
+
stages: asList(facts['stages']).map((stage)=>({
|
|
291
|
+
id: asText(stage['id']),
|
|
292
|
+
name: asText(stage['name']),
|
|
293
|
+
kind: asText(stage['kind'])
|
|
294
|
+
}))
|
|
295
|
+
} : {});
|
|
296
|
+
}
|
|
297
|
+
/** A record answer held to the record it is about. */ export function checkAiCrmRecord(answer, context) {
|
|
298
|
+
const violations = [];
|
|
299
|
+
const offending = {};
|
|
300
|
+
const summary = textField(answer, 'summary', 'The summary', AI_CRM_LIMITS.summary, violations, offending);
|
|
301
|
+
let nextStep = null;
|
|
302
|
+
let stage = null;
|
|
303
|
+
let standing = null;
|
|
304
|
+
if (context.kind === 'lead') {
|
|
305
|
+
standing = textField(answer, 'standing', 'The standing', AI_CRM_LIMITS.standing, violations, offending);
|
|
306
|
+
} else {
|
|
307
|
+
nextStep = checkNextStep(answer['nextStep'], context, violations, offending);
|
|
308
|
+
if (context.kind === 'deal') stage = checkStage(answer['stage'], context, violations, offending);
|
|
309
|
+
}
|
|
310
|
+
return violations.length ? {
|
|
311
|
+
value: null,
|
|
312
|
+
violations,
|
|
313
|
+
offending
|
|
314
|
+
} : {
|
|
315
|
+
value: {
|
|
316
|
+
summary,
|
|
317
|
+
nextStep,
|
|
318
|
+
stage,
|
|
319
|
+
standing
|
|
320
|
+
},
|
|
321
|
+
violations: []
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
/** The merge fields an email from a record may use: never an address. */ export function aiCrmEmailMergeFields(kind) {
|
|
325
|
+
const groups = kind === 'lead' ? [
|
|
326
|
+
'Lead'
|
|
327
|
+
] : kind === 'deal' ? [
|
|
328
|
+
'Contact',
|
|
329
|
+
'Deal'
|
|
330
|
+
] : [
|
|
331
|
+
'Contact'
|
|
332
|
+
];
|
|
333
|
+
return CRM_MERGE_FIELDS.filter((field)=>(groups.includes(field.group) || field.group === 'You' || field.group === 'Site') && !field.key.endsWith('.email')).map((field)=>field.key);
|
|
334
|
+
}
|
|
335
|
+
const EMAIL_ADDRESS = /[\w.+-]+@[\w-]+\.[\w.-]+/;
|
|
336
|
+
/** A run of digits and the separators a phone number is written with. */ const DIGIT_RUN = /\+?\d[\d\s().-]{7,}\d/g;
|
|
337
|
+
/** Calendar days, which the facts write and a draft may repeat. */ const DAYS_ONLY = /^\d{4}-\d{2}-\d{2}(?:\s+\d{4}-\d{2}-\d{2})*$/;
|
|
338
|
+
/** Whether text writes a phone number: a run of ten digits or more that is not a list of days. */ export function aiCrmWritesPhoneNumber(text) {
|
|
339
|
+
for (const [run] of text.matchAll(DIGIT_RUN)){
|
|
340
|
+
if (DAYS_ONLY.test(run.trim())) continue;
|
|
341
|
+
if (run.replace(/\D/g, '').length >= 10) return true;
|
|
342
|
+
}
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
const MARKDOWN = /\*\*|__|^#{1,6}\s|\[[^\]]+\]\([^)]+\)|```/m;
|
|
346
|
+
/** An email answer held to the composer and to what a person may be sent. */ export function checkAiCrmEmail(answer, context) {
|
|
347
|
+
const violations = [];
|
|
348
|
+
const offending = {};
|
|
349
|
+
const subject = textField(answer, 'subject', 'The subject', AI_CRM_LIMITS.subject, violations, offending);
|
|
350
|
+
const rawBody = typeof answer['body'] === 'string' ? answer['body'] : null;
|
|
351
|
+
const body = rawBody === null ? '' : rawBody.replace(/\r\n/g, '\n').replace(/[ \t]+\n/g, '\n').replace(/\n{3,}/g, '\n\n').trim();
|
|
352
|
+
if (rawBody === null) {
|
|
353
|
+
violations.push(violation('type', 'The message must be text.', 'body'));
|
|
354
|
+
offending['body'] = answer['body'];
|
|
355
|
+
} else if (!body) {
|
|
356
|
+
violations.push(violation('missing', 'The message is empty.', 'body'));
|
|
357
|
+
offending['body'] = rawBody;
|
|
358
|
+
} else if (body.length > AI_CRM_LIMITS.body) {
|
|
359
|
+
violations.push(violation('too-long', `The message is ${body.length} characters; at most ${AI_CRM_LIMITS.body}.`, 'body'));
|
|
360
|
+
offending['body'] = rawBody;
|
|
361
|
+
}
|
|
362
|
+
if (typeof answer['subject'] === 'string' && /[\r\n]/.test(answer['subject'].trim())) {
|
|
363
|
+
violations.push(violation('subject-lines', 'The subject must be one line.', 'subject'));
|
|
364
|
+
offending['subject'] = answer['subject'];
|
|
365
|
+
}
|
|
366
|
+
const allowed = new Set(context.mergeFields);
|
|
367
|
+
const unknown = [
|
|
368
|
+
...new Set([
|
|
369
|
+
...crmMergeFieldsIn(subject),
|
|
370
|
+
...crmMergeFieldsIn(body)
|
|
371
|
+
])
|
|
372
|
+
].filter((key)=>!allowed.has(key));
|
|
373
|
+
if (unknown.length) {
|
|
374
|
+
violations.push(violation('merge-field-unknown', `The draft uses merge fields this record cannot fill: ${unknown.join(', ')}.`));
|
|
375
|
+
}
|
|
376
|
+
const text = `${subject}\n${body}`;
|
|
377
|
+
if (EMAIL_ADDRESS.test(text) || aiCrmWritesPhoneNumber(text)) {
|
|
378
|
+
violations.push(violation('contact-detail', 'The draft writes an email address or a phone number. Leave them out.'));
|
|
379
|
+
}
|
|
380
|
+
if (MARKDOWN.test(body)) {
|
|
381
|
+
violations.push(violation('markdown', 'The message uses markdown. Write plain text.', 'body'));
|
|
382
|
+
offending['body'] = rawBody;
|
|
383
|
+
}
|
|
384
|
+
return violations.length ? {
|
|
385
|
+
value: null,
|
|
386
|
+
violations,
|
|
387
|
+
offending
|
|
388
|
+
} : {
|
|
389
|
+
value: {
|
|
390
|
+
subject,
|
|
391
|
+
body
|
|
392
|
+
},
|
|
393
|
+
violations: []
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
/** An import catalog's fields as the facts report them, in the order they are numbered. */ export function aiCrmImportFields(facts) {
|
|
397
|
+
return asList(facts['fields']).map((field)=>({
|
|
398
|
+
key: asText(field['key']),
|
|
399
|
+
label: asText(field['label']),
|
|
400
|
+
type: asText(field['type']) || 'text',
|
|
401
|
+
required: field['required'] === true
|
|
402
|
+
})).filter((field)=>field.key && field.label);
|
|
403
|
+
}
|
|
404
|
+
/** The column shapes each field type takes; a field type absent here takes any shape. */ const SHAPES_FOR_TYPE = {
|
|
405
|
+
email: [
|
|
406
|
+
'email',
|
|
407
|
+
'empty'
|
|
408
|
+
],
|
|
409
|
+
phone: [
|
|
410
|
+
'phone',
|
|
411
|
+
'number',
|
|
412
|
+
'empty'
|
|
413
|
+
],
|
|
414
|
+
number: [
|
|
415
|
+
'number',
|
|
416
|
+
'empty'
|
|
417
|
+
],
|
|
418
|
+
date: [
|
|
419
|
+
'date',
|
|
420
|
+
'empty'
|
|
421
|
+
],
|
|
422
|
+
'yes-no': [
|
|
423
|
+
'yes-no',
|
|
424
|
+
'empty'
|
|
425
|
+
]
|
|
426
|
+
};
|
|
427
|
+
/** A mapping answer held to the file's columns and the import's fields. */ export function checkAiCrmMapping(answer, context) {
|
|
428
|
+
const violations = [];
|
|
429
|
+
const raw = answer['matches'];
|
|
430
|
+
if (!Array.isArray(raw)) {
|
|
431
|
+
return {
|
|
432
|
+
value: null,
|
|
433
|
+
violations: [
|
|
434
|
+
violation('type', 'The matches must be a list.', 'matches')
|
|
435
|
+
],
|
|
436
|
+
offending: {
|
|
437
|
+
matches: raw
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
const columns = new Set();
|
|
442
|
+
const taken = new Set();
|
|
443
|
+
const matches = [];
|
|
444
|
+
const offending = [];
|
|
445
|
+
for (const entry of raw){
|
|
446
|
+
const match = entry != null ? entry : {};
|
|
447
|
+
const column = match['column'];
|
|
448
|
+
const number = match['field'];
|
|
449
|
+
const field = typeof number === 'number' && Number.isInteger(number) ? context.fields[number] : undefined;
|
|
450
|
+
const at = typeof column === 'number' && Number.isInteger(column) ? context.columns[column] : undefined;
|
|
451
|
+
if (!at) {
|
|
452
|
+
violations.push(violation('column-unknown', `Column ${String(column)} is not one the file has.`));
|
|
453
|
+
} else if (!field) {
|
|
454
|
+
violations.push(violation('field-unknown', `Field ${String(number)} is not one this import fills.`));
|
|
455
|
+
} else if (columns.has(column)) {
|
|
456
|
+
violations.push(violation('column-twice', `Column ${String(column)} is matched twice.`));
|
|
457
|
+
} else if (taken.has(field.key)) {
|
|
458
|
+
violations.push(violation('field-twice', `${field.label} takes one column, and two were matched to it.`));
|
|
459
|
+
} else if (SHAPES_FOR_TYPE[field.type] && !SHAPES_FOR_TYPE[field.type].includes(at.shape)) {
|
|
460
|
+
violations.push(violation('shape-mismatch', `Column ${String(column)} holds ${at.shape} values, which ${field.label} cannot take.`));
|
|
461
|
+
} else if (at.shape === 'email' && field.type !== 'email') {
|
|
462
|
+
violations.push(violation('shape-mismatch', `Column ${String(column)} holds email addresses, which ${field.label} is not.`));
|
|
463
|
+
} else {
|
|
464
|
+
columns.add(column);
|
|
465
|
+
taken.add(field.key);
|
|
466
|
+
matches.push({
|
|
467
|
+
column: column,
|
|
468
|
+
header: at.header,
|
|
469
|
+
field: field.key,
|
|
470
|
+
label: field.label
|
|
471
|
+
});
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
offending.push(entry);
|
|
475
|
+
}
|
|
476
|
+
return violations.length ? {
|
|
477
|
+
value: null,
|
|
478
|
+
violations,
|
|
479
|
+
offending: {
|
|
480
|
+
matches: offending
|
|
481
|
+
}
|
|
482
|
+
} : {
|
|
483
|
+
value: matches.sort((a, b)=>a.column - b.column),
|
|
484
|
+
violations: []
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
//# sourceMappingURL=ai-crm-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/tools/ai-crm-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 { CRM_MERGE_FIELDS, crmMergeFieldsIn } from '@aglyn/aglyn/app-utils/crm-email-templates'\nimport type { ConsoleImportColumn } from '@aglyn/aglyn/plugin-manager/record-zone-props'\nimport {\n AI_CRM_LIMITS,\n type AiCrmColumnMatch,\n type AiCrmNextStep,\n type AiCrmRecordKind,\n} from '../model/ai-crm'\nimport type { AiTool } from '../providers/contract'\nimport type { AiDoctrineViolation } from '../runtime/ai-doctrine-validators'\n\n/**\n * The strict tools CRM by AI answers through (AGL-2917), and the checks that\n * hold each answer to what the CRM can take.\n *\n * - `propose_record_insight` — a record's summary, and by kind: the next step\n * as a task (a contact, company or deal), a stage (a deal), a lead's\n * standing. One schema per kind, so no answer carries a field its record\n * cannot use, and each keeps its nullable fields to the one or two a member\n * may legitimately be offered nothing for.\n * - `propose_email_draft` — a subject and a plain-text message.\n * - `propose_column_matches` — the columns of a file matched to import fields.\n *\n * A strict schema forbids extra keys, requires every key, says \"no value\" with\n * `null`, and accepts no length keyword, so every length is stated in a\n * description and enforced here. A check returns a value only when nothing in\n * the answer is broken, and otherwise the violations and the parts at fault,\n * for the generation call's one re-ask.\n */\n\nexport const AI_CRM_RECORD_TOOL_NAME = 'propose_record_insight'\nexport const AI_CRM_EMAIL_TOOL_NAME = 'propose_email_draft'\nexport const AI_CRM_MAPPING_TOOL_NAME = 'propose_column_matches'\n\nconst TASK_KINDS = ['call', 'email', 'meeting', 'todo'] as const\nconst PRIORITIES = ['low', 'normal', 'high'] as const\n\nconst string = (description: string) => ({ type: 'string', description })\n\nconst NEXT_STEP_SCHEMA = {\n anyOf: [\n {\n type: 'object',\n properties: {\n title: string(`The task, starting with a verb. At most ${AI_CRM_LIMITS.taskTitle} characters.`),\n kind: { type: 'string', enum: [...TASK_KINDS] },\n priority: { type: 'string', enum: [...PRIORITIES] },\n dueInDays: {\n type: 'integer',\n description: `Days from today it is due, from 0 to ${AI_CRM_LIMITS.dueInDays}.`,\n },\n reason: string(`Why, naming the fact behind it. At most ${AI_CRM_LIMITS.reason} characters.`),\n },\n required: ['title', 'kind', 'priority', 'dueInDays', 'reason'],\n additionalProperties: false,\n },\n { type: 'null' },\n ],\n}\n\nconst STAGE_SCHEMA = {\n anyOf: [\n {\n type: 'object',\n properties: {\n stageId: string('The id of an open stage the facts list, other than the current one.'),\n reason: string(`The fact that shows the deal moved. At most ${AI_CRM_LIMITS.reason} characters.`),\n },\n required: ['stageId', 'reason'],\n additionalProperties: false,\n },\n { type: 'null' },\n ],\n}\n\n/** The record tool for one kind of record. */\nexport function aiCrmRecordTool(kind: AiCrmRecordKind): AiTool {\n const summary = string(`Where the relationship stands. At most ${AI_CRM_LIMITS.summary} characters and two sentences.`)\n const properties: Record<string, unknown> =\n kind === 'lead'\n ? {\n summary,\n standing: string(\n `Why the lead stands where it does. At most ${AI_CRM_LIMITS.standing} characters and two sentences.`,\n ),\n }\n : kind === 'deal'\n ? { summary, nextStep: NEXT_STEP_SCHEMA, stage: STAGE_SCHEMA }\n : { summary, nextStep: NEXT_STEP_SCHEMA }\n return {\n name: AI_CRM_RECORD_TOOL_NAME,\n description: 'Propose what a team member reads about one CRM record, and what to do next. Every field is required.',\n strict: true,\n inputSchema: {\n type: 'object',\n properties,\n required: Object.keys(properties),\n additionalProperties: false,\n },\n }\n}\n\nexport const AI_CRM_EMAIL_TOOL: AiTool = {\n name: AI_CRM_EMAIL_TOOL_NAME,\n description: 'Propose one email for a team member to review, edit and send themselves.',\n strict: true,\n inputSchema: {\n type: 'object',\n properties: {\n subject: string(`One line. At most ${AI_CRM_LIMITS.subject} characters.`),\n body: string(\n `Plain text in short paragraphs separated by a blank line. At most ${AI_CRM_LIMITS.body.toLocaleString('en-US')} characters.`,\n ),\n },\n required: ['subject', 'body'],\n additionalProperties: false,\n },\n}\n\nexport const AI_CRM_MAPPING_TOOL: AiTool = {\n name: AI_CRM_MAPPING_TOOL_NAME,\n description: 'Propose which columns of the file fill which fields. Leave out a column no field fits.',\n strict: true,\n inputSchema: {\n type: 'object',\n properties: {\n matches: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n column: { type: 'integer', description: 'The column’s number, as the request lists it.' },\n field: { type: 'integer', description: 'The field’s number, as the request lists it.' },\n },\n required: ['column', 'field'],\n additionalProperties: false,\n },\n },\n },\n required: ['matches'],\n additionalProperties: false,\n },\n}\n\n/* ------------------------------------------------------------------------ *\n * Checks\n * ------------------------------------------------------------------------ */\n\nexport interface AiCrmCheckResult<T> {\n value: T | null\n violations: AiDoctrineViolation[]\n offending?: Record<string, unknown>\n}\n\nconst violation = (code: string, message: string, path?: string): AiDoctrineViolation => ({\n rule: null,\n code,\n message,\n ...(path ? { paths: [path] } : {}),\n})\n\nconst collapse = (value: unknown): string => (typeof value === 'string' ? value.replace(/\\s+/g, ' ').trim() : '')\n\n/** A required text field held to its length; the value, or a violation. */\nfunction textField(\n answer: Record<string, unknown>,\n key: string,\n label: string,\n max: number,\n violations: AiDoctrineViolation[],\n offending: Record<string, unknown>,\n): string {\n const raw = answer[key]\n if (typeof raw !== 'string') {\n violations.push(violation('type', `${label} must be text.`, key))\n offending[key] = raw\n return ''\n }\n const text = collapse(raw)\n if (!text) {\n violations.push(violation('missing', `${label} is empty.`, key))\n offending[key] = raw\n } else if (text.length > max) {\n violations.push(violation('too-long', `${label} is ${text.length} characters; at most ${max}.`, key))\n offending[key] = raw\n }\n return text\n}\n\ntype Facts = Readonly<Record<string, unknown>>\n\nconst asText = (value: unknown): string => (typeof value === 'string' ? value : '')\nconst asList = (value: unknown): Array<Record<string, unknown>> =>\n Array.isArray(value)\n ? value.filter((entry): entry is Record<string, unknown> => Boolean(entry) && typeof entry === 'object')\n : []\n\n/** What the record facts say a check needs: a deal's stages and status, and every record's open tasks. */\nexport interface AiCrmRecordCheckContext {\n kind: AiCrmRecordKind\n /** The deal's stage, and its pipeline's stages in order. */\n stageId?: string\n status?: string\n stages?: ReadonlyArray<{ id: string; name: string; kind: string }>\n /** The titles of the record's open tasks, which a next step may not repeat. */\n openTaskTitles?: readonly string[]\n}\n\nexport interface AiCrmRecordAnswer {\n summary: string\n nextStep: AiCrmNextStep | null\n stage: { stageId: string; stageName: string; reason: string } | null\n standing: string | null\n}\n\nfunction checkNextStep(\n raw: unknown,\n context: AiCrmRecordCheckContext,\n violations: AiDoctrineViolation[],\n offending: Record<string, unknown>,\n): AiCrmNextStep | null {\n if (raw === null) return null\n const step = raw as Record<string, unknown>\n if (typeof step !== 'object' || Array.isArray(step)) {\n violations.push(violation('type', 'The next step must be a task or null.', 'nextStep'))\n offending['nextStep'] = raw\n return null\n }\n const before = violations.length\n const title = textField(step, 'title', 'The next step’s title', AI_CRM_LIMITS.taskTitle, violations, {})\n const reason = textField(step, 'reason', 'The next step’s reason', AI_CRM_LIMITS.reason, violations, {})\n const kind = TASK_KINDS.find((entry) => entry === step['kind'])\n const priority = PRIORITIES.find((entry) => entry === step['priority'])\n if (!kind || !priority) violations.push(violation('type', 'The next step’s kind or priority is not one the CRM has.', 'nextStep'))\n const due = step['dueInDays']\n if (typeof due !== 'number' || !Number.isInteger(due) || due < 0 || due > AI_CRM_LIMITS.dueInDays) {\n violations.push(\n violation('next-step-due', `The next step must be due in 0 to ${AI_CRM_LIMITS.dueInDays} days.`, 'nextStep.dueInDays'),\n )\n }\n const open = new Set((context.openTaskTitles ?? []).map((entry) => collapse(entry).toLowerCase()))\n if (title && open.has(title.toLowerCase())) {\n violations.push(\n violation('next-step-open', 'The next step repeats a task that is already open. Propose another, or null.', 'nextStep.title'),\n )\n }\n if (violations.length > before) {\n offending['nextStep'] = raw\n return null\n }\n return { title, kind: kind as AiCrmNextStep['kind'], priority: priority as AiCrmNextStep['priority'], dueInDays: due as number, reason }\n}\n\nfunction checkStage(\n raw: unknown,\n context: AiCrmRecordCheckContext,\n violations: AiDoctrineViolation[],\n offending: Record<string, unknown>,\n): AiCrmRecordAnswer['stage'] {\n if (raw === null) return null\n const stage = raw as Record<string, unknown>\n if (typeof stage !== 'object' || Array.isArray(stage)) {\n violations.push(violation('type', 'The stage must be a move or null.', 'stage'))\n offending['stage'] = raw\n return null\n }\n const before = violations.length\n const reason = textField(stage, 'reason', 'The stage’s reason', AI_CRM_LIMITS.reason, violations, {})\n const target = (context.stages ?? []).find((entry) => entry.id === stage['stageId'])\n if (context.status && context.status !== 'open') {\n violations.push(violation('stage-closed', 'The deal is already closed, so its stage must be null.', 'stage'))\n } else if (!target) {\n violations.push(violation('stage-unknown', 'The stage is not one the deal’s pipeline lists.', 'stage.stageId'))\n } else if (target.kind !== 'open') {\n violations.push(\n violation('stage-won-lost', 'Winning or losing a deal is the team’s call. Propose an open stage, or null.', 'stage.stageId'),\n )\n } else if (target.id === context.stageId) {\n violations.push(violation('stage-current', 'The deal is already in that stage. Propose another, or null.', 'stage.stageId'))\n }\n if (violations.length > before || !target) {\n offending['stage'] = raw\n return null\n }\n return { stageId: target.id, stageName: target.name, reason }\n}\n\n/** What a record's facts say its check needs. */\nexport function aiCrmRecordCheckContext(kind: AiCrmRecordKind, facts: Facts): AiCrmRecordCheckContext {\n return {\n kind,\n openTaskTitles: asList(facts['openTasks']).map((task) => asText(task['title'])),\n ...(kind === 'deal'\n ? {\n stageId: asText(facts['stageId']),\n status: asText(facts['status']),\n stages: asList(facts['stages']).map((stage) => ({\n id: asText(stage['id']),\n name: asText(stage['name']),\n kind: asText(stage['kind']),\n })),\n }\n : {}),\n }\n}\n\n/** A record answer held to the record it is about. */\nexport function checkAiCrmRecord(\n answer: Record<string, unknown>,\n context: AiCrmRecordCheckContext,\n): AiCrmCheckResult<AiCrmRecordAnswer> {\n const violations: AiDoctrineViolation[] = []\n const offending: Record<string, unknown> = {}\n const summary = textField(answer, 'summary', 'The summary', AI_CRM_LIMITS.summary, violations, offending)\n let nextStep: AiCrmNextStep | null = null\n let stage: AiCrmRecordAnswer['stage'] = null\n let standing: string | null = null\n if (context.kind === 'lead') {\n standing = textField(answer, 'standing', 'The standing', AI_CRM_LIMITS.standing, violations, offending)\n } else {\n nextStep = checkNextStep(answer['nextStep'], context, violations, offending)\n if (context.kind === 'deal') stage = checkStage(answer['stage'], context, violations, offending)\n }\n return violations.length\n ? { value: null, violations, offending }\n : { value: { summary, nextStep, stage, standing }, violations: [] }\n}\n\n/** The merge fields an email from a record may use: never an address. */\nexport function aiCrmEmailMergeFields(kind: AiCrmRecordKind): string[] {\n const groups = kind === 'lead' ? ['Lead'] : kind === 'deal' ? ['Contact', 'Deal'] : ['Contact']\n return CRM_MERGE_FIELDS.filter(\n (field) => (groups.includes(field.group) || field.group === 'You' || field.group === 'Site') && !field.key.endsWith('.email'),\n ).map((field) => field.key)\n}\n\nconst EMAIL_ADDRESS = /[\\w.+-]+@[\\w-]+\\.[\\w.-]+/\n/** A run of digits and the separators a phone number is written with. */\nconst DIGIT_RUN = /\\+?\\d[\\d\\s().-]{7,}\\d/g\n/** Calendar days, which the facts write and a draft may repeat. */\nconst DAYS_ONLY = /^\\d{4}-\\d{2}-\\d{2}(?:\\s+\\d{4}-\\d{2}-\\d{2})*$/\n\n/** Whether text writes a phone number: a run of ten digits or more that is not a list of days. */\nexport function aiCrmWritesPhoneNumber(text: string): boolean {\n for (const [run] of text.matchAll(DIGIT_RUN)) {\n if (DAYS_ONLY.test(run.trim())) continue\n if (run.replace(/\\D/g, '').length >= 10) return true\n }\n return false\n}\nconst MARKDOWN = /\\*\\*|__|^#{1,6}\\s|\\[[^\\]]+\\]\\([^)]+\\)|```/m\n\nexport interface AiCrmEmailAnswer {\n subject: string\n body: string\n}\n\n/** An email answer held to the composer and to what a person may be sent. */\nexport function checkAiCrmEmail(\n answer: Record<string, unknown>,\n context: { mergeFields: readonly string[] },\n): AiCrmCheckResult<AiCrmEmailAnswer> {\n const violations: AiDoctrineViolation[] = []\n const offending: Record<string, unknown> = {}\n const subject = textField(answer, 'subject', 'The subject', AI_CRM_LIMITS.subject, violations, offending)\n const rawBody = typeof answer['body'] === 'string' ? answer['body'] : null\n const body = rawBody === null ? '' : rawBody.replace(/\\r\\n/g, '\\n').replace(/[ \\t]+\\n/g, '\\n').replace(/\\n{3,}/g, '\\n\\n').trim()\n if (rawBody === null) {\n violations.push(violation('type', 'The message must be text.', 'body'))\n offending['body'] = answer['body']\n } else if (!body) {\n violations.push(violation('missing', 'The message is empty.', 'body'))\n offending['body'] = rawBody\n } else if (body.length > AI_CRM_LIMITS.body) {\n violations.push(violation('too-long', `The message is ${body.length} characters; at most ${AI_CRM_LIMITS.body}.`, 'body'))\n offending['body'] = rawBody\n }\n if (typeof answer['subject'] === 'string' && /[\\r\\n]/.test(answer['subject'].trim())) {\n violations.push(violation('subject-lines', 'The subject must be one line.', 'subject'))\n offending['subject'] = answer['subject']\n }\n const allowed = new Set(context.mergeFields)\n const unknown = [...new Set([...crmMergeFieldsIn(subject), ...crmMergeFieldsIn(body)])].filter((key) => !allowed.has(key))\n if (unknown.length) {\n violations.push(\n violation('merge-field-unknown', `The draft uses merge fields this record cannot fill: ${unknown.join(', ')}.`),\n )\n }\n const text = `${subject}\\n${body}`\n if (EMAIL_ADDRESS.test(text) || aiCrmWritesPhoneNumber(text)) {\n violations.push(violation('contact-detail', 'The draft writes an email address or a phone number. Leave them out.'))\n }\n if (MARKDOWN.test(body)) {\n violations.push(violation('markdown', 'The message uses markdown. Write plain text.', 'body'))\n offending['body'] = rawBody\n }\n return violations.length ? { value: null, violations, offending } : { value: { subject, body }, violations: [] }\n}\n\n/** One field an import may fill, as the CRM's catalog lists it. */\nexport interface AiCrmImportField {\n key: string\n label: string\n type: string\n required: boolean\n}\n\n/** An import catalog's fields as the facts report them, in the order they are numbered. */\nexport function aiCrmImportFields(facts: Facts): AiCrmImportField[] {\n return asList(facts['fields'])\n .map((field) => ({\n key: asText(field['key']),\n label: asText(field['label']),\n type: asText(field['type']) || 'text',\n required: field['required'] === true,\n }))\n .filter((field) => field.key && field.label)\n}\n\n/** The column shapes each field type takes; a field type absent here takes any shape. */\nconst SHAPES_FOR_TYPE: Readonly<Record<string, readonly string[]>> = {\n email: ['email', 'empty'],\n phone: ['phone', 'number', 'empty'],\n number: ['number', 'empty'],\n date: ['date', 'empty'],\n 'yes-no': ['yes-no', 'empty'],\n}\n\n/** A mapping answer held to the file's columns and the import's fields. */\nexport function checkAiCrmMapping(\n answer: Record<string, unknown>,\n context: { columns: readonly ConsoleImportColumn[]; fields: readonly AiCrmImportField[] },\n): AiCrmCheckResult<AiCrmColumnMatch[]> {\n const violations: AiDoctrineViolation[] = []\n const raw = answer['matches']\n if (!Array.isArray(raw)) {\n return { value: null, violations: [violation('type', 'The matches must be a list.', 'matches')], offending: { matches: raw } }\n }\n const columns = new Set<number>()\n const taken = new Set<string>()\n const matches: AiCrmColumnMatch[] = []\n const offending: unknown[] = []\n for (const entry of raw) {\n const match = (entry ?? {}) as Record<string, unknown>\n const column = match['column']\n const number = match['field']\n const field = typeof number === 'number' && Number.isInteger(number) ? context.fields[number] : undefined\n const at = typeof column === 'number' && Number.isInteger(column) ? context.columns[column] : undefined\n if (!at) {\n violations.push(violation('column-unknown', `Column ${String(column)} is not one the file has.`))\n } else if (!field) {\n violations.push(violation('field-unknown', `Field ${String(number)} is not one this import fills.`))\n } else if (columns.has(column as number)) {\n violations.push(violation('column-twice', `Column ${String(column)} is matched twice.`))\n } else if (taken.has(field.key)) {\n violations.push(violation('field-twice', `${field.label} takes one column, and two were matched to it.`))\n } else if (SHAPES_FOR_TYPE[field.type] && !SHAPES_FOR_TYPE[field.type].includes(at.shape)) {\n violations.push(\n violation('shape-mismatch', `Column ${String(column)} holds ${at.shape} values, which ${field.label} cannot take.`),\n )\n } else if (at.shape === 'email' && field.type !== 'email') {\n violations.push(violation('shape-mismatch', `Column ${String(column)} holds email addresses, which ${field.label} is not.`))\n } else {\n columns.add(column as number)\n taken.add(field.key)\n matches.push({ column: column as number, header: at.header, field: field.key, label: field.label })\n continue\n }\n offending.push(entry)\n }\n return violations.length\n ? { value: null, violations, offending: { matches: offending } }\n : { value: matches.sort((a, b) => a.column - b.column), violations: [] }\n}\n"],"names":["CRM_MERGE_FIELDS","crmMergeFieldsIn","AI_CRM_LIMITS","AI_CRM_RECORD_TOOL_NAME","AI_CRM_EMAIL_TOOL_NAME","AI_CRM_MAPPING_TOOL_NAME","TASK_KINDS","PRIORITIES","string","description","type","NEXT_STEP_SCHEMA","anyOf","properties","title","taskTitle","kind","enum","priority","dueInDays","reason","required","additionalProperties","STAGE_SCHEMA","stageId","aiCrmRecordTool","summary","standing","nextStep","stage","name","strict","inputSchema","Object","keys","AI_CRM_EMAIL_TOOL","subject","body","toLocaleString","AI_CRM_MAPPING_TOOL","matches","items","column","field","violation","code","message","path","rule","paths","collapse","value","replace","trim","textField","answer","key","label","max","violations","offending","raw","push","text","length","asText","asList","Array","isArray","filter","entry","Boolean","checkNextStep","context","step","before","find","due","Number","isInteger","open","Set","openTaskTitles","map","toLowerCase","has","checkStage","target","stages","id","status","stageName","aiCrmRecordCheckContext","facts","task","checkAiCrmRecord","aiCrmEmailMergeFields","groups","includes","group","endsWith","EMAIL_ADDRESS","DIGIT_RUN","DAYS_ONLY","aiCrmWritesPhoneNumber","run","matchAll","test","MARKDOWN","checkAiCrmEmail","rawBody","allowed","mergeFields","unknown","join","aiCrmImportFields","SHAPES_FOR_TYPE","email","phone","number","date","checkAiCrmMapping","columns","taken","match","fields","undefined","at","String","shape","add","header","sort","a","b"],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
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 DuplicableHostResourceKind } from '@aglyn/aglyn/app-utils/duplicate-resource';
|
|
18
|
+
import type { AiTool } from '../providers/contract';
|
|
19
|
+
import type { AiGateContext } from '../runtime/ai-gate';
|
|
20
|
+
/**
|
|
21
|
+
* The `duplicate_resource` tool (AGL-2936, AGL-2984): a model that would
|
|
22
|
+
* rebuild something the site already has copies it instead, through core's
|
|
23
|
+
* `duplicateResource` — the same copy the row menus and the console door
|
|
24
|
+
* make, with the same uniqueness rules, the same band arithmetic and the same
|
|
25
|
+
* activity rows.
|
|
26
|
+
*
|
|
27
|
+
* It spends no tokens of its own, so it calls no provider: it runs inside a
|
|
28
|
+
* door or a job step that has already climbed `aiGateLadder`, and takes that
|
|
29
|
+
* ladder's context as its proof — the caller is signed in and verified, the
|
|
30
|
+
* release flag, entitlement and lockdown rungs admitted the request, and the
|
|
31
|
+
* workspace's band and caps admitted a reservation. On top of that it asks
|
|
32
|
+
* what a copy needs whichever door called it: `ai.generate`, because a copy
|
|
33
|
+
* is a generation's output, and a host role that may write the site, because
|
|
34
|
+
* the copy lands there.
|
|
35
|
+
*
|
|
36
|
+
* DRAFTS ONLY, by construction of the copy: a screen copy has no route, a
|
|
37
|
+
* workflow copy no trigger, and nothing places a component, layout or form
|
|
38
|
+
* copy until a person does.
|
|
39
|
+
*/
|
|
40
|
+
export declare const AI_DUPLICATE_RESOURCE_TOOL_NAME = "duplicate_resource";
|
|
41
|
+
/** The structured-output tool a generation offers the model. */
|
|
42
|
+
export declare const AI_DUPLICATE_RESOURCE_TOOL: AiTool;
|
|
43
|
+
/** A tool call's input, read. */
|
|
44
|
+
export type AiDuplicateResourceInput = {
|
|
45
|
+
kind: DuplicableHostResourceKind;
|
|
46
|
+
sourceId: string;
|
|
47
|
+
name: string | null;
|
|
48
|
+
};
|
|
49
|
+
/** What the tool answers: the copy, or a refusal the caller can relay. */
|
|
50
|
+
export type AiDuplicateResourceOutcome = {
|
|
51
|
+
ok: true;
|
|
52
|
+
kind: DuplicableHostResourceKind;
|
|
53
|
+
id: string;
|
|
54
|
+
versionId: string | null;
|
|
55
|
+
name: string;
|
|
56
|
+
} | {
|
|
57
|
+
ok: false;
|
|
58
|
+
status: number;
|
|
59
|
+
error: string;
|
|
60
|
+
};
|
|
61
|
+
/** Reads a tool call's input; `null` when it is not one this tool accepts. */
|
|
62
|
+
export declare function parseAiDuplicateResourceInput(input: Record<string, unknown>): AiDuplicateResourceInput | null;
|
|
63
|
+
/**
|
|
64
|
+
* Makes the copy on `hostId` for the person the gate admitted. Refusals are
|
|
65
|
+
* outcomes, never throws: a model's call that names a missing source or a
|
|
66
|
+
* full band is an answer to relay, not a fault.
|
|
67
|
+
*/
|
|
68
|
+
export declare function runAiDuplicateResourceTool(context: {
|
|
69
|
+
gate: AiGateContext;
|
|
70
|
+
hostId: string;
|
|
71
|
+
}, input: Record<string, unknown>): Promise<AiDuplicateResourceOutcome>;
|