@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,538 @@
|
|
|
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 { resolveOrgIdForHost } from "@aglyn/tenant-data-admin/server/organizations";
|
|
18
|
+
import { isAiPlanNewRef } from "../model/ai-build-plan.js";
|
|
19
|
+
import { AI_SITE_EMAIL_TYPE, AI_SITE_MAX_SECTIONS, AI_SITE_PAGES, aiSitePlanRefusal, aiSiteSubmissions, aiSiteWords, parseAiSiteJobInputs } from "../model/ai-site-job.js";
|
|
20
|
+
import { AI_SITE_SEO_OUTPUT_ID, aiSiteSeoProposalForInputs } from "../model/ai-site-start-seo.js";
|
|
21
|
+
import { aiModelForStep } from "../providers/routing.js";
|
|
22
|
+
import { registerAiJobAdmission } from "./ai-job-admission.js";
|
|
23
|
+
import { aiRecordedJobDraftId } from "./ai-job-draft-ids.js";
|
|
24
|
+
import { aiConfirmedPlan, aiUnspentOutcome } from "./ai-job-generation.js";
|
|
25
|
+
import { AI_JOB_BRIEF_MAX_CHARS } from "./ai-job-text-step.js";
|
|
26
|
+
import { AI_JOB_PAGE_STEP_MINIMUM_MS } from "./ai-job-page-budget.js";
|
|
27
|
+
import { aiJobStepRunMinimumMs, aiJobStepRunnerFor, registerAiJobStep, registerAiJobStepPasses } from "./ai-jobs.js";
|
|
28
|
+
/** The job kind and output resource each unit is built through. */ const UNIT_KINDS = {
|
|
29
|
+
theme: {
|
|
30
|
+
jobKind: 'theme',
|
|
31
|
+
resource: 'theme'
|
|
32
|
+
},
|
|
33
|
+
layout: {
|
|
34
|
+
jobKind: 'layout',
|
|
35
|
+
resource: 'layout'
|
|
36
|
+
},
|
|
37
|
+
form: {
|
|
38
|
+
jobKind: 'form',
|
|
39
|
+
resource: 'form'
|
|
40
|
+
},
|
|
41
|
+
component: {
|
|
42
|
+
jobKind: 'component',
|
|
43
|
+
resource: 'reusableComponent'
|
|
44
|
+
},
|
|
45
|
+
page: {
|
|
46
|
+
jobKind: 'page',
|
|
47
|
+
resource: 'screen'
|
|
48
|
+
},
|
|
49
|
+
email: {
|
|
50
|
+
jobKind: 'email',
|
|
51
|
+
resource: 'emailScreen'
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/** The unit kind a creation is built as, where a unit builds it. */ const CREATION_UNIT_KINDS = {
|
|
55
|
+
'theme-change': 'theme',
|
|
56
|
+
layout: 'layout',
|
|
57
|
+
form: 'form',
|
|
58
|
+
component: 'component'
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* The unit one creation is built as, under the slot its derived job and draft
|
|
62
|
+
* are addressed by; `null` for a creation no unit builds.
|
|
63
|
+
*/ export function aiCreationUnit(creation, slot) {
|
|
64
|
+
const kind = CREATION_UNIT_KINDS[creation.kind];
|
|
65
|
+
if (!kind) return null;
|
|
66
|
+
return _extends({
|
|
67
|
+
kind
|
|
68
|
+
}, UNIT_KINDS[kind], {
|
|
69
|
+
slot,
|
|
70
|
+
creation,
|
|
71
|
+
label: creation.name
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/** The creation kinds a unit is built from, by unit kind. */ const CREATION_UNITS = [
|
|
75
|
+
{
|
|
76
|
+
unit: 'theme',
|
|
77
|
+
create: 'theme-change'
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
unit: 'layout',
|
|
81
|
+
create: 'layout'
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
unit: 'form',
|
|
85
|
+
create: 'form'
|
|
86
|
+
}
|
|
87
|
+
];
|
|
88
|
+
export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to build.';
|
|
89
|
+
/** What a scaffold answers where the step that builds a page is not loaded. */ export const AI_SITE_NO_PAGE_STEP_COPY = 'Building a whole site is not available yet.';
|
|
90
|
+
/** A unit that finished without reporting what it built; the scaffold cannot go on. */ export const AI_SITE_UNIT_EMPTY_COPY = 'Part of this site could not be built. Try the site brief again.';
|
|
91
|
+
/**
|
|
92
|
+
* The most passes a scaffold's step may take: the largest plan it admits —
|
|
93
|
+
* eight pages of eight sections, its three creations and a welcome email —
|
|
94
|
+
* with nothing to spare, so a runner that never finishes is still bounded
|
|
95
|
+
* while a real site is not.
|
|
96
|
+
*/ export const AI_SITE_MAX_PASSES = AI_SITE_PAGES.max * (AI_SITE_MAX_SECTIONS + 1) + CREATION_UNITS.length + 1;
|
|
97
|
+
/**
|
|
98
|
+
* The units a plan implies, in build order: the palette first, because a
|
|
99
|
+
* member reads it while the pages are still building; then the layout every
|
|
100
|
+
* page renders inside and the form they place, because a page binds both by
|
|
101
|
+
* id and so needs them to exist; then the pages; then the welcome email,
|
|
102
|
+
* which is about the site rather than part of it.
|
|
103
|
+
*/ export function aiSiteJobUnits(plan, options = {}) {
|
|
104
|
+
const units = [];
|
|
105
|
+
for (const { unit, create } of CREATION_UNITS){
|
|
106
|
+
const creation = plan.create.find((entry)=>entry.kind === create);
|
|
107
|
+
if (!creation) continue;
|
|
108
|
+
units.push(_extends({
|
|
109
|
+
kind: unit
|
|
110
|
+
}, UNIT_KINDS[unit], {
|
|
111
|
+
slot: unit[0],
|
|
112
|
+
creation,
|
|
113
|
+
label: creation.name
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
plan.screens.forEach((screen, index)=>{
|
|
117
|
+
units.push(_extends({
|
|
118
|
+
kind: 'page'
|
|
119
|
+
}, UNIT_KINDS.page, {
|
|
120
|
+
slot: `p${index}`,
|
|
121
|
+
screen,
|
|
122
|
+
label: screen.title
|
|
123
|
+
}));
|
|
124
|
+
});
|
|
125
|
+
if (options.welcomeEmail) {
|
|
126
|
+
units.push(_extends({
|
|
127
|
+
kind: 'email'
|
|
128
|
+
}, UNIT_KINDS.email, {
|
|
129
|
+
slot: 'e',
|
|
130
|
+
label: 'Welcome email'
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
return units;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The units a scaffold still owes after the outputs recorded so far. Each
|
|
137
|
+
* unit reports one output of its own resource when it completes, so the
|
|
138
|
+
* outputs already recorded are consumed against the units in build order.
|
|
139
|
+
*/ export function aiSitePendingUnits(units, outputs) {
|
|
140
|
+
const done = new Map();
|
|
141
|
+
for (const output of outputs){
|
|
142
|
+
var _done_get;
|
|
143
|
+
done.set(output.resource, ((_done_get = done.get(output.resource)) != null ? _done_get : 0) + 1);
|
|
144
|
+
}
|
|
145
|
+
return units.filter((unit)=>{
|
|
146
|
+
var _done_get;
|
|
147
|
+
const left = (_done_get = done.get(unit.resource)) != null ? _done_get : 0;
|
|
148
|
+
if (left <= 0) return true;
|
|
149
|
+
done.set(unit.resource, left - 1);
|
|
150
|
+
return false;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The site's own search listing as the scaffold reports it (AGL-2918), or
|
|
155
|
+
* nothing when the job already reported one or its inputs describe no site.
|
|
156
|
+
*
|
|
157
|
+
* It costs nothing and asks no model: the values are arithmetic on the
|
|
158
|
+
* answers (`aiSiteSeoProposal`), so they ride out on the first pass that
|
|
159
|
+
* builds anything rather than waiting for a pass of their own. Its resource
|
|
160
|
+
* is `seo`, which no unit reports, so it cannot be mistaken for a unit's
|
|
161
|
+
* output by `aiSitePendingUnits` and cannot move where the scaffold thinks
|
|
162
|
+
* it is.
|
|
163
|
+
*/ export function aiSiteSeoOutputs(job) {
|
|
164
|
+
var _job_outputs, _job_hostId;
|
|
165
|
+
const outputs = (_job_outputs = job.outputs) != null ? _job_outputs : [];
|
|
166
|
+
if (outputs.some((output)=>output.resource === 'seo' && output.id === AI_SITE_SEO_OUTPUT_ID)) {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
const proposal = aiSiteSeoProposalForInputs(job.inputs);
|
|
170
|
+
if (!proposal) return [];
|
|
171
|
+
return [
|
|
172
|
+
{
|
|
173
|
+
resource: 'seo',
|
|
174
|
+
id: AI_SITE_SEO_OUTPUT_ID,
|
|
175
|
+
hostId: (_job_hostId = job.hostId) != null ? _job_hostId : null,
|
|
176
|
+
label: 'The site’s search title and description',
|
|
177
|
+
proposal: proposal
|
|
178
|
+
}
|
|
179
|
+
];
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* What the scaffold has already created, as the plan's `new:<name>`
|
|
183
|
+
* references resolve to: the id of the record each completed creation wrote.
|
|
184
|
+
* A page unit is told about the layout and the form by id, exactly as a page
|
|
185
|
+
* job is told about records the site already had.
|
|
186
|
+
*/ export function aiSiteBuiltRefs(units, outputs) {
|
|
187
|
+
const byResource = new Map();
|
|
188
|
+
for (const output of outputs){
|
|
189
|
+
var _byResource_get;
|
|
190
|
+
const rows = (_byResource_get = byResource.get(output.resource)) != null ? _byResource_get : [];
|
|
191
|
+
rows.push(output);
|
|
192
|
+
byResource.set(output.resource, rows);
|
|
193
|
+
}
|
|
194
|
+
const built = new Map();
|
|
195
|
+
for (const unit of units){
|
|
196
|
+
const rows = byResource.get(unit.resource);
|
|
197
|
+
const row = rows == null ? void 0 : rows.shift();
|
|
198
|
+
if (!row || !unit.creation) continue;
|
|
199
|
+
// A theme change is a proposal with no record to reference; a layout, a
|
|
200
|
+
// form and a component become ids a page can name.
|
|
201
|
+
if (unit.creation.kind !== 'layout' && unit.creation.kind !== 'form' && unit.creation.kind !== 'component') {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
built.set(unit.creation.name.toLowerCase(), {
|
|
205
|
+
id: row.id,
|
|
206
|
+
label: row.label || unit.creation.name,
|
|
207
|
+
kind: unit.creation.kind
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return built;
|
|
211
|
+
}
|
|
212
|
+
/** A plan reference as the unit's own job reads it: an id the site now has, or nothing. */ function resolved(ref, built) {
|
|
213
|
+
var _ref;
|
|
214
|
+
var _built_get;
|
|
215
|
+
if (!ref) return null;
|
|
216
|
+
if (!isAiPlanNewRef(ref)) return ref;
|
|
217
|
+
return (_ref = (_built_get = built.get(ref.slice(ref.indexOf(':') + 1).trim().toLowerCase())) == null ? void 0 : _built_get.id) != null ? _ref : null;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* The site's own words, as every unit's brief carries them.
|
|
221
|
+
*
|
|
222
|
+
* The audience is here rather than left to the brief's prose (AGL-2918). A
|
|
223
|
+
* guided start writes it into the brief itself, but an agency batch's brief
|
|
224
|
+
* is a member's own sentence and may never mention it, and a theme, a layout
|
|
225
|
+
* or a form asked to serve nobody in particular serves nobody in particular.
|
|
226
|
+
*/ export function aiSiteBriefLines(brief, inputs) {
|
|
227
|
+
const lines = [
|
|
228
|
+
brief.trim()
|
|
229
|
+
];
|
|
230
|
+
const site = [
|
|
231
|
+
inputs.businessName ? `name: ${inputs.businessName}` : '',
|
|
232
|
+
`business: ${inputs.businessType}`,
|
|
233
|
+
inputs.audience ? `for: ${inputs.audience}` : '',
|
|
234
|
+
inputs.city ? `city: ${inputs.city}` : '',
|
|
235
|
+
inputs.brand ? `brand: ${inputs.brand}` : ''
|
|
236
|
+
].filter(Boolean);
|
|
237
|
+
lines.push(`Site — ${site.join('; ')}.`);
|
|
238
|
+
return lines;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* What the welcome email is told (AGL-2918), beyond that it is a welcome
|
|
242
|
+
* email.
|
|
243
|
+
*
|
|
244
|
+
* The scaffold's email unit used to carry one sentence, and a yes/no toggle
|
|
245
|
+
* decided whether it ran — so the draft was a welcome email for a business
|
|
246
|
+
* in general, to nobody in particular, about nothing that had happened. The
|
|
247
|
+
* two answers it is missing are who wrote in and what now becomes of what
|
|
248
|
+
* they wrote, and the second of those is the person's own routing answer, so
|
|
249
|
+
* the email and the form it acknowledges cannot say different things.
|
|
250
|
+
*
|
|
251
|
+
* ⛔ A DRAFT either way. Nothing here sends, schedules or enrolls anybody:
|
|
252
|
+
* the email step writes an unpublished email design and stops.
|
|
253
|
+
*/ export function aiSiteEmailBriefLines(inputs) {
|
|
254
|
+
const lines = [
|
|
255
|
+
'Write the welcome email this site sends someone who gets in touch.'
|
|
256
|
+
];
|
|
257
|
+
const { audience } = aiSiteWords(inputs);
|
|
258
|
+
if (audience) lines.push(`Write it to ${audience}.`);
|
|
259
|
+
const submissions = aiSiteSubmissions(inputs);
|
|
260
|
+
if (submissions === 'lead') {
|
|
261
|
+
lines.push('Their message is a sales lead, so say that somebody will be in touch about it.');
|
|
262
|
+
} else if (submissions === 'inbox') {
|
|
263
|
+
lines.push('Their message has been read, so say it arrived and that a reply is coming.');
|
|
264
|
+
}
|
|
265
|
+
return lines;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* The id a unit's job is named by, and so the id its draft is written under
|
|
269
|
+
* (AGL-3079): the id the plan entry it builds recorded, or for the welcome
|
|
270
|
+
* email the id recorded on this job's step. A unit that writes no draft — a
|
|
271
|
+
* palette change — and a unit whose plan recorded no id are named by this
|
|
272
|
+
* job's id and the unit's slot, the name every draft of such a plan has.
|
|
273
|
+
*/ export function aiSiteUnitJobId(job, unit) {
|
|
274
|
+
var _ref, _ref1;
|
|
275
|
+
var _unit_creation, _unit_screen;
|
|
276
|
+
const recorded = (_ref = (_ref1 = (_unit_creation = unit.creation) == null ? void 0 : _unit_creation.id) != null ? _ref1 : (_unit_screen = unit.screen) == null ? void 0 : _unit_screen.id) != null ? _ref : unit.kind === 'email' ? aiRecordedJobDraftId(job, 'email') : null;
|
|
277
|
+
return recorded || `${job.$id}-${unit.slot}`;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* The job a unit is built under: this job's org, site, creator and model,
|
|
281
|
+
* the kind that owns the unit, and a plan narrowed to the unit alone.
|
|
282
|
+
*
|
|
283
|
+
* The derived job carries NO steps and NO outputs of the scaffold's: a page
|
|
284
|
+
* job's step reads its own draft and its own plan, and what the other units
|
|
285
|
+
* produced is not its business. Its `$id` is the id the unit's draft is
|
|
286
|
+
* written under (`aiSiteUnitJobId`), which is what a step with no id of its
|
|
287
|
+
* own recorded names its draft by, so a unit re-run after its write finds its
|
|
288
|
+
* own draft rather than writing a second.
|
|
289
|
+
*
|
|
290
|
+
* A creation unit reuses what the plan reuses less what the plan's screens
|
|
291
|
+
* place themselves (AGL-3031): a component a page's section places is the
|
|
292
|
+
* page's to place, and a layout or a card told to place it would be refused
|
|
293
|
+
* for leaving it out.
|
|
294
|
+
*/ export function aiSiteUnitJob(job, unit, built) {
|
|
295
|
+
var _plan_labels;
|
|
296
|
+
const plan = job.plan;
|
|
297
|
+
const labels = _extends({}, (_plan_labels = plan.labels) != null ? _plan_labels : {});
|
|
298
|
+
for (const entry of built.values())labels[entry.id] = entry.label;
|
|
299
|
+
const inputs = parseAiSiteJobInputs(job.inputs);
|
|
300
|
+
const brief = typeof inputs === 'string' ? [
|
|
301
|
+
job.brief
|
|
302
|
+
] : aiSiteBriefLines(job.brief, inputs);
|
|
303
|
+
const unitPlan = _extends({}, plan, {
|
|
304
|
+
labels,
|
|
305
|
+
reuse: [
|
|
306
|
+
...plan.reuse
|
|
307
|
+
],
|
|
308
|
+
create: [],
|
|
309
|
+
screens: []
|
|
310
|
+
});
|
|
311
|
+
if (unit.creation) {
|
|
312
|
+
const placedByScreens = new Set(plan.screens.flatMap((screen)=>screen.sections.flatMap((section)=>section.uses)));
|
|
313
|
+
unitPlan.reuse = plan.reuse.filter((entry)=>!placedByScreens.has(entry.id));
|
|
314
|
+
unitPlan.create = [
|
|
315
|
+
_extends({}, unit.creation, {
|
|
316
|
+
duplicateOf: resolved(unit.creation.duplicateOf, built)
|
|
317
|
+
})
|
|
318
|
+
];
|
|
319
|
+
brief.push(`Build the ${unit.creation.kind} “${unit.creation.name}”: ${unit.creation.why}`);
|
|
320
|
+
}
|
|
321
|
+
if (unit.screen) {
|
|
322
|
+
const screen = unit.screen;
|
|
323
|
+
// Everything the scaffold has already built is a record the site has, so
|
|
324
|
+
// the page is planned against it the way a page job is planned against
|
|
325
|
+
// what the site always had.
|
|
326
|
+
for (const entry of built.values()){
|
|
327
|
+
unitPlan.reuse.push({
|
|
328
|
+
kind: entry.kind,
|
|
329
|
+
id: entry.id,
|
|
330
|
+
purpose: `the ${entry.kind} this site’s pages are built on`
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
unitPlan.screens = [
|
|
334
|
+
_extends({}, screen, {
|
|
335
|
+
layout: resolved(screen.layout, built),
|
|
336
|
+
template: resolved(screen.template, built),
|
|
337
|
+
duplicateOf: resolved(screen.duplicateOf, built),
|
|
338
|
+
sections: screen.sections.map((section)=>_extends({}, section, {
|
|
339
|
+
uses: section.uses.map((ref)=>resolved(ref, built)).filter((ref)=>!!ref)
|
|
340
|
+
}))
|
|
341
|
+
})
|
|
342
|
+
];
|
|
343
|
+
brief.push(`Build the page “${screen.title}” of this site, at ${screen.slug}.`);
|
|
344
|
+
}
|
|
345
|
+
if (unit.kind === 'email') {
|
|
346
|
+
brief.push(...aiSiteEmailBriefLines(job.inputs));
|
|
347
|
+
}
|
|
348
|
+
return _extends({}, job, {
|
|
349
|
+
$id: aiSiteUnitJobId(job, unit),
|
|
350
|
+
kind: unit.jobKind,
|
|
351
|
+
steps: [],
|
|
352
|
+
outputs: [],
|
|
353
|
+
plan: unitPlan
|
|
354
|
+
}, unit.kind === 'theme' ? {
|
|
355
|
+
inputs: _extends({}, job.inputs, {
|
|
356
|
+
mode: 'create'
|
|
357
|
+
})
|
|
358
|
+
} : {}, unit.kind === 'email' ? {
|
|
359
|
+
inputs: _extends({}, job.inputs, {
|
|
360
|
+
emailType: AI_SITE_EMAIL_TYPE
|
|
361
|
+
})
|
|
362
|
+
} : {}, {
|
|
363
|
+
brief: brief.join('\n').slice(0, AI_JOB_BRIEF_MAX_CHARS)
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* A scaffold is admitted with inputs that read, for a site of the job's own
|
|
368
|
+
* org, and only where this deployment has loaded the step that builds a page:
|
|
369
|
+
* a scaffold whose pages nothing can build is not a scaffold.
|
|
370
|
+
*/ export const aiSiteJobAdmission = async (context)=>{
|
|
371
|
+
const inputs = parseAiSiteJobInputs(context.inputs);
|
|
372
|
+
if (typeof inputs === 'string') return {
|
|
373
|
+
status: 400,
|
|
374
|
+
error: inputs
|
|
375
|
+
};
|
|
376
|
+
if (!context.hostId) {
|
|
377
|
+
return {
|
|
378
|
+
status: 400,
|
|
379
|
+
error: 'Open the site the scaffold is for before starting the job'
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
const owner = await resolveOrgIdForHost(context.hostId);
|
|
383
|
+
if (!owner || owner !== context.orgId) return {
|
|
384
|
+
status: 404,
|
|
385
|
+
error: 'Unknown site'
|
|
386
|
+
};
|
|
387
|
+
if (!aiJobStepRunnerFor('page')) {
|
|
388
|
+
return {
|
|
389
|
+
status: 400,
|
|
390
|
+
error: AI_SITE_NO_PAGE_STEP_COPY
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
return null;
|
|
394
|
+
};
|
|
395
|
+
/**
|
|
396
|
+
* One delegated pass (AGL-2911, AGL-3031): the unit handed to the runner of
|
|
397
|
+
* the kind that owns it, under the job derived for it, and its outcome as the
|
|
398
|
+
* delegating job records it. A delegate proposes a plan for its own job,
|
|
399
|
+
* which does not exist, so no plan is carried back. A unit that stopped for a
|
|
400
|
+
* person, refused or failed is the delegating job's stop; a unit that asked
|
|
401
|
+
* for another pass keeps its turn; and a unit that finished without reporting
|
|
402
|
+
* what it built fails with `emptyCopy`, since another pass would ask the same
|
|
403
|
+
* thing again. The tokens it spent are on the bill either way.
|
|
404
|
+
*/ export async function aiRunJobUnit(context, input) {
|
|
405
|
+
var _job_outputs;
|
|
406
|
+
const { job } = context;
|
|
407
|
+
const outputs = (_job_outputs = job.outputs) != null ? _job_outputs : [];
|
|
408
|
+
const outcome = await input.runner(_extends({}, context, {
|
|
409
|
+
job: aiSiteUnitJob(job, input.unit, aiSiteBuiltRefs(input.units, outputs))
|
|
410
|
+
}));
|
|
411
|
+
const spent = _extends({
|
|
412
|
+
outputs: outcome.outputs,
|
|
413
|
+
usage: outcome.usage,
|
|
414
|
+
estCostUsd: outcome.estCostUsd,
|
|
415
|
+
model: outcome.model,
|
|
416
|
+
stopReason: outcome.stopReason
|
|
417
|
+
}, outcome.effort ? {
|
|
418
|
+
effort: outcome.effort
|
|
419
|
+
} : {}, outcome.refused ? {
|
|
420
|
+
refused: true
|
|
421
|
+
} : {}, outcome.failure ? {
|
|
422
|
+
failure: outcome.failure
|
|
423
|
+
} : {}, outcome.review ? {
|
|
424
|
+
review: outcome.review
|
|
425
|
+
} : {});
|
|
426
|
+
if (spent.review || spent.refused || spent.failure) return {
|
|
427
|
+
outcome: spent,
|
|
428
|
+
built: false
|
|
429
|
+
};
|
|
430
|
+
if (outcome.continue) return {
|
|
431
|
+
outcome: _extends({}, spent, {
|
|
432
|
+
continue: true
|
|
433
|
+
}),
|
|
434
|
+
built: false
|
|
435
|
+
};
|
|
436
|
+
if (!outcome.outputs.length) return {
|
|
437
|
+
outcome: _extends({}, spent, {
|
|
438
|
+
failure: input.emptyCopy
|
|
439
|
+
}),
|
|
440
|
+
built: false
|
|
441
|
+
};
|
|
442
|
+
return {
|
|
443
|
+
outcome: spent,
|
|
444
|
+
built: true
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
export function createAiJobSiteStep(deps = {}) {
|
|
448
|
+
var _deps_runnerFor;
|
|
449
|
+
const runnerFor = (_deps_runnerFor = deps.runnerFor) != null ? _deps_runnerFor : aiJobStepRunnerFor;
|
|
450
|
+
return async (context)=>{
|
|
451
|
+
var _ref, _job_outputs;
|
|
452
|
+
const { job } = context;
|
|
453
|
+
// The scaffold asks no model of its own. What it names where it spends
|
|
454
|
+
// nothing is the model its plan ran on, which is the one exchange this
|
|
455
|
+
// job has already had of its own.
|
|
456
|
+
const model = (_ref = context.modelFor == null ? void 0 : context.modelFor.call(context, 'job.plan')) != null ? _ref : aiModelForStep('job.plan');
|
|
457
|
+
const plan = aiConfirmedPlan(job);
|
|
458
|
+
if (!plan) return _extends({}, aiUnspentOutcome(model), {
|
|
459
|
+
failure: AI_SITE_NO_PLAN_COPY
|
|
460
|
+
});
|
|
461
|
+
// The resume door refuses such a plan at confirmation once it can read
|
|
462
|
+
// one; a plan confirmed before a site changed still stops here, unspent.
|
|
463
|
+
const refusal = aiSitePlanRefusal(plan);
|
|
464
|
+
if (refusal) return _extends({}, aiUnspentOutcome(model), {
|
|
465
|
+
failure: refusal
|
|
466
|
+
});
|
|
467
|
+
const inputs = parseAiSiteJobInputs(job.inputs);
|
|
468
|
+
if (typeof inputs === 'string') return _extends({}, aiUnspentOutcome(model), {
|
|
469
|
+
failure: inputs
|
|
470
|
+
});
|
|
471
|
+
// A kind this deployment has not loaded is not among the units at all, so
|
|
472
|
+
// a scaffold owes only what something can build.
|
|
473
|
+
const units = aiSiteJobUnits(plan, {
|
|
474
|
+
welcomeEmail: inputs.welcomeEmail
|
|
475
|
+
}).filter((unit)=>runnerFor(unit.jobKind));
|
|
476
|
+
const outputs = (_job_outputs = job.outputs) != null ? _job_outputs : [];
|
|
477
|
+
const pending = aiSitePendingUnits(units, outputs);
|
|
478
|
+
if (!pending.length) return aiUnspentOutcome(model);
|
|
479
|
+
const unit = pending[0];
|
|
480
|
+
const runner = runnerFor(unit.jobKind);
|
|
481
|
+
if (!runner) return aiUnspentOutcome(model);
|
|
482
|
+
const pass = await aiRunJobUnit(context, {
|
|
483
|
+
unit,
|
|
484
|
+
units,
|
|
485
|
+
runner,
|
|
486
|
+
emptyCopy: AI_SITE_UNIT_EMPTY_COPY
|
|
487
|
+
});
|
|
488
|
+
// The site's own listing rides out beside the first unit's output, once
|
|
489
|
+
// (AGL-2918): it is derived from the answers rather than generated, so it
|
|
490
|
+
// is ready before anything is built and costs the pass nothing.
|
|
491
|
+
const outcome = _extends({}, pass.outcome, {
|
|
492
|
+
outputs: [
|
|
493
|
+
...aiSiteSeoOutputs(job),
|
|
494
|
+
...pass.outcome.outputs
|
|
495
|
+
]
|
|
496
|
+
});
|
|
497
|
+
// A built unit continues the scaffold while units remain after it.
|
|
498
|
+
return pass.built && pending.length > 1 ? _extends({}, outcome, {
|
|
499
|
+
continue: true
|
|
500
|
+
}) : outcome;
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
export const runAiJobSiteStep = createAiJobSiteStep();
|
|
504
|
+
/**
|
|
505
|
+
* The least time a scaffold's next pass needs (AGL-3035). The scaffold asks no
|
|
506
|
+
* model itself: each pass hands one unit to the step registered for its kind,
|
|
507
|
+
* under the job derived for it, so it needs what that step registers for that
|
|
508
|
+
* job — a palette change's or a layout's time for those units, a page pass's
|
|
509
|
+
* for a page. A scaffold with nothing left to build, or with no plan it can
|
|
510
|
+
* build, spends nothing, and a page pass's time covers it.
|
|
511
|
+
*/ export function aiSiteJobRunMinimumMs(job) {
|
|
512
|
+
var _job_outputs;
|
|
513
|
+
const plan = aiConfirmedPlan(job);
|
|
514
|
+
const inputs = parseAiSiteJobInputs(job.inputs);
|
|
515
|
+
if (!plan || typeof inputs === 'string') return AI_JOB_PAGE_STEP_MINIMUM_MS;
|
|
516
|
+
const units = aiSiteJobUnits(plan, {
|
|
517
|
+
welcomeEmail: inputs.welcomeEmail
|
|
518
|
+
}).filter((unit)=>aiJobStepRunnerFor(unit.jobKind));
|
|
519
|
+
const outputs = (_job_outputs = job.outputs) != null ? _job_outputs : [];
|
|
520
|
+
const [unit] = aiSitePendingUnits(units, outputs);
|
|
521
|
+
if (!unit) return AI_JOB_PAGE_STEP_MINIMUM_MS;
|
|
522
|
+
return aiJobStepRunMinimumMs(aiSiteUnitJob(job, unit, aiSiteBuiltRefs(units, outputs)));
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Registers the site scaffold with the least time a pass needs — every
|
|
526
|
+
* scaffold builds pages, and a page pass needs the least of any unit — and the
|
|
527
|
+
* time its next pass needs, the passes a whole site's plan may take, and the
|
|
528
|
+
* check a site job passes before it is created or resumed.
|
|
529
|
+
*/ export function registerAiSiteJob() {
|
|
530
|
+
registerAiJobStep('site', runAiJobSiteStep, {
|
|
531
|
+
minimumMs: AI_JOB_PAGE_STEP_MINIMUM_MS,
|
|
532
|
+
minimumMsFor: aiSiteJobRunMinimumMs
|
|
533
|
+
});
|
|
534
|
+
registerAiJobStepPasses('site', AI_SITE_MAX_PASSES);
|
|
535
|
+
registerAiJobAdmission('site', aiSiteJobAdmission);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
//# sourceMappingURL=ai-job-site-step.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-site-step.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { resolveOrgIdForHost } from '@aglyn/tenant-data-admin/server/organizations'\nimport {\n isAiPlanNewRef,\n type AiBuildPlanCreate,\n type AiBuildPlanCreateKind,\n type AiBuildPlanScreen,\n} from '../model/ai-build-plan'\nimport type {\n AiJob,\n AiJobKind,\n AiJobOutput,\n AiJobOutputResource,\n AiJobPlan,\n} from '../model/ai-jobs.types'\nimport {\n AI_SITE_EMAIL_TYPE,\n AI_SITE_MAX_SECTIONS,\n AI_SITE_PAGES,\n aiSitePlanRefusal,\n aiSiteSubmissions,\n aiSiteWords,\n parseAiSiteJobInputs,\n type AiSiteJobInputs,\n} from '../model/ai-site-job'\nimport {\n AI_SITE_SEO_OUTPUT_ID,\n aiSiteSeoProposalForInputs,\n} from '../model/ai-site-start-seo'\nimport { aiModelForStep } from '../providers/routing'\nimport { registerAiJobAdmission, type AiJobAdmission } from './ai-job-admission'\nimport { aiRecordedJobDraftId } from './ai-job-draft-ids'\nimport { aiConfirmedPlan, aiUnspentOutcome } from './ai-job-generation'\nimport {\n AI_JOB_BRIEF_MAX_CHARS,\n type AiJobStepContext,\n type AiJobStepOutcome,\n type AiJobStepRunner,\n} from './ai-job-text-step'\nimport { AI_JOB_PAGE_STEP_MINIMUM_MS } from './ai-job-page-budget'\nimport {\n aiJobStepRunMinimumMs,\n aiJobStepRunnerFor,\n registerAiJobStep,\n registerAiJobStepPasses,\n} from './ai-jobs'\n\n/**\n * The site scaffold (AGL-2911): the generation step of a `site` job, run once\n * a member confirmed the plan their brief produced.\n *\n * ── It builds nothing itself ─────────────────────────────────────────────\n *\n * A scaffold is a whole site: a palette suggestion, the layout its pages\n * render inside, the contact form they place, four to eight pages with their\n * search listings, and a welcome email. Every one of those is already a job\n * kind with a step of its own, so this step generates nothing and asks no\n * model anything. It works through the confirmed plan one UNIT at a time and\n * hands each unit to the runner registered for the kind that owns it — the\n * theme step for the palette, the page step for a page — under a job of that\n * kind derived from this one.\n *\n * That is why the scaffold cannot drift from the thing it scaffolds: a page\n * it builds is a page job's page, held to the same doctrine, written by the\n * same draft writer, left unpublished by the same rule. A kind whose step\n * this deployment has not loaded is simply not among the units, so nothing\n * here knows which issues have landed.\n *\n * ── One unit a pass ──────────────────────────────────────────────────────\n *\n * The step runs ONE delegated pass and asks the machine to continue, so every\n * pass is one reservation, one provider exchange and one recorded spend, and\n * the org's monthly ceiling binds a scaffold exactly as it binds a chat turn.\n * Credits running out mid-scaffold is therefore the machine's own park: the\n * job waits as `needs_input` with the meter's words, and the beat resumes it\n * where it stopped once the workspace's standing has changed. A pass needs the\n * time its unit's own step needs (`aiSiteJobRunMinimumMs`), so the beat starts\n * a palette change only with a palette change's time left.\n *\n * Where it stopped is read from the job's OUTPUTS rather than kept anywhere:\n * each unit reports exactly one output when it completes, so the units\n * already represented there are the ones already built. A pass interrupted\n * between its work and its record repeats a unit that then finds its own\n * draft and reports it, which is what every step's draft id already gives.\n *\n * ── Never published ──────────────────────────────────────────────────────\n *\n * Nothing here publishes, routes or sends: each delegated step writes the\n * unpublished draft it already wrote for a job of its own kind, and the\n * palette and navigation travel as proposals a member applies.\n *\n * ── The page job builds its creations the same way (AGL-3031) ────────────\n *\n * A page job whose plan creates a layout, forms or components builds them\n * before its page through this same machinery: the units a creation implies\n * (`aiCreationUnit`), where the job stands read from its outputs\n * (`aiSitePendingUnits`), one delegated pass a unit (`aiRunJobUnit`), and the\n * `new:<name>` references resolved to what was built (`aiSiteBuiltRefs`,\n * `aiSiteUnitJob`). There is one loop, and it is the machine's.\n */\n\n/** What a scaffold's units are, in the order it builds them; a component is a page job's. */\nexport type AiSiteUnitKind = 'theme' | 'layout' | 'form' | 'component' | 'page' | 'email'\n\nexport interface AiSiteUnit {\n kind: AiSiteUnitKind\n /** The job kind whose registered runner builds it. */\n jobKind: AiJobKind\n /** The resource the unit reports when it completes. */\n resource: AiJobOutputResource\n /** Stable within the job: what the unit's derived job and draft are addressed by. */\n slot: string\n /** The plan screen a page unit builds. */\n screen?: AiBuildPlanScreen\n /** The creation a theme, layout or form unit builds. */\n creation?: AiBuildPlanCreate\n /** What the unit is, for the derived job's brief. */\n label: string\n}\n\n/** The job kind and output resource each unit is built through. */\nconst UNIT_KINDS: Record<\n AiSiteUnitKind,\n { jobKind: AiJobKind; resource: AiJobOutputResource }\n> = {\n theme: { jobKind: 'theme', resource: 'theme' },\n layout: { jobKind: 'layout', resource: 'layout' },\n form: { jobKind: 'form', resource: 'form' },\n component: { jobKind: 'component', resource: 'reusableComponent' },\n page: { jobKind: 'page', resource: 'screen' },\n email: { jobKind: 'email', resource: 'emailScreen' },\n}\n\n/** The unit kind a creation is built as, where a unit builds it. */\nconst CREATION_UNIT_KINDS: Partial<Record<AiBuildPlanCreateKind, AiSiteUnitKind>> = {\n 'theme-change': 'theme',\n layout: 'layout',\n form: 'form',\n component: 'component',\n}\n\n/**\n * The unit one creation is built as, under the slot its derived job and draft\n * are addressed by; `null` for a creation no unit builds.\n */\nexport function aiCreationUnit(creation: AiBuildPlanCreate, slot: string): AiSiteUnit | null {\n const kind = CREATION_UNIT_KINDS[creation.kind]\n if (!kind) return null\n return { kind, ...UNIT_KINDS[kind], slot, creation, label: creation.name }\n}\n\n/** The creation kinds a unit is built from, by unit kind. */\nconst CREATION_UNITS: Array<{\n unit: AiSiteUnitKind\n create: AiBuildPlanCreateKind\n}> = [\n { unit: 'theme', create: 'theme-change' },\n { unit: 'layout', create: 'layout' },\n { unit: 'form', create: 'form' },\n]\n\nexport const AI_SITE_NO_PLAN_COPY =\n 'This site job has no confirmed plan to build.'\n\n/** What a scaffold answers where the step that builds a page is not loaded. */\nexport const AI_SITE_NO_PAGE_STEP_COPY =\n 'Building a whole site is not available yet.'\n\n/** A unit that finished without reporting what it built; the scaffold cannot go on. */\nexport const AI_SITE_UNIT_EMPTY_COPY =\n 'Part of this site could not be built. Try the site brief again.'\n\n/**\n * The most passes a scaffold's step may take: the largest plan it admits —\n * eight pages of eight sections, its three creations and a welcome email —\n * with nothing to spare, so a runner that never finishes is still bounded\n * while a real site is not.\n */\nexport const AI_SITE_MAX_PASSES =\n AI_SITE_PAGES.max * (AI_SITE_MAX_SECTIONS + 1) + CREATION_UNITS.length + 1\n\n/**\n * The units a plan implies, in build order: the palette first, because a\n * member reads it while the pages are still building; then the layout every\n * page renders inside and the form they place, because a page binds both by\n * id and so needs them to exist; then the pages; then the welcome email,\n * which is about the site rather than part of it.\n */\nexport function aiSiteJobUnits(\n plan: Pick<AiJobPlan, 'create' | 'screens'>,\n options: { welcomeEmail?: boolean } = {},\n): AiSiteUnit[] {\n const units: AiSiteUnit[] = []\n for (const { unit, create } of CREATION_UNITS) {\n const creation = plan.create.find((entry) => entry.kind === create)\n if (!creation) continue\n units.push({\n kind: unit,\n ...UNIT_KINDS[unit],\n slot: unit[0],\n creation,\n label: creation.name,\n })\n }\n plan.screens.forEach((screen, index) => {\n units.push({\n kind: 'page',\n ...UNIT_KINDS.page,\n slot: `p${index}`,\n screen,\n label: screen.title,\n })\n })\n if (options.welcomeEmail) {\n units.push({\n kind: 'email',\n ...UNIT_KINDS.email,\n slot: 'e',\n label: 'Welcome email',\n })\n }\n return units\n}\n\n/**\n * The units a scaffold still owes after the outputs recorded so far. Each\n * unit reports one output of its own resource when it completes, so the\n * outputs already recorded are consumed against the units in build order.\n */\nexport function aiSitePendingUnits(\n units: readonly AiSiteUnit[],\n outputs: readonly Pick<AiJobOutput, 'resource'>[],\n): AiSiteUnit[] {\n const done = new Map<AiJobOutputResource, number>()\n for (const output of outputs) {\n done.set(output.resource, (done.get(output.resource) ?? 0) + 1)\n }\n return units.filter((unit) => {\n const left = done.get(unit.resource) ?? 0\n if (left <= 0) return true\n done.set(unit.resource, left - 1)\n return false\n })\n}\n\n/**\n * The site's own search listing as the scaffold reports it (AGL-2918), or\n * nothing when the job already reported one or its inputs describe no site.\n *\n * It costs nothing and asks no model: the values are arithmetic on the\n * answers (`aiSiteSeoProposal`), so they ride out on the first pass that\n * builds anything rather than waiting for a pass of their own. Its resource\n * is `seo`, which no unit reports, so it cannot be mistaken for a unit's\n * output by `aiSitePendingUnits` and cannot move where the scaffold thinks\n * it is.\n */\nexport function aiSiteSeoOutputs(job: AiJob): AiJobOutput[] {\n const outputs = job.outputs ?? []\n if (outputs.some((output) => output.resource === 'seo' && output.id === AI_SITE_SEO_OUTPUT_ID)) {\n return []\n }\n const proposal = aiSiteSeoProposalForInputs(job.inputs)\n if (!proposal) return []\n return [\n {\n resource: 'seo',\n id: AI_SITE_SEO_OUTPUT_ID,\n hostId: job.hostId ?? null,\n label: 'The site’s search title and description',\n proposal: proposal as unknown as Record<string, unknown>,\n },\n ]\n}\n\n/** A record an earlier unit created, as a later one references it. */\nexport interface AiSiteBuiltRef {\n id: string\n label: string\n /** Only what becomes a record a page can name; a palette change is not one. */\n kind: 'layout' | 'form' | 'component'\n}\n\n/**\n * What the scaffold has already created, as the plan's `new:<name>`\n * references resolve to: the id of the record each completed creation wrote.\n * A page unit is told about the layout and the form by id, exactly as a page\n * job is told about records the site already had.\n */\nexport function aiSiteBuiltRefs(\n units: readonly AiSiteUnit[],\n outputs: readonly Pick<AiJobOutput, 'resource' | 'id' | 'label'>[],\n): Map<string, AiSiteBuiltRef> {\n const byResource = new Map<\n AiJobOutputResource,\n Array<Pick<AiJobOutput, 'id' | 'label'>>\n >()\n for (const output of outputs) {\n const rows = byResource.get(output.resource) ?? []\n rows.push(output)\n byResource.set(output.resource, rows)\n }\n const built = new Map<string, AiSiteBuiltRef>()\n for (const unit of units) {\n const rows = byResource.get(unit.resource)\n const row = rows?.shift()\n if (!row || !unit.creation) continue\n // A theme change is a proposal with no record to reference; a layout, a\n // form and a component become ids a page can name.\n if (\n unit.creation.kind !== 'layout' &&\n unit.creation.kind !== 'form' &&\n unit.creation.kind !== 'component'\n ) {\n continue\n }\n built.set(unit.creation.name.toLowerCase(), {\n id: row.id,\n label: row.label || unit.creation.name,\n kind: unit.creation.kind,\n })\n }\n return built\n}\n\ntype BuiltRefs = ReturnType<typeof aiSiteBuiltRefs>\n\n/** A plan reference as the unit's own job reads it: an id the site now has, or nothing. */\nfunction resolved(ref: string | null, built: BuiltRefs): string | null {\n if (!ref) return null\n if (!isAiPlanNewRef(ref)) return ref\n return (\n built.get(\n ref\n .slice(ref.indexOf(':') + 1)\n .trim()\n .toLowerCase(),\n )?.id ?? null\n )\n}\n\n/**\n * The site's own words, as every unit's brief carries them.\n *\n * The audience is here rather than left to the brief's prose (AGL-2918). A\n * guided start writes it into the brief itself, but an agency batch's brief\n * is a member's own sentence and may never mention it, and a theme, a layout\n * or a form asked to serve nobody in particular serves nobody in particular.\n */\nexport function aiSiteBriefLines(\n brief: string,\n inputs: AiSiteJobInputs,\n): string[] {\n const lines = [brief.trim()]\n const site = [\n inputs.businessName ? `name: ${inputs.businessName}` : '',\n `business: ${inputs.businessType}`,\n inputs.audience ? `for: ${inputs.audience}` : '',\n inputs.city ? `city: ${inputs.city}` : '',\n inputs.brand ? `brand: ${inputs.brand}` : '',\n ].filter(Boolean)\n lines.push(`Site — ${site.join('; ')}.`)\n return lines\n}\n\n/**\n * What the welcome email is told (AGL-2918), beyond that it is a welcome\n * email.\n *\n * The scaffold's email unit used to carry one sentence, and a yes/no toggle\n * decided whether it ran — so the draft was a welcome email for a business\n * in general, to nobody in particular, about nothing that had happened. The\n * two answers it is missing are who wrote in and what now becomes of what\n * they wrote, and the second of those is the person's own routing answer, so\n * the email and the form it acknowledges cannot say different things.\n *\n * ⛔ A DRAFT either way. Nothing here sends, schedules or enrolls anybody:\n * the email step writes an unpublished email design and stops.\n */\nexport function aiSiteEmailBriefLines(\n inputs: Readonly<Record<string, unknown>> | null | undefined,\n): string[] {\n const lines = [\n 'Write the welcome email this site sends someone who gets in touch.',\n ]\n const { audience } = aiSiteWords(inputs)\n if (audience) lines.push(`Write it to ${audience}.`)\n const submissions = aiSiteSubmissions(inputs)\n if (submissions === 'lead') {\n lines.push('Their message is a sales lead, so say that somebody will be in touch about it.')\n } else if (submissions === 'inbox') {\n lines.push('Their message has been read, so say it arrived and that a reply is coming.')\n }\n return lines\n}\n\n/**\n * The id a unit's job is named by, and so the id its draft is written under\n * (AGL-3079): the id the plan entry it builds recorded, or for the welcome\n * email the id recorded on this job's step. A unit that writes no draft — a\n * palette change — and a unit whose plan recorded no id are named by this\n * job's id and the unit's slot, the name every draft of such a plan has.\n */\nexport function aiSiteUnitJobId(job: Pick<AiJob, '$id' | 'steps'>, unit: AiSiteUnit): string {\n const recorded =\n unit.creation?.id ?? unit.screen?.id ?? (unit.kind === 'email' ? aiRecordedJobDraftId(job, 'email') : null)\n return recorded || `${job.$id}-${unit.slot}`\n}\n\n/**\n * The job a unit is built under: this job's org, site, creator and model,\n * the kind that owns the unit, and a plan narrowed to the unit alone.\n *\n * The derived job carries NO steps and NO outputs of the scaffold's: a page\n * job's step reads its own draft and its own plan, and what the other units\n * produced is not its business. Its `$id` is the id the unit's draft is\n * written under (`aiSiteUnitJobId`), which is what a step with no id of its\n * own recorded names its draft by, so a unit re-run after its write finds its\n * own draft rather than writing a second.\n *\n * A creation unit reuses what the plan reuses less what the plan's screens\n * place themselves (AGL-3031): a component a page's section places is the\n * page's to place, and a layout or a card told to place it would be refused\n * for leaving it out.\n */\nexport function aiSiteUnitJob(\n job: AiJob,\n unit: AiSiteUnit,\n built: BuiltRefs,\n): AiJob {\n const plan = job.plan as AiJobPlan\n const labels = { ...(plan.labels ?? {}) }\n for (const entry of built.values()) labels[entry.id] = entry.label\n const inputs = parseAiSiteJobInputs(job.inputs)\n const brief =\n typeof inputs === 'string'\n ? [job.brief]\n : aiSiteBriefLines(job.brief, inputs)\n const unitPlan: AiJobPlan = {\n ...plan,\n labels,\n reuse: [...plan.reuse],\n create: [],\n screens: [],\n }\n if (unit.creation) {\n const placedByScreens = new Set(\n plan.screens.flatMap((screen) => screen.sections.flatMap((section) => section.uses)),\n )\n unitPlan.reuse = plan.reuse.filter((entry) => !placedByScreens.has(entry.id))\n unitPlan.create = [\n {\n ...unit.creation,\n duplicateOf: resolved(unit.creation.duplicateOf, built),\n },\n ]\n brief.push(\n `Build the ${unit.creation.kind} “${unit.creation.name}”: ${unit.creation.why}`,\n )\n }\n if (unit.screen) {\n const screen = unit.screen\n // Everything the scaffold has already built is a record the site has, so\n // the page is planned against it the way a page job is planned against\n // what the site always had.\n for (const entry of built.values()) {\n unitPlan.reuse.push({\n kind: entry.kind,\n id: entry.id,\n purpose: `the ${entry.kind} this site’s pages are built on`,\n })\n }\n unitPlan.screens = [\n {\n ...screen,\n layout: resolved(screen.layout, built),\n template: resolved(screen.template, built),\n duplicateOf: resolved(screen.duplicateOf, built),\n sections: screen.sections.map((section) => ({\n ...section,\n uses: section.uses\n .map((ref) => resolved(ref, built))\n .filter((ref): ref is string => !!ref),\n })),\n },\n ]\n brief.push(\n `Build the page “${screen.title}” of this site, at ${screen.slug}.`,\n )\n }\n if (unit.kind === 'email') {\n brief.push(...aiSiteEmailBriefLines(job.inputs))\n }\n return {\n ...job,\n $id: aiSiteUnitJobId(job, unit),\n kind: unit.jobKind,\n steps: [],\n outputs: [],\n plan: unitPlan,\n // A theme change on a site with no theme of its own is a new palette.\n ...(unit.kind === 'theme'\n ? { inputs: { ...job.inputs, mode: 'create' } }\n : {}),\n // The email step reads the kind off the inputs it is handed, so a job the\n // scaffold composed says which kind it is exactly as a member's own does.\n ...(unit.kind === 'email'\n ? { inputs: { ...job.inputs, emailType: AI_SITE_EMAIL_TYPE } }\n : {}),\n brief: brief.join('\\n').slice(0, AI_JOB_BRIEF_MAX_CHARS),\n }\n}\n\n/**\n * A scaffold is admitted with inputs that read, for a site of the job's own\n * org, and only where this deployment has loaded the step that builds a page:\n * a scaffold whose pages nothing can build is not a scaffold.\n */\nexport const aiSiteJobAdmission: AiJobAdmission = async (context) => {\n const inputs = parseAiSiteJobInputs(context.inputs)\n if (typeof inputs === 'string') return { status: 400, error: inputs }\n if (!context.hostId) {\n return {\n status: 400,\n error: 'Open the site the scaffold is for before starting the job',\n }\n }\n const owner = await resolveOrgIdForHost(context.hostId)\n if (!owner || owner !== context.orgId)\n return { status: 404, error: 'Unknown site' }\n if (!aiJobStepRunnerFor('page')) {\n return { status: 400, error: AI_SITE_NO_PAGE_STEP_COPY }\n }\n return null\n}\n\n/** What one delegated pass came to: the unit's spend as the job records it, and whether the unit is built. */\nexport interface AiJobUnitPass {\n outcome: AiJobStepOutcome\n /** The unit reported what it built and asked for no pass of its own. */\n built: boolean\n}\n\n/**\n * One delegated pass (AGL-2911, AGL-3031): the unit handed to the runner of\n * the kind that owns it, under the job derived for it, and its outcome as the\n * delegating job records it. A delegate proposes a plan for its own job,\n * which does not exist, so no plan is carried back. A unit that stopped for a\n * person, refused or failed is the delegating job's stop; a unit that asked\n * for another pass keeps its turn; and a unit that finished without reporting\n * what it built fails with `emptyCopy`, since another pass would ask the same\n * thing again. The tokens it spent are on the bill either way.\n */\nexport async function aiRunJobUnit(\n context: AiJobStepContext,\n input: {\n unit: AiSiteUnit\n units: readonly AiSiteUnit[]\n runner: AiJobStepRunner\n emptyCopy: string\n },\n): Promise<AiJobUnitPass> {\n const { job } = context\n const outputs = job.outputs ?? []\n const outcome = await input.runner({\n ...context,\n job: aiSiteUnitJob(job, input.unit, aiSiteBuiltRefs(input.units, outputs)),\n })\n const spent: AiJobStepOutcome = {\n outputs: outcome.outputs,\n usage: outcome.usage,\n estCostUsd: outcome.estCostUsd,\n model: outcome.model,\n stopReason: outcome.stopReason,\n ...(outcome.effort ? { effort: outcome.effort } : {}),\n ...(outcome.refused ? { refused: true } : {}),\n ...(outcome.failure ? { failure: outcome.failure } : {}),\n ...(outcome.review ? { review: outcome.review } : {}),\n }\n if (spent.review || spent.refused || spent.failure) return { outcome: spent, built: false }\n if (outcome.continue) return { outcome: { ...spent, continue: true }, built: false }\n if (!outcome.outputs.length) return { outcome: { ...spent, failure: input.emptyCopy }, built: false }\n return { outcome: spent, built: true }\n}\n\nexport interface AiJobSiteStepDeps {\n /** The runner registry; specs hand in a fake for a kind they drive. */\n runnerFor?: typeof aiJobStepRunnerFor\n}\n\nexport function createAiJobSiteStep(\n deps: AiJobSiteStepDeps = {},\n): AiJobStepRunner {\n const runnerFor = deps.runnerFor ?? aiJobStepRunnerFor\n return async (context): Promise<AiJobStepOutcome> => {\n const { job } = context\n // The scaffold asks no model of its own. What it names where it spends\n // nothing is the model its plan ran on, which is the one exchange this\n // job has already had of its own.\n const model = context.modelFor?.('job.plan') ?? aiModelForStep('job.plan')\n const plan = aiConfirmedPlan(job)\n if (!plan)\n return { ...aiUnspentOutcome(model), failure: AI_SITE_NO_PLAN_COPY }\n // The resume door refuses such a plan at confirmation once it can read\n // one; a plan confirmed before a site changed still stops here, unspent.\n const refusal = aiSitePlanRefusal(plan)\n if (refusal) return { ...aiUnspentOutcome(model), failure: refusal }\n const inputs = parseAiSiteJobInputs(job.inputs)\n if (typeof inputs === 'string')\n return { ...aiUnspentOutcome(model), failure: inputs }\n\n // A kind this deployment has not loaded is not among the units at all, so\n // a scaffold owes only what something can build.\n const units = aiSiteJobUnits(plan, {\n welcomeEmail: inputs.welcomeEmail,\n }).filter((unit) => runnerFor(unit.jobKind))\n const outputs = job.outputs ?? []\n const pending = aiSitePendingUnits(units, outputs)\n if (!pending.length) return aiUnspentOutcome(model)\n const unit = pending[0]\n const runner = runnerFor(unit.jobKind)\n if (!runner) return aiUnspentOutcome(model)\n\n const pass = await aiRunJobUnit(context, {\n unit,\n units,\n runner,\n emptyCopy: AI_SITE_UNIT_EMPTY_COPY,\n })\n // The site's own listing rides out beside the first unit's output, once\n // (AGL-2918): it is derived from the answers rather than generated, so it\n // is ready before anything is built and costs the pass nothing.\n const outcome: AiJobStepOutcome = {\n ...pass.outcome,\n outputs: [...aiSiteSeoOutputs(job), ...pass.outcome.outputs],\n }\n // A built unit continues the scaffold while units remain after it.\n return pass.built && pending.length > 1 ? { ...outcome, continue: true } : outcome\n }\n}\n\nexport const runAiJobSiteStep = createAiJobSiteStep()\n\n/**\n * The least time a scaffold's next pass needs (AGL-3035). The scaffold asks no\n * model itself: each pass hands one unit to the step registered for its kind,\n * under the job derived for it, so it needs what that step registers for that\n * job — a palette change's or a layout's time for those units, a page pass's\n * for a page. A scaffold with nothing left to build, or with no plan it can\n * build, spends nothing, and a page pass's time covers it.\n */\nexport function aiSiteJobRunMinimumMs(job: AiJob): number {\n const plan = aiConfirmedPlan(job)\n const inputs = parseAiSiteJobInputs(job.inputs)\n if (!plan || typeof inputs === 'string') return AI_JOB_PAGE_STEP_MINIMUM_MS\n const units = aiSiteJobUnits(plan, { welcomeEmail: inputs.welcomeEmail }).filter((unit) =>\n aiJobStepRunnerFor(unit.jobKind),\n )\n const outputs = job.outputs ?? []\n const [unit] = aiSitePendingUnits(units, outputs)\n if (!unit) return AI_JOB_PAGE_STEP_MINIMUM_MS\n return aiJobStepRunMinimumMs(aiSiteUnitJob(job, unit, aiSiteBuiltRefs(units, outputs)))\n}\n\n/**\n * Registers the site scaffold with the least time a pass needs — every\n * scaffold builds pages, and a page pass needs the least of any unit — and the\n * time its next pass needs, the passes a whole site's plan may take, and the\n * check a site job passes before it is created or resumed.\n */\nexport function registerAiSiteJob(): void {\n registerAiJobStep('site', runAiJobSiteStep, {\n minimumMs: AI_JOB_PAGE_STEP_MINIMUM_MS,\n minimumMsFor: aiSiteJobRunMinimumMs,\n })\n registerAiJobStepPasses('site', AI_SITE_MAX_PASSES)\n registerAiJobAdmission('site', aiSiteJobAdmission)\n}\n"],"names":["resolveOrgIdForHost","isAiPlanNewRef","AI_SITE_EMAIL_TYPE","AI_SITE_MAX_SECTIONS","AI_SITE_PAGES","aiSitePlanRefusal","aiSiteSubmissions","aiSiteWords","parseAiSiteJobInputs","AI_SITE_SEO_OUTPUT_ID","aiSiteSeoProposalForInputs","aiModelForStep","registerAiJobAdmission","aiRecordedJobDraftId","aiConfirmedPlan","aiUnspentOutcome","AI_JOB_BRIEF_MAX_CHARS","AI_JOB_PAGE_STEP_MINIMUM_MS","aiJobStepRunMinimumMs","aiJobStepRunnerFor","registerAiJobStep","registerAiJobStepPasses","UNIT_KINDS","theme","jobKind","resource","layout","form","component","page","email","CREATION_UNIT_KINDS","aiCreationUnit","creation","slot","kind","label","name","CREATION_UNITS","unit","create","AI_SITE_NO_PLAN_COPY","AI_SITE_NO_PAGE_STEP_COPY","AI_SITE_UNIT_EMPTY_COPY","AI_SITE_MAX_PASSES","max","length","aiSiteJobUnits","plan","options","units","find","entry","push","screens","forEach","screen","index","title","welcomeEmail","aiSitePendingUnits","outputs","done","Map","output","set","get","filter","left","aiSiteSeoOutputs","job","some","id","proposal","inputs","hostId","aiSiteBuiltRefs","byResource","rows","built","row","shift","toLowerCase","resolved","ref","slice","indexOf","trim","aiSiteBriefLines","brief","lines","site","businessName","businessType","audience","city","brand","Boolean","join","aiSiteEmailBriefLines","submissions","aiSiteUnitJobId","recorded","$id","aiSiteUnitJob","labels","values","unitPlan","reuse","placedByScreens","Set","flatMap","sections","section","uses","has","duplicateOf","why","purpose","template","map","slug","steps","mode","emailType","aiSiteJobAdmission","context","status","error","owner","orgId","aiRunJobUnit","input","outcome","runner","spent","usage","estCostUsd","model","stopReason","effort","refused","failure","review","continue","emptyCopy","createAiJobSiteStep","deps","runnerFor","modelFor","refusal","pending","pass","runAiJobSiteStep","aiSiteJobRunMinimumMs","registerAiSiteJob","minimumMs","minimumMsFor"],"mappings":"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"}
|