@aglyn/plugins-ai 1.0.0-beta.239 → 1.0.0-beta.241
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/components/ai-job-links.d.ts +17 -0
- package/src/lib/components/ai-job-links.js +63 -0
- package/src/lib/components/ai-job-links.js.map +1 -1
- package/src/lib/components/ai-job-plan.component.js +8 -1
- package/src/lib/components/ai-job-plan.component.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +5 -0
- package/src/lib/components/ai-job-requests.js +4 -2
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-site-build-page.component.js +7 -1
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-store-finish-card.component.d.ts +28 -0
- package/src/lib/components/ai-store-finish-card.component.js +116 -0
- package/src/lib/components/ai-store-finish-card.component.js.map +1 -0
- package/src/lib/components/assist-build-card.component.js +12 -1
- package/src/lib/components/assist-build-card.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.js +14 -2
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/jobs/ai-job-build-step.d.ts +45 -1
- package/src/lib/jobs/ai-job-build-step.js +283 -7
- package/src/lib/jobs/ai-job-build-step.js.map +1 -1
- package/src/lib/jobs/ai-job-drafts.d.ts +9 -1
- package/src/lib/jobs/ai-job-drafts.js +4 -1
- package/src/lib/jobs/ai-job-drafts.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.d.ts +3 -0
- package/src/lib/jobs/ai-job-layout-language.js +11 -4
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-step.js +3 -1
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +2 -1
- package/src/lib/jobs/ai-job-page-language.js +26 -9
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-sections.d.ts +11 -0
- package/src/lib/jobs/ai-job-page-sections.js +53 -5
- package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.d.ts +2 -1
- package/src/lib/jobs/ai-job-page-step.js +51 -10
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +12 -0
- package/src/lib/jobs/ai-job-plan-step.js +41 -7
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-datasets.d.ts +89 -2
- package/src/lib/jobs/ai-job-site-datasets.js +239 -15
- package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +18 -2
- package/src/lib/jobs/ai-job-site-step.js +109 -22
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-store-pages.d.ts +75 -0
- package/src/lib/jobs/ai-job-site-store-pages.js +195 -0
- package/src/lib/jobs/ai-job-site-store-pages.js.map +1 -0
- package/src/lib/jobs/ai-job-store-links-layout.d.ts +71 -0
- package/src/lib/jobs/ai-job-store-links-layout.js +95 -0
- package/src/lib/jobs/ai-job-store-links-layout.js.map +1 -0
- package/src/lib/jobs/ai-layout-stock-photos.d.ts +69 -3
- package/src/lib/jobs/ai-layout-stock-photos.js +603 -42
- package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
- package/src/lib/jobs/ai-site-publish.d.ts +18 -0
- package/src/lib/jobs/ai-site-publish.js +76 -15
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/jobs/fixtures/ai-stock-photo-ember-oak-hits.d.ts +43 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-ember-oak-hits.js +61 -0
- package/src/lib/jobs/fixtures/ai-stock-photo-ember-oak-hits.js.map +1 -0
- package/src/lib/layout-language/ai-layout-compiler.js +25 -2
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
- package/src/lib/layout-language/ai-layout-frame.d.ts +10 -0
- package/src/lib/layout-language/ai-layout-frame.js +58 -4
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
- package/src/lib/layout-language/ai-layout-listings.d.ts +6 -0
- package/src/lib/layout-language/ai-layout-listings.js +3 -0
- package/src/lib/layout-language/ai-layout-listings.js.map +1 -1
- package/src/lib/layout-language/ai-layout-pictures.js +12 -4
- package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
- package/src/lib/model/ai-build-job.d.ts +2 -0
- package/src/lib/model/ai-build-job.js +23 -3
- package/src/lib/model/ai-build-job.js.map +1 -1
- package/src/lib/model/ai-build-plan.d.ts +7 -0
- package/src/lib/model/ai-build-plan.js.map +1 -1
- package/src/lib/model/ai-build-progress.js +3 -1
- package/src/lib/model/ai-build-progress.js.map +1 -1
- package/src/lib/model/ai-build-store-pages.d.ts +133 -0
- package/src/lib/model/ai-build-store-pages.js +209 -0
- package/src/lib/model/ai-build-store-pages.js.map +1 -0
- package/src/lib/model/ai-layout-store-links.d.ts +64 -0
- package/src/lib/model/ai-layout-store-links.js +165 -0
- package/src/lib/model/ai-layout-store-links.js.map +1 -0
- package/src/lib/model/ai-site-inventory.d.ts +5 -0
- package/src/lib/model/ai-site-inventory.js.map +1 -1
- package/src/lib/model/ai-site-store-pages.d.ts +192 -0
- package/src/lib/model/ai-site-store-pages.js +383 -0
- package/src/lib/model/ai-site-store-pages.js.map +1 -0
- package/src/lib/runtime/ai-doctrine-validators.d.ts +44 -0
- package/src/lib/runtime/ai-doctrine-validators.js +177 -0
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +3 -2
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/site-inventory.js +8 -3
- package/src/lib/runtime/site-inventory.js.map +1 -1
- package/src/lib/testing/stand-in-dataset-index.js +8 -4
- package/src/lib/testing/stand-in-dataset-index.js.map +1 -1
|
@@ -38,6 +38,10 @@ import { AI_LAYOUT_FORM_PAGE_INPUT, AI_LAYOUT_LANGUAGE_INPUT, aiLayoutFormPageOf
|
|
|
38
38
|
import { aiDatasetListingsOf } from "./ai-job-site-datasets.js";
|
|
39
39
|
import { AI_FORM_DATASET_MADE_INPUT } from "./ai-job-form-dataset.js";
|
|
40
40
|
import { AI_LAYOUT_LISTINGS_INPUT } from "../layout-language/ai-layout-listings.js";
|
|
41
|
+
import { AI_BUILD_STORE_OP, AI_BUILD_STORE_PAGES_PRESENT_NOTE, aiBuildStoreLayoutLinks, aiBuildStoreLayoutOf, aiBuildStorePagesOf, aiBuildStorePagesStillMissing } from "../model/ai-build-store-pages.js";
|
|
42
|
+
import { writeAiStoreLinksLayoutDraft } from "./ai-job-store-links-layout.js";
|
|
43
|
+
import { AI_SITE_STORE_LINKS_INPUT, AI_SITE_STORE_PAGES_NOTE, aiStoreFrameLinks, aiStorePagesToWrite } from "../model/ai-site-store-pages.js";
|
|
44
|
+
import { AI_SITE_STORE_PAGES_INPUT, aiSiteStorePageId, aiSiteStorePagesRefusal, runAiSiteStorePagesUnit } from "./ai-job-site-store-pages.js";
|
|
41
45
|
import { AI_JOB_BRIEF_MAX_CHARS } from "./ai-job-text-step.js";
|
|
42
46
|
import { aiJobPublishesBuild, aiPublishGuidedSite } from "./ai-site-publish.js";
|
|
43
47
|
import { AI_PLANNED_JOB_KINDS, aiJobStepRunMinimumMs, aiJobStepRunnerFor, registerAiJobStep, registerAiJobStepPasses } from "./ai-jobs.js";
|
|
@@ -78,7 +82,7 @@ import { AI_PLANNED_JOB_KINDS, aiJobStepRunMinimumMs, aiJobStepRunnerFor, regist
|
|
|
78
82
|
* The most passes a build's step may take: every unit at a page's worst — its
|
|
79
83
|
* sections and its listing — so a runner that never finishes is still
|
|
80
84
|
* bounded while the largest plan is not. Try again starts the count over.
|
|
81
|
-
*/ export const AI_BUILD_MAX_PASSES = AI_BUILD_LIMITS.units * (AI_SITE_MAX_SECTIONS + 1);
|
|
85
|
+
*/ export const AI_BUILD_MAX_PASSES = AI_BUILD_LIMITS.units * (AI_SITE_MAX_SECTIONS + 1) + 1;
|
|
82
86
|
/** The job kind a creation of the build is built by. */ const CREATION_JOB_KINDS = {
|
|
83
87
|
layout: 'layout',
|
|
84
88
|
form: 'form',
|
|
@@ -221,6 +225,10 @@ import { AI_PLANNED_JOB_KINDS, aiJobStepRunMinimumMs, aiJobStepRunnerFor, regist
|
|
|
221
225
|
const listings = aiDatasetListingsOf(datasets, plan.screens);
|
|
222
226
|
if (listings.length) inputs[AI_LAYOUT_LISTINGS_INPUT] = listings;
|
|
223
227
|
}
|
|
228
|
+
// A build that makes the site a store links its account and policies from
|
|
229
|
+
// the layout it makes (AGL-3676), by path: they are written after it.
|
|
230
|
+
const storePages = aiBuildStorePagesOf(plan);
|
|
231
|
+
if (context.kind === 'layout' && storePages) inputs[AI_SITE_STORE_LINKS_INPUT] = aiStoreFrameLinks(storePages.pages);
|
|
224
232
|
return _extends({}, job, {
|
|
225
233
|
$id: aiBuildUnitJobId(job, unit),
|
|
226
234
|
kind: context.kind,
|
|
@@ -239,6 +247,139 @@ import { AI_PLANNED_JOB_KINDS, aiJobStepRunMinimumMs, aiJobStepRunnerFor, regist
|
|
|
239
247
|
failure
|
|
240
248
|
}, extra);
|
|
241
249
|
}
|
|
250
|
+
/** The site's pages as a store's own pages are checked against them (AGL-3676): every page that is not deleted. */ export async function readAiStoreSitePages(firestore, hostId) {
|
|
251
|
+
const snapshot = await firestore.collection('hosts').doc(hostId).collection('screens').select('displayName', 'slug', 'kind', 'deletedAt', 'layoutId').get();
|
|
252
|
+
return snapshot.docs.flatMap((doc)=>{
|
|
253
|
+
var _doc_get, _doc_get1;
|
|
254
|
+
const kind = doc.get('kind');
|
|
255
|
+
if (doc.get('deletedAt') || kind && kind !== 'template') return [];
|
|
256
|
+
const slug = String((_doc_get = doc.get('slug')) != null ? _doc_get : '');
|
|
257
|
+
const layoutId = doc.get('layoutId');
|
|
258
|
+
return slug ? [
|
|
259
|
+
{
|
|
260
|
+
id: doc.id,
|
|
261
|
+
slug,
|
|
262
|
+
title: String((_doc_get1 = doc.get('displayName')) != null ? _doc_get1 : ''),
|
|
263
|
+
template: kind === 'template',
|
|
264
|
+
layoutId: typeof layoutId === 'string' && layoutId ? layoutId : null
|
|
265
|
+
}
|
|
266
|
+
] : [];
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* What a build's store pages unit is told (AGL-3676): the pages its plan kept,
|
|
271
|
+
* less any the site has gained since — never counting the pages this unit
|
|
272
|
+
* wrote itself on an earlier pass, which it finds again by their ids — what
|
|
273
|
+
* their words link, and the layout they render inside: the plan's Shop
|
|
274
|
+
* page's, else the site's own (`aiBuildStoreLayoutOf`).
|
|
275
|
+
*/ export function aiBuildStorePagesInput(job, context) {
|
|
276
|
+
var _job_outputs;
|
|
277
|
+
const plan = job.plan;
|
|
278
|
+
const kept = aiBuildStorePagesOf(plan);
|
|
279
|
+
if (!kept) return null;
|
|
280
|
+
const own = new Set(kept.pages.map((page)=>aiSiteStorePageId(context.unitJobId, page.key)));
|
|
281
|
+
const pages = aiBuildStorePagesStillMissing(kept.pages, context.sitePages.filter((page)=>!page.id || !own.has(page.id)));
|
|
282
|
+
const built = aiBuildBuiltRefs(context.units, context.ledger, (_job_outputs = job.outputs) != null ? _job_outputs : []);
|
|
283
|
+
const shop = plan.screens.find((screen)=>!screen.record && screen.slug.replace(/^\/+/, '').split('/')[0].toLowerCase() === kept.facts.shopPath.slice(1));
|
|
284
|
+
const layout = shop ? aiSiteResolvedRef(shop.layout, built) : null;
|
|
285
|
+
return {
|
|
286
|
+
pages,
|
|
287
|
+
facts: kept.facts,
|
|
288
|
+
layoutId: aiBuildStoreLayoutOf(layout && !isAiPlanNewRef(layout) ? layout : null, context.sitePages)
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Adds a store's links to the site's own layout (AGL-3676), as a draft
|
|
293
|
+
* version, where the build made no layout of its own for its store pages: the
|
|
294
|
+
* outputs that record it — the layout version written (`storeLinks: draft`),
|
|
295
|
+
* and on the first page `storeLinks: missing` where the layout had no header
|
|
296
|
+
* or footer list to add them to, or there is no layout at all.
|
|
297
|
+
*/ export async function aiBuildStoreLinksOutputs(firestore, input, write = writeAiStoreLinksLayoutDraft) {
|
|
298
|
+
var _outputs_find;
|
|
299
|
+
const outputs = input.outputs.map((output)=>_extends({}, output));
|
|
300
|
+
const layoutId = input.store.layoutId;
|
|
301
|
+
// A layout this build made was told the store's links as it was compiled.
|
|
302
|
+
if (layoutId && input.builtLayouts.has(layoutId)) return outputs;
|
|
303
|
+
const written = new Set(outputs.map((output)=>{
|
|
304
|
+
var _output_proposal;
|
|
305
|
+
return (_output_proposal = output.proposal) == null ? void 0 : _output_proposal['storePage'];
|
|
306
|
+
}).filter((key)=>typeof key === 'string'));
|
|
307
|
+
const links = aiBuildStoreLayoutLinks(input.store.pages, written);
|
|
308
|
+
const missing = ()=>{
|
|
309
|
+
var _first_proposal;
|
|
310
|
+
const [first, ...rest] = outputs;
|
|
311
|
+
const state = 'missing';
|
|
312
|
+
return first ? [
|
|
313
|
+
_extends({}, first, {
|
|
314
|
+
proposal: _extends({}, (_first_proposal = first.proposal) != null ? _first_proposal : {}, {
|
|
315
|
+
storeLinks: state
|
|
316
|
+
})
|
|
317
|
+
}),
|
|
318
|
+
...rest
|
|
319
|
+
] : outputs;
|
|
320
|
+
};
|
|
321
|
+
if (!layoutId || !input.job.hostId) return missing();
|
|
322
|
+
const hrefs = new Set([
|
|
323
|
+
...links.header,
|
|
324
|
+
...links.cart ? [
|
|
325
|
+
links.cart
|
|
326
|
+
] : [],
|
|
327
|
+
...links.footer
|
|
328
|
+
].map((link)=>link.href.slice(1)));
|
|
329
|
+
const screenPaths = {};
|
|
330
|
+
for (const page of input.sitePages){
|
|
331
|
+
const slug = page.slug.replace(/^\/+/, '').split('/')[0].toLowerCase();
|
|
332
|
+
if (page.id && hrefs.has(slug)) screenPaths[page.id] = slug;
|
|
333
|
+
}
|
|
334
|
+
const draft = await write(firestore, {
|
|
335
|
+
hostId: input.job.hostId,
|
|
336
|
+
layoutId,
|
|
337
|
+
versionId: `${input.unitJobId}-links`.slice(0, 64),
|
|
338
|
+
links,
|
|
339
|
+
screenPaths,
|
|
340
|
+
uid: input.job.createdBy,
|
|
341
|
+
aiJobId: aiOriginJobId(input.job),
|
|
342
|
+
now: input.now
|
|
343
|
+
});
|
|
344
|
+
if (draft.status === 'present') return outputs;
|
|
345
|
+
if (draft.status === 'gone') return missing();
|
|
346
|
+
const versionId = draft.versionId;
|
|
347
|
+
const layout = versionId ? [
|
|
348
|
+
{
|
|
349
|
+
resource: 'layout',
|
|
350
|
+
id: draft.layoutId,
|
|
351
|
+
versionId,
|
|
352
|
+
hostId: input.job.hostId,
|
|
353
|
+
hostSubdomain: (_outputs_find = outputs.find((output)=>output.hostSubdomain)) == null ? void 0 : _outputs_find.hostSubdomain,
|
|
354
|
+
label: draft.name,
|
|
355
|
+
note: 'A new draft version with Account and policy links. Visitors see it once it is published.',
|
|
356
|
+
proposal: {
|
|
357
|
+
storeLinks: 'draft',
|
|
358
|
+
links,
|
|
359
|
+
screenPaths
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
] : [];
|
|
363
|
+
return [
|
|
364
|
+
...draft.status === 'unrecognized' ? missing() : outputs,
|
|
365
|
+
...layout
|
|
366
|
+
];
|
|
367
|
+
}
|
|
368
|
+
/** The store's links a build drafted into the site's layout (AGL-3676), as its publish puts them live; `null` where it drafted none. */ export function aiBuildStoreLinksToPublish(outputs) {
|
|
369
|
+
var _ref;
|
|
370
|
+
var _draft_proposal, _draft_proposal1;
|
|
371
|
+
const draft = outputs.find((output)=>{
|
|
372
|
+
var _output_proposal;
|
|
373
|
+
return output.resource === 'layout' && ((_output_proposal = output.proposal) == null ? void 0 : _output_proposal['storeLinks']) === 'draft' && output.versionId;
|
|
374
|
+
});
|
|
375
|
+
if (!(draft == null ? void 0 : draft.versionId)) return null;
|
|
376
|
+
return {
|
|
377
|
+
layoutId: draft.id,
|
|
378
|
+
versionId: draft.versionId,
|
|
379
|
+
links: (_draft_proposal = draft.proposal) == null ? void 0 : _draft_proposal['links'],
|
|
380
|
+
screenPaths: (_ref = (_draft_proposal1 = draft.proposal) == null ? void 0 : _draft_proposal1['screenPaths']) != null ? _ref : {}
|
|
381
|
+
};
|
|
382
|
+
}
|
|
242
383
|
/** Whether a build's workspace spends the Free taste. */ export function aiBuildFreeTaste(org) {
|
|
243
384
|
return Boolean(org) && resolveEffectivePlan(org) === 'free';
|
|
244
385
|
}
|
|
@@ -248,7 +389,7 @@ import { AI_PLANNED_JOB_KINDS, aiJobStepRunMinimumMs, aiJobStepRunnerFor, regist
|
|
|
248
389
|
return (_data = (await firestore.collection('hosts').doc(hostId).get()).data()) != null ? _data : null;
|
|
249
390
|
}
|
|
250
391
|
export function createAiJobBuildStep(deps = {}) {
|
|
251
|
-
var _deps_runnerFor, _deps_writerFor, _deps_opsFor, _deps_admissionFor, _deps_pluginAdmission, _deps_readNodes, _deps_publish;
|
|
392
|
+
var _deps_runnerFor, _deps_writerFor, _deps_opsFor, _deps_admissionFor, _deps_pluginAdmission, _deps_readNodes, _deps_publish, _deps_storePages, _deps_storePagesRefusal, _deps_readSitePages, _deps_writeStoreLinks;
|
|
252
393
|
const runnerFor = (_deps_runnerFor = deps.runnerFor) != null ? _deps_runnerFor : aiJobStepRunnerFor;
|
|
253
394
|
const writerFor = (_deps_writerFor = deps.writerFor) != null ? _deps_writerFor : aiPluginDraftWriter;
|
|
254
395
|
const opsFor = (_deps_opsFor = deps.opsFor) != null ? _deps_opsFor : (context)=>aiBuildOps(context);
|
|
@@ -256,6 +397,10 @@ export function createAiJobBuildStep(deps = {}) {
|
|
|
256
397
|
const pluginAdmission = (_deps_pluginAdmission = deps.pluginAdmission) != null ? _deps_pluginAdmission : aiPluginDraftAdmissionRefusal;
|
|
257
398
|
const readNodes = (_deps_readNodes = deps.readNodes) != null ? _deps_readNodes : readAiDraftNodes;
|
|
258
399
|
const publish = (_deps_publish = deps.publish) != null ? _deps_publish : aiPublishGuidedSite;
|
|
400
|
+
const storePagesRunner = (_deps_storePages = deps.storePages) != null ? _deps_storePages : runAiSiteStorePagesUnit;
|
|
401
|
+
const storePagesRefusal = (_deps_storePagesRefusal = deps.storePagesRefusal) != null ? _deps_storePagesRefusal : aiSiteStorePagesRefusal;
|
|
402
|
+
const readSitePages = (_deps_readSitePages = deps.readSitePages) != null ? _deps_readSitePages : readAiStoreSitePages;
|
|
403
|
+
const writeStoreLinks = (_deps_writeStoreLinks = deps.writeStoreLinks) != null ? _deps_writeStoreLinks : writeAiStoreLinksLayoutDraft;
|
|
259
404
|
return async (context)=>{
|
|
260
405
|
var _ref, _context_org, _aiBuildOrder, _job_hostId, _job_hostId1, _ref1;
|
|
261
406
|
var _job_items, _rows_get;
|
|
@@ -292,14 +437,15 @@ export function createAiJobBuildStep(deps = {}) {
|
|
|
292
437
|
status: 'pending'
|
|
293
438
|
});
|
|
294
439
|
});
|
|
295
|
-
/** The build's last pass puts its pages live, where it was asked and confirmed. */ const finish = async (outcome, extraPages = [])=>{
|
|
296
|
-
var _job_outputs;
|
|
440
|
+
/** The build's last pass puts its pages live, where it was asked and confirmed. */ const finish = async (outcome, extraPages = [], extraOutputs = [])=>{
|
|
441
|
+
var _job_outputs, _job_outputs1;
|
|
297
442
|
if (!aiJobPublishesBuild(job) || job.sitePublish || !job.hostId) return outcome;
|
|
298
443
|
// A record template renders once per record only once its binding is
|
|
299
444
|
// saved, so it is never published at its own address (AGL-3616).
|
|
445
|
+
// A store's own pages (AGL-3676) go live with the pages the build planned.
|
|
300
446
|
const pageIds = new Set(units.filter((one)=>{
|
|
301
447
|
var _rows_get;
|
|
302
|
-
return one.screen && !one.screen.record && aiBuildItemDelivered((_rows_get = rows.get(one.slot)) != null ? _rows_get : {
|
|
448
|
+
return (one.screen && !one.screen.record || one.op === AI_BUILD_STORE_OP) && aiBuildItemDelivered((_rows_get = rows.get(one.slot)) != null ? _rows_get : {
|
|
303
449
|
status: 'pending'
|
|
304
450
|
});
|
|
305
451
|
}).flatMap((one)=>{
|
|
@@ -314,11 +460,26 @@ export function createAiJobBuildStep(deps = {}) {
|
|
|
314
460
|
if (!pages.length) return outcome;
|
|
315
461
|
// A canceled build never puts anything live (AGL-3616): its pages stay drafts.
|
|
316
462
|
if (await aiJobCancelAsked(firestore, job, context.signal)) return outcome;
|
|
317
|
-
|
|
463
|
+
// The store pages a layout this build made links and that were not written come out of it.
|
|
464
|
+
const storePages = aiBuildStorePagesOf(plan);
|
|
465
|
+
const live = new Set(pages.map((page)=>{
|
|
466
|
+
var _page_proposal;
|
|
467
|
+
return (_page_proposal = page.proposal) == null ? void 0 : _page_proposal['storePage'];
|
|
468
|
+
}).filter(Boolean));
|
|
469
|
+
const unwrittenHrefs = storePages ? aiStorePagesToWrite(storePages.pages).filter((page)=>!live.has(page.key)).map((page)=>page.href) : [];
|
|
470
|
+
const storeLinks = aiBuildStoreLinksToPublish([
|
|
471
|
+
...(_job_outputs1 = job.outputs) != null ? _job_outputs1 : [],
|
|
472
|
+
...extraOutputs
|
|
473
|
+
]);
|
|
474
|
+
const sitePublish = await publish(firestore, _extends({
|
|
318
475
|
job,
|
|
319
476
|
outputs: pages,
|
|
320
477
|
now: context.now
|
|
321
|
-
}
|
|
478
|
+
}, unwrittenHrefs.length ? {
|
|
479
|
+
unwrittenHrefs
|
|
480
|
+
} : {}, storeLinks ? {
|
|
481
|
+
storeLinks
|
|
482
|
+
} : {})).catch((error)=>{
|
|
322
483
|
console.error('ai build publish threw', {
|
|
323
484
|
orgId: job.orgId,
|
|
324
485
|
jobId: job.$id,
|
|
@@ -350,6 +511,121 @@ export function createAiJobBuildStep(deps = {}) {
|
|
|
350
511
|
degradedBy: degradation.degradedBy
|
|
351
512
|
});
|
|
352
513
|
}
|
|
514
|
+
// A store's own pages (AGL-3676): written by code, behind the site start's gate.
|
|
515
|
+
if (unit.op === AI_BUILD_STORE_OP) {
|
|
516
|
+
var _job_outputs;
|
|
517
|
+
var _rows_get1;
|
|
518
|
+
if (!job.hostId) return settle({
|
|
519
|
+
slot: unit.slot,
|
|
520
|
+
status: 'skipped',
|
|
521
|
+
note: 'Not built: open the site first.'
|
|
522
|
+
});
|
|
523
|
+
if (((_rows_get1 = rows.get(unit.slot)) == null ? void 0 : _rows_get1.status) !== 'running') {
|
|
524
|
+
const refusal = await storePagesRefusal(_extends({}, context, {
|
|
525
|
+
job
|
|
526
|
+
})).catch((error)=>{
|
|
527
|
+
console.error('ai build store pages admission failed', {
|
|
528
|
+
orgId: job.orgId,
|
|
529
|
+
jobId: job.$id,
|
|
530
|
+
error
|
|
531
|
+
});
|
|
532
|
+
return AI_BUILD_UNIT_EMPTY_COPY;
|
|
533
|
+
});
|
|
534
|
+
if (refusal) return settle({
|
|
535
|
+
slot: unit.slot,
|
|
536
|
+
status: 'skipped',
|
|
537
|
+
note: `Not built: ${refusal}`
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
const unitJobId = aiBuildUnitJobId(job, unit);
|
|
541
|
+
const sitePages = await readSitePages(firestore, job.hostId);
|
|
542
|
+
const input = aiBuildStorePagesInput(job, {
|
|
543
|
+
unitJobId,
|
|
544
|
+
sitePages,
|
|
545
|
+
units,
|
|
546
|
+
ledger
|
|
547
|
+
});
|
|
548
|
+
if (!input) return settle({
|
|
549
|
+
slot: unit.slot,
|
|
550
|
+
status: 'skipped',
|
|
551
|
+
note: aiBuildUnavailableCopy('store page')
|
|
552
|
+
});
|
|
553
|
+
if (!aiStorePagesToWrite(input.pages).length) {
|
|
554
|
+
return settle({
|
|
555
|
+
slot: unit.slot,
|
|
556
|
+
status: 'skipped',
|
|
557
|
+
note: AI_BUILD_STORE_PAGES_PRESENT_NOTE
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
const derived = _extends({}, job, {
|
|
561
|
+
$id: unitJobId,
|
|
562
|
+
kind: 'text',
|
|
563
|
+
steps: [],
|
|
564
|
+
outputs: [],
|
|
565
|
+
items: null,
|
|
566
|
+
plan: null,
|
|
567
|
+
inputs: _extends({}, job.inputs, {
|
|
568
|
+
originJobId: aiOriginJobId(job),
|
|
569
|
+
[AI_SITE_STORE_PAGES_INPUT]: input
|
|
570
|
+
})
|
|
571
|
+
});
|
|
572
|
+
let outcome;
|
|
573
|
+
try {
|
|
574
|
+
outcome = await storePagesRunner(_extends({}, context, {
|
|
575
|
+
job: derived
|
|
576
|
+
}));
|
|
577
|
+
} catch (error) {
|
|
578
|
+
if (aiUnitErrorRetryable(error)) throw error;
|
|
579
|
+
console.error('ai build store pages threw', {
|
|
580
|
+
orgId: job.orgId,
|
|
581
|
+
jobId: job.$id,
|
|
582
|
+
error
|
|
583
|
+
});
|
|
584
|
+
return settle(failed(unit.slot, {
|
|
585
|
+
ours: true,
|
|
586
|
+
reason: 'step-failure',
|
|
587
|
+
message: AI_BUILD_UNIT_EMPTY_COPY
|
|
588
|
+
}));
|
|
589
|
+
}
|
|
590
|
+
const stopped = aiUnitFailure(unit.slot, outcome);
|
|
591
|
+
if (stopped) return settle(stopped, aiUnitSpend(outcome));
|
|
592
|
+
// The site's own header and footer link them (AGL-3676), in a draft
|
|
593
|
+
// version of its layout; a layout this build made already does.
|
|
594
|
+
const builtLayouts = new Set([
|
|
595
|
+
...aiBuildBuiltRefs(units, ledger, (_job_outputs = job.outputs) != null ? _job_outputs : []).values()
|
|
596
|
+
].filter((entry)=>entry.kind === 'layout').map((entry)=>entry.id));
|
|
597
|
+
const outputs = await aiBuildStoreLinksOutputs(firestore, {
|
|
598
|
+
job,
|
|
599
|
+
unitJobId,
|
|
600
|
+
store: input,
|
|
601
|
+
outputs: outcome.outputs,
|
|
602
|
+
sitePages,
|
|
603
|
+
builtLayouts,
|
|
604
|
+
now: context.now
|
|
605
|
+
}, writeStoreLinks).catch((error)=>{
|
|
606
|
+
console.error('ai build store links not written', {
|
|
607
|
+
orgId: job.orgId,
|
|
608
|
+
jobId: job.$id,
|
|
609
|
+
error
|
|
610
|
+
});
|
|
611
|
+
return outcome.outputs;
|
|
612
|
+
});
|
|
613
|
+
const ids = outputs.map((output)=>output.id);
|
|
614
|
+
const done = settle({
|
|
615
|
+
slot: unit.slot,
|
|
616
|
+
status: 'succeeded',
|
|
617
|
+
outputs: ids,
|
|
618
|
+
note: AI_SITE_STORE_PAGES_NOTE
|
|
619
|
+
}, _extends({}, aiUnitSpend(outcome), {
|
|
620
|
+
outputs
|
|
621
|
+
}));
|
|
622
|
+
if (done.continue) return done;
|
|
623
|
+
rows.set(unit.slot, _extends({}, rows.get(unit.slot), {
|
|
624
|
+
status: 'succeeded',
|
|
625
|
+
outputs: ids
|
|
626
|
+
}));
|
|
627
|
+
return finish(done, outputs.filter((output)=>output.resource === 'screen'), outputs);
|
|
628
|
+
}
|
|
353
629
|
const capability = ops.get(unit.op);
|
|
354
630
|
const noun = (_ref1 = capability == null ? void 0 : capability.noun) != null ? _ref1 : unit.op;
|
|
355
631
|
if (!capability) return settle({
|