@aglyn/plugins-ai 1.0.0-beta.244 → 1.0.0-beta.246
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 +3 -1
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/components/ai-job-links.js +7 -0
- package/src/lib/components/ai-job-links.js.map +1 -1
- package/src/lib/components/ai-product-zones.d.ts +3 -1
- package/src/lib/components/ai-product-zones.js.map +1 -1
- package/src/lib/components/ai-products-hub-card.component.js +1 -1
- package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
- package/src/lib/components/ai-products-proposals.component.js +17 -9
- package/src/lib/components/ai-products-proposals.component.js.map +1 -1
- package/src/lib/components/ai-site-start-card.component.js +6 -4
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/components/ai-upsell-dialog.component.js +1 -1
- package/src/lib/components/ai-upsell-dialog.component.js.map +1 -1
- package/src/lib/jobs/ai-build-capabilities.js +162 -2
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
- package/src/lib/jobs/ai-job-build-step.d.ts +7 -0
- package/src/lib/jobs/ai-job-build-step.js +85 -16
- package/src/lib/jobs/ai-job-build-step.js.map +1 -1
- package/src/lib/jobs/ai-job-duplicate-step.d.ts +123 -0
- package/src/lib/jobs/ai-job-duplicate-step.js +269 -0
- package/src/lib/jobs/ai-job-duplicate-step.js.map +1 -0
- package/src/lib/jobs/ai-job-layout-language.js +13 -0
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
- package/src/lib/jobs/ai-job-navigation-step.d.ts +157 -0
- package/src/lib/jobs/ai-job-navigation-step.js +439 -0
- package/src/lib/jobs/ai-job-navigation-step.js.map +1 -0
- package/src/lib/jobs/ai-job-page-language.d.ts +2 -1
- package/src/lib/jobs/ai-job-page-language.js +21 -5
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-sections.js +1 -1
- package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +4 -2
- package/src/lib/jobs/ai-job-plan-step.js +16 -7
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-products-step.d.ts +2 -2
- package/src/lib/jobs/ai-job-products-step.js +2 -2
- package/src/lib/jobs/ai-job-products-step.js.map +1 -1
- package/src/lib/jobs/ai-job-settings-step.d.ts +272 -0
- package/src/lib/jobs/ai-job-settings-step.js +695 -0
- package/src/lib/jobs/ai-job-settings-step.js.map +1 -0
- package/src/lib/jobs/ai-job-site-content.d.ts +20 -6
- package/src/lib/jobs/ai-job-site-content.js +28 -12
- package/src/lib/jobs/ai-job-site-content.js.map +1 -1
- package/src/lib/jobs/ai-job-site-datasets.d.ts +2 -0
- package/src/lib/jobs/ai-job-site-datasets.js +10 -3
- package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +3 -1
- package/src/lib/jobs/ai-job-site-step.js +70 -10
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-site-publish.d.ts +62 -4
- package/src/lib/jobs/ai-site-publish.js +203 -56
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/layout-language/ai-layout-compiler.d.ts +7 -4
- package/src/lib/layout-language/ai-layout-compiler.js +26 -25
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
- package/src/lib/layout-language/ai-layout-frame-hollows.d.ts +41 -0
- package/src/lib/layout-language/ai-layout-frame-hollows.js +330 -0
- package/src/lib/layout-language/ai-layout-frame-hollows.js.map +1 -0
- package/src/lib/layout-language/ai-layout-frame.d.ts +18 -1
- package/src/lib/layout-language/ai-layout-frame.js +83 -13
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
- package/src/lib/layout-language/ai-layout-listings.d.ts +35 -0
- package/src/lib/layout-language/ai-layout-listings.js +34 -0
- package/src/lib/layout-language/ai-layout-listings.js.map +1 -1
- package/src/lib/layout-language/ai-layout-tree.d.ts +2 -0
- package/src/lib/layout-language/ai-layout-tree.js +17 -0
- package/src/lib/layout-language/ai-layout-tree.js.map +1 -1
- package/src/lib/model/ai-build-job.d.ts +23 -0
- package/src/lib/model/ai-build-job.js +102 -13
- package/src/lib/model/ai-build-job.js.map +1 -1
- package/src/lib/model/ai-build-plan.d.ts +25 -0
- package/src/lib/model/ai-build-plan.js +45 -1
- package/src/lib/model/ai-build-plan.js.map +1 -1
- package/src/lib/model/ai-credit-estimate.d.ts +52 -0
- package/src/lib/model/ai-credit-estimate.js +51 -0
- package/src/lib/model/ai-credit-estimate.js.map +1 -1
- package/src/lib/model/ai-job-activity.js +4 -1
- package/src/lib/model/ai-job-activity.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +10 -2
- package/src/lib/model/ai-jobs.types.js +4 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-layout-menus.d.ts +104 -0
- package/src/lib/model/ai-layout-menus.js +518 -0
- package/src/lib/model/ai-layout-menus.js.map +1 -0
- package/src/lib/model/ai-products.d.ts +31 -1
- package/src/lib/model/ai-products.js +34 -1
- package/src/lib/model/ai-products.js.map +1 -1
- package/src/lib/model/ai-site-inventory.d.ts +15 -0
- package/src/lib/model/ai-site-inventory.js.map +1 -1
- package/src/lib/model/ai-site-job.d.ts +10 -0
- package/src/lib/model/ai-site-job.js +36 -9
- package/src/lib/model/ai-site-job.js.map +1 -1
- package/src/lib/model/ai-site-store-pages.js +1 -1
- package/src/lib/model/ai-site-store-pages.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.d.ts +53 -0
- package/src/lib/runtime/ai-doctrine-validators.js +166 -25
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +7 -2
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-palette.generated.js +1 -1
- package/src/lib/runtime/ai-palette.generated.js.map +1 -1
- package/src/lib/runtime/ai-products-generation.d.ts +4 -2
- package/src/lib/runtime/ai-products-generation.js +12 -6
- package/src/lib/runtime/ai-products-generation.js.map +1 -1
- package/src/lib/runtime/site-inventory.d.ts +12 -0
- package/src/lib/runtime/site-inventory.js +29 -1
- package/src/lib/runtime/site-inventory.js.map +1 -1
- package/src/lib/server.js +12 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/stand-in-dataset-index.js +37 -3
- package/src/lib/testing/stand-in-dataset-index.js.map +1 -1
- package/src/lib/tools/ai-products-tool.d.ts +3 -1
- package/src/lib/tools/ai-products-tool.js +15 -5
- package/src/lib/tools/ai-products-tool.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-page-language.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 { CANVAS_ROOT_ELEMENT_ID } from '@aglyn/aglyn/foundation/constants/canvas'\nimport type { NodesMap } from '@aglyn/aglyn/types/nodes'\nimport { isAiPlanNewRef, type AiBuildPlanScreen } from '../model/ai-build-plan'\nimport type { AiJob, AiJobPlan } from '../model/ai-jobs.types'\nimport {\n aiHomeScreenIds,\n type AiSiteInventory,\n} from '../model/ai-site-inventory'\nimport { AI_LAYOUT_POST_ADDRESS_TOKENS, aiCompileLayoutPage } from '../layout-language/ai-layout-compiler'\nimport { aiLayoutListingAt, aiLayoutListingsOf, type AiLayoutListing } from '../layout-language/ai-layout-listings'\nimport {\n AI_LAYOUT_LANGUAGE_TEXT,\n AI_LAYOUT_PAGE_TOOL,\n aiReadLayoutPage,\n type AiLayoutSection,\n type AiLayoutSettlement,\n} from '../layout-language/ai-layout-language'\nimport type {\n AiLayoutPage,\n AiLayoutTargets,\n} from '../layout-language/ai-layout-links'\nimport { aiLayoutCopyCheck } from '../layout-language/ai-layout-gaps'\nimport { aiLayoutStoredTree } from '../layout-language/ai-layout-store'\nimport { AI_GENERATION_MAX_ATTEMPTS } from '../runtime/ai-generation-bounds'\nimport { AI_STEP_TIERS } from '../providers/catalog'\nimport {\n runValidatedGeneration,\n type AiGenerationCheck,\n type AiGenerationSpend,\n type AiValidatedGeneration,\n} from '../runtime/ai-doctrine'\nimport type { AiUsage } from '../providers/contract'\nimport {\n aiSettleMechanicalRules,\n aiSettleUnrelatedScreenLinks,\n validateAiDoctrineTree,\n type AiDoctrineNode,\n type AiDoctrineTreeContext,\n type AiDoctrineViolation,\n} from '../runtime/ai-doctrine-validators'\nimport type { AiLoadEstimate } from '../runtime/ai-palette'\nimport { aiSiteKindDesignLines, aiSiteKindOfInputs } from '../model/ai-site-kinds'\nimport { aiSiteSeed } from '../model/ai-site-look'\nimport type { AiLayoutDesign } from '../layout-language/ai-layout-design'\nimport { aiOriginJobId } from './ai-job-draft-ids'\nimport type { AiSystemBlock } from '../runtime/ai-runtime'\nimport { aiGenerationWorstCaseOnTierMs, aiJobStepBudget } from './ai-job-budget'\nimport { aiJobBriefLine, aiPlanReferenceLines } from './ai-job-generation'\nimport { aiLayoutIsHomeSlug, aiLayoutSiteAliases, aiLayoutSitePages } from './ai-job-layout-site-pages'\nimport { aiLayoutInventedContactViolations } from './ai-layout-site-facts'\n\n/**\n * A page built in the compact layout language (AGL-3660): the page step's\n * pass for a site's page units — a guided start's and a build's — in place of\n * the raw-tree section passes.\n *\n * ONE answer a page: every planned section, in the language, through\n * `submit_page`. The compiler writes the tree, the palette validator stores\n * it as it stores any generated tree, and the doctrine checks the whole page.\n * A section the answer left out or left empty is the one thing a re-ask asks\n * for: the sections that read are kept, and the second answer fills only\n * what is still missing. Then the page step's last pass runs as it always\n * has — the whole page held to the doctrine again, its listing written, the\n * draft reported — so the item ledger, the credits and Try again work exactly\n * as they did.\n */\n\n/** The unit input that says a page or a layout is built in the layout language. */\nexport const AI_LAYOUT_LANGUAGE_INPUT = 'layoutLanguage'\n\n/** The unit input naming the page of the site that places its form, where it is another page. */\nexport const AI_LAYOUT_FORM_PAGE_INPUT = 'layoutFormPage'\n\n/** Whether this job builds its page or its layout in the layout language. */\nexport function aiJobUsesLayoutLanguage(job: Pick<AiJob, 'inputs'>): boolean {\n return job.inputs?.[AI_LAYOUT_LANGUAGE_INPUT] === true\n}\n\n/**\n * How the language doors think (AGL-3660): adaptively, at an effort named\n * rather than left to the model's default. Zach, 2026-10-07: quality first —\n * a page and a site's frame are designed, not transcribed, and the caching\n * work pays for the thinking. Medium is where Claude Sonnet 5.5, the balanced\n * default, is tuned to start for multistep design work.\n */\nexport const AI_LAYOUT_LANGUAGE_THINKING = { thinking: 'adaptive', effort: 'medium' } as const\n\n/**\n * Room for the thinking a page's answer does before it writes, inside the\n * same `max_tokens` as the answer: thinking is drawn from the ceiling first,\n * so a ceiling sized for the answer alone would cut a thoughtful answer off.\n *\n * Bounded by TIME, not by money: the page step's answer, its re-ask and the\n * follow-up must fit the least time a beat gives a step\n * (`AI_JOB_STEP_MAX_MINIMUM_MS`), and `aiJobStepBudget` quietly lowers every\n * ceiling to what fits. 2,000 here, with the follow-up's 500, is the most\n * that fits whole on the balanced tier; at 5,000 the budget cut a page's\n * ceiling to 879 tokens, under the answer itself.\n */\nexport const AI_LAYOUT_PAGE_THINKING_TOKENS = 2_000\n\n/** The same room for a site's header and footer, whose step has the time for more. */\nexport const AI_LAYOUT_FRAME_THINKING_TOKENS = 4_000\n\n/**\n * The most one page's answer asks for: the answer and the thinking before it.\n * A section in the language is about 120 to 250 tokens with its copy, so the\n * largest page a plan admits — eight sections — fits in 3,000 with room (the\n * live runs of 2026-10-07 wrote 683 to 1,745); the compiler, not the ceiling,\n * keeps a page small.\n */\nexport const AI_JOB_PAGE_LANGUAGE_TOKENS = 3_000 + AI_LAYOUT_PAGE_THINKING_TOKENS\n\n/**\n * The most one section of a page is written in, its copy included: the top of\n * the 120 to 250 tokens a section runs to. The Free site wall prices each\n * planned section at it (AGL-3660).\n */\nexport const AI_LAYOUT_SECTION_MOST_TOKENS = 250\n\n/**\n * The time a language page pass needs: its lookup rounds, its answer and its\n * re-ask at `AI_JOB_PAGE_LANGUAGE_TOKENS` on the tier the page step is served\n * from, with the step's reads and writes.\n */\n/** The most the follow-up asking only for the sections an answer left out may run to, its thinking included. */\nexport const AI_JOB_PAGE_LANGUAGE_FOLLOW_UP_TOKENS = 1_500 + 500\n\nexport const AI_JOB_PAGE_LANGUAGE_BUDGET = aiJobStepBudget({\n tier: AI_STEP_TIERS['job.page'],\n maxTokens: AI_JOB_PAGE_LANGUAGE_TOKENS,\n // The follow-up for sections an answer left out is one more generation.\n ownReadsMs: aiGenerationWorstCaseOnTierMs({\n tier: AI_STEP_TIERS['job.page'],\n maxTokens: AI_JOB_PAGE_LANGUAGE_FOLLOW_UP_TOKENS,\n }),\n})\n\n/** The doctrine scope the language doors are told: values the compiler checks itself. */\nexport const AI_LAYOUT_PAGE_KIND = 'layout-page'\n\n/** The language, as the page door's cached instructions. */\nexport const AI_JOB_PAGE_LANGUAGE_INSTRUCTIONS: readonly AiSystemBlock[] = [\n {\n text: [\n AI_LAYOUT_LANGUAGE_TEXT,\n '',\n 'Answer with submit_page: the whole page, one entry in sections for each planned section, in order.',\n ].join('\\n'),\n cacheBreakpoint: true,\n },\n]\n\n/** The page of a site plan that places its form: the form the plan creates, or one the site has. */\nexport function aiLayoutFormPageOfPlan(\n plan: Pick<AiJobPlan, 'create' | 'screens'>,\n formIds: readonly string[] = [],\n): string | null {\n const created = new Set(\n plan.create\n .filter((entry) => entry.kind === 'form')\n .map((entry) => `new:${entry.name}`.toLowerCase()),\n )\n const forms = new Set(formIds)\n const screen = plan.screens.find((entry) =>\n entry.sections.some((section) =>\n section.uses.some((ref) =>\n isAiPlanNewRef(ref) ? created.has(ref.toLowerCase()) : forms.has(ref),\n ),\n ),\n )\n return typeof screen?.id === 'string' ? screen.id : null\n}\n\n/** Every word the job was given, which a page's contact details are held to. */\nexport function aiLayoutFacts(job: Pick<AiJob, 'brief' | 'inputs'>): string {\n const values = Object.values(job.inputs ?? {}).filter(\n (value): value is string => typeof value === 'string',\n )\n return [job.brief, ...values].join('\\n')\n}\n\n/** What a page's links resolve against: the site's pages, built and planned, its forms and components. */\nexport function aiLayoutPageTargets(input: {\n job: Pick<AiJob, 'brief' | 'inputs'>\n inventory: AiSiteInventory | null\n own: ReadonlyArray<string | null | undefined>\n}): AiLayoutTargets {\n const { job, inventory } = input\n const own = input.own.filter((id): id is string => !!id)\n const planned = aiLayoutSitePages(job.inputs)\n const pages: AiLayoutPage[] = [\n ...planned,\n // Planned pages merged into the blog (AGL-3676): a link to one goes to the blog.\n ...aiLayoutSiteAliases(job.inputs).filter((alias) => !planned.some((page) => page.id === alias.id)),\n ...(inventory?.screens ?? [])\n .filter(\n (row) => !row.template && !planned.some((page) => page.id === row.id),\n )\n .map((row) => ({ id: row.id, label: row.name, slug: row.slug })),\n ]\n const formPage = job.inputs?.[AI_LAYOUT_FORM_PAGE_INPUT]\n return {\n pageId: own[0] ?? null,\n pages: pages.filter((page) => !own.includes(page.id)),\n homeIds: aiHomeScreenIds(inventory),\n forms: (inventory?.forms ?? []).map((form) => ({\n id: form.id,\n name: form.name,\n })),\n formPageId:\n typeof formPage === 'string' && !own.includes(formPage) ? formPage : null,\n components: (inventory?.components ?? []).map((component) => ({\n id: component.id,\n name: component.name,\n props: component.props,\n })),\n facts: aiLayoutFacts(job),\n // The site's catalog and blog, and the sections that list them (AGL-3676),\n // and its datasets (AGL-3616).\n listings: aiLayoutListingsWithDatasets(aiLayoutListingsOf(job.inputs), inventory),\n }\n}\n\n/**\n * A page's listings with each dataset's held to the site's inventory\n * (AGL-3616): a records listing is kept only where the site has the dataset —\n * the tree check admits a repeat over no other, and a card left repeating\n * over nothing would show its `{{item.*}}` — and one that names no fields\n * takes the inventory's, in the dataset's order.\n */\nexport function aiLayoutListingsWithDatasets(\n listings: readonly AiLayoutListing[],\n inventory: Pick<AiSiteInventory, 'datasets'> | null,\n): AiLayoutListing[] {\n return listings.flatMap((listing) => {\n if (listing.kind !== 'records') return [listing]\n const row = inventory?.datasets.find((dataset) => dataset.id === listing.datasetId)\n if (!row) return []\n // The photo field is the card's picture, never its words (AGL-3616).\n const imageField = listing.imageField ?? row.imageField\n const fields = (\n listing.fields?.length\n ? listing.fields\n : row.fields.map((name, index) => ({ id: row.fieldIds?.[index] || name, name, type: 'text' }))\n ).filter((field) => field.id !== imageField)\n return fields.length ? [{ ...listing, fields, ...(imageField ? { imageField } : {}) }] : []\n })\n}\n\n/**\n * The page check's context with what a section listing the blog's posts\n * binds (AGL-3676): each post's card links its post and shows its cover by\n * the tokens the page fills per post, which a page's store admits whole only\n * where a listing places them. A dataset's card shows its record's photo\n * the same way (AGL-3616), by `{{item.<photo field>}}`. And the page that\n * places the site's form, which a call to action asking a visitor to get in\n * touch links even when it is home (AGL-3729).\n */\nexport function aiLayoutListingContext(\n context: AiDoctrineTreeContext,\n targets: AiLayoutTargets,\n): AiDoctrineTreeContext {\n if (targets.formPageId) context = { ...context, formScreenIds: [targets.formPageId] }\n const here = (targets.listings ?? []).filter((listing) =>\n listing.placements.some((placement) => placement.screenId === targets.pageId),\n )\n const tokens = [\n ...(here.some((listing) => listing.kind === 'posts') ? AI_LAYOUT_POST_ADDRESS_TOKENS : []),\n ...here.flatMap((listing) => (listing.kind === 'records' && listing.imageField ? [`{{item.${listing.imageField}}}`] : [])),\n ]\n if (!tokens.length) return context\n return { ...context, bindingTokens: [...new Set([...(context.bindingTokens ?? []), ...tokens])] }\n}\n\n/** The page's user turn: the page, the brief, the plan, its sections and where its links may go. */\nexport function aiLayoutPagePrompt(input: {\n job: Pick<AiJob, 'brief' | 'inputs' | '$id'>\n plan: AiJobPlan\n screen: AiBuildPlanScreen\n targets: AiLayoutTargets\n reusableComponents: boolean\n /** The sections a re-ask still needs, by plan index; absent on the first ask. */\n missing?: readonly number[]\n}): string {\n const { job, plan, screen, targets } = input\n const sections = screen.sections.map((section, index) => {\n const places = section.uses.length\n ? `; places ${section.uses.join(', ')}`\n : ''\n // A section the site's records fill (AGL-3676): the platform places them,\n // so the design writes the words around them and no group for them.\n const listed = aiLayoutListingAt(targets.listings ?? [], targets.pageId, index)\n if (listed?.listing.kind === 'tracks') {\n // A music site's player (AGL-3716): placed empty, for the owner's own uploads.\n return `${index + 1}. \"${section.name}\"${places}; the platform places a music player here for the artist's own tracks, which they add themselves: write only its heading and a line inviting visitors to listen, and no cards, list, images or links for songs`\n }\n if (listed?.listing.kind === 'reviews') {\n // A store's own reviews (AGL-3676): shoppers write them; none is ever written here.\n return `${index + 1}. \"${section.name}\"${places}; the platform shows the store's real customer reviews here with their star ratings, once shoppers leave them: write only its heading, and no quotes, names, ratings or cards`\n }\n if (listed?.listing.kind === 'signup') {\n // A store's newsletter field (AGL-3676), placed by the platform.\n return `${index + 1}. \"${section.name}\"${places}; the platform places the newsletter sign-up field here: write its heading and one line on what subscribers hear about, from the brief, and no form, button or offer the brief does not make`\n }\n if (listed?.listing.kind === 'records') {\n // One of the site's datasets (AGL-3616), repeated by the platform over its records.\n const names = listed.listing.records.length ? ` (${listed.listing.records.slice(0, 6).map((name) => `“${name}”`).join(', ')})` : ''\n return `${index + 1}. \"${section.name}\"${places}; the platform lists the records of the dataset “${listed.listing.name}”${names} here itself, one card each: write only its heading and a line about them, and no cards, list or images for them`\n }\n if (listed) {\n return `${index + 1}. \"${section.name}\"${places}; the platform lists ${listed.listing.name}'s ${listed.listing.kind} here itself, with their photos and links: write only its heading and a line about them, and no cards, list or images for them`\n }\n const items = section.items ? `; shows ${section.items} items` : ''\n return `${index + 1}. \"${section.name}\"${places}${items}`\n })\n // A page merged into the blog is not offered: the blog is, by its own entry.\n const pages = targets.pages.filter((page) => !page.standsInFor).map((page) => `${page.label} (page:${page.id})`)\n const components = targets.components.map(\n (component) =>\n `${component.name} (${component.id}; props ${Object.keys(component.props).join(', ') || 'none'})`,\n )\n return [\n `Page: \"${screen.title}\" at ${screen.slug}`,\n aiJobBriefLine(job),\n // The kind of site the person picked sets how its pages are arranged (AGL-3660).\n ...aiSiteKindDesignLines(job.inputs),\n ...aiPlanReferenceLines(plan),\n `Sections to design, in order:`,\n ...sections,\n pages.length\n ? `Other pages of this site: ${pages.join(', ')}.`\n : 'This site has no other page to link.',\n targets.forms.length\n ? `The site's form: ${targets.forms.map((form) => `${form.name} (${form.id})`).join(', ')}.`\n : 'The site has no saved form: place none.',\n ...(components.length\n ? [`Components this page may place: ${components.join('; ')}.`]\n : []),\n input.reusableComponents\n ? 'Where a section repeats an item, place the component its plan line names with cards whose to is that component.'\n : 'This site keeps no reusable components: draw repeated items as cards, steps, stats or a list.',\n // A per-job word, so two identical briefs are designed apart.\n `Design seed: ${job.$id.slice(-6)}.`,\n ].join('\\n')\n}\n\n/**\n * The site a page is designed for (AGL-3660): the kind its job names, the\n * seed its look was drawn with — the same for every page of the site, so the\n * site reads as one design — and whether the page is its home. `null` for a\n * job that names no kind of site, which compiles the compiler's first way.\n */\nexport function aiLayoutDesignOf(job: Pick<AiJob, '$id' | 'inputs'>, slug: string): AiLayoutDesign | null {\n const kind = aiSiteKindOfInputs(job.inputs)\n if (!kind) return null\n const style = job.inputs?.['siteStyle'] as Record<string, unknown> | undefined\n const seed = typeof style?.['seed'] === 'number' && Number.isFinite(style['seed']) ? (style['seed'] as number) >>> 0 : aiSiteSeed(aiOriginJobId(job))\n return { kind: kind.id, seed, home: aiLayoutIsHomeSlug(slug) }\n}\n\n/** A validated language page, stored as the page keeps it. */\nexport interface AiLayoutPageBuilt {\n nodes: NodesMap\n load: AiLoadEstimate | null\n settled: AiLayoutSettlement[]\n /** What the last answer's gaps took out of the page (`ai-layout-gaps.ts`). */\n dropped: string[]\n /** How many repeated items each plan section shows, as built (AGL-3660). */\n items: number[]\n}\n\nexport interface AiLayoutPageCheckInput {\n screen: AiBuildPlanScreen\n sectionIds: readonly string[]\n targets: AiLayoutTargets\n context: AiDoctrineTreeContext\n reusableComponents: boolean\n /**\n * What earlier answers gave, by plan index, shared between the page's\n * generations: a follow-up asking only for missing sections fills the rest.\n */\n kept?: Array<AiLayoutSection | null>\n /** The plan indices this answer's sections fill, in order; absent, every section. */\n only?: readonly number[]\n /** The site the page is drawn for (`aiLayoutDesignOf`); absent, the compiler's first design. */\n design?: AiLayoutDesign | null\n}\n\n/**\n * The follow-up turn for the sections a page's answer left out (AGL-3660):\n * the page as before, told which sections it already has, and asked for only\n * the missing ones, in order — the one part of a page asked for again.\n */\nexport function aiLayoutMissingSectionsPrompt(input: {\n base: string\n screen: AiBuildPlanScreen\n missing: readonly number[]\n}): string {\n const names = input.missing.map((index) => `${index + 1}. \"${input.screen.sections[index].name}\"`)\n return [\n input.base,\n '',\n `The other sections of this page are already designed. Design ONLY these, in this order, one entry in sections each: ${names.join('; ')}. Give each at least one block.`,\n ].join('\\n')\n}\n\n/** The plan indices a page still lacks, after the answers so far. */\nexport function aiLayoutMissingSections(kept: ReadonlyArray<AiLayoutSection | null>): number[] {\n return kept.flatMap((section, index) => (section ? [] : [index]))\n}\n\n/** The violation a planned section the answer gave nothing usable for is named by. */\nexport const AI_LAYOUT_SECTION_MISSING_CODE = 'layout-section-missing'\n\n/** The code a section planned with items that shows none is refused under (AGL-3660). */\nexport const AI_LAYOUT_SECTION_EMPTY_CODE = 'layout-section-no-items'\n\n/** How many of a section's planned items it must show: one for a short list, two for anything longer. */\nconst leastItems = (planned: number) => (planned >= 3 ? 2 : planned >= 1 ? 1 : 0)\n\n/**\n * How many repeated items each section shows once stored (AGL-3660): the\n * elements the compiler drew for them, under the ids they are stored by,\n * that are still in the page after anything later took words out.\n */\nexport function aiLayoutShownItems(\n itemIds: readonly (readonly string[])[],\n storedIds: Readonly<Record<string, string>>,\n nodes: Readonly<Record<string, unknown>>,\n): number[] {\n return itemIds.map((ids) => ids.filter((id) => storedIds[id] !== undefined && storedIds[id] in nodes).length)\n}\n\n/**\n * The sections a page planned with repeated items — cards, steps, a list —\n * that show none, or too few, once the page is built (AGL-3660). A heading\n * and an intro over nothing is a section a visitor reads as broken, so it is\n * asked for again.\n */\nexport function aiLayoutEmptyItemSections(\n screen: Pick<AiBuildPlanScreen, 'sections'>,\n items: readonly number[],\n /** Sections whose only items were customer quotes, which no answer may give (AGL-3676). */\n quotesOnly: readonly number[] = [],\n): AiDoctrineViolation[] {\n return screen.sections.flatMap((section, index): AiDoctrineViolation[] => {\n if (quotesOnly.includes(index)) return []\n const least = leastItems(section.items)\n if (!least) return []\n const shown = items[index] ?? 0\n if (shown >= least) return []\n return [\n {\n rule: null,\n code: AI_LAYOUT_SECTION_EMPTY_CODE,\n message: `Section ${index + 1} (\"${section.name}\") is planned with ${section.items} items and shows ${shown || 'none'}.`,\n detail: `Give section ${index + 1} one cards, steps, stats, list or faq block holding its ${section.items} items, each with a title and its words.`,\n },\n ]\n })\n}\n\n/**\n * The check a language page answer is held to: each planned section read,\n * the page compiled, stored and checked whole. Sections that read are kept\n * across the re-ask, so the second answer is asked only for what was missing,\n * and a section it sends again that already read is not taken twice.\n */\nexport function aiLayoutPageCheck(\n input: AiLayoutPageCheckInput,\n): AiGenerationCheck<AiLayoutPageBuilt> {\n const kept: Array<AiLayoutSection | null> = input.kept ?? input.screen.sections.map(() => null)\n const fills = input.only ?? input.screen.sections.map((_, index) => index)\n const context = aiLayoutListingContext(input.context, input.targets)\n let answers = 0\n return (answer) => {\n // The last answer a generation takes has its gaps taken out rather than asked about again.\n answers += 1\n const last = answers >= AI_GENERATION_MAX_ATTEMPTS\n const reading = aiReadLayoutPage(\n answer,\n fills.length,\n fills.map((index) => input.screen.sections[index]),\n )\n reading.sections.forEach((section, position) => {\n // A section the answer gives is taken as given; one it leaves out keeps\n // what an earlier answer gave, so a re-ask may send only what was missing.\n if (section) kept[fills[position]] = section\n })\n const missing = kept.flatMap((section, index) => (section ? [] : [index]))\n if (missing.length) {\n const names = missing.map(\n (index) => `${index + 1} (\"${input.screen.sections[index].name}\")`,\n )\n return {\n value: null,\n violations: [\n {\n rule: null,\n code: AI_LAYOUT_SECTION_MISSING_CODE,\n message: `The page left out section ${names.join(', ')}.`,\n detail: `Answer again with every section in order; the sections you already designed are kept, so only ${names.join(', ')} ${missing.length === 1 ? 'needs' : 'need'} its design. Give each at least one block.`,\n },\n ],\n }\n }\n const compiled = aiCompileLayoutPage(\n kept as AiLayoutSection[],\n { title: input.screen.title, sections: input.screen.sections },\n input.targets,\n {\n reusableComponents: input.reusableComponents,\n sectionIds: input.sectionIds,\n ...(input.design ? { design: input.design } : {}),\n },\n )\n const stored = aiLayoutStoredTree(\n compiled.tree,\n 'screen',\n context,\n input.sectionIds,\n )\n if (stored.ok === false) {\n // The compiler writes only palette trees, which the property spec holds;\n // a refusal here is the platform's, and is reported as one.\n console.error('ai layout page: a compiled page did not store', {\n error: stored.error,\n })\n return {\n value: null,\n violations: [\n {\n rule: null,\n code: 'layout-compile',\n message: 'This page could not be built. Try again.',\n detail: stored.error,\n },\n ],\n }\n }\n // No gap and no internal reference in the words of a page that is published as built.\n const copy = aiLayoutCopyCheck(\n stored.nodes,\n CANVAS_ROOT_ELEMENT_ID,\n {\n pages: input.targets.pages,\n ids: [\n ...input.targets.pages.map((page) => page.id),\n ...input.targets.forms.map((form) => form.id),\n ...input.targets.components.map((component) => component.id),\n ...input.sectionIds,\n ...(input.targets.pageId ? [input.targets.pageId] : []),\n ],\n },\n last,\n )\n const { dropped } = copy\n // An attribute a rule has one answer for is settled, not asked of the model again (AGL-3660),\n // and a link sent home for nothing is sent to the form or left out (AGL-3729).\n const nodes = aiSettleUnrelatedScreenLinks(\n aiSettleMechanicalRules(\n { rootId: CANVAS_ROOT_ELEMENT_ID, nodes: copy.nodes as unknown as Record<string, AiDoctrineNode> },\n 'page',\n ),\n 'page',\n { ...context, ownScreenIds: input.targets.pageId ? [input.targets.pageId] : [] },\n ).nodes as unknown as typeof copy.nodes\n const report = validateAiDoctrineTree(\n { rootId: CANVAS_ROOT_ELEMENT_ID, nodes },\n 'page',\n {\n ...context,\n scrollTargetIds: input.sectionIds,\n // The layout language draws its own picture cards (AGL-3660).\n repeatsCompiled: true,\n },\n )\n // Each section's items as they are stored, after anything the gaps took out.\n const items = aiLayoutShownItems(compiled.itemIds, stored.storedIds, nodes as unknown as Record<string, unknown>)\n // A street address or opening hours the job was never given is invented\n // (rule 14, AGL-3596), the same check a layout is held to; a phone number\n // or an email the compiler already writes as its gap.\n const violations: AiDoctrineViolation[] = [\n ...report.violations,\n ...copy.violations,\n ...aiLayoutEmptyItemSections(input.screen, items, compiled.quotesOnly),\n ...aiLayoutInventedContactViolations(\n { rootId: CANVAS_ROOT_ELEMENT_ID, nodes: nodes as unknown as Record<string, AiDoctrineNode> },\n input.targets.facts,\n ),\n ]\n return {\n value: violations.length\n ? null\n : {\n nodes,\n load: report.load,\n settled: [...reading.settled, ...compiled.settled],\n dropped,\n items,\n },\n violations,\n }\n }\n}\n\nexport interface AiLayoutPageRunInput {\n job: Pick<AiJob, 'brief' | 'inputs' | '$id'>\n plan: AiJobPlan\n screen: AiBuildPlanScreen\n sectionIds: readonly string[]\n targets: AiLayoutTargets\n context: AiDoctrineTreeContext\n reusableComponents: boolean\n inventory: AiSiteInventory | null\n model: string\n signal?: AbortSignal\n /** Wraps the check, for an eval that records each answer it reads. */\n observe?: (check: AiGenerationCheck<AiLayoutPageBuilt>) => AiGenerationCheck<AiLayoutPageBuilt>\n}\n\n/** Two generations' spend as one: every call is billed. */\nfunction spentTogether(first: AiGenerationSpend, second: AiGenerationSpend): AiGenerationSpend {\n const usage: AiUsage = {\n inputTokens: first.usage.inputTokens + second.usage.inputTokens,\n outputTokens: first.usage.outputTokens + second.usage.outputTokens,\n cacheReadTokens: first.usage.cacheReadTokens + second.usage.cacheReadTokens,\n cacheWriteTokens: first.usage.cacheWriteTokens + second.usage.cacheWriteTokens,\n }\n return {\n attempts: first.attempts + second.attempts,\n usage,\n estCostUsd: Math.round((first.estCostUsd + second.estCostUsd) * 1_000_000) / 1_000_000,\n model: second.model,\n stopReason: second.stopReason,\n effort: second.effort,\n }\n}\n\n/**\n * A whole page in the layout language: one answer for every section, and,\n * where that answer and its re-ask still left a section out, one follow-up\n * asking for only those (AGL-3660). The sections that read are kept between\n * them, so the page is compiled whole once every section is designed.\n */\nexport async function aiRunLayoutPage(input: AiLayoutPageRunInput): Promise<AiValidatedGeneration<AiLayoutPageBuilt>> {\n const kept: Array<AiLayoutSection | null> = input.screen.sections.map(() => null)\n const observe = input.observe ?? ((check) => check)\n const base = aiLayoutPagePrompt({\n job: input.job,\n plan: input.plan,\n screen: input.screen,\n targets: input.targets,\n reusableComponents: input.reusableComponents,\n })\n const ask = (content: string, maxTokens: number, only?: readonly number[]) =>\n runValidatedGeneration<AiLayoutPageBuilt>(AI_LAYOUT_PAGE_KIND, {\n step: 'job.page',\n model: input.model,\n instructions: AI_JOB_PAGE_LANGUAGE_INSTRUCTIONS,\n inventory: input.inventory,\n messages: [{ role: 'user', content }],\n tool: AI_LAYOUT_PAGE_TOOL,\n maxTokens,\n cutOff: { noun: 'page', smaller: 'Write shorter copy, and fewer items in each group.' },\n ...AI_LAYOUT_LANGUAGE_THINKING,\n check: observe(\n aiLayoutPageCheck({\n screen: input.screen,\n sectionIds: input.sectionIds,\n targets: input.targets,\n context: input.context,\n reusableComponents: input.reusableComponents,\n kept,\n design: aiLayoutDesignOf(input.job, input.screen.slug),\n ...(only ? { only } : {}),\n }),\n ),\n ...(input.signal ? { signal: input.signal } : {}),\n })\n const first = await ask(base, AI_JOB_PAGE_LANGUAGE_BUDGET.maxTokens(input.model))\n const missing = aiLayoutMissingSections(kept)\n if (\n first.status !== 'needs_input' ||\n !missing.length ||\n !first.violations.every((violation) => violation.code === AI_LAYOUT_SECTION_MISSING_CODE)\n ) {\n return first\n }\n const second = await ask(\n aiLayoutMissingSectionsPrompt({ base, screen: input.screen, missing }),\n Math.min(AI_JOB_PAGE_LANGUAGE_FOLLOW_UP_TOKENS, AI_JOB_PAGE_LANGUAGE_BUDGET.maxTokens(input.model)),\n missing,\n )\n return { ...second, ...spentTogether(first, second) }\n}\n"],"names":["CANVAS_ROOT_ELEMENT_ID","isAiPlanNewRef","aiHomeScreenIds","AI_LAYOUT_POST_ADDRESS_TOKENS","aiCompileLayoutPage","aiLayoutListingAt","aiLayoutListingsOf","AI_LAYOUT_LANGUAGE_TEXT","AI_LAYOUT_PAGE_TOOL","aiReadLayoutPage","aiLayoutCopyCheck","aiLayoutStoredTree","AI_GENERATION_MAX_ATTEMPTS","AI_STEP_TIERS","runValidatedGeneration","aiSettleMechanicalRules","aiSettleUnrelatedScreenLinks","validateAiDoctrineTree","aiSiteKindDesignLines","aiSiteKindOfInputs","aiSiteSeed","aiOriginJobId","aiGenerationWorstCaseOnTierMs","aiJobStepBudget","aiJobBriefLine","aiPlanReferenceLines","aiLayoutIsHomeSlug","aiLayoutSiteAliases","aiLayoutSitePages","aiLayoutInventedContactViolations","AI_LAYOUT_LANGUAGE_INPUT","AI_LAYOUT_FORM_PAGE_INPUT","aiJobUsesLayoutLanguage","job","inputs","AI_LAYOUT_LANGUAGE_THINKING","thinking","effort","AI_LAYOUT_PAGE_THINKING_TOKENS","AI_LAYOUT_FRAME_THINKING_TOKENS","AI_JOB_PAGE_LANGUAGE_TOKENS","AI_LAYOUT_SECTION_MOST_TOKENS","AI_JOB_PAGE_LANGUAGE_FOLLOW_UP_TOKENS","AI_JOB_PAGE_LANGUAGE_BUDGET","tier","maxTokens","ownReadsMs","AI_LAYOUT_PAGE_KIND","AI_JOB_PAGE_LANGUAGE_INSTRUCTIONS","text","join","cacheBreakpoint","aiLayoutFormPageOfPlan","plan","formIds","created","Set","create","filter","entry","kind","map","name","toLowerCase","forms","screen","screens","find","sections","some","section","uses","ref","has","id","aiLayoutFacts","values","Object","value","brief","aiLayoutPageTargets","input","own","inventory","planned","pages","alias","page","row","template","label","slug","formPage","pageId","includes","homeIds","form","formPageId","components","component","props","facts","listings","aiLayoutListingsWithDatasets","flatMap","listing","datasets","dataset","datasetId","imageField","fields","length","index","fieldIds","type","field","aiLayoutListingContext","context","targets","formScreenIds","here","placements","placement","screenId","tokens","bindingTokens","aiLayoutPagePrompt","places","listed","names","records","slice","items","standsInFor","keys","title","reusableComponents","$id","aiLayoutDesignOf","style","seed","Number","isFinite","home","aiLayoutMissingSectionsPrompt","missing","base","aiLayoutMissingSections","kept","AI_LAYOUT_SECTION_MISSING_CODE","AI_LAYOUT_SECTION_EMPTY_CODE","leastItems","aiLayoutShownItems","itemIds","storedIds","nodes","ids","undefined","aiLayoutEmptyItemSections","quotesOnly","least","shown","rule","code","message","detail","aiLayoutPageCheck","fills","only","_","answers","answer","last","reading","forEach","position","violations","compiled","sectionIds","design","stored","tree","ok","console","error","copy","dropped","rootId","ownScreenIds","report","scrollTargetIds","repeatsCompiled","load","settled","spentTogether","first","second","usage","inputTokens","outputTokens","cacheReadTokens","cacheWriteTokens","attempts","estCostUsd","Math","round","model","stopReason","aiRunLayoutPage","observe","check","ask","content","step","instructions","messages","role","tool","cutOff","noun","smaller","signal","status","every","violation","min"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-page-language.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 { CANVAS_ROOT_ELEMENT_ID } from '@aglyn/aglyn/foundation/constants/canvas'\nimport type { NodesMap } from '@aglyn/aglyn/types/nodes'\nimport { isAiPlanNewRef, type AiBuildPlanScreen } from '../model/ai-build-plan'\nimport type { AiJob, AiJobPlan } from '../model/ai-jobs.types'\nimport {\n aiHomeScreenIds,\n type AiSiteInventory,\n} from '../model/ai-site-inventory'\nimport { AI_LAYOUT_POST_ADDRESS_TOKENS, aiCompileLayoutPage } from '../layout-language/ai-layout-compiler'\nimport { aiLayoutListingAt, aiLayoutListingsOf, aiLayoutRecordHref, type AiLayoutListing } from '../layout-language/ai-layout-listings'\nimport {\n AI_LAYOUT_LANGUAGE_TEXT,\n AI_LAYOUT_PAGE_TOOL,\n aiReadLayoutPage,\n type AiLayoutSection,\n type AiLayoutSettlement,\n} from '../layout-language/ai-layout-language'\nimport type {\n AiLayoutPage,\n AiLayoutTargets,\n} from '../layout-language/ai-layout-links'\nimport { aiLayoutCopyCheck } from '../layout-language/ai-layout-gaps'\nimport { aiLayoutStoredTree } from '../layout-language/ai-layout-store'\nimport { AI_GENERATION_MAX_ATTEMPTS } from '../runtime/ai-generation-bounds'\nimport { AI_STEP_TIERS } from '../providers/catalog'\nimport {\n runValidatedGeneration,\n type AiGenerationCheck,\n type AiGenerationSpend,\n type AiValidatedGeneration,\n} from '../runtime/ai-doctrine'\nimport type { AiUsage } from '../providers/contract'\nimport {\n aiSettleMechanicalRules,\n aiSettleUnrelatedScreenLinks,\n validateAiDoctrineTree,\n type AiDoctrineNode,\n type AiDoctrineTreeContext,\n type AiDoctrineViolation,\n} from '../runtime/ai-doctrine-validators'\nimport type { AiLoadEstimate } from '../runtime/ai-palette'\nimport { aiSiteKindDesignLines, aiSiteKindOfInputs } from '../model/ai-site-kinds'\nimport { aiSiteSeed } from '../model/ai-site-look'\nimport type { AiLayoutDesign } from '../layout-language/ai-layout-design'\nimport { aiOriginJobId } from './ai-job-draft-ids'\nimport type { AiSystemBlock } from '../runtime/ai-runtime'\nimport { aiGenerationWorstCaseOnTierMs, aiJobStepBudget } from './ai-job-budget'\nimport { aiJobBriefLine, aiPlanReferenceLines } from './ai-job-generation'\nimport { aiLayoutIsHomeSlug, aiLayoutSiteAliases, aiLayoutSitePages } from './ai-job-layout-site-pages'\nimport { aiLayoutInventedContactViolations } from './ai-layout-site-facts'\n\n/**\n * A page built in the compact layout language (AGL-3660): the page step's\n * pass for a site's page units — a guided start's and a build's — in place of\n * the raw-tree section passes.\n *\n * ONE answer a page: every planned section, in the language, through\n * `submit_page`. The compiler writes the tree, the palette validator stores\n * it as it stores any generated tree, and the doctrine checks the whole page.\n * A section the answer left out or left empty is the one thing a re-ask asks\n * for: the sections that read are kept, and the second answer fills only\n * what is still missing. Then the page step's last pass runs as it always\n * has — the whole page held to the doctrine again, its listing written, the\n * draft reported — so the item ledger, the credits and Try again work exactly\n * as they did.\n */\n\n/** The unit input that says a page or a layout is built in the layout language. */\nexport const AI_LAYOUT_LANGUAGE_INPUT = 'layoutLanguage'\n\n/** The unit input naming the page of the site that places its form, where it is another page. */\nexport const AI_LAYOUT_FORM_PAGE_INPUT = 'layoutFormPage'\n\n/** Whether this job builds its page or its layout in the layout language. */\nexport function aiJobUsesLayoutLanguage(job: Pick<AiJob, 'inputs'>): boolean {\n return job.inputs?.[AI_LAYOUT_LANGUAGE_INPUT] === true\n}\n\n/**\n * How the language doors think (AGL-3660): adaptively, at an effort named\n * rather than left to the model's default. Zach, 2026-10-07: quality first —\n * a page and a site's frame are designed, not transcribed, and the caching\n * work pays for the thinking. Medium is where Claude Sonnet 5.5, the balanced\n * default, is tuned to start for multistep design work.\n */\nexport const AI_LAYOUT_LANGUAGE_THINKING = { thinking: 'adaptive', effort: 'medium' } as const\n\n/**\n * Room for the thinking a page's answer does before it writes, inside the\n * same `max_tokens` as the answer: thinking is drawn from the ceiling first,\n * so a ceiling sized for the answer alone would cut a thoughtful answer off.\n *\n * Bounded by TIME, not by money: the page step's answer, its re-ask and the\n * follow-up must fit the least time a beat gives a step\n * (`AI_JOB_STEP_MAX_MINIMUM_MS`), and `aiJobStepBudget` quietly lowers every\n * ceiling to what fits. 2,000 here, with the follow-up's 500, is the most\n * that fits whole on the balanced tier; at 5,000 the budget cut a page's\n * ceiling to 879 tokens, under the answer itself.\n */\nexport const AI_LAYOUT_PAGE_THINKING_TOKENS = 2_000\n\n/** The same room for a site's header and footer, whose step has the time for more. */\nexport const AI_LAYOUT_FRAME_THINKING_TOKENS = 4_000\n\n/**\n * The most one page's answer asks for: the answer and the thinking before it.\n * A section in the language is about 120 to 250 tokens with its copy, so the\n * largest page a plan admits — eight sections — fits in 3,000 with room (the\n * live runs of 2026-10-07 wrote 683 to 1,745); the compiler, not the ceiling,\n * keeps a page small.\n */\nexport const AI_JOB_PAGE_LANGUAGE_TOKENS = 3_000 + AI_LAYOUT_PAGE_THINKING_TOKENS\n\n/**\n * The most one section of a page is written in, its copy included: the top of\n * the 120 to 250 tokens a section runs to. The Free site wall prices each\n * planned section at it (AGL-3660).\n */\nexport const AI_LAYOUT_SECTION_MOST_TOKENS = 250\n\n/**\n * The time a language page pass needs: its lookup rounds, its answer and its\n * re-ask at `AI_JOB_PAGE_LANGUAGE_TOKENS` on the tier the page step is served\n * from, with the step's reads and writes.\n */\n/** The most the follow-up asking only for the sections an answer left out may run to, its thinking included. */\nexport const AI_JOB_PAGE_LANGUAGE_FOLLOW_UP_TOKENS = 1_500 + 500\n\nexport const AI_JOB_PAGE_LANGUAGE_BUDGET = aiJobStepBudget({\n tier: AI_STEP_TIERS['job.page'],\n maxTokens: AI_JOB_PAGE_LANGUAGE_TOKENS,\n // The follow-up for sections an answer left out is one more generation.\n ownReadsMs: aiGenerationWorstCaseOnTierMs({\n tier: AI_STEP_TIERS['job.page'],\n maxTokens: AI_JOB_PAGE_LANGUAGE_FOLLOW_UP_TOKENS,\n }),\n})\n\n/** The doctrine scope the language doors are told: values the compiler checks itself. */\nexport const AI_LAYOUT_PAGE_KIND = 'layout-page'\n\n/** The language, as the page door's cached instructions. */\nexport const AI_JOB_PAGE_LANGUAGE_INSTRUCTIONS: readonly AiSystemBlock[] = [\n {\n text: [\n AI_LAYOUT_LANGUAGE_TEXT,\n '',\n 'Answer with submit_page: the whole page, one entry in sections for each planned section, in order.',\n ].join('\\n'),\n cacheBreakpoint: true,\n },\n]\n\n/** The page of a site plan that places its form: the form the plan creates, or one the site has. */\nexport function aiLayoutFormPageOfPlan(\n plan: Pick<AiJobPlan, 'create' | 'screens'>,\n formIds: readonly string[] = [],\n): string | null {\n const created = new Set(\n plan.create\n .filter((entry) => entry.kind === 'form')\n .map((entry) => `new:${entry.name}`.toLowerCase()),\n )\n const forms = new Set(formIds)\n const screen = plan.screens.find((entry) =>\n entry.sections.some((section) =>\n section.uses.some((ref) =>\n isAiPlanNewRef(ref) ? created.has(ref.toLowerCase()) : forms.has(ref),\n ),\n ),\n )\n return typeof screen?.id === 'string' ? screen.id : null\n}\n\n/** Every word the job was given, which a page's contact details are held to. */\nexport function aiLayoutFacts(job: Pick<AiJob, 'brief' | 'inputs'>): string {\n const values = Object.values(job.inputs ?? {}).filter(\n (value): value is string => typeof value === 'string',\n )\n return [job.brief, ...values].join('\\n')\n}\n\n/** What a page's links resolve against: the site's pages, built and planned, its forms and components. */\nexport function aiLayoutPageTargets(input: {\n job: Pick<AiJob, 'brief' | 'inputs'>\n inventory: AiSiteInventory | null\n own: ReadonlyArray<string | null | undefined>\n}): AiLayoutTargets {\n const { job, inventory } = input\n const own = input.own.filter((id): id is string => !!id)\n const planned = aiLayoutSitePages(job.inputs)\n const pages: AiLayoutPage[] = [\n ...planned,\n // Planned pages merged into the blog (AGL-3676): a link to one goes to the blog.\n ...aiLayoutSiteAliases(job.inputs).filter((alias) => !planned.some((page) => page.id === alias.id)),\n ...(inventory?.screens ?? [])\n .filter(\n (row) => !row.template && !planned.some((page) => page.id === row.id),\n )\n .map((row) => ({ id: row.id, label: row.name, slug: row.slug })),\n ]\n const formPage = job.inputs?.[AI_LAYOUT_FORM_PAGE_INPUT]\n return {\n pageId: own[0] ?? null,\n pages: pages.filter((page) => !own.includes(page.id)),\n homeIds: aiHomeScreenIds(inventory),\n forms: (inventory?.forms ?? []).map((form) => ({\n id: form.id,\n name: form.name,\n })),\n formPageId:\n typeof formPage === 'string' && !own.includes(formPage) ? formPage : null,\n components: (inventory?.components ?? []).map((component) => ({\n id: component.id,\n name: component.name,\n props: component.props,\n })),\n facts: aiLayoutFacts(job),\n // The site's catalog and blog, and the sections that list them (AGL-3676),\n // and its datasets (AGL-3616).\n listings: aiLayoutListingsWithDatasets(aiLayoutListingsOf(job.inputs), inventory),\n }\n}\n\n/**\n * A page's listings with each dataset's held to the site's inventory\n * (AGL-3616): a records listing is kept only where the site has the dataset —\n * the tree check admits a repeat over no other, and a card left repeating\n * over nothing would show its `{{item.*}}` — and one that names no fields\n * takes the inventory's, in the dataset's order. Its cards link the record\n * pages the plan makes, else those the site already serves (AGL-3747).\n */\nexport function aiLayoutListingsWithDatasets(\n listings: readonly AiLayoutListing[],\n inventory: Pick<AiSiteInventory, 'datasets'> | null,\n): AiLayoutListing[] {\n return listings.flatMap((listing) => {\n if (listing.kind !== 'records') return [listing]\n const row = inventory?.datasets.find((dataset) => dataset.id === listing.datasetId)\n if (!row) return []\n // The photo field is the card's picture, never its words (AGL-3616).\n const imageField = listing.imageField ?? row.imageField\n // The address is the card's link to its record's page, never its words (AGL-3727).\n const addressField = listing.addressField ?? row.addressField\n // A record page the site already serves for the dataset (AGL-3747), where\n // the plan makes none of its own.\n const recordBase = listing.recordBase ?? row.recordBase\n const fields = (\n listing.fields?.length\n ? listing.fields\n : row.fields.map((name, index) => ({ id: row.fieldIds?.[index] || name, name, type: 'text' }))\n ).filter((field) => field.id !== imageField && field.id !== addressField)\n return fields.length\n ? [\n {\n ...listing,\n fields,\n ...(imageField ? { imageField } : {}),\n ...(recordBase && addressField ? { recordBase, addressField } : {}),\n },\n ]\n : []\n })\n}\n\n/**\n * The page check's context with what a section listing the blog's posts\n * binds (AGL-3676): each post's card links its post and shows its cover by\n * the tokens the page fills per post, which a page's store admits whole only\n * where a listing places them. A dataset's card shows its record's photo\n * the same way (AGL-3616), by `{{item.<photo field>}}`. And the page that\n * places the site's form, which a call to action asking a visitor to get in\n * touch links even when it is home (AGL-3729).\n */\nexport function aiLayoutListingContext(\n context: AiDoctrineTreeContext,\n targets: AiLayoutTargets,\n): AiDoctrineTreeContext {\n if (targets.formPageId) context = { ...context, formScreenIds: [targets.formPageId] }\n const here = (targets.listings ?? []).filter((listing) =>\n listing.placements.some((placement) => placement.screenId === targets.pageId),\n )\n const tokens = [\n ...(here.some((listing) => listing.kind === 'posts') ? AI_LAYOUT_POST_ADDRESS_TOKENS : []),\n ...here.flatMap((listing) => (listing.kind === 'records' && listing.imageField ? [`{{item.${listing.imageField}}}`] : [])),\n // Each card's link to its record's own page (AGL-3727), admitted whole.\n ...here.flatMap((listing) => {\n const href = aiLayoutRecordHref(listing)\n return href ? [href] : []\n }),\n ]\n if (!tokens.length) return context\n return { ...context, bindingTokens: [...new Set([...(context.bindingTokens ?? []), ...tokens])] }\n}\n\n/** The page's user turn: the page, the brief, the plan, its sections and where its links may go. */\nexport function aiLayoutPagePrompt(input: {\n job: Pick<AiJob, 'brief' | 'inputs' | '$id'>\n plan: AiJobPlan\n screen: AiBuildPlanScreen\n targets: AiLayoutTargets\n reusableComponents: boolean\n /** The sections a re-ask still needs, by plan index; absent on the first ask. */\n missing?: readonly number[]\n}): string {\n const { job, plan, screen, targets } = input\n const sections = screen.sections.map((section, index) => {\n const places = section.uses.length\n ? `; places ${section.uses.join(', ')}`\n : ''\n // A section the site's records fill (AGL-3676): the platform places them,\n // so the design writes the words around them and no group for them.\n const listed = aiLayoutListingAt(targets.listings ?? [], targets.pageId, index)\n if (listed?.listing.kind === 'tracks') {\n // A music site's player (AGL-3716): placed empty, for the owner's own uploads.\n return `${index + 1}. \"${section.name}\"${places}; the platform places a music player here for the artist's own tracks, which they add themselves: write only its heading and a line inviting visitors to listen, and no cards, list, images or links for songs`\n }\n if (listed?.listing.kind === 'reviews') {\n // A store's own reviews (AGL-3676): shoppers write them; none is ever written here.\n return `${index + 1}. \"${section.name}\"${places}; the platform shows the store's real customer reviews here with their star ratings, once shoppers leave them: write only its heading, and no quotes, names, ratings or cards`\n }\n if (listed?.listing.kind === 'signup') {\n // A store's newsletter field (AGL-3676), placed by the platform.\n return `${index + 1}. \"${section.name}\"${places}; the platform places the newsletter sign-up field here: write its heading and one line on what subscribers hear about, from the brief, and no form, button or offer the brief does not make`\n }\n if (listed?.listing.kind === 'records') {\n // One of the site's datasets (AGL-3616), repeated by the platform over its records.\n const names = listed.listing.records.length ? ` (${listed.listing.records.slice(0, 6).map((name) => `“${name}”`).join(', ')})` : ''\n return `${index + 1}. \"${section.name}\"${places}; the platform lists the records of the dataset “${listed.listing.name}”${names} here itself, one card each: write only its heading and a line about them, and no cards, list or images for them`\n }\n if (listed) {\n return `${index + 1}. \"${section.name}\"${places}; the platform lists ${listed.listing.name}'s ${listed.listing.kind} here itself, with their photos and links: write only its heading and a line about them, and no cards, list or images for them`\n }\n const items = section.items ? `; shows ${section.items} items` : ''\n return `${index + 1}. \"${section.name}\"${places}${items}`\n })\n // A page merged into the blog is not offered: the blog is, by its own entry.\n const pages = targets.pages.filter((page) => !page.standsInFor).map((page) => `${page.label} (page:${page.id})`)\n const components = targets.components.map(\n (component) =>\n `${component.name} (${component.id}; props ${Object.keys(component.props).join(', ') || 'none'})`,\n )\n return [\n `Page: \"${screen.title}\" at ${screen.slug}`,\n aiJobBriefLine(job),\n // The kind of site the person picked sets how its pages are arranged (AGL-3660).\n ...aiSiteKindDesignLines(job.inputs),\n ...aiPlanReferenceLines(plan),\n `Sections to design, in order:`,\n ...sections,\n pages.length\n ? `Other pages of this site: ${pages.join(', ')}.`\n : 'This site has no other page to link.',\n targets.forms.length\n ? `The site's form: ${targets.forms.map((form) => `${form.name} (${form.id})`).join(', ')}.`\n : 'The site has no saved form: place none.',\n ...(components.length\n ? [`Components this page may place: ${components.join('; ')}.`]\n : []),\n input.reusableComponents\n ? 'Where a section repeats an item, place the component its plan line names with cards whose to is that component.'\n : 'This site keeps no reusable components: draw repeated items as cards, steps, stats or a list.',\n // A per-job word, so two identical briefs are designed apart.\n `Design seed: ${job.$id.slice(-6)}.`,\n ].join('\\n')\n}\n\n/**\n * The site a page is designed for (AGL-3660): the kind its job names, the\n * seed its look was drawn with — the same for every page of the site, so the\n * site reads as one design — and whether the page is its home. `null` for a\n * job that names no kind of site, which compiles the compiler's first way.\n */\nexport function aiLayoutDesignOf(job: Pick<AiJob, '$id' | 'inputs'>, slug: string): AiLayoutDesign | null {\n const kind = aiSiteKindOfInputs(job.inputs)\n if (!kind) return null\n const style = job.inputs?.['siteStyle'] as Record<string, unknown> | undefined\n const seed = typeof style?.['seed'] === 'number' && Number.isFinite(style['seed']) ? (style['seed'] as number) >>> 0 : aiSiteSeed(aiOriginJobId(job))\n return { kind: kind.id, seed, home: aiLayoutIsHomeSlug(slug) }\n}\n\n/** A validated language page, stored as the page keeps it. */\nexport interface AiLayoutPageBuilt {\n nodes: NodesMap\n load: AiLoadEstimate | null\n settled: AiLayoutSettlement[]\n /** What the last answer's gaps took out of the page (`ai-layout-gaps.ts`). */\n dropped: string[]\n /** How many repeated items each plan section shows, as built (AGL-3660). */\n items: number[]\n}\n\nexport interface AiLayoutPageCheckInput {\n screen: AiBuildPlanScreen\n sectionIds: readonly string[]\n targets: AiLayoutTargets\n context: AiDoctrineTreeContext\n reusableComponents: boolean\n /**\n * What earlier answers gave, by plan index, shared between the page's\n * generations: a follow-up asking only for missing sections fills the rest.\n */\n kept?: Array<AiLayoutSection | null>\n /** The plan indices this answer's sections fill, in order; absent, every section. */\n only?: readonly number[]\n /** The site the page is drawn for (`aiLayoutDesignOf`); absent, the compiler's first design. */\n design?: AiLayoutDesign | null\n}\n\n/**\n * The follow-up turn for the sections a page's answer left out (AGL-3660):\n * the page as before, told which sections it already has, and asked for only\n * the missing ones, in order — the one part of a page asked for again.\n */\nexport function aiLayoutMissingSectionsPrompt(input: {\n base: string\n screen: AiBuildPlanScreen\n missing: readonly number[]\n}): string {\n const names = input.missing.map((index) => `${index + 1}. \"${input.screen.sections[index].name}\"`)\n return [\n input.base,\n '',\n `The other sections of this page are already designed. Design ONLY these, in this order, one entry in sections each: ${names.join('; ')}. Give each at least one block.`,\n ].join('\\n')\n}\n\n/** The plan indices a page still lacks, after the answers so far. */\nexport function aiLayoutMissingSections(kept: ReadonlyArray<AiLayoutSection | null>): number[] {\n return kept.flatMap((section, index) => (section ? [] : [index]))\n}\n\n/** The violation a planned section the answer gave nothing usable for is named by. */\nexport const AI_LAYOUT_SECTION_MISSING_CODE = 'layout-section-missing'\n\n/** The code a section planned with items that shows none is refused under (AGL-3660). */\nexport const AI_LAYOUT_SECTION_EMPTY_CODE = 'layout-section-no-items'\n\n/** How many of a section's planned items it must show: one for a short list, two for anything longer. */\nconst leastItems = (planned: number) => (planned >= 3 ? 2 : planned >= 1 ? 1 : 0)\n\n/**\n * How many repeated items each section shows once stored (AGL-3660): the\n * elements the compiler drew for them, under the ids they are stored by,\n * that are still in the page after anything later took words out.\n */\nexport function aiLayoutShownItems(\n itemIds: readonly (readonly string[])[],\n storedIds: Readonly<Record<string, string>>,\n nodes: Readonly<Record<string, unknown>>,\n): number[] {\n return itemIds.map((ids) => ids.filter((id) => storedIds[id] !== undefined && storedIds[id] in nodes).length)\n}\n\n/**\n * The sections a page planned with repeated items — cards, steps, a list —\n * that show none, or too few, once the page is built (AGL-3660). A heading\n * and an intro over nothing is a section a visitor reads as broken, so it is\n * asked for again.\n */\nexport function aiLayoutEmptyItemSections(\n screen: Pick<AiBuildPlanScreen, 'sections'>,\n items: readonly number[],\n /** Sections whose only items were customer quotes, which no answer may give (AGL-3676). */\n quotesOnly: readonly number[] = [],\n): AiDoctrineViolation[] {\n return screen.sections.flatMap((section, index): AiDoctrineViolation[] => {\n if (quotesOnly.includes(index)) return []\n const least = leastItems(section.items)\n if (!least) return []\n const shown = items[index] ?? 0\n if (shown >= least) return []\n return [\n {\n rule: null,\n code: AI_LAYOUT_SECTION_EMPTY_CODE,\n message: `Section ${index + 1} (\"${section.name}\") is planned with ${section.items} items and shows ${shown || 'none'}.`,\n detail: `Give section ${index + 1} one cards, steps, stats, list or faq block holding its ${section.items} items, each with a title and its words.`,\n },\n ]\n })\n}\n\n/**\n * The check a language page answer is held to: each planned section read,\n * the page compiled, stored and checked whole. Sections that read are kept\n * across the re-ask, so the second answer is asked only for what was missing,\n * and a section it sends again that already read is not taken twice.\n */\nexport function aiLayoutPageCheck(\n input: AiLayoutPageCheckInput,\n): AiGenerationCheck<AiLayoutPageBuilt> {\n const kept: Array<AiLayoutSection | null> = input.kept ?? input.screen.sections.map(() => null)\n const fills = input.only ?? input.screen.sections.map((_, index) => index)\n const context = aiLayoutListingContext(input.context, input.targets)\n let answers = 0\n return (answer) => {\n // The last answer a generation takes has its gaps taken out rather than asked about again.\n answers += 1\n const last = answers >= AI_GENERATION_MAX_ATTEMPTS\n const reading = aiReadLayoutPage(\n answer,\n fills.length,\n fills.map((index) => input.screen.sections[index]),\n )\n reading.sections.forEach((section, position) => {\n // A section the answer gives is taken as given; one it leaves out keeps\n // what an earlier answer gave, so a re-ask may send only what was missing.\n if (section) kept[fills[position]] = section\n })\n const missing = kept.flatMap((section, index) => (section ? [] : [index]))\n if (missing.length) {\n const names = missing.map(\n (index) => `${index + 1} (\"${input.screen.sections[index].name}\")`,\n )\n return {\n value: null,\n violations: [\n {\n rule: null,\n code: AI_LAYOUT_SECTION_MISSING_CODE,\n message: `The page left out section ${names.join(', ')}.`,\n detail: `Answer again with every section in order; the sections you already designed are kept, so only ${names.join(', ')} ${missing.length === 1 ? 'needs' : 'need'} its design. Give each at least one block.`,\n },\n ],\n }\n }\n const compiled = aiCompileLayoutPage(\n kept as AiLayoutSection[],\n { title: input.screen.title, sections: input.screen.sections },\n input.targets,\n {\n reusableComponents: input.reusableComponents,\n sectionIds: input.sectionIds,\n ...(input.design ? { design: input.design } : {}),\n },\n )\n const stored = aiLayoutStoredTree(\n compiled.tree,\n 'screen',\n context,\n input.sectionIds,\n )\n if (stored.ok === false) {\n // The compiler writes only palette trees, which the property spec holds;\n // a refusal here is the platform's, and is reported as one.\n console.error('ai layout page: a compiled page did not store', {\n error: stored.error,\n })\n return {\n value: null,\n violations: [\n {\n rule: null,\n code: 'layout-compile',\n message: 'This page could not be built. Try again.',\n detail: stored.error,\n },\n ],\n }\n }\n // No gap and no internal reference in the words of a page that is published as built.\n const copy = aiLayoutCopyCheck(\n stored.nodes,\n CANVAS_ROOT_ELEMENT_ID,\n {\n pages: input.targets.pages,\n ids: [\n ...input.targets.pages.map((page) => page.id),\n ...input.targets.forms.map((form) => form.id),\n ...input.targets.components.map((component) => component.id),\n ...input.sectionIds,\n ...(input.targets.pageId ? [input.targets.pageId] : []),\n ],\n },\n last,\n )\n const { dropped } = copy\n // An attribute a rule has one answer for is settled, not asked of the model again (AGL-3660),\n // and a link sent home for nothing is sent to the form or left out (AGL-3729).\n const nodes = aiSettleUnrelatedScreenLinks(\n aiSettleMechanicalRules(\n { rootId: CANVAS_ROOT_ELEMENT_ID, nodes: copy.nodes as unknown as Record<string, AiDoctrineNode> },\n 'page',\n ),\n 'page',\n { ...context, ownScreenIds: input.targets.pageId ? [input.targets.pageId] : [] },\n ).nodes as unknown as typeof copy.nodes\n const report = validateAiDoctrineTree(\n { rootId: CANVAS_ROOT_ELEMENT_ID, nodes },\n 'page',\n {\n ...context,\n scrollTargetIds: input.sectionIds,\n // The layout language draws its own picture cards (AGL-3660).\n repeatsCompiled: true,\n },\n )\n // Each section's items as they are stored, after anything the gaps took out.\n const items = aiLayoutShownItems(compiled.itemIds, stored.storedIds, nodes as unknown as Record<string, unknown>)\n // A street address or opening hours the job was never given is invented\n // (rule 14, AGL-3596), the same check a layout is held to; a phone number\n // or an email the compiler already writes as its gap.\n const violations: AiDoctrineViolation[] = [\n ...report.violations,\n ...copy.violations,\n ...aiLayoutEmptyItemSections(input.screen, items, compiled.quotesOnly),\n ...aiLayoutInventedContactViolations(\n { rootId: CANVAS_ROOT_ELEMENT_ID, nodes: nodes as unknown as Record<string, AiDoctrineNode> },\n input.targets.facts,\n ),\n ]\n return {\n value: violations.length\n ? null\n : {\n nodes,\n load: report.load,\n settled: [...reading.settled, ...compiled.settled],\n dropped,\n items,\n },\n violations,\n }\n }\n}\n\nexport interface AiLayoutPageRunInput {\n job: Pick<AiJob, 'brief' | 'inputs' | '$id'>\n plan: AiJobPlan\n screen: AiBuildPlanScreen\n sectionIds: readonly string[]\n targets: AiLayoutTargets\n context: AiDoctrineTreeContext\n reusableComponents: boolean\n inventory: AiSiteInventory | null\n model: string\n signal?: AbortSignal\n /** Wraps the check, for an eval that records each answer it reads. */\n observe?: (check: AiGenerationCheck<AiLayoutPageBuilt>) => AiGenerationCheck<AiLayoutPageBuilt>\n}\n\n/** Two generations' spend as one: every call is billed. */\nfunction spentTogether(first: AiGenerationSpend, second: AiGenerationSpend): AiGenerationSpend {\n const usage: AiUsage = {\n inputTokens: first.usage.inputTokens + second.usage.inputTokens,\n outputTokens: first.usage.outputTokens + second.usage.outputTokens,\n cacheReadTokens: first.usage.cacheReadTokens + second.usage.cacheReadTokens,\n cacheWriteTokens: first.usage.cacheWriteTokens + second.usage.cacheWriteTokens,\n }\n return {\n attempts: first.attempts + second.attempts,\n usage,\n estCostUsd: Math.round((first.estCostUsd + second.estCostUsd) * 1_000_000) / 1_000_000,\n model: second.model,\n stopReason: second.stopReason,\n effort: second.effort,\n }\n}\n\n/**\n * A whole page in the layout language: one answer for every section, and,\n * where that answer and its re-ask still left a section out, one follow-up\n * asking for only those (AGL-3660). The sections that read are kept between\n * them, so the page is compiled whole once every section is designed.\n */\nexport async function aiRunLayoutPage(input: AiLayoutPageRunInput): Promise<AiValidatedGeneration<AiLayoutPageBuilt>> {\n const kept: Array<AiLayoutSection | null> = input.screen.sections.map(() => null)\n const observe = input.observe ?? ((check) => check)\n const base = aiLayoutPagePrompt({\n job: input.job,\n plan: input.plan,\n screen: input.screen,\n targets: input.targets,\n reusableComponents: input.reusableComponents,\n })\n const ask = (content: string, maxTokens: number, only?: readonly number[]) =>\n runValidatedGeneration<AiLayoutPageBuilt>(AI_LAYOUT_PAGE_KIND, {\n step: 'job.page',\n model: input.model,\n instructions: AI_JOB_PAGE_LANGUAGE_INSTRUCTIONS,\n inventory: input.inventory,\n messages: [{ role: 'user', content }],\n tool: AI_LAYOUT_PAGE_TOOL,\n maxTokens,\n cutOff: { noun: 'page', smaller: 'Write shorter copy, and fewer items in each group.' },\n ...AI_LAYOUT_LANGUAGE_THINKING,\n check: observe(\n aiLayoutPageCheck({\n screen: input.screen,\n sectionIds: input.sectionIds,\n targets: input.targets,\n context: input.context,\n reusableComponents: input.reusableComponents,\n kept,\n design: aiLayoutDesignOf(input.job, input.screen.slug),\n ...(only ? { only } : {}),\n }),\n ),\n ...(input.signal ? { signal: input.signal } : {}),\n })\n const first = await ask(base, AI_JOB_PAGE_LANGUAGE_BUDGET.maxTokens(input.model))\n const missing = aiLayoutMissingSections(kept)\n if (\n first.status !== 'needs_input' ||\n !missing.length ||\n !first.violations.every((violation) => violation.code === AI_LAYOUT_SECTION_MISSING_CODE)\n ) {\n return first\n }\n const second = await ask(\n aiLayoutMissingSectionsPrompt({ base, screen: input.screen, missing }),\n Math.min(AI_JOB_PAGE_LANGUAGE_FOLLOW_UP_TOKENS, AI_JOB_PAGE_LANGUAGE_BUDGET.maxTokens(input.model)),\n missing,\n )\n return { ...second, ...spentTogether(first, second) }\n}\n"],"names":["CANVAS_ROOT_ELEMENT_ID","isAiPlanNewRef","aiHomeScreenIds","AI_LAYOUT_POST_ADDRESS_TOKENS","aiCompileLayoutPage","aiLayoutListingAt","aiLayoutListingsOf","aiLayoutRecordHref","AI_LAYOUT_LANGUAGE_TEXT","AI_LAYOUT_PAGE_TOOL","aiReadLayoutPage","aiLayoutCopyCheck","aiLayoutStoredTree","AI_GENERATION_MAX_ATTEMPTS","AI_STEP_TIERS","runValidatedGeneration","aiSettleMechanicalRules","aiSettleUnrelatedScreenLinks","validateAiDoctrineTree","aiSiteKindDesignLines","aiSiteKindOfInputs","aiSiteSeed","aiOriginJobId","aiGenerationWorstCaseOnTierMs","aiJobStepBudget","aiJobBriefLine","aiPlanReferenceLines","aiLayoutIsHomeSlug","aiLayoutSiteAliases","aiLayoutSitePages","aiLayoutInventedContactViolations","AI_LAYOUT_LANGUAGE_INPUT","AI_LAYOUT_FORM_PAGE_INPUT","aiJobUsesLayoutLanguage","job","inputs","AI_LAYOUT_LANGUAGE_THINKING","thinking","effort","AI_LAYOUT_PAGE_THINKING_TOKENS","AI_LAYOUT_FRAME_THINKING_TOKENS","AI_JOB_PAGE_LANGUAGE_TOKENS","AI_LAYOUT_SECTION_MOST_TOKENS","AI_JOB_PAGE_LANGUAGE_FOLLOW_UP_TOKENS","AI_JOB_PAGE_LANGUAGE_BUDGET","tier","maxTokens","ownReadsMs","AI_LAYOUT_PAGE_KIND","AI_JOB_PAGE_LANGUAGE_INSTRUCTIONS","text","join","cacheBreakpoint","aiLayoutFormPageOfPlan","plan","formIds","created","Set","create","filter","entry","kind","map","name","toLowerCase","forms","screen","screens","find","sections","some","section","uses","ref","has","id","aiLayoutFacts","values","Object","value","brief","aiLayoutPageTargets","input","own","inventory","planned","pages","alias","page","row","template","label","slug","formPage","pageId","includes","homeIds","form","formPageId","components","component","props","facts","listings","aiLayoutListingsWithDatasets","flatMap","listing","datasets","dataset","datasetId","imageField","addressField","recordBase","fields","length","index","fieldIds","type","field","aiLayoutListingContext","context","targets","formScreenIds","here","placements","placement","screenId","tokens","href","bindingTokens","aiLayoutPagePrompt","places","listed","names","records","slice","items","standsInFor","keys","title","reusableComponents","$id","aiLayoutDesignOf","style","seed","Number","isFinite","home","aiLayoutMissingSectionsPrompt","missing","base","aiLayoutMissingSections","kept","AI_LAYOUT_SECTION_MISSING_CODE","AI_LAYOUT_SECTION_EMPTY_CODE","leastItems","aiLayoutShownItems","itemIds","storedIds","nodes","ids","undefined","aiLayoutEmptyItemSections","quotesOnly","least","shown","rule","code","message","detail","aiLayoutPageCheck","fills","only","_","answers","answer","last","reading","forEach","position","violations","compiled","sectionIds","design","stored","tree","ok","console","error","copy","dropped","rootId","ownScreenIds","report","scrollTargetIds","repeatsCompiled","load","settled","spentTogether","first","second","usage","inputTokens","outputTokens","cacheReadTokens","cacheWriteTokens","attempts","estCostUsd","Math","round","model","stopReason","aiRunLayoutPage","observe","check","ask","content","step","instructions","messages","role","tool","cutOff","noun","smaller","signal","status","every","violation","min"],"mappings":"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"}
|
|
@@ -184,7 +184,7 @@ import { aiPlanItemCountViolations } from "./ai-job-plan-conformance.js";
|
|
|
184
184
|
* a route, so the job never writes it (rule 13): the member saves it where
|
|
185
185
|
* every record template is set up.
|
|
186
186
|
*/ export function aiPageRecordNote(template) {
|
|
187
|
-
return `This page is drafted as the record template of "${template.name}". To serve a page per record at /${template.base}/…, open Page Properties → Record pages and save its dataset, address and fields.`;
|
|
187
|
+
return `This page is drafted as the record template of "${template.name}". To serve a page per record at /${template.base}/…, open Page Properties → Record pages and save its dataset, address and fields: the cards that list its records link those pages.`;
|
|
188
188
|
}
|
|
189
189
|
/**
|
|
190
190
|
* The pages a section may link by id beyond the ones the site has built, and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-page-sections.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 { REUSABLE_INSTANCE_COMPONENT_ID } from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport { CANVAS_ROOT_ELEMENT_ID } from '@aglyn/aglyn/foundation/constants/canvas'\nimport type { NodesMap } from '@aglyn/aglyn/types/nodes'\nimport {\n aiPlanCreateFor,\n type AiBuildPlanRecord,\n type AiBuildPlanScreen,\n type AiBuildPlanSection,\n} from '../model/ai-build-plan'\nimport { aiPageTypeDefinition, parseAiPageJobInputs } from '../model/ai-page-job'\nimport type { AiJob, AiJobPlan } from '../model/ai-jobs.types'\nimport { aiHomeScreenIds, type AiSiteInventory } from '../model/ai-site-inventory'\nimport type { AiTool } from '../providers/contract'\nimport {\n AI_REASK_OFFENDING_MAX_CHARS,\n aiAnswerTree,\n aiNodeTreeContextFromInventory,\n type AiGenerationCheck,\n} from '../runtime/ai-doctrine'\nimport {\n aiSettleCutHeadings,\n aiSettleDisagreeingNodes,\n aiSettleGridItems,\n aiSettleMechanicalRules,\n detectCutLines,\n detectDisagreeingNodes,\n isAiLinkElement,\n validateAiDoctrineTree,\n walkTree,\n type AiDoctrineNode,\n type AiDoctrineTreeContext,\n type AiDoctrineViolation,\n} from '../runtime/ai-doctrine-validators'\nimport { AI_INSTANCE_REF_PROP, validateAiNodeTree } from '../runtime/ai-node-tree'\nimport { aiPageLinkTarget, aiPageScrollInteraction } from '../runtime/ai-page-links'\nimport type { AiLoadEstimate } from '../runtime/ai-palette'\nimport { AI_PALETTE_CATALOG } from '../runtime/ai-palette.generated'\nimport { AI_REPEAT_KEY, expandAiRepeatedItems } from '../runtime/ai-repeated-items'\nimport type { AiSystemBlock } from '../runtime/ai-runtime'\nimport { aiJobBriefLine, aiPlanReferenceLines } from './ai-job-generation'\nimport { aiPlanItemCountViolations } from './ai-job-plan-conformance'\n\n/**\n * A page built one section at a time (AGL-2907): what one section pass asks\n * for, how its answer is held to the building rules as part of the page, and\n * how it joins the page.\n *\n * Pure: no Firestore and no provider, so the page step, its specs and the\n * evals read one definition of a section.\n *\n * ── Held as part of the page ─────────────────────────────────────────────\n *\n * A section is checked twice over, by validators the doctrine already has:\n * the palette validator on the section as the model wrote it, then the\n * doctrine's whole page check on the page built so far with the section\n * added. So the page's one main, its one h1 and its heading outline, repeats\n * across sections, and its weight against the page budget are held on every\n * pass, not only on the last. The violations name the section's own nodes,\n * by the ids the model wrote, so a re-ask quotes this section and nothing\n * else — the page is never sent back.\n *\n * ── A repeated item written once (AGL-3053) ──────────────────────────────\n *\n * Where the workspace keeps no reusable components, an answer writes a\n * repeated item once and lists its copies' values, and the check draws the\n * copies before either validator reads the section (`ai-repeated-items.ts`).\n * Both then read the section as the page stores it, so the page's rules hold\n * on every copy exactly as on an item written out in full, and a finding on a\n * copy names the node the model wrote. Where the workspace keeps components\n * the same shape is written around an instance (AGL-3024), so a section of\n * many cards costs its structure once on every plan; an item that places no\n * instance is still refused there.\n */\n\n/** The section root id a pass writes, from the job and the plan section's index. */\nexport function aiPageSectionNodeId(jobId: string, index: number): string {\n return `ai-${jobId.slice(0, 12)}-section-${index + 1}`\n}\n\n/** The strict tool a section arrives through. The node map rides as JSON text, as a page's does. */\nexport const AI_PAGE_SECTION_TOOL: AiTool = {\n name: 'submit_section',\n description: 'Submit one section of the page as one flat node map.',\n strict: true,\n inputSchema: {\n type: 'object',\n additionalProperties: false,\n required: ['tree'],\n properties: {\n tree: {\n type: 'string',\n description:\n 'The section as JSON: {\"rootId\": \"<id>\", \"nodes\": {\"<id>\": {\"componentId\": \"...\", \"props\": {...}, \"sx\": {...}, \"nodes\": [\"<child id>\", ...]}}}. The root is the document wrapper (componentId \"div\") holding one Section.',\n },\n },\n },\n}\n\n/** The page step's own instructions, cached after the doctrine, with the screen palette after them. */\nexport const AI_JOB_PAGE_INSTRUCTIONS: readonly AiSystemBlock[] = [\n {\n text: [\n 'You build a web page one section at a time, in the order a confirmed plan gives. Each answer is ONE section: call submit_section with a flat node map whose root is the document wrapper (componentId \"div\") holding exactly one Section (section).',\n 'The first section is the top of the page and holds the page’s one h1, its title. Every later section opens with an h2, and headings below it step down one level at a time.',\n 'Place what the section’s plan line names. A component the site has is placed as an instance, never drawn again: componentId \"reusableInstance\", props {\"refId\": \"<component id>\", \"propValues\": {…}} filling the props the inventory lists. A form the site has is a Form (form) whose formId is that form’s id. Another page of the site is linked by its page id, with a Page Link (muiScreenLink) or a Button (muiButton) whose screenId is that id.',\n 'Where the request says the site keeps no reusable components, draw a repeated item in the section instead, written once. A form is only ever a saved one placed by its formId: where the plan line names no form, the section draws no form and no form fields.',\n 'Lay the section out with a Container, a Stack or a Grid (\"container\": true, \"spacing\": 3) of Grid items sized like \"xs:12 md:4\", and size nothing with a fixed width. Colors come from the theme’s palette tokens such as primary.main, spacing from the spacing scale, and type from the text variants.',\n 'The page renders inside the site’s layout, so a section is never a header, navigation or footer.',\n 'A picture is an Image (image) with alt text that says what it should show and no src, for the site owner to fill from the media library.',\n 'Write plain, specific copy in the site’s voice, with no filler. Where the brief leaves out a fact, such as a price, a phone number or an address, write the gap in square brackets instead of inventing it.',\n ].join('\\n'),\n },\n { text: AI_PALETTE_CATALOG.screen, cacheBreakpoint: true },\n]\n\n/** A plan reference as the request names it: the id with the name it was planned under. */\nfunction referenceOf(plan: AiJobPlan, ref: string): string {\n const label = plan.labels?.[ref]\n return label ? `${ref} (\"${label}\")` : ref\n}\n\n/**\n * A record template as a page pass reads it (AGL-3475): the dataset by name,\n * its base, and the fields its copy binds, as `{{item.<id>}}` with the name a\n * member gave each. A dataset the plan creates has no ids yet, so its tokens\n * are the field names it was planned with.\n */\nexport interface AiPageRecordTemplate {\n /** The dataset: an inventory id, or the plan's `new:<name>`. */\n dataset: string\n name: string\n base: string\n fields: Array<{ id: string; name: string }>\n /** The field holding each record's photo, where the dataset has one (AGL-3616). */\n imageField?: string\n}\n\n/** The record template a plan screen is, read against the site's datasets; null for a page that is one page. */\nexport function aiPageRecordTemplate(\n record: AiBuildPlanRecord | null | undefined,\n inventory: AiSiteInventory | null,\n plan: AiJobPlan,\n): AiPageRecordTemplate | null {\n if (!record) return null\n const row = inventory?.datasets.find((entry) => entry.id === record.dataset)\n if (row) {\n return {\n dataset: record.dataset,\n name: row.name,\n base: record.base,\n fields: row.fields.map((name, index) => ({ id: row.fieldIds?.[index] || name, name })),\n ...(row.imageField ? { imageField: row.imageField } : {}),\n }\n }\n const created = aiPlanCreateFor(plan, record.dataset)\n return {\n dataset: record.dataset,\n name: created?.name ?? plan.labels?.[record.dataset] ?? record.dataset,\n base: record.base,\n fields: (created?.fields ?? []).map((name) => ({ id: name, name })),\n }\n}\n\n/** Every token a record template's page may bind: each field, and `{{item.url}}`. */\nexport function aiPageRecordTokens(template: AiPageRecordTemplate | null): string[] {\n if (!template) return []\n return [...template.fields.map((field) => `{{item.${field.id}}}`), '{{item.url}}']\n}\n\n/** What a section request says on a record template's page. */\nexport function aiPageRecordLine(template: AiPageRecordTemplate): string {\n const fields = template.fields.length\n ? ` Its fields: ${template.fields\n .map((field) => (field.name === field.id ? `{{item.${field.id}}}` : `{{item.${field.id}}} (${field.name})`))\n .join(', ')}.`\n : ''\n // A record's photo is a picture's address, never its words (AGL-3616).\n const photo = template.imageField ? ` Each record's photo is {{item.${template.imageField}}}: the src of the page's main Image.` : ''\n return `This page is the record template of the dataset \"${template.name}\": it is served once per record, at /${template.base}/<record address>. Write what differs from one record to the next as {{item.<field>}}, never one record's copy, and write out what every record page shares.${fields}${photo}`\n}\n\n/**\n * A record template's section with the record's own photo (AGL-3616): where\n * the dataset keeps one and the page shows it nowhere yet, the section's\n * first Image that names no record's photo shows `{{item.<photo field>}}`,\n * so each record's page leads with its piece, its dish, its person, as its\n * card on the list does. Any other section, and a page already showing it,\n * is returned as it came. Pure.\n */\nexport function aiPageSectionWithRecordImage(\n section: AiPageSection,\n page: NodesMap,\n template: AiPageRecordTemplate | null,\n): AiPageSection {\n const field = template?.imageField\n if (!field) return section\n const token = `{{item.${field}}}`\n const showsIt = (nodes: NodesMap) =>\n Object.values(nodes as unknown as Record<string, { componentId?: unknown; props?: Record<string, unknown> }>).some(\n (node) => node?.componentId === 'image' && node.props?.['src'] === token,\n )\n if (showsIt(page) || showsIt(section.nodes)) return section\n const first = walkTree({ rootId: section.rootId, nodes: section.nodes as unknown as Record<string, AiDoctrineNode> }).find(\n ({ node }) => node.componentId === 'image',\n )\n if (!first) return section\n const node = (section.nodes as unknown as Record<string, Record<string, unknown>>)[first.id]\n const props = isRecord(node['props']) ? node['props'] : {}\n return {\n ...section,\n nodes: { ...section.nodes, [first.id]: { ...node, props: { ...props, src: token } } } as unknown as NodesMap,\n }\n}\n\n/**\n * What a record template's draft tells the member to do next. The binding is\n * a route, so the job never writes it (rule 13): the member saves it where\n * every record template is set up.\n */\nexport function aiPageRecordNote(template: AiPageRecordTemplate): string {\n return `This page is drafted as the record template of \"${template.name}\". To serve a page per record at /${template.base}/…, open Page Properties → Record pages and save its dataset, address and fields.`\n}\n\nexport interface AiPageSectionPromptInput {\n job: Pick<AiJob, 'brief' | 'inputs'>\n plan: AiJobPlan\n screen: AiBuildPlanScreen\n index: number\n /** The most elements the section may carry at this pass's answer ceiling. */\n maxElements: number\n /**\n * Whether the workspace keeps reusable components (AGL-3030); `false`\n * asks for a repeated item drawn in the section. Absent is `true`. A form\n * is never drawn inline, whatever this says (AGL-3596).\n */\n reusableComponents?: boolean\n /** The dataset this page is the record template of; absent for a page that is one page. */\n record?: AiPageRecordTemplate | null\n /**\n * The site's other pages a link may go to by id (AGL-3596): a guided\n * start's pages are minted on its plan before any is built, so the Home\n * page is built before the Contact page its buttons go to exists.\n */\n linkablePages?: readonly AiLinkablePage[]\n}\n\n/** A page of the site a section may link by its id, built or still to come. */\nexport interface AiLinkablePage {\n id: string\n label: string\n slug: string\n}\n\n/**\n * The pages a section may link by id beyond the ones the site has built, and\n * the one page a link that names no destination can only mean (AGL-3596).\n * `planned` are a guided start's pages, minted on its plan (the input the\n * layout reads them from); `own` are this page's ids, which neither counts.\n * The link target is the site's one page that is neither its home nor this\n * page, where it has exactly one, built or planned: a two-page guided start's\n * Contact page, which its Home hero's \"Book an appointment\" goes to.\n */\nexport function aiPageLinkablePages(\n inventory: AiSiteInventory | null,\n planned: readonly AiLinkablePage[],\n own: ReadonlyArray<string | null | undefined>,\n): { linkablePages: AiLinkablePage[]; linkTarget: string | null } {\n const mine = new Set(own.filter((id): id is string => Boolean(id)))\n const home = new Set(aiHomeScreenIds(inventory))\n const isHome = (slug: string): boolean => slug.replace(/^\\/+|\\/+$/g, '') === ''\n const linkablePages = planned.filter((page) => !mine.has(page.id))\n const targets = new Set([\n ...(inventory?.screens ?? [])\n .filter((row) => !row.template && !home.has(row.id) && !isHome(row.slug))\n .map((row) => row.id),\n ...linkablePages.filter((page) => !isHome(page.slug)).map((page) => page.id),\n ])\n for (const id of mine) targets.delete(id)\n return { linkablePages, linkTarget: targets.size === 1 ? [...targets][0] : null }\n}\n\n/** The line a section request names the site's other pages in. */\nexport function aiPageSectionLinkablePagesLine(pages: readonly AiLinkablePage[]): string | null {\n if (!pages.length) return null\n const listed = pages.map((page) => `${page.label} (${page.slug || '/'}, id \"${page.id}\")`).join(', ')\n return `Other pages of this site: ${listed}. A button or link that goes to one sets its \"screenId\" to that id.`\n}\n\n/** What a section request says where the workspace keeps no reusable components. */\nexport const AI_PAGE_SECTION_INLINE_LINE =\n 'This site keeps no reusable components: write a repeated item once.'\n\n/** How a repeated item is written once, in the words a request and a re-ask share. */\nconst AI_PAGE_SECTION_REPEAT_SHAPE = `put {{1}}, {{2}}… where its copies differ, and give its outermost node \"${AI_REPEAT_KEY}\", one list of values a copy, in that order, as [[\"Title 1\", \"Text 1\"], [\"Title 2\", \"Text 2\"]]`\n\n/**\n * How a repeated item is written once (AGL-3053): the item's subtree once,\n * with placeholders where its copies differ and their values listed, which\n * the section check draws into its copies (`ai-repeated-items.ts`). It rides\n * the request of a section whose plan line shows items on a workspace that\n * keeps no reusable components, and no other: a section with nothing to repeat\n * pays nothing for it, and the cached prefix every workspace shares says only\n * that a repeated item is written once.\n */\nexport const AI_PAGE_SECTION_REPEAT_LINE = `Write a repeated item once: ${AI_PAGE_SECTION_REPEAT_SHAPE}.`\n\n/**\n * How a workspace that keeps reusable components writes a repeated item\n * (AGL-3143 §10): the shape a Free section writes, around an instance of a\n * component the section already places — the instance ONCE, `{{n}}` through\n * the values it fills, and one list of values a copy — rather than the item's\n * subtree drawn once per copy, or one instance node written per copy.\n *\n * Six cards written as six instance nodes spend their structure six times;\n * written once they spend it once, which is the difference between a section\n * that fits its ceiling and one that is cut off. A section stays ONE section\n * either way: splitting it would give the page a second h2 for the same idea,\n * which is not what the member asked for and not what its outline should say.\n *\n * ⛔ The repeated item is the GRID ITEM, not the instance. Measured live on\n * 2026-09-22: told only to \"place ONE instance … and give its outermost node\n * repeat\", the model made the instance itself the repeated node and hung it\n * straight off the Grid container. The section fitted — the ceiling failure\n * was gone — and the page was then refused by rule 12, which requires every\n * child of a Grid container to be a sized Grid item (AGL-3055). The line has\n * to name the wrapper, because \"outermost node\" reads as the instance when\n * the instance is all the request mentions.\n *\n * It rides the request of a section whose plan line shows items AND names a\n * record to place, on the same terms the repeat line rides a Free one: a\n * section with nothing to repeat, or nothing to repeat it FROM, pays nothing\n * for it.\n *\n * ## Why a paid section could not be built without it (AGL-3024)\n *\n * The Free path is reconciled at both ends — its plan is held to the sections\n * its wall pays for (AGL-3070) and its request is shown the repeat shape\n * (AGL-3053). The paid path was reconciled at neither: `AI_BUILD_PLAN_LIMITS`\n * lets a plan promise up to `items: 500` in one section, the pass that builds\n * it fits `aiJobPageSectionMaxElements` — fifteen at the balanced tier — and\n * the request said only how many elements to keep under, never how to get\n * there. A six-card grid measured live on 2026-09-21 was drawn inline, ran\n * past its ceiling, and was cut off; the re-ask then said to place an instance\n * \"of a component the site has\" without naming one, so it was cut off too, and\n * `AI_GENERATION_MAX_ATTEMPTS` ended the job with no page. A four-card grid on\n * the same site had fitted, which is why this went unseen. Naming the shape\n * was not enough on its own: `ai-repeated-items.ts` refused `repeat` outright\n * on such a workspace, so the only shape the request could ask for was the\n * expensive one.\n *\n * ⛔ This does NOT make the plan and the pass agree about what fits — a plan\n * may still promise more items than any ceiling can carry, and this line only\n * gives the pass its cheapest way to try. That bound belongs on the plan step\n * and is deliberately not taken here.\n */\nexport const AI_PAGE_SECTION_INSTANCE_LINE = `Write a repeated item once: put ONE instance of the component this section places inside ONE Grid item sized like \"xs:12 sm:6 md:4\", and repeat THAT GRID ITEM rather than the instance — every child of a Grid container is itself a Grid item. Put {{1}}, {{2}}… where the copies differ, and give the Grid item \"${AI_REPEAT_KEY}\", one list of values a copy, in that order, as [[\"Title 1\", \"Text 1\"], [\"Title 2\", \"Text 2\"]].`\n\n/**\n * What a pass whose answer ran past its ceiling is told makes a section\n * smaller (AGL-3042): fewer elements, down to the budget the request gave,\n * shorter copy, and a repeated item drawn no more than once — placed as an\n * instance where the workspace keeps reusable components, and written once\n * where it keeps none (AGL-3053), with the shape spelled out, since a section\n * whose plan line showed no items was never told it. It rides the re-ask,\n * never the first request, so a pass that fits sends no byte more.\n */\nexport function aiPageSectionSmaller(input: Pick<AiPageSectionPromptInput, 'maxElements' | 'reusableComponents'>): string {\n return input.reusableComponents === false\n ? `Make it smaller: use fewer elements, at most ${input.maxElements}; write shorter copy; and write a repeated item once instead of drawing it again: ${AI_PAGE_SECTION_REPEAT_SHAPE}.`\n : `Make it smaller: use fewer elements, at most ${input.maxElements}; write shorter copy; and write a repeated item once instead of drawing it again: put ONE instance of a component the site has inside ONE Grid item sized like \"xs:12 sm:6 md:4\", and repeat that Grid item — ${AI_PAGE_SECTION_REPEAT_SHAPE}.`\n}\n\n/** One pass's user turn: the page, the brief, the plan, this section and what is built above it. */\nexport function aiPageSectionPrompt(input: AiPageSectionPromptInput): string {\n const { job, plan, screen, index } = input\n const inputs = parseAiPageJobInputs(job.inputs)\n const type = typeof inputs === 'string' ? null : aiPageTypeDefinition(inputs.pageType)\n const section = screen.sections[index] as AiBuildPlanSection\n const places = section.uses.length\n ? ` It places ${section.uses.map((ref) => referenceOf(plan, ref)).join(', ')}.`\n : ''\n const items = section.items ? ` It shows ${section.items} items.` : ''\n const built = screen.sections.slice(0, index).map((entry, position) => `${position + 1}. ${entry.name}`)\n return [\n `Page: \"${screen.title}\" at ${screen.slug}`,\n ...(type ? [`Page type: ${type.purpose}`] : []),\n ...(input.record ? [aiPageRecordLine(input.record)] : []),\n aiJobBriefLine(job),\n ...aiPlanReferenceLines(plan),\n `Build section ${index + 1} of ${screen.sections.length}: \"${section.name}\".${places}${items}`,\n built.length\n ? `Already built, above it: ${built.join('; ')}. The page’s h1 is in section 1.`\n : 'Nothing is built yet: this section holds the page’s h1.',\n ...(input.reusableComponents === false\n ? [AI_PAGE_SECTION_INLINE_LINE, ...(section.items ? [AI_PAGE_SECTION_REPEAT_LINE] : [])]\n : section.items && section.uses.length\n ? [AI_PAGE_SECTION_INSTANCE_LINE]\n : []),\n ...(input.linkablePages?.length ? [aiPageSectionLinkablePagesLine(input.linkablePages) as string] : []),\n `Keep this section to at most ${input.maxElements} elements.`,\n ].join('\\n')\n}\n\n/** A validated section: its nodes keyed as the page stores them, its root under the page root. */\nexport interface AiPageSection {\n rootId: string\n nodes: NodesMap\n /** The page's weight with the section added, as the doctrine measured it. */\n load: AiLoadEstimate | null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/** A page with nothing on it yet: the document wrapper. */\nexport function aiEmptyPage(): NodesMap {\n return {\n [CANVAS_ROOT_ELEMENT_ID]: {\n $id: CANVAS_ROOT_ELEMENT_ID,\n componentId: 'div',\n parentId: null,\n nodes: [],\n },\n } as unknown as NodesMap\n}\n\n/**\n * The page with a section in its plan position: after every section with a\n * lower index and before every one with a higher, the page's other children\n * — whatever a member placed — kept where they are. A section already on the\n * page is replaced, never doubled.\n */\nexport function aiPageWithSection(\n page: NodesMap,\n section: AiPageSection,\n sectionIds: readonly string[],\n): NodesMap {\n const nodes: Record<string, Record<string, unknown>> = {}\n const previous = (page as unknown as Record<string, Record<string, unknown>>)[section.rootId]\n const replaced = new Set<string>()\n if (previous) {\n for (const { id } of walkTree({\n rootId: section.rootId,\n nodes: page as unknown as Record<string, AiDoctrineNode>,\n })) {\n replaced.add(id)\n }\n }\n for (const [id, node] of Object.entries(page)) {\n if (!replaced.has(id)) nodes[id] = { ...(node as unknown as Record<string, unknown>) }\n }\n const root = nodes[CANVAS_ROOT_ELEMENT_ID] ?? (aiEmptyPage()[CANVAS_ROOT_ELEMENT_ID] as unknown as Record<string, unknown>)\n const children = (Array.isArray(root['nodes']) ? (root['nodes'] as string[]) : []).filter(\n (id) => id !== section.rootId,\n )\n const order = new Map(sectionIds.map((id, position) => [id, position]))\n const at = order.get(section.rootId) ?? sectionIds.length\n const before = children.findIndex((id) => (order.get(id) ?? -1) > at)\n children.splice(before === -1 ? children.length : before, 0, section.rootId)\n nodes[CANVAS_ROOT_ELEMENT_ID] = { ...root, nodes: children }\n for (const [id, node] of Object.entries(section.nodes)) {\n nodes[id] = { ...(node as unknown as Record<string, unknown>) }\n }\n return nodes as unknown as NodesMap\n}\n\n/**\n * What a tree generated against this inventory may reference, the brand it is\n * held to, where the workspace keeps no reusable components\n * (AGL-3030) that the page is built inline, the sections its plan names,\n * which a link may take a visitor to (AGL-3097), and the players its plan\n * lists for this page, the only ones it may embed (AGL-3433).\n */\nexport function aiPageCheckContext(\n inventory: AiSiteInventory | null,\n options: {\n reusableComponents?: boolean\n sections?: readonly string[]\n embeds?: AiDoctrineTreeContext['plannedEmbeds']\n /** A record template's tokens, which its links and images may name (AGL-3475). */\n recordTokens?: readonly string[]\n /** The site's pages still to be built that a link may go to by id (AGL-3596). */\n linkablePages?: readonly AiLinkablePage[]\n } = {},\n): AiDoctrineTreeContext {\n const tree = aiNodeTreeContextFromInventory(inventory)\n const screenIds = [...new Set([...(tree.screenIds ?? []), ...(options.linkablePages ?? []).map((page) => page.id)])]\n return {\n brand: inventory?.theme ? { colors: inventory.theme.colors, fonts: inventory.theme.fonts } : null,\n ...tree,\n ...(tree.screenIds || options.linkablePages?.length ? { screenIds } : {}),\n homeScreenIds: aiHomeScreenIds(inventory),\n ...(options.reusableComponents === false ? { reusableComponents: false } : {}),\n ...(options.sections?.length ? { pageSections: options.sections } : {}),\n ...(options.embeds?.length ? { plannedEmbeds: options.embeds } : {}),\n ...(options.recordTokens?.length ? { bindingTokens: options.recordTokens } : {}),\n }\n}\n\nexport interface AiPageSectionCheckInput {\n /** The page as stored so far; an empty page on the first pass. */\n page: NodesMap\n /** Every section root id of the plan, in order. */\n sectionIds: readonly string[]\n index: number\n context: AiDoctrineTreeContext\n /**\n * The plan line this pass answers for: what it places by inventory id, and\n * how many items it promised, which the answer is held to (AGL-3024).\n */\n section: Pick<AiBuildPlanSection, 'name' | 'uses' | 'items'>\n inventory: AiSiteInventory | null\n /**\n * The one page a link that goes nowhere can only mean, where the site has\n * exactly one page besides its home and this one (AGL-3596): a guided\n * start's Contact page. Absent or `null`, such a link is re-asked.\n */\n linkTarget?: string | null\n}\n\n/** The parts of an answer the violations name, as the model wrote them, capped as the doctrine caps a re-ask. */\nfunction offendingOf(raw: unknown, violations: readonly AiDoctrineViolation[]): { offending?: Record<string, unknown> } {\n const rawNodes = isRecord(raw) && isRecord(raw['nodes']) ? raw['nodes'] : {}\n const offending: Record<string, unknown> = {}\n let used = 2\n for (const id of new Set(violations.flatMap((violation) => violation.nodeIds ?? []))) {\n if (rawNodes[id] === undefined) continue\n const size = JSON.stringify(rawNodes[id]).length + id.length + 4\n if (used + size > AI_REASK_OFFENDING_MAX_CHARS) break\n offending[id] = rawNodes[id]\n used += size\n }\n return Object.keys(offending).length ? { offending } : {}\n}\n\n/**\n * The check a section's answer is held to: a repeated item written once drawn\n * into its copies (AGL-3053), then the palette validator on the section, with\n * any line it cut at its ceiling refused (AGL-3076), a Grid container's items\n * sized where rule 12 has one answer (AGL-3596), the doctrine's page check\n * on the page with the section added, and the plan line — every component it\n * names placed as an instance, every form bound by its id (rule 7), and as\n * many items as it promised (AGL-3024). Violations\n * name the section's own nodes by the ids the MODEL wrote, and a copy's nodes\n * by the item's; one that names only nodes an earlier pass stored belongs to\n * the page rather than to this answer, and is left to the last pass (AGL-3078).\n */\nexport function aiPageSectionCheck(input: AiPageSectionCheckInput): AiGenerationCheck<AiPageSection> {\n const sectionId = input.sectionIds[input.index]\n const components = new Set((input.inventory?.components ?? []).map((row) => row.id))\n const forms = new Set((input.inventory?.forms ?? []).map((row) => row.id))\n return (answer) => {\n // A child named and never written, an element written and held by\n // nothing, and a heading whose first clause fits its ceiling are settled\n // where each has one reading (AGL-3596).\n const raw = aiSettleCutHeadings(aiSettleDisagreeingNodes(aiAnswerTree(answer)))\n // Before anything is drawn or dropped: a repeated item written and never\n // placed is content the section loses silently, and a child named and\n // never written ends the pass with nothing to answer (AGL-3143).\n const disagreeing = detectDisagreeingNodes(raw)\n if (disagreeing.length) {\n return { value: null, violations: disagreeing, ...offendingOf(raw, disagreeing) }\n }\n // A repeated item is drawn inline where the workspace keeps no reusable\n // components, and where this section's plan line places none (AGL-3596):\n // there is then no component it could be drawing by hand, and a paid\n // guided start's \"Why choose us\" was refused for rule 1 with nothing to place.\n const inline = input.context.reusableComponents === false || !input.section.uses.some((ref) => components.has(ref))\n const drawn = expandAiRepeatedItems(raw, { inline, noun: 'section' })\n if (drawn.ok === false) {\n return { value: null, violations: drawn.violations, ...offendingOf(raw, drawn.violations) }\n }\n // Every id below is the drawn tree's; a copy's leads back to the node the model wrote.\n const written = (id: string): string => drawn.sourceIds[id] ?? id\n const validated = validateAiNodeTree(drawn.tree, 'screen', input.context)\n if (validated.ok === false) {\n return {\n value: null,\n violations: [\n {\n rule: null,\n code: `tree-${validated.code}`,\n message: 'The answer could not be used as a section.',\n detail: validated.error,\n },\n ],\n }\n }\n const drawnNodes = isRecord(drawn.tree) && isRecord(drawn.tree['nodes']) ? drawn.tree['nodes'] : {}\n // A Grid container's items are sized, and an element straight in one is\n // put in an item, before the page check reads them: that rule has one\n // answer, the size its re-ask would name (AGL-3596). Read off the section\n // as the palette validator stored it, with what the model wrote beside it.\n const { nodes: settled } = aiSettleGridItems(\n { rootId: validated.rootId, nodes: validated.nodes as unknown as Record<string, AiDoctrineNode> },\n { written: (id) => drawnNodes[validated.sourceIds[id] ?? id] },\n )\n const wrapper = settled[validated.rootId] as AiDoctrineNode | undefined\n const top = (wrapper?.nodes ?? []).filter((id) => settled[id])\n const sectionNode = top.length === 1 ? settled[top[0]] : null\n if (!sectionNode || sectionNode.componentId !== 'section') {\n return {\n value: null,\n violations: [\n {\n rule: null,\n code: 'section-shape',\n message: 'Answer with exactly one Section element inside the document wrapper.',\n },\n ],\n }\n }\n\n // The section's root takes its plan id, so a pass run again finds it, and\n // hangs under the page root; every other minted id stays as minted.\n const minted = top[0]\n const modelIds: Record<string, string> = Object.fromEntries(\n Object.entries(validated.sourceIds).map(([id, source]) => [id, written(source)]),\n )\n modelIds[sectionId] = written(validated.sourceIds[minted] ?? minted)\n const sectionNodes: Record<string, Record<string, unknown>> = {}\n for (const { id, node } of walkTree({ rootId: minted, nodes: settled })) {\n const stored = { ...(node as unknown as Record<string, unknown>) }\n if (id === minted) {\n stored['$id'] = sectionId\n stored['parentId'] = CANVAS_ROOT_ELEMENT_ID\n } else if (stored['parentId'] === minted) {\n stored['parentId'] = sectionId\n }\n sectionNodes[id === minted ? sectionId : id] = stored\n }\n // What the model wrote of one of the section's nodes, by the id the page stores it under.\n const drawnIdOf = (stored: string): string =>\n validated.sourceIds[stored === sectionId ? minted : stored] ?? stored\n // A link that names a section of this page carries the platform's Scroll to\n // element interaction to that section's root, whose id is minted from the\n // plan before the section is built (AGL-3097).\n const sections = input.context.pageSections ?? []\n // A link that names no destination at all, on a site with one page it can\n // only mean, goes to that page (AGL-3596); one inside a form is the form's\n // own button, which rule 10 asks to take out.\n const inForm = (id: string): boolean => {\n for (let at = sectionNodes[id]?.['parentId']; typeof at === 'string'; at = sectionNodes[at]?.['parentId']) {\n if (sectionNodes[at]?.['componentId'] === 'form') return true\n }\n return false\n }\n for (const [id, node] of Object.entries(sectionNodes)) {\n const props = isRecord(node['props']) ? node['props'] : {}\n if (!isAiLinkElement(node['componentId']) || props['screenId'] || props['href']) continue\n const target = aiPageLinkTarget(drawnNodes[drawnIdOf(id)], sections)\n if (target?.kind === 'section') {\n node['interactions'] = [aiPageScrollInteraction(input.sectionIds[target.section], sections[target.section])]\n } else if (!target && input.linkTarget && !inForm(id)) {\n node['props'] = { ...props, screenId: input.linkTarget }\n }\n }\n const section: AiPageSection = { rootId: sectionId, nodes: sectionNodes as unknown as NodesMap, load: null }\n\n // An attribute a rule has one answer for is applied on the page with the\n // section added, since the first image and the one h1 are the page's\n // (AGL-3660). The section keeps what that settled of its own nodes; what\n // it settled of an earlier pass's is the last pass's to store.\n const settledPage = aiSettleMechanicalRules(\n {\n rootId: CANVAS_ROOT_ELEMENT_ID,\n nodes: aiPageWithSection(input.page, section, input.sectionIds) as unknown as Record<string, AiDoctrineNode>,\n },\n 'page',\n )\n for (const id of Object.keys(sectionNodes)) {\n sectionNodes[id] = settledPage.nodes[id] as unknown as Record<string, unknown>\n }\n const page = settledPage.nodes as unknown as NodesMap\n const own = new Set(Object.keys(sectionNodes))\n // The page check reads the section as the page stores it, where the palette\n // validator has already dropped what it could not read, such as a\n // `container` written as text or a link's `scrollTo`; what the model wrote\n // of each of the section's nodes is read from the section as it was drawn\n // (AGL-3078). A link the page already carries to one of its section roots\n // goes there, whichever pass wrote it (AGL-3097).\n const report = validateAiDoctrineTree({ rootId: CANVAS_ROOT_ELEMENT_ID, nodes: page }, 'page', {\n ...input.context,\n writtenNode: (id) => (own.has(id) ? drawnNodes[drawnIdOf(id)] : undefined),\n scrollTargetIds: input.sectionIds,\n })\n // The page check mints its ids afresh: its map leads back to the page's\n // ids, and the section's own lead back to the model's.\n const pageIds = report.tree?.sourceIds ?? {}\n const toModel = (id: string): string | null => {\n const stored = pageIds[id] ?? id\n return own.has(stored) ? (modelIds[stored] ?? stored) : null\n }\n // The page check reads the section as it is stored, where a line the\n // palette validator cut is already cut, so the cut is read from the\n // section's own validation, first (AGL-3076). Copies of one item name one\n // node the model wrote, once.\n //\n // A PASS ANSWERS ONLY FOR THE SECTION IT WROTE (AGL-3078). The page check\n // reads the whole page, so it also names nodes an earlier pass stored; the\n // model is not shown those and cannot mend them, so a finding that names\n // none of this section's nodes is not held against this answer. Dropping\n // it neither hides nor forgives it: the last pass runs the same check on\n // the finished page, where every node is the page's and the review names\n // each one and outlines it. Kept, such a finding would re-ask the model\n // for a node it never saw, refuse the same answer twice, and stop the page\n // with findings whose ids all filtered away — no node ids, and so no\n // outline either.\n const violations: AiDoctrineViolation[] = [\n ...detectCutLines(validated.repairs, drawnNodes, written),\n ...report.violations.flatMap((violation) => {\n if (!violation.nodeIds?.length) return [violation]\n const named = [...new Set(violation.nodeIds.map(toModel).filter((id): id is string => id !== null))]\n return named.length ? [{ ...violation, nodeIds: named }] : []\n }),\n ]\n\n const placed = new Set<string>()\n const bound = new Set<string>()\n for (const node of Object.values(sectionNodes)) {\n const props = isRecord(node['props']) ? node['props'] : {}\n if (node['componentId'] === REUSABLE_INSTANCE_COMPONENT_ID && typeof props[AI_INSTANCE_REF_PROP] === 'string') {\n placed.add(props[AI_INSTANCE_REF_PROP] as string)\n }\n if (node['componentId'] === 'form' && typeof props['formId'] === 'string') bound.add(props['formId'])\n }\n const missing = input.section.uses.filter(\n (ref) => (components.has(ref) && !placed.has(ref)) || (forms.has(ref) && !bound.has(ref)),\n )\n if (missing.length) {\n violations.push({\n rule: 7,\n code: 'plan-reuse-not-placed',\n message: `The confirmed plan places ${missing.join(', ')} in this section, and the section does not. Place each one by its id.`,\n })\n }\n // The count the plan promised, against the section as the page stores it\n // (AGL-3024): the prompt states it, and until now nothing read it back.\n violations.push(\n ...aiPlanItemCountViolations(input.section, {\n rootId: sectionId,\n nodes: sectionNodes as unknown as Record<string, AiDoctrineNode>,\n }),\n )\n\n return {\n value: { ...section, load: report.load },\n violations,\n ...offendingOf(raw, violations),\n }\n }\n}\n"],"names":["REUSABLE_INSTANCE_COMPONENT_ID","CANVAS_ROOT_ELEMENT_ID","aiPlanCreateFor","aiPageTypeDefinition","parseAiPageJobInputs","aiHomeScreenIds","AI_REASK_OFFENDING_MAX_CHARS","aiAnswerTree","aiNodeTreeContextFromInventory","aiSettleCutHeadings","aiSettleDisagreeingNodes","aiSettleGridItems","aiSettleMechanicalRules","detectCutLines","detectDisagreeingNodes","isAiLinkElement","validateAiDoctrineTree","walkTree","AI_INSTANCE_REF_PROP","validateAiNodeTree","aiPageLinkTarget","aiPageScrollInteraction","AI_PALETTE_CATALOG","AI_REPEAT_KEY","expandAiRepeatedItems","aiJobBriefLine","aiPlanReferenceLines","aiPlanItemCountViolations","aiPageSectionNodeId","jobId","index","slice","AI_PAGE_SECTION_TOOL","name","description","strict","inputSchema","type","additionalProperties","required","properties","tree","AI_JOB_PAGE_INSTRUCTIONS","text","join","screen","cacheBreakpoint","referenceOf","plan","ref","label","labels","aiPageRecordTemplate","record","inventory","created","row","datasets","find","entry","id","dataset","base","fields","map","fieldIds","imageField","aiPageRecordTokens","template","field","aiPageRecordLine","length","photo","aiPageSectionWithRecordImage","section","page","token","showsIt","nodes","Object","values","some","node","componentId","props","first","rootId","isRecord","src","aiPageRecordNote","aiPageLinkablePages","planned","own","mine","Set","filter","Boolean","home","isHome","slug","replace","linkablePages","has","targets","screens","delete","linkTarget","size","aiPageSectionLinkablePagesLine","pages","listed","AI_PAGE_SECTION_INLINE_LINE","AI_PAGE_SECTION_REPEAT_SHAPE","AI_PAGE_SECTION_REPEAT_LINE","AI_PAGE_SECTION_INSTANCE_LINE","aiPageSectionSmaller","input","reusableComponents","maxElements","aiPageSectionPrompt","job","inputs","pageType","sections","places","uses","items","built","position","title","purpose","value","Array","isArray","aiEmptyPage","$id","parentId","aiPageWithSection","sectionIds","order","previous","replaced","add","entries","root","children","Map","at","get","before","findIndex","splice","aiPageCheckContext","options","screenIds","brand","theme","colors","fonts","homeScreenIds","pageSections","embeds","plannedEmbeds","recordTokens","bindingTokens","offendingOf","raw","violations","rawNodes","offending","used","flatMap","violation","nodeIds","undefined","JSON","stringify","keys","aiPageSectionCheck","sectionId","components","forms","answer","validated","report","disagreeing","inline","context","drawn","noun","ok","written","sourceIds","rule","code","message","detail","error","drawnNodes","settled","wrapper","top","sectionNode","minted","modelIds","fromEntries","source","sectionNodes","stored","drawnIdOf","inForm","target","kind","screenId","load","settledPage","writtenNode","scrollTargetIds","pageIds","toModel","repairs","named","placed","bound","missing","push"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-page-sections.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 { REUSABLE_INSTANCE_COMPONENT_ID } from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport { CANVAS_ROOT_ELEMENT_ID } from '@aglyn/aglyn/foundation/constants/canvas'\nimport type { NodesMap } from '@aglyn/aglyn/types/nodes'\nimport {\n aiPlanCreateFor,\n type AiBuildPlanRecord,\n type AiBuildPlanScreen,\n type AiBuildPlanSection,\n} from '../model/ai-build-plan'\nimport { aiPageTypeDefinition, parseAiPageJobInputs } from '../model/ai-page-job'\nimport type { AiJob, AiJobPlan } from '../model/ai-jobs.types'\nimport { aiHomeScreenIds, type AiSiteInventory } from '../model/ai-site-inventory'\nimport type { AiTool } from '../providers/contract'\nimport {\n AI_REASK_OFFENDING_MAX_CHARS,\n aiAnswerTree,\n aiNodeTreeContextFromInventory,\n type AiGenerationCheck,\n} from '../runtime/ai-doctrine'\nimport {\n aiSettleCutHeadings,\n aiSettleDisagreeingNodes,\n aiSettleGridItems,\n aiSettleMechanicalRules,\n detectCutLines,\n detectDisagreeingNodes,\n isAiLinkElement,\n validateAiDoctrineTree,\n walkTree,\n type AiDoctrineNode,\n type AiDoctrineTreeContext,\n type AiDoctrineViolation,\n} from '../runtime/ai-doctrine-validators'\nimport { AI_INSTANCE_REF_PROP, validateAiNodeTree } from '../runtime/ai-node-tree'\nimport { aiPageLinkTarget, aiPageScrollInteraction } from '../runtime/ai-page-links'\nimport type { AiLoadEstimate } from '../runtime/ai-palette'\nimport { AI_PALETTE_CATALOG } from '../runtime/ai-palette.generated'\nimport { AI_REPEAT_KEY, expandAiRepeatedItems } from '../runtime/ai-repeated-items'\nimport type { AiSystemBlock } from '../runtime/ai-runtime'\nimport { aiJobBriefLine, aiPlanReferenceLines } from './ai-job-generation'\nimport { aiPlanItemCountViolations } from './ai-job-plan-conformance'\n\n/**\n * A page built one section at a time (AGL-2907): what one section pass asks\n * for, how its answer is held to the building rules as part of the page, and\n * how it joins the page.\n *\n * Pure: no Firestore and no provider, so the page step, its specs and the\n * evals read one definition of a section.\n *\n * ── Held as part of the page ─────────────────────────────────────────────\n *\n * A section is checked twice over, by validators the doctrine already has:\n * the palette validator on the section as the model wrote it, then the\n * doctrine's whole page check on the page built so far with the section\n * added. So the page's one main, its one h1 and its heading outline, repeats\n * across sections, and its weight against the page budget are held on every\n * pass, not only on the last. The violations name the section's own nodes,\n * by the ids the model wrote, so a re-ask quotes this section and nothing\n * else — the page is never sent back.\n *\n * ── A repeated item written once (AGL-3053) ──────────────────────────────\n *\n * Where the workspace keeps no reusable components, an answer writes a\n * repeated item once and lists its copies' values, and the check draws the\n * copies before either validator reads the section (`ai-repeated-items.ts`).\n * Both then read the section as the page stores it, so the page's rules hold\n * on every copy exactly as on an item written out in full, and a finding on a\n * copy names the node the model wrote. Where the workspace keeps components\n * the same shape is written around an instance (AGL-3024), so a section of\n * many cards costs its structure once on every plan; an item that places no\n * instance is still refused there.\n */\n\n/** The section root id a pass writes, from the job and the plan section's index. */\nexport function aiPageSectionNodeId(jobId: string, index: number): string {\n return `ai-${jobId.slice(0, 12)}-section-${index + 1}`\n}\n\n/** The strict tool a section arrives through. The node map rides as JSON text, as a page's does. */\nexport const AI_PAGE_SECTION_TOOL: AiTool = {\n name: 'submit_section',\n description: 'Submit one section of the page as one flat node map.',\n strict: true,\n inputSchema: {\n type: 'object',\n additionalProperties: false,\n required: ['tree'],\n properties: {\n tree: {\n type: 'string',\n description:\n 'The section as JSON: {\"rootId\": \"<id>\", \"nodes\": {\"<id>\": {\"componentId\": \"...\", \"props\": {...}, \"sx\": {...}, \"nodes\": [\"<child id>\", ...]}}}. The root is the document wrapper (componentId \"div\") holding one Section.',\n },\n },\n },\n}\n\n/** The page step's own instructions, cached after the doctrine, with the screen palette after them. */\nexport const AI_JOB_PAGE_INSTRUCTIONS: readonly AiSystemBlock[] = [\n {\n text: [\n 'You build a web page one section at a time, in the order a confirmed plan gives. Each answer is ONE section: call submit_section with a flat node map whose root is the document wrapper (componentId \"div\") holding exactly one Section (section).',\n 'The first section is the top of the page and holds the page’s one h1, its title. Every later section opens with an h2, and headings below it step down one level at a time.',\n 'Place what the section’s plan line names. A component the site has is placed as an instance, never drawn again: componentId \"reusableInstance\", props {\"refId\": \"<component id>\", \"propValues\": {…}} filling the props the inventory lists. A form the site has is a Form (form) whose formId is that form’s id. Another page of the site is linked by its page id, with a Page Link (muiScreenLink) or a Button (muiButton) whose screenId is that id.',\n 'Where the request says the site keeps no reusable components, draw a repeated item in the section instead, written once. A form is only ever a saved one placed by its formId: where the plan line names no form, the section draws no form and no form fields.',\n 'Lay the section out with a Container, a Stack or a Grid (\"container\": true, \"spacing\": 3) of Grid items sized like \"xs:12 md:4\", and size nothing with a fixed width. Colors come from the theme’s palette tokens such as primary.main, spacing from the spacing scale, and type from the text variants.',\n 'The page renders inside the site’s layout, so a section is never a header, navigation or footer.',\n 'A picture is an Image (image) with alt text that says what it should show and no src, for the site owner to fill from the media library.',\n 'Write plain, specific copy in the site’s voice, with no filler. Where the brief leaves out a fact, such as a price, a phone number or an address, write the gap in square brackets instead of inventing it.',\n ].join('\\n'),\n },\n { text: AI_PALETTE_CATALOG.screen, cacheBreakpoint: true },\n]\n\n/** A plan reference as the request names it: the id with the name it was planned under. */\nfunction referenceOf(plan: AiJobPlan, ref: string): string {\n const label = plan.labels?.[ref]\n return label ? `${ref} (\"${label}\")` : ref\n}\n\n/**\n * A record template as a page pass reads it (AGL-3475): the dataset by name,\n * its base, and the fields its copy binds, as `{{item.<id>}}` with the name a\n * member gave each. A dataset the plan creates has no ids yet, so its tokens\n * are the field names it was planned with.\n */\nexport interface AiPageRecordTemplate {\n /** The dataset: an inventory id, or the plan's `new:<name>`. */\n dataset: string\n name: string\n base: string\n fields: Array<{ id: string; name: string }>\n /** The field holding each record's photo, where the dataset has one (AGL-3616). */\n imageField?: string\n}\n\n/** The record template a plan screen is, read against the site's datasets; null for a page that is one page. */\nexport function aiPageRecordTemplate(\n record: AiBuildPlanRecord | null | undefined,\n inventory: AiSiteInventory | null,\n plan: AiJobPlan,\n): AiPageRecordTemplate | null {\n if (!record) return null\n const row = inventory?.datasets.find((entry) => entry.id === record.dataset)\n if (row) {\n return {\n dataset: record.dataset,\n name: row.name,\n base: record.base,\n fields: row.fields.map((name, index) => ({ id: row.fieldIds?.[index] || name, name })),\n ...(row.imageField ? { imageField: row.imageField } : {}),\n }\n }\n const created = aiPlanCreateFor(plan, record.dataset)\n return {\n dataset: record.dataset,\n name: created?.name ?? plan.labels?.[record.dataset] ?? record.dataset,\n base: record.base,\n fields: (created?.fields ?? []).map((name) => ({ id: name, name })),\n }\n}\n\n/** Every token a record template's page may bind: each field, and `{{item.url}}`. */\nexport function aiPageRecordTokens(template: AiPageRecordTemplate | null): string[] {\n if (!template) return []\n return [...template.fields.map((field) => `{{item.${field.id}}}`), '{{item.url}}']\n}\n\n/** What a section request says on a record template's page. */\nexport function aiPageRecordLine(template: AiPageRecordTemplate): string {\n const fields = template.fields.length\n ? ` Its fields: ${template.fields\n .map((field) => (field.name === field.id ? `{{item.${field.id}}}` : `{{item.${field.id}}} (${field.name})`))\n .join(', ')}.`\n : ''\n // A record's photo is a picture's address, never its words (AGL-3616).\n const photo = template.imageField ? ` Each record's photo is {{item.${template.imageField}}}: the src of the page's main Image.` : ''\n return `This page is the record template of the dataset \"${template.name}\": it is served once per record, at /${template.base}/<record address>. Write what differs from one record to the next as {{item.<field>}}, never one record's copy, and write out what every record page shares.${fields}${photo}`\n}\n\n/**\n * A record template's section with the record's own photo (AGL-3616): where\n * the dataset keeps one and the page shows it nowhere yet, the section's\n * first Image that names no record's photo shows `{{item.<photo field>}}`,\n * so each record's page leads with its piece, its dish, its person, as its\n * card on the list does. Any other section, and a page already showing it,\n * is returned as it came. Pure.\n */\nexport function aiPageSectionWithRecordImage(\n section: AiPageSection,\n page: NodesMap,\n template: AiPageRecordTemplate | null,\n): AiPageSection {\n const field = template?.imageField\n if (!field) return section\n const token = `{{item.${field}}}`\n const showsIt = (nodes: NodesMap) =>\n Object.values(nodes as unknown as Record<string, { componentId?: unknown; props?: Record<string, unknown> }>).some(\n (node) => node?.componentId === 'image' && node.props?.['src'] === token,\n )\n if (showsIt(page) || showsIt(section.nodes)) return section\n const first = walkTree({ rootId: section.rootId, nodes: section.nodes as unknown as Record<string, AiDoctrineNode> }).find(\n ({ node }) => node.componentId === 'image',\n )\n if (!first) return section\n const node = (section.nodes as unknown as Record<string, Record<string, unknown>>)[first.id]\n const props = isRecord(node['props']) ? node['props'] : {}\n return {\n ...section,\n nodes: { ...section.nodes, [first.id]: { ...node, props: { ...props, src: token } } } as unknown as NodesMap,\n }\n}\n\n/**\n * What a record template's draft tells the member to do next. The binding is\n * a route, so the job never writes it (rule 13): the member saves it where\n * every record template is set up.\n */\nexport function aiPageRecordNote(template: AiPageRecordTemplate): string {\n return `This page is drafted as the record template of \"${template.name}\". To serve a page per record at /${template.base}/…, open Page Properties → Record pages and save its dataset, address and fields: the cards that list its records link those pages.`\n}\n\nexport interface AiPageSectionPromptInput {\n job: Pick<AiJob, 'brief' | 'inputs'>\n plan: AiJobPlan\n screen: AiBuildPlanScreen\n index: number\n /** The most elements the section may carry at this pass's answer ceiling. */\n maxElements: number\n /**\n * Whether the workspace keeps reusable components (AGL-3030); `false`\n * asks for a repeated item drawn in the section. Absent is `true`. A form\n * is never drawn inline, whatever this says (AGL-3596).\n */\n reusableComponents?: boolean\n /** The dataset this page is the record template of; absent for a page that is one page. */\n record?: AiPageRecordTemplate | null\n /**\n * The site's other pages a link may go to by id (AGL-3596): a guided\n * start's pages are minted on its plan before any is built, so the Home\n * page is built before the Contact page its buttons go to exists.\n */\n linkablePages?: readonly AiLinkablePage[]\n}\n\n/** A page of the site a section may link by its id, built or still to come. */\nexport interface AiLinkablePage {\n id: string\n label: string\n slug: string\n}\n\n/**\n * The pages a section may link by id beyond the ones the site has built, and\n * the one page a link that names no destination can only mean (AGL-3596).\n * `planned` are a guided start's pages, minted on its plan (the input the\n * layout reads them from); `own` are this page's ids, which neither counts.\n * The link target is the site's one page that is neither its home nor this\n * page, where it has exactly one, built or planned: a two-page guided start's\n * Contact page, which its Home hero's \"Book an appointment\" goes to.\n */\nexport function aiPageLinkablePages(\n inventory: AiSiteInventory | null,\n planned: readonly AiLinkablePage[],\n own: ReadonlyArray<string | null | undefined>,\n): { linkablePages: AiLinkablePage[]; linkTarget: string | null } {\n const mine = new Set(own.filter((id): id is string => Boolean(id)))\n const home = new Set(aiHomeScreenIds(inventory))\n const isHome = (slug: string): boolean => slug.replace(/^\\/+|\\/+$/g, '') === ''\n const linkablePages = planned.filter((page) => !mine.has(page.id))\n const targets = new Set([\n ...(inventory?.screens ?? [])\n .filter((row) => !row.template && !home.has(row.id) && !isHome(row.slug))\n .map((row) => row.id),\n ...linkablePages.filter((page) => !isHome(page.slug)).map((page) => page.id),\n ])\n for (const id of mine) targets.delete(id)\n return { linkablePages, linkTarget: targets.size === 1 ? [...targets][0] : null }\n}\n\n/** The line a section request names the site's other pages in. */\nexport function aiPageSectionLinkablePagesLine(pages: readonly AiLinkablePage[]): string | null {\n if (!pages.length) return null\n const listed = pages.map((page) => `${page.label} (${page.slug || '/'}, id \"${page.id}\")`).join(', ')\n return `Other pages of this site: ${listed}. A button or link that goes to one sets its \"screenId\" to that id.`\n}\n\n/** What a section request says where the workspace keeps no reusable components. */\nexport const AI_PAGE_SECTION_INLINE_LINE =\n 'This site keeps no reusable components: write a repeated item once.'\n\n/** How a repeated item is written once, in the words a request and a re-ask share. */\nconst AI_PAGE_SECTION_REPEAT_SHAPE = `put {{1}}, {{2}}… where its copies differ, and give its outermost node \"${AI_REPEAT_KEY}\", one list of values a copy, in that order, as [[\"Title 1\", \"Text 1\"], [\"Title 2\", \"Text 2\"]]`\n\n/**\n * How a repeated item is written once (AGL-3053): the item's subtree once,\n * with placeholders where its copies differ and their values listed, which\n * the section check draws into its copies (`ai-repeated-items.ts`). It rides\n * the request of a section whose plan line shows items on a workspace that\n * keeps no reusable components, and no other: a section with nothing to repeat\n * pays nothing for it, and the cached prefix every workspace shares says only\n * that a repeated item is written once.\n */\nexport const AI_PAGE_SECTION_REPEAT_LINE = `Write a repeated item once: ${AI_PAGE_SECTION_REPEAT_SHAPE}.`\n\n/**\n * How a workspace that keeps reusable components writes a repeated item\n * (AGL-3143 §10): the shape a Free section writes, around an instance of a\n * component the section already places — the instance ONCE, `{{n}}` through\n * the values it fills, and one list of values a copy — rather than the item's\n * subtree drawn once per copy, or one instance node written per copy.\n *\n * Six cards written as six instance nodes spend their structure six times;\n * written once they spend it once, which is the difference between a section\n * that fits its ceiling and one that is cut off. A section stays ONE section\n * either way: splitting it would give the page a second h2 for the same idea,\n * which is not what the member asked for and not what its outline should say.\n *\n * ⛔ The repeated item is the GRID ITEM, not the instance. Measured live on\n * 2026-09-22: told only to \"place ONE instance … and give its outermost node\n * repeat\", the model made the instance itself the repeated node and hung it\n * straight off the Grid container. The section fitted — the ceiling failure\n * was gone — and the page was then refused by rule 12, which requires every\n * child of a Grid container to be a sized Grid item (AGL-3055). The line has\n * to name the wrapper, because \"outermost node\" reads as the instance when\n * the instance is all the request mentions.\n *\n * It rides the request of a section whose plan line shows items AND names a\n * record to place, on the same terms the repeat line rides a Free one: a\n * section with nothing to repeat, or nothing to repeat it FROM, pays nothing\n * for it.\n *\n * ## Why a paid section could not be built without it (AGL-3024)\n *\n * The Free path is reconciled at both ends — its plan is held to the sections\n * its wall pays for (AGL-3070) and its request is shown the repeat shape\n * (AGL-3053). The paid path was reconciled at neither: `AI_BUILD_PLAN_LIMITS`\n * lets a plan promise up to `items: 500` in one section, the pass that builds\n * it fits `aiJobPageSectionMaxElements` — fifteen at the balanced tier — and\n * the request said only how many elements to keep under, never how to get\n * there. A six-card grid measured live on 2026-09-21 was drawn inline, ran\n * past its ceiling, and was cut off; the re-ask then said to place an instance\n * \"of a component the site has\" without naming one, so it was cut off too, and\n * `AI_GENERATION_MAX_ATTEMPTS` ended the job with no page. A four-card grid on\n * the same site had fitted, which is why this went unseen. Naming the shape\n * was not enough on its own: `ai-repeated-items.ts` refused `repeat` outright\n * on such a workspace, so the only shape the request could ask for was the\n * expensive one.\n *\n * ⛔ This does NOT make the plan and the pass agree about what fits — a plan\n * may still promise more items than any ceiling can carry, and this line only\n * gives the pass its cheapest way to try. That bound belongs on the plan step\n * and is deliberately not taken here.\n */\nexport const AI_PAGE_SECTION_INSTANCE_LINE = `Write a repeated item once: put ONE instance of the component this section places inside ONE Grid item sized like \"xs:12 sm:6 md:4\", and repeat THAT GRID ITEM rather than the instance — every child of a Grid container is itself a Grid item. Put {{1}}, {{2}}… where the copies differ, and give the Grid item \"${AI_REPEAT_KEY}\", one list of values a copy, in that order, as [[\"Title 1\", \"Text 1\"], [\"Title 2\", \"Text 2\"]].`\n\n/**\n * What a pass whose answer ran past its ceiling is told makes a section\n * smaller (AGL-3042): fewer elements, down to the budget the request gave,\n * shorter copy, and a repeated item drawn no more than once — placed as an\n * instance where the workspace keeps reusable components, and written once\n * where it keeps none (AGL-3053), with the shape spelled out, since a section\n * whose plan line showed no items was never told it. It rides the re-ask,\n * never the first request, so a pass that fits sends no byte more.\n */\nexport function aiPageSectionSmaller(input: Pick<AiPageSectionPromptInput, 'maxElements' | 'reusableComponents'>): string {\n return input.reusableComponents === false\n ? `Make it smaller: use fewer elements, at most ${input.maxElements}; write shorter copy; and write a repeated item once instead of drawing it again: ${AI_PAGE_SECTION_REPEAT_SHAPE}.`\n : `Make it smaller: use fewer elements, at most ${input.maxElements}; write shorter copy; and write a repeated item once instead of drawing it again: put ONE instance of a component the site has inside ONE Grid item sized like \"xs:12 sm:6 md:4\", and repeat that Grid item — ${AI_PAGE_SECTION_REPEAT_SHAPE}.`\n}\n\n/** One pass's user turn: the page, the brief, the plan, this section and what is built above it. */\nexport function aiPageSectionPrompt(input: AiPageSectionPromptInput): string {\n const { job, plan, screen, index } = input\n const inputs = parseAiPageJobInputs(job.inputs)\n const type = typeof inputs === 'string' ? null : aiPageTypeDefinition(inputs.pageType)\n const section = screen.sections[index] as AiBuildPlanSection\n const places = section.uses.length\n ? ` It places ${section.uses.map((ref) => referenceOf(plan, ref)).join(', ')}.`\n : ''\n const items = section.items ? ` It shows ${section.items} items.` : ''\n const built = screen.sections.slice(0, index).map((entry, position) => `${position + 1}. ${entry.name}`)\n return [\n `Page: \"${screen.title}\" at ${screen.slug}`,\n ...(type ? [`Page type: ${type.purpose}`] : []),\n ...(input.record ? [aiPageRecordLine(input.record)] : []),\n aiJobBriefLine(job),\n ...aiPlanReferenceLines(plan),\n `Build section ${index + 1} of ${screen.sections.length}: \"${section.name}\".${places}${items}`,\n built.length\n ? `Already built, above it: ${built.join('; ')}. The page’s h1 is in section 1.`\n : 'Nothing is built yet: this section holds the page’s h1.',\n ...(input.reusableComponents === false\n ? [AI_PAGE_SECTION_INLINE_LINE, ...(section.items ? [AI_PAGE_SECTION_REPEAT_LINE] : [])]\n : section.items && section.uses.length\n ? [AI_PAGE_SECTION_INSTANCE_LINE]\n : []),\n ...(input.linkablePages?.length ? [aiPageSectionLinkablePagesLine(input.linkablePages) as string] : []),\n `Keep this section to at most ${input.maxElements} elements.`,\n ].join('\\n')\n}\n\n/** A validated section: its nodes keyed as the page stores them, its root under the page root. */\nexport interface AiPageSection {\n rootId: string\n nodes: NodesMap\n /** The page's weight with the section added, as the doctrine measured it. */\n load: AiLoadEstimate | null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/** A page with nothing on it yet: the document wrapper. */\nexport function aiEmptyPage(): NodesMap {\n return {\n [CANVAS_ROOT_ELEMENT_ID]: {\n $id: CANVAS_ROOT_ELEMENT_ID,\n componentId: 'div',\n parentId: null,\n nodes: [],\n },\n } as unknown as NodesMap\n}\n\n/**\n * The page with a section in its plan position: after every section with a\n * lower index and before every one with a higher, the page's other children\n * — whatever a member placed — kept where they are. A section already on the\n * page is replaced, never doubled.\n */\nexport function aiPageWithSection(\n page: NodesMap,\n section: AiPageSection,\n sectionIds: readonly string[],\n): NodesMap {\n const nodes: Record<string, Record<string, unknown>> = {}\n const previous = (page as unknown as Record<string, Record<string, unknown>>)[section.rootId]\n const replaced = new Set<string>()\n if (previous) {\n for (const { id } of walkTree({\n rootId: section.rootId,\n nodes: page as unknown as Record<string, AiDoctrineNode>,\n })) {\n replaced.add(id)\n }\n }\n for (const [id, node] of Object.entries(page)) {\n if (!replaced.has(id)) nodes[id] = { ...(node as unknown as Record<string, unknown>) }\n }\n const root = nodes[CANVAS_ROOT_ELEMENT_ID] ?? (aiEmptyPage()[CANVAS_ROOT_ELEMENT_ID] as unknown as Record<string, unknown>)\n const children = (Array.isArray(root['nodes']) ? (root['nodes'] as string[]) : []).filter(\n (id) => id !== section.rootId,\n )\n const order = new Map(sectionIds.map((id, position) => [id, position]))\n const at = order.get(section.rootId) ?? sectionIds.length\n const before = children.findIndex((id) => (order.get(id) ?? -1) > at)\n children.splice(before === -1 ? children.length : before, 0, section.rootId)\n nodes[CANVAS_ROOT_ELEMENT_ID] = { ...root, nodes: children }\n for (const [id, node] of Object.entries(section.nodes)) {\n nodes[id] = { ...(node as unknown as Record<string, unknown>) }\n }\n return nodes as unknown as NodesMap\n}\n\n/**\n * What a tree generated against this inventory may reference, the brand it is\n * held to, where the workspace keeps no reusable components\n * (AGL-3030) that the page is built inline, the sections its plan names,\n * which a link may take a visitor to (AGL-3097), and the players its plan\n * lists for this page, the only ones it may embed (AGL-3433).\n */\nexport function aiPageCheckContext(\n inventory: AiSiteInventory | null,\n options: {\n reusableComponents?: boolean\n sections?: readonly string[]\n embeds?: AiDoctrineTreeContext['plannedEmbeds']\n /** A record template's tokens, which its links and images may name (AGL-3475). */\n recordTokens?: readonly string[]\n /** The site's pages still to be built that a link may go to by id (AGL-3596). */\n linkablePages?: readonly AiLinkablePage[]\n } = {},\n): AiDoctrineTreeContext {\n const tree = aiNodeTreeContextFromInventory(inventory)\n const screenIds = [...new Set([...(tree.screenIds ?? []), ...(options.linkablePages ?? []).map((page) => page.id)])]\n return {\n brand: inventory?.theme ? { colors: inventory.theme.colors, fonts: inventory.theme.fonts } : null,\n ...tree,\n ...(tree.screenIds || options.linkablePages?.length ? { screenIds } : {}),\n homeScreenIds: aiHomeScreenIds(inventory),\n ...(options.reusableComponents === false ? { reusableComponents: false } : {}),\n ...(options.sections?.length ? { pageSections: options.sections } : {}),\n ...(options.embeds?.length ? { plannedEmbeds: options.embeds } : {}),\n ...(options.recordTokens?.length ? { bindingTokens: options.recordTokens } : {}),\n }\n}\n\nexport interface AiPageSectionCheckInput {\n /** The page as stored so far; an empty page on the first pass. */\n page: NodesMap\n /** Every section root id of the plan, in order. */\n sectionIds: readonly string[]\n index: number\n context: AiDoctrineTreeContext\n /**\n * The plan line this pass answers for: what it places by inventory id, and\n * how many items it promised, which the answer is held to (AGL-3024).\n */\n section: Pick<AiBuildPlanSection, 'name' | 'uses' | 'items'>\n inventory: AiSiteInventory | null\n /**\n * The one page a link that goes nowhere can only mean, where the site has\n * exactly one page besides its home and this one (AGL-3596): a guided\n * start's Contact page. Absent or `null`, such a link is re-asked.\n */\n linkTarget?: string | null\n}\n\n/** The parts of an answer the violations name, as the model wrote them, capped as the doctrine caps a re-ask. */\nfunction offendingOf(raw: unknown, violations: readonly AiDoctrineViolation[]): { offending?: Record<string, unknown> } {\n const rawNodes = isRecord(raw) && isRecord(raw['nodes']) ? raw['nodes'] : {}\n const offending: Record<string, unknown> = {}\n let used = 2\n for (const id of new Set(violations.flatMap((violation) => violation.nodeIds ?? []))) {\n if (rawNodes[id] === undefined) continue\n const size = JSON.stringify(rawNodes[id]).length + id.length + 4\n if (used + size > AI_REASK_OFFENDING_MAX_CHARS) break\n offending[id] = rawNodes[id]\n used += size\n }\n return Object.keys(offending).length ? { offending } : {}\n}\n\n/**\n * The check a section's answer is held to: a repeated item written once drawn\n * into its copies (AGL-3053), then the palette validator on the section, with\n * any line it cut at its ceiling refused (AGL-3076), a Grid container's items\n * sized where rule 12 has one answer (AGL-3596), the doctrine's page check\n * on the page with the section added, and the plan line — every component it\n * names placed as an instance, every form bound by its id (rule 7), and as\n * many items as it promised (AGL-3024). Violations\n * name the section's own nodes by the ids the MODEL wrote, and a copy's nodes\n * by the item's; one that names only nodes an earlier pass stored belongs to\n * the page rather than to this answer, and is left to the last pass (AGL-3078).\n */\nexport function aiPageSectionCheck(input: AiPageSectionCheckInput): AiGenerationCheck<AiPageSection> {\n const sectionId = input.sectionIds[input.index]\n const components = new Set((input.inventory?.components ?? []).map((row) => row.id))\n const forms = new Set((input.inventory?.forms ?? []).map((row) => row.id))\n return (answer) => {\n // A child named and never written, an element written and held by\n // nothing, and a heading whose first clause fits its ceiling are settled\n // where each has one reading (AGL-3596).\n const raw = aiSettleCutHeadings(aiSettleDisagreeingNodes(aiAnswerTree(answer)))\n // Before anything is drawn or dropped: a repeated item written and never\n // placed is content the section loses silently, and a child named and\n // never written ends the pass with nothing to answer (AGL-3143).\n const disagreeing = detectDisagreeingNodes(raw)\n if (disagreeing.length) {\n return { value: null, violations: disagreeing, ...offendingOf(raw, disagreeing) }\n }\n // A repeated item is drawn inline where the workspace keeps no reusable\n // components, and where this section's plan line places none (AGL-3596):\n // there is then no component it could be drawing by hand, and a paid\n // guided start's \"Why choose us\" was refused for rule 1 with nothing to place.\n const inline = input.context.reusableComponents === false || !input.section.uses.some((ref) => components.has(ref))\n const drawn = expandAiRepeatedItems(raw, { inline, noun: 'section' })\n if (drawn.ok === false) {\n return { value: null, violations: drawn.violations, ...offendingOf(raw, drawn.violations) }\n }\n // Every id below is the drawn tree's; a copy's leads back to the node the model wrote.\n const written = (id: string): string => drawn.sourceIds[id] ?? id\n const validated = validateAiNodeTree(drawn.tree, 'screen', input.context)\n if (validated.ok === false) {\n return {\n value: null,\n violations: [\n {\n rule: null,\n code: `tree-${validated.code}`,\n message: 'The answer could not be used as a section.',\n detail: validated.error,\n },\n ],\n }\n }\n const drawnNodes = isRecord(drawn.tree) && isRecord(drawn.tree['nodes']) ? drawn.tree['nodes'] : {}\n // A Grid container's items are sized, and an element straight in one is\n // put in an item, before the page check reads them: that rule has one\n // answer, the size its re-ask would name (AGL-3596). Read off the section\n // as the palette validator stored it, with what the model wrote beside it.\n const { nodes: settled } = aiSettleGridItems(\n { rootId: validated.rootId, nodes: validated.nodes as unknown as Record<string, AiDoctrineNode> },\n { written: (id) => drawnNodes[validated.sourceIds[id] ?? id] },\n )\n const wrapper = settled[validated.rootId] as AiDoctrineNode | undefined\n const top = (wrapper?.nodes ?? []).filter((id) => settled[id])\n const sectionNode = top.length === 1 ? settled[top[0]] : null\n if (!sectionNode || sectionNode.componentId !== 'section') {\n return {\n value: null,\n violations: [\n {\n rule: null,\n code: 'section-shape',\n message: 'Answer with exactly one Section element inside the document wrapper.',\n },\n ],\n }\n }\n\n // The section's root takes its plan id, so a pass run again finds it, and\n // hangs under the page root; every other minted id stays as minted.\n const minted = top[0]\n const modelIds: Record<string, string> = Object.fromEntries(\n Object.entries(validated.sourceIds).map(([id, source]) => [id, written(source)]),\n )\n modelIds[sectionId] = written(validated.sourceIds[minted] ?? minted)\n const sectionNodes: Record<string, Record<string, unknown>> = {}\n for (const { id, node } of walkTree({ rootId: minted, nodes: settled })) {\n const stored = { ...(node as unknown as Record<string, unknown>) }\n if (id === minted) {\n stored['$id'] = sectionId\n stored['parentId'] = CANVAS_ROOT_ELEMENT_ID\n } else if (stored['parentId'] === minted) {\n stored['parentId'] = sectionId\n }\n sectionNodes[id === minted ? sectionId : id] = stored\n }\n // What the model wrote of one of the section's nodes, by the id the page stores it under.\n const drawnIdOf = (stored: string): string =>\n validated.sourceIds[stored === sectionId ? minted : stored] ?? stored\n // A link that names a section of this page carries the platform's Scroll to\n // element interaction to that section's root, whose id is minted from the\n // plan before the section is built (AGL-3097).\n const sections = input.context.pageSections ?? []\n // A link that names no destination at all, on a site with one page it can\n // only mean, goes to that page (AGL-3596); one inside a form is the form's\n // own button, which rule 10 asks to take out.\n const inForm = (id: string): boolean => {\n for (let at = sectionNodes[id]?.['parentId']; typeof at === 'string'; at = sectionNodes[at]?.['parentId']) {\n if (sectionNodes[at]?.['componentId'] === 'form') return true\n }\n return false\n }\n for (const [id, node] of Object.entries(sectionNodes)) {\n const props = isRecord(node['props']) ? node['props'] : {}\n if (!isAiLinkElement(node['componentId']) || props['screenId'] || props['href']) continue\n const target = aiPageLinkTarget(drawnNodes[drawnIdOf(id)], sections)\n if (target?.kind === 'section') {\n node['interactions'] = [aiPageScrollInteraction(input.sectionIds[target.section], sections[target.section])]\n } else if (!target && input.linkTarget && !inForm(id)) {\n node['props'] = { ...props, screenId: input.linkTarget }\n }\n }\n const section: AiPageSection = { rootId: sectionId, nodes: sectionNodes as unknown as NodesMap, load: null }\n\n // An attribute a rule has one answer for is applied on the page with the\n // section added, since the first image and the one h1 are the page's\n // (AGL-3660). The section keeps what that settled of its own nodes; what\n // it settled of an earlier pass's is the last pass's to store.\n const settledPage = aiSettleMechanicalRules(\n {\n rootId: CANVAS_ROOT_ELEMENT_ID,\n nodes: aiPageWithSection(input.page, section, input.sectionIds) as unknown as Record<string, AiDoctrineNode>,\n },\n 'page',\n )\n for (const id of Object.keys(sectionNodes)) {\n sectionNodes[id] = settledPage.nodes[id] as unknown as Record<string, unknown>\n }\n const page = settledPage.nodes as unknown as NodesMap\n const own = new Set(Object.keys(sectionNodes))\n // The page check reads the section as the page stores it, where the palette\n // validator has already dropped what it could not read, such as a\n // `container` written as text or a link's `scrollTo`; what the model wrote\n // of each of the section's nodes is read from the section as it was drawn\n // (AGL-3078). A link the page already carries to one of its section roots\n // goes there, whichever pass wrote it (AGL-3097).\n const report = validateAiDoctrineTree({ rootId: CANVAS_ROOT_ELEMENT_ID, nodes: page }, 'page', {\n ...input.context,\n writtenNode: (id) => (own.has(id) ? drawnNodes[drawnIdOf(id)] : undefined),\n scrollTargetIds: input.sectionIds,\n })\n // The page check mints its ids afresh: its map leads back to the page's\n // ids, and the section's own lead back to the model's.\n const pageIds = report.tree?.sourceIds ?? {}\n const toModel = (id: string): string | null => {\n const stored = pageIds[id] ?? id\n return own.has(stored) ? (modelIds[stored] ?? stored) : null\n }\n // The page check reads the section as it is stored, where a line the\n // palette validator cut is already cut, so the cut is read from the\n // section's own validation, first (AGL-3076). Copies of one item name one\n // node the model wrote, once.\n //\n // A PASS ANSWERS ONLY FOR THE SECTION IT WROTE (AGL-3078). The page check\n // reads the whole page, so it also names nodes an earlier pass stored; the\n // model is not shown those and cannot mend them, so a finding that names\n // none of this section's nodes is not held against this answer. Dropping\n // it neither hides nor forgives it: the last pass runs the same check on\n // the finished page, where every node is the page's and the review names\n // each one and outlines it. Kept, such a finding would re-ask the model\n // for a node it never saw, refuse the same answer twice, and stop the page\n // with findings whose ids all filtered away — no node ids, and so no\n // outline either.\n const violations: AiDoctrineViolation[] = [\n ...detectCutLines(validated.repairs, drawnNodes, written),\n ...report.violations.flatMap((violation) => {\n if (!violation.nodeIds?.length) return [violation]\n const named = [...new Set(violation.nodeIds.map(toModel).filter((id): id is string => id !== null))]\n return named.length ? [{ ...violation, nodeIds: named }] : []\n }),\n ]\n\n const placed = new Set<string>()\n const bound = new Set<string>()\n for (const node of Object.values(sectionNodes)) {\n const props = isRecord(node['props']) ? node['props'] : {}\n if (node['componentId'] === REUSABLE_INSTANCE_COMPONENT_ID && typeof props[AI_INSTANCE_REF_PROP] === 'string') {\n placed.add(props[AI_INSTANCE_REF_PROP] as string)\n }\n if (node['componentId'] === 'form' && typeof props['formId'] === 'string') bound.add(props['formId'])\n }\n const missing = input.section.uses.filter(\n (ref) => (components.has(ref) && !placed.has(ref)) || (forms.has(ref) && !bound.has(ref)),\n )\n if (missing.length) {\n violations.push({\n rule: 7,\n code: 'plan-reuse-not-placed',\n message: `The confirmed plan places ${missing.join(', ')} in this section, and the section does not. Place each one by its id.`,\n })\n }\n // The count the plan promised, against the section as the page stores it\n // (AGL-3024): the prompt states it, and until now nothing read it back.\n violations.push(\n ...aiPlanItemCountViolations(input.section, {\n rootId: sectionId,\n nodes: sectionNodes as unknown as Record<string, AiDoctrineNode>,\n }),\n )\n\n return {\n value: { ...section, load: report.load },\n violations,\n ...offendingOf(raw, violations),\n }\n }\n}\n"],"names":["REUSABLE_INSTANCE_COMPONENT_ID","CANVAS_ROOT_ELEMENT_ID","aiPlanCreateFor","aiPageTypeDefinition","parseAiPageJobInputs","aiHomeScreenIds","AI_REASK_OFFENDING_MAX_CHARS","aiAnswerTree","aiNodeTreeContextFromInventory","aiSettleCutHeadings","aiSettleDisagreeingNodes","aiSettleGridItems","aiSettleMechanicalRules","detectCutLines","detectDisagreeingNodes","isAiLinkElement","validateAiDoctrineTree","walkTree","AI_INSTANCE_REF_PROP","validateAiNodeTree","aiPageLinkTarget","aiPageScrollInteraction","AI_PALETTE_CATALOG","AI_REPEAT_KEY","expandAiRepeatedItems","aiJobBriefLine","aiPlanReferenceLines","aiPlanItemCountViolations","aiPageSectionNodeId","jobId","index","slice","AI_PAGE_SECTION_TOOL","name","description","strict","inputSchema","type","additionalProperties","required","properties","tree","AI_JOB_PAGE_INSTRUCTIONS","text","join","screen","cacheBreakpoint","referenceOf","plan","ref","label","labels","aiPageRecordTemplate","record","inventory","created","row","datasets","find","entry","id","dataset","base","fields","map","fieldIds","imageField","aiPageRecordTokens","template","field","aiPageRecordLine","length","photo","aiPageSectionWithRecordImage","section","page","token","showsIt","nodes","Object","values","some","node","componentId","props","first","rootId","isRecord","src","aiPageRecordNote","aiPageLinkablePages","planned","own","mine","Set","filter","Boolean","home","isHome","slug","replace","linkablePages","has","targets","screens","delete","linkTarget","size","aiPageSectionLinkablePagesLine","pages","listed","AI_PAGE_SECTION_INLINE_LINE","AI_PAGE_SECTION_REPEAT_SHAPE","AI_PAGE_SECTION_REPEAT_LINE","AI_PAGE_SECTION_INSTANCE_LINE","aiPageSectionSmaller","input","reusableComponents","maxElements","aiPageSectionPrompt","job","inputs","pageType","sections","places","uses","items","built","position","title","purpose","value","Array","isArray","aiEmptyPage","$id","parentId","aiPageWithSection","sectionIds","order","previous","replaced","add","entries","root","children","Map","at","get","before","findIndex","splice","aiPageCheckContext","options","screenIds","brand","theme","colors","fonts","homeScreenIds","pageSections","embeds","plannedEmbeds","recordTokens","bindingTokens","offendingOf","raw","violations","rawNodes","offending","used","flatMap","violation","nodeIds","undefined","JSON","stringify","keys","aiPageSectionCheck","sectionId","components","forms","answer","validated","report","disagreeing","inline","context","drawn","noun","ok","written","sourceIds","rule","code","message","detail","error","drawnNodes","settled","wrapper","top","sectionNode","minted","modelIds","fromEntries","source","sectionNodes","stored","drawnIdOf","inForm","target","kind","screenId","load","settledPage","writtenNode","scrollTargetIds","pageIds","toModel","repairs","named","placed","bound","missing","push"],"mappings":"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"}
|
|
@@ -88,14 +88,16 @@ export declare const AI_JOB_PLAN_REVIEW_COPY = "The plan is ready. Review what t
|
|
|
88
88
|
* (AGL-3030). Per workspace and per site, which is why they ride here and
|
|
89
89
|
* never in a system block the platform's cache entry is keyed on.
|
|
90
90
|
*/
|
|
91
|
-
export declare function aiJobPlanPrompt(job: Pick<AiJob, 'kind' | 'brief' | 'inputs'>, capabilities?: AiPlanCapabilities | null, inventory?: AiSiteInventory | null, ops?: AiBuildOps | null): string;
|
|
91
|
+
export declare function aiJobPlanPrompt(job: Pick<AiJob, 'kind' | 'brief' | 'inputs'>, capabilities?: AiPlanCapabilities | null, inventory?: AiSiteInventory | null, ops?: AiBuildOps | null, now?: Date | null): string;
|
|
92
92
|
/**
|
|
93
93
|
* What a BUILD job's plan is told (AGL-3616): that one request becomes pages,
|
|
94
94
|
* creations and items, how many pages it may hold, and the item operations
|
|
95
95
|
* this site has with their arguments. On the job's own turn, never a cached
|
|
96
96
|
* system block, because the operations are per site.
|
|
97
97
|
*/
|
|
98
|
-
export declare function aiPlanBuildLines(job: Pick<AiJob, 'kind'>, capabilities: AiPlanCapabilities | null, ops: AiBuildOps | null): string[];
|
|
98
|
+
export declare function aiPlanBuildLines(job: Pick<AiJob, 'kind'>, capabilities: AiPlanCapabilities | null, ops: AiBuildOps | null, now?: Date | null): string[];
|
|
99
|
+
/** The build's date, so a dated item falls after it (AGL-3743). */
|
|
100
|
+
export declare function aiPlanTodaySentence(now: Date): string;
|
|
99
101
|
/**
|
|
100
102
|
* What a SITE job's plan is told beside the inventory (AGL-3594): the pages
|
|
101
103
|
* the site already has and that their addresses are taken, which one — the
|