@aglyn/plugins-ai 1.0.0-beta.229 → 1.0.0-beta.231
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/README.md +3 -3
- package/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.js +7 -1
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/components/ai-assist-provider-on-host.component.d.ts +66 -0
- package/src/lib/components/ai-assist-provider-on-host.component.js +78 -0
- package/src/lib/components/ai-assist-provider-on-host.component.js.map +1 -0
- package/src/lib/components/ai-assist-provider.component.js +9 -10
- package/src/lib/components/ai-assist-provider.component.js.map +1 -1
- package/src/lib/components/ai-automation-zones.d.ts +38 -0
- package/src/lib/components/ai-automation-zones.js +5 -1
- package/src/lib/components/ai-automation-zones.js.map +1 -1
- package/src/lib/components/ai-brief-dialog.component.d.ts +20 -2
- package/src/lib/components/ai-brief-dialog.component.js +87 -8
- package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
- package/src/lib/components/ai-campaign-create.component.d.ts +54 -0
- package/src/lib/components/ai-campaign-create.component.js +270 -0
- package/src/lib/components/ai-campaign-create.component.js.map +1 -0
- package/src/lib/components/ai-describe-automation.component.d.ts +8 -3
- package/src/lib/components/ai-describe-automation.component.js +15 -6
- package/src/lib/components/ai-describe-automation.component.js.map +1 -1
- package/src/lib/components/ai-describe-button.component.d.ts +20 -8
- package/src/lib/components/ai-describe-button.component.js +19 -36
- package/src/lib/components/ai-describe-button.component.js.map +1 -1
- package/src/lib/components/ai-describe-email.component.d.ts +31 -0
- package/src/lib/components/ai-describe-email.component.js +22 -0
- package/src/lib/components/ai-describe-email.component.js.map +1 -0
- package/src/lib/components/ai-describe-org-automation.component.d.ts +36 -0
- package/src/lib/components/ai-describe-org-automation.component.js +238 -0
- package/src/lib/components/ai-describe-org-automation.component.js.map +1 -0
- package/src/lib/components/ai-experiment-cards.component.d.ts +9 -1
- package/src/lib/components/ai-experiment-cards.component.js +104 -18
- package/src/lib/components/ai-experiment-cards.component.js.map +1 -1
- package/src/lib/components/ai-explain-automation.component.js +1 -5
- package/src/lib/components/ai-explain-automation.component.js.map +1 -1
- package/src/lib/components/ai-funnel-zones.component.d.ts +61 -0
- package/src/lib/components/ai-funnel-zones.component.js +178 -0
- package/src/lib/components/ai-funnel-zones.component.js.map +1 -0
- package/src/lib/components/ai-insight-card.component.d.ts +42 -0
- package/src/lib/components/ai-insight-card.component.js +137 -0
- package/src/lib/components/ai-insight-card.component.js.map +1 -0
- package/src/lib/components/ai-insight-dialog.component.d.ts +6 -0
- package/src/lib/components/ai-insight-dialog.component.js +9 -3
- package/src/lib/components/ai-insight-dialog.component.js.map +1 -1
- package/src/lib/components/ai-job-plan.component.d.ts +7 -2
- package/src/lib/components/ai-job-plan.component.js +38 -6
- package/src/lib/components/ai-job-plan.component.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +17 -1
- package/src/lib/components/ai-job-requests.js +39 -3
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-logic-zones.d.ts +64 -0
- package/src/lib/components/ai-logic-zones.js +18 -0
- package/src/lib/components/ai-logic-zones.js.map +1 -0
- package/src/lib/components/ai-logic.component.d.ts +77 -0
- package/src/lib/components/ai-logic.component.js +553 -0
- package/src/lib/components/ai-logic.component.js.map +1 -0
- package/src/lib/components/ai-marketing-insight.component.d.ts +30 -0
- package/src/lib/components/ai-marketing-insight.component.js +80 -0
- package/src/lib/components/ai-marketing-insight.component.js.map +1 -0
- package/src/lib/components/ai-media-create.component.d.ts +55 -0
- package/src/lib/components/ai-media-create.component.js +433 -0
- package/src/lib/components/ai-media-create.component.js.map +1 -0
- package/src/lib/components/ai-overlay-cards.component.d.ts +83 -0
- package/src/lib/components/ai-overlay-cards.component.js +505 -0
- package/src/lib/components/ai-overlay-cards.component.js.map +1 -0
- package/src/lib/components/ai-permissions-on-host.component.d.ts +3 -46
- package/src/lib/components/ai-permissions-on-host.component.js +5 -53
- package/src/lib/components/ai-permissions-on-host.component.js.map +1 -1
- package/src/lib/components/ai-product-zones.d.ts +5 -0
- package/src/lib/components/ai-product-zones.js +1 -1
- package/src/lib/components/ai-product-zones.js.map +1 -1
- package/src/lib/components/ai-products-create-button.component.d.ts +42 -0
- package/src/lib/components/ai-products-create-button.component.js +67 -0
- package/src/lib/components/ai-products-create-button.component.js.map +1 -0
- package/src/lib/components/ai-products-hub-card.component.js +100 -81
- package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
- package/src/lib/components/ai-revise-automation.component.d.ts +16 -0
- package/src/lib/components/ai-revise-automation.component.js +207 -0
- package/src/lib/components/ai-revise-automation.component.js.map +1 -0
- package/src/lib/components/ai-site-build-page.component.js +160 -24
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-upsell-dialog.component.d.ts +53 -0
- package/src/lib/components/ai-upsell-dialog.component.js +177 -0
- package/src/lib/components/ai-upsell-dialog.component.js.map +1 -0
- package/src/lib/components/assist-build-card.component.d.ts +42 -0
- package/src/lib/components/assist-build-card.component.js +183 -0
- package/src/lib/components/assist-build-card.component.js.map +1 -0
- package/src/lib/components/assist-edit-canvas.d.ts +2 -0
- package/src/lib/components/assist-edit-canvas.js +56 -1
- package/src/lib/components/assist-edit-canvas.js.map +1 -1
- package/src/lib/components/assist-jobs-drawer.component.js +48 -3
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.js +51 -2
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/components/use-ai-job-run.d.ts +3 -14
- package/src/lib/components/use-ai-job-run.js +0 -50
- package/src/lib/components/use-ai-job-run.js.map +1 -1
- package/src/lib/jobs/ai-build-capabilities.d.ts +58 -0
- package/src/lib/jobs/ai-build-capabilities.js +256 -0
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -0
- package/src/lib/jobs/ai-build-unit-outcome.d.ts +52 -0
- package/src/lib/jobs/ai-build-unit-outcome.js +140 -0
- package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -0
- package/src/lib/jobs/ai-job-auto-confirm.d.ts +8 -0
- package/src/lib/jobs/ai-job-auto-confirm.js +30 -6
- package/src/lib/jobs/ai-job-auto-confirm.js.map +1 -1
- package/src/lib/jobs/ai-job-build-step.d.ts +144 -0
- package/src/lib/jobs/ai-job-build-step.js +668 -0
- package/src/lib/jobs/ai-job-build-step.js.map +1 -0
- package/src/lib/jobs/ai-job-draft-ids.js +9 -1
- package/src/lib/jobs/ai-job-draft-ids.js.map +1 -1
- package/src/lib/jobs/ai-job-drafts.d.ts +14 -4
- package/src/lib/jobs/ai-job-drafts.js +25 -4
- package/src/lib/jobs/ai-job-drafts.js.map +1 -1
- package/src/lib/jobs/ai-job-generation.d.ts +8 -0
- package/src/lib/jobs/ai-job-generation.js +13 -2
- package/src/lib/jobs/ai-job-generation.js.map +1 -1
- package/src/lib/jobs/ai-job-insight-step.js +8 -1
- package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.d.ts +73 -0
- package/src/lib/jobs/ai-job-layout-language.js +194 -0
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -0
- package/src/lib/jobs/ai-job-layout-site-pages.d.ts +13 -2
- package/src/lib/jobs/ai-job-layout-site-pages.js +18 -2
- package/src/lib/jobs/ai-job-layout-site-pages.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-step.d.ts +5 -0
- package/src/lib/jobs/ai-job-layout-step.js +105 -5
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-logic-step.d.ts +107 -0
- package/src/lib/jobs/ai-job-logic-step.js +395 -0
- package/src/lib/jobs/ai-job-logic-step.js.map +1 -0
- package/src/lib/jobs/ai-job-overlay-copy.d.ts +70 -0
- package/src/lib/jobs/ai-job-overlay-copy.js +178 -0
- package/src/lib/jobs/ai-job-overlay-copy.js.map +1 -0
- package/src/lib/jobs/ai-job-page-language.d.ts +149 -0
- package/src/lib/jobs/ai-job-page-language.js +355 -0
- package/src/lib/jobs/ai-job-page-language.js.map +1 -0
- package/src/lib/jobs/ai-job-page-sections.d.ts +37 -1
- package/src/lib/jobs/ai-job-page-sections.js +93 -11
- package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.d.ts +4 -4
- package/src/lib/jobs/ai-job-page-step.js +111 -20
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +27 -2
- package/src/lib/jobs/ai-job-plan-step.js +87 -13
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +19 -1
- package/src/lib/jobs/ai-job-site-step.js +220 -61
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-text-step.d.ts +22 -1
- package/src/lib/jobs/ai-job-text-step.js +12 -0
- package/src/lib/jobs/ai-job-text-step.js.map +1 -1
- package/src/lib/jobs/ai-job-workflow-step.d.ts +54 -4
- package/src/lib/jobs/ai-job-workflow-step.js +320 -15
- package/src/lib/jobs/ai-job-workflow-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs.d.ts +80 -2
- package/src/lib/jobs/ai-jobs.js +391 -18
- package/src/lib/jobs/ai-jobs.js.map +1 -1
- package/src/lib/jobs/ai-layout-full-height.d.ts +40 -0
- package/src/lib/jobs/ai-layout-full-height.js +82 -0
- package/src/lib/jobs/ai-layout-full-height.js.map +1 -0
- package/src/lib/jobs/ai-layout-site-facts.d.ts +54 -0
- package/src/lib/jobs/ai-layout-site-facts.js +153 -0
- package/src/lib/jobs/ai-layout-site-facts.js.map +1 -0
- package/src/lib/jobs/ai-logic-records.d.ts +40 -0
- package/src/lib/jobs/ai-logic-records.js +55 -0
- package/src/lib/jobs/ai-logic-records.js.map +1 -0
- package/src/lib/jobs/ai-site-publish.d.ts +7 -0
- package/src/lib/jobs/ai-site-publish.js +9 -0
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/jobs/ai-workflow-records.d.ts +4 -0
- package/src/lib/jobs/ai-workflow-records.js +40 -1
- package/src/lib/jobs/ai-workflow-records.js.map +1 -1
- package/src/lib/layout-language/ai-layout-compiler.d.ts +145 -0
- package/src/lib/layout-language/ai-layout-compiler.js +1148 -0
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -0
- package/src/lib/layout-language/ai-layout-copy.d.ts +73 -0
- package/src/lib/layout-language/ai-layout-copy.js +137 -0
- package/src/lib/layout-language/ai-layout-copy.js.map +1 -0
- package/src/lib/layout-language/ai-layout-frame.d.ts +52 -0
- package/src/lib/layout-language/ai-layout-frame.js +457 -0
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -0
- package/src/lib/layout-language/ai-layout-gaps.d.ts +63 -0
- package/src/lib/layout-language/ai-layout-gaps.js +345 -0
- package/src/lib/layout-language/ai-layout-gaps.js.map +1 -0
- package/src/lib/layout-language/ai-layout-language.d.ts +161 -0
- package/src/lib/layout-language/ai-layout-language.js +446 -0
- package/src/lib/layout-language/ai-layout-language.js.map +1 -0
- package/src/lib/layout-language/ai-layout-links.d.ts +80 -0
- package/src/lib/layout-language/ai-layout-links.js +109 -0
- package/src/lib/layout-language/ai-layout-links.js.map +1 -0
- package/src/lib/layout-language/ai-layout-store.d.ts +39 -0
- package/src/lib/layout-language/ai-layout-store.js +69 -0
- package/src/lib/layout-language/ai-layout-store.js.map +1 -0
- package/src/lib/layout-language/ai-layout-tree.d.ts +59 -0
- package/src/lib/layout-language/ai-layout-tree.js +84 -0
- package/src/lib/layout-language/ai-layout-tree.js.map +1 -0
- package/src/lib/lazy-widget.d.ts +45 -0
- package/src/lib/lazy-widget.js +53 -0
- package/src/lib/lazy-widget.js.map +1 -0
- package/src/lib/model/ai-automation-draft.d.ts +18 -0
- package/src/lib/model/ai-automation-draft.js +86 -0
- package/src/lib/model/ai-automation-draft.js.map +1 -1
- package/src/lib/model/ai-build-job.d.ts +201 -0
- package/src/lib/model/ai-build-job.js +472 -0
- package/src/lib/model/ai-build-job.js.map +1 -0
- package/src/lib/model/ai-build-plan.d.ts +61 -0
- package/src/lib/model/ai-build-plan.js +154 -9
- package/src/lib/model/ai-build-plan.js.map +1 -1
- package/src/lib/model/ai-build-progress.d.ts +73 -0
- package/src/lib/model/ai-build-progress.js +170 -0
- package/src/lib/model/ai-build-progress.js.map +1 -0
- package/src/lib/model/ai-host-publish-context.d.ts +51 -0
- package/src/lib/model/ai-host-publish-context.js +104 -0
- package/src/lib/model/ai-host-publish-context.js.map +1 -0
- package/src/lib/model/ai-insight.d.ts +20 -10
- package/src/lib/model/ai-insight.js +72 -9
- package/src/lib/model/ai-insight.js.map +1 -1
- package/src/lib/model/ai-job-activity.d.ts +22 -0
- package/src/lib/model/ai-job-activity.js +25 -2
- package/src/lib/model/ai-job-activity.js.map +1 -1
- package/src/lib/model/ai-job-failure-copy.d.ts +38 -1
- package/src/lib/model/ai-job-failure-copy.js +56 -1
- package/src/lib/model/ai-job-failure-copy.js.map +1 -1
- package/src/lib/model/ai-job-notice.d.ts +3 -1
- package/src/lib/model/ai-job-notice.js +31 -9
- package/src/lib/model/ai-job-notice.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +99 -2
- package/src/lib/model/ai-jobs.types.js +3 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-logic-job.d.ts +108 -0
- package/src/lib/model/ai-logic-job.js +327 -0
- package/src/lib/model/ai-logic-job.js.map +1 -0
- package/src/lib/model/ai-media-credits.d.ts +52 -0
- package/src/lib/model/ai-media-credits.js +61 -0
- package/src/lib/model/ai-media-credits.js.map +1 -0
- package/src/lib/model/ai-overlay-copy.d.ts +114 -0
- package/src/lib/model/ai-overlay-copy.js +175 -0
- package/src/lib/model/ai-overlay-copy.js.map +1 -0
- package/src/lib/model/ai-site-build-progress.d.ts +25 -4
- package/src/lib/model/ai-site-build-progress.js +194 -11
- package/src/lib/model/ai-site-build-progress.js.map +1 -1
- package/src/lib/model/ai-site-job.d.ts +8 -0
- package/src/lib/model/ai-site-job.js +9 -0
- package/src/lib/model/ai-site-job.js.map +1 -1
- package/src/lib/model/ai-site-start-seo.d.ts +1 -1
- package/src/lib/model/ai-site-start.d.ts +5 -2
- package/src/lib/model/ai-site-start.js +5 -2
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/model/ai-svg.d.ts +69 -0
- package/src/lib/model/ai-svg.js +265 -0
- package/src/lib/model/ai-svg.js.map +1 -0
- package/src/lib/model/ai-usage-by-user.d.ts +3 -2
- package/src/lib/model/ai-usage-by-user.js.map +1 -1
- package/src/lib/model/ai-workflow-job.d.ts +92 -4
- package/src/lib/model/ai-workflow-job.js +124 -7
- package/src/lib/model/ai-workflow-job.js.map +1 -1
- package/src/lib/model/assist-build.d.ts +58 -0
- package/src/lib/model/assist-build.js +52 -0
- package/src/lib/model/assist-build.js.map +1 -0
- package/src/lib/model/assist-edit.d.ts +48 -3
- package/src/lib/model/assist-edit.js +48 -4
- package/src/lib/model/assist-edit.js.map +1 -1
- package/src/lib/plugin-config.js +2 -0
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +308 -47
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/providers/catalog.d.ts +82 -5
- package/src/lib/providers/catalog.js +83 -12
- package/src/lib/providers/catalog.js.map +1 -1
- package/src/lib/providers/image-contract.d.ts +116 -0
- package/src/lib/providers/image-contract.js +74 -0
- package/src/lib/providers/image-contract.js.map +1 -0
- package/src/lib/providers/model-choice.js +11 -0
- package/src/lib/providers/model-choice.js.map +1 -1
- package/src/lib/providers/routing.js +18 -0
- package/src/lib/providers/routing.js.map +1 -1
- package/src/lib/providers/vertex-image.d.ts +121 -0
- package/src/lib/providers/vertex-image.js +312 -0
- package/src/lib/providers/vertex-image.js.map +1 -0
- package/src/lib/runtime/ai-doctrine-validators.d.ts +101 -0
- package/src/lib/runtime/ai-doctrine-validators.js +525 -4
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +21 -6
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-eval-live.js +4 -0
- package/src/lib/runtime/ai-eval-live.js.map +1 -1
- package/src/lib/runtime/ai-eval.d.ts +15 -1
- package/src/lib/runtime/ai-eval.js +52 -1
- package/src/lib/runtime/ai-eval.js.map +1 -1
- package/src/lib/runtime/ai-icon-library.d.ts +257 -0
- package/src/lib/runtime/ai-icon-library.js +254 -0
- package/src/lib/runtime/ai-icon-library.js.map +1 -0
- package/src/lib/runtime/ai-node-tree.d.ts +9 -0
- package/src/lib/runtime/ai-node-tree.js +30 -4
- package/src/lib/runtime/ai-node-tree.js.map +1 -1
- package/src/lib/runtime/ai-palette.d.ts +6 -0
- package/src/lib/runtime/ai-palette.generated.js +70 -0
- package/src/lib/runtime/ai-palette.generated.js.map +1 -1
- package/src/lib/runtime/ai-palette.js.map +1 -1
- package/src/lib/runtime/experiment-variant-copy.d.ts +34 -0
- package/src/lib/runtime/experiment-variant-copy.js +102 -0
- package/src/lib/runtime/experiment-variant-copy.js.map +1 -0
- package/src/lib/server/ai-experiment-versions.d.ts +51 -0
- package/src/lib/server/ai-experiment-versions.js +270 -0
- package/src/lib/server/ai-experiment-versions.js.map +1 -0
- package/src/lib/server/ai-jobs-resume.js +74 -4
- package/src/lib/server/ai-jobs-resume.js.map +1 -1
- package/src/lib/server/ai-media-image.d.ts +66 -0
- package/src/lib/server/ai-media-image.js +521 -0
- package/src/lib/server/ai-media-image.js.map +1 -0
- package/src/lib/server/ai-media-svg.d.ts +91 -0
- package/src/lib/server/ai-media-svg.js +186 -0
- package/src/lib/server/ai-media-svg.js.map +1 -0
- package/src/lib/server/assist-build.d.ts +54 -0
- package/src/lib/server/assist-build.js +121 -0
- package/src/lib/server/assist-build.js.map +1 -0
- package/src/lib/server/assist-chat.js +108 -12
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-edit.js +213 -3
- package/src/lib/server/assist-edit.js.map +1 -1
- package/src/lib/server/assist-view-context.js +242 -4
- package/src/lib/server/assist-view-context.js.map +1 -1
- package/src/lib/server.js +26 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tools/ai-logic-tool.d.ts +27 -0
- package/src/lib/tools/ai-logic-tool.js +207 -0
- package/src/lib/tools/ai-logic-tool.js.map +1 -0
- package/src/lib/tools/ai-overlay-tool.d.ts +35 -0
- package/src/lib/tools/ai-overlay-tool.js +107 -0
- package/src/lib/tools/ai-overlay-tool.js.map +1 -0
- package/src/lib/tools/ai-workflow-tool.d.ts +17 -2
- package/src/lib/tools/ai-workflow-tool.js +47 -14
- package/src/lib/tools/ai-workflow-tool.js.map +1 -1
- package/src/lib/usage/assist-job-refund.d.ts +28 -1
- package/src/lib/usage/assist-job-refund.js +44 -9
- package/src/lib/usage/assist-job-refund.js.map +1 -1
- package/src/lib/usage/assist-usage.d.ts +5 -0
- package/src/lib/usage/assist-usage.js +2 -0
- package/src/lib/usage/assist-usage.js.map +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
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 { ConsoleHostScreensZoneProps } from '@aglyn/aglyn/plugin-manager/feature-plugins';
|
|
18
|
+
/**
|
|
19
|
+
* "Create with AI" for email (AGL-3596): the same button and dialog as a
|
|
20
|
+
* page's, a form's or a template's, beside New template on the email
|
|
21
|
+
* plugin's `hostEmailTemplates` zone (the `hostScreens` contract: the site
|
|
22
|
+
* and its org). The Campaigns section's door is a widget of its own
|
|
23
|
+
* (`ai-campaign-create.component`), on the marketing plugin's `hostCampaigns`.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* An email design from a brief, on a site's email templates
|
|
27
|
+
* (`hostEmailTemplates`). Its dialog also offers to draft the campaign that
|
|
28
|
+
* would send it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function AiDescribeEmailButton(props: ConsoleHostScreensZoneProps): import("react").JSX.Element;
|
|
31
|
+
export default AiDescribeEmailButton;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
3
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
|
+
import { AiDescribeButton } from "./ai-describe-button.component.js";
|
|
5
|
+
/**
|
|
6
|
+
* "Create with AI" for email (AGL-3596): the same button and dialog as a
|
|
7
|
+
* page's, a form's or a template's, beside New template on the email
|
|
8
|
+
* plugin's `hostEmailTemplates` zone (the `hostScreens` contract: the site
|
|
9
|
+
* and its org). The Campaigns section's door is a widget of its own
|
|
10
|
+
* (`ai-campaign-create.component`), on the marketing plugin's `hostCampaigns`.
|
|
11
|
+
*/ /**
|
|
12
|
+
* An email design from a brief, on a site's email templates
|
|
13
|
+
* (`hostEmailTemplates`). Its dialog also offers to draft the campaign that
|
|
14
|
+
* would send it.
|
|
15
|
+
*/ export function AiDescribeEmailButton(props) {
|
|
16
|
+
return /*#__PURE__*/ _jsx(AiDescribeButton, _extends({}, props, {
|
|
17
|
+
kind: "email"
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
export default AiDescribeEmailButton;
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=ai-describe-email.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-describe-email.component.tsx"],"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 type { ConsoleHostScreensZoneProps } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { AiDescribeButton } from './ai-describe-button.component'\n\n/**\n * \"Create with AI\" for email (AGL-3596): the same button and dialog as a\n * page's, a form's or a template's, beside New template on the email\n * plugin's `hostEmailTemplates` zone (the `hostScreens` contract: the site\n * and its org). The Campaigns section's door is a widget of its own\n * (`ai-campaign-create.component`), on the marketing plugin's `hostCampaigns`.\n */\n\n/**\n * An email design from a brief, on a site's email templates\n * (`hostEmailTemplates`). Its dialog also offers to draft the campaign that\n * would send it.\n */\nexport function AiDescribeEmailButton(props: ConsoleHostScreensZoneProps) {\n return <AiDescribeButton {...props} kind=\"email\" />\n}\n\nexport default AiDescribeEmailButton\n"],"names":["AiDescribeButton","AiDescribeEmailButton","props","kind"],"mappings":"AAAA;;;AAoBA,SAASA,gBAAgB,QAAQ,oCAAgC;AAEjE;;;;;;CAMC,GAED;;;;CAIC,GACD,OAAO,SAASC,sBAAsBC,KAAkC;IACtE,qBAAO,KAACF,+BAAqBE;QAAOC,MAAK;;AAC3C;AAEA,eAAeF,sBAAqB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
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 { ConsoleWidgetEntitlementProps } from '@aglyn/aglyn/plugin-manager/feature-plugins';
|
|
18
|
+
import type { ConsoleOrgAutomationsZoneProps } from './ai-automation-zones';
|
|
19
|
+
export declare const AI_ORG_AUTOMATION_COPY: {
|
|
20
|
+
readonly create: "Create with AI";
|
|
21
|
+
readonly title: "Describe an org automation";
|
|
22
|
+
readonly label: "What should happen, and when?";
|
|
23
|
+
readonly placeholder: "When someone books on any of our sites, make them a contact, tag them booked and send them a welcome email";
|
|
24
|
+
readonly next: "It is drafted from what an org automation can start on and do, and opens in the editor switched off, where you choose its sites and save it. Lists, campaigns or datasets your workspace does not have are left for you to pick.";
|
|
25
|
+
readonly submit: "Draft the automation";
|
|
26
|
+
readonly running: "Drafting it. This can take a few minutes.";
|
|
27
|
+
readonly ready: "Drafted";
|
|
28
|
+
readonly open: "Open in the editor";
|
|
29
|
+
readonly notOpened: "It could not be opened in the editor. Check the page for why, then try again.";
|
|
30
|
+
readonly failed: "The automation could not be drafted. Try again.";
|
|
31
|
+
};
|
|
32
|
+
export declare function AiDescribeOrgAutomationButton({ orgId, triggers, steps, propose, entitled, upgrade, }: ConsoleOrgAutomationsZoneProps & ConsoleWidgetEntitlementProps): import("react").JSX.Element;
|
|
33
|
+
export declare namespace AiDescribeOrgAutomationButton {
|
|
34
|
+
var displayName: string;
|
|
35
|
+
}
|
|
36
|
+
export default AiDescribeOrgAutomationButton;
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { pluginDocsHelp } from "@aglyn/aglyn/app-utils/docs-help";
|
|
4
|
+
import { mdiCreation } from "@aglyn/shared-data-mdi";
|
|
5
|
+
import { MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
6
|
+
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
7
|
+
import { Alert, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, Link, Stack, TextField, Typography } from "@mui/material";
|
|
8
|
+
import { useEffect, useState } from "react";
|
|
9
|
+
import { AI_ORG_AUTOMATION_RESOURCE, aiOrgAutomationInputs, readAiOrgAutomationProposal } from "../model/ai-workflow-job.js";
|
|
10
|
+
import { openAiJobs } from "./ai-jobs-store.js";
|
|
11
|
+
import { AiUpsellButton } from "./ai-upsell-dialog.component.js";
|
|
12
|
+
import { aiJobProblem, useAiJobRun } from "./use-ai-job-run.js";
|
|
13
|
+
/**
|
|
14
|
+
* "Create with AI" on the workspace's Org automations (AGL-3603), in that
|
|
15
|
+
* section's card header through the `orgAutomations` zone: a description
|
|
16
|
+
* becomes a `workflow` job drafting one of the WORKSPACE's automations, held
|
|
17
|
+
* to the triggers and steps the zone says an org automation may use.
|
|
18
|
+
*
|
|
19
|
+
* Nothing is written. The job's proposal opens in the section's editor as a
|
|
20
|
+
* new automation, unsaved and switched off; the person picks the sites it
|
|
21
|
+
* runs on and saves it with the editor's own Save, through the section's
|
|
22
|
+
* route — or closes the editor, and nothing changes.
|
|
23
|
+
*/ const BRIEF_MAX_CHARS = 4000;
|
|
24
|
+
export const AI_ORG_AUTOMATION_COPY = {
|
|
25
|
+
create: 'Create with AI',
|
|
26
|
+
title: 'Describe an org automation',
|
|
27
|
+
label: 'What should happen, and when?',
|
|
28
|
+
placeholder: 'When someone books on any of our sites, make them a contact, tag them booked and send them a welcome email',
|
|
29
|
+
next: 'It is drafted from what an org automation can start on and do, and opens in the editor switched off, where you choose its sites and save it. Lists, campaigns or datasets your workspace does not have are left for you to pick.',
|
|
30
|
+
submit: 'Draft the automation',
|
|
31
|
+
running: 'Drafting it. This can take a few minutes.',
|
|
32
|
+
ready: 'Drafted',
|
|
33
|
+
open: 'Open in the editor',
|
|
34
|
+
notOpened: 'It could not be opened in the editor. Check the page for why, then try again.',
|
|
35
|
+
failed: 'The automation could not be drafted. Try again.'
|
|
36
|
+
};
|
|
37
|
+
/** The proposal a finished job wrote, with what to decide, or `null`. */ function proposalOf(job) {
|
|
38
|
+
var _output_note;
|
|
39
|
+
if ((job == null ? void 0 : job.status) !== 'done') return null;
|
|
40
|
+
const output = job.outputs.find((one)=>one.resource === AI_ORG_AUTOMATION_RESOURCE);
|
|
41
|
+
const automation = readAiOrgAutomationProposal(output == null ? void 0 : output.proposal);
|
|
42
|
+
return automation && output ? {
|
|
43
|
+
automation,
|
|
44
|
+
label: output.label,
|
|
45
|
+
note: (_output_note = output.note) != null ? _output_note : null
|
|
46
|
+
} : null;
|
|
47
|
+
}
|
|
48
|
+
export function AiDescribeOrgAutomationButton({ orgId, triggers, steps, propose, entitled, upgrade }) {
|
|
49
|
+
var _aiJobProblem;
|
|
50
|
+
const copy = AI_ORG_AUTOMATION_COPY;
|
|
51
|
+
const help = pluginDocsHelp('aiAutomations', {
|
|
52
|
+
anchor: '#org-automations'
|
|
53
|
+
});
|
|
54
|
+
const { data: user } = useUser();
|
|
55
|
+
const run = useAiJobRun(user, copy.failed);
|
|
56
|
+
const { job, starting, running, notice, reset } = run;
|
|
57
|
+
const [open, setOpen] = useState(false);
|
|
58
|
+
const [brief, setBrief] = useState('');
|
|
59
|
+
const [notOpened, setNotOpened] = useState(false);
|
|
60
|
+
// Opening or closing starts over and stops following: a job still drafting
|
|
61
|
+
// carries on in AI jobs.
|
|
62
|
+
useEffect(()=>{
|
|
63
|
+
reset();
|
|
64
|
+
setNotOpened(false);
|
|
65
|
+
}, [
|
|
66
|
+
open,
|
|
67
|
+
reset
|
|
68
|
+
]);
|
|
69
|
+
// Drawn from the shell's gates alone (AGL-3601): nothing asks a server
|
|
70
|
+
// until it is used, and a plan without the add-on gets the add-on's dialog.
|
|
71
|
+
if (entitled === false) return upgrade ? /*#__PURE__*/ _jsx(AiUpsellButton, {
|
|
72
|
+
kind: "workflow",
|
|
73
|
+
upgrade: upgrade
|
|
74
|
+
}) : null;
|
|
75
|
+
const ready = proposalOf(job);
|
|
76
|
+
const problem = (_aiJobProblem = aiJobProblem(job, copy.failed)) != null ? _aiJobProblem : (job == null ? void 0 : job.status) === 'done' && !ready ? copy.failed : null;
|
|
77
|
+
const asking = !job || Boolean(notice);
|
|
78
|
+
const close = ()=>setOpen(false);
|
|
79
|
+
const start = async ()=>{
|
|
80
|
+
const trimmed = brief.trim();
|
|
81
|
+
if (!orgId || !trimmed) return;
|
|
82
|
+
setNotOpened(false);
|
|
83
|
+
const inputs = aiOrgAutomationInputs({
|
|
84
|
+
triggers,
|
|
85
|
+
steps
|
|
86
|
+
});
|
|
87
|
+
if (await run.start({
|
|
88
|
+
orgId,
|
|
89
|
+
hostId: null,
|
|
90
|
+
kind: 'workflow',
|
|
91
|
+
brief: trimmed,
|
|
92
|
+
inputs
|
|
93
|
+
})) setBrief('');
|
|
94
|
+
};
|
|
95
|
+
const apply = ()=>{
|
|
96
|
+
if (!ready) return;
|
|
97
|
+
if (propose(ready.automation)) close();
|
|
98
|
+
else setNotOpened(true);
|
|
99
|
+
};
|
|
100
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
101
|
+
children: [
|
|
102
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
103
|
+
size: "small",
|
|
104
|
+
variant: "outlined",
|
|
105
|
+
startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
106
|
+
path: mdiCreation.path
|
|
107
|
+
}),
|
|
108
|
+
onClick: ()=>setOpen(true),
|
|
109
|
+
children: copy.create
|
|
110
|
+
}),
|
|
111
|
+
/*#__PURE__*/ _jsxs(Dialog, {
|
|
112
|
+
open: open,
|
|
113
|
+
onClose: starting ? undefined : close,
|
|
114
|
+
fullWidth: true,
|
|
115
|
+
maxWidth: "sm",
|
|
116
|
+
children: [
|
|
117
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
118
|
+
children: copy.title
|
|
119
|
+
}),
|
|
120
|
+
/*#__PURE__*/ _jsx(DialogContent, {
|
|
121
|
+
children: asking ? /*#__PURE__*/ _jsxs(Stack, {
|
|
122
|
+
spacing: 2,
|
|
123
|
+
sx: {
|
|
124
|
+
pt: 1
|
|
125
|
+
},
|
|
126
|
+
children: [
|
|
127
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
128
|
+
label: copy.label,
|
|
129
|
+
placeholder: copy.placeholder,
|
|
130
|
+
multiline: true,
|
|
131
|
+
minRows: 4,
|
|
132
|
+
value: brief,
|
|
133
|
+
onChange: (event)=>setBrief(event.target.value.slice(0, BRIEF_MAX_CHARS)),
|
|
134
|
+
helperText: `${brief.length.toLocaleString('en-US')} / ${BRIEF_MAX_CHARS.toLocaleString('en-US')}`,
|
|
135
|
+
disabled: starting,
|
|
136
|
+
autoFocus: true
|
|
137
|
+
}),
|
|
138
|
+
/*#__PURE__*/ _jsxs(Typography, {
|
|
139
|
+
variant: "body2",
|
|
140
|
+
color: "text.secondary",
|
|
141
|
+
children: [
|
|
142
|
+
copy.next,
|
|
143
|
+
' ',
|
|
144
|
+
/*#__PURE__*/ _jsx(Link, {
|
|
145
|
+
href: help.href,
|
|
146
|
+
target: "_blank",
|
|
147
|
+
rel: "noopener",
|
|
148
|
+
title: help.excerpt,
|
|
149
|
+
children: 'How it works'
|
|
150
|
+
})
|
|
151
|
+
]
|
|
152
|
+
}),
|
|
153
|
+
notice ? /*#__PURE__*/ _jsx(Alert, {
|
|
154
|
+
severity: "warning",
|
|
155
|
+
children: notice
|
|
156
|
+
}) : null
|
|
157
|
+
]
|
|
158
|
+
}) : /*#__PURE__*/ _jsxs(Stack, {
|
|
159
|
+
spacing: 2,
|
|
160
|
+
sx: {
|
|
161
|
+
pt: 1
|
|
162
|
+
},
|
|
163
|
+
children: [
|
|
164
|
+
running && job ? /*#__PURE__*/ _jsx(Alert, {
|
|
165
|
+
severity: "info",
|
|
166
|
+
icon: /*#__PURE__*/ _jsx(CircularProgress, {
|
|
167
|
+
size: 18,
|
|
168
|
+
"aria-label": "Drafting"
|
|
169
|
+
}),
|
|
170
|
+
action: /*#__PURE__*/ _jsx(Button, {
|
|
171
|
+
color: "inherit",
|
|
172
|
+
size: "small",
|
|
173
|
+
variant: "outlined",
|
|
174
|
+
onClick: ()=>{
|
|
175
|
+
openAiJobs({
|
|
176
|
+
jobId: job.id
|
|
177
|
+
});
|
|
178
|
+
close();
|
|
179
|
+
},
|
|
180
|
+
children: 'Open AI jobs'
|
|
181
|
+
}),
|
|
182
|
+
children: copy.running
|
|
183
|
+
}) : null,
|
|
184
|
+
ready ? /*#__PURE__*/ _jsxs(Alert, {
|
|
185
|
+
severity: "success",
|
|
186
|
+
children: [
|
|
187
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
188
|
+
variant: "body2",
|
|
189
|
+
sx: {
|
|
190
|
+
fontWeight: 600
|
|
191
|
+
},
|
|
192
|
+
children: `${copy.ready}: ${ready.label}`
|
|
193
|
+
}),
|
|
194
|
+
ready.note ? /*#__PURE__*/ _jsx(Typography, {
|
|
195
|
+
variant: "body2",
|
|
196
|
+
children: ready.note
|
|
197
|
+
}) : null
|
|
198
|
+
]
|
|
199
|
+
}) : null,
|
|
200
|
+
problem ? /*#__PURE__*/ _jsx(Alert, {
|
|
201
|
+
severity: (job == null ? void 0 : job.status) === 'failed' ? 'error' : 'warning',
|
|
202
|
+
children: problem
|
|
203
|
+
}) : null,
|
|
204
|
+
notOpened ? /*#__PURE__*/ _jsx(Alert, {
|
|
205
|
+
severity: "warning",
|
|
206
|
+
children: copy.notOpened
|
|
207
|
+
}) : null
|
|
208
|
+
]
|
|
209
|
+
})
|
|
210
|
+
}),
|
|
211
|
+
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
212
|
+
children: [
|
|
213
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
214
|
+
onClick: close,
|
|
215
|
+
disabled: starting,
|
|
216
|
+
children: asking ? 'Cancel' : 'Close'
|
|
217
|
+
}),
|
|
218
|
+
asking ? /*#__PURE__*/ _jsx(Button, {
|
|
219
|
+
variant: "contained",
|
|
220
|
+
onClick: ()=>void start(),
|
|
221
|
+
disabled: starting || !orgId || !brief.trim(),
|
|
222
|
+
children: copy.submit
|
|
223
|
+
}) : ready ? /*#__PURE__*/ _jsx(Button, {
|
|
224
|
+
variant: "contained",
|
|
225
|
+
onClick: apply,
|
|
226
|
+
children: copy.open
|
|
227
|
+
}) : null
|
|
228
|
+
]
|
|
229
|
+
})
|
|
230
|
+
]
|
|
231
|
+
})
|
|
232
|
+
]
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
AiDescribeOrgAutomationButton.displayName = 'AiDescribeOrgAutomationButton';
|
|
236
|
+
export default AiDescribeOrgAutomationButton;
|
|
237
|
+
|
|
238
|
+
//# sourceMappingURL=ai-describe-org-automation.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-describe-org-automation.component.tsx"],"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 type { ConsoleWidgetEntitlementProps } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { mdiCreation } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n CircularProgress,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Link,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useEffect, useState } from 'react'\nimport type { AiJobSummary } from '../model/ai-jobs.types'\nimport {\n AI_ORG_AUTOMATION_RESOURCE,\n aiOrgAutomationInputs,\n readAiOrgAutomationProposal,\n type AiOrgAutomationProposal,\n} from '../model/ai-workflow-job'\nimport type { ConsoleOrgAutomationsZoneProps } from './ai-automation-zones'\nimport { openAiJobs } from './ai-jobs-store'\nimport { AiUpsellButton } from './ai-upsell-dialog.component'\nimport { aiJobProblem, useAiJobRun } from './use-ai-job-run'\n\n/**\n * \"Create with AI\" on the workspace's Org automations (AGL-3603), in that\n * section's card header through the `orgAutomations` zone: a description\n * becomes a `workflow` job drafting one of the WORKSPACE's automations, held\n * to the triggers and steps the zone says an org automation may use.\n *\n * Nothing is written. The job's proposal opens in the section's editor as a\n * new automation, unsaved and switched off; the person picks the sites it\n * runs on and saves it with the editor's own Save, through the section's\n * route — or closes the editor, and nothing changes.\n */\n\nconst BRIEF_MAX_CHARS = 4_000\n\nexport const AI_ORG_AUTOMATION_COPY = {\n create: 'Create with AI',\n title: 'Describe an org automation',\n label: 'What should happen, and when?',\n placeholder:\n 'When someone books on any of our sites, make them a contact, tag them booked and send them a welcome email',\n next:\n 'It is drafted from what an org automation can start on and do, and opens in the editor switched off, where you choose its sites and save it. Lists, campaigns or datasets your workspace does not have are left for you to pick.',\n submit: 'Draft the automation',\n running: 'Drafting it. This can take a few minutes.',\n ready: 'Drafted',\n open: 'Open in the editor',\n notOpened: 'It could not be opened in the editor. Check the page for why, then try again.',\n failed: 'The automation could not be drafted. Try again.',\n} as const\n\n/** The proposal a finished job wrote, with what to decide, or `null`. */\nfunction proposalOf(job: AiJobSummary | null): { automation: AiOrgAutomationProposal; label: string; note: string | null } | null {\n if (job?.status !== 'done') return null\n const output = job.outputs.find((one) => one.resource === AI_ORG_AUTOMATION_RESOURCE)\n const automation = readAiOrgAutomationProposal(output?.proposal)\n return automation && output ? { automation, label: output.label, note: output.note ?? null } : null\n}\n\nexport function AiDescribeOrgAutomationButton({\n orgId,\n triggers,\n steps,\n propose,\n entitled,\n upgrade,\n}: ConsoleOrgAutomationsZoneProps & ConsoleWidgetEntitlementProps) {\n const copy = AI_ORG_AUTOMATION_COPY\n const help = pluginDocsHelp('aiAutomations', { anchor: '#org-automations' })\n const { data: user } = useUser()\n const run = useAiJobRun(user, copy.failed)\n const { job, starting, running, notice, reset } = run\n const [open, setOpen] = useState(false)\n const [brief, setBrief] = useState('')\n const [notOpened, setNotOpened] = useState(false)\n\n // Opening or closing starts over and stops following: a job still drafting\n // carries on in AI jobs.\n useEffect(() => {\n reset()\n setNotOpened(false)\n }, [open, reset])\n\n // Drawn from the shell's gates alone (AGL-3601): nothing asks a server\n // until it is used, and a plan without the add-on gets the add-on's dialog.\n if (entitled === false) return upgrade ? <AiUpsellButton kind=\"workflow\" upgrade={upgrade} /> : null\n const ready = proposalOf(job)\n const problem = aiJobProblem(job, copy.failed) ?? (job?.status === 'done' && !ready ? copy.failed : null)\n const asking = !job || Boolean(notice)\n const close = () => setOpen(false)\n\n const start = async () => {\n const trimmed = brief.trim()\n if (!orgId || !trimmed) return\n setNotOpened(false)\n const inputs = aiOrgAutomationInputs({ triggers, steps })\n if (await run.start({ orgId, hostId: null, kind: 'workflow', brief: trimmed, inputs })) setBrief('')\n }\n const apply = () => {\n if (!ready) return\n if (propose(ready.automation)) close()\n else setNotOpened(true)\n }\n\n return (\n <>\n <Button size=\"small\" variant=\"outlined\" startIcon={<MdiIcon path={mdiCreation.path} />} onClick={() => setOpen(true)}>\n {copy.create}\n </Button>\n <Dialog open={open} onClose={starting ? undefined : close} fullWidth maxWidth=\"sm\">\n <DialogTitle>{copy.title}</DialogTitle>\n <DialogContent>\n {asking ? (\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n label={copy.label}\n placeholder={copy.placeholder}\n multiline\n minRows={4}\n value={brief}\n onChange={(event) => setBrief(event.target.value.slice(0, BRIEF_MAX_CHARS))}\n helperText={`${brief.length.toLocaleString('en-US')} / ${BRIEF_MAX_CHARS.toLocaleString('en-US')}`}\n disabled={starting}\n autoFocus\n />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {copy.next}{' '}\n <Link href={help.href} target=\"_blank\" rel=\"noopener\" title={help.excerpt}>\n {'How it works'}\n </Link>\n </Typography>\n {notice ? <Alert severity=\"warning\">{notice}</Alert> : null}\n </Stack>\n ) : (\n <Stack spacing={2} sx={{ pt: 1 }}>\n {running && job ? (\n <Alert\n severity=\"info\"\n icon={<CircularProgress size={18} aria-label=\"Drafting\" />}\n action={\n <Button\n color=\"inherit\"\n size=\"small\"\n variant=\"outlined\"\n onClick={() => {\n openAiJobs({ jobId: job.id })\n close()\n }}\n >\n {'Open AI jobs'}\n </Button>\n }\n >\n {copy.running}\n </Alert>\n ) : null}\n {ready ? (\n <Alert severity=\"success\">\n <Typography variant=\"body2\" sx={{ fontWeight: 600 }}>\n {`${copy.ready}: ${ready.label}`}\n </Typography>\n {ready.note ? <Typography variant=\"body2\">{ready.note}</Typography> : null}\n </Alert>\n ) : null}\n {problem ? <Alert severity={job?.status === 'failed' ? 'error' : 'warning'}>{problem}</Alert> : null}\n {notOpened ? <Alert severity=\"warning\">{copy.notOpened}</Alert> : null}\n </Stack>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={close} disabled={starting}>\n {asking ? 'Cancel' : 'Close'}\n </Button>\n {asking ? (\n <Button variant=\"contained\" onClick={() => void start()} disabled={starting || !orgId || !brief.trim()}>\n {copy.submit}\n </Button>\n ) : ready ? (\n <Button variant=\"contained\" onClick={apply}>\n {copy.open}\n </Button>\n ) : null}\n </DialogActions>\n </Dialog>\n </>\n )\n}\nAiDescribeOrgAutomationButton.displayName = 'AiDescribeOrgAutomationButton'\n\nexport default AiDescribeOrgAutomationButton\n"],"names":["pluginDocsHelp","mdiCreation","MdiIcon","useUser","Alert","Button","CircularProgress","Dialog","DialogActions","DialogContent","DialogTitle","Link","Stack","TextField","Typography","useEffect","useState","AI_ORG_AUTOMATION_RESOURCE","aiOrgAutomationInputs","readAiOrgAutomationProposal","openAiJobs","AiUpsellButton","aiJobProblem","useAiJobRun","BRIEF_MAX_CHARS","AI_ORG_AUTOMATION_COPY","create","title","label","placeholder","next","submit","running","ready","open","notOpened","failed","proposalOf","job","output","status","outputs","find","one","resource","automation","proposal","note","AiDescribeOrgAutomationButton","orgId","triggers","steps","propose","entitled","upgrade","copy","help","anchor","data","user","run","starting","notice","reset","setOpen","brief","setBrief","setNotOpened","kind","problem","asking","Boolean","close","start","trimmed","trim","inputs","hostId","apply","size","variant","startIcon","path","onClick","onClose","undefined","fullWidth","maxWidth","spacing","sx","pt","multiline","minRows","value","onChange","event","target","slice","helperText","length","toLocaleString","disabled","autoFocus","color","href","rel","excerpt","severity","icon","aria-label","action","jobId","id","fontWeight","displayName"],"mappings":"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"}
|
|
@@ -6,6 +6,8 @@ export interface AiExperimentZoneVariant {
|
|
|
6
6
|
name: string;
|
|
7
7
|
subject: string;
|
|
8
8
|
body: string;
|
|
9
|
+
/** The screen version a page or section variant pins; empty for the published one. */
|
|
10
|
+
versionId?: string;
|
|
9
11
|
}
|
|
10
12
|
/** What the variants zone hands this widget. */
|
|
11
13
|
export interface AiExperimentVariantsCardProps {
|
|
@@ -14,6 +16,10 @@ export interface AiExperimentVariantsCardProps {
|
|
|
14
16
|
name: string;
|
|
15
17
|
target: AiExperimentTarget;
|
|
16
18
|
goal: string;
|
|
19
|
+
/** A page or section test's page; empty until one is picked (AGL-3603). */
|
|
20
|
+
screenId?: string;
|
|
21
|
+
/** A section test's element; empty until one is picked. */
|
|
22
|
+
nodeId?: string;
|
|
17
23
|
variants: AiExperimentZoneVariant[];
|
|
18
24
|
proposeVariants: (variants: readonly AiExperimentZoneVariant[], key: string) => void;
|
|
19
25
|
}
|
|
@@ -36,7 +42,9 @@ export declare function aiExperimentSubjectFrom(target: AiExperimentTarget, vari
|
|
|
36
42
|
* body, and a screen or a section varies a screen version, so there only the
|
|
37
43
|
* name is filled and the copy is read on the card.
|
|
38
44
|
*/
|
|
39
|
-
export declare function aiExperimentVariantDrafts(target: AiExperimentTarget, variants: readonly AiExperimentZoneVariant[], proposal: AiExperimentVariantsProposalView
|
|
45
|
+
export declare function aiExperimentVariantDrafts(target: AiExperimentTarget, variants: readonly AiExperimentZoneVariant[], proposal: AiExperimentVariantsProposalView,
|
|
46
|
+
/** Draft versions made for a page or section test (AGL-3603), by the proposal's index. */
|
|
47
|
+
versions?: ReadonlyMap<number, string>): AiExperimentZoneVariant[];
|
|
40
48
|
/** Where a proposed variant's copy lands, said before the person presses the button. */
|
|
41
49
|
export declare function aiExperimentApplyCopy(target: AiExperimentTarget): string;
|
|
42
50
|
/**
|
|
@@ -17,13 +17,14 @@
|
|
|
17
17
|
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
18
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
19
|
import { pluginDocsHelp } from "@aglyn/aglyn/app-utils/docs-help";
|
|
20
|
+
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
20
21
|
import { ScrollTable } from "@aglyn/shared-ui-jsx/components/scroll-table.component";
|
|
21
22
|
import { useHostOrgId, useUser } from "@aglyn/tenant-feature-instance";
|
|
22
23
|
import { Alert, Box, Button, Chip, CircularProgress, Link, Stack, TableBody, TableCell, TableHead, TableRow, TextField, Typography } from "@mui/material";
|
|
23
24
|
import { useEffect, useMemo, useState } from "react";
|
|
24
25
|
import { AI_EXPERIMENT_SUBJECT_MAX_CHARS } from "../model/ai-experiment.js";
|
|
25
26
|
import { aiExperimentArmIsNamed, aiExperimentVerdictDisplay, readAiExperimentExplanation, readAiExperimentVariants } from "../model/ai-experiment-proposal.js";
|
|
26
|
-
import { aiJobProblem, useAiJobRun
|
|
27
|
+
import { aiJobProblem, useAiJobRun } from "./use-ai-job-run.js";
|
|
27
28
|
/**
|
|
28
29
|
* A/B tests by AI in the console (AGL-2914): the two doors a person reaches
|
|
29
30
|
* the `experiment` job through, and the surfaces that render what it answers.
|
|
@@ -84,28 +85,32 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
|
|
|
84
85
|
* that target has a place for are filled: an email varies its subject and
|
|
85
86
|
* body, and a screen or a section varies a screen version, so there only the
|
|
86
87
|
* name is filled and the copy is read on the card.
|
|
87
|
-
*/ export function aiExperimentVariantDrafts(target, variants, proposal) {
|
|
88
|
+
*/ export function aiExperimentVariantDrafts(target, variants, proposal, /** Draft versions made for a page or section test (AGL-3603), by the proposal's index. */ versions = new Map()) {
|
|
88
89
|
return variants.map((variant, index)=>{
|
|
89
90
|
const proposed = proposal.variants[index];
|
|
90
91
|
if (!proposed) return variant;
|
|
91
|
-
|
|
92
|
+
const versionId = target === 'email' ? undefined : versions.get(index);
|
|
93
|
+
return _extends({
|
|
92
94
|
id: variant.id,
|
|
93
95
|
name: proposed.name,
|
|
94
96
|
subject: target === 'email' ? proposed.subject : '',
|
|
95
97
|
body: target === 'email' ? proposed.body : ''
|
|
96
|
-
}
|
|
98
|
+
}, versionId ? {
|
|
99
|
+
versionId
|
|
100
|
+
} : {});
|
|
97
101
|
});
|
|
98
102
|
}
|
|
99
103
|
/** Where a proposed variant's copy lands, said before the person presses the button. */ export function aiExperimentApplyCopy(target) {
|
|
100
|
-
return target === 'email' ? 'Each variant above takes its name, subject and body. Nothing is saved until you save the experiment.' : 'Each variant above takes its name.
|
|
104
|
+
return target === 'email' ? 'Each variant above takes its name, subject and body. Nothing is saved until you save the experiment.' : 'Each variant above takes its name. Make draft versions to put each variant’s copy into a new unpublished version of the page, pinned to its variant; the first stays on the published page as the control.';
|
|
101
105
|
}
|
|
106
|
+
const VERSIONS_FAILED_COPY = 'The draft versions could not be made. Try again.';
|
|
102
107
|
/**
|
|
103
108
|
* "Write variants with AI", in the experiment editor beneath the variants it
|
|
104
109
|
* writes for. It proposes COPY: no weight, no traffic split, no goal and no
|
|
105
110
|
* schedule, and the first variant it writes is the copy as it stands so the
|
|
106
111
|
* test has something to measure against.
|
|
107
112
|
*/ export function AiExperimentVariantsCard(props) {
|
|
108
|
-
var _useHostOrgId, _aiJobProblem;
|
|
113
|
+
var _useHostOrgId, _aiJobProblem, _props_screenId, _props_nodeId;
|
|
109
114
|
var _run_job, _run_job1, _run_job2, _run_job3;
|
|
110
115
|
const { hostId, target, variants, proposeVariants } = props;
|
|
111
116
|
// The zone hands the SITE, which is what the card it is drawn in knows. The
|
|
@@ -113,7 +118,6 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
|
|
|
113
118
|
// plugin's zone resolves it.
|
|
114
119
|
const orgId = (_useHostOrgId = useHostOrgId(hostId)) != null ? _useHostOrgId : undefined;
|
|
115
120
|
const { data: user } = useUser();
|
|
116
|
-
const verdict = useAiJobsVerdict(user, orgId);
|
|
117
121
|
const run = useAiJobRun(user, VARIANTS_FAILED_COPY);
|
|
118
122
|
const prefill = useMemo(()=>aiExperimentSubjectFrom(target, variants), [
|
|
119
123
|
target,
|
|
@@ -121,6 +125,8 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
|
|
|
121
125
|
]);
|
|
122
126
|
const [subject, setSubject] = useState(prefill);
|
|
123
127
|
const [applied, setApplied] = useState(null);
|
|
128
|
+
const [versioning, setVersioning] = useState(false);
|
|
129
|
+
const [versionsNote, setVersionsNote] = useState(null);
|
|
124
130
|
// The control's copy follows the editor until the person edits this field,
|
|
125
131
|
// so switching a draft test from a page to an email fills it rather than
|
|
126
132
|
// leaving the earlier target's copy under a question about a new one.
|
|
@@ -135,7 +141,6 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
|
|
|
135
141
|
run.job
|
|
136
142
|
]);
|
|
137
143
|
const problem = (_aiJobProblem = aiJobProblem(run.job, VARIANTS_FAILED_COPY)) != null ? _aiJobProblem : ((_run_job = run.job) == null ? void 0 : _run_job.status) === 'done' && !proposal ? VARIANTS_FAILED_COPY : null;
|
|
138
|
-
if (verdict !== 'ready') return null;
|
|
139
144
|
const busy = run.starting || run.running;
|
|
140
145
|
const noun = TARGET_NOUN[target];
|
|
141
146
|
const variantsHelp = pluginDocsHelp('aiExperiments', {
|
|
@@ -165,6 +170,67 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
|
|
|
165
170
|
proposeVariants(aiExperimentVariantDrafts(target, variants, proposal), run.job.id);
|
|
166
171
|
setApplied(run.job.id);
|
|
167
172
|
};
|
|
173
|
+
/*
|
|
174
|
+
* A page or a section varies a VERSION of the page (AGL-3603): the door
|
|
175
|
+
* copies the published version once per variant past the control, puts
|
|
176
|
+
* the variant's copy into it, and stores it unpublished; the versions are
|
|
177
|
+
* then pinned to the variants here as unsaved edits.
|
|
178
|
+
*/ const screenId = (_props_screenId = props.screenId) != null ? _props_screenId : '';
|
|
179
|
+
const nodeId = (_props_nodeId = props.nodeId) != null ? _props_nodeId : '';
|
|
180
|
+
const versionsBlocked = target === 'email' ? null : !screenId ? 'Pick the page under test above to make draft versions.' : target === 'section' && !nodeId ? 'Pick the section under test above to make draft versions.' : null;
|
|
181
|
+
const makeVersions = async ()=>{
|
|
182
|
+
if (!proposal || !run.job || !orgId || versionsBlocked) return;
|
|
183
|
+
const jobId = run.job.id;
|
|
184
|
+
setVersioning(true);
|
|
185
|
+
setVersionsNote(null);
|
|
186
|
+
try {
|
|
187
|
+
var _ref, _answer_versions, _answer_versions1, _answer_skipped;
|
|
188
|
+
const response = await authorizedFetch(user, '/api/ai/experiments/versions', {
|
|
189
|
+
method: 'POST',
|
|
190
|
+
headers: {
|
|
191
|
+
'Content-Type': 'application/json'
|
|
192
|
+
},
|
|
193
|
+
body: JSON.stringify(_extends({
|
|
194
|
+
orgId,
|
|
195
|
+
hostId,
|
|
196
|
+
jobId,
|
|
197
|
+
screenId
|
|
198
|
+
}, nodeId ? {
|
|
199
|
+
nodeId
|
|
200
|
+
} : {}))
|
|
201
|
+
});
|
|
202
|
+
const answer = (_ref = await response.json().catch(()=>null)) != null ? _ref : {};
|
|
203
|
+
if (!response.ok) {
|
|
204
|
+
setVersionsNote({
|
|
205
|
+
ok: false,
|
|
206
|
+
text: answer.error || VERSIONS_FAILED_COPY
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const made = new Map(((_answer_versions = answer.versions) != null ? _answer_versions : []).map((entry)=>[
|
|
211
|
+
entry.index,
|
|
212
|
+
entry.versionId
|
|
213
|
+
]));
|
|
214
|
+
proposeVariants(aiExperimentVariantDrafts(target, variants, proposal, made), jobId);
|
|
215
|
+
setApplied(jobId);
|
|
216
|
+
const names = ((_answer_versions1 = answer.versions) != null ? _answer_versions1 : []).map((entry)=>entry.name);
|
|
217
|
+
const skipped = (_answer_skipped = answer.skipped) != null ? _answer_skipped : [];
|
|
218
|
+
setVersionsNote({
|
|
219
|
+
ok: names.length > 0,
|
|
220
|
+
text: [
|
|
221
|
+
names.length ? `Draft versions made and pinned above: ${names.join(', ')}. Open each in the editor to check it, then Save the experiment. Nothing is published.` : 'No draft version could be made.',
|
|
222
|
+
...skipped.map((entry)=>`Variant ${entry.index + 1}: ${entry.reason}`)
|
|
223
|
+
].join(' ')
|
|
224
|
+
});
|
|
225
|
+
} catch (unused) {
|
|
226
|
+
setVersionsNote({
|
|
227
|
+
ok: false,
|
|
228
|
+
text: VERSIONS_FAILED_COPY
|
|
229
|
+
});
|
|
230
|
+
} finally{
|
|
231
|
+
setVersioning(false);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
168
234
|
return /*#__PURE__*/ _jsx(Box, {
|
|
169
235
|
sx: {
|
|
170
236
|
border: 1,
|
|
@@ -298,17 +364,39 @@ const liftText = (value)=>value === null ? '—' : `${value >= 0 ? '+' : ''}${va
|
|
|
298
364
|
color: "text.secondary",
|
|
299
365
|
children: aiExperimentApplyCopy(target)
|
|
300
366
|
}),
|
|
301
|
-
/*#__PURE__*/
|
|
367
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
302
368
|
direction: "row",
|
|
303
369
|
spacing: 1,
|
|
304
|
-
children:
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
370
|
+
children: [
|
|
371
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
372
|
+
size: "small",
|
|
373
|
+
variant: "contained",
|
|
374
|
+
disabled: applied === ((_run_job2 = run.job) == null ? void 0 : _run_job2.id),
|
|
375
|
+
onClick: apply,
|
|
376
|
+
children: 'Put into the variants'
|
|
377
|
+
}),
|
|
378
|
+
target === 'email' ? null : /*#__PURE__*/ _jsx(Button, {
|
|
379
|
+
size: "small",
|
|
380
|
+
variant: "outlined",
|
|
381
|
+
disabled: versioning || Boolean(versionsBlocked),
|
|
382
|
+
onClick: ()=>void makeVersions(),
|
|
383
|
+
children: 'Make draft versions'
|
|
384
|
+
}),
|
|
385
|
+
versioning ? /*#__PURE__*/ _jsx(CircularProgress, {
|
|
386
|
+
size: 16,
|
|
387
|
+
"aria-label": "Making draft versions"
|
|
388
|
+
}) : null
|
|
389
|
+
]
|
|
311
390
|
}),
|
|
391
|
+
versionsBlocked && target !== 'email' ? /*#__PURE__*/ _jsx(Typography, {
|
|
392
|
+
variant: "caption",
|
|
393
|
+
color: "text.secondary",
|
|
394
|
+
children: versionsBlocked
|
|
395
|
+
}) : null,
|
|
396
|
+
versionsNote ? /*#__PURE__*/ _jsx(Alert, {
|
|
397
|
+
severity: versionsNote.ok ? 'success' : 'warning',
|
|
398
|
+
children: versionsNote.text
|
|
399
|
+
}) : null,
|
|
312
400
|
applied === ((_run_job3 = run.job) == null ? void 0 : _run_job3.id) ? /*#__PURE__*/ _jsx(Alert, {
|
|
313
401
|
severity: "success",
|
|
314
402
|
children: 'In the variants above. Review them, then Save the experiment — or Cancel to leave it as it was.'
|
|
@@ -464,13 +552,11 @@ AiExperimentExplanation.displayName = 'AiExperimentExplanation';
|
|
|
464
552
|
const { hostId, test } = props;
|
|
465
553
|
const orgId = (_useHostOrgId = useHostOrgId(hostId)) != null ? _useHostOrgId : undefined;
|
|
466
554
|
const { data: user } = useUser();
|
|
467
|
-
const verdict = useAiJobsVerdict(user, orgId);
|
|
468
555
|
const run = useAiJobRun(user, EXPLAIN_FAILED_COPY);
|
|
469
556
|
const explanation = useMemo(()=>readAiExperimentExplanation(proposalOf(run.job)), [
|
|
470
557
|
run.job
|
|
471
558
|
]);
|
|
472
559
|
const problem = (_aiJobProblem = aiJobProblem(run.job, EXPLAIN_FAILED_COPY)) != null ? _aiJobProblem : ((_run_job = run.job) == null ? void 0 : _run_job.status) === 'done' && !explanation ? EXPLAIN_FAILED_COPY : null;
|
|
473
|
-
if (verdict !== 'ready') return null;
|
|
474
560
|
const busy = run.starting || run.running;
|
|
475
561
|
const resultHelp = pluginDocsHelp('aiExperiments', {
|
|
476
562
|
anchor: '#the-verdict',
|