@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,307 @@
|
|
|
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
|
+
*/ // lockdown-423: via libs/plugins/ai/src/lib/runtime/ai-gate.ts
|
|
18
|
+
// The POST climbs `aiGateLadder`, whose lockdown rung is the verdict; the
|
|
19
|
+
// GET climbs `ai-jobs-gate.ts`, which carries the same rung.
|
|
20
|
+
import { randomUUID } from "crypto";
|
|
21
|
+
import { AI_JOB_KINDS } from "../model/ai-jobs.types.js";
|
|
22
|
+
// By their own entry points rather than the barrel (AGL-2903): the specs
|
|
23
|
+
// stub the barrel closed-world, and the ladder, the machine and the runtime
|
|
24
|
+
// are the things under test here, not things to be stubbed away.
|
|
25
|
+
import { aiGateLadder } from "../runtime/ai-gate.js";
|
|
26
|
+
import { aiJobAdmissionRefusal, aiJobSiteRefusal } from "../jobs/ai-job-admission.js";
|
|
27
|
+
import { AI_JOB_BRIEF_MAX_CHARS } from "../jobs/ai-job-text-step.js";
|
|
28
|
+
import { AI_JOB_INLINE_BUDGET_MS, aiJobNextStepMinimumMs, aiJobSummary, createAiJob, listAiJobs, runAiJobStep } from "../jobs/ai-jobs.js";
|
|
29
|
+
import { releaseAssistMessage } from "../usage/assist-usage.js";
|
|
30
|
+
import { aiUsageMeter } from "../usage/ai-usage-meter.js";
|
|
31
|
+
import { aiJobsGate } from "./ai-jobs-gate.js";
|
|
32
|
+
/**
|
|
33
|
+
* AI generation jobs: create and list (AGL-2904).
|
|
34
|
+
*
|
|
35
|
+
* `POST` is a door that spends, so it climbs the whole ladder (AGL-2903) —
|
|
36
|
+
* `aiGenerative`, `release_ai_generative`, the `ai-generate` switch, a
|
|
37
|
+
* per-uid window, and a reservation — and then creates the job and runs
|
|
38
|
+
* its first step INLINE under `AI_JOB_INLINE_BUDGET_MS`. A step that
|
|
39
|
+
* finishes in time answers with the job `done` (or `queued` behind its
|
|
40
|
+
* next step); one that does not is aborted, its reservation handed back,
|
|
41
|
+
* and the job answers `queued` for the beat to resume. Either way the
|
|
42
|
+
* caller gets the job document, and the events route is how it watches
|
|
43
|
+
* from there.
|
|
44
|
+
*
|
|
45
|
+
* `GET` lists the org's jobs, newest first, through the read gate: the
|
|
46
|
+
* same rungs up to the lockdown verdict, no reservation.
|
|
47
|
+
*
|
|
48
|
+
* The request must NAME the org it is metered against (AGL-1934). There
|
|
49
|
+
* is no fallback to "the caller's first org".
|
|
50
|
+
*/ const AI_JOBS_RATE_LIMIT = {
|
|
51
|
+
key: 'ai-jobs',
|
|
52
|
+
limit: 10,
|
|
53
|
+
windowMs: 60000
|
|
54
|
+
};
|
|
55
|
+
/** Kind-specific inputs, bounded: a runner reads scalars, not a document. */ const MAX_INPUTS_JSON_CHARS = 8000;
|
|
56
|
+
/** The admitted statuses for the list filter, as the union spells them. */ const AI_JOB_STATUSES = [
|
|
57
|
+
'queued',
|
|
58
|
+
'running',
|
|
59
|
+
'needs_input',
|
|
60
|
+
'needs_review',
|
|
61
|
+
'done',
|
|
62
|
+
'failed',
|
|
63
|
+
'canceled'
|
|
64
|
+
];
|
|
65
|
+
const ID_CHARS = /^[A-Za-z0-9_-]{1,100}$/;
|
|
66
|
+
/** The longest model id a body may carry; the catalog's ids are far shorter. */ const MAX_MODEL_CHARS = 100;
|
|
67
|
+
/** Validate + clamp the request body; a string names what is wrong. */ export function parseCreateAiJobBody(payload) {
|
|
68
|
+
var _body_orgId, _body_kind, _body_brief;
|
|
69
|
+
const body = payload != null ? payload : {};
|
|
70
|
+
const orgId = String((_body_orgId = body.orgId) != null ? _body_orgId : '').trim();
|
|
71
|
+
if (!orgId) return 'Open a workspace before using this feature';
|
|
72
|
+
const kind = String((_body_kind = body.kind) != null ? _body_kind : '');
|
|
73
|
+
if (!AI_JOB_KINDS.includes(kind)) {
|
|
74
|
+
return `kind must be one of ${AI_JOB_KINDS.join(', ')}`;
|
|
75
|
+
}
|
|
76
|
+
const brief = String((_body_brief = body.brief) != null ? _body_brief : '').trim();
|
|
77
|
+
if (!brief) return 'Write a brief for the job';
|
|
78
|
+
if (brief.length > AI_JOB_BRIEF_MAX_CHARS) {
|
|
79
|
+
return `Keep the brief under ${AI_JOB_BRIEF_MAX_CHARS.toLocaleString('en-US')} characters`;
|
|
80
|
+
}
|
|
81
|
+
const rawHost = body.hostId;
|
|
82
|
+
const hostId = rawHost === undefined || rawHost === null || rawHost === '' ? null : typeof rawHost === 'string' && ID_CHARS.test(rawHost) ? rawHost : undefined;
|
|
83
|
+
if (hostId === undefined) return 'hostId is not a site id';
|
|
84
|
+
// A theme is fields on one site's document, so a theme job that names no
|
|
85
|
+
// site has nothing to propose a change to (AGL-2938).
|
|
86
|
+
if (kind === 'theme' && !hostId) return 'Open a site before changing its theme';
|
|
87
|
+
const rawInputs = body.inputs;
|
|
88
|
+
const inputs = {};
|
|
89
|
+
if (rawInputs !== undefined && rawInputs !== null) {
|
|
90
|
+
if (typeof rawInputs !== 'object' || Array.isArray(rawInputs)) {
|
|
91
|
+
return 'inputs must be an object';
|
|
92
|
+
}
|
|
93
|
+
for (const [key, value] of Object.entries(rawInputs)){
|
|
94
|
+
if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {
|
|
95
|
+
return `inputs.${key} must be a string, number or boolean`;
|
|
96
|
+
}
|
|
97
|
+
inputs[key] = value;
|
|
98
|
+
}
|
|
99
|
+
if (JSON.stringify(inputs).length > MAX_INPUTS_JSON_CHARS) {
|
|
100
|
+
return 'inputs are too large';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const rawModel = typeof body.model === 'string' ? body.model.trim() : '';
|
|
104
|
+
if (rawModel.length > MAX_MODEL_CHARS) return 'model is not a model id';
|
|
105
|
+
// Validated against the plan and the allotment allowlists when each step
|
|
106
|
+
// runs, not here: the allowlists are read inside the step's reservation.
|
|
107
|
+
const model = rawModel && rawModel !== 'auto' ? rawModel : null;
|
|
108
|
+
return {
|
|
109
|
+
orgId,
|
|
110
|
+
hostId,
|
|
111
|
+
kind: kind,
|
|
112
|
+
brief,
|
|
113
|
+
inputs,
|
|
114
|
+
model
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export async function POST(request) {
|
|
118
|
+
var _ref, _gate_decoded_email;
|
|
119
|
+
let payload;
|
|
120
|
+
try {
|
|
121
|
+
payload = await request.json();
|
|
122
|
+
} catch (unused) {
|
|
123
|
+
payload = null;
|
|
124
|
+
}
|
|
125
|
+
const parsed = parseCreateAiJobBody(payload);
|
|
126
|
+
// The org is parsed BEFORE the ladder so a request that named none is
|
|
127
|
+
// refused with the ladder's 400 rather than a shape error; every other
|
|
128
|
+
// shape fault waits until the caller has proven who they are.
|
|
129
|
+
const orgId = typeof parsed === 'string' ? String((_ref = payload == null ? void 0 : payload.orgId) != null ? _ref : '') : parsed.orgId;
|
|
130
|
+
// The site rides along for the same reason: a collaborator's `ai.generate`
|
|
131
|
+
// is decided per site (AGL-2927), so the ladder needs it before it can say
|
|
132
|
+
// whether this member may generate here at all.
|
|
133
|
+
const hostId = typeof parsed === 'string' ? null : parsed.hostId;
|
|
134
|
+
const gate = await aiGateLadder({
|
|
135
|
+
request,
|
|
136
|
+
orgId,
|
|
137
|
+
hostId
|
|
138
|
+
}, {
|
|
139
|
+
feature: 'aiGenerative',
|
|
140
|
+
releaseFlag: 'release_ai_generative',
|
|
141
|
+
lockdownFeature: 'ai-generate',
|
|
142
|
+
permission: 'ai.generate',
|
|
143
|
+
rateLimit: AI_JOBS_RATE_LIMIT
|
|
144
|
+
});
|
|
145
|
+
if (gate instanceof Response) return gate;
|
|
146
|
+
if (typeof parsed === 'string') {
|
|
147
|
+
// Admitted, reserved, and then found to have sent nothing runnable: the
|
|
148
|
+
// reservation goes back, because no token was spent.
|
|
149
|
+
await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(()=>undefined);
|
|
150
|
+
return Response.json({
|
|
151
|
+
error: parsed
|
|
152
|
+
}, {
|
|
153
|
+
status: 400
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// What only this kind can say about the request (AGL-2909): a site it
|
|
157
|
+
// needs, inputs it reads, an allowance its draft counts against. Asked
|
|
158
|
+
// before the job exists, so a refusal spends nothing.
|
|
159
|
+
let refusal;
|
|
160
|
+
try {
|
|
161
|
+
var _ref1;
|
|
162
|
+
// A site that switched AI off first (AGL-3028), then the kind's own check.
|
|
163
|
+
refusal = (_ref1 = await aiJobSiteRefusal({
|
|
164
|
+
firestore: gate.firestore,
|
|
165
|
+
org: gate.org,
|
|
166
|
+
hostId: parsed.hostId
|
|
167
|
+
})) != null ? _ref1 : await aiJobAdmissionRefusal(parsed.kind, {
|
|
168
|
+
firestore: gate.firestore,
|
|
169
|
+
orgId: gate.orgId,
|
|
170
|
+
hostId: parsed.hostId,
|
|
171
|
+
inputs: parsed.inputs,
|
|
172
|
+
org: gate.org,
|
|
173
|
+
uid: gate.uid
|
|
174
|
+
});
|
|
175
|
+
} catch (error) {
|
|
176
|
+
await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(()=>undefined);
|
|
177
|
+
console.error('ai job admission failed', {
|
|
178
|
+
orgId: gate.orgId,
|
|
179
|
+
kind: parsed.kind,
|
|
180
|
+
error
|
|
181
|
+
});
|
|
182
|
+
return Response.json({
|
|
183
|
+
error: 'The AI job could not be created'
|
|
184
|
+
}, {
|
|
185
|
+
status: 500
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
if (refusal) {
|
|
189
|
+
await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(()=>undefined);
|
|
190
|
+
return Response.json({
|
|
191
|
+
error: refusal.error
|
|
192
|
+
}, {
|
|
193
|
+
status: refusal.status
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const now = new Date();
|
|
197
|
+
let created;
|
|
198
|
+
try {
|
|
199
|
+
var _gate_decoded_email1;
|
|
200
|
+
created = await createAiJob(gate.firestore, {
|
|
201
|
+
orgId: gate.orgId,
|
|
202
|
+
hostId: parsed.hostId,
|
|
203
|
+
kind: parsed.kind,
|
|
204
|
+
brief: parsed.brief,
|
|
205
|
+
inputs: parsed.inputs,
|
|
206
|
+
model: parsed.model,
|
|
207
|
+
createdBy: gate.uid,
|
|
208
|
+
createdByEmail: (_gate_decoded_email1 = gate.decoded.email) != null ? _gate_decoded_email1 : null
|
|
209
|
+
}, now);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(()=>undefined);
|
|
212
|
+
console.error('ai job create failed', {
|
|
213
|
+
orgId: gate.orgId,
|
|
214
|
+
error
|
|
215
|
+
});
|
|
216
|
+
return Response.json({
|
|
217
|
+
error: 'The AI job could not be created'
|
|
218
|
+
}, {
|
|
219
|
+
status: 500
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
const jobId = created.$id;
|
|
223
|
+
// A first step that needs more time than this request has (AGL-2907) is left
|
|
224
|
+
// queued for the beat, which starts it with a budget of its own: a provider
|
|
225
|
+
// call this request's timeout cut off would be billed upstream and metered
|
|
226
|
+
// nowhere. Nothing ran, so the reservation goes back.
|
|
227
|
+
if (aiJobNextStepMinimumMs(created) > AI_JOB_INLINE_BUDGET_MS) {
|
|
228
|
+
await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(()=>undefined);
|
|
229
|
+
return Response.json({
|
|
230
|
+
job: aiJobSummary(created, now),
|
|
231
|
+
meter: aiUsageMeter(gate.reservation, {
|
|
232
|
+
lastCredits: null
|
|
233
|
+
})
|
|
234
|
+
}, {
|
|
235
|
+
status: 200
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
// The first step, inline, on the reservation the ladder already holds.
|
|
239
|
+
// The runner hands that reservation back itself if the provider is never
|
|
240
|
+
// reached, and re-queues the step when the budget ends first.
|
|
241
|
+
const run = await runAiJobStep(gate.firestore, gate.orgId, jobId, {
|
|
242
|
+
owner: `route:${randomUUID()}`,
|
|
243
|
+
now,
|
|
244
|
+
reservation: gate.reservation,
|
|
245
|
+
org: gate.org,
|
|
246
|
+
signal: AbortSignal.timeout(AI_JOB_INLINE_BUDGET_MS),
|
|
247
|
+
// The caller is on the request, so what the inline step produces is
|
|
248
|
+
// attributed with their address; the beat's steps carry the uid alone.
|
|
249
|
+
actor: {
|
|
250
|
+
uid: gate.uid,
|
|
251
|
+
email: (_gate_decoded_email = gate.decoded.email) != null ? _gate_decoded_email : null
|
|
252
|
+
},
|
|
253
|
+
// The workspace's AI pause lets staff through, as the ladder above did.
|
|
254
|
+
staff: gate.staff
|
|
255
|
+
});
|
|
256
|
+
if (run.outcome === 'not-claimable') {
|
|
257
|
+
// A job created a moment ago has a claimable first step; anything else
|
|
258
|
+
// is a fault in the machine, and the reservation must not be stranded.
|
|
259
|
+
await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(()=>undefined);
|
|
260
|
+
console.error('ai job first step not claimable', {
|
|
261
|
+
orgId: gate.orgId,
|
|
262
|
+
jobId
|
|
263
|
+
});
|
|
264
|
+
return Response.json({
|
|
265
|
+
error: 'The AI job could not be started'
|
|
266
|
+
}, {
|
|
267
|
+
status: 500
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
return Response.json({
|
|
271
|
+
job: aiJobSummary(run.job),
|
|
272
|
+
// The usage strip's envelope (AGL-2942): the reservation the ladder
|
|
273
|
+
// took, with what the inline step spent.
|
|
274
|
+
meter: aiUsageMeter(gate.reservation, {
|
|
275
|
+
lastCredits: run.job.creditsSpent > 0 ? run.job.creditsSpent : null
|
|
276
|
+
})
|
|
277
|
+
}, {
|
|
278
|
+
status: 200
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
export async function GET(request) {
|
|
282
|
+
var _url_searchParams_get, _url_searchParams_get1, _url_searchParams_get2;
|
|
283
|
+
const url = new URL(request.url);
|
|
284
|
+
const gate = await aiJobsGate(request, (_url_searchParams_get = url.searchParams.get('orgId')) != null ? _url_searchParams_get : '');
|
|
285
|
+
if (gate instanceof Response) return gate;
|
|
286
|
+
const rawStatus = (_url_searchParams_get1 = url.searchParams.get('status')) != null ? _url_searchParams_get1 : '';
|
|
287
|
+
const status = AI_JOB_STATUSES.includes(rawStatus) ? rawStatus : undefined;
|
|
288
|
+
const limit = Number((_url_searchParams_get2 = url.searchParams.get('limit')) != null ? _url_searchParams_get2 : '');
|
|
289
|
+
const now = new Date();
|
|
290
|
+
const jobs = await listAiJobs(gate.firestore, gate.orgId, _extends({}, status ? {
|
|
291
|
+
status
|
|
292
|
+
} : {}, Number.isFinite(limit) && limit > 0 ? {
|
|
293
|
+
limit
|
|
294
|
+
} : {}));
|
|
295
|
+
return Response.json({
|
|
296
|
+
jobs: jobs.map((job)=>aiJobSummary(job, now))
|
|
297
|
+
}, {
|
|
298
|
+
status: 200,
|
|
299
|
+
headers: {
|
|
300
|
+
'Cache-Control': 'no-store'
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
export const dynamic = 'force-dynamic';
|
|
305
|
+
export const maxDuration = 60;
|
|
306
|
+
|
|
307
|
+
//# sourceMappingURL=ai-jobs-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/server/ai-jobs-route.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\n// lockdown-423: via libs/plugins/ai/src/lib/runtime/ai-gate.ts\n// The POST climbs `aiGateLadder`, whose lockdown rung is the verdict; the\n// GET climbs `ai-jobs-gate.ts`, which carries the same rung.\n\nimport { randomUUID } from 'crypto'\nimport {\n AI_JOB_KINDS,\n type AiJobKind,\n type AiJobStatus,\n} from '../model/ai-jobs.types'\n// By their own entry points rather than the barrel (AGL-2903): the specs\n// stub the barrel closed-world, and the ladder, the machine and the runtime\n// are the things under test here, not things to be stubbed away.\nimport { aiGateLadder } from '../runtime/ai-gate'\nimport { aiJobAdmissionRefusal, aiJobSiteRefusal } from '../jobs/ai-job-admission'\nimport { AI_JOB_BRIEF_MAX_CHARS } from '../jobs/ai-job-text-step'\nimport {\n AI_JOB_INLINE_BUDGET_MS,\n aiJobNextStepMinimumMs,\n aiJobSummary,\n createAiJob,\n listAiJobs,\n runAiJobStep,\n} from '../jobs/ai-jobs'\nimport { releaseAssistMessage } from '../usage/assist-usage'\nimport { aiUsageMeter } from '../usage/ai-usage-meter'\nimport { aiJobsGate } from './ai-jobs-gate'\n\n/**\n * AI generation jobs: create and list (AGL-2904).\n *\n * `POST` is a door that spends, so it climbs the whole ladder (AGL-2903) —\n * `aiGenerative`, `release_ai_generative`, the `ai-generate` switch, a\n * per-uid window, and a reservation — and then creates the job and runs\n * its first step INLINE under `AI_JOB_INLINE_BUDGET_MS`. A step that\n * finishes in time answers with the job `done` (or `queued` behind its\n * next step); one that does not is aborted, its reservation handed back,\n * and the job answers `queued` for the beat to resume. Either way the\n * caller gets the job document, and the events route is how it watches\n * from there.\n *\n * `GET` lists the org's jobs, newest first, through the read gate: the\n * same rungs up to the lockdown verdict, no reservation.\n *\n * The request must NAME the org it is metered against (AGL-1934). There\n * is no fallback to \"the caller's first org\".\n */\n\nconst AI_JOBS_RATE_LIMIT = { key: 'ai-jobs', limit: 10, windowMs: 60_000 }\n\n/** Kind-specific inputs, bounded: a runner reads scalars, not a document. */\nconst MAX_INPUTS_JSON_CHARS = 8_000\n\n/** The admitted statuses for the list filter, as the union spells them. */\nconst AI_JOB_STATUSES: readonly AiJobStatus[] = [\n 'queued',\n 'running',\n 'needs_input',\n 'needs_review',\n 'done',\n 'failed',\n 'canceled',\n]\n\nexport interface CreateAiJobBody {\n orgId: string\n hostId: string | null\n kind: AiJobKind\n brief: string\n inputs: Record<string, string | number | boolean>\n /** A catalog model the creator picked (AGL-2942), or `null` for Auto. */\n model: string | null\n}\n\nconst ID_CHARS = /^[A-Za-z0-9_-]{1,100}$/\n\n/** The longest model id a body may carry; the catalog's ids are far shorter. */\nconst MAX_MODEL_CHARS = 100\n\n/** Validate + clamp the request body; a string names what is wrong. */\nexport function parseCreateAiJobBody(payload: unknown): CreateAiJobBody | string {\n const body = (payload ?? {}) as Record<string, unknown>\n const orgId = String(body.orgId ?? '').trim()\n if (!orgId) return 'Open a workspace before using this feature'\n const kind = String(body.kind ?? '')\n if (!(AI_JOB_KINDS as readonly string[]).includes(kind)) {\n return `kind must be one of ${AI_JOB_KINDS.join(', ')}`\n }\n const brief = String(body.brief ?? '').trim()\n if (!brief) return 'Write a brief for the job'\n if (brief.length > AI_JOB_BRIEF_MAX_CHARS) {\n return `Keep the brief under ${AI_JOB_BRIEF_MAX_CHARS.toLocaleString('en-US')} characters`\n }\n const rawHost = body.hostId\n const hostId =\n rawHost === undefined || rawHost === null || rawHost === ''\n ? null\n : typeof rawHost === 'string' && ID_CHARS.test(rawHost)\n ? rawHost\n : undefined\n if (hostId === undefined) return 'hostId is not a site id'\n // A theme is fields on one site's document, so a theme job that names no\n // site has nothing to propose a change to (AGL-2938).\n if (kind === 'theme' && !hostId) return 'Open a site before changing its theme'\n const rawInputs = body.inputs\n const inputs: Record<string, string | number | boolean> = {}\n if (rawInputs !== undefined && rawInputs !== null) {\n if (typeof rawInputs !== 'object' || Array.isArray(rawInputs)) {\n return 'inputs must be an object'\n }\n for (const [key, value] of Object.entries(rawInputs as Record<string, unknown>)) {\n if (\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n return `inputs.${key} must be a string, number or boolean`\n }\n inputs[key] = value\n }\n if (JSON.stringify(inputs).length > MAX_INPUTS_JSON_CHARS) {\n return 'inputs are too large'\n }\n }\n const rawModel = typeof body.model === 'string' ? body.model.trim() : ''\n if (rawModel.length > MAX_MODEL_CHARS) return 'model is not a model id'\n // Validated against the plan and the allotment allowlists when each step\n // runs, not here: the allowlists are read inside the step's reservation.\n const model = rawModel && rawModel !== 'auto' ? rawModel : null\n return { orgId, hostId, kind: kind as AiJobKind, brief, inputs, model }\n}\n\nexport async function POST(request: Request): Promise<Response> {\n let payload: unknown\n try {\n payload = await request.json()\n } catch {\n payload = null\n }\n const parsed = parseCreateAiJobBody(payload)\n // The org is parsed BEFORE the ladder so a request that named none is\n // refused with the ladder's 400 rather than a shape error; every other\n // shape fault waits until the caller has proven who they are.\n const orgId = typeof parsed === 'string' ? String((payload as Record<string, unknown> | null)?.orgId ?? '') : parsed.orgId\n // The site rides along for the same reason: a collaborator's `ai.generate`\n // is decided per site (AGL-2927), so the ladder needs it before it can say\n // whether this member may generate here at all.\n const hostId = typeof parsed === 'string' ? null : parsed.hostId\n const gate = await aiGateLadder(\n { request, orgId, hostId },\n {\n feature: 'aiGenerative',\n releaseFlag: 'release_ai_generative',\n lockdownFeature: 'ai-generate',\n permission: 'ai.generate',\n rateLimit: AI_JOBS_RATE_LIMIT,\n },\n )\n if (gate instanceof Response) return gate\n if (typeof parsed === 'string') {\n // Admitted, reserved, and then found to have sent nothing runnable: the\n // reservation goes back, because no token was spent.\n await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(\n () => undefined,\n )\n return Response.json({ error: parsed }, { status: 400 })\n }\n // What only this kind can say about the request (AGL-2909): a site it\n // needs, inputs it reads, an allowance its draft counts against. Asked\n // before the job exists, so a refusal spends nothing.\n let refusal: Awaited<ReturnType<typeof aiJobAdmissionRefusal>>\n try {\n // A site that switched AI off first (AGL-3028), then the kind's own check.\n refusal =\n (await aiJobSiteRefusal({\n firestore: gate.firestore,\n org: gate.org,\n hostId: parsed.hostId,\n })) ??\n (await aiJobAdmissionRefusal(parsed.kind, {\n firestore: gate.firestore,\n orgId: gate.orgId,\n hostId: parsed.hostId,\n inputs: parsed.inputs,\n org: gate.org,\n uid: gate.uid,\n }))\n } catch (error) {\n await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(\n () => undefined,\n )\n console.error('ai job admission failed', { orgId: gate.orgId, kind: parsed.kind, error })\n return Response.json({ error: 'The AI job could not be created' }, { status: 500 })\n }\n if (refusal) {\n await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(\n () => undefined,\n )\n return Response.json({ error: refusal.error }, { status: refusal.status })\n }\n\n const now = new Date()\n let created: Awaited<ReturnType<typeof createAiJob>>\n try {\n created = await createAiJob(\n gate.firestore,\n {\n orgId: gate.orgId,\n hostId: parsed.hostId,\n kind: parsed.kind,\n brief: parsed.brief,\n inputs: parsed.inputs,\n model: parsed.model,\n createdBy: gate.uid,\n createdByEmail: gate.decoded.email ?? null,\n },\n now,\n )\n } catch (error) {\n await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(\n () => undefined,\n )\n console.error('ai job create failed', { orgId: gate.orgId, error })\n return Response.json({ error: 'The AI job could not be created' }, { status: 500 })\n }\n const jobId = created.$id\n\n // A first step that needs more time than this request has (AGL-2907) is left\n // queued for the beat, which starts it with a budget of its own: a provider\n // call this request's timeout cut off would be billed upstream and metered\n // nowhere. Nothing ran, so the reservation goes back.\n if (aiJobNextStepMinimumMs(created) > AI_JOB_INLINE_BUDGET_MS) {\n await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(\n () => undefined,\n )\n return Response.json(\n {\n job: aiJobSummary(created, now),\n meter: aiUsageMeter(gate.reservation, { lastCredits: null }),\n },\n { status: 200 },\n )\n }\n\n // The first step, inline, on the reservation the ladder already holds.\n // The runner hands that reservation back itself if the provider is never\n // reached, and re-queues the step when the budget ends first.\n const run = await runAiJobStep(gate.firestore, gate.orgId, jobId, {\n owner: `route:${randomUUID()}`,\n now,\n reservation: gate.reservation,\n org: gate.org,\n signal: AbortSignal.timeout(AI_JOB_INLINE_BUDGET_MS),\n // The caller is on the request, so what the inline step produces is\n // attributed with their address; the beat's steps carry the uid alone.\n actor: { uid: gate.uid, email: gate.decoded.email ?? null },\n // The workspace's AI pause lets staff through, as the ladder above did.\n staff: gate.staff,\n })\n if (run.outcome === 'not-claimable') {\n // A job created a moment ago has a claimable first step; anything else\n // is a fault in the machine, and the reservation must not be stranded.\n await releaseAssistMessage(gate.firestore, gate.orgId, gate.reservation).catch(\n () => undefined,\n )\n console.error('ai job first step not claimable', { orgId: gate.orgId, jobId })\n return Response.json({ error: 'The AI job could not be started' }, { status: 500 })\n }\n return Response.json(\n {\n job: aiJobSummary(run.job),\n // The usage strip's envelope (AGL-2942): the reservation the ladder\n // took, with what the inline step spent.\n meter: aiUsageMeter(gate.reservation, {\n lastCredits: run.job.creditsSpent > 0 ? run.job.creditsSpent : null,\n }),\n },\n { status: 200 },\n )\n}\n\nexport async function GET(request: Request): Promise<Response> {\n const url = new URL(request.url)\n const gate = await aiJobsGate(request, url.searchParams.get('orgId') ?? '')\n if (gate instanceof Response) return gate\n const rawStatus = url.searchParams.get('status') ?? ''\n const status = (AI_JOB_STATUSES as readonly string[]).includes(rawStatus)\n ? (rawStatus as AiJobStatus)\n : undefined\n const limit = Number(url.searchParams.get('limit') ?? '')\n const now = new Date()\n const jobs = await listAiJobs(gate.firestore, gate.orgId, {\n ...(status ? { status } : {}),\n ...(Number.isFinite(limit) && limit > 0 ? { limit } : {}),\n })\n return Response.json(\n { jobs: jobs.map((job) => aiJobSummary(job, now)) },\n { status: 200, headers: { 'Cache-Control': 'no-store' } },\n )\n}\n\nexport const dynamic = 'force-dynamic'\nexport const maxDuration = 60\n"],"names":["randomUUID","AI_JOB_KINDS","aiGateLadder","aiJobAdmissionRefusal","aiJobSiteRefusal","AI_JOB_BRIEF_MAX_CHARS","AI_JOB_INLINE_BUDGET_MS","aiJobNextStepMinimumMs","aiJobSummary","createAiJob","listAiJobs","runAiJobStep","releaseAssistMessage","aiUsageMeter","aiJobsGate","AI_JOBS_RATE_LIMIT","key","limit","windowMs","MAX_INPUTS_JSON_CHARS","AI_JOB_STATUSES","ID_CHARS","MAX_MODEL_CHARS","parseCreateAiJobBody","payload","body","orgId","String","trim","kind","includes","join","brief","length","toLocaleString","rawHost","hostId","undefined","test","rawInputs","inputs","Array","isArray","value","Object","entries","JSON","stringify","rawModel","model","POST","request","gate","json","parsed","feature","releaseFlag","lockdownFeature","permission","rateLimit","Response","firestore","reservation","catch","error","status","refusal","org","uid","console","now","Date","created","createdBy","createdByEmail","decoded","email","jobId","$id","job","meter","lastCredits","run","owner","signal","AbortSignal","timeout","actor","staff","outcome","creditsSpent","GET","url","URL","searchParams","get","rawStatus","Number","jobs","isFinite","map","headers","dynamic","maxDuration"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
declare function handler(request: Request): Promise<Response>;
|
|
18
|
+
export { handler as GET };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { pluginRequestFromWeb } from "@aglyn/aglyn/server";
|
|
17
|
+
import { resolveEffectivePlan } from "@aglyn/aglyn/app-utils/plan-entitlements";
|
|
18
|
+
import { permissionRefusal, emailUnverifiedResponse, firebaseAdmin, isImpersonationSession, memberHasPermissionOnHost, resolveOrgMembership } from "@aglyn/tenant-data-admin";
|
|
19
|
+
import { invalidIdTokenResponse } from "@aglyn/tenant-data-admin/server/id-token-refusal";
|
|
20
|
+
import { aiUsageMonthKeys } from "../model/ai-usage-by-user.js";
|
|
21
|
+
import { AI_STEP_TIERS } from "../providers/catalog.js";
|
|
22
|
+
import { aiModelOptions } from "../providers/model-choice.js";
|
|
23
|
+
import { aiProviderReady } from "../runtime/ai-runtime.js";
|
|
24
|
+
import { readAiAllotmentGate } from "../usage/ai-allotments.js";
|
|
25
|
+
import { readMeasuredStepUsage } from "../usage/ai-model-sample.js";
|
|
26
|
+
// lockdown-423: exempt — a READ-ONLY listing of what the model switch
|
|
27
|
+
// offers; it spends nothing and writes nothing, and every door the pick is
|
|
28
|
+
// then sent to carries its own lockdown rung.
|
|
29
|
+
/**
|
|
30
|
+
* THE MODEL SWITCH'S OPTIONS (AGL-2942): `GET ?orgId=&hostId=&kind=`.
|
|
31
|
+
*
|
|
32
|
+
* What the selector in the panel and the generation dialogs lists for one
|
|
33
|
+
* step kind: Auto — labeled with the model the routing table sends that kind
|
|
34
|
+
* to under the caller's bounds — and the models a manual pick may name, each
|
|
35
|
+
* with its credits per typical request and its multiple of Auto.
|
|
36
|
+
*
|
|
37
|
+
* Read when the switch is OPENED, never on a panel's mount, and bounded to
|
|
38
|
+
* the reads the answer needs: the org's plan (the membership read already
|
|
39
|
+
* returns the org), the allotment allowlists that apply to the caller on the
|
|
40
|
+
* site, and a bounded page of the workspace's own signals for the measured
|
|
41
|
+
* median. The door the pick is sent to decides again, inside its own
|
|
42
|
+
* reservation, so this list is a courtesy the server does not trust.
|
|
43
|
+
*
|
|
44
|
+
* Gated on `ai.use` on the caller's axis — the switch is part of using AI.
|
|
45
|
+
*/ const json = (body, status)=>Response.json(body, {
|
|
46
|
+
status
|
|
47
|
+
});
|
|
48
|
+
const STEP_KINDS = Object.keys(AI_STEP_TIERS);
|
|
49
|
+
async function handler(request) {
|
|
50
|
+
var _headers_authorization, _params_orgId, _params_hostId, _params_kind;
|
|
51
|
+
const { method, query, headers: rawHeaders } = await pluginRequestFromWeb(request);
|
|
52
|
+
const headers = rawHeaders;
|
|
53
|
+
if (method !== 'GET') return json({
|
|
54
|
+
error: 'Method not allowed'
|
|
55
|
+
}, 405);
|
|
56
|
+
const authorization = (_headers_authorization = headers.authorization) != null ? _headers_authorization : '';
|
|
57
|
+
const idToken = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
|
|
58
|
+
if (!idToken) return json({
|
|
59
|
+
error: 'Unauthenticated'
|
|
60
|
+
}, 401);
|
|
61
|
+
const params = query != null ? query : {};
|
|
62
|
+
const orgId = String((_params_orgId = params['orgId']) != null ? _params_orgId : '').trim();
|
|
63
|
+
const hostId = String((_params_hostId = params['hostId']) != null ? _params_hostId : '').trim();
|
|
64
|
+
const kind = String((_params_kind = params['kind']) != null ? _params_kind : '');
|
|
65
|
+
if (!orgId) return json({
|
|
66
|
+
error: 'Missing orgId'
|
|
67
|
+
}, 400);
|
|
68
|
+
if (!STEP_KINDS.includes(kind)) {
|
|
69
|
+
return json({
|
|
70
|
+
error: `kind must be one of ${STEP_KINDS.join(', ')}`
|
|
71
|
+
}, 400);
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
var _orgSnapshot_data, _ref, _ref1, _ref2, _ref3, _ref4;
|
|
75
|
+
const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken);
|
|
76
|
+
if (!decoded.email_verified && !isImpersonationSession(decoded)) {
|
|
77
|
+
return emailUnverifiedResponse();
|
|
78
|
+
}
|
|
79
|
+
const staff = decoded['staff'] === true;
|
|
80
|
+
const membership = await resolveOrgMembership(decoded.uid, orgId);
|
|
81
|
+
if (!membership && !staff) return json({
|
|
82
|
+
error: 'Not found'
|
|
83
|
+
}, 404);
|
|
84
|
+
if (!staff && !await memberHasPermissionOnHost(orgId, hostId, membership == null ? void 0 : membership.member, 'ai.use')) {
|
|
85
|
+
return permissionRefusal('ai.use');
|
|
86
|
+
}
|
|
87
|
+
if (!aiProviderReady()) {
|
|
88
|
+
return json({
|
|
89
|
+
kind,
|
|
90
|
+
auto: null,
|
|
91
|
+
options: [],
|
|
92
|
+
measured: false
|
|
93
|
+
}, 200);
|
|
94
|
+
}
|
|
95
|
+
const firestore = firebaseAdmin.app().firestore();
|
|
96
|
+
const orgRef = firestore.collection('orgs').doc(orgId);
|
|
97
|
+
const month = aiUsageMonthKeys()[0];
|
|
98
|
+
const [orgSnapshot, gate, measured] = await Promise.all([
|
|
99
|
+
orgRef.get(),
|
|
100
|
+
readAiAllotmentGate((ref)=>ref.get(), orgRef, {
|
|
101
|
+
uid: decoded.uid,
|
|
102
|
+
hostId
|
|
103
|
+
}, month),
|
|
104
|
+
readMeasuredStepUsage(firestore, orgId, kind).catch(()=>null)
|
|
105
|
+
]);
|
|
106
|
+
const org = (_orgSnapshot_data = orgSnapshot.data()) != null ? _orgSnapshot_data : {};
|
|
107
|
+
const listed = aiModelOptions(kind, {
|
|
108
|
+
plan: resolveEffectivePlan(org),
|
|
109
|
+
allotmentModels: (_ref = gate == null ? void 0 : gate.models) != null ? _ref : null,
|
|
110
|
+
orgModels: (_ref1 = gate == null ? void 0 : gate.orgModels) != null ? _ref1 : null
|
|
111
|
+
}, measured);
|
|
112
|
+
return Response.json({
|
|
113
|
+
kind,
|
|
114
|
+
auto: (_ref2 = listed == null ? void 0 : listed.auto) != null ? _ref2 : null,
|
|
115
|
+
options: (_ref3 = listed == null ? void 0 : listed.options) != null ? _ref3 : [],
|
|
116
|
+
measured: (_ref4 = listed == null ? void 0 : listed.measured) != null ? _ref4 : false
|
|
117
|
+
}, {
|
|
118
|
+
status: 200,
|
|
119
|
+
headers: {
|
|
120
|
+
'Cache-Control': 'no-store, private'
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
} catch (error) {
|
|
124
|
+
const unauthenticated = invalidIdTokenResponse(error);
|
|
125
|
+
if (unauthenticated) return unauthenticated;
|
|
126
|
+
console.error('[ai/models] failed', orgId, error);
|
|
127
|
+
return json({
|
|
128
|
+
error: 'AI models unavailable'
|
|
129
|
+
}, 500);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export { handler as GET };
|
|
133
|
+
|
|
134
|
+
//# sourceMappingURL=ai-models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/server/ai-models.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 { pluginRequestFromWeb } from '@aglyn/aglyn/server'\nimport { resolveEffectivePlan } from '@aglyn/aglyn/app-utils/plan-entitlements'\nimport {\n permissionRefusal,\n emailUnverifiedResponse,\n firebaseAdmin,\n isImpersonationSession,\n memberHasPermissionOnHost,\n resolveOrgMembership,\n} from '@aglyn/tenant-data-admin'\nimport { invalidIdTokenResponse } from '@aglyn/tenant-data-admin/server/id-token-refusal'\nimport { aiUsageMonthKeys } from '../model/ai-usage-by-user'\nimport { AI_STEP_TIERS, type AiStepKind } from '../providers/catalog'\nimport { aiModelOptions } from '../providers/model-choice'\nimport { aiProviderReady } from '../runtime/ai-runtime'\nimport { readAiAllotmentGate } from '../usage/ai-allotments'\nimport { readMeasuredStepUsage } from '../usage/ai-model-sample'\n\n// lockdown-423: exempt — a READ-ONLY listing of what the model switch\n// offers; it spends nothing and writes nothing, and every door the pick is\n// then sent to carries its own lockdown rung.\n\n/**\n * THE MODEL SWITCH'S OPTIONS (AGL-2942): `GET ?orgId=&hostId=&kind=`.\n *\n * What the selector in the panel and the generation dialogs lists for one\n * step kind: Auto — labeled with the model the routing table sends that kind\n * to under the caller's bounds — and the models a manual pick may name, each\n * with its credits per typical request and its multiple of Auto.\n *\n * Read when the switch is OPENED, never on a panel's mount, and bounded to\n * the reads the answer needs: the org's plan (the membership read already\n * returns the org), the allotment allowlists that apply to the caller on the\n * site, and a bounded page of the workspace's own signals for the measured\n * median. The door the pick is sent to decides again, inside its own\n * reservation, so this list is a courtesy the server does not trust.\n *\n * Gated on `ai.use` on the caller's axis — the switch is part of using AI.\n */\n\nconst json = (body: unknown, status: number) => Response.json(body, { status })\n\nconst STEP_KINDS = Object.keys(AI_STEP_TIERS) as AiStepKind[]\n\nasync function handler(request: Request): Promise<Response> {\n const { method, query, headers: rawHeaders } = await pluginRequestFromWeb(request)\n const headers = rawHeaders as Partial<Record<string, string>>\n if (method !== 'GET') return json({ error: 'Method not allowed' }, 405)\n const authorization = headers.authorization ?? ''\n const idToken = authorization.startsWith('Bearer ')\n ? authorization.slice('Bearer '.length)\n : undefined\n if (!idToken) return json({ error: 'Unauthenticated' }, 401)\n const params = (query ?? {}) as Record<string, unknown>\n const orgId = String(params['orgId'] ?? '').trim()\n const hostId = String(params['hostId'] ?? '').trim()\n const kind = String(params['kind'] ?? '') as AiStepKind\n if (!orgId) return json({ error: 'Missing orgId' }, 400)\n if (!STEP_KINDS.includes(kind)) {\n return json({ error: `kind must be one of ${STEP_KINDS.join(', ')}` }, 400)\n }\n\n try {\n const decoded = await firebaseAdmin.app().auth().verifyIdToken(idToken)\n if (!decoded.email_verified && !isImpersonationSession(decoded)) {\n return emailUnverifiedResponse()\n }\n const staff = decoded['staff'] === true\n const membership = await resolveOrgMembership(decoded.uid, orgId)\n if (!membership && !staff) return json({ error: 'Not found' }, 404)\n if (\n !staff &&\n !(await memberHasPermissionOnHost(orgId, hostId, membership?.member, 'ai.use'))\n ) {\n return permissionRefusal('ai.use')\n }\n if (!aiProviderReady()) {\n return json({ kind, auto: null, options: [], measured: false }, 200)\n }\n\n const firestore = firebaseAdmin.app().firestore()\n const orgRef = firestore.collection('orgs').doc(orgId)\n const month = aiUsageMonthKeys()[0]\n const [orgSnapshot, gate, measured] = await Promise.all([\n orgRef.get(),\n readAiAllotmentGate((ref) => ref.get(), orgRef, { uid: decoded.uid, hostId }, month),\n readMeasuredStepUsage(firestore, orgId, kind).catch(() => null),\n ])\n const org = (orgSnapshot.data() ?? {}) as Record<string, unknown>\n const listed = aiModelOptions(\n kind,\n {\n plan: resolveEffectivePlan(org as never),\n allotmentModels: gate?.models ?? null,\n orgModels: gate?.orgModels ?? null,\n },\n measured,\n )\n return Response.json(\n {\n kind,\n auto: listed?.auto ?? null,\n options: listed?.options ?? [],\n measured: listed?.measured ?? false,\n },\n { status: 200, headers: { 'Cache-Control': 'no-store, private' } },\n )\n } catch (error) {\n const unauthenticated = invalidIdTokenResponse(error)\n if (unauthenticated) return unauthenticated\n console.error('[ai/models] failed', orgId, error)\n return json({ error: 'AI models unavailable' }, 500)\n }\n}\n\nexport { handler as GET }\n"],"names":["pluginRequestFromWeb","resolveEffectivePlan","permissionRefusal","emailUnverifiedResponse","firebaseAdmin","isImpersonationSession","memberHasPermissionOnHost","resolveOrgMembership","invalidIdTokenResponse","aiUsageMonthKeys","AI_STEP_TIERS","aiModelOptions","aiProviderReady","readAiAllotmentGate","readMeasuredStepUsage","json","body","status","Response","STEP_KINDS","Object","keys","handler","request","headers","params","method","query","rawHeaders","error","authorization","idToken","startsWith","slice","length","undefined","orgId","String","trim","hostId","kind","includes","join","orgSnapshot","decoded","app","auth","verifyIdToken","email_verified","staff","membership","uid","member","auto","options","measured","firestore","orgRef","collection","doc","month","gate","Promise","all","get","ref","catch","org","data","listed","plan","allotmentModels","models","orgModels","unauthenticated","console","GET"],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { AiJob } from '../model/ai-jobs.types';
|
|
18
|
+
import { type AiSeoAuditView } from '../model/ai-seo';
|
|
19
|
+
/** The version history sentence the versions route gives, for a plan without it. */
|
|
20
|
+
export declare const AI_SEO_APPLY_VERSIONING_COPY = "Version history requires a Pro plan \u2014 see Billing to upgrade";
|
|
21
|
+
export interface AiSeoApplyInput {
|
|
22
|
+
orgId: string;
|
|
23
|
+
hostId: string;
|
|
24
|
+
job: AiJob;
|
|
25
|
+
view: AiSeoAuditView;
|
|
26
|
+
uid: string;
|
|
27
|
+
/** Whether the org's plan keeps more than one version of a page. */
|
|
28
|
+
versioning: boolean;
|
|
29
|
+
now?: Date;
|
|
30
|
+
}
|
|
31
|
+
export interface AiSeoApplyResult {
|
|
32
|
+
job: AiJob;
|
|
33
|
+
/** The version each page's content fixes went into; `fixes` is 0 for one opened by an earlier apply. */
|
|
34
|
+
versions: Array<{
|
|
35
|
+
screenId: string;
|
|
36
|
+
versionId: string;
|
|
37
|
+
name: string;
|
|
38
|
+
fixes: number;
|
|
39
|
+
}>;
|
|
40
|
+
/** Pages whose listing values wait in their SEO card. */
|
|
41
|
+
staged: string[];
|
|
42
|
+
skipped: Array<{
|
|
43
|
+
screenId: string;
|
|
44
|
+
reason: string;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Open the versions and record the apply. Exported for the spec, which drives
|
|
49
|
+
* it against a Firestore double and proves what it leaves alone.
|
|
50
|
+
*/
|
|
51
|
+
export declare function applyAiSeoAudit(firestore: FirebaseFirestore.Firestore, input: AiSeoApplyInput): Promise<AiSeoApplyResult>;
|
|
52
|
+
export declare function POST(request: Request): Promise<Response>;
|
|
53
|
+
export declare const dynamic = "force-dynamic";
|