@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,176 @@
|
|
|
1
|
+
'use client';
|
|
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 { lockdownRefusalText, parseLockdownRefusal } from "@aglyn/aglyn";
|
|
18
|
+
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
19
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
20
|
+
import { AI_JOB_TERMINAL_STATUSES } from "../model/ai-jobs.types.js";
|
|
21
|
+
import { readEventFrames } from "./assist-jobs-drawer.component.js";
|
|
22
|
+
/**
|
|
23
|
+
* One answer per member and workspace, however many controls ask. The
|
|
24
|
+
* automation run history draws a control on every failed run, and each asking
|
|
25
|
+
* the route would be a request a row.
|
|
26
|
+
*/ const verdicts = new Map();
|
|
27
|
+
/** Forgets every answer, so the next control to mount asks the route again. */ export function forgetAiJobsVerdicts() {
|
|
28
|
+
verdicts.clear();
|
|
29
|
+
}
|
|
30
|
+
function askJobsRoute(user, uid, orgId) {
|
|
31
|
+
const key = `${uid}\n${orgId}`;
|
|
32
|
+
const known = verdicts.get(key);
|
|
33
|
+
if (known) return known;
|
|
34
|
+
const answer = authorizedFetch(user, `/api/ai/jobs?orgId=${encodeURIComponent(orgId)}&limit=1`)// The release flag off (404) and a plan or member without generation
|
|
35
|
+
// (403): the feature is not this workspace's, so the control is absent.
|
|
36
|
+
.then((response)=>response.status === 404 || response.status === 403 ? 'hidden' : 'ready').catch(()=>{
|
|
37
|
+
// A request that never arrived is no answer, so the next control asks again.
|
|
38
|
+
verdicts.delete(key);
|
|
39
|
+
return 'hidden';
|
|
40
|
+
});
|
|
41
|
+
verdicts.set(key, answer);
|
|
42
|
+
return answer;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Whether a control that starts a job should be drawn. The shell decided the
|
|
46
|
+
* plan and the member's permission before mounting it; the release flag is the
|
|
47
|
+
* route's to decide.
|
|
48
|
+
*/ export function useAiJobsVerdict(user, orgId) {
|
|
49
|
+
var _ref;
|
|
50
|
+
// Held in a ref so the question keys on WHO is signed in, never on the
|
|
51
|
+
// identity of the object that says so.
|
|
52
|
+
const userRef = useRef(user);
|
|
53
|
+
userRef.current = user;
|
|
54
|
+
const uid = (_ref = user == null ? void 0 : user.uid) != null ? _ref : null;
|
|
55
|
+
const [verdict, setVerdict] = useState('checking');
|
|
56
|
+
useEffect(()=>{
|
|
57
|
+
if (!orgId || !uid) return;
|
|
58
|
+
let active = true;
|
|
59
|
+
setVerdict('checking');
|
|
60
|
+
void askJobsRoute(userRef.current, uid, orgId).then((answer)=>{
|
|
61
|
+
if (active) setVerdict(answer);
|
|
62
|
+
});
|
|
63
|
+
return ()=>{
|
|
64
|
+
active = false;
|
|
65
|
+
};
|
|
66
|
+
}, [
|
|
67
|
+
orgId,
|
|
68
|
+
uid
|
|
69
|
+
]);
|
|
70
|
+
return verdict;
|
|
71
|
+
}
|
|
72
|
+
/** Whether a job has stopped moving: finished, or waiting on something only a person can change. */ export function aiJobSettled(job) {
|
|
73
|
+
if (!job) return false;
|
|
74
|
+
return AI_JOB_TERMINAL_STATUSES.includes(job.status) || job.status === 'needs_input' || job.status === 'needs_review';
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Why a settled job has no result to show, in words a person can act on, or
|
|
78
|
+
* `null` for a job that finished.
|
|
79
|
+
*/ export function aiJobProblem(job, failed) {
|
|
80
|
+
var _job_review;
|
|
81
|
+
if (!job || !aiJobSettled(job) || job.status === 'done') return null;
|
|
82
|
+
if (job.status === 'canceled') return 'The job was canceled.';
|
|
83
|
+
if (job.status === 'needs_review') return ((_job_review = job.review) == null ? void 0 : _job_review.message) || job.error || failed;
|
|
84
|
+
return job.error || failed;
|
|
85
|
+
}
|
|
86
|
+
export function useAiJobRun(user, failed) {
|
|
87
|
+
const userRef = useRef(user);
|
|
88
|
+
userRef.current = user;
|
|
89
|
+
const [job, setJob] = useState(null);
|
|
90
|
+
const [starting, setStarting] = useState(false);
|
|
91
|
+
const [notice, setNotice] = useState(null);
|
|
92
|
+
const watchRef = useRef(null);
|
|
93
|
+
useEffect(()=>()=>{
|
|
94
|
+
var _watchRef_current;
|
|
95
|
+
return (_watchRef_current = watchRef.current) == null ? void 0 : _watchRef_current.abort();
|
|
96
|
+
}, []);
|
|
97
|
+
/** Follows a job through the events route until it settles or the control goes. */ const watch = useCallback(async (jobId, orgId)=>{
|
|
98
|
+
var _watchRef_current;
|
|
99
|
+
(_watchRef_current = watchRef.current) == null ? void 0 : _watchRef_current.abort();
|
|
100
|
+
const controller = new AbortController();
|
|
101
|
+
watchRef.current = controller;
|
|
102
|
+
let again = true;
|
|
103
|
+
while(again && !controller.signal.aborted){
|
|
104
|
+
again = false;
|
|
105
|
+
try {
|
|
106
|
+
const response = await authorizedFetch(userRef.current, `/api/ai/jobs/${encodeURIComponent(jobId)}/events?orgId=${encodeURIComponent(orgId)}`, {
|
|
107
|
+
signal: controller.signal
|
|
108
|
+
});
|
|
109
|
+
if (!response.ok || !response.body) return;
|
|
110
|
+
await readEventFrames(response.body, (event)=>{
|
|
111
|
+
if (controller.signal.aborted) return;
|
|
112
|
+
if (event['type'] === 'state') setJob(event['job']);
|
|
113
|
+
else if (event['type'] === 'reconnect') again = true;
|
|
114
|
+
});
|
|
115
|
+
} catch (unused) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}, []);
|
|
120
|
+
const start = useCallback(async (request)=>{
|
|
121
|
+
var _watchRef_current;
|
|
122
|
+
(_watchRef_current = watchRef.current) == null ? void 0 : _watchRef_current.abort();
|
|
123
|
+
setStarting(true);
|
|
124
|
+
setNotice(null);
|
|
125
|
+
setJob(null);
|
|
126
|
+
let next;
|
|
127
|
+
try {
|
|
128
|
+
const response = await authorizedFetch(userRef.current, '/api/ai/jobs', {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: {
|
|
131
|
+
'Content-Type': 'application/json'
|
|
132
|
+
},
|
|
133
|
+
body: JSON.stringify(request)
|
|
134
|
+
});
|
|
135
|
+
const payload = await response.json().catch(()=>null);
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
var _ref;
|
|
138
|
+
const locked = parseLockdownRefusal(response.status, payload);
|
|
139
|
+
setNotice(locked ? lockdownRefusalText(locked) : String((_ref = payload == null ? void 0 : payload.error) != null ? _ref : failed));
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
next = payload == null ? void 0 : payload.job;
|
|
143
|
+
if (!next) {
|
|
144
|
+
setNotice(failed);
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
setJob(next);
|
|
148
|
+
} catch (unused) {
|
|
149
|
+
setNotice(failed);
|
|
150
|
+
return false;
|
|
151
|
+
} finally{
|
|
152
|
+
setStarting(false);
|
|
153
|
+
}
|
|
154
|
+
if (!aiJobSettled(next)) void watch(next.id, request.orgId);
|
|
155
|
+
return true;
|
|
156
|
+
}, [
|
|
157
|
+
failed,
|
|
158
|
+
watch
|
|
159
|
+
]);
|
|
160
|
+
const reset = useCallback(()=>{
|
|
161
|
+
var _watchRef_current;
|
|
162
|
+
(_watchRef_current = watchRef.current) == null ? void 0 : _watchRef_current.abort();
|
|
163
|
+
setJob(null);
|
|
164
|
+
setNotice(null);
|
|
165
|
+
}, []);
|
|
166
|
+
return {
|
|
167
|
+
job,
|
|
168
|
+
starting,
|
|
169
|
+
running: Boolean(job && !aiJobSettled(job)),
|
|
170
|
+
notice,
|
|
171
|
+
start,
|
|
172
|
+
reset
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
//# sourceMappingURL=use-ai-job-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/use-ai-job-run.ts"],"sourcesContent":["'use client'\n\n/**\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 { lockdownRefusalText, parseLockdownRefusal } from '@aglyn/aglyn'\nimport {\n authorizedFetch,\n type MaybeTokenSource,\n type TokenSource,\n} from '@aglyn/shared-util-http/authorized-token'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n AI_JOB_TERMINAL_STATUSES,\n type AiJobKind,\n type AiJobSummary,\n} from '../model/ai-jobs.types'\nimport { readEventFrames } from './assist-jobs-drawer.component'\n\n/**\n * Starting one AI job from a console control, and following it until it\n * settles (AGL-2919): the jobs route's create door, then its events door, the\n * way the SEO card follows its jobs. A control that starts a job the beat\n * runs shows its progress here and its result when it arrives; closing the\n * control stops following, and the job carries on in AI jobs.\n */\n\n/** Whether the jobs route serves a workspace: still asking, yes, or no. */\nexport type AiJobsVerdict = 'checking' | 'ready' | 'hidden'\n\n/**\n * One answer per member and workspace, however many controls ask. The\n * automation run history draws a control on every failed run, and each asking\n * the route would be a request a row.\n */\nconst verdicts = new Map<string, Promise<Exclude<AiJobsVerdict, 'checking'>>>()\n\n/** Forgets every answer, so the next control to mount asks the route again. */\nexport function forgetAiJobsVerdicts(): void {\n verdicts.clear()\n}\n\nfunction askJobsRoute(\n user: MaybeTokenSource,\n uid: string,\n orgId: string,\n): Promise<Exclude<AiJobsVerdict, 'checking'>> {\n const key = `${uid}\\n${orgId}`\n const known = verdicts.get(key)\n if (known) return known\n const answer = authorizedFetch(user, `/api/ai/jobs?orgId=${encodeURIComponent(orgId)}&limit=1`)\n // The release flag off (404) and a plan or member without generation\n // (403): the feature is not this workspace's, so the control is absent.\n .then((response): Exclude<AiJobsVerdict, 'checking'> =>\n response.status === 404 || response.status === 403 ? 'hidden' : 'ready',\n )\n .catch((): Exclude<AiJobsVerdict, 'checking'> => {\n // A request that never arrived is no answer, so the next control asks again.\n verdicts.delete(key)\n return 'hidden'\n })\n verdicts.set(key, answer)\n return answer\n}\n\n/**\n * Whether a control that starts a job should be drawn. The shell decided the\n * plan and the member's permission before mounting it; the release flag is the\n * route's to decide.\n */\nexport function useAiJobsVerdict(\n user: (TokenSource & { uid?: string | null }) | null | undefined,\n orgId: string | undefined,\n): AiJobsVerdict {\n // Held in a ref so the question keys on WHO is signed in, never on the\n // identity of the object that says so.\n const userRef = useRef(user)\n userRef.current = user\n const uid = user?.uid ?? null\n const [verdict, setVerdict] = useState<AiJobsVerdict>('checking')\n\n useEffect(() => {\n if (!orgId || !uid) return\n let active = true\n setVerdict('checking')\n void askJobsRoute(userRef.current, uid, orgId).then((answer) => {\n if (active) setVerdict(answer)\n })\n return () => {\n active = false\n }\n }, [orgId, uid])\n\n return verdict\n}\n\n/** What a control asks the create door for. */\nexport interface AiJobRequest {\n orgId: string\n hostId: string\n kind: AiJobKind\n brief: string\n inputs: Record<string, string>\n}\n\n/** Whether a job has stopped moving: finished, or waiting on something only a person can change. */\nexport function aiJobSettled(job: AiJobSummary | null): boolean {\n if (!job) return false\n return (\n AI_JOB_TERMINAL_STATUSES.includes(job.status) ||\n job.status === 'needs_input' ||\n job.status === 'needs_review'\n )\n}\n\n/**\n * Why a settled job has no result to show, in words a person can act on, or\n * `null` for a job that finished.\n */\nexport function aiJobProblem(job: AiJobSummary | null, failed: string): string | null {\n if (!job || !aiJobSettled(job) || job.status === 'done') return null\n if (job.status === 'canceled') return 'The job was canceled.'\n if (job.status === 'needs_review') return job.review?.message || job.error || failed\n return job.error || failed\n}\n\nexport interface AiJobRun {\n /** The job as it last arrived; `null` before one is started. */\n job: AiJobSummary | null\n /** The create door is being asked. */\n starting: boolean\n /** The job exists and has not settled. */\n running: boolean\n /** Why the create door refused, or could not be reached. */\n notice: string | null\n /** Starts the job, `true` once it exists, and follows it from there; `false` when the door refused. */\n start: (request: AiJobRequest) => Promise<boolean>\n /** Stops following and forgets the job, for a control asked again. */\n reset: () => void\n}\n\nexport function useAiJobRun(user: MaybeTokenSource, failed: string): AiJobRun {\n const userRef = useRef(user)\n userRef.current = user\n const [job, setJob] = useState<AiJobSummary | null>(null)\n const [starting, setStarting] = useState(false)\n const [notice, setNotice] = useState<string | null>(null)\n const watchRef = useRef<AbortController | null>(null)\n\n useEffect(() => () => watchRef.current?.abort(), [])\n\n /** Follows a job through the events route until it settles or the control goes. */\n const watch = useCallback(async (jobId: string, orgId: string) => {\n watchRef.current?.abort()\n const controller = new AbortController()\n watchRef.current = controller\n let again = true\n while (again && !controller.signal.aborted) {\n again = false\n try {\n const response = await authorizedFetch(\n userRef.current,\n `/api/ai/jobs/${encodeURIComponent(jobId)}/events?orgId=${encodeURIComponent(orgId)}`,\n { signal: controller.signal },\n )\n if (!response.ok || !response.body) return\n await readEventFrames(response.body, (event) => {\n if (controller.signal.aborted) return\n if (event['type'] === 'state') setJob(event['job'] as AiJobSummary)\n else if (event['type'] === 'reconnect') again = true\n })\n } catch {\n return\n }\n }\n }, [])\n\n const start = useCallback(\n async (request: AiJobRequest) => {\n watchRef.current?.abort()\n setStarting(true)\n setNotice(null)\n setJob(null)\n let next: AiJobSummary | undefined\n try {\n const response = await authorizedFetch(userRef.current, '/api/ai/jobs', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n })\n const payload = await response.json().catch(() => null)\n if (!response.ok) {\n const locked = parseLockdownRefusal(response.status, payload)\n setNotice(locked ? lockdownRefusalText(locked) : String(payload?.error ?? failed))\n return false\n }\n next = payload?.job as AiJobSummary | undefined\n if (!next) {\n setNotice(failed)\n return false\n }\n setJob(next)\n } catch {\n setNotice(failed)\n return false\n } finally {\n setStarting(false)\n }\n if (!aiJobSettled(next)) void watch(next.id, request.orgId)\n return true\n },\n [failed, watch],\n )\n\n const reset = useCallback(() => {\n watchRef.current?.abort()\n setJob(null)\n setNotice(null)\n }, [])\n\n return { job, starting, running: Boolean(job && !aiJobSettled(job)), notice, start, reset }\n}\n"],"names":["lockdownRefusalText","parseLockdownRefusal","authorizedFetch","useCallback","useEffect","useRef","useState","AI_JOB_TERMINAL_STATUSES","readEventFrames","verdicts","Map","forgetAiJobsVerdicts","clear","askJobsRoute","user","uid","orgId","key","known","get","answer","encodeURIComponent","then","response","status","catch","delete","set","useAiJobsVerdict","userRef","current","verdict","setVerdict","active","aiJobSettled","job","includes","aiJobProblem","failed","review","message","error","useAiJobRun","setJob","starting","setStarting","notice","setNotice","watchRef","abort","watch","jobId","controller","AbortController","again","signal","aborted","ok","body","event","start","request","next","method","headers","JSON","stringify","payload","json","locked","String","id","reset","running","Boolean"],"mappings":"AAAA;AAEA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,mBAAmB,EAAEC,oBAAoB,QAAQ,eAAc;AACxE,SACEC,eAAe,QAGV,2CAA0C;AACjD,SAASC,WAAW,EAAEC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAChE,SACEC,wBAAwB,QAGnB,4BAAwB;AAC/B,SAASC,eAAe,QAAQ,oCAAgC;AAahE;;;;CAIC,GACD,MAAMC,WAAW,IAAIC;AAErB,6EAA6E,GAC7E,OAAO,SAASC;IACdF,SAASG,KAAK;AAChB;AAEA,SAASC,aACPC,IAAsB,EACtBC,GAAW,EACXC,KAAa;IAEb,MAAMC,MAAM,GAAGF,IAAI,EAAE,EAAEC,OAAO;IAC9B,MAAME,QAAQT,SAASU,GAAG,CAACF;IAC3B,IAAIC,OAAO,OAAOA;IAClB,MAAME,SAASlB,gBAAgBY,MAAM,CAAC,mBAAmB,EAAEO,mBAAmBL,OAAO,QAAQ,CAAC,CAC5F,qEAAqE;IACrE,wEAAwE;KACvEM,IAAI,CAAC,CAACC,WACLA,SAASC,MAAM,KAAK,OAAOD,SAASC,MAAM,KAAK,MAAM,WAAW,SAEjEC,KAAK,CAAC;QACL,6EAA6E;QAC7EhB,SAASiB,MAAM,CAACT;QAChB,OAAO;IACT;IACFR,SAASkB,GAAG,CAACV,KAAKG;IAClB,OAAOA;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASQ,iBACdd,IAAgE,EAChEE,KAAyB;;IAEzB,uEAAuE;IACvE,uCAAuC;IACvC,MAAMa,UAAUxB,OAAOS;IACvBe,QAAQC,OAAO,GAAGhB;IAClB,MAAMC,cAAMD,wBAAAA,KAAMC,GAAG,mBAAI;IACzB,MAAM,CAACgB,SAASC,WAAW,GAAG1B,SAAwB;IAEtDF,UAAU;QACR,IAAI,CAACY,SAAS,CAACD,KAAK;QACpB,IAAIkB,SAAS;QACbD,WAAW;QACX,KAAKnB,aAAagB,QAAQC,OAAO,EAAEf,KAAKC,OAAOM,IAAI,CAAC,CAACF;YACnD,IAAIa,QAAQD,WAAWZ;QACzB;QACA,OAAO;YACLa,SAAS;QACX;IACF,GAAG;QAACjB;QAAOD;KAAI;IAEf,OAAOgB;AACT;AAWA,kGAAkG,GAClG,OAAO,SAASG,aAAaC,GAAwB;IACnD,IAAI,CAACA,KAAK,OAAO;IACjB,OACE5B,yBAAyB6B,QAAQ,CAACD,IAAIX,MAAM,KAC5CW,IAAIX,MAAM,KAAK,iBACfW,IAAIX,MAAM,KAAK;AAEnB;AAEA;;;CAGC,GACD,OAAO,SAASa,aAAaF,GAAwB,EAAEG,MAAc;QAGzBH;IAF1C,IAAI,CAACA,OAAO,CAACD,aAAaC,QAAQA,IAAIX,MAAM,KAAK,QAAQ,OAAO;IAChE,IAAIW,IAAIX,MAAM,KAAK,YAAY,OAAO;IACtC,IAAIW,IAAIX,MAAM,KAAK,gBAAgB,OAAOW,EAAAA,cAAAA,IAAII,MAAM,qBAAVJ,YAAYK,OAAO,KAAIL,IAAIM,KAAK,IAAIH;IAC9E,OAAOH,IAAIM,KAAK,IAAIH;AACtB;AAiBA,OAAO,SAASI,YAAY5B,IAAsB,EAAEwB,MAAc;IAChE,MAAMT,UAAUxB,OAAOS;IACvBe,QAAQC,OAAO,GAAGhB;IAClB,MAAM,CAACqB,KAAKQ,OAAO,GAAGrC,SAA8B;IACpD,MAAM,CAACsC,UAAUC,YAAY,GAAGvC,SAAS;IACzC,MAAM,CAACwC,QAAQC,UAAU,GAAGzC,SAAwB;IACpD,MAAM0C,WAAW3C,OAA+B;IAEhDD,UAAU,IAAM;gBAAM4C;oBAAAA,oBAAAA,SAASlB,OAAO,qBAAhBkB,kBAAkBC,KAAK;WAAI,EAAE;IAEnD,iFAAiF,GACjF,MAAMC,QAAQ/C,YAAY,OAAOgD,OAAenC;YAC9CgC;SAAAA,oBAAAA,SAASlB,OAAO,qBAAhBkB,kBAAkBC,KAAK;QACvB,MAAMG,aAAa,IAAIC;QACvBL,SAASlB,OAAO,GAAGsB;QACnB,IAAIE,QAAQ;QACZ,MAAOA,SAAS,CAACF,WAAWG,MAAM,CAACC,OAAO,CAAE;YAC1CF,QAAQ;YACR,IAAI;gBACF,MAAM/B,WAAW,MAAMrB,gBACrB2B,QAAQC,OAAO,EACf,CAAC,aAAa,EAAET,mBAAmB8B,OAAO,cAAc,EAAE9B,mBAAmBL,QAAQ,EACrF;oBAAEuC,QAAQH,WAAWG,MAAM;gBAAC;gBAE9B,IAAI,CAAChC,SAASkC,EAAE,IAAI,CAAClC,SAASmC,IAAI,EAAE;gBACpC,MAAMlD,gBAAgBe,SAASmC,IAAI,EAAE,CAACC;oBACpC,IAAIP,WAAWG,MAAM,CAACC,OAAO,EAAE;oBAC/B,IAAIG,KAAK,CAAC,OAAO,KAAK,SAAShB,OAAOgB,KAAK,CAAC,MAAM;yBAC7C,IAAIA,KAAK,CAAC,OAAO,KAAK,aAAaL,QAAQ;gBAClD;YACF,EAAE,eAAM;gBACN;YACF;QACF;IACF,GAAG,EAAE;IAEL,MAAMM,QAAQzD,YACZ,OAAO0D;YACLb;SAAAA,oBAAAA,SAASlB,OAAO,qBAAhBkB,kBAAkBC,KAAK;QACvBJ,YAAY;QACZE,UAAU;QACVJ,OAAO;QACP,IAAImB;QACJ,IAAI;YACF,MAAMvC,WAAW,MAAMrB,gBAAgB2B,QAAQC,OAAO,EAAE,gBAAgB;gBACtEiC,QAAQ;gBACRC,SAAS;oBAAE,gBAAgB;gBAAmB;gBAC9CN,MAAMO,KAAKC,SAAS,CAACL;YACvB;YACA,MAAMM,UAAU,MAAM5C,SAAS6C,IAAI,GAAG3C,KAAK,CAAC,IAAM;YAClD,IAAI,CAACF,SAASkC,EAAE,EAAE;;gBAChB,MAAMY,SAASpE,qBAAqBsB,SAASC,MAAM,EAAE2C;gBACrDpB,UAAUsB,SAASrE,oBAAoBqE,UAAUC,eAAOH,2BAAAA,QAAS1B,KAAK,mBAAIH;gBAC1E,OAAO;YACT;YACAwB,OAAOK,2BAAAA,QAAShC,GAAG;YACnB,IAAI,CAAC2B,MAAM;gBACTf,UAAUT;gBACV,OAAO;YACT;YACAK,OAAOmB;QACT,EAAE,eAAM;YACNf,UAAUT;YACV,OAAO;QACT,SAAU;YACRO,YAAY;QACd;QACA,IAAI,CAACX,aAAa4B,OAAO,KAAKZ,MAAMY,KAAKS,EAAE,EAAEV,QAAQ7C,KAAK;QAC1D,OAAO;IACT,GACA;QAACsB;QAAQY;KAAM;IAGjB,MAAMsB,QAAQrE,YAAY;YACxB6C;SAAAA,oBAAAA,SAASlB,OAAO,qBAAhBkB,kBAAkBC,KAAK;QACvBN,OAAO;QACPI,UAAU;IACZ,GAAG,EAAE;IAEL,OAAO;QAAEZ;QAAKS;QAAU6B,SAASC,QAAQvC,OAAO,CAACD,aAAaC;QAAOW;QAAQc;QAAOY;IAAM;AAC5F"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AiStepKind } from '../providers/catalog';
|
|
2
|
+
import type { AiModelOption } from '../providers/model-choice';
|
|
3
|
+
/**
|
|
4
|
+
* THE MODEL SWITCH'S STATE (AGL-2942): the reader's pick for one surface,
|
|
5
|
+
* remembered per person per workspace per surface, and the options the
|
|
6
|
+
* server lists for it — fetched when the switch is OPENED, never on mount,
|
|
7
|
+
* because the panel mounts on every console page.
|
|
8
|
+
*
|
|
9
|
+
* `null` is Auto. A remembered pick the server no longer lists — the plan
|
|
10
|
+
* changed, a manager narrowed an allowlist — falls back to Auto the moment
|
|
11
|
+
* the options arrive, and a door would have run the request on Auto anyway:
|
|
12
|
+
* the server decides again inside each request, so the remembered value is
|
|
13
|
+
* a preference, never a grant.
|
|
14
|
+
*/
|
|
15
|
+
/** Where a pick is remembered: the chat, the copy rewrite, a section, a job. */
|
|
16
|
+
export type AiModelSurface = 'assist' | 'copy' | 'section' | 'jobs';
|
|
17
|
+
export interface AiModelOptionsWire {
|
|
18
|
+
kind: AiStepKind;
|
|
19
|
+
auto: (AiModelOption & {
|
|
20
|
+
model: string;
|
|
21
|
+
}) | null;
|
|
22
|
+
options: AiModelOption[];
|
|
23
|
+
measured: boolean;
|
|
24
|
+
}
|
|
25
|
+
export type AiModelOptionsStatus = 'idle' | 'loading' | 'ready' | 'refused' | 'error';
|
|
26
|
+
/** Forget every read; specs start each case from nothing. */
|
|
27
|
+
export declare function resetAiModelOptionReadsForTests(): void;
|
|
28
|
+
export interface AiModelChoiceState {
|
|
29
|
+
/** The pick to send, or `null` for Auto. */
|
|
30
|
+
model: string | null;
|
|
31
|
+
/** The pick's label as last listed, for the button before options load. */
|
|
32
|
+
label: string;
|
|
33
|
+
options: AiModelOptionsWire | null;
|
|
34
|
+
status: AiModelOptionsStatus;
|
|
35
|
+
/** Read the options — the switch calls this when it opens. */
|
|
36
|
+
load: () => void;
|
|
37
|
+
select: (option: {
|
|
38
|
+
id: string;
|
|
39
|
+
label: string;
|
|
40
|
+
} | null) => void;
|
|
41
|
+
}
|
|
42
|
+
export declare function useAiModelChoice(input: {
|
|
43
|
+
orgId?: string | null;
|
|
44
|
+
hostId?: string | null;
|
|
45
|
+
surface: AiModelSurface;
|
|
46
|
+
kind: AiStepKind;
|
|
47
|
+
}): AiModelChoiceState;
|
|
@@ -0,0 +1,150 @@
|
|
|
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
|
+
*/ 'use client';
|
|
17
|
+
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
18
|
+
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
19
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
20
|
+
const storageKey = (uid, orgId, surface)=>`aglyn-ai-model:${uid}:${orgId}:${surface}`;
|
|
21
|
+
function readRemembered(uid, orgId, surface) {
|
|
22
|
+
try {
|
|
23
|
+
var _globalThis_localStorage;
|
|
24
|
+
const raw = (_globalThis_localStorage = globalThis.localStorage) == null ? void 0 : _globalThis_localStorage.getItem(storageKey(uid, orgId, surface));
|
|
25
|
+
const parsed = raw ? JSON.parse(raw) : null;
|
|
26
|
+
return parsed && typeof parsed.id === 'string' && typeof parsed.label === 'string' ? {
|
|
27
|
+
id: parsed.id,
|
|
28
|
+
label: parsed.label
|
|
29
|
+
} : null;
|
|
30
|
+
} catch (unused) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function writeRemembered(uid, orgId, surface, value) {
|
|
35
|
+
try {
|
|
36
|
+
var _globalThis_localStorage, _globalThis_localStorage1;
|
|
37
|
+
const key = storageKey(uid, orgId, surface);
|
|
38
|
+
if (value) (_globalThis_localStorage = globalThis.localStorage) == null ? void 0 : _globalThis_localStorage.setItem(key, JSON.stringify(value));
|
|
39
|
+
else (_globalThis_localStorage1 = globalThis.localStorage) == null ? void 0 : _globalThis_localStorage1.removeItem(key);
|
|
40
|
+
} catch (unused) {
|
|
41
|
+
// A pick that cannot be remembered still applies to this page.
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** One options read per reader, workspace, site and kind, shared by every mount. */ const optionReads = new Map();
|
|
45
|
+
/** Forget every read; specs start each case from nothing. */ export function resetAiModelOptionReadsForTests() {
|
|
46
|
+
optionReads.clear();
|
|
47
|
+
}
|
|
48
|
+
export function useAiModelChoice(input) {
|
|
49
|
+
var _input_hostId, _ref, _ref1, _ref2;
|
|
50
|
+
const { orgId, surface, kind } = input;
|
|
51
|
+
const hostId = (_input_hostId = input.hostId) != null ? _input_hostId : '';
|
|
52
|
+
const { data: user } = useUser();
|
|
53
|
+
const uid = (_ref = user == null ? void 0 : user.uid) != null ? _ref : null;
|
|
54
|
+
const userRef = useRef(user);
|
|
55
|
+
userRef.current = user;
|
|
56
|
+
const [remembered, setRemembered] = useState(null);
|
|
57
|
+
const [options, setOptions] = useState(null);
|
|
58
|
+
const [status, setStatus] = useState('idle');
|
|
59
|
+
useEffect(()=>{
|
|
60
|
+
setRemembered(uid && orgId ? readRemembered(uid, orgId, surface) : null);
|
|
61
|
+
setOptions(null);
|
|
62
|
+
setStatus('idle');
|
|
63
|
+
}, [
|
|
64
|
+
uid,
|
|
65
|
+
orgId,
|
|
66
|
+
surface
|
|
67
|
+
]);
|
|
68
|
+
const select = useCallback((option)=>{
|
|
69
|
+
const value = option ? {
|
|
70
|
+
id: option.id,
|
|
71
|
+
label: option.label
|
|
72
|
+
} : null;
|
|
73
|
+
setRemembered(value);
|
|
74
|
+
if (uid && orgId) writeRemembered(uid, orgId, surface, value);
|
|
75
|
+
}, [
|
|
76
|
+
uid,
|
|
77
|
+
orgId,
|
|
78
|
+
surface
|
|
79
|
+
]);
|
|
80
|
+
const load = useCallback(()=>{
|
|
81
|
+
const signedIn = userRef.current;
|
|
82
|
+
if (!uid || !orgId || !signedIn) return;
|
|
83
|
+
const key = [
|
|
84
|
+
uid,
|
|
85
|
+
orgId,
|
|
86
|
+
hostId,
|
|
87
|
+
kind
|
|
88
|
+
].join('\x00');
|
|
89
|
+
let read = optionReads.get(key);
|
|
90
|
+
if (!read) {
|
|
91
|
+
const params = new URLSearchParams({
|
|
92
|
+
orgId,
|
|
93
|
+
kind
|
|
94
|
+
});
|
|
95
|
+
if (hostId) params.set('hostId', hostId);
|
|
96
|
+
read = authorizedFetch(signedIn, `/api/ai/models?${params.toString()}`).then(async (response)=>{
|
|
97
|
+
if (response.status === 403) return {
|
|
98
|
+
status: 'refused',
|
|
99
|
+
data: null
|
|
100
|
+
};
|
|
101
|
+
const payload = await response.json().catch(()=>null);
|
|
102
|
+
return response.ok && payload ? {
|
|
103
|
+
status: 'ready',
|
|
104
|
+
data: payload
|
|
105
|
+
} : {
|
|
106
|
+
status: 'error',
|
|
107
|
+
data: null
|
|
108
|
+
};
|
|
109
|
+
}).catch(()=>({
|
|
110
|
+
status: 'error',
|
|
111
|
+
data: null
|
|
112
|
+
}));
|
|
113
|
+
optionReads.set(key, read);
|
|
114
|
+
// A failed read is not cached: the next open asks again.
|
|
115
|
+
void read.then((result)=>{
|
|
116
|
+
if (result.status === 'error') optionReads.delete(key);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
setStatus((current)=>current === 'ready' ? current : 'loading');
|
|
120
|
+
void read.then((result)=>{
|
|
121
|
+
setStatus(result.status);
|
|
122
|
+
setOptions(result.data);
|
|
123
|
+
});
|
|
124
|
+
}, [
|
|
125
|
+
uid,
|
|
126
|
+
orgId,
|
|
127
|
+
hostId,
|
|
128
|
+
kind
|
|
129
|
+
]);
|
|
130
|
+
// A remembered pick the server no longer lists is Auto again.
|
|
131
|
+
useEffect(()=>{
|
|
132
|
+
if (status !== 'ready' || !options || !remembered) return;
|
|
133
|
+
if (!options.options.some((option)=>option.id === remembered.id)) select(null);
|
|
134
|
+
}, [
|
|
135
|
+
status,
|
|
136
|
+
options,
|
|
137
|
+
remembered,
|
|
138
|
+
select
|
|
139
|
+
]);
|
|
140
|
+
return {
|
|
141
|
+
model: (_ref1 = remembered == null ? void 0 : remembered.id) != null ? _ref1 : null,
|
|
142
|
+
label: (_ref2 = remembered == null ? void 0 : remembered.label) != null ? _ref2 : 'Auto',
|
|
143
|
+
options,
|
|
144
|
+
status,
|
|
145
|
+
load,
|
|
146
|
+
select
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
//# sourceMappingURL=use-ai-model-choice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/use-ai-model-choice.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'use client'\n\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { AiStepKind } from '../providers/catalog'\nimport type { AiModelOption } from '../providers/model-choice'\n\n/**\n * THE MODEL SWITCH'S STATE (AGL-2942): the reader's pick for one surface,\n * remembered per person per workspace per surface, and the options the\n * server lists for it — fetched when the switch is OPENED, never on mount,\n * because the panel mounts on every console page.\n *\n * `null` is Auto. A remembered pick the server no longer lists — the plan\n * changed, a manager narrowed an allowlist — falls back to Auto the moment\n * the options arrive, and a door would have run the request on Auto anyway:\n * the server decides again inside each request, so the remembered value is\n * a preference, never a grant.\n */\n\n/** Where a pick is remembered: the chat, the copy rewrite, a section, a job. */\nexport type AiModelSurface = 'assist' | 'copy' | 'section' | 'jobs'\n\nexport interface AiModelOptionsWire {\n kind: AiStepKind\n auto: (AiModelOption & { model: string }) | null\n options: AiModelOption[]\n measured: boolean\n}\n\nexport type AiModelOptionsStatus = 'idle' | 'loading' | 'ready' | 'refused' | 'error'\n\ninterface Remembered {\n id: string\n label: string\n}\n\nconst storageKey = (uid: string, orgId: string, surface: AiModelSurface) =>\n `aglyn-ai-model:${uid}:${orgId}:${surface}`\n\nfunction readRemembered(uid: string, orgId: string, surface: AiModelSurface): Remembered | null {\n try {\n const raw = globalThis.localStorage?.getItem(storageKey(uid, orgId, surface))\n const parsed = raw ? (JSON.parse(raw) as Partial<Remembered>) : null\n return parsed && typeof parsed.id === 'string' && typeof parsed.label === 'string'\n ? { id: parsed.id, label: parsed.label }\n : null\n } catch {\n return null\n }\n}\n\nfunction writeRemembered(\n uid: string,\n orgId: string,\n surface: AiModelSurface,\n value: Remembered | null,\n): void {\n try {\n const key = storageKey(uid, orgId, surface)\n if (value) globalThis.localStorage?.setItem(key, JSON.stringify(value))\n else globalThis.localStorage?.removeItem(key)\n } catch {\n // A pick that cannot be remembered still applies to this page.\n }\n}\n\n/** One options read per reader, workspace, site and kind, shared by every mount. */\nconst optionReads = new Map<string, Promise<{ status: AiModelOptionsStatus; data: AiModelOptionsWire | null }>>()\n\n/** Forget every read; specs start each case from nothing. */\nexport function resetAiModelOptionReadsForTests(): void {\n optionReads.clear()\n}\n\nexport interface AiModelChoiceState {\n /** The pick to send, or `null` for Auto. */\n model: string | null\n /** The pick's label as last listed, for the button before options load. */\n label: string\n options: AiModelOptionsWire | null\n status: AiModelOptionsStatus\n /** Read the options — the switch calls this when it opens. */\n load: () => void\n select: (option: { id: string; label: string } | null) => void\n}\n\nexport function useAiModelChoice(input: {\n orgId?: string | null\n hostId?: string | null\n surface: AiModelSurface\n kind: AiStepKind\n}): AiModelChoiceState {\n const { orgId, surface, kind } = input\n const hostId = input.hostId ?? ''\n const { data: user } = useUser()\n const uid = user?.uid ?? null\n const userRef = useRef(user)\n userRef.current = user\n const [remembered, setRemembered] = useState<Remembered | null>(null)\n const [options, setOptions] = useState<AiModelOptionsWire | null>(null)\n const [status, setStatus] = useState<AiModelOptionsStatus>('idle')\n\n useEffect(() => {\n setRemembered(uid && orgId ? readRemembered(uid, orgId, surface) : null)\n setOptions(null)\n setStatus('idle')\n }, [uid, orgId, surface])\n\n const select = useCallback(\n (option: { id: string; label: string } | null) => {\n const value = option ? { id: option.id, label: option.label } : null\n setRemembered(value)\n if (uid && orgId) writeRemembered(uid, orgId, surface, value)\n },\n [uid, orgId, surface],\n )\n\n const load = useCallback(() => {\n const signedIn = userRef.current\n if (!uid || !orgId || !signedIn) return\n const key = [uid, orgId, hostId, kind].join('\\x00')\n let read = optionReads.get(key)\n if (!read) {\n const params = new URLSearchParams({ orgId, kind })\n if (hostId) params.set('hostId', hostId)\n read = authorizedFetch(signedIn, `/api/ai/models?${params.toString()}`)\n .then(async (response) => {\n if (response.status === 403) return { status: 'refused' as const, data: null }\n const payload = (await response.json().catch(() => null)) as AiModelOptionsWire | null\n return response.ok && payload\n ? { status: 'ready' as const, data: payload }\n : { status: 'error' as const, data: null }\n })\n .catch(() => ({ status: 'error' as const, data: null }))\n optionReads.set(key, read)\n // A failed read is not cached: the next open asks again.\n void read.then((result) => {\n if (result.status === 'error') optionReads.delete(key)\n })\n }\n setStatus((current) => (current === 'ready' ? current : 'loading'))\n void read.then((result) => {\n setStatus(result.status)\n setOptions(result.data)\n })\n }, [uid, orgId, hostId, kind])\n\n // A remembered pick the server no longer lists is Auto again.\n useEffect(() => {\n if (status !== 'ready' || !options || !remembered) return\n if (!options.options.some((option) => option.id === remembered.id)) select(null)\n }, [status, options, remembered, select])\n\n return {\n model: remembered?.id ?? null,\n label: remembered?.label ?? 'Auto',\n options,\n status,\n load,\n select,\n }\n}\n"],"names":["authorizedFetch","useUser","useCallback","useEffect","useRef","useState","storageKey","uid","orgId","surface","readRemembered","globalThis","raw","localStorage","getItem","parsed","JSON","parse","id","label","writeRemembered","value","key","setItem","stringify","removeItem","optionReads","Map","resetAiModelOptionReadsForTests","clear","useAiModelChoice","input","kind","hostId","data","user","userRef","current","remembered","setRemembered","options","setOptions","status","setStatus","select","option","load","signedIn","join","read","get","params","URLSearchParams","set","toString","then","response","payload","json","catch","ok","result","delete","some","model"],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type AiJobSummary } from '../model/ai-jobs.types';
|
|
2
|
+
/**
|
|
3
|
+
* The jobs route, as a commerce card asks it (AGL-2916): whether the feature
|
|
4
|
+
* is this workspace's at all, the site's recent `products` jobs, starting one,
|
|
5
|
+
* and following each until it settles.
|
|
6
|
+
*
|
|
7
|
+
* The shell has already decided the plan and the member's permission before a
|
|
8
|
+
* card mounts; the release flag is the route's, so a 404 or 403 from the list
|
|
9
|
+
* is the card staying absent. A card follows more than one job at a time — a
|
|
10
|
+
* bulk copy job and a catalog, say — so each job has its own watch: every job
|
|
11
|
+
* it starts, and of the jobs it finds already moving, the ones `follows`
|
|
12
|
+
* names as its own.
|
|
13
|
+
*/
|
|
14
|
+
/** How many recent jobs a card reads to find this site's products jobs. */
|
|
15
|
+
export declare const AI_PRODUCTS_RECENT_JOBS_READ = 20;
|
|
16
|
+
export type AiProductsJobsVerdict = 'checking' | 'ready' | 'hidden';
|
|
17
|
+
export interface AiProductsJobs {
|
|
18
|
+
/** The org the jobs are metered against: the zone's, or the site's. */
|
|
19
|
+
orgId: string | undefined;
|
|
20
|
+
verdict: AiProductsJobsVerdict;
|
|
21
|
+
/** The site's recent `products` jobs, newest first, kept current while followed. */
|
|
22
|
+
jobs: AiJobSummary[];
|
|
23
|
+
notice: string | null;
|
|
24
|
+
setNotice: (notice: string | null) => void;
|
|
25
|
+
/** Starts a job and follows it; resolves with the job as created, or `null` with a notice. */
|
|
26
|
+
start: (brief: string, inputs: Record<string, string>) => Promise<AiJobSummary | null>;
|
|
27
|
+
}
|
|
28
|
+
export declare const isAiJobSettled: (job: AiJobSummary | null | undefined) => boolean;
|
|
29
|
+
/** Whether a job is moving now: queued or running, rather than settled or waiting for a person. */
|
|
30
|
+
export declare const isAiJobMoving: (job: AiJobSummary | null | undefined) => boolean;
|
|
31
|
+
export declare function useAiProductsJobs(input: {
|
|
32
|
+
hostId: string;
|
|
33
|
+
orgId: string | undefined;
|
|
34
|
+
/** Which of the site's moving jobs this card shows, and so follows; none when absent. */
|
|
35
|
+
follows?: (job: AiJobSummary) => boolean;
|
|
36
|
+
}): AiProductsJobs;
|
|
@@ -0,0 +1,190 @@
|
|
|
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
|
+
*/ 'use client';
|
|
17
|
+
import { lockdownRefusalText, parseLockdownRefusal } from "@aglyn/aglyn";
|
|
18
|
+
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
19
|
+
import { useHostOrgId, useUser } from "@aglyn/tenant-feature-instance";
|
|
20
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
21
|
+
import { AI_JOB_TERMINAL_STATUSES } from "../model/ai-jobs.types.js";
|
|
22
|
+
import { readEventFrames } from "./assist-jobs-drawer.component.js";
|
|
23
|
+
/**
|
|
24
|
+
* The jobs route, as a commerce card asks it (AGL-2916): whether the feature
|
|
25
|
+
* is this workspace's at all, the site's recent `products` jobs, starting one,
|
|
26
|
+
* and following each until it settles.
|
|
27
|
+
*
|
|
28
|
+
* The shell has already decided the plan and the member's permission before a
|
|
29
|
+
* card mounts; the release flag is the route's, so a 404 or 403 from the list
|
|
30
|
+
* is the card staying absent. A card follows more than one job at a time — a
|
|
31
|
+
* bulk copy job and a catalog, say — so each job has its own watch: every job
|
|
32
|
+
* it starts, and of the jobs it finds already moving, the ones `follows`
|
|
33
|
+
* names as its own.
|
|
34
|
+
*/ /** How many recent jobs a card reads to find this site's products jobs. */ export const AI_PRODUCTS_RECENT_JOBS_READ = 20;
|
|
35
|
+
export const isAiJobSettled = (job)=>Boolean(job && AI_JOB_TERMINAL_STATUSES.includes(job.status));
|
|
36
|
+
/** Whether a job is moving now: queued or running, rather than settled or waiting for a person. */ export const isAiJobMoving = (job)=>(job == null ? void 0 : job.status) === 'queued' || (job == null ? void 0 : job.status) === 'running';
|
|
37
|
+
const START_FAILED_COPY = 'The AI job could not be started. Try again.';
|
|
38
|
+
const LIST_FAILED_COPY = 'Recent AI proposals could not be loaded.';
|
|
39
|
+
export function useAiProductsJobs(input) {
|
|
40
|
+
var _ref, _input_orgId, _ref1;
|
|
41
|
+
const { hostId } = input;
|
|
42
|
+
// Read through a ref: a card passes a fresh function each render, and the
|
|
43
|
+
// list is read once for who is signed in, not once for each.
|
|
44
|
+
const followsRef = useRef(input.follows);
|
|
45
|
+
followsRef.current = input.follows;
|
|
46
|
+
// A plugin-hosted zone may not know the org; the site does.
|
|
47
|
+
const hostOrgId = useHostOrgId(input.orgId ? undefined : hostId);
|
|
48
|
+
const orgId = (_ref = (_input_orgId = input.orgId) != null ? _input_orgId : hostOrgId) != null ? _ref : undefined;
|
|
49
|
+
const { data: user } = useUser();
|
|
50
|
+
// Held in a ref so the reads key on WHO is signed in, never on the identity
|
|
51
|
+
// of the object that says so.
|
|
52
|
+
const userRef = useRef(user);
|
|
53
|
+
userRef.current = user;
|
|
54
|
+
const uid = (_ref1 = user == null ? void 0 : user.uid) != null ? _ref1 : null;
|
|
55
|
+
const [verdict, setVerdict] = useState('checking');
|
|
56
|
+
const [jobs, setJobs] = useState([]);
|
|
57
|
+
const [notice, setNotice] = useState(null);
|
|
58
|
+
const watches = useRef(new Map());
|
|
59
|
+
useEffect(()=>{
|
|
60
|
+
const open = watches.current;
|
|
61
|
+
return ()=>{
|
|
62
|
+
for (const controller of open.values())controller.abort();
|
|
63
|
+
open.clear();
|
|
64
|
+
};
|
|
65
|
+
}, []);
|
|
66
|
+
const put = useCallback((job)=>{
|
|
67
|
+
setJobs((current)=>[
|
|
68
|
+
job,
|
|
69
|
+
...current.filter((entry)=>entry.id !== job.id)
|
|
70
|
+
].sort((a, b)=>b.createdAt.localeCompare(a.createdAt)));
|
|
71
|
+
}, []);
|
|
72
|
+
/** Follows one job through the events route until it settles. */ const follow = useCallback(async (job, org)=>{
|
|
73
|
+
if (!isAiJobMoving(job) || watches.current.has(job.id)) return;
|
|
74
|
+
const controller = new AbortController();
|
|
75
|
+
watches.current.set(job.id, controller);
|
|
76
|
+
try {
|
|
77
|
+
let again = true;
|
|
78
|
+
while(again && !controller.signal.aborted){
|
|
79
|
+
again = false;
|
|
80
|
+
const response = await authorizedFetch(userRef.current, `/api/ai/jobs/${encodeURIComponent(job.id)}/events?orgId=${encodeURIComponent(org)}`, {
|
|
81
|
+
signal: controller.signal
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok || !response.body) return;
|
|
84
|
+
await readEventFrames(response.body, (event)=>{
|
|
85
|
+
if (event['type'] === 'state') put(event['job']);
|
|
86
|
+
else if (event['type'] === 'reconnect') again = true;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
} catch (unused) {
|
|
90
|
+
// An aborted or dropped watch leaves the last state shown.
|
|
91
|
+
} finally{
|
|
92
|
+
watches.current.delete(job.id);
|
|
93
|
+
}
|
|
94
|
+
}, [
|
|
95
|
+
put
|
|
96
|
+
]);
|
|
97
|
+
useEffect(()=>{
|
|
98
|
+
if (!orgId || !hostId || !uid) return;
|
|
99
|
+
let active = true;
|
|
100
|
+
setVerdict('checking');
|
|
101
|
+
void (async ()=>{
|
|
102
|
+
try {
|
|
103
|
+
const response = await authorizedFetch(userRef.current, `/api/ai/jobs?orgId=${encodeURIComponent(orgId)}&limit=${AI_PRODUCTS_RECENT_JOBS_READ}`);
|
|
104
|
+
if (!active) return;
|
|
105
|
+
// The flag off (404) and the plan without generation (403): the
|
|
106
|
+
// feature is not this workspace's, so the card is not here at all.
|
|
107
|
+
if (response.status === 404 || response.status === 403) {
|
|
108
|
+
setVerdict('hidden');
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const payload = await response.json().catch(()=>null);
|
|
112
|
+
if (!active) return;
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
var _ref;
|
|
115
|
+
const locked = parseLockdownRefusal(response.status, payload);
|
|
116
|
+
setNotice(locked ? lockdownRefusalText(locked) : String((_ref = payload == null ? void 0 : payload.error) != null ? _ref : LIST_FAILED_COPY));
|
|
117
|
+
} else {
|
|
118
|
+
var _ref1;
|
|
119
|
+
const recent = ((_ref1 = payload == null ? void 0 : payload.jobs) != null ? _ref1 : []).filter((entry)=>entry.kind === 'products' && entry.hostId === hostId);
|
|
120
|
+
setJobs(recent);
|
|
121
|
+
for (const job of recent){
|
|
122
|
+
if (followsRef.current == null ? void 0 : followsRef.current.call(followsRef, job)) void follow(job, orgId);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
setVerdict('ready');
|
|
126
|
+
} catch (unused) {
|
|
127
|
+
if (!active) return;
|
|
128
|
+
setNotice(LIST_FAILED_COPY);
|
|
129
|
+
setVerdict('ready');
|
|
130
|
+
}
|
|
131
|
+
})();
|
|
132
|
+
return ()=>{
|
|
133
|
+
active = false;
|
|
134
|
+
};
|
|
135
|
+
}, [
|
|
136
|
+
orgId,
|
|
137
|
+
hostId,
|
|
138
|
+
uid,
|
|
139
|
+
follow
|
|
140
|
+
]);
|
|
141
|
+
const start = useCallback(async (brief, inputs)=>{
|
|
142
|
+
if (!orgId) return null;
|
|
143
|
+
setNotice(null);
|
|
144
|
+
try {
|
|
145
|
+
const response = await authorizedFetch(userRef.current, '/api/ai/jobs', {
|
|
146
|
+
method: 'POST',
|
|
147
|
+
headers: {
|
|
148
|
+
'Content-Type': 'application/json'
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
orgId,
|
|
152
|
+
hostId,
|
|
153
|
+
kind: 'products',
|
|
154
|
+
brief,
|
|
155
|
+
inputs
|
|
156
|
+
})
|
|
157
|
+
});
|
|
158
|
+
const payload = await response.json().catch(()=>null);
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
var _ref;
|
|
161
|
+
const locked = parseLockdownRefusal(response.status, payload);
|
|
162
|
+
setNotice(locked ? lockdownRefusalText(locked) : String((_ref = payload == null ? void 0 : payload.error) != null ? _ref : START_FAILED_COPY));
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
const job = payload == null ? void 0 : payload.job;
|
|
166
|
+
if (!job) return null;
|
|
167
|
+
put(job);
|
|
168
|
+
void follow(job, orgId);
|
|
169
|
+
return job;
|
|
170
|
+
} catch (unused) {
|
|
171
|
+
setNotice(START_FAILED_COPY);
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
}, [
|
|
175
|
+
orgId,
|
|
176
|
+
hostId,
|
|
177
|
+
put,
|
|
178
|
+
follow
|
|
179
|
+
]);
|
|
180
|
+
return {
|
|
181
|
+
orgId,
|
|
182
|
+
verdict,
|
|
183
|
+
jobs,
|
|
184
|
+
notice,
|
|
185
|
+
setNotice,
|
|
186
|
+
start
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
//# sourceMappingURL=use-ai-products-jobs.js.map
|