@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,73 @@
|
|
|
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 AiJobItemLedger, type AiJobSummary } from './ai-jobs.types';
|
|
18
|
+
/**
|
|
19
|
+
* What a `build` job shows of each item (AGL-3616), wherever it is shown —
|
|
20
|
+
* the AI jobs drawer, the job's own page, the chat card: the item, where it
|
|
21
|
+
* stands, what it cost, and what became of its credits when it failed.
|
|
22
|
+
*
|
|
23
|
+
* Pure: no React, no request.
|
|
24
|
+
*/
|
|
25
|
+
/** Where one item stands, as a row's icon reads it. */
|
|
26
|
+
export type AiBuildItemRowState = 'done' | 'active' | 'waiting' | 'failed' | 'skipped';
|
|
27
|
+
export interface AiBuildItemRow {
|
|
28
|
+
slot: string;
|
|
29
|
+
/** "Page: About", "Form: Contact". */
|
|
30
|
+
label: string;
|
|
31
|
+
state: AiBuildItemRowState;
|
|
32
|
+
/** What the person should know: the failure, the note, what was given back. */
|
|
33
|
+
detail: string | null;
|
|
34
|
+
/** When the active item started, for the elapsed time beside it; absent on every other row. */
|
|
35
|
+
startedAt?: string | null;
|
|
36
|
+
}
|
|
37
|
+
/** What an operation is called at the start of a row: its own noun, or the op spelled as words. */
|
|
38
|
+
export declare function aiBuildOpNoun(op: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* What became of a failed item's credits (AGL-3616), in the words every
|
|
41
|
+
* surface uses for a failure on our side: "This one’s on us — you weren’t
|
|
42
|
+
* charged." A failure that was not ours — the model declining, a site at its
|
|
43
|
+
* allowance — says what it used, which was charged. `null` for an item that
|
|
44
|
+
* did not fail.
|
|
45
|
+
*/
|
|
46
|
+
export declare function aiBuildItemRefundCopy(row: Pick<AiJobItemLedger, 'status' | 'failure' | 'creditsRefunded' | 'creditsSpent'>): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* The item the build is on (AGL-3596): the one its ledger marks running, else
|
|
49
|
+
* — while the job moves — the first still pending, which is the one its runner
|
|
50
|
+
* builds next. The runner settles an item in the write that records its pass,
|
|
51
|
+
* so the item it is writing reads `pending` until it is done; read as such,
|
|
52
|
+
* every row waited and the build looked stalled. `null` when the job is not
|
|
53
|
+
* moving or nothing is left.
|
|
54
|
+
*/
|
|
55
|
+
export declare function aiBuildActiveSlot(job: Pick<AiJobSummary, 'items'> & Partial<Pick<AiJobSummary, 'status'>>): string | null;
|
|
56
|
+
/**
|
|
57
|
+
* When the active item started: when the last item before it settled, which
|
|
58
|
+
* the ledger records, else when the build step started — the first item's
|
|
59
|
+
* start, and the best a ledger written before settling was recorded has.
|
|
60
|
+
*/
|
|
61
|
+
export declare function aiBuildActiveStartedAt(job: Pick<AiJobSummary, 'items'> & Partial<Pick<AiJobSummary, 'steps'>>): string | null;
|
|
62
|
+
/** One row an item, in the order the build planned them; the item it is on is the active one. */
|
|
63
|
+
export declare function aiBuildItemRows(job: Pick<AiJobSummary, 'items'> & Partial<Pick<AiJobSummary, 'status' | 'steps'>>): AiBuildItemRow[];
|
|
64
|
+
/** How a build came out, in one line: "4 of 5 built; 1 failed." `null` while it runs. */
|
|
65
|
+
export declare function aiBuildOutcomeLine(job: Pick<AiJobSummary, 'items' | 'status'>): string | null;
|
|
66
|
+
/** Whether a finished build — or a site that built part of itself — has failed items to try again. */
|
|
67
|
+
export declare function aiBuildCanRetry(job: Pick<AiJobSummary, 'kind' | 'status' | 'items'>): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* What a guided start that built part of its site says (AGL-3616), in the
|
|
70
|
+
* words every surface uses: "Built 1 of 2 pages. Home couldn’t be built —
|
|
71
|
+
* that one’s on us…". `null` when every page was built, or none was.
|
|
72
|
+
*/
|
|
73
|
+
export declare function aiSitePartialCopy(job: Pick<AiJobSummary, 'items' | 'status'>): string | null;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ import { aiCustomerSafeItem } from "./ai-job-failure-copy.js";
|
|
18
|
+
import { AI_JOB_PLAN_STEP } from "./ai-jobs.types.js";
|
|
19
|
+
const OP_NOUNS = {
|
|
20
|
+
page: 'Page',
|
|
21
|
+
layout: 'Layout',
|
|
22
|
+
form: 'Form',
|
|
23
|
+
component: 'Component',
|
|
24
|
+
email: 'Email design',
|
|
25
|
+
template: 'Page template',
|
|
26
|
+
campaign: 'Email campaign',
|
|
27
|
+
workflow: 'Automation'
|
|
28
|
+
};
|
|
29
|
+
/** What an operation is called at the start of a row: its own noun, or the op spelled as words. */ export function aiBuildOpNoun(op) {
|
|
30
|
+
const known = OP_NOUNS[op];
|
|
31
|
+
if (known) return known;
|
|
32
|
+
const words = op.replace(/[-_]+/g, ' ').trim();
|
|
33
|
+
return words ? `${words[0].toUpperCase()}${words.slice(1)}` : 'Item';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* What became of a failed item's credits (AGL-3616), in the words every
|
|
37
|
+
* surface uses for a failure on our side: "This one’s on us — you weren’t
|
|
38
|
+
* charged." A failure that was not ours — the model declining, a site at its
|
|
39
|
+
* allowance — says what it used, which was charged. `null` for an item that
|
|
40
|
+
* did not fail.
|
|
41
|
+
*/ export function aiBuildItemRefundCopy(row) {
|
|
42
|
+
var _row_creditsSpent;
|
|
43
|
+
var _row_failure;
|
|
44
|
+
if (row.status !== 'failed') return null;
|
|
45
|
+
if ((_row_failure = row.failure) == null ? void 0 : _row_failure.ours) {
|
|
46
|
+
var _row_creditsRefunded;
|
|
47
|
+
const refunded = Math.max(0, Math.floor((_row_creditsRefunded = row.creditsRefunded) != null ? _row_creditsRefunded : 0));
|
|
48
|
+
if (refunded > 0) {
|
|
49
|
+
return `This one’s on us — you weren’t charged. The ${refunded} ${refunded === 1 ? 'credit' : 'credits'} it used ${refunded === 1 ? 'is' : 'are'} back in your AI credits.`;
|
|
50
|
+
}
|
|
51
|
+
return 'This one’s on us — you weren’t charged.';
|
|
52
|
+
}
|
|
53
|
+
const spent = Math.max(0, Math.floor((_row_creditsSpent = row.creditsSpent) != null ? _row_creditsSpent : 0));
|
|
54
|
+
return spent > 0 ? `It used ${spent} ${spent === 1 ? 'credit' : 'credits'}.` : null;
|
|
55
|
+
}
|
|
56
|
+
const STATES = {
|
|
57
|
+
pending: 'waiting',
|
|
58
|
+
running: 'active',
|
|
59
|
+
succeeded: 'done',
|
|
60
|
+
degraded: 'done',
|
|
61
|
+
failed: 'failed',
|
|
62
|
+
skipped: 'skipped'
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* The item the build is on (AGL-3596): the one its ledger marks running, else
|
|
66
|
+
* — while the job moves — the first still pending, which is the one its runner
|
|
67
|
+
* builds next. The runner settles an item in the write that records its pass,
|
|
68
|
+
* so the item it is writing reads `pending` until it is done; read as such,
|
|
69
|
+
* every row waited and the build looked stalled. `null` when the job is not
|
|
70
|
+
* moving or nothing is left.
|
|
71
|
+
*/ export function aiBuildActiveSlot(job) {
|
|
72
|
+
var _job_items, _ref;
|
|
73
|
+
var _items_find;
|
|
74
|
+
const items = (_job_items = job.items) != null ? _job_items : [];
|
|
75
|
+
const running = items.find((row)=>row.status === 'running');
|
|
76
|
+
if (running) return running.slot;
|
|
77
|
+
if (job.status !== 'queued' && job.status !== 'running') return null;
|
|
78
|
+
return (_ref = (_items_find = items.find((row)=>row.status === 'pending')) == null ? void 0 : _items_find.slot) != null ? _ref : null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* When the active item started: when the last item before it settled, which
|
|
82
|
+
* the ledger records, else when the build step started — the first item's
|
|
83
|
+
* start, and the best a ledger written before settling was recorded has.
|
|
84
|
+
*/ export function aiBuildActiveStartedAt(job) {
|
|
85
|
+
var _job_items, _job_steps, _ref;
|
|
86
|
+
let latest = null;
|
|
87
|
+
for (const row of (_job_items = job.items) != null ? _job_items : []){
|
|
88
|
+
const at = row.settledAt ? Date.parse(row.settledAt) : NaN;
|
|
89
|
+
if (Number.isFinite(at) && (!latest || at > latest.at)) latest = {
|
|
90
|
+
at,
|
|
91
|
+
iso: row.settledAt
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (latest) return latest.iso;
|
|
95
|
+
const step = ((_job_steps = job.steps) != null ? _job_steps : []).find((one)=>one.name !== AI_JOB_PLAN_STEP && one.startedAt);
|
|
96
|
+
return (_ref = step == null ? void 0 : step.startedAt) != null ? _ref : null;
|
|
97
|
+
}
|
|
98
|
+
/** One row an item, in the order the build planned them; the item it is on is the active one. */ export function aiBuildItemRows(job) {
|
|
99
|
+
var _job_items;
|
|
100
|
+
const active = aiBuildActiveSlot(job);
|
|
101
|
+
return ((_job_items = job.items) != null ? _job_items : []).map((ledger)=>{
|
|
102
|
+
var _STATES_row_status;
|
|
103
|
+
var _row_failure;
|
|
104
|
+
// A building rule's own words never reach a customer (AGL-3596).
|
|
105
|
+
const row = aiCustomerSafeItem(ledger);
|
|
106
|
+
const parts = [];
|
|
107
|
+
if (row.status === 'failed' && ((_row_failure = row.failure) == null ? void 0 : _row_failure.message)) parts.push(row.failure.message);
|
|
108
|
+
if (row.note) parts.push(row.note);
|
|
109
|
+
const refund = aiBuildItemRefundCopy(row);
|
|
110
|
+
if (refund) parts.push(refund);
|
|
111
|
+
return _extends({
|
|
112
|
+
slot: row.slot,
|
|
113
|
+
label: `${aiBuildOpNoun(row.op)}: ${row.label}`,
|
|
114
|
+
state: row.slot === active ? 'active' : (_STATES_row_status = STATES[row.status]) != null ? _STATES_row_status : 'waiting',
|
|
115
|
+
detail: parts.length ? parts.join(' ') : null
|
|
116
|
+
}, row.slot === active ? {
|
|
117
|
+
startedAt: aiBuildActiveStartedAt(job)
|
|
118
|
+
} : {});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/** How a build came out, in one line: "4 of 5 built; 1 failed." `null` while it runs. */ export function aiBuildOutcomeLine(job) {
|
|
122
|
+
var _job_items;
|
|
123
|
+
const items = (_job_items = job.items) != null ? _job_items : [];
|
|
124
|
+
if (!items.length || job.status !== 'done' && job.status !== 'failed') return null;
|
|
125
|
+
const built = items.filter((row)=>row.status === 'succeeded' || row.status === 'degraded').length;
|
|
126
|
+
const failed = items.filter((row)=>row.status === 'failed').length;
|
|
127
|
+
const skipped = items.filter((row)=>row.status === 'skipped').length;
|
|
128
|
+
const tail = [
|
|
129
|
+
failed ? `${failed} failed` : '',
|
|
130
|
+
skipped ? `${skipped} not built` : ''
|
|
131
|
+
].filter(Boolean);
|
|
132
|
+
return `${built} of ${items.length} built${tail.length ? `; ${tail.join(', ')}` : ''}.`;
|
|
133
|
+
}
|
|
134
|
+
/** Whether a finished build — or a site that built part of itself — has failed items to try again. */ export function aiBuildCanRetry(job) {
|
|
135
|
+
var _job_items;
|
|
136
|
+
// A site that built nothing starts over from its own answers instead.
|
|
137
|
+
const finished = job.kind === 'build' ? job.status === 'done' || job.status === 'failed' : job.kind === 'site' && job.status === 'done';
|
|
138
|
+
return finished && ((_job_items = job.items) != null ? _job_items : []).some((row)=>{
|
|
139
|
+
var _row_degradedBy;
|
|
140
|
+
return row.status === 'failed' || row.status === 'skipped' && !((_row_degradedBy = row.degradedBy) == null ? void 0 : _row_degradedBy.length);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* What a guided start that built part of its site says (AGL-3616), in the
|
|
145
|
+
* words every surface uses: "Built 1 of 2 pages. Home couldn’t be built —
|
|
146
|
+
* that one’s on us…". `null` when every page was built, or none was.
|
|
147
|
+
*/ export function aiSitePartialCopy(job) {
|
|
148
|
+
var _job_items, _job_items1;
|
|
149
|
+
const pages = ((_job_items = job.items) != null ? _job_items : []).filter((row)=>row.op === 'page');
|
|
150
|
+
const built = pages.filter((row)=>row.status === 'succeeded' || row.status === 'degraded');
|
|
151
|
+
const unbuilt = ((_job_items1 = job.items) != null ? _job_items1 : []).filter((row)=>row.status === 'failed' || row.status === 'skipped');
|
|
152
|
+
if (job.status !== 'done' || !unbuilt.length || !built.length) return null;
|
|
153
|
+
const names = unbuilt.map((row)=>row.op === 'page' ? row.label : `The ${aiBuildOpNoun(row.op).toLowerCase()} “${row.label}”`);
|
|
154
|
+
const list = names.length === 1 ? names[0] : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`;
|
|
155
|
+
const refunded = unbuilt.reduce((total, row)=>{
|
|
156
|
+
var _row_creditsRefunded;
|
|
157
|
+
return total + Math.max(0, Math.floor((_row_creditsRefunded = row.creditsRefunded) != null ? _row_creditsRefunded : 0));
|
|
158
|
+
}, 0);
|
|
159
|
+
const back = refunded > 0 ? ` The ${refunded} ${refunded === 1 ? 'credit' : 'credits'} it used ${refunded === 1 ? 'is' : 'are'} back in your AI credits.` : '';
|
|
160
|
+
// Only a failure on our side says so; a part the AI declined or an allowance
|
|
161
|
+
// stopped was charged for what it used, and the row says that.
|
|
162
|
+
const ours = unbuilt.every((row)=>{
|
|
163
|
+
var _row_failure;
|
|
164
|
+
return row.status === 'skipped' || ((_row_failure = row.failure) == null ? void 0 : _row_failure.ours) === true;
|
|
165
|
+
});
|
|
166
|
+
const why = ours ? ` — that one’s on us, you weren’t charged for ${unbuilt.length === 1 ? 'it' : 'them'}.` : '.';
|
|
167
|
+
return `Built ${built.length} of ${pages.length} ${pages.length === 1 ? 'page' : 'pages'}. ${list} couldn’t be built${why}${back} Try again builds only what failed.`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//# sourceMappingURL=ai-build-progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/model/ai-build-progress.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { aiCustomerSafeItem } from './ai-job-failure-copy'\nimport { AI_JOB_PLAN_STEP, type AiJobItemLedger, type AiJobSummary } from './ai-jobs.types'\n\n/**\n * What a `build` job shows of each item (AGL-3616), wherever it is shown —\n * the AI jobs drawer, the job's own page, the chat card: the item, where it\n * stands, what it cost, and what became of its credits when it failed.\n *\n * Pure: no React, no request.\n */\n\n/** Where one item stands, as a row's icon reads it. */\nexport type AiBuildItemRowState = 'done' | 'active' | 'waiting' | 'failed' | 'skipped'\n\nexport interface AiBuildItemRow {\n slot: string\n /** \"Page: About\", \"Form: Contact\". */\n label: string\n state: AiBuildItemRowState\n /** What the person should know: the failure, the note, what was given back. */\n detail: string | null\n /** When the active item started, for the elapsed time beside it; absent on every other row. */\n startedAt?: string | null\n}\n\nconst OP_NOUNS: Readonly<Record<string, string>> = {\n page: 'Page',\n layout: 'Layout',\n form: 'Form',\n component: 'Component',\n email: 'Email design',\n template: 'Page template',\n campaign: 'Email campaign',\n workflow: 'Automation',\n}\n\n/** What an operation is called at the start of a row: its own noun, or the op spelled as words. */\nexport function aiBuildOpNoun(op: string): string {\n const known = OP_NOUNS[op]\n if (known) return known\n const words = op.replace(/[-_]+/g, ' ').trim()\n return words ? `${words[0].toUpperCase()}${words.slice(1)}` : 'Item'\n}\n\n/**\n * What became of a failed item's credits (AGL-3616), in the words every\n * surface uses for a failure on our side: \"This one’s on us — you weren’t\n * charged.\" A failure that was not ours — the model declining, a site at its\n * allowance — says what it used, which was charged. `null` for an item that\n * did not fail.\n */\nexport function aiBuildItemRefundCopy(\n row: Pick<AiJobItemLedger, 'status' | 'failure' | 'creditsRefunded' | 'creditsSpent'>,\n): string | null {\n if (row.status !== 'failed') return null\n if (row.failure?.ours) {\n const refunded = Math.max(0, Math.floor(row.creditsRefunded ?? 0))\n if (refunded > 0) {\n return `This one’s on us — you weren’t charged. The ${refunded} ${refunded === 1 ? 'credit' : 'credits'} it used ${refunded === 1 ? 'is' : 'are'} back in your AI credits.`\n }\n return 'This one’s on us — you weren’t charged.'\n }\n const spent = Math.max(0, Math.floor(row.creditsSpent ?? 0))\n return spent > 0 ? `It used ${spent} ${spent === 1 ? 'credit' : 'credits'}.` : null\n}\n\nconst STATES: Readonly<Record<AiJobItemLedger['status'], AiBuildItemRowState>> = {\n pending: 'waiting',\n running: 'active',\n succeeded: 'done',\n degraded: 'done',\n failed: 'failed',\n skipped: 'skipped',\n}\n\n/**\n * The item the build is on (AGL-3596): the one its ledger marks running, else\n * — while the job moves — the first still pending, which is the one its runner\n * builds next. The runner settles an item in the write that records its pass,\n * so the item it is writing reads `pending` until it is done; read as such,\n * every row waited and the build looked stalled. `null` when the job is not\n * moving or nothing is left.\n */\nexport function aiBuildActiveSlot(\n job: Pick<AiJobSummary, 'items'> & Partial<Pick<AiJobSummary, 'status'>>,\n): string | null {\n const items = job.items ?? []\n const running = items.find((row) => row.status === 'running')\n if (running) return running.slot\n if (job.status !== 'queued' && job.status !== 'running') return null\n return items.find((row) => row.status === 'pending')?.slot ?? null\n}\n\n/**\n * When the active item started: when the last item before it settled, which\n * the ledger records, else when the build step started — the first item's\n * start, and the best a ledger written before settling was recorded has.\n */\nexport function aiBuildActiveStartedAt(\n job: Pick<AiJobSummary, 'items'> & Partial<Pick<AiJobSummary, 'steps'>>,\n): string | null {\n let latest: { at: number; iso: string } | null = null\n for (const row of job.items ?? []) {\n const at = row.settledAt ? Date.parse(row.settledAt) : NaN\n if (Number.isFinite(at) && (!latest || at > latest.at)) latest = { at, iso: row.settledAt as string }\n }\n if (latest) return latest.iso\n const step = (job.steps ?? []).find((one) => one.name !== AI_JOB_PLAN_STEP && one.startedAt)\n return step?.startedAt ?? null\n}\n\n/** One row an item, in the order the build planned them; the item it is on is the active one. */\nexport function aiBuildItemRows(\n job: Pick<AiJobSummary, 'items'> & Partial<Pick<AiJobSummary, 'status' | 'steps'>>,\n): AiBuildItemRow[] {\n const active = aiBuildActiveSlot(job)\n return (job.items ?? []).map((ledger) => {\n // A building rule's own words never reach a customer (AGL-3596).\n const row = aiCustomerSafeItem(ledger)\n const parts: string[] = []\n if (row.status === 'failed' && row.failure?.message) parts.push(row.failure.message)\n if (row.note) parts.push(row.note)\n const refund = aiBuildItemRefundCopy(row)\n if (refund) parts.push(refund)\n return {\n slot: row.slot,\n label: `${aiBuildOpNoun(row.op)}: ${row.label}`,\n state: row.slot === active ? 'active' : (STATES[row.status] ?? 'waiting'),\n detail: parts.length ? parts.join(' ') : null,\n ...(row.slot === active ? { startedAt: aiBuildActiveStartedAt(job) } : {}),\n }\n })\n}\n\n/** How a build came out, in one line: \"4 of 5 built; 1 failed.\" `null` while it runs. */\nexport function aiBuildOutcomeLine(job: Pick<AiJobSummary, 'items' | 'status'>): string | null {\n const items = job.items ?? []\n if (!items.length || (job.status !== 'done' && job.status !== 'failed')) return null\n const built = items.filter((row) => row.status === 'succeeded' || row.status === 'degraded').length\n const failed = items.filter((row) => row.status === 'failed').length\n const skipped = items.filter((row) => row.status === 'skipped').length\n const tail = [failed ? `${failed} failed` : '', skipped ? `${skipped} not built` : ''].filter(Boolean)\n return `${built} of ${items.length} built${tail.length ? `; ${tail.join(', ')}` : ''}.`\n}\n\n/** Whether a finished build — or a site that built part of itself — has failed items to try again. */\nexport function aiBuildCanRetry(job: Pick<AiJobSummary, 'kind' | 'status' | 'items'>): boolean {\n // A site that built nothing starts over from its own answers instead.\n const finished = job.kind === 'build' ? job.status === 'done' || job.status === 'failed' : job.kind === 'site' && job.status === 'done'\n return (\n finished &&\n (job.items ?? []).some((row) => row.status === 'failed' || (row.status === 'skipped' && !row.degradedBy?.length))\n )\n}\n\n/**\n * What a guided start that built part of its site says (AGL-3616), in the\n * words every surface uses: \"Built 1 of 2 pages. Home couldn’t be built —\n * that one’s on us…\". `null` when every page was built, or none was.\n */\nexport function aiSitePartialCopy(job: Pick<AiJobSummary, 'items' | 'status'>): string | null {\n const pages = (job.items ?? []).filter((row) => row.op === 'page')\n const built = pages.filter((row) => row.status === 'succeeded' || row.status === 'degraded')\n const unbuilt = (job.items ?? []).filter((row) => row.status === 'failed' || row.status === 'skipped')\n if (job.status !== 'done' || !unbuilt.length || !built.length) return null\n const names = unbuilt.map((row) => (row.op === 'page' ? row.label : `The ${aiBuildOpNoun(row.op).toLowerCase()} “${row.label}”`))\n const list = names.length === 1 ? names[0] : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n const refunded = unbuilt.reduce((total, row) => total + Math.max(0, Math.floor(row.creditsRefunded ?? 0)), 0)\n const back = refunded > 0 ? ` The ${refunded} ${refunded === 1 ? 'credit' : 'credits'} it used ${refunded === 1 ? 'is' : 'are'} back in your AI credits.` : ''\n // Only a failure on our side says so; a part the AI declined or an allowance\n // stopped was charged for what it used, and the row says that.\n const ours = unbuilt.every((row) => row.status === 'skipped' || row.failure?.ours === true)\n const why = ours ? ` — that one’s on us, you weren’t charged for ${unbuilt.length === 1 ? 'it' : 'them'}.` : '.'\n return `Built ${built.length} of ${pages.length} ${pages.length === 1 ? 'page' : 'pages'}. ${list} couldn’t be built${why}${back} Try again builds only what failed.`\n}\n"],"names":["aiCustomerSafeItem","AI_JOB_PLAN_STEP","OP_NOUNS","page","layout","form","component","email","template","campaign","workflow","aiBuildOpNoun","op","known","words","replace","trim","toUpperCase","slice","aiBuildItemRefundCopy","row","status","failure","ours","refunded","Math","max","floor","creditsRefunded","spent","creditsSpent","STATES","pending","running","succeeded","degraded","failed","skipped","aiBuildActiveSlot","job","items","find","slot","aiBuildActiveStartedAt","latest","at","settledAt","Date","parse","NaN","Number","isFinite","iso","step","steps","one","name","startedAt","aiBuildItemRows","active","map","ledger","parts","message","push","note","refund","label","state","detail","length","join","aiBuildOutcomeLine","built","filter","tail","Boolean","aiBuildCanRetry","finished","kind","some","degradedBy","aiSitePartialCopy","pages","unbuilt","names","toLowerCase","list","reduce","total","back","every","why"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
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 { AiInsightTable } from './ai-insight';
|
|
18
|
+
/**
|
|
19
|
+
* Whether a site is published and where, read off its host document — the
|
|
20
|
+
* facts an AI job must be told rather than left to infer. Pure: no read, so
|
|
21
|
+
* every job that already holds the host can use it, and the site inventory
|
|
22
|
+
* every AI job will get (AGL-3661) absorbs it rather than duplicating it.
|
|
23
|
+
*/
|
|
24
|
+
export interface AiHostPublishContext {
|
|
25
|
+
/** At least one page a visitor can open. */
|
|
26
|
+
published: boolean;
|
|
27
|
+
/** The address visitors use: a custom domain only once it serves, else the platform subdomain. */
|
|
28
|
+
liveUrl: string | null;
|
|
29
|
+
/** The published pages' paths, `/` first. */
|
|
30
|
+
publishedPages: string[];
|
|
31
|
+
/** When the first page went live, in ms, when the screens passed say so. */
|
|
32
|
+
firstPublishedAt: number | null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* `host.screens` is the routing map publishing writes — screen id to path —
|
|
36
|
+
* so its entries are exactly the pages a visitor can reach. `screens`, when a
|
|
37
|
+
* caller has the page documents, adds when the first one went live.
|
|
38
|
+
*/
|
|
39
|
+
export declare function aiHostPublishContext(host: Record<string, unknown> | null | undefined, screens?: ReadonlyArray<{
|
|
40
|
+
publishedAt?: unknown;
|
|
41
|
+
deletedAt?: unknown;
|
|
42
|
+
}>): AiHostPublishContext;
|
|
43
|
+
/** The reader id the site-status table carries. Code writes it; the model never chooses it. */
|
|
44
|
+
export declare const AI_SITE_STATUS_READER = "site.status";
|
|
45
|
+
/**
|
|
46
|
+
* The site's publish state as a table an insight can cite (AGL-2915's trace
|
|
47
|
+
* holds it like any other). Without it, a question about launch was answered
|
|
48
|
+
* from traffic alone, and "no views yet" was read as "not live" for a site
|
|
49
|
+
* that had been live for a minute.
|
|
50
|
+
*/
|
|
51
|
+
export declare function aiSiteStatusTable(context: AiHostPublishContext, ref: string): AiInsightTable;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { liveCustomDomain, TENANT_APEX } from "@aglyn/aglyn/app-utils/host-naming";
|
|
17
|
+
const millis = (value)=>{
|
|
18
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
19
|
+
if (value && typeof value.toMillis === 'function') {
|
|
20
|
+
return value.toMillis();
|
|
21
|
+
}
|
|
22
|
+
if (typeof value === 'string') {
|
|
23
|
+
const parsed = Date.parse(value);
|
|
24
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* `host.screens` is the routing map publishing writes — screen id to path —
|
|
30
|
+
* so its entries are exactly the pages a visitor can reach. `screens`, when a
|
|
31
|
+
* caller has the page documents, adds when the first one went live.
|
|
32
|
+
*/ export function aiHostPublishContext(host, screens) {
|
|
33
|
+
const routes = host == null ? void 0 : host['screens'];
|
|
34
|
+
const paths = routes && typeof routes === 'object' ? [
|
|
35
|
+
...new Set(Object.values(routes).filter((path)=>typeof path === 'string' && path.startsWith('/')))
|
|
36
|
+
] : [];
|
|
37
|
+
paths.sort((a, b)=>a === '/' ? -1 : b === '/' ? 1 : a.localeCompare(b));
|
|
38
|
+
const domain = host ? liveCustomDomain(host) : undefined;
|
|
39
|
+
const subdomain = typeof (host == null ? void 0 : host['subdomain']) === 'string' ? host['subdomain'] : '';
|
|
40
|
+
const liveUrl = domain ? `https://${domain}` : subdomain ? `https://${subdomain}.${TENANT_APEX}` : null;
|
|
41
|
+
const firsts = (screens != null ? screens : []).filter((screen)=>!screen.deletedAt).map((screen)=>millis(screen.publishedAt)).filter((ms)=>ms !== null);
|
|
42
|
+
return {
|
|
43
|
+
published: paths.length > 0,
|
|
44
|
+
liveUrl,
|
|
45
|
+
publishedPages: paths,
|
|
46
|
+
firstPublishedAt: firsts.length ? Math.min(...firsts) : null
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** The reader id the site-status table carries. Code writes it; the model never chooses it. */ export const AI_SITE_STATUS_READER = 'site.status';
|
|
50
|
+
/** At most this many paths are named; the rest are counted after them. */ const SITE_STATUS_MAX_PAGES = 12;
|
|
51
|
+
/**
|
|
52
|
+
* The site's publish state as a table an insight can cite (AGL-2915's trace
|
|
53
|
+
* holds it like any other). Without it, a question about launch was answered
|
|
54
|
+
* from traffic alone, and "no views yet" was read as "not live" for a site
|
|
55
|
+
* that had been live for a minute.
|
|
56
|
+
*/ export function aiSiteStatusTable(context, ref) {
|
|
57
|
+
var _context_liveUrl;
|
|
58
|
+
const pages = context.publishedPages.slice(0, SITE_STATUS_MAX_PAGES);
|
|
59
|
+
const more = context.publishedPages.length - pages.length;
|
|
60
|
+
return {
|
|
61
|
+
ref,
|
|
62
|
+
reader: AI_SITE_STATUS_READER,
|
|
63
|
+
days: 0,
|
|
64
|
+
scope: 'site',
|
|
65
|
+
title: 'Site status',
|
|
66
|
+
source: {
|
|
67
|
+
label: 'Pages',
|
|
68
|
+
path: 'screens'
|
|
69
|
+
},
|
|
70
|
+
period: null,
|
|
71
|
+
columns: [
|
|
72
|
+
{
|
|
73
|
+
key: 'figure',
|
|
74
|
+
label: 'Figure',
|
|
75
|
+
kind: 'text'
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
key: 'value',
|
|
79
|
+
label: 'Now',
|
|
80
|
+
kind: 'text'
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
rows: [
|
|
84
|
+
{
|
|
85
|
+
figure: 'Published',
|
|
86
|
+
value: context.published ? 'Yes: visitors can open the site now' : 'No: no page is published yet'
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
figure: 'Address',
|
|
90
|
+
value: (_context_liveUrl = context.liveUrl) != null ? _context_liveUrl : 'None yet'
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
figure: 'Published pages',
|
|
94
|
+
value: pages.length ? `${pages.join(', ')}${more > 0 ? `, and ${more} more` : ''}` : 'None'
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
omitted: 0,
|
|
98
|
+
notes: [
|
|
99
|
+
'Page views count visits, not whether the site is up: a published site with no views yet is still live.'
|
|
100
|
+
]
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=ai-host-publish-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/model/ai-host-publish-context.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { liveCustomDomain, TENANT_APEX } from '@aglyn/aglyn/app-utils/host-naming'\nimport type { AiInsightTable } from './ai-insight'\n\n/**\n * Whether a site is published and where, read off its host document — the\n * facts an AI job must be told rather than left to infer. Pure: no read, so\n * every job that already holds the host can use it, and the site inventory\n * every AI job will get (AGL-3661) absorbs it rather than duplicating it.\n */\nexport interface AiHostPublishContext {\n /** At least one page a visitor can open. */\n published: boolean\n /** The address visitors use: a custom domain only once it serves, else the platform subdomain. */\n liveUrl: string | null\n /** The published pages' paths, `/` first. */\n publishedPages: string[]\n /** When the first page went live, in ms, when the screens passed say so. */\n firstPublishedAt: number | null\n}\n\nconst millis = (value: unknown): number | null => {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (value && typeof (value as { toMillis?: unknown }).toMillis === 'function') {\n return (value as { toMillis: () => number }).toMillis()\n }\n if (typeof value === 'string') {\n const parsed = Date.parse(value)\n return Number.isNaN(parsed) ? null : parsed\n }\n return null\n}\n\n/**\n * `host.screens` is the routing map publishing writes — screen id to path —\n * so its entries are exactly the pages a visitor can reach. `screens`, when a\n * caller has the page documents, adds when the first one went live.\n */\nexport function aiHostPublishContext(\n host: Record<string, unknown> | null | undefined,\n screens?: ReadonlyArray<{ publishedAt?: unknown; deletedAt?: unknown }>,\n): AiHostPublishContext {\n const routes = host?.['screens']\n const paths =\n routes && typeof routes === 'object'\n ? [...new Set(Object.values(routes as Record<string, unknown>).filter((path): path is string => typeof path === 'string' && path.startsWith('/')))]\n : []\n paths.sort((a, b) => (a === '/' ? -1 : b === '/' ? 1 : a.localeCompare(b)))\n const domain = host ? liveCustomDomain(host as Parameters<typeof liveCustomDomain>[0]) : undefined\n const subdomain = typeof host?.['subdomain'] === 'string' ? (host['subdomain'] as string) : ''\n const liveUrl = domain ? `https://${domain}` : subdomain ? `https://${subdomain}.${TENANT_APEX}` : null\n const firsts = (screens ?? [])\n .filter((screen) => !screen.deletedAt)\n .map((screen) => millis(screen.publishedAt))\n .filter((ms): ms is number => ms !== null)\n return {\n published: paths.length > 0,\n liveUrl,\n publishedPages: paths,\n firstPublishedAt: firsts.length ? Math.min(...firsts) : null,\n }\n}\n\n/** The reader id the site-status table carries. Code writes it; the model never chooses it. */\nexport const AI_SITE_STATUS_READER = 'site.status'\n\n/** At most this many paths are named; the rest are counted after them. */\nconst SITE_STATUS_MAX_PAGES = 12\n\n/**\n * The site's publish state as a table an insight can cite (AGL-2915's trace\n * holds it like any other). Without it, a question about launch was answered\n * from traffic alone, and \"no views yet\" was read as \"not live\" for a site\n * that had been live for a minute.\n */\nexport function aiSiteStatusTable(context: AiHostPublishContext, ref: string): AiInsightTable {\n const pages = context.publishedPages.slice(0, SITE_STATUS_MAX_PAGES)\n const more = context.publishedPages.length - pages.length\n return {\n ref,\n reader: AI_SITE_STATUS_READER,\n days: 0,\n scope: 'site',\n title: 'Site status',\n source: { label: 'Pages', path: 'screens' },\n period: null,\n columns: [\n { key: 'figure', label: 'Figure', kind: 'text' },\n { key: 'value', label: 'Now', kind: 'text' },\n ],\n rows: [\n { figure: 'Published', value: context.published ? 'Yes: visitors can open the site now' : 'No: no page is published yet' },\n { figure: 'Address', value: context.liveUrl ?? 'None yet' },\n {\n figure: 'Published pages',\n value: pages.length ? `${pages.join(', ')}${more > 0 ? `, and ${more} more` : ''}` : 'None',\n },\n ],\n omitted: 0,\n notes: [\n 'Page views count visits, not whether the site is up: a published site with no views yet is still live.',\n ],\n }\n}\n"],"names":["liveCustomDomain","TENANT_APEX","millis","value","Number","isFinite","toMillis","parsed","Date","parse","isNaN","aiHostPublishContext","host","screens","routes","paths","Set","Object","values","filter","path","startsWith","sort","a","b","localeCompare","domain","undefined","subdomain","liveUrl","firsts","screen","deletedAt","map","publishedAt","ms","published","length","publishedPages","firstPublishedAt","Math","min","AI_SITE_STATUS_READER","SITE_STATUS_MAX_PAGES","aiSiteStatusTable","context","ref","pages","slice","more","reader","days","scope","title","source","label","period","columns","key","kind","rows","figure","join","omitted","notes"],"mappings":"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"}
|
|
@@ -44,10 +44,12 @@ import type { AiJob, AiJobOutput } from './ai-jobs.types';
|
|
|
44
44
|
* weekly digest, to the members who reach its site.
|
|
45
45
|
*/
|
|
46
46
|
/**
|
|
47
|
-
* Where an insight was asked: the console page whose Assist panel
|
|
48
|
-
* or the weekly digest,
|
|
47
|
+
* Where an insight was asked: the console page whose Assist panel — or
|
|
48
|
+
* whose "Ask AI about these numbers" card — asked it, or the weekly digest,
|
|
49
|
+
* which no person asked. A site's Marketing, Automation and Bookings pages
|
|
50
|
+
* and the workspace's own pages joined at AGL-3603.
|
|
49
51
|
*/
|
|
50
|
-
export type AiInsightSurface = 'analytics' | 'datasets' | 'crm-reports' | 'digest';
|
|
52
|
+
export type AiInsightSurface = 'analytics' | 'datasets' | 'crm-reports' | 'marketing' | 'automations' | 'bookings' | 'workspace' | 'digest';
|
|
51
53
|
export declare const AI_INSIGHT_SURFACES: readonly AiInsightSurface[];
|
|
52
54
|
/** The surfaces a person asks from. */
|
|
53
55
|
export declare const AI_INSIGHT_ASK_SURFACES: readonly AiInsightSurface[];
|
|
@@ -55,12 +57,17 @@ export declare const AI_INSIGHT_ASK_SURFACES: readonly AiInsightSurface[];
|
|
|
55
57
|
export declare function aiInsightSurface(inputs: Readonly<Record<string, unknown>> | null | undefined): AiInsightSurface | null;
|
|
56
58
|
/**
|
|
57
59
|
* The readers a surface may offer, by the first word of a reader's id. The
|
|
58
|
-
* Analytics page
|
|
59
|
-
*
|
|
60
|
-
*
|
|
60
|
+
* Analytics page — and a site's dashboard — answers about the site's traffic,
|
|
61
|
+
* what it sold, took and collected, its automations' runs and its CRM
|
|
62
|
+
* pipeline; a Data page about its datasets; CRM Reports about where people
|
|
63
|
+
* came from, what they did and the pipeline; the Marketing page about what
|
|
64
|
+
* its campaigns, overlays and tests caused and earned, beside the traffic and
|
|
65
|
+
* the forms they drove; the Automation page about its runs; the Bookings page
|
|
66
|
+
* about its bookings; and the workspace's own pages about its pipeline and
|
|
67
|
+
* its datasets.
|
|
61
68
|
*/
|
|
62
69
|
export declare const AI_INSIGHT_SURFACE_READERS: Readonly<Record<AiInsightSurface, readonly string[]>>;
|
|
63
|
-
/** Whether a surface answers about one site; the Data page may answer about the whole workspace. */
|
|
70
|
+
/** Whether a surface answers about one site; the Data page and the workspace's pages may answer about the whole workspace. */
|
|
64
71
|
export declare function aiInsightSurfaceNeedsSite(surface: AiInsightSurface): boolean;
|
|
65
72
|
/**
|
|
66
73
|
* The readers a weekly digest reads, in the order the digest names them:
|
|
@@ -157,9 +164,12 @@ export declare function aiInsightOutput(job: Pick<AiJob, '$id' | 'hostId'>, reco
|
|
|
157
164
|
/** The answer on the wire: the stored record, with nothing a client does not render. */
|
|
158
165
|
export type AiInsightAnswerWire = AiInsightRecord;
|
|
159
166
|
/**
|
|
160
|
-
* The Assist panel's insight surface for a console path, or `null` off one
|
|
161
|
-
*
|
|
162
|
-
*
|
|
167
|
+
* The Assist panel's insight surface for a console path, or `null` off one:
|
|
168
|
+
* a site's dashboard, Analytics, Data, CRM Reports, Marketing, Automation and
|
|
169
|
+
* Bookings pages; the workspace's Data page; and the workspace's sites page
|
|
170
|
+
* and CRM Reports, which read the workspace's pipeline and datasets. The
|
|
171
|
+
* organization's Marketing page reads site figures, so it is not one — it
|
|
172
|
+
* asks about the site it is showing, through its own in-page entry.
|
|
163
173
|
*/
|
|
164
174
|
export declare function aiInsightSurfaceForPath(pathname: string | null | undefined): {
|
|
165
175
|
surface: Exclude<AiInsightSurface, 'digest'>;
|