@aglyn/plugins-ai 1.0.0-beta.230 → 1.0.0-beta.232
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/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.js +8 -4
- 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-job-follow.component.js +1 -0
- package/src/lib/components/ai-job-follow.component.js.map +1 -1
- package/src/lib/components/ai-job-links.js +13 -0
- package/src/lib/components/ai-job-links.js.map +1 -1
- package/src/lib/components/ai-job-plan.component.js +3 -1
- package/src/lib/components/ai-job-plan.component.js.map +1 -1
- package/src/lib/components/ai-jobs-list-page.component.js +1 -0
- package/src/lib/components/ai-jobs-list-page.component.js.map +1 -1
- package/src/lib/components/ai-media-create.component.d.ts +20 -7
- package/src/lib/components/ai-media-create.component.js +107 -55
- package/src/lib/components/ai-media-create.component.js.map +1 -1
- 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-seo-fields-card.component.js +1 -0
- package/src/lib/components/ai-seo-fields-card.component.js.map +1 -1
- package/src/lib/components/ai-site-build-page.component.js +20 -8
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-site-memory-card.component.d.ts +32 -0
- package/src/lib/components/ai-site-memory-card.component.js +187 -0
- package/src/lib/components/ai-site-memory-card.component.js.map +1 -0
- package/src/lib/components/ai-site-start-card.component.js +80 -77
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/components/ai-theme-proposal-card.component.js +4 -0
- package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -1
- package/src/lib/components/ai-usage-strip.component.js +1 -0
- package/src/lib/components/ai-usage-strip.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.d.ts +10 -0
- package/src/lib/components/assist-panel.component.js +119 -9
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/components/assist-signals-page.component.js +2 -0
- package/src/lib/components/assist-signals-page.component.js.map +1 -1
- package/src/lib/components/billing-ai-allotments.component.js +3 -0
- package/src/lib/components/billing-ai-allotments.component.js.map +1 -1
- package/src/lib/components/billing-ai-top-users.component.js +1 -0
- package/src/lib/components/billing-ai-top-users.component.js.map +1 -1
- package/src/lib/components/billing-assist-overage-card.component.js +2 -0
- package/src/lib/components/billing-assist-overage-card.component.js.map +1 -1
- package/src/lib/components/member-ai-usage-card.component.js +10 -0
- package/src/lib/components/member-ai-usage-card.component.js.map +1 -1
- package/src/lib/components/staff-org-ai-card.component.js +1 -0
- package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
- package/src/lib/components/staff-org-ai-conversations.component.d.ts +23 -0
- package/src/lib/components/staff-org-ai-conversations.component.js +346 -0
- package/src/lib/components/staff-org-ai-conversations.component.js.map +1 -0
- package/src/lib/jobs/ai-build-capabilities.d.ts +13 -1
- package/src/lib/jobs/ai-build-capabilities.js +101 -7
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
- package/src/lib/jobs/ai-build-unit-outcome.js +4 -2
- package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -1
- package/src/lib/jobs/ai-business-profile-prefill.d.ts +29 -0
- package/src/lib/jobs/ai-business-profile-prefill.js +85 -0
- package/src/lib/jobs/ai-business-profile-prefill.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.js +14 -1
- package/src/lib/jobs/ai-job-build-step.js.map +1 -1
- package/src/lib/jobs/ai-job-edit-step.d.ts +225 -0
- package/src/lib/jobs/ai-job-edit-step.js +631 -0
- package/src/lib/jobs/ai-job-edit-step.js.map +1 -0
- 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 +29 -5
- package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.d.ts +78 -0
- package/src/lib/jobs/ai-job-layout-language.js +200 -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 +107 -6
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-logic-step.d.ts +20 -0
- package/src/lib/jobs/ai-job-logic-step.js +87 -6
- package/src/lib/jobs/ai-job-logic-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +194 -0
- package/src/lib/jobs/ai-job-page-language.js +418 -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 +115 -14
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +20 -6
- package/src/lib/jobs/ai-job-plan-step.js +62 -22
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-content.d.ts +163 -0
- package/src/lib/jobs/ai-job-site-content.js +443 -0
- package/src/lib/jobs/ai-job-site-content.js.map +1 -0
- package/src/lib/jobs/ai-job-site-look.d.ts +112 -0
- package/src/lib/jobs/ai-job-site-look.js +322 -0
- package/src/lib/jobs/ai-job-site-look.js.map +1 -0
- package/src/lib/jobs/ai-job-site-step.d.ts +30 -5
- package/src/lib/jobs/ai-job-site-step.js +183 -27
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-workflow-step.js +2 -2
- package/src/lib/jobs/ai-job-workflow-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs-notify.d.ts +6 -1
- package/src/lib/jobs/ai-jobs-notify.js +15 -3
- package/src/lib/jobs/ai-jobs-notify.js.map +1 -1
- package/src/lib/jobs/ai-jobs.d.ts +1 -1
- package/src/lib/jobs/ai-jobs.js +17 -8
- 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/layout-language/ai-layout-compiler.d.ts +154 -0
- package/src/lib/layout-language/ai-layout-compiler.js +1235 -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 +458 -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 +168 -0
- package/src/lib/layout-language/ai-layout-language.js +529 -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-pictures.d.ts +144 -0
- package/src/lib/layout-language/ai-layout-pictures.js +214 -0
- package/src/lib/layout-language/ai-layout-pictures.js.map +1 -0
- package/src/lib/layout-language/ai-layout-store.d.ts +41 -0
- package/src/lib/layout-language/ai-layout-store.js +75 -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-build-job.js +2 -1
- package/src/lib/model/ai-build-job.js.map +1 -1
- package/src/lib/model/ai-build-progress.d.ts +20 -3
- package/src/lib/model/ai-build-progress.js +52 -7
- package/src/lib/model/ai-build-progress.js.map +1 -1
- package/src/lib/model/ai-edit-job.d.ts +109 -0
- package/src/lib/model/ai-edit-job.js +157 -0
- package/src/lib/model/ai-edit-job.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-job-activity.d.ts +22 -0
- package/src/lib/model/ai-job-activity.js +23 -1
- 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 +22 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-logic-job.d.ts +18 -1
- package/src/lib/model/ai-logic-job.js +24 -3
- package/src/lib/model/ai-logic-job.js.map +1 -1
- package/src/lib/model/ai-media-credits.d.ts +8 -4
- package/src/lib/model/ai-media-credits.js +11 -4
- package/src/lib/model/ai-media-credits.js.map +1 -1
- package/src/lib/model/ai-media-kinds.d.ts +68 -0
- package/src/lib/model/ai-media-kinds.js +98 -0
- package/src/lib/model/ai-media-kinds.js.map +1 -0
- package/src/lib/model/ai-site-build-progress.d.ts +9 -1
- package/src/lib/model/ai-site-build-progress.js +54 -14
- package/src/lib/model/ai-site-build-progress.js.map +1 -1
- package/src/lib/model/ai-site-context.d.ts +111 -0
- package/src/lib/model/ai-site-context.js +222 -0
- package/src/lib/model/ai-site-context.js.map +1 -0
- package/src/lib/model/ai-site-job.d.ts +18 -2
- package/src/lib/model/ai-site-job.js +21 -5
- package/src/lib/model/ai-site-job.js.map +1 -1
- package/src/lib/model/ai-site-kinds.d.ts +164 -0
- package/src/lib/model/ai-site-kinds.js +1942 -0
- package/src/lib/model/ai-site-kinds.js.map +1 -0
- package/src/lib/model/ai-site-look.d.ts +150 -0
- package/src/lib/model/ai-site-look.js +1236 -0
- package/src/lib/model/ai-site-look.js.map +1 -0
- package/src/lib/model/ai-site-memory.d.ts +80 -0
- package/src/lib/model/ai-site-memory.js +171 -0
- package/src/lib/model/ai-site-memory.js.map +1 -0
- package/src/lib/model/ai-site-start-seo.d.ts +1 -1
- package/src/lib/model/ai-site-start.d.ts +15 -3
- package/src/lib/model/ai-site-start.js +21 -4
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/model/assist-follow-up.d.ts +92 -0
- package/src/lib/model/assist-follow-up.js +128 -0
- package/src/lib/model/assist-follow-up.js.map +1 -0
- package/src/lib/plugin-config.js +2 -0
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +99 -48
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/providers/anthropic.d.ts +9 -1
- package/src/lib/providers/anthropic.js +143 -9
- package/src/lib/providers/anthropic.js.map +1 -1
- package/src/lib/providers/catalog.d.ts +38 -8
- package/src/lib/providers/catalog.js +106 -14
- package/src/lib/providers/catalog.js.map +1 -1
- package/src/lib/providers/contract.d.ts +29 -0
- package/src/lib/providers/contract.js.map +1 -1
- package/src/lib/providers/image-contract.d.ts +22 -1
- package/src/lib/providers/image-contract.js +40 -1
- package/src/lib/providers/image-contract.js.map +1 -1
- package/src/lib/providers/image-endpoints.d.ts +24 -0
- package/src/lib/providers/image-endpoints.js +28 -0
- package/src/lib/providers/image-endpoints.js.map +1 -0
- package/src/lib/providers/model-choice.js +23 -2
- 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-endpoint.d.ts +48 -0
- package/src/lib/providers/vertex-image-endpoint.js +80 -0
- package/src/lib/providers/vertex-image-endpoint.js.map +1 -0
- package/src/lib/providers/vertex-image.d.ts +13 -27
- package/src/lib/providers/vertex-image.js +15 -42
- package/src/lib/providers/vertex-image.js.map +1 -1
- package/src/lib/runtime/ai-blog-post-generation.d.ts +62 -0
- package/src/lib/runtime/ai-blog-post-generation.js +89 -0
- package/src/lib/runtime/ai-blog-post-generation.js.map +1 -0
- package/src/lib/runtime/ai-dev-env.d.ts +53 -0
- package/src/lib/runtime/ai-dev-env.js +72 -0
- package/src/lib/runtime/ai-dev-env.js.map +1 -0
- package/src/lib/runtime/ai-dev-replay.d.ts +116 -0
- package/src/lib/runtime/ai-dev-replay.js +313 -0
- package/src/lib/runtime/ai-dev-replay.js.map +1 -0
- package/src/lib/runtime/ai-doctrine-validators.d.ts +82 -0
- package/src/lib/runtime/ai-doctrine-validators.js +436 -4
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +16 -3
- 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 +13 -1
- package/src/lib/runtime/ai-eval.js +84 -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-live-batch.d.ts +45 -0
- package/src/lib/runtime/ai-live-batch.js +89 -0
- package/src/lib/runtime/ai-live-batch.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/ai-runtime.js +46 -2
- package/src/lib/runtime/ai-runtime.js.map +1 -1
- package/src/lib/runtime/site-context.d.ts +58 -0
- package/src/lib/runtime/site-context.js +127 -0
- package/src/lib/runtime/site-context.js.map +1 -0
- package/src/lib/server/ai-admin-conversations.d.ts +22 -0
- package/src/lib/server/ai-admin-conversations.js +197 -0
- package/src/lib/server/ai-admin-conversations.js.map +1 -0
- package/src/lib/server/ai-media-image.d.ts +5 -5
- package/src/lib/server/ai-media-image.js +25 -11
- package/src/lib/server/ai-media-image.js.map +1 -1
- package/src/lib/server/ai-media-raster-prompt.d.ts +34 -0
- package/src/lib/server/ai-media-raster-prompt.js +53 -0
- package/src/lib/server/ai-media-raster-prompt.js.map +1 -0
- package/src/lib/server/assist-chat.d.ts +11 -0
- package/src/lib/server/assist-chat.js +57 -18
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-edit-applied.js +16 -3
- package/src/lib/server/assist-edit-applied.js.map +1 -1
- package/src/lib/server/assist-view-context.d.ts +19 -1
- package/src/lib/server/assist-view-context.js +38 -1
- package/src/lib/server/assist-view-context.js.map +1 -1
- package/src/lib/server.js +10 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/subprocessors.js +17 -1
- package/src/lib/subprocessors.js.map +1 -1
- package/src/lib/tools/ai-blog-post-tool.d.ts +60 -0
- package/src/lib/tools/ai-blog-post-tool.js +175 -0
- package/src/lib/tools/ai-blog-post-tool.js.map +1 -0
- package/src/lib/tools/ai-workflow-tool.d.ts +6 -2
- package/src/lib/tools/ai-workflow-tool.js +16 -14
- package/src/lib/tools/ai-workflow-tool.js.map +1 -1
- package/src/lib/usage/assist-usage.d.ts +3 -0
- package/src/lib/usage/assist-usage.js +4 -2
- package/src/lib/usage/assist-usage.js.map +1 -1
- package/src/lib/usage/staff-org-ai-conversations.d.ts +103 -0
- package/src/lib/usage/staff-org-ai-conversations.js +152 -0
- package/src/lib/usage/staff-org-ai-conversations.js.map +1 -0
|
@@ -21,6 +21,8 @@ import { type AiSiteJobInputs } from '../model/ai-site-job';
|
|
|
21
21
|
import { type AiJobAdmission } from './ai-job-admission';
|
|
22
22
|
import { readAiDraftNodes } from './ai-job-drafts';
|
|
23
23
|
import { aiPublishGuidedSite } from './ai-site-publish';
|
|
24
|
+
import { aiPublishSitePosts, aiSiteContentRefusal } from './ai-job-site-content';
|
|
25
|
+
import { dropPluginSiteCache } from '@aglyn/aglyn/plugin-manager/plugin-site-cache';
|
|
24
26
|
import { type AiJobStepContext, type AiJobStepOutcome, type AiJobStepRunner } from './ai-job-text-step';
|
|
25
27
|
import { aiJobStepRunnerFor } from './ai-jobs';
|
|
26
28
|
/**
|
|
@@ -76,8 +78,13 @@ import { aiJobStepRunnerFor } from './ai-jobs';
|
|
|
76
78
|
* `new:<name>` references resolved to what was built (`aiSiteBuiltRefs`,
|
|
77
79
|
* `aiSiteUnitJob`). There is one loop, and it is the machine's.
|
|
78
80
|
*/
|
|
79
|
-
/**
|
|
80
|
-
|
|
81
|
+
/**
|
|
82
|
+
* What a scaffold's units are, in the order it builds them; a component is a
|
|
83
|
+
* page job's. A blog's first posts and a store's first products (AGL-3676)
|
|
84
|
+
* are built after the layout and the form and before the pages, which are
|
|
85
|
+
* told what they are.
|
|
86
|
+
*/
|
|
87
|
+
export type AiSiteUnitKind = 'theme' | 'layout' | 'form' | 'component' | 'posts' | 'products' | 'page' | 'email';
|
|
81
88
|
export interface AiSiteUnit {
|
|
82
89
|
kind: AiSiteUnitKind;
|
|
83
90
|
/** The job kind whose registered runner builds it. */
|
|
@@ -98,6 +105,8 @@ export interface AiSiteUnit {
|
|
|
98
105
|
* are addressed by; `null` for a creation no unit builds.
|
|
99
106
|
*/
|
|
100
107
|
export declare function aiCreationUnit(creation: AiBuildPlanCreate, slot: string): AiSiteUnit | null;
|
|
108
|
+
/** What the look's unit is called on the ledger. */
|
|
109
|
+
export declare const AI_SITE_LOOK_LABEL = "Your look";
|
|
101
110
|
export declare const AI_SITE_NO_PLAN_COPY = "This site job has no confirmed plan to build.";
|
|
102
111
|
/** What a scaffold answers where the step that builds a page is not loaded. */
|
|
103
112
|
export declare const AI_SITE_NO_PAGE_STEP_COPY = "Building a whole site is not available yet.";
|
|
@@ -105,9 +114,10 @@ export declare const AI_SITE_NO_PAGE_STEP_COPY = "Building a whole site is not a
|
|
|
105
114
|
export declare const AI_SITE_UNIT_EMPTY_COPY = "Part of this site could not be built. Try the site brief again.";
|
|
106
115
|
/**
|
|
107
116
|
* The most passes a scaffold's step may take: the largest plan it admits —
|
|
108
|
-
* eight pages of eight sections, its three creations
|
|
109
|
-
*
|
|
110
|
-
* while a real site
|
|
117
|
+
* eight pages of eight sections, its three creations, a blog's first posts
|
|
118
|
+
* (one a pass, the largest part) and a welcome email — with nothing to
|
|
119
|
+
* spare, so a runner that never finishes is still bounded while a real site
|
|
120
|
+
* is not.
|
|
111
121
|
*/
|
|
112
122
|
export declare const AI_SITE_MAX_PASSES: number;
|
|
113
123
|
/**
|
|
@@ -119,6 +129,7 @@ export declare const AI_SITE_MAX_PASSES: number;
|
|
|
119
129
|
*/
|
|
120
130
|
export declare function aiSiteJobUnits(plan: Pick<AiJobPlan, 'create' | 'screens'>, options?: {
|
|
121
131
|
welcomeEmail?: boolean;
|
|
132
|
+
content?: 'posts' | 'products' | null;
|
|
122
133
|
}): AiSiteUnit[];
|
|
123
134
|
/**
|
|
124
135
|
* The units a scaffold still owes after the outputs recorded so far. Each
|
|
@@ -162,6 +173,10 @@ export declare function aiSiteResolvedRef(ref: string | null, built: BuiltRefs):
|
|
|
162
173
|
* guided start writes it into the brief itself, but an agency batch's brief
|
|
163
174
|
* is a member's own sentence and may never mention it, and a theme, a layout
|
|
164
175
|
* or a form asked to serve nobody in particular serves nobody in particular.
|
|
176
|
+
*
|
|
177
|
+
* The name is said twice (AGL-3596): as a field, and as the instruction to use
|
|
178
|
+
* it as written. A layout told only "a dog groomer in Austin" put a business
|
|
179
|
+
* name of its own in the header and the footer.
|
|
165
180
|
*/
|
|
166
181
|
export declare function aiSiteBriefLines(brief: string, inputs: AiSiteJobInputs): string[];
|
|
167
182
|
/**
|
|
@@ -246,6 +261,16 @@ export interface AiJobSiteStepDeps {
|
|
|
246
261
|
readNodes?: typeof readAiDraftNodes;
|
|
247
262
|
/** The guided start's publish; specs hand in a fake. */
|
|
248
263
|
publish?: typeof aiPublishGuidedSite;
|
|
264
|
+
/** The look's pass (AGL-3660); specs hand in a fake. */
|
|
265
|
+
look?: (context: AiJobStepContext, job: AiJob) => Promise<AiJobStepOutcome>;
|
|
266
|
+
/** The first posts' and first products' passes (AGL-3676); specs hand in fakes. */
|
|
267
|
+
posts?: AiJobStepRunner;
|
|
268
|
+
products?: AiJobStepRunner;
|
|
269
|
+
/** Whether a part may be built for this member, before its first pass. */
|
|
270
|
+
contentRefusal?: typeof aiSiteContentRefusal;
|
|
271
|
+
/** The posts' publish once the pages are live, and the cache drop after it. */
|
|
272
|
+
publishPosts?: typeof aiPublishSitePosts;
|
|
273
|
+
dropCache?: typeof dropPluginSiteCache;
|
|
249
274
|
}
|
|
250
275
|
/** A page the scaffold reported built that holds none of its plan's sections. */
|
|
251
276
|
export declare const AI_SITE_PAGE_NOT_WRITTEN_COPY = "A page of this site was not written from its plan. Try the site brief again.";
|
|
@@ -19,7 +19,7 @@ import { resolveOrgIdForHost } from "@aglyn/tenant-data-admin/server/organizatio
|
|
|
19
19
|
import { isAiPlanNewRef } from "../model/ai-build-plan.js";
|
|
20
20
|
import { aiBuildDegradation, aiBuildInitialLedger, aiBuildItemDelivered, aiBuildItemOpen, aiBuildNextUnit } from "../model/ai-build-job.js";
|
|
21
21
|
import { aiBuildBuiltRefs, aiUnitErrorRetryable, aiUnitFailure, aiUnitSpend } from "./ai-build-unit-outcome.js";
|
|
22
|
-
import { AI_SITE_EMAIL_TYPE, AI_SITE_MAX_SECTIONS, AI_SITE_PAGES, aiSitePagesRefusal, aiSitePlanRefusal, aiSiteSubmissions, aiSiteWords, parseAiSiteJobInputs } from "../model/ai-site-job.js";
|
|
22
|
+
import { AI_SITE_EMAIL_TYPE, AI_SITE_MAX_SECTIONS, AI_SITE_PAGES, aiSiteNameSentence, aiSitePagesRefusal, aiSitePlanRefusal, aiSiteSubmissions, aiSiteWords, parseAiSiteJobInputs } from "../model/ai-site-job.js";
|
|
23
23
|
import { AI_SITE_SEO_OUTPUT_ID, aiSiteSeoProposalForInputs } from "../model/ai-site-start-seo.js";
|
|
24
24
|
import { aiModelForStep } from "../providers/routing.js";
|
|
25
25
|
import { registerAiJobAdmission } from "./ai-job-admission.js";
|
|
@@ -27,7 +27,11 @@ import { aiOriginJobId, aiRecordedJobDraftId } from "./ai-job-draft-ids.js";
|
|
|
27
27
|
import { readAiDraftNodes } from "./ai-job-drafts.js";
|
|
28
28
|
import { AI_LAYOUT_SITE_PAGES_INPUT, aiLayoutSitePagesOfPlan } from "./ai-job-layout-site-pages.js";
|
|
29
29
|
import { aiPageSectionNodeId } from "./ai-job-page-sections.js";
|
|
30
|
+
import { AI_LAYOUT_FORM_PAGE_INPUT, AI_LAYOUT_LANGUAGE_INPUT, aiLayoutFormPageOfPlan } from "./ai-job-page-language.js";
|
|
30
31
|
import { aiJobPublishesSite, aiPublishGuidedSite } from "./ai-site-publish.js";
|
|
32
|
+
import { AI_SITE_CONTENT_INPUT, AI_SITE_POST_BUDGET, AI_SITE_POSTS, AI_SITE_POSTS_LABEL, AI_SITE_PRODUCTS_LABEL, aiPublishSitePosts, aiSiteContentBriefLines, aiSiteContentPart, aiSiteContentRefusal, aiSiteProductsBriefLine, createAiSiteProductsRunner, runAiSitePostsUnit } from "./ai-job-site-content.js";
|
|
33
|
+
import { dropPluginSiteCache } from "@aglyn/aglyn/plugin-manager/plugin-site-cache";
|
|
34
|
+
import { AI_SITE_LOOK_BUDGET, aiRunSiteLook } from "./ai-job-site-look.js";
|
|
31
35
|
import { aiConfirmedPlan, aiUnspentOutcome } from "./ai-job-generation.js";
|
|
32
36
|
import { AI_JOB_BRIEF_MAX_CHARS } from "./ai-job-text-step.js";
|
|
33
37
|
import { AI_JOB_PAGE_STEP_MINIMUM_MS } from "./ai-job-page-budget.js";
|
|
@@ -56,6 +60,17 @@ import { aiJobStepRunMinimumMs, aiJobStepRunnerFor, registerAiJobStep, registerA
|
|
|
56
60
|
email: {
|
|
57
61
|
jobKind: 'email',
|
|
58
62
|
resource: 'emailScreen'
|
|
63
|
+
},
|
|
64
|
+
// The scaffold's own runner writes them (`ai-job-site-content.ts`); the
|
|
65
|
+
// posts' job kind is the one whose derived job a post's brief is, and the
|
|
66
|
+
// products' the step that proposes the catalog they are written from.
|
|
67
|
+
posts: {
|
|
68
|
+
jobKind: 'text',
|
|
69
|
+
resource: 'entry'
|
|
70
|
+
},
|
|
71
|
+
products: {
|
|
72
|
+
jobKind: 'products',
|
|
73
|
+
resource: 'product'
|
|
59
74
|
}
|
|
60
75
|
};
|
|
61
76
|
/** The unit kind a creation is built as, where a unit builds it. */ const CREATION_UNIT_KINDS = {
|
|
@@ -92,15 +107,17 @@ import { aiJobStepRunMinimumMs, aiJobStepRunnerFor, registerAiJobStep, registerA
|
|
|
92
107
|
create: 'form'
|
|
93
108
|
}
|
|
94
109
|
];
|
|
110
|
+
/** What the look's unit is called on the ledger. */ export const AI_SITE_LOOK_LABEL = 'Your look';
|
|
95
111
|
export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to build.';
|
|
96
112
|
/** What a scaffold answers where the step that builds a page is not loaded. */ export const AI_SITE_NO_PAGE_STEP_COPY = 'Building a whole site is not available yet.';
|
|
97
113
|
/** A unit that finished without reporting what it built; the scaffold cannot go on. */ export const AI_SITE_UNIT_EMPTY_COPY = 'Part of this site could not be built. Try the site brief again.';
|
|
98
114
|
/**
|
|
99
115
|
* The most passes a scaffold's step may take: the largest plan it admits —
|
|
100
|
-
* eight pages of eight sections, its three creations
|
|
101
|
-
*
|
|
102
|
-
* while a real site
|
|
103
|
-
|
|
116
|
+
* eight pages of eight sections, its three creations, a blog's first posts
|
|
117
|
+
* (one a pass, the largest part) and a welcome email — with nothing to
|
|
118
|
+
* spare, so a runner that never finishes is still bounded while a real site
|
|
119
|
+
* is not.
|
|
120
|
+
*/ export const AI_SITE_MAX_PASSES = AI_SITE_PAGES.max * (AI_SITE_MAX_SECTIONS + 1) + CREATION_UNITS.length + AI_SITE_POSTS + 1;
|
|
104
121
|
/**
|
|
105
122
|
* The units a plan implies, in build order: the palette first, because a
|
|
106
123
|
* member reads it while the pages are still building; then the layout every
|
|
@@ -108,8 +125,19 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
108
125
|
* id and so needs them to exist; then the pages; then the welcome email,
|
|
109
126
|
* which is about the site rather than part of it.
|
|
110
127
|
*/ export function aiSiteJobUnits(plan, options = {}) {
|
|
111
|
-
|
|
128
|
+
// The site's look is designed first, on every scaffold (AGL-3660): the
|
|
129
|
+
// header, the footer and every page render in it from their first draft.
|
|
130
|
+
// A theme change the plan names is that same unit, never a second one.
|
|
131
|
+
const units = [
|
|
132
|
+
_extends({
|
|
133
|
+
kind: 'theme'
|
|
134
|
+
}, UNIT_KINDS.theme, {
|
|
135
|
+
slot: 't',
|
|
136
|
+
label: AI_SITE_LOOK_LABEL
|
|
137
|
+
})
|
|
138
|
+
];
|
|
112
139
|
for (const { unit, create } of CREATION_UNITS){
|
|
140
|
+
if (unit === 'theme') continue;
|
|
113
141
|
const creation = plan.create.find((entry)=>entry.kind === create);
|
|
114
142
|
if (!creation) continue;
|
|
115
143
|
units.push(_extends({
|
|
@@ -120,6 +148,22 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
120
148
|
label: creation.name
|
|
121
149
|
}));
|
|
122
150
|
}
|
|
151
|
+
// A paid blog's first posts and a paid store's first products (AGL-3676).
|
|
152
|
+
if (options.content === 'posts') {
|
|
153
|
+
units.push(_extends({
|
|
154
|
+
kind: 'posts'
|
|
155
|
+
}, UNIT_KINDS.posts, {
|
|
156
|
+
slot: 'posts',
|
|
157
|
+
label: AI_SITE_POSTS_LABEL
|
|
158
|
+
}));
|
|
159
|
+
} else if (options.content === 'products') {
|
|
160
|
+
units.push(_extends({
|
|
161
|
+
kind: 'products'
|
|
162
|
+
}, UNIT_KINDS.products, {
|
|
163
|
+
slot: 'products',
|
|
164
|
+
label: AI_SITE_PRODUCTS_LABEL
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
123
167
|
plan.screens.forEach((screen, index)=>{
|
|
124
168
|
units.push(_extends({
|
|
125
169
|
kind: 'page'
|
|
@@ -234,6 +278,10 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
234
278
|
* guided start writes it into the brief itself, but an agency batch's brief
|
|
235
279
|
* is a member's own sentence and may never mention it, and a theme, a layout
|
|
236
280
|
* or a form asked to serve nobody in particular serves nobody in particular.
|
|
281
|
+
*
|
|
282
|
+
* The name is said twice (AGL-3596): as a field, and as the instruction to use
|
|
283
|
+
* it as written. A layout told only "a dog groomer in Austin" put a business
|
|
284
|
+
* name of its own in the header and the footer.
|
|
237
285
|
*/ export function aiSiteBriefLines(brief, inputs) {
|
|
238
286
|
const lines = [
|
|
239
287
|
brief.trim()
|
|
@@ -246,6 +294,7 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
246
294
|
inputs.brand ? `brand: ${inputs.brand}` : ''
|
|
247
295
|
].filter(Boolean);
|
|
248
296
|
lines.push(`Site — ${site.join('; ')}.`);
|
|
297
|
+
if (inputs.businessName) lines.push(aiSiteNameSentence(inputs.businessName));
|
|
249
298
|
return lines;
|
|
250
299
|
}
|
|
251
300
|
/**
|
|
@@ -330,7 +379,7 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
330
379
|
brief.push(`Build the ${unit.creation.kind} “${unit.creation.name}”: ${unit.creation.why}`);
|
|
331
380
|
}
|
|
332
381
|
if (unit.screen) {
|
|
333
|
-
var _aiSiteResolvedRef, _aiSiteResolvedRef1;
|
|
382
|
+
var _aiSiteResolvedRef, _aiSiteResolvedRef1, _job_outputs;
|
|
334
383
|
const screen = unit.screen;
|
|
335
384
|
// Everything the scaffold has already built is a record the site has, so
|
|
336
385
|
// the page is planned against it the way a page job is planned against
|
|
@@ -364,7 +413,10 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
364
413
|
})
|
|
365
414
|
];
|
|
366
415
|
brief.push(`Build the page “${screen.title}” of this site, at ${screen.slug}.`);
|
|
416
|
+
// What the blog's posts or the store's products are, once built (AGL-3676).
|
|
417
|
+
if (job.kind === 'site') brief.push(...aiSiteContentBriefLines((_job_outputs = job.outputs) != null ? _job_outputs : []));
|
|
367
418
|
}
|
|
419
|
+
if (unit.kind === 'products') brief.push(aiSiteProductsBriefLine());
|
|
368
420
|
if (unit.kind === 'email') {
|
|
369
421
|
brief.push(...aiSiteEmailBriefLines(job.inputs));
|
|
370
422
|
}
|
|
@@ -375,10 +427,46 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
375
427
|
});
|
|
376
428
|
// The layout is built before the pages, so it is told them (AGL-3596): their
|
|
377
429
|
// ids are minted on the plan, and the platform writes the header's links.
|
|
378
|
-
|
|
379
|
-
|
|
430
|
+
// A page is told them too, so its buttons may go to a page built after it.
|
|
431
|
+
if (job.kind === 'site' && (unit.kind === 'layout' || unit.kind === 'page')) {
|
|
432
|
+
// A guided start links every page the person asked for (AGL-3660).
|
|
433
|
+
const pages = aiLayoutSitePagesOfPlan(plan.screens, {
|
|
434
|
+
guided: true
|
|
435
|
+
});
|
|
380
436
|
if (pages.length) unitInputs[AI_LAYOUT_SITE_PAGES_INPUT] = pages;
|
|
381
437
|
}
|
|
438
|
+
// A site's pages and its layout are designed in the layout language and
|
|
439
|
+
// compiled (AGL-3660), and a page is told which page places the site's form.
|
|
440
|
+
if (unit.kind === 'layout' || unit.kind === 'page') {
|
|
441
|
+
var _job_outputs1;
|
|
442
|
+
var _look_proposal;
|
|
443
|
+
// The look designed first (AGL-3660): its header arrangement and band rhythm.
|
|
444
|
+
const look = ((_job_outputs1 = job.outputs) != null ? _job_outputs1 : []).find((output)=>output.resource === 'theme' && output.id === 'look');
|
|
445
|
+
const style = look == null ? void 0 : (_look_proposal = look.proposal) == null ? void 0 : _look_proposal['style'];
|
|
446
|
+
if (style) unitInputs['siteStyle'] = {
|
|
447
|
+
headerAlign: style['headerAlign'],
|
|
448
|
+
rhythm: style['rhythm']
|
|
449
|
+
};
|
|
450
|
+
unitInputs[AI_LAYOUT_LANGUAGE_INPUT] = true;
|
|
451
|
+
const formPage = aiLayoutFormPageOfPlan(plan);
|
|
452
|
+
if (formPage) unitInputs[AI_LAYOUT_FORM_PAGE_INPUT] = formPage;
|
|
453
|
+
}
|
|
454
|
+
if (unit.kind === 'posts') {
|
|
455
|
+
var _job_outputs2, _inputs_businessName;
|
|
456
|
+
// The posts already written (one a pass), the addresses the site's own
|
|
457
|
+
// pages answer at, and the byline the person gave (AGL-3676).
|
|
458
|
+
const posts = {
|
|
459
|
+
written: ((_job_outputs2 = job.outputs) != null ? _job_outputs2 : []).filter((output)=>output.resource === 'entry').map((output)=>({
|
|
460
|
+
id: output.id,
|
|
461
|
+
title: output.label
|
|
462
|
+
})),
|
|
463
|
+
total: AI_SITE_POSTS,
|
|
464
|
+
avoidSlugs: plan.screens.map((screen)=>screen.slug.replace(/^\/+/, '').split('/')[0]).filter(Boolean),
|
|
465
|
+
byline: typeof inputs === 'string' ? '' : (_inputs_businessName = inputs.businessName) != null ? _inputs_businessName : ''
|
|
466
|
+
};
|
|
467
|
+
unitInputs[AI_SITE_CONTENT_INPUT] = posts;
|
|
468
|
+
}
|
|
469
|
+
if (unit.kind === 'products') unitInputs['target'] = 'catalog';
|
|
382
470
|
return _extends({}, job, {
|
|
383
471
|
$id: aiSiteUnitJobId(job, unit),
|
|
384
472
|
kind: unit.jobKind,
|
|
@@ -529,7 +617,7 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
529
617
|
const creations = units.filter((unit)=>unit.kind === 'layout' || unit.kind === 'form').map((unit)=>unit.slot);
|
|
530
618
|
return units.map((unit)=>_extends({
|
|
531
619
|
slot: unit.slot,
|
|
532
|
-
op: unit.kind === 'theme'
|
|
620
|
+
op: unit.kind === 'theme' || unit.kind === 'posts' || unit.kind === 'products' ? unit.kind : unit.jobKind,
|
|
533
621
|
label: unit.label
|
|
534
622
|
}, unit.creation ? {
|
|
535
623
|
creation: unit.creation
|
|
@@ -566,17 +654,22 @@ export const AI_SITE_NO_PLAN_COPY = 'This site job has no confirmed plan to buil
|
|
|
566
654
|
}
|
|
567
655
|
/** The units a scaffold owes on this job: what its plan implies that this deployment can build. */ function aiSiteOwedUnits(job, plan, inputs, freeTaste, runnerFor) {
|
|
568
656
|
return aiSiteJobUnits(plan, {
|
|
569
|
-
welcomeEmail: aiSiteWelcomeEmail(inputs, freeTaste)
|
|
570
|
-
|
|
657
|
+
welcomeEmail: aiSiteWelcomeEmail(inputs, freeTaste),
|
|
658
|
+
content: aiSiteContentPart(job.inputs, freeTaste)
|
|
659
|
+
}).filter((unit)=>unit.kind === 'theme' || unit.kind === 'posts' || runnerFor(unit.jobKind));
|
|
571
660
|
}
|
|
572
661
|
export function createAiJobSiteStep(deps = {}) {
|
|
573
|
-
var _deps_runnerFor, _deps_readNodes, _deps_publish;
|
|
662
|
+
var _deps_runnerFor, _deps_readNodes, _deps_publish, _deps_look, _deps_contentRefusal, _deps_publishPosts, _deps_dropCache;
|
|
574
663
|
const runnerFor = (_deps_runnerFor = deps.runnerFor) != null ? _deps_runnerFor : aiJobStepRunnerFor;
|
|
575
664
|
const readNodes = (_deps_readNodes = deps.readNodes) != null ? _deps_readNodes : readAiDraftNodes;
|
|
576
665
|
const publish = (_deps_publish = deps.publish) != null ? _deps_publish : aiPublishGuidedSite;
|
|
666
|
+
const look = (_deps_look = deps.look) != null ? _deps_look : aiRunSiteLook;
|
|
667
|
+
const contentRefusal = (_deps_contentRefusal = deps.contentRefusal) != null ? _deps_contentRefusal : aiSiteContentRefusal;
|
|
668
|
+
const publishPosts = (_deps_publishPosts = deps.publishPosts) != null ? _deps_publishPosts : aiPublishSitePosts;
|
|
669
|
+
const dropCache = (_deps_dropCache = deps.dropCache) != null ? _deps_dropCache : dropPluginSiteCache;
|
|
577
670
|
return async (context)=>{
|
|
578
|
-
var _ref, _job_outputs, _job_outputs1;
|
|
579
|
-
var _job_items;
|
|
671
|
+
var _ref, _job_outputs, _deps_posts, _deps_products, _job_outputs1;
|
|
672
|
+
var _job_items, _rows_get;
|
|
580
673
|
const { job } = context;
|
|
581
674
|
// The scaffold asks no model of its own. What it names where it spends
|
|
582
675
|
// nothing is the model its plan ran on, which is the one exchange this
|
|
@@ -630,10 +723,36 @@ export function createAiJobSiteStep(deps = {}) {
|
|
|
630
723
|
});
|
|
631
724
|
return null;
|
|
632
725
|
});
|
|
726
|
+
if (sitePublish == null ? void 0 : sitePublish.published.length) await finishPosts();
|
|
633
727
|
return sitePublish ? _extends({}, outcome, {
|
|
634
728
|
sitePublish
|
|
635
729
|
}) : outcome;
|
|
636
730
|
};
|
|
731
|
+
/** The blog's posts go live with its pages (AGL-3676), as a person's Publish would put them. */ const finishPosts = async ()=>{
|
|
732
|
+
var _job_outputs;
|
|
733
|
+
const row = rows.get('posts');
|
|
734
|
+
if (!row || !aiBuildItemDelivered(row) || !job.hostId) return;
|
|
735
|
+
const ids = new Set(row.outputs);
|
|
736
|
+
const posts = ((_job_outputs = job.outputs) != null ? _job_outputs : []).filter((output)=>output.resource === 'entry' && ids.has(output.id));
|
|
737
|
+
const published = await publishPosts(context.firestore, {
|
|
738
|
+
job,
|
|
739
|
+
outputs: posts,
|
|
740
|
+
now: context.now
|
|
741
|
+
});
|
|
742
|
+
if (!(published == null ? void 0 : published.paths.length)) return;
|
|
743
|
+
await dropCache({
|
|
744
|
+
hostIds: [
|
|
745
|
+
job.hostId
|
|
746
|
+
],
|
|
747
|
+
reason: 'guided AI site start published its posts',
|
|
748
|
+
paths: {
|
|
749
|
+
[job.hostId]: published.paths
|
|
750
|
+
}
|
|
751
|
+
}).catch((error)=>console.warn('ai site posts: cache not dropped', {
|
|
752
|
+
jobId: job.$id,
|
|
753
|
+
error
|
|
754
|
+
}));
|
|
755
|
+
};
|
|
637
756
|
/** The pages built so far, as the job reported them. */ const builtPages = (extra = [])=>{
|
|
638
757
|
var _job_outputs;
|
|
639
758
|
const ids = new Set(units.filter((unit)=>{
|
|
@@ -653,7 +772,11 @@ export function createAiJobSiteStep(deps = {}) {
|
|
|
653
772
|
};
|
|
654
773
|
if (!next) return finish(_extends({}, aiUnspentOutcome(model), init), builtPages());
|
|
655
774
|
const unit = units.find((one)=>one.slot === next.slot);
|
|
656
|
-
|
|
775
|
+
// The look is the scaffold's own pass (AGL-3660), not the theme job's proposal.
|
|
776
|
+
const catalog = unit.kind === 'products' ? runnerFor('products') : undefined;
|
|
777
|
+
const runner = unit.kind === 'theme' ? (lookContext)=>look(lookContext, lookContext.job) : unit.kind === 'posts' ? (_deps_posts = deps.posts) != null ? _deps_posts : runAiSitePostsUnit : unit.kind === 'products' ? (_deps_products = deps.products) != null ? _deps_products : catalog ? createAiSiteProductsRunner({
|
|
778
|
+
catalog
|
|
779
|
+
}) : undefined : runnerFor(unit.jobKind);
|
|
657
780
|
if (!runner) return _extends({}, aiUnspentOutcome(model), init);
|
|
658
781
|
const othersOpen = ledgerUnits.some((one)=>{
|
|
659
782
|
var _rows_get;
|
|
@@ -675,6 +798,33 @@ export function createAiJobSiteStep(deps = {}) {
|
|
|
675
798
|
}, item.status === 'running' || othersOpen ? {
|
|
676
799
|
continue: true
|
|
677
800
|
} : {});
|
|
801
|
+
/**
|
|
802
|
+
* A unit that failed or was skipped with nothing else open ends the job
|
|
803
|
+
* on this pass (AGL-3676): a guided start whose last unit — its welcome
|
|
804
|
+
* email — failed was never published, because the pass that publishes is
|
|
805
|
+
* the one after. So the end is the publish, whatever the last unit came to.
|
|
806
|
+
*/ const closing = async (outcome)=>outcome.continue ? outcome : finish(outcome, builtPages());
|
|
807
|
+
// A blog's posts and a store's products ask, before their first pass,
|
|
808
|
+
// whether this member may have them here (AGL-3676): a refusal spends
|
|
809
|
+
// nothing, and the row says why, as a build's item does.
|
|
810
|
+
if ((unit.kind === 'posts' || unit.kind === 'products') && ((_rows_get = rows.get(unit.slot)) == null ? void 0 : _rows_get.status) !== 'running') {
|
|
811
|
+
const refusal = await contentRefusal(unit.kind, _extends({}, context, {
|
|
812
|
+
job
|
|
813
|
+
})).catch((error)=>{
|
|
814
|
+
console.error('ai site part admission failed', {
|
|
815
|
+
orgId: job.orgId,
|
|
816
|
+
jobId: job.$id,
|
|
817
|
+
slot: unit.slot,
|
|
818
|
+
error
|
|
819
|
+
});
|
|
820
|
+
return AI_SITE_UNIT_EMPTY_COPY;
|
|
821
|
+
});
|
|
822
|
+
if (refusal) return closing(settle({
|
|
823
|
+
slot: unit.slot,
|
|
824
|
+
status: 'skipped',
|
|
825
|
+
note: `Not built: ${refusal}`
|
|
826
|
+
}));
|
|
827
|
+
}
|
|
678
828
|
// A page whose layout or form failed is built without it, and says so.
|
|
679
829
|
const degradation = aiBuildDegradation(next, {
|
|
680
830
|
units: ledgerUnits,
|
|
@@ -703,7 +853,7 @@ export function createAiJobSiteStep(deps = {}) {
|
|
|
703
853
|
slot: unit.slot,
|
|
704
854
|
error
|
|
705
855
|
});
|
|
706
|
-
return settle({
|
|
856
|
+
return closing(settle({
|
|
707
857
|
slot: unit.slot,
|
|
708
858
|
status: 'failed',
|
|
709
859
|
failure: {
|
|
@@ -711,16 +861,16 @@ export function createAiJobSiteStep(deps = {}) {
|
|
|
711
861
|
reason: 'provider',
|
|
712
862
|
message: AI_SITE_UNIT_EMPTY_COPY
|
|
713
863
|
}
|
|
714
|
-
});
|
|
864
|
+
}));
|
|
715
865
|
}
|
|
716
866
|
const spent = aiUnitSpend(outcome);
|
|
717
867
|
const stopped = aiUnitFailure(unit.slot, outcome);
|
|
718
868
|
if (stopped) {
|
|
719
|
-
return settle(stopped.status === 'failed' && stopped.failure && !outcome.failure && !outcome.refused && !outcome.review ? _extends({}, stopped, {
|
|
869
|
+
return closing(settle(stopped.status === 'failed' && stopped.failure && !outcome.failure && !outcome.refused && !outcome.review ? _extends({}, stopped, {
|
|
720
870
|
failure: _extends({}, stopped.failure, {
|
|
721
871
|
message: AI_SITE_UNIT_EMPTY_COPY
|
|
722
872
|
})
|
|
723
|
-
}) : stopped, spent);
|
|
873
|
+
}) : stopped, spent));
|
|
724
874
|
}
|
|
725
875
|
// A page counts as built only when its plan's sections are in it
|
|
726
876
|
// (AGL-3596): otherwise the page fails, on our side, and is not reported.
|
|
@@ -733,7 +883,7 @@ export function createAiJobSiteStep(deps = {}) {
|
|
|
733
883
|
draftId: page.id
|
|
734
884
|
}, readNodes);
|
|
735
885
|
if (!written) {
|
|
736
|
-
return settle({
|
|
886
|
+
return closing(settle({
|
|
737
887
|
slot: unit.slot,
|
|
738
888
|
status: 'failed',
|
|
739
889
|
failure: {
|
|
@@ -743,7 +893,7 @@ export function createAiJobSiteStep(deps = {}) {
|
|
|
743
893
|
}
|
|
744
894
|
}, _extends({}, spent, {
|
|
745
895
|
outputs: spent.outputs.filter((output)=>output.resource !== 'screen')
|
|
746
|
-
}));
|
|
896
|
+
})));
|
|
747
897
|
}
|
|
748
898
|
}
|
|
749
899
|
const done = settle(_extends({
|
|
@@ -770,19 +920,25 @@ export const runAiJobSiteStep = createAiJobSiteStep();
|
|
|
770
920
|
* for a page. A scaffold with nothing left to build, or with no plan it can
|
|
771
921
|
* build, spends nothing, and a page pass's time covers it.
|
|
772
922
|
*/ export function aiSiteJobRunMinimumMs(job) {
|
|
773
|
-
var _job_outputs;
|
|
774
|
-
var
|
|
923
|
+
var _job_items, _job_outputs;
|
|
924
|
+
var _job_items1;
|
|
775
925
|
const plan = aiConfirmedPlan(job);
|
|
776
926
|
const inputs = parseAiSiteJobInputs(job.inputs);
|
|
777
927
|
if (!plan || typeof inputs === 'string') return AI_JOB_PAGE_STEP_MINIMUM_MS;
|
|
928
|
+
// The org is not read here, so a blog's or a store's part is counted as a
|
|
929
|
+
// paid plan's; a ledger, once the job has one, says which units it owes.
|
|
930
|
+
const owed = new Set(((_job_items = job.items) != null ? _job_items : []).map((row)=>row.slot));
|
|
778
931
|
const units = aiSiteJobUnits(plan, {
|
|
779
|
-
welcomeEmail: inputs.welcomeEmail
|
|
780
|
-
|
|
932
|
+
welcomeEmail: inputs.welcomeEmail,
|
|
933
|
+
content: aiSiteContentPart(job.inputs, false)
|
|
934
|
+
}).filter((unit)=>(unit.kind === 'theme' || unit.kind === 'posts' || aiJobStepRunnerFor(unit.jobKind)) && (!owed.size || owed.has(unit.slot)));
|
|
781
935
|
const outputs = (_job_outputs = job.outputs) != null ? _job_outputs : [];
|
|
782
|
-
const ledger = ((
|
|
936
|
+
const ledger = ((_job_items1 = job.items) == null ? void 0 : _job_items1.length) ? job.items : aiSiteInitialLedger(units, outputs);
|
|
783
937
|
const next = aiBuildNextUnit(aiSiteLedgerUnits(units), ledger);
|
|
784
938
|
const unit = next ? units.find((one)=>one.slot === next.slot) : undefined;
|
|
785
939
|
if (!unit) return AI_JOB_PAGE_STEP_MINIMUM_MS;
|
|
940
|
+
if (unit.kind === 'theme') return AI_SITE_LOOK_BUDGET.minimumMs;
|
|
941
|
+
if (unit.kind === 'posts') return AI_SITE_POST_BUDGET.minimumMs;
|
|
786
942
|
return aiJobStepRunMinimumMs(aiSiteUnitJob(job, unit, aiBuildBuiltRefs(aiSiteLedgerUnits(units), ledger, outputs)));
|
|
787
943
|
}
|
|
788
944
|
/**
|