@aglyn/plugins-ai 1.0.0-beta.284 → 1.0.0-beta.287

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.
Files changed (210) hide show
  1. package/package.json +17 -17
  2. package/src/lib/assets/site-styles/nonprofit.webp +0 -0
  3. package/src/lib/assets/site-styles/professional.webp +0 -0
  4. package/src/lib/assets/site-styles/store.webp +0 -0
  5. package/src/lib/assets/site-styles/trades.webp +0 -0
  6. package/src/lib/components/ai-theme-proposal-card.component.js +12 -3
  7. package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -1
  8. package/src/lib/declarations.js +5 -2
  9. package/src/lib/declarations.js.map +1 -1
  10. package/src/lib/declarations.server.js +12 -0
  11. package/src/lib/declarations.server.js.map +1 -1
  12. package/src/lib/jobs/ai-build-capabilities.d.ts +3 -1
  13. package/src/lib/jobs/ai-build-capabilities.js +27 -2
  14. package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
  15. package/src/lib/jobs/ai-image-reads.d.ts +59 -0
  16. package/src/lib/jobs/ai-image-reads.js +138 -0
  17. package/src/lib/jobs/ai-image-reads.js.map +1 -0
  18. package/src/lib/jobs/ai-job-build-step.d.ts +29 -0
  19. package/src/lib/jobs/ai-job-build-step.js +83 -12
  20. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  21. package/src/lib/jobs/ai-job-duplicate-step.d.ts +2 -1
  22. package/src/lib/jobs/ai-job-duplicate-step.js +6 -6
  23. package/src/lib/jobs/ai-job-duplicate-step.js.map +1 -1
  24. package/src/lib/jobs/ai-job-import-step.d.ts +4 -2
  25. package/src/lib/jobs/ai-job-import-step.js +15 -11
  26. package/src/lib/jobs/ai-job-import-step.js.map +1 -1
  27. package/src/lib/jobs/ai-job-insight-step.d.ts +10 -0
  28. package/src/lib/jobs/ai-job-insight-step.js +23 -5
  29. package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
  30. package/src/lib/jobs/ai-job-layout-language.js +2 -1
  31. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  32. package/src/lib/jobs/ai-job-media-step.d.ts +2 -1
  33. package/src/lib/jobs/ai-job-media-step.js +6 -8
  34. package/src/lib/jobs/ai-job-media-step.js.map +1 -1
  35. package/src/lib/jobs/ai-job-navigation-step.d.ts +2 -1
  36. package/src/lib/jobs/ai-job-navigation-step.js +7 -9
  37. package/src/lib/jobs/ai-job-navigation-step.js.map +1 -1
  38. package/src/lib/jobs/ai-job-page-language.js +7 -1
  39. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  40. package/src/lib/jobs/ai-job-page-sections.js +16 -3
  41. package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
  42. package/src/lib/jobs/ai-job-page-step.js +9 -1
  43. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  44. package/src/lib/jobs/ai-job-plan-step.d.ts +30 -8
  45. package/src/lib/jobs/ai-job-plan-step.js +78 -13
  46. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  47. package/src/lib/jobs/ai-job-privacy-step.d.ts +4 -2
  48. package/src/lib/jobs/ai-job-privacy-step.js +14 -15
  49. package/src/lib/jobs/ai-job-privacy-step.js.map +1 -1
  50. package/src/lib/jobs/ai-job-products-step.js +5 -3
  51. package/src/lib/jobs/ai-job-products-step.js.map +1 -1
  52. package/src/lib/jobs/ai-job-settings-step.d.ts +2 -1
  53. package/src/lib/jobs/ai-job-settings-step.js +7 -8
  54. package/src/lib/jobs/ai-job-settings-step.js.map +1 -1
  55. package/src/lib/jobs/ai-job-site-content.d.ts +34 -1
  56. package/src/lib/jobs/ai-job-site-content.js +67 -8
  57. package/src/lib/jobs/ai-job-site-content.js.map +1 -1
  58. package/src/lib/jobs/ai-job-site-datasets.d.ts +53 -3
  59. package/src/lib/jobs/ai-job-site-datasets.js +298 -30
  60. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  61. package/src/lib/jobs/ai-job-site-step.js +6 -3
  62. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  63. package/src/lib/jobs/ai-job-site-store-pages.js +3 -3
  64. package/src/lib/jobs/ai-job-site-store-pages.js.map +1 -1
  65. package/src/lib/jobs/ai-job-tracking-step.d.ts +2 -1
  66. package/src/lib/jobs/ai-job-tracking-step.js +7 -8
  67. package/src/lib/jobs/ai-job-tracking-step.js.map +1 -1
  68. package/src/lib/jobs/ai-jobs-beat.d.ts +11 -7
  69. package/src/lib/jobs/ai-jobs-beat.js +18 -8
  70. package/src/lib/jobs/ai-jobs-beat.js.map +1 -1
  71. package/src/lib/jobs/ai-jobs-notify.d.ts +66 -1
  72. package/src/lib/jobs/ai-jobs-notify.js +136 -3
  73. package/src/lib/jobs/ai-jobs-notify.js.map +1 -1
  74. package/src/lib/jobs/ai-layout-stock-photos.d.ts +59 -4
  75. package/src/lib/jobs/ai-layout-stock-photos.js +897 -81
  76. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  77. package/src/lib/jobs/ai-product-image.d.ts +14 -0
  78. package/src/lib/jobs/ai-product-image.js +73 -21
  79. package/src/lib/jobs/ai-product-image.js.map +1 -1
  80. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +9 -1
  81. package/src/lib/jobs/ai-theme-brand-inputs.js +28 -2
  82. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -1
  83. package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.d.ts +175 -0
  84. package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.js +601 -0
  85. package/src/lib/jobs/fixtures/ai-site-agl4065-datasets.js.map +1 -0
  86. package/src/lib/jobs/fixtures/ai-site-agl4065-pages.d.ts +46 -0
  87. package/src/lib/jobs/fixtures/ai-site-agl4065-pages.js +2862 -0
  88. package/src/lib/jobs/fixtures/ai-site-agl4065-pages.js.map +1 -0
  89. package/src/lib/jobs/fixtures/ai-site-agl4065-plans.d.ts +74 -0
  90. package/src/lib/jobs/fixtures/ai-site-agl4065-plans.js +888 -0
  91. package/src/lib/jobs/fixtures/ai-site-agl4065-plans.js.map +1 -0
  92. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.d.ts +29 -0
  93. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.js +81 -0
  94. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-judge.js.map +1 -0
  95. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.d.ts +87 -0
  96. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.js +225 -0
  97. package/src/lib/jobs/fixtures/ai-stock-photo-agl4065-recordings.js.map +1 -0
  98. package/src/lib/layout-language/ai-layout-compiler.d.ts +11 -0
  99. package/src/lib/layout-language/ai-layout-compiler.js +194 -18
  100. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  101. package/src/lib/layout-language/ai-layout-copy.d.ts +37 -0
  102. package/src/lib/layout-language/ai-layout-copy.js +383 -3
  103. package/src/lib/layout-language/ai-layout-copy.js.map +1 -1
  104. package/src/lib/layout-language/ai-layout-design.d.ts +19 -0
  105. package/src/lib/layout-language/ai-layout-design.js +31 -11
  106. package/src/lib/layout-language/ai-layout-design.js.map +1 -1
  107. package/src/lib/layout-language/ai-layout-listings.d.ts +7 -1
  108. package/src/lib/layout-language/ai-layout-listings.js +9 -1
  109. package/src/lib/layout-language/ai-layout-listings.js.map +1 -1
  110. package/src/lib/layout-language/ai-layout-pictures.d.ts +30 -0
  111. package/src/lib/layout-language/ai-layout-pictures.js +131 -3
  112. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  113. package/src/lib/layout-language/ai-layout-storefront.d.ts +18 -4
  114. package/src/lib/layout-language/ai-layout-storefront.js +100 -20
  115. package/src/lib/layout-language/ai-layout-storefront.js.map +1 -1
  116. package/src/lib/model/ai-build-job.d.ts +7 -0
  117. package/src/lib/model/ai-build-job.js +36 -7
  118. package/src/lib/model/ai-build-job.js.map +1 -1
  119. package/src/lib/model/ai-build-plan.d.ts +28 -4
  120. package/src/lib/model/ai-build-plan.js +49 -9
  121. package/src/lib/model/ai-build-plan.js.map +1 -1
  122. package/src/lib/model/ai-build-progress.js +3 -1
  123. package/src/lib/model/ai-build-progress.js.map +1 -1
  124. package/src/lib/model/ai-job-notice.d.ts +8 -0
  125. package/src/lib/model/ai-job-notice.js +33 -0
  126. package/src/lib/model/ai-job-notice.js.map +1 -1
  127. package/src/lib/model/ai-job-plan-lines.d.ts +2 -1
  128. package/src/lib/model/ai-job-plan-lines.js +6 -1
  129. package/src/lib/model/ai-job-plan-lines.js.map +1 -1
  130. package/src/lib/model/ai-jobs.types.d.ts +8 -0
  131. package/src/lib/model/ai-jobs.types.js.map +1 -1
  132. package/src/lib/model/ai-permissions.d.ts +13 -0
  133. package/src/lib/model/ai-permissions.js +29 -1
  134. package/src/lib/model/ai-permissions.js.map +1 -1
  135. package/src/lib/model/ai-products.d.ts +18 -0
  136. package/src/lib/model/ai-products.js +32 -0
  137. package/src/lib/model/ai-products.js.map +1 -1
  138. package/src/lib/model/ai-site-inspiration.d.ts +3 -2
  139. package/src/lib/model/ai-site-inspiration.js +3 -2
  140. package/src/lib/model/ai-site-inspiration.js.map +1 -1
  141. package/src/lib/plugin.js +4 -13
  142. package/src/lib/plugin.js.map +1 -1
  143. package/src/lib/providers/anthropic.js +9 -2
  144. package/src/lib/providers/anthropic.js.map +1 -1
  145. package/src/lib/providers/catalog.js +14 -5
  146. package/src/lib/providers/catalog.js.map +1 -1
  147. package/src/lib/providers/contract.d.ts +24 -1
  148. package/src/lib/providers/contract.js.map +1 -1
  149. package/src/lib/providers/routing.js +5 -2
  150. package/src/lib/providers/routing.js.map +1 -1
  151. package/src/lib/runtime/ai-dataset-generation.d.ts +99 -1
  152. package/src/lib/runtime/ai-dataset-generation.js +251 -3
  153. package/src/lib/runtime/ai-dataset-generation.js.map +1 -1
  154. package/src/lib/runtime/ai-dev-replay.d.ts +1 -0
  155. package/src/lib/runtime/ai-dev-replay.js +4 -2
  156. package/src/lib/runtime/ai-dev-replay.js.map +1 -1
  157. package/src/lib/runtime/ai-doctrine-validators.d.ts +47 -3
  158. package/src/lib/runtime/ai-doctrine-validators.js +343 -27
  159. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  160. package/src/lib/runtime/ai-doctrine.js +8 -2
  161. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  162. package/src/lib/runtime/ai-icon-library.d.ts +27 -1
  163. package/src/lib/runtime/ai-icon-library.js +30 -3
  164. package/src/lib/runtime/ai-icon-library.js.map +1 -1
  165. package/src/lib/runtime/ai-products-generation.d.ts +11 -1
  166. package/src/lib/runtime/ai-products-generation.js +51 -4
  167. package/src/lib/runtime/ai-products-generation.js.map +1 -1
  168. package/src/lib/runtime/assist-answer-cache.d.ts +2 -0
  169. package/src/lib/runtime/assist-answer-cache.js +5 -2
  170. package/src/lib/runtime/assist-answer-cache.js.map +1 -1
  171. package/src/lib/server/ai-allotments.js +7 -2
  172. package/src/lib/server/ai-allotments.js.map +1 -1
  173. package/src/lib/server/ai-experiment-versions.js +5 -5
  174. package/src/lib/server/ai-experiment-versions.js.map +1 -1
  175. package/src/lib/server/ai-host-permissions-roster.d.ts +25 -0
  176. package/src/lib/server/ai-host-permissions-roster.js +33 -0
  177. package/src/lib/server/ai-host-permissions-roster.js.map +1 -0
  178. package/src/lib/server/ai-host-permissions.js +8 -6
  179. package/src/lib/server/ai-host-permissions.js.map +1 -1
  180. package/src/lib/server/ai-image-reads-route.d.ts +17 -0
  181. package/src/lib/server/ai-image-reads-route.js +106 -0
  182. package/src/lib/server/ai-image-reads-route.js.map +1 -0
  183. package/src/lib/server/ai-seo-apply.js +5 -5
  184. package/src/lib/server/ai-seo-apply.js.map +1 -1
  185. package/src/lib/server/ai-site-import-route.js +7 -4
  186. package/src/lib/server/ai-site-import-route.js.map +1 -1
  187. package/src/lib/server/assist-build.js +1 -0
  188. package/src/lib/server/assist-build.js.map +1 -1
  189. package/src/lib/server/assist-chat.d.ts +11 -7
  190. package/src/lib/server/assist-chat.js +185 -48
  191. package/src/lib/server/assist-chat.js.map +1 -1
  192. package/src/lib/server/assist-docs-query.d.ts +51 -0
  193. package/src/lib/server/assist-docs-query.js +57 -0
  194. package/src/lib/server/assist-docs-query.js.map +1 -0
  195. package/src/lib/server/assist-jobs-context.d.ts +102 -0
  196. package/src/lib/server/assist-jobs-context.js +227 -0
  197. package/src/lib/server/assist-jobs-context.js.map +1 -0
  198. package/src/lib/server/assist-view-context.d.ts +8 -4
  199. package/src/lib/server/assist-view-context.js +12 -7
  200. package/src/lib/server/assist-view-context.js.map +1 -1
  201. package/src/lib/server.js +12 -0
  202. package/src/lib/server.js.map +1 -1
  203. package/src/lib/tools/ai-dataset-tool.d.ts +11 -1
  204. package/src/lib/tools/ai-dataset-tool.js +24 -7
  205. package/src/lib/tools/ai-dataset-tool.js.map +1 -1
  206. package/src/lib/tools/ai-duplicate-resource-tool.js +5 -6
  207. package/src/lib/tools/ai-duplicate-resource-tool.js.map +1 -1
  208. package/src/lib/components/ai-collaborator-permissions-column.component.d.ts +0 -32
  209. package/src/lib/components/ai-collaborator-permissions-column.component.js +0 -132
  210. package/src/lib/components/ai-collaborator-permissions-column.component.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-site-datasets.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 { mediaRefFromCdnPath } from '@aglyn/aglyn/app-utils/media-ref'\nimport { checkDatasetQuota } from '@aglyn/aglyn/app-utils/plan-entitlements'\nimport { pluginResourceDraftWriter } from '@aglyn/aglyn/plugin-manager/plugin-resource-drafts'\nimport { pluginRecordIndex } from '@aglyn/aglyn/plugin-manager/plugin-record-index'\nimport {\n AI_BUILD_PLAN_LIMITS,\n AI_PLAN_NEW_REF_PREFIX,\n isAiPlanNewRef,\n type AiBuildPlan,\n type AiBuildPlanCreate,\n type AiBuildPlanScreen,\n} from '../model/ai-build-plan'\nimport type { AiInventoryDataset, AiSiteInventory } from '../model/ai-site-inventory'\nimport { AI_TYPED_LIST_MIN_ITEMS } from '../runtime/ai-doctrine-validators'\nimport type { AiJob, AiJobOutput, AiJobPlan } from '../model/ai-jobs.types'\nimport type { AiPlanCapabilities } from '../model/ai-plan-capabilities'\nimport { AI_SITE_DATASETS_MAX } from '../model/ai-site-job'\nimport { AI_STEP_TIERS } from '../providers/catalog'\nimport { aiModelForStep } from '../providers/routing'\nimport {\n AI_DATASET_MAX_TOKENS,\n AI_DATASET_STEP,\n aiDatasetDraftContent,\n generateAiDataset,\n} from '../runtime/ai-dataset-generation'\nimport {\n aiLayoutListingId,\n aiLayoutRecordBaseOf,\n aiLayoutRecordsPlacements,\n type AiLayoutListing,\n type AiLayoutListingField,\n type AiLayoutListingScreen,\n} from '../layout-language/ai-layout-listings'\nimport {\n aiLayoutNeutralStarterRun,\n aiLayoutSeedNumber,\n aiLayoutStarterPhotos,\n type AiLayoutPicturePhoto,\n type AiLayoutPictureReport,\n type AiLayoutPictureSlot,\n} from '../layout-language/ai-layout-pictures'\nimport { aiSiteWords } from '../model/ai-site-job'\nimport { aiSiteIsStarterSrc, type AiSitePhotos, type AiSiteStarterList, type AiStockRefusedPicks } from '../model/ai-site-photos'\nimport type { AiJobAdmissionContext } from './ai-job-admission'\nimport { aiOriginJobId } from './ai-job-draft-ids'\nimport { aiSiteProductPhotoSrc } from './ai-job-site-content'\nimport {\n aiLayoutStockPhotoSource,\n aiStockJobPhotosOf,\n aiStockPhotoWordsOf,\n aiStockRecordScene,\n aiStockStem,\n} from './ai-layout-stock-photos'\nimport { AI_DATASET_DRAFT_RESOURCE } from './ai-build-unit-outcome'\nimport { aiJobStepBudget } from './ai-job-budget'\nimport { aiGenerationSpent, aiUnspentOutcome } from './ai-job-generation'\nimport { aiPluginDraftAdmissionRefusal } from './ai-job-plugin-drafts'\nimport type { AiJobStepContext, AiJobStepOutcome, AiJobStepRunner } from './ai-job-text-step'\n\n/**\n * A SITE START'S DATASETS (AGL-3616): \"Aglyn AI can also use/create datasets\n * too for whatever it needs\" (Zach, 2026-10-10).\n *\n * A site whose content is a list of like things — a restaurant's menu, a\n * studio's team, a contractor's services, a photographer's portfolio, an\n * events list, its questions and answers — keeps it as a DATASET, the way the\n * docs teach a person to: the owner edits one record and every page listing\n * it follows. On a workspace that may create datasets, the site plan creates\n * one for such content (`create`, kind `dataset`) and names it in the `uses`\n * of each section that lists it. The scaffold then builds each dataset as a\n * unit of its own, after the layout and before the form (which may write\n * its submissions to one) and the pages:\n *\n * - DESIGNED by the `submit_dataset` generation (`ai-dataset-generation.ts`):\n * the planned fields typed, at most a few more, and 3 to 12 records seeded\n * from the brief. Nothing anybody did not say: no review, testimonial,\n * rating, quote or person's name, no price the brief does not state.\n * - WRITTEN by the data plugin's `dataset` writer — this plugin never names\n * the datasets collection — with every rule the console's datasets route\n * has: the member's role and `data.manage`, `release_data_store`,\n * `dataStore` (Starter and up), `datasetsPerOrg` counted inside the create,\n * `recordsPerDataset` and the storage band.\n * - PICTURED where the plan lists it the way a gallery is listed (Zach,\n * 2026-10-10: a ceramic artist's \"Selected work\" came back as text-only\n * cards, where it had been an image-led gallery): a portfolio's pieces, a\n * team, a menu, classes and events, and services or offerings whose\n * section says it shows them in pictures (`aiSiteDatasetPicturesOf`). Such\n * a dataset gets an Image field, and each record a stock photo of its own\n * name in the site's craft, copied into the site's library — never one the\n * job already placed, else a starter photo — searched in code, so it\n * costs no credits (`aiSiteDatasetRecordPhotos`).\n * - LISTED by the pages built after it: each section naming it repeats over\n * the dataset (`aiSiteDatasetListings`, a `records` listing the layout\n * compiler draws, its card led by the record's photo where it has one),\n * and a page the plan made its record template binds its fields by id,\n * its photo the record's, and keeps the address field the writer added.\n *\n * Where datasets cannot be created — the Free taste, Starter's two used up,\n * the data store not released — the plan is told so and creates none, so its\n * sections write the items out. A dataset unit that fails or is refused\n * leaves the pages that list it built without it (they say so), and its\n * record page is not built.\n */\n\n/** The most datasets one site start creates. */\nexport { AI_SITE_DATASETS_MAX } from '../model/ai-site-job'\n\n/** The resource the data plugin's writer is registered under. */\nexport const AI_SITE_DATASET_RESOURCE = AI_DATASET_DRAFT_RESOURCE\n\n/** What the site's plugin list calls the plugin, for \"Turn on Data for this site\". */\nconst DATA_PLUGIN_LABEL = 'Data'\n\n/** The input a dataset unit's own job carries what it needs in. */\nexport const AI_SITE_DATASET_INPUT = 'siteDataset'\n\n/** What a dataset unit's job is told beside its creation. */\nexport interface AiSiteDatasetInput {\n /** The sections that list it, by page: \"Menu › Our dishes (12 items)\". */\n shownIn: string[]\n /** Whether a page of the plan is its record template. */\n recordPages: boolean\n /**\n * The form of the plan that writes its submissions to it (AGL-3616), by\n * name, with that form's planned fields; absent where no form does.\n */\n forForm?: { name: string; fields: string[] }\n /**\n * Whether its records carry a photo, and of what (AGL-3616): `things` for a\n * portfolio's pieces, a menu, classes; `people` for a team. Absent for a\n * list a visitor reads rather than looks at: questions, steps, hours.\n */\n pictures?: AiSiteDatasetPictures\n}\n\n/** What a dataset's records are pictured as: things or people. */\nexport type AiSiteDatasetPictures = 'things' | 'people'\n\n/** A list of questions, voices or plain facts: read, never pictured. */\nconst READ_ONLY_LIST =\n /\\b(faqs?|questions?|q ?& ?a|answers?|testimonials?|reviews?|quotes?|voices|hours|opening|steps?|process|policies|policy|terms|stats?|numbers|figures|milestones|timeline|values|benefits|reasons|features|requirements|checklist|ingredients|donations?|needs|partners|sponsors|supporters|roles|positions|jobs|openings)\\b/i\n/** A list of people: its photos are of the business's people. */\nconst PEOPLE_LIST =\n /\\b(team|staff|people|crew|instructors?|teachers?|tutors?|stylists?|barbers?|therapists?|coaches?|trainers?|chefs?|doctors?|dentists?|hygienists?|practitioners?|artists?|musicians?|performers?|speakers?|founders?|members?)\\b/i\n/** A list a visitor looks at before reading: pictured wherever it is listed. */\nconst PICTURED_LIST =\n /\\b(portfolio|pieces?|works?|projects?|gallery|galleries|collections?|series|menus?|dishes|plates|drinks|cocktails|wines?|beers?|coffees?|pastries|cakes|products?|items|events?|classes|class|workshops?|courses?|retreats?|tours?|trips?|adventures?|experiences?|rooms?|suites?|cabins?|properties|listings|homes|venues?|spaces?|recipes?|artworks?|paintings?|prints?|photos?|photographs?|designs?|commissions?|builds?|vehicles?|animals?|pets?|plants?|flowers?|bouquets?|arrangements?|case studies)\\b/i\n/** A section that says it shows its items in pictures: a gallery, a grid of photos, tiles. */\nconst PICTURED_SECTION =\n /\\b(gallery|galleries|grid|images?|photos?|photographs?|pictures?|lightbox|portfolio|showcase|tiles?|visuals?|lookbook|carousel|slideshow|mosaic|thumbnails?)\\b/i\n\n/**\n * Whether a dataset's records carry a photo, read off the plan (AGL-3616):\n * its name and the names of the sections that list it. Questions, voices and\n * plain facts never; people as people; a list a visitor looks at — pieces,\n * dishes, classes, events, rooms — always; any other list (services,\n * offerings, programs) only where a section that lists it says it shows them\n * in pictures, or names one of those. A dataset no page lists is not\n * pictured. Pure.\n */\nexport function aiSiteDatasetPicturesOf(\n dataset: Pick<AiBuildPlanCreate, 'name'>,\n sections: readonly string[],\n): AiSiteDatasetPictures | null {\n if (!sections.length) return null\n const own = dataset.name\n if (READ_ONLY_LIST.test(own)) return null\n if (PEOPLE_LIST.test(own)) return 'people'\n if (PICTURED_LIST.test(own)) return 'things'\n if (sections.some((section) => READ_ONLY_LIST.test(section) && !PICTURED_SECTION.test(section))) return null\n if (sections.some((section) => PEOPLE_LIST.test(section))) return 'people'\n if (sections.some((section) => PICTURED_LIST.test(section) || PICTURED_SECTION.test(section))) return 'things'\n return null\n}\n\n/** What a dataset row says when its design could not be written: our failure, refunded. */\nexport const AI_SITE_DATASET_NOT_WRITTEN_COPY = 'This dataset could not be added this time.'\n\n/** The note a written dataset carries on the job's page. */\nexport function aiSiteDatasetNote(records: number): string {\n return `${records} ${records === 1 ? 'record' : 'records'} to start, in Data. Edit them there and every page that lists them follows.`\n}\n\n/** The note a record template's row adds: the binding is the member's to save (rule 13). */\nexport const AI_SITE_RECORD_PAGE_NOTE =\n 'A page per record is drafted, not live: open Page Properties → Record pages to save it.'\n\n/** ASSUMED: what one dataset pass reads and writes beside its generation: the site, the writer's reads and its transaction. */\nexport const AI_SITE_DATASET_WRITES_MS = 2_000\n\n/** One dataset's pass: its generation and re-ask at its ceiling, and its writes. */\nexport const AI_SITE_DATASET_BUDGET = aiJobStepBudget({\n tier: AI_STEP_TIERS[AI_DATASET_STEP],\n maxTokens: AI_DATASET_MAX_TOKENS,\n lookups: 0,\n ownReadsMs: AI_SITE_DATASET_WRITES_MS,\n})\n\nconst str = (value: unknown): string => (typeof value === 'string' ? value.trim() : '')\n\n/** The plan's reference to a dataset as a section names it: `new:<name>`, compared lowercased. */\nfunction namesDataset(ref: string, name: string): boolean {\n return isAiPlanNewRef(ref) && ref.slice(ref.indexOf(':') + 1).trim().toLowerCase() === name.trim().toLowerCase()\n}\n\n/** The plan's datasets, in plan order, at most the most a start creates. */\nexport function aiSitePlanDatasets(plan: Pick<AiJobPlan, 'create'>): AiBuildPlanCreate[] {\n return plan.create.filter((entry) => entry.kind === 'dataset').slice(0, AI_SITE_DATASETS_MAX)\n}\n\n/** Where the plan lists a dataset, in words its design reads, whether a page is its record template, and the form that writes to it. */\nexport function aiSiteDatasetInputOf(\n dataset: Pick<AiBuildPlanCreate, 'name'>,\n screens: readonly AiBuildPlanScreen[],\n create: readonly AiBuildPlanCreate[] = [],\n): AiSiteDatasetInput {\n const shownIn: string[] = []\n const sectionNames: string[] = []\n for (const screen of screens) {\n for (const section of screen.sections) {\n if (!section.uses.some((ref) => namesDataset(ref, dataset.name))) continue\n shownIn.push(`${screen.title} › ${section.name}${section.items ? ` (${section.items} items)` : ''}`)\n sectionNames.push(section.name)\n }\n }\n const recordPages = screens.some((screen) => !!screen.record && namesDataset(screen.record.dataset, dataset.name))\n const form = create.find((entry) => entry.kind === 'form' && !!entry.writesTo && namesDataset(entry.writesTo, dataset.name))\n // A form's dataset holds its submissions: nobody's photo.\n const pictures = form ? null : aiSiteDatasetPicturesOf(dataset, sectionNames)\n return {\n shownIn: shownIn.slice(0, 8),\n recordPages,\n ...(form ? { forForm: { name: form.name, fields: form.fields.slice(0, AI_SITE_FORM_DATASET_FIELDS_MAX) } } : {}),\n ...(pictures ? { pictures } : {}),\n }\n}\n\n/** Whether a plan screen is the record template of a dataset the plan creates, and which. */\nexport function aiSiteRecordTemplateOf(screen: Pick<AiBuildPlanScreen, 'record'>): string | null {\n const ref = screen.record?.dataset\n return ref && isAiPlanNewRef(ref) ? ref.slice(ref.indexOf(':') + 1).trim() : null\n}\n\nfunction datasetInputOf(job: Pick<AiJob, 'inputs'>): AiSiteDatasetInput {\n const raw = (job.inputs?.[AI_SITE_DATASET_INPUT] ?? {}) as Partial<AiSiteDatasetInput>\n const form = raw.forForm && typeof raw.forForm === 'object' ? raw.forForm : null\n return {\n shownIn: Array.isArray(raw.shownIn) ? raw.shownIn.map(str).filter(Boolean).slice(0, 8) : [],\n recordPages: raw.recordPages === true,\n ...(form && str(form.name)\n ? {\n forForm: {\n name: str(form.name),\n fields: Array.isArray(form.fields) ? form.fields.map(str).filter(Boolean).slice(0, AI_SITE_FORM_DATASET_FIELDS_MAX) : [],\n },\n }\n : {}),\n ...(raw.pictures === 'things' || raw.pictures === 'people' ? { pictures: raw.pictures } : {}),\n }\n}\n\n/** The most fields a form's dataset is designed with: the data plugin writer's own ceiling is higher. */\nexport const AI_SITE_FORM_DATASET_FIELDS_MAX = 12\n\n/** The field types a planned `Name:type` may name, as the data plugin's writer takes them. */\nconst FORM_DATASET_FIELD_TYPES = ['text', 'number', 'integer', 'boolean', 'list'] as const\n\n/** A planned field as a person reads it: `fullName` and `full_name` are \"Full name\", `fechaDeÚltimaVisita` \"Fecha de última visita\". */\nexport function aiSiteDatasetFieldName(planned: string): string {\n const words = planned\n .replace(/([\\p{Ll}\\p{N}])(\\p{Lu})/gu, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n return words ? words.charAt(0).toUpperCase() + words.slice(1).toLowerCase() : ''\n}\n\n/**\n * A dataset a form writes to, as the data plugin's writer takes it\n * (AGL-3616): designed with no model, since its records are the\n * submissions. Its fields are its planned ones — or, where the plan gave it\n * none, the form's — each a person's words for it, text unless the plan\n * typed it as `Name:type`, never required, so a submission that leaves one\n * blank is still a record. It starts with no records. Pure.\n */\nexport function aiSiteFormDatasetContent(\n name: string,\n planned: readonly string[],\n form: { fields: readonly string[] },\n): Record<string, unknown> {\n const specs = (planned.length ? planned : form.fields).slice(0, AI_SITE_FORM_DATASET_FIELDS_MAX)\n const seen = new Set<string>()\n const fields: Array<{ name: string; type: string }> = []\n for (const spec of specs) {\n const at = spec.lastIndexOf(':')\n const typed = at > 0 ? spec.slice(at + 1).trim().toLowerCase() : ''\n const type = (FORM_DATASET_FIELD_TYPES as readonly string[]).includes(typed) ? typed : 'text'\n const fieldName = aiSiteDatasetFieldName(type === typed ? spec.slice(0, at) : spec).slice(0, 60)\n if (!fieldName || seen.has(fieldName.toLowerCase())) continue\n seen.add(fieldName.toLowerCase())\n fields.push({ name: fieldName, type })\n }\n return { name, fields, records: [] }\n}\n\n/** The note a form's dataset carries on the job's page. */\nexport function aiSiteFormDatasetNote(form: string): string {\n return `Empty to start: each submission of the form “${form}” is added here, in Data.`\n}\n\nconst limitReview = (message: string) => ({ reason: 'limit' as const, message, findings: [] })\n\n/** The wall clock a dataset's photos may take inside its pass: the 20 seconds a page's pictures had (AGL-3660). */\nexport const AI_SITE_DATASET_PHOTOS_BUDGET_MS = 20_000\n\n/** The field a pictured dataset's photo is kept in, where the plan gave it none. */\nexport const AI_SITE_DATASET_IMAGE_FIELD = 'Image'\n\n/**\n * The field a pictured dataset keeps what each record's photo shows in\n * (AGL-3856), which its card's and its page's Image take as their alt text:\n * a record's title is what it is called, never what its photo shows.\n */\nexport const AI_SITE_DATASET_IMAGE_ALT_FIELD = 'Image description'\n\n/** A planned field that already names a record's photo. */\nconst IMAGE_FIELD_NAME =\n /^(?:main |cover |hero |featured? )?(?:image|photo|picture|photograph|thumbnail|headshot|portrait|cover)s?$/i\n\n/** One record's photo: the address its Image shows, and the library asset placed, which no page shows again. */\nexport interface AiSiteDatasetRecordPhoto {\n /** The media library's CDN path, or a starter's site path; `null` for none. */\n src: string | null\n /** The `media:` reference of the stock photo placed, or `null` for a starter. */\n placed: string | null\n /** What the photo shows, in its own words (AGL-3856); `null` for none. */\n alt?: string | null\n /** The library photo's size, where it is one (AGL-3988): what a page the library fails reuses it at. */\n width?: number\n height?: number\n /**\n * The picks the library's image hosts refused for a record left on a\n * starter (AGL-3988), which the site start's late photo pass asks again.\n */\n refused?: AiStockRefusedPicks\n /** A starter on a site with no stock library (AGL-3988): it keeps it, and no late pass fills it. */\n noLibrary?: true\n}\n\n/**\n * A photo for each record of a pictured dataset (AGL-3616), in order: a stock\n * photo of the record's own name, in the site's craft (\"ceramic speckled\n * serving bowl\"), copied into the site's library, where the deployment has a\n * stock library — never twice in the dataset nor one another part of the job\n * placed, inside {@link AI_SITE_DATASET_PHOTOS_BUDGET_MS} — else a starter\n * photo, as a page's empty picture takes one. A team is searched as the\n * business's people. The photo is kept as the asset's CDN path, the form a\n * product keeps (`aiSiteProductPhotoSrc`), so a replace in the library still\n * reaches it. No AI model is asked, so no credits; never throws.\n */\nexport async function aiSiteDatasetRecordPhotos(input: {\n job: Pick<AiJob, '$id' | 'hostId' | 'createdBy' | 'inputs' | 'brief' | 'plan'>\n /** The dataset, as the plan named it. */\n name: string\n /** Each record's name, by position. */\n names: readonly string[]\n /** What each record is filed under, by position ({@link aiSiteDatasetCategoryOf}, AGL-3856); absent for a list that files none. */\n categories?: ReadonlyArray<string | null>\n pictures: AiSiteDatasetPictures\n signal?: AbortSignal\n stockPhotos?: typeof aiLayoutStockPhotoSource\n}): Promise<AiSiteDatasetRecordPhoto[]> {\n const { job } = input\n if (!input.names.length || !job.hostId) return input.names.map(() => ({ src: null, placed: null }))\n const people = input.pictures === 'people'\n const slots: AiLayoutPictureSlot[] = input.names.map((name, index) => ({\n imageId: `record${index}`,\n frameId: null,\n iconId: null,\n alt: name.trim() || input.name,\n // The record card's own shape: a team's portraits stand, pieces sit wide.\n aspect: people ? 4 / 5 : 4 / 3,\n sectionIndex: 0,\n role: people ? ('about' as const) : ('gallery' as const),\n // A record's name is a search's words, never what its photo shows (AGL-3856).\n standIn: true,\n // A team's record shows an adult in their role, never a child (AGL-3856).\n ...(people ? { people: true } : {}),\n // A piece's record is OF what it names and what it is filed under (AGL-3856).\n ...(people ? {} : { record: input.categories?.[index]?.trim() ? { category: (input.categories[index] as string).trim() } : {} }),\n }))\n const seed = `${job.$id}:records`\n let found: ReadonlyArray<AiLayoutPicturePhoto | null> = []\n /** The picks the image hosts refused, by record (AGL-3988). */\n const report: AiLayoutPictureReport = { refused: new Map() }\n /** Whether the site has a stock library: its records then never take a starter that shows another business (AGL-3988). */\n let library = false\n try {\n const source = (input.stockPhotos ?? aiLayoutStockPhotoSource)(\n {\n hostId: job.hostId,\n uid: job.createdBy,\n seed,\n business: aiSiteWords(job.inputs).about || job.brief,\n ...aiStockPhotoWordsOf(job),\n sectionNames: [input.name],\n jobId: aiOriginJobId(job),\n // Each record may try its name, its object and the site's world.\n searches: slots.length * 3,\n ...(input.signal ? { signal: input.signal } : {}),\n },\n { budgetMs: AI_SITE_DATASET_PHOTOS_BUDGET_MS },\n )\n library = Boolean(source)\n if (source) found = await source(slots, report)\n } catch (error) {\n console.warn('ai site dataset: the stock photos failed; the job’s own photos or starters fill them', { error: String(error) })\n }\n const hostId = job.hostId\n const copied: Array<AiLayoutPicturePhoto | null> = slots.map((_slot, index) => (found[index]?.src ? (found[index] as AiLayoutPicturePhoto) : null))\n // A record left without a photo takes one this list already shows, on its\n // own subject (AGL-3988), before any starter.\n const photos =\n library && !people\n ? aiSiteDatasetRecordsFromOwn(\n input.names.map((name, index) => ({ name, category: input.categories?.[index] ?? null })),\n copied,\n seed,\n )\n : copied\n // Only a job with no photo of its own takes starters: with a library, the\n // neutral ones in turn, never a workbench or houseplants (AGL-3923); a\n // team's records, and a site with no library, the starters as before.\n const starters = library && !people ? aiLayoutNeutralStarterRun(slots.length, seed) : aiLayoutStarterPhotos(slots, seed)\n return slots.map((_slot, index) => {\n const photo = photos[index]\n const stock = aiSiteProductPhotoSrc(photo?.src, hostId)\n if (photo && stock) {\n const copied = found[index]?.src === photo.src\n return {\n src: stock,\n placed: copied ? photo.src : null,\n alt: photo.alt?.trim() || null,\n width: photo.width,\n height: photo.height,\n }\n }\n const refused = report.refused.get(slots[index] as AiLayoutPictureSlot)\n return {\n src: aiSiteProductPhotoSrc(starters[index]?.src, hostId),\n placed: null,\n alt: starters[index]?.alt?.trim() || null,\n ...(refused ? { refused } : {}),\n ...(library ? {} : { noLibrary: true as const }),\n }\n })\n}\n\n/**\n * The photos of a list's records, each record its library left without one\n * given one of those the list already shows (AGL-3988). The beta.270 Sugar\n * Hollow Photography covers, a wedding photographer's, filed five \"Weddings\n * and elopements\" galleries under a windowsill, a workbench, a desk and an\n * office team, every copy refused by Pixabay's rate limit, while three of\n * its records had copied a snowy mountain wedding, a couple at sunset and a\n * father and son in the mountains.\n *\n * A record takes, in order: a photo of a record filed under the same\n * category; a photo whose words name the people its own moment shows\n * (`aiStockRecordScene`: a couple for \"Couple Portraits\", never a family);\n * either again where only the record beside it shows them; and last any\n * photo the list shows. Never the photo of the record beside it while\n * another fits, the least shown first, the seed picking among equals. A\n * record no photo fits keeps none, and takes a starter. Pure.\n *\n * `besideLast` is the site start's late photo pass (AGL-3988): there the\n * other choice is a starter photo of another business, so a record every\n * photo sits beside takes the photo beside it rather than none.\n */\nexport function aiSiteDatasetRecordsFromOwn(\n records: ReadonlyArray<{ name: string; category?: string | null }>,\n photos: ReadonlyArray<AiLayoutPicturePhoto | null>,\n seed: string,\n /**\n * The photos the job copied for its pages (AGL-3988), which the site\n * start's late photo pass offers a list whose own photos were all refused:\n * filed under no category, so each is taken by the people it shows.\n */\n others: readonly AiLayoutPicturePhoto[] = [],\n options: { besideLast?: boolean } = {},\n): Array<AiLayoutPicturePhoto | null> {\n const listed = photos.flatMap((photo, index) => (photo?.src ? [{ photo, index }] : []))\n const shownHere = new Set(listed.map((entry) => entry.photo.src))\n const own = [\n ...listed,\n ...others\n .filter((photo, at, all) => photo.src && !shownHere.has(photo.src) && all.findIndex((one) => one.src === photo.src) === at)\n .map((photo, at) => ({ photo, index: records.length + at })),\n ]\n if (!own.length) return [...photos]\n /** Every place a photo is ranked from: the list's records, then the job's other photos. */\n const span = records.length + own.length - listed.length\n const category = (index: number) => records[index]?.category?.replace(/\\s+/g, ' ').trim().toLowerCase() ?? ''\n const turn = aiLayoutSeedNumber(seed)\n /** Whether a photo's words name the people a record's moment shows, and none it never shows. */\n const shows = (photo: AiLayoutPicturePhoto, record: { name: string; category?: string | null }) => {\n const scene = aiStockRecordScene(record.name, record.category ?? '')\n if (!scene) return false\n const stems = new Set(\n (photo.alt ?? '')\n .toLowerCase()\n .split(/[^a-z\\u00c0-\\u024f]+/)\n .filter(Boolean)\n .map(aiStockStem),\n )\n return scene.people.some((stem) => stems.has(stem)) && !scene.shun.some((stem) => stems.has(stem))\n }\n /** The list filled in one order; the record beside one filled before it is known, the one after not yet. */\n const fill = (order: readonly number[]) => {\n const filled = [...photos]\n for (const index of order) {\n const record = records[index]\n if (!record || filled[index]?.src) continue\n const beside = new Set([filled[index - 1]?.src, filled[index + 1]?.src].filter(Boolean))\n const apart = (entry: { photo: AiLayoutPicturePhoto }) => !beside.has(entry.photo.src)\n const same = own.filter((entry) => category(index) && category(entry.index) === category(index))\n const subject = own.filter((entry) => shows(entry.photo, record))\n const pool = [same.filter(apart), subject.filter(apart), same, subject, own.filter(apart), options.besideLast ? own : []].find(\n (list) => list.length,\n )\n if (!pool) continue\n const uses = (src: string) => filled.filter((photo) => photo?.src === src).length\n const rank = (at: number) => (((at - turn) % span) + span) % span\n const [pick] = [...pool].sort((a, b) => uses(a.photo.src) - uses(b.photo.src) || rank(a.index) - rank(b.index))\n if (pick) filled[index] = { ...pick.photo }\n }\n return filled\n }\n // Filled from either end, the one that shows a photo beside itself least:\n // a record beside a copied one is the most held, and is served first.\n const forward = fill(records.map((_record, index) => index))\n const backward = fill(records.map((_record, index) => records.length - 1 - index))\n const repeats = (list: ReadonlyArray<AiLayoutPicturePhoto | null>) =>\n list.filter((photo, index) => index > 0 && photo?.src && photo.src === list[index - 1]?.src).length\n return repeats(backward) < repeats(forward) ? backward : forward\n}\n\n/**\n * A designed dataset's content with its records' photos (AGL-3616): the\n * planned field that names a photo (\"Image\", \"Photo\") becomes the data\n * plugin's `image` field, else one called \"Image\" is added after the others,\n * and each record holds its photo there; a record with none holds nothing.\n * Pure.\n */\nexport function aiSiteDatasetContentWithPhotos(\n content: Record<string, unknown>,\n photos: ReadonlyArray<string | null>,\n /** What each record's photo shows (AGL-3856), kept in {@link AI_SITE_DATASET_IMAGE_ALT_FIELD}; none adds no field. */\n alts: ReadonlyArray<string | null> = [],\n): Record<string, unknown> {\n const fields = (Array.isArray(content['fields']) ? content['fields'] : []) as Array<{ name: string; type?: string }>\n const named = fields.find((field) => IMAGE_FIELD_NAME.test(str(field.name)))\n const fieldName = named ? named.name : AI_SITE_DATASET_IMAGE_FIELD\n const withImage = named\n ? fields.map((field) => (field === named ? { ...field, type: 'image' } : field))\n : [...fields, { name: AI_SITE_DATASET_IMAGE_FIELD, type: 'image' }]\n const described = alts.some((alt, index) => Boolean(alt && photos[index]))\n const altName = AI_SITE_DATASET_IMAGE_ALT_FIELD\n const nextFields =\n described && !withImage.some((field) => str(field.name).toLowerCase() === altName.toLowerCase())\n ? [...withImage, { name: altName, type: 'text' }]\n : withImage\n const records = (Array.isArray(content['records']) ? content['records'] : []) as Array<Record<string, unknown>>\n return {\n ...content,\n fields: nextFields,\n records: records.map((record, index) => {\n const next = { ...record }\n delete next[fieldName]\n const photo = photos[index]\n const alt = photo && described ? alts[index] : null\n return photo ? { ...next, [fieldName]: photo, ...(alt ? { [altName]: alt } : {}) } : next\n }),\n }\n}\n\nexport interface AiSiteDatasetRunnerDeps {\n generate?: typeof generateAiDataset\n writerFor?: typeof pluginResourceDraftWriter\n /** Where a pictured dataset's photos come from; the stock library, else the starters, otherwise. */\n photos?: typeof aiSiteDatasetRecordPhotos\n}\n\n/** The fields and record names a written dataset reports, as its output's proposal keeps them. */\ninterface AiSiteDatasetProposal {\n fields: AiLayoutListingField[]\n /** Each record's name: its first field's value. */\n recordNames: string[]\n addressField: string | null\n /** The field each record's photo is in, where it has one (AGL-3616). */\n imageField?: string | null\n /** The library photos its records show (`media:` references), which no page places again. */\n photos?: string[]\n /**\n * The same photos with their size and words (AGL-3988): what a page's\n * picture the library fails takes before any starter.\n */\n placedPhotos?: AiLayoutPicturePhoto[]\n /**\n * The fields most of its first records leave empty, by id (AGL-3616): a\n * tour's venues not yet known. A card never binds one — it would print\n * nothing on most records — so its listing leaves them out.\n */\n sparseFields?: string[]\n /**\n * What its records are filed under (AGL-3921): the category-like field, by\n * id, and each record's value of it, by position as {@link recordNames}.\n * A section named for one value lists only its records.\n */\n groups?: { field: string; values: string[] }\n}\n\n/** A field whose name says it files its records: a category, a type, a kind. */\nconst CATEGORY_FIELD = /^(?:(?:gallery|session|service|event|course|class|product|menu|work|project) )?(?:category|categories|type|kind|collection|genre|group|section|subject|occasion|series)$/i\n\n/**\n * What a designed dataset's records are filed under (AGL-3921): its first\n * field whose name says it files them (\"Category\", \"Type\", \"Session type\"),\n * with each record's value, where they hold at least two different values\n * and some record shares one — a list that files every record apart files\n * none. `null` otherwise. Pure.\n */\nexport function aiSiteDatasetCategoryOf(dataset: {\n fields: ReadonlyArray<{ name: string }>\n records: ReadonlyArray<ReadonlyArray<string | undefined>>\n}): { column: number; name: string; values: Array<string | null> } | null {\n for (const [column, field] of dataset.fields.entries()) {\n if (column === 0 || !CATEGORY_FIELD.test(field.name.trim())) continue\n const values = dataset.records.map((values) => (values[column] ?? '').replace(/\\s+/g, ' ').trim() || null)\n const distinct = new Set(values.filter((value): value is string => Boolean(value)).map((value) => value.toLowerCase()))\n if (distinct.size >= 2 && distinct.size < values.filter(Boolean).length) return { column, name: field.name, values }\n }\n return null\n}\n\n/**\n * A dataset's groups as its proposal keeps them: the written field's id, and\n * the value of each record its {@link AiSiteDatasetProposal.recordNames} names.\n */\nfunction aiSiteDatasetGroupsOf(\n category: ReturnType<typeof aiSiteDatasetCategoryOf>,\n written: readonly AiLayoutListingField[],\n designed: { fields: ReadonlyArray<{ name: string }>; records: ReadonlyArray<ReadonlyArray<string | undefined>> },\n): Pick<AiSiteDatasetProposal, 'groups'> {\n if (!category) return {}\n const field =\n written.find((entry) => entry.name.trim().toLowerCase() === category.name.trim().toLowerCase())?.id ??\n (written.length === designed.fields.length ? written[category.column]?.id : undefined)\n if (!field) return {}\n const values = designed.records.flatMap((record, index) => record[0] ? [category.values[index] ?? ''] : []).slice(0, 12)\n return { groups: { field, values } }\n}\n\n/**\n * The fields of a designed dataset that its records leave empty on most of\n * them — every record, or more than half — by the id the data plugin gave\n * each (AGL-3616). Its first field is the record's name and is never one. The\n * live low-tide-hollow start (beta.239) seeded its tour dates with no venue,\n * rightly inventing none, and its cards bound the venue as their eyebrow.\n */\nexport function aiDatasetSparseFields(\n dataset: { fields: ReadonlyArray<{ name: string }>; records: ReadonlyArray<ReadonlyArray<string | undefined>> },\n written: readonly AiLayoutListingField[],\n): string[] {\n if (!dataset.records.length) return []\n const idOf = (name: string, column: number) =>\n written.find((field) => field.name.trim().toLowerCase() === name.trim().toLowerCase())?.id ?? written[column]?.id ?? null\n return dataset.fields.flatMap((field, column) => {\n if (column === 0) return []\n const filled = dataset.records.filter((values) => (values[column] ?? '').trim()).length\n const id = idOf(field.name, column)\n return id && filled * 2 <= dataset.records.length ? [id] : []\n })\n}\n\nfunction proposalOf(output: Pick<AiJobOutput, 'proposal'>): AiSiteDatasetProposal {\n const raw = (output.proposal ?? {}) as Partial<AiSiteDatasetProposal>\n return {\n fields: Array.isArray(raw.fields)\n ? raw.fields.filter((field) => field && typeof field.id === 'string' && field.id).map((field) => ({ id: field.id, name: str(field.name) || field.id, type: str(field.type) || 'text' }))\n : [],\n recordNames: Array.isArray(raw.recordNames) ? raw.recordNames.map(str).filter(Boolean).slice(0, 12) : [],\n addressField: str(raw.addressField) || null,\n imageField: str(raw.imageField) || null,\n photos: Array.isArray(raw.photos) ? raw.photos.map(str).filter((src) => src.startsWith('media:')).slice(0, 24) : [],\n sparseFields: Array.isArray(raw.sparseFields) ? raw.sparseFields.map(str).filter(Boolean) : [],\n ...(raw.groups && typeof raw.groups === 'object' && str(raw.groups.field) && Array.isArray(raw.groups.values)\n ? { groups: { field: str(raw.groups.field), values: raw.groups.values.slice(0, 12).map(str) } }\n : {}),\n }\n}\n\n/**\n * The dataset unit's runner, on the job the scaffold derived for it: the one\n * creation its plan carries, designed by the model and written by the data\n * plugin, under the creation's own id. A pass repeated after its write finds\n * the dataset the writer wrote and reports it again, spending nothing.\n */\nexport function createAiSiteDatasetRunner(deps: AiSiteDatasetRunnerDeps = {}): AiJobStepRunner {\n const generate = deps.generate ?? generateAiDataset\n const writerFor = deps.writerFor ?? pluginResourceDraftWriter\n const photosFor = deps.photos ?? aiSiteDatasetRecordPhotos\n return async (context): Promise<AiJobStepOutcome> => {\n const { job, firestore, signal } = context\n const model = context.modelFor?.(AI_DATASET_STEP) ?? aiModelForStep(AI_DATASET_STEP)\n const creation = (job.plan as AiJobPlan | null)?.create?.find((entry) => entry.kind === 'dataset')\n const keeper = writerFor(AI_SITE_DATASET_RESOURCE)\n if (!job.hostId || !creation) return { ...aiUnspentOutcome(model), failure: 'Open the site before adding its data.' }\n if (!keeper) return { ...aiUnspentOutcome(model), failure: 'Datasets are not available on this site.' }\n const host = await firestore.collection('hosts').doc(job.hostId).get()\n const hostSubdomain = str(host.get('subdomain')) || null\n const output = (id: string, name: string, proposal: AiSiteDatasetProposal, records: number): AiJobOutput => ({\n resource: 'draft',\n draftResource: AI_SITE_DATASET_RESOURCE,\n id,\n hostId: job.hostId ?? null,\n hostSubdomain,\n label: name,\n note: aiSiteDatasetNote(records),\n proposal: proposal as unknown as Record<string, unknown>,\n })\n const input = datasetInputOf(job)\n // Asked again under the same id: the dataset already written.\n const written = await keeper.writer.read({ hostId: job.hostId, id: job.$id })\n if (written) {\n const facts = written.facts as { fields?: AiLayoutListingField[]; addressField?: string | null; imageField?: string | null }\n const again = output(\n written.id,\n written.name || creation.name,\n { fields: facts.fields ?? [], recordNames: [], addressField: facts.addressField ?? null, imageField: facts.imageField ?? null },\n 0,\n )\n return aiUnspentOutcome(model, {\n outputs: [input.forForm ? { ...again, note: aiSiteFormDatasetNote(input.forForm.name) } : again],\n })\n }\n // A form's dataset (AGL-3616): its records are the submissions, so it is\n // designed from the plan with no model, and starts empty.\n if (input.forForm) {\n const content = aiSiteFormDatasetContent(creation.name, creation.fields, input.forForm)\n const checked = keeper.writer.check(content, { hostId: job.hostId })\n if (checked.ok === false) {\n console.error('ai site dataset: the dataset writer refused a form dataset we made', { orgId: job.orgId, jobId: job.$id, problems: checked.problems })\n return { ...aiUnspentOutcome(model), failure: AI_SITE_DATASET_NOT_WRITTEN_COPY }\n }\n const result = await keeper.writer.write({\n orgId: job.orgId,\n hostId: job.hostId,\n uid: job.createdBy,\n org: (context.org ?? null) as Readonly<Record<string, unknown>> | null,\n now: context.now,\n id: job.$id,\n name: creation.name,\n content,\n })\n if (result.ok === false) {\n if (result.status === 400) return { ...aiUnspentOutcome(model), failure: AI_SITE_DATASET_NOT_WRITTEN_COPY }\n return { ...aiUnspentOutcome(model), review: limitReview(result.error) }\n }\n const facts = result.facts as { fields?: AiLayoutListingField[]; addressField?: string | null }\n return aiUnspentOutcome(model, {\n outputs: [\n {\n ...output(result.id, result.name, { fields: facts.fields ?? [], recordNames: [], addressField: null }, 0),\n note: aiSiteFormDatasetNote(input.forForm.name),\n },\n ],\n })\n }\n const generation = await generate({\n brief: job.brief,\n merchantWords: job.brief,\n name: creation.name,\n why: creation.why,\n fields: creation.fields,\n shownIn: input.shownIn,\n recordPages: input.recordPages,\n model,\n maxTokens: AI_SITE_DATASET_BUDGET.maxTokens(model),\n ...(signal ? { signal } : {}),\n })\n const spent = aiGenerationSpent(generation)\n if (generation.status === 'refused') return { ...spent, refused: true }\n if (generation.status === 'needs_input') return { ...spent, failure: generation.message }\n const designed = aiDatasetDraftContent(creation.name, generation.value, {\n recordPages: input.recordPages,\n ...((job.plan as AiJobPlan | null)?.language ? { language: (job.plan as AiJobPlan).language } : {}),\n })\n // What each record is filed under, which its photo and the sections that list it by its value read (AGL-3856).\n const category = aiSiteDatasetCategoryOf(generation.value)\n // A list a visitor looks at keeps its records' photos (AGL-3616): searched\n // in code, never asked of the model, so they cost no credits.\n const photos = input.pictures\n ? await photosFor({\n job,\n name: creation.name,\n names: generation.value.records.map((values) => values[0] ?? ''),\n ...(category ? { categories: category.values } : {}),\n pictures: input.pictures,\n ...(signal ? { signal } : {}),\n }).catch(() => [] as AiSiteDatasetRecordPhoto[])\n : []\n const content = input.pictures\n ? aiSiteDatasetContentWithPhotos(\n designed,\n generation.value.records.map((_values, index) => photos[index]?.src ?? null),\n generation.value.records.map((_values, index) => photos[index]?.alt ?? null),\n )\n : designed\n // The data plugin's own rules, before anything is written: content we\n // made that its model refuses is our failure, refunded.\n const checked = keeper.writer.check(content, { hostId: job.hostId })\n if (checked.ok === false) {\n console.error('ai site dataset: the dataset writer refused a dataset we made', { orgId: job.orgId, jobId: job.$id, problems: checked.problems })\n return { ...spent, failure: AI_SITE_DATASET_NOT_WRITTEN_COPY }\n }\n const result = await keeper.writer.write({\n orgId: job.orgId,\n hostId: job.hostId,\n uid: job.createdBy,\n org: (context.org ?? null) as Readonly<Record<string, unknown>> | null,\n now: context.now,\n id: job.$id,\n name: creation.name,\n content,\n })\n if (result.ok === false) {\n if (result.status === 400) return { ...spent, failure: AI_SITE_DATASET_NOT_WRITTEN_COPY }\n // The allowance, the role, the plan or the flag: the workspace's to change.\n return { ...spent, review: limitReview(result.error) }\n }\n const facts = result.facts as {\n fields?: AiLayoutListingField[]\n records?: number\n addressField?: string | null\n imageField?: string | null\n }\n const placed = photos.flatMap((photo) => (photo.placed ? [photo.placed] : []))\n const placedPhotos = photos.flatMap((photo) =>\n photo.placed && photo.width && photo.height\n ? [{ src: photo.placed, width: photo.width, height: photo.height, ...(photo.alt ? { alt: photo.alt } : {}) }]\n : [],\n )\n const proposal: AiSiteDatasetProposal = {\n fields: facts.fields ?? [],\n recordNames: generation.value.records.map((values) => values[0] ?? '').filter(Boolean).slice(0, 12),\n addressField: facts.addressField ?? null,\n ...(facts.imageField ? { imageField: facts.imageField } : {}),\n ...(placed.length ? { photos: placed } : {}),\n ...(placedPhotos.length ? { placedPhotos } : {}),\n sparseFields: aiDatasetSparseFields(generation.value, facts.fields ?? []),\n ...aiSiteDatasetGroupsOf(category, facts.fields ?? [], generation.value),\n }\n // Its records left on a starter, which the site start's late photo pass fills (AGL-3988).\n const starters = aiSiteDatasetStarterList({\n dataset: result.id,\n hostId: job.hostId,\n imageField: facts.imageField ?? null,\n fields: facts.fields ?? [],\n people: input.pictures === 'people',\n names: generation.value.records.map((values) => values[0] ?? ''),\n categories: category?.values ?? [],\n photos,\n })\n return {\n ...spent,\n outputs: [output(result.id, result.name, proposal, facts.records ?? generation.value.records.length)],\n ...(starters ? { sitePhotos: { pages: [], lists: [starters] } satisfies AiSitePhotos } : {}),\n }\n }\n}\n\n/**\n * A pictured list's records as the late photo pass reads them (AGL-3988),\n * where any of them holds a starter on a site with a stock library: each\n * record's name, category and photo\n * value in order, the library photo it shows as a media reference with its\n * size and words, and the picks the image hosts refused it. `null` where\n * every record shows a library photo, or the list keeps no photo field.\n */\nexport function aiSiteDatasetStarterList(input: {\n dataset: string\n hostId: string\n imageField: string | null\n fields: readonly AiLayoutListingField[]\n people: boolean\n names: readonly string[]\n categories: ReadonlyArray<string | null>\n photos: readonly AiSiteDatasetRecordPhoto[]\n}): AiSiteStarterList | null {\n // A site with no stock library keeps its starters, as it always has.\n if (!input.imageField || !input.photos.some((photo) => aiSiteIsStarterSrc(photo.src) && !photo.noLibrary)) return null\n const altField = input.fields.find((field) => field.name.trim().toLowerCase() === AI_SITE_DATASET_IMAGE_ALT_FIELD.toLowerCase())?.id\n return {\n dataset: input.dataset,\n imageField: input.imageField,\n ...(altField ? { altField } : {}),\n ...(input.people ? { people: true } : {}),\n records: input.names.map((name, index) => {\n const photo = input.photos[index]\n const value = photo?.src ?? ''\n const src = aiSiteIsStarterSrc(value) ? null : photo?.placed || mediaRefFromCdnPath(value) || null\n const category = input.categories[index]?.trim()\n return {\n name,\n ...(category ? { category } : {}),\n value,\n ...(src && photo?.width && photo.height\n ? { photo: { src, width: photo.width, height: photo.height, ...(photo.alt ? { alt: photo.alt } : {}) } }\n : {}),\n ...(photo?.refused ? { refused: photo.refused } : {}),\n }\n }),\n }\n}\n\nexport const runAiSiteDatasetUnit = createAiSiteDatasetRunner()\n\n/**\n * Whether a dataset may be created for this member on this site, asked before\n * its first pass so a refusal spends nothing; `null` admits. The data plugin\n * must run here (on for the workspace and the site, past its release flag),\n * and its writer says whether this member may make one now: the role, the\n * plan, the flag, the allowance.\n */\nexport async function aiSiteDatasetRefusal(\n context: Pick<AiJobStepContext, 'firestore' | 'org' | 'now'> & { job: Pick<AiJob, 'orgId' | 'hostId' | 'createdBy'> },\n deps: { admission?: typeof aiPluginDraftAdmissionRefusal; writerFor?: (resource: string) => ReturnType<typeof pluginResourceDraftWriter> } = {},\n): Promise<string | null> {\n const { job } = context\n if (!job.hostId) return 'Open the site first.'\n const writerFor = deps.writerFor ?? pluginResourceDraftWriter\n const admission: AiJobAdmissionContext = {\n firestore: context.firestore,\n orgId: job.orgId,\n hostId: job.hostId,\n inputs: {},\n org: context.org ?? null,\n uid: job.createdBy,\n }\n const refused = await (deps.admission ?? aiPluginDraftAdmissionRefusal)(admission, {\n kind: 'site',\n drafts: [{ resource: AI_SITE_DATASET_RESOURCE, label: DATA_PLUGIN_LABEL }],\n writerFor: (resource) => writerFor(resource)?.writer ?? null,\n ownerFor: (resource) => writerFor(resource)?.pluginId ?? null,\n now: context.now,\n })\n return refused?.error ?? null\n}\n\n/**\n * A site plan's dataset capability on this workspace (AGL-3616): where the\n * workspace's plan includes datasets, whether the data plugin runs here and\n * this member may create one now, and how many a start may make. A clause the\n * plan's turn completes is the reason where it may not.\n */\nexport async function aiSitePlanDatasetCapability(\n capabilities: AiPlanCapabilities,\n context: Parameters<typeof aiSiteDatasetRefusal>[0],\n deps: Parameters<typeof aiSiteDatasetRefusal>[1] = {},\n): Promise<AiPlanCapabilities> {\n if (!capabilities.create.dataset.allowed) return capabilities\n const refusal = await aiSiteDatasetRefusal(context, deps).catch((error: unknown) => {\n console.error('ai site plan: the dataset admission failed', { orgId: context.job.orgId, error })\n return 'datasets could not be checked just now'\n })\n const left = Math.min(AI_SITE_DATASETS_MAX, checkDatasetQuota(context.org as never, 0).limit)\n const dataset = refusal\n ? { allowed: false, left: 0, reason: `datasets cannot be created here: ${refusal.replace(/\\.$/, '')}` }\n : { allowed: true, left, reason: null }\n return { ...capabilities, create: { ...capabilities.create, dataset } }\n}\n\n/**\n * A `records` listing for each dataset that was made and that a section of the\n * plan names (AGL-3616). Its fields, where none are given, are read off the\n * site's inventory when the page is designed (`aiLayoutListingsWithDatasets`).\n */\nexport function aiDatasetListingsOf(\n datasets: ReadonlyArray<{\n id: string\n name: string\n records?: string[]\n fields?: AiLayoutListingField[]\n imageField?: string | null\n /** The record's page-address field, where the writer added one (AGL-3727). */\n addressField?: string | null\n /** What its records are filed under, by position as `records` (AGL-3921): a section named for one value lists its records alone. */\n groups?: { field: string; values: readonly string[] } | null\n }>,\n screens: readonly AiLayoutListingScreen[],\n): AiLayoutListing[] {\n return datasets.flatMap((dataset) => {\n const placements = aiLayoutRecordsPlacements(dataset, screens)\n if (!placements.length) return []\n // Each card links its record's own page where the plan makes one (AGL-3727).\n const recordBase = aiLayoutRecordBaseOf(dataset, screens)\n return [\n {\n id: aiLayoutListingId('records', dataset.id),\n kind: 'records' as const,\n name: dataset.name,\n records: dataset.records ?? [],\n datasetId: dataset.id,\n ...(dataset.fields?.length ? { fields: dataset.fields } : {}),\n // Its card leads with the record's photo (AGL-3616).\n ...(dataset.imageField ? { imageField: dataset.imageField } : {}),\n // The address is read off the site's inventory where the build does not know it yet.\n ...(recordBase ? { recordBase, ...(dataset.addressField ? { addressField: dataset.addressField } : {}) } : {}),\n placements,\n },\n ]\n })\n}\n\n/**\n * A `records` listing for each dataset the workspace already keeps that a\n * site start's plan reuses and a section names (AGL-3771), as a build lists\n * the ones it reuses (AGL-3747). A second site in a workspace reuses the\n * first one's menu: its plan names the dataset by id, the start listed only\n * the datasets it made, and the page was asked to \"place\" a dataset no block\n * can draw — the home's \"Del menú\" section was refused for showing none of\n * its six items, and the Menú page published with no menu. A dataset one of\n * the plan's forms writes into holds the site's submissions, and is never\n * listed on a page.\n */\nexport function aiSiteReusedDatasetListings(input: {\n plan: Pick<AiJobPlan, 'reuse' | 'create' | 'labels'>\n screens: readonly AiLayoutListingScreen[]\n /** The listings the start already has, whose datasets are not listed twice. */\n listed: ReadonlyArray<Pick<AiLayoutListing, 'datasetId'>>\n}): AiLayoutListing[] {\n const submissions = new Set(\n input.plan.create.flatMap((entry) => (entry.kind === 'form' && entry.writesTo && !isAiPlanNewRef(entry.writesTo) ? [entry.writesTo] : [])),\n )\n const listed = new Set(input.listed.map((listing) => listing.datasetId).filter(Boolean))\n const datasets = input.plan.reuse\n .filter((entry) => entry.kind === 'dataset' && !submissions.has(entry.id) && !listed.has(entry.id))\n .map((entry) => ({ id: entry.id, name: input.plan.labels?.[entry.id] || entry.id }))\n return aiDatasetListingsOf(datasets, input.screens)\n}\n\n/**\n * A SITE START NEVER SHOWS ANOTHER SITE'S RECORDS (AGL-3912).\n *\n * Datasets belong to the organization, and so do their records: neither\n * names the site it was written for, and a dataset outlives the site that\n * filled it (the data plugin keeps `visibleTo` and nothing else of a site). A\n * gym's start reused the workspace's \"Session packages\", \"Coaches\" and \"Gym\n * FAQs\", and published a deleted photographer's wedding packages and a\n * deleted studio's coach bio (\"Leads coaching at Ironline Strength Studio\")\n * with four broken photos; a photographer's start reused another\n * photographer's gallery and drew six broken covers.\n *\n * So a site start reuses a dataset only when its records are this site's to\n * show ({@link aiSiteDatasetIsThisSites}):\n * - it holds no records at all — an empty list, such as the one a form\n * writes its submissions to, is the same list on any site; or\n * - its scope names this site alone (`siteOnly`), so it was made for it; or\n * - this site already serves its records pages of their own (`recordBase`).\n * Anything else — records in a dataset shared with the workspace or with\n * other sites, and a dataset whose records could not be counted — was filled\n * for something else, and the plan is settled in code before the rules read\n * it ({@link aiSettleSiteForeignDatasets}): the reuse becomes a creation of\n * the same name and fields, designed from this site's brief with photos of\n * its own, and every section, record template and form that named it names\n * the creation. Where this job may create no dataset, the reuse comes off\n * instead and each section writes its items out. Never a refusal, and\n * nothing a member is asked.\n *\n * An Assist change to a site that exists keeps reusing what the site lists:\n * this is a site start's rule, and only its plan is settled by it.\n */\nexport function aiSiteDatasetIsThisSites(row: Pick<AiInventoryDataset, 'records' | 'siteOnly' | 'recordBase'>): boolean {\n return row.records === 0 || row.siteOnly === true || Boolean(row.recordBase)\n}\n\n/** A planned field that is a record's page address, which the writer adds itself. */\nconst ADDRESS_FIELD_NAME = /^(?:page )?(?:address|slug|url|link)$/i\n\n/** The fields a dataset is made again with: its own, less the photo, its description and the page address the writer adds. */\nfunction remadeFields(row: AiInventoryDataset): string[] {\n const ids = row.fieldIds ?? []\n return row.fields\n .filter((name, index) => {\n const id = ids[index]\n if (id && (id === row.imageField || id === row.addressField)) return false\n if (IMAGE_FIELD_NAME.test(name.trim()) || ADDRESS_FIELD_NAME.test(name.trim())) return false\n return name.trim().toLowerCase() !== AI_SITE_DATASET_IMAGE_ALT_FIELD.toLowerCase()\n })\n .slice(0, AI_BUILD_PLAN_LIMITS.fields)\n}\n\n/**\n * A site start's plan with every dataset it reuses that holds another\n * site's records made again for this one (AGL-3912): each the inventory marks\n * `foreign` ({@link aiSiteInventoryWithRecordCounts}, by\n * {@link aiSiteDatasetIsThisSites}). The creation keeps the dataset's name,\n * which rule 7 does not hold against it as a duplicate. Pure; a plan that\n * reuses none comes back as it was.\n */\nexport function aiSettleSiteForeignDatasets(\n plan: AiBuildPlan,\n inventory: Pick<AiSiteInventory, 'datasets'> | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n const rows = new Map((inventory?.datasets ?? []).map((row) => [row.id, row]))\n const foreign = plan.reuse.filter((entry) => entry.kind === 'dataset' && rows.get(entry.id)?.foreign === true)\n if (!foreign.length) return plan\n const creatable = !capabilities || capabilities.create.dataset.allowed\n const taken = new Map<string, AiBuildPlanCreate | null>([\n ...plan.create.map((entry) => [entry.name.trim().toLowerCase(), entry] as const),\n ...(plan.items ?? []).map((item) => [item.name.trim().toLowerCase(), null] as const),\n ])\n // Each foreign dataset's id → the `new:` reference that replaces it, or `null` where it comes off.\n const replaced = new Map<string, string | null>()\n const added: AiBuildPlanCreate[] = []\n for (const entry of foreign) {\n const row = rows.get(entry.id) as AiInventoryDataset\n const base = row.name.trim() || 'Records'\n if (!creatable) {\n replaced.set(entry.id, null)\n continue\n }\n // The plan already makes one of that name: that one is this site's.\n const same = taken.get(base.toLowerCase())\n if (same?.kind === 'dataset') {\n replaced.set(entry.id, `${AI_PLAN_NEW_REF_PREFIX}${same.name}`)\n continue\n }\n let name = base\n for (let n = 2; taken.has(name.toLowerCase()); n += 1) name = `${base} ${n}`\n const creation: AiBuildPlanCreate = {\n kind: 'dataset',\n name,\n why: entry.purpose || `Lists ${base} on this site.`,\n duplicateOf: null,\n fields: remadeFields(row),\n }\n added.push(creation)\n taken.set(name.toLowerCase(), creation)\n replaced.set(entry.id, `${AI_PLAN_NEW_REF_PREFIX}${name}`)\n }\n const swap = (ref: string): string | null => (replaced.has(ref) ? (replaced.get(ref) ?? null) : ref)\n return {\n ...plan,\n reuse: plan.reuse.filter((entry) => !(entry.kind === 'dataset' && replaced.has(entry.id))),\n create: [\n ...plan.create.map((entry) => {\n if (entry.kind !== 'form' || !entry.writesTo || !replaced.has(entry.writesTo)) return entry\n const writesTo = swap(entry.writesTo)\n if (writesTo) return { ...entry, writesTo }\n // A form whose dataset comes off sends its submissions to the Inbox only.\n const rest = { ...entry }\n delete rest.writesTo\n return rest\n }),\n ...added,\n ],\n screens: plan.screens.map((screen) => {\n // A record template of a dataset made again shows the new one; of one that comes off, it is a page of its own.\n const record =\n screen.record && replaced.has(screen.record.dataset) ? { record: swap(screen.record.dataset) } : null\n const sections = screen.sections.map((section) => {\n if (!section.uses.some((ref) => replaced.has(ref))) return section\n const uses = section.uses.flatMap((ref) => {\n const next = swap(ref)\n return next ? [next] : []\n })\n // A list that comes off is written out on the page, as fewer items than a dataset binds.\n const dropped = section.uses.some((ref) => replaced.has(ref) && !replaced.get(ref))\n return { ...section, uses, ...(dropped ? { items: Math.min(section.items, AI_TYPED_LIST_MIN_ITEMS - 1) } : {}) }\n })\n return {\n ...screen,\n ...(record && screen.record ? { record: record.record ? { ...screen.record, dataset: record.record } : null } : {}),\n sections,\n }\n }),\n }\n}\n\n/** How a dataset's records are counted: the data plugin's index, which answers `facts.records`. */\nexport type AiDatasetRecordCounter = (request: { orgId: string; id: string }) => Promise<number | null>\n\n/** The production counter: the data plugin's `dataset` index, read one dataset at a time. */\nexport const aiDatasetRecordCount: AiDatasetRecordCounter = async ({ orgId, id }) => {\n const index = pluginRecordIndex('dataset')?.index\n if (!index) return null\n const found = await index.get({ orgId, id })\n const records = found?.facts['records']\n return typeof records === 'number' && Number.isFinite(records) ? records : null\n}\n\n/**\n * A site start's inventory with how many records each dataset holds\n * (AGL-3912), and each whose records are not this site's to show\n * ({@link aiSiteDatasetIsThisSites}) marked `foreign`. The count is asked\n * once per plan, of every dataset the site sees, all at once; a count that\n * fails leaves `records` out, which reads as another site's. Never throws.\n */\nexport async function aiSiteInventoryWithRecordCounts(\n inventory: AiSiteInventory | null,\n orgId: string,\n count: AiDatasetRecordCounter = aiDatasetRecordCount,\n): Promise<AiSiteInventory | null> {\n if (!inventory?.datasets.length) return inventory\n const counts = await Promise.all(\n inventory.datasets.map((row) =>\n count({ orgId, id: row.id }).catch((error: unknown) => {\n console.warn('ai site plan: a dataset’s records could not be counted', { orgId, id: row.id, error: String(error) })\n return null\n }),\n ),\n )\n return {\n ...inventory,\n datasets: inventory.datasets.map((row, index) => {\n const records = counts[index]\n const counted = typeof records === 'number' ? { ...row, records } : row\n return aiSiteDatasetIsThisSites(counted) ? counted : { ...counted, foreign: true as const }\n }),\n }\n}\n\n/**\n * The site's datasets a layout or a page unit is handed (AGL-3616), each a\n * `records` listing with the sections of the plan's pages that name it, once\n * its unit wrote it. A dataset not yet written, or one that failed, lists\n * nowhere: the pages built without it write the items out.\n */\nexport function aiSiteDatasetListings(input: {\n outputs: readonly AiJobOutput[]\n datasets: ReadonlyArray<Pick<AiBuildPlanCreate, 'name'>>\n screens: readonly AiLayoutListingScreen[]\n /** The ids each dataset's unit delivered, by plan name lowercased. */\n delivered: ReadonlyMap<string, string>\n}): AiLayoutListing[] {\n const made = input.datasets.flatMap((dataset) => {\n const id = input.delivered.get(dataset.name.trim().toLowerCase())\n const output = id\n ? input.outputs.find((entry) => entry.resource === 'draft' && entry.draftResource === AI_SITE_DATASET_RESOURCE && entry.id === id)\n : undefined\n if (!id || !output) return []\n const proposal = proposalOf(output)\n return [\n {\n id,\n // Placed by the name the plan's sections gave it.\n name: dataset.name,\n records: proposal.recordNames,\n // The address field is the record page's, never a card's words; the\n // photo is the card's picture, never its words; a field most records\n // leave empty is no card's either (AGL-3616).\n fields: proposal.fields.filter(\n (field, index) =>\n field.id !== proposal.addressField &&\n field.id !== proposal.imageField &&\n (index === 0 || !proposal.sparseFields?.includes(field.id)),\n ),\n imageField: proposal.imageField ?? null,\n addressField: proposal.addressField,\n groups: proposal.groups ?? null,\n },\n ]\n })\n return aiDatasetListingsOf(made, input.screens)\n}\n\n/** The library photos the site's datasets' records show (AGL-3616), which a page does not place again. */\nexport function aiSiteDatasetPlacedPhotos(outputs: readonly AiJobOutput[]): string[] {\n return [\n ...new Set(\n outputs\n .filter((output) => output.resource === 'draft' && output.draftResource === AI_SITE_DATASET_RESOURCE)\n .flatMap((output) => proposalOf(output).photos ?? []),\n ),\n ]\n}\n\n/** The same photos with their size and words (AGL-3988), which a page's picture the library fails takes before any starter. */\nexport function aiSiteDatasetPlacedPhotoDetails(outputs: readonly AiJobOutput[]): AiLayoutPicturePhoto[] {\n const seen = new Set<string>()\n return outputs\n .filter((output) => output.resource === 'draft' && output.draftResource === AI_SITE_DATASET_RESOURCE)\n .flatMap((output) => aiStockJobPhotosOf((output.proposal as { placedPhotos?: unknown } | null)?.placedPhotos))\n .filter((photo) => !seen.has(photo.src) && Boolean(seen.add(photo.src)))\n}\n\n/** What a page is told about the datasets built before it. */\nexport function aiSiteDatasetBriefLines(outputs: readonly AiJobOutput[]): string[] {\n const datasets = outputs.filter((output) => output.resource === 'draft' && output.draftResource === AI_SITE_DATASET_RESOURCE)\n return datasets.flatMap((output) => {\n const names = proposalOf(output).recordNames\n return names.length\n ? [`This site's dataset “${output.label}” holds: ${names.map((name) => `“${name}”`).join(', ')}. Where a page names one, name it as written; never name one that is not in this list.`]\n : []\n })\n}\n"],"names":["mediaRefFromCdnPath","checkDatasetQuota","pluginResourceDraftWriter","pluginRecordIndex","AI_BUILD_PLAN_LIMITS","AI_PLAN_NEW_REF_PREFIX","isAiPlanNewRef","AI_TYPED_LIST_MIN_ITEMS","AI_SITE_DATASETS_MAX","AI_STEP_TIERS","aiModelForStep","AI_DATASET_MAX_TOKENS","AI_DATASET_STEP","aiDatasetDraftContent","generateAiDataset","aiLayoutListingId","aiLayoutRecordBaseOf","aiLayoutRecordsPlacements","aiLayoutNeutralStarterRun","aiLayoutSeedNumber","aiLayoutStarterPhotos","aiSiteWords","aiSiteIsStarterSrc","aiOriginJobId","aiSiteProductPhotoSrc","aiLayoutStockPhotoSource","aiStockJobPhotosOf","aiStockPhotoWordsOf","aiStockRecordScene","aiStockStem","AI_DATASET_DRAFT_RESOURCE","aiJobStepBudget","aiGenerationSpent","aiUnspentOutcome","aiPluginDraftAdmissionRefusal","AI_SITE_DATASET_RESOURCE","DATA_PLUGIN_LABEL","AI_SITE_DATASET_INPUT","READ_ONLY_LIST","PEOPLE_LIST","PICTURED_LIST","PICTURED_SECTION","aiSiteDatasetPicturesOf","dataset","sections","length","own","name","test","some","section","AI_SITE_DATASET_NOT_WRITTEN_COPY","aiSiteDatasetNote","records","AI_SITE_RECORD_PAGE_NOTE","AI_SITE_DATASET_WRITES_MS","AI_SITE_DATASET_BUDGET","tier","maxTokens","lookups","ownReadsMs","str","value","trim","namesDataset","ref","slice","indexOf","toLowerCase","aiSitePlanDatasets","plan","create","filter","entry","kind","aiSiteDatasetInputOf","screens","shownIn","sectionNames","screen","uses","push","title","items","recordPages","record","form","find","writesTo","pictures","forForm","fields","AI_SITE_FORM_DATASET_FIELDS_MAX","aiSiteRecordTemplateOf","datasetInputOf","job","raw","inputs","Array","isArray","map","Boolean","FORM_DATASET_FIELD_TYPES","aiSiteDatasetFieldName","planned","words","replace","charAt","toUpperCase","aiSiteFormDatasetContent","specs","seen","Set","spec","at","lastIndexOf","typed","type","includes","fieldName","has","add","aiSiteFormDatasetNote","limitReview","message","reason","findings","AI_SITE_DATASET_PHOTOS_BUDGET_MS","AI_SITE_DATASET_IMAGE_FIELD","AI_SITE_DATASET_IMAGE_ALT_FIELD","IMAGE_FIELD_NAME","aiSiteDatasetRecordPhotos","input","names","hostId","src","placed","people","slots","index","imageId","frameId","iconId","alt","aspect","sectionIndex","role","standIn","categories","category","seed","$id","found","report","refused","Map","library","source","stockPhotos","uid","createdBy","business","about","brief","jobId","searches","signal","budgetMs","error","console","warn","String","copied","_slot","photos","aiSiteDatasetRecordsFromOwn","starters","photo","stock","width","height","get","noLibrary","others","options","listed","flatMap","shownHere","all","findIndex","one","span","turn","shows","scene","stems","split","stem","shun","fill","order","filled","beside","apart","same","subject","pool","besideLast","list","rank","pick","sort","a","b","forward","_record","backward","repeats","aiSiteDatasetContentWithPhotos","content","alts","named","field","withImage","described","altName","nextFields","next","CATEGORY_FIELD","aiSiteDatasetCategoryOf","column","entries","values","distinct","size","aiSiteDatasetGroupsOf","written","designed","id","undefined","groups","aiDatasetSparseFields","idOf","proposalOf","output","proposal","recordNames","addressField","imageField","startsWith","sparseFields","createAiSiteDatasetRunner","deps","generate","writerFor","photosFor","context","facts","firestore","model","modelFor","creation","keeper","failure","host","collection","doc","hostSubdomain","resource","draftResource","label","note","writer","read","again","outputs","checked","check","ok","orgId","problems","result","write","org","now","status","review","generation","merchantWords","why","spent","language","catch","_values","placedPhotos","aiSiteDatasetStarterList","sitePhotos","pages","lists","altField","runAiSiteDatasetUnit","aiSiteDatasetRefusal","admission","drafts","ownerFor","pluginId","aiSitePlanDatasetCapability","capabilities","allowed","refusal","left","Math","min","limit","aiDatasetListingsOf","datasets","placements","recordBase","datasetId","aiSiteReusedDatasetListings","submissions","listing","reuse","labels","aiSiteDatasetIsThisSites","row","siteOnly","ADDRESS_FIELD_NAME","remadeFields","ids","fieldIds","aiSettleSiteForeignDatasets","inventory","rows","foreign","creatable","taken","item","replaced","added","base","set","n","purpose","duplicateOf","swap","rest","dropped","aiDatasetRecordCount","Number","isFinite","aiSiteInventoryWithRecordCounts","count","counts","Promise","counted","aiSiteDatasetListings","made","delivered","aiSiteDatasetPlacedPhotos","aiSiteDatasetPlacedPhotoDetails","aiSiteDatasetBriefLines","join"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/jobs/ai-job-site-datasets.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 { mediaRefFromCdnPath } from '@aglyn/aglyn/app-utils/media-ref'\nimport { checkDatasetQuota } from '@aglyn/aglyn/app-utils/plan-entitlements'\nimport { pluginResourceDraftWriter } from '@aglyn/aglyn/plugin-manager/plugin-resource-drafts'\nimport { pluginRecordIndex } from '@aglyn/aglyn/plugin-manager/plugin-record-index'\nimport {\n AI_BUILD_PLAN_LIMITS,\n AI_PLAN_NEW_REF_PREFIX,\n isAiPlanNewRef,\n type AiBuildPlan,\n type AiBuildPlanCreate,\n type AiBuildPlanScreen,\n} from '../model/ai-build-plan'\nimport type { AiInventoryDataset, AiSiteInventory } from '../model/ai-site-inventory'\nimport { AI_TYPED_LIST_MIN_ITEMS } from '../runtime/ai-doctrine-validators'\nimport type { AiJob, AiJobOutput, AiJobPlan } from '../model/ai-jobs.types'\nimport type { AiPlanCapabilities } from '../model/ai-plan-capabilities'\nimport { AI_SITE_DATASETS_MAX } from '../model/ai-site-job'\nimport { AI_STEP_TIERS } from '../providers/catalog'\nimport { aiModelForStep } from '../providers/routing'\nimport {\n AI_DATASET_MAX_TOKENS,\n AI_DATASET_PLACEHOLDER_CODE,\n AI_DATASET_STEP,\n aiDatasetDraftContent,\n aiDatasetListedAsPast,\n aiDatasetRealRecords,\n aiDatasetSampleDates,\n aiDatasetWithoutPlaceholders,\n generateAiDataset,\n type AiDatasetSplit,\n} from '../runtime/ai-dataset-generation'\nimport type { AiDataset } from '../tools/ai-dataset-tool'\nimport {\n aiLayoutListingId,\n aiLayoutRecordBaseOf,\n aiLayoutRecordsPlacements,\n type AiLayoutListing,\n type AiLayoutListingField,\n type AiLayoutListingScreen,\n} from '../layout-language/ai-layout-listings'\nimport {\n aiLayoutNeutralStarterRun,\n aiLayoutSeedNumber,\n aiLayoutStarterPhotos,\n type AiLayoutPicturePhoto,\n type AiLayoutPictureReport,\n type AiLayoutPictureSlot,\n} from '../layout-language/ai-layout-pictures'\nimport { aiSiteWords } from '../model/ai-site-job'\nimport { aiSiteIsStarterSrc, type AiSitePhotos, type AiSiteStarterList, type AiStockRefusedPicks } from '../model/ai-site-photos'\nimport type { AiJobAdmissionContext } from './ai-job-admission'\nimport { aiOriginJobId } from './ai-job-draft-ids'\nimport { aiSiteProductPhotoSrc } from './ai-job-site-content'\nimport {\n aiLayoutStockPhotoSource,\n aiStockJobPhotosOf,\n aiStockPhotoWordsOf,\n aiStockRecordScene,\n aiStockStem,\n} from './ai-layout-stock-photos'\nimport { AI_DATASET_DRAFT_RESOURCE } from './ai-build-unit-outcome'\nimport { aiJobStepBudget } from './ai-job-budget'\nimport { aiGenerationSpent, aiUnspentOutcome } from './ai-job-generation'\nimport { aiPluginDraftAdmissionRefusal } from './ai-job-plugin-drafts'\nimport type { AiJobStepContext, AiJobStepOutcome, AiJobStepRunner } from './ai-job-text-step'\n\n/**\n * A SITE START'S DATASETS (AGL-3616): \"Aglyn AI can also use/create datasets\n * too for whatever it needs\" (Zach, 2026-10-10).\n *\n * A site whose content is a list of like things — a restaurant's menu, a\n * studio's team, a contractor's services, a photographer's portfolio, an\n * events list, its questions and answers — keeps it as a DATASET, the way the\n * docs teach a person to: the owner edits one record and every page listing\n * it follows. On a workspace that may create datasets, the site plan creates\n * one for such content (`create`, kind `dataset`) and names it in the `uses`\n * of each section that lists it. The scaffold then builds each dataset as a\n * unit of its own, after the layout and before the form (which may write\n * its submissions to one) and the pages:\n *\n * - DESIGNED by the `submit_dataset` generation (`ai-dataset-generation.ts`):\n * the planned fields typed, at most a few more, and 3 to 12 records seeded\n * from the brief. Nothing anybody did not say: no review, testimonial,\n * rating, quote or person's name, no price the brief does not state.\n * - WRITTEN by the data plugin's `dataset` writer — this plugin never names\n * the datasets collection — with every rule the console's datasets route\n * has: the member's role and `data.manage`, `release_data_store`,\n * `dataStore` (Starter and up), `datasetsPerOrg` counted inside the create,\n * `recordsPerDataset` and the storage band. Each seeded record's\n * reference and filter index is that writer's to stamp, with the data\n * plugin's `datasetIntegrityFields` (`server/dataset-drafts.ts`), so this\n * file writes no record of its own: its `'records'` is a listing's kind and\n * its `values` a section group's.\n * - PICTURED where the plan lists it the way a gallery is listed (Zach,\n * 2026-10-10: a ceramic artist's \"Selected work\" came back as text-only\n * cards, where it had been an image-led gallery): a portfolio's pieces, a\n * team, a menu, classes and events, and services or offerings whose\n * section says it shows them in pictures (`aiSiteDatasetPicturesOf`). Such\n * a dataset gets an Image field, and each record a stock photo of its own\n * name in the site's craft, copied into the site's library — never one the\n * job already placed, else a starter photo — searched in code, so it\n * costs no credits (`aiSiteDatasetRecordPhotos`).\n * - LISTED by the pages built after it: each section naming it repeats over\n * the dataset (`aiSiteDatasetListings`, a `records` listing the layout\n * compiler draws, its card led by the record's photo where it has one),\n * and a page the plan made its record template binds its fields by id,\n * its photo the record's, and keeps the address field the writer added.\n *\n * Where datasets cannot be created — the Free taste, Starter's two used up,\n * the data store not released — the plan is told so and creates none, so its\n * sections write the items out. A dataset unit that fails or is refused\n * leaves the pages that list it built without it (they say so), and its\n * record page is not built.\n */\n\n/** The most datasets one site start creates. */\nexport { AI_SITE_DATASETS_MAX } from '../model/ai-site-job'\n\n/** The resource the data plugin's writer is registered under. */\nexport const AI_SITE_DATASET_RESOURCE = AI_DATASET_DRAFT_RESOURCE\n\n/** What the site's plugin list calls the plugin, for \"Turn on Data for this site\". */\nconst DATA_PLUGIN_LABEL = 'Data'\n\n/** The input a dataset unit's own job carries what it needs in. */\nexport const AI_SITE_DATASET_INPUT = 'siteDataset'\n\n/** What a dataset unit's job is told beside its creation. */\nexport interface AiSiteDatasetInput {\n /** The sections that list it, by page: \"Menu › Our dishes (12 items)\". */\n shownIn: string[]\n /** Whether a page of the plan is its record template. */\n recordPages: boolean\n /**\n * The form of the plan that writes its submissions to it (AGL-3616), by\n * name, with that form's planned fields; absent where no form does.\n */\n forForm?: { name: string; fields: string[] }\n /**\n * Whether its records carry a photo, and of what (AGL-3616): `things` for a\n * portfolio's pieces, a menu, classes; `people` for a team. Absent for a\n * list a visitor reads rather than looks at: questions, steps, hours.\n */\n pictures?: AiSiteDatasetPictures\n /**\n * The sections of one page that each list part of it, and the value of a\n * planned field each lists (AGL-4065, {@link aiSiteDatasetSplitOf}):\n * absent where no page lists it twice.\n */\n split?: AiDatasetSplit\n}\n\n/** What a dataset's records are pictured as: things or people. */\nexport type AiSiteDatasetPictures = 'things' | 'people'\n\n/** A list of questions, voices or plain facts: read, never pictured. */\nconst READ_ONLY_LIST =\n /\\b(faqs?|questions?|q ?& ?a|answers?|testimonials?|reviews?|quotes?|voices|hours|opening|steps?|process|policies|policy|terms|stats?|numbers|figures|milestones|timeline|values|benefits|reasons|features|requirements|checklist|ingredients|donations?|needs|partners|sponsors|supporters|roles|positions|jobs|openings)\\b/i\n/** A list of people: its photos are of the business's people. */\nconst PEOPLE_LIST =\n /\\b(team|staff|people|crew|instructors?|teachers?|tutors?|stylists?|barbers?|therapists?|coaches?|trainers?|chefs?|doctors?|dentists?|hygienists?|practitioners?|artists?|musicians?|performers?|speakers?|founders?|members?)\\b/i\n/** A list a visitor looks at before reading: pictured wherever it is listed. */\nconst PICTURED_LIST =\n /\\b(portfolio|pieces?|works?|projects?|gallery|galleries|collections?|series|menus?|dishes|plates|drinks|cocktails|wines?|beers?|coffees?|pastries|cakes|products?|items|events?|classes|class|workshops?|courses?|retreats?|tours?|trips?|adventures?|experiences?|rooms?|suites?|cabins?|properties|listings|homes|venues?|spaces?|recipes?|artworks?|paintings?|prints?|photos?|photographs?|designs?|commissions?|builds?|vehicles?|animals?|pets?|plants?|flowers?|bouquets?|arrangements?|case studies)\\b/i\n/** A section that says it shows its items in pictures: a gallery, a grid of photos, tiles. */\nconst PICTURED_SECTION =\n /\\b(gallery|galleries|grid|images?|photos?|photographs?|pictures?|lightbox|portfolio|showcase|tiles?|visuals?|lookbook|carousel|slideshow|mosaic|thumbnails?)\\b/i\n\n/**\n * Whether a dataset's records carry a photo, read off the plan (AGL-3616):\n * its name and the names of the sections that list it. Questions, voices and\n * plain facts never; people as people; a list a visitor looks at — pieces,\n * dishes, classes, events, rooms — always; any other list (services,\n * offerings, programs) only where a section that lists it says it shows them\n * in pictures, or names one of those. A dataset no page lists is not\n * pictured. Pure.\n */\nexport function aiSiteDatasetPicturesOf(\n dataset: Pick<AiBuildPlanCreate, 'name'>,\n sections: readonly string[],\n): AiSiteDatasetPictures | null {\n if (!sections.length) return null\n const own = dataset.name\n if (READ_ONLY_LIST.test(own)) return null\n if (PEOPLE_LIST.test(own)) return 'people'\n if (PICTURED_LIST.test(own)) return 'things'\n if (sections.some((section) => READ_ONLY_LIST.test(section) && !PICTURED_SECTION.test(section))) return null\n if (sections.some((section) => PEOPLE_LIST.test(section))) return 'people'\n if (sections.some((section) => PICTURED_LIST.test(section) || PICTURED_SECTION.test(section))) return 'things'\n return null\n}\n\n/** What a dataset row says when its design could not be written: our failure, refunded. */\nexport const AI_SITE_DATASET_NOT_WRITTEN_COPY = 'This dataset could not be added this time.'\n\n/** The note a written dataset carries on the job's page. */\nexport function aiSiteDatasetNote(records: number): string {\n return `${records} ${records === 1 ? 'record' : 'records'} to start, in Data. Edit them there and every page that lists them follows.`\n}\n\n/**\n * The note a dataset that starts with samples carries (AGL-4065): the brief\n * gave no entries for the list, so its rows are samples to replace.\n */\nexport function aiSiteDatasetSampleNote(records: number, samples: number): string {\n return samples >= records\n ? `${records} sample ${records === 1 ? 'record' : 'records'} to start, made because the brief gave none: replace them with your own in Data, and every page that lists them follows.`\n : `${records} records to start, ${samples} of them ${samples === 1 ? 'a sample' : 'samples'} to replace with your own, in Data. Edit them there and every page that lists them follows.`\n}\n\n/**\n * The note a dataset written with no records carries (AGL-4065): where its\n * rows go. A list the brief gives no entries for starts with samples\n * (`AI_DATASET_LIST_WITHOUT_ENTRIES`), so this is the one whose samples were\n * placeholders even after the re-ask, or a start that makes none. Its band\n * stays on every page that lists it — its heading, one honest line, and the\n * live list the owner's first row fills.\n */\nexport function aiSiteDatasetEmptyNote(name: string): string {\n return `No ${name} rows yet: add them in Data › ${name}, and every page that lists them follows.`\n}\n\n/** The note a record template's row adds: the binding is the member's to save (rule 13). */\nexport const AI_SITE_RECORD_PAGE_NOTE =\n 'A page per record is drafted, not live: open Page Properties → Record pages to save it.'\n\n/** ASSUMED: what one dataset pass reads and writes beside its generation: the site, the writer's reads and its transaction. */\nexport const AI_SITE_DATASET_WRITES_MS = 2_000\n\n/** One dataset's pass: its generation and re-ask at its ceiling, and its writes. */\nexport const AI_SITE_DATASET_BUDGET = aiJobStepBudget({\n tier: AI_STEP_TIERS[AI_DATASET_STEP],\n maxTokens: AI_DATASET_MAX_TOKENS,\n lookups: 0,\n ownReadsMs: AI_SITE_DATASET_WRITES_MS,\n})\n\nconst str = (value: unknown): string => (typeof value === 'string' ? value.trim() : '')\n\n/** The plan's reference to a dataset as a section names it: `new:<name>`, compared lowercased. */\nfunction namesDataset(ref: string, name: string): boolean {\n return isAiPlanNewRef(ref) && ref.slice(ref.indexOf(':') + 1).trim().toLowerCase() === name.trim().toLowerCase()\n}\n\n/** The plan's datasets, in plan order, at most the most a start creates. */\nexport function aiSitePlanDatasets(plan: Pick<AiJobPlan, 'create'>): AiBuildPlanCreate[] {\n return plan.create.filter((entry) => entry.kind === 'dataset').slice(0, AI_SITE_DATASETS_MAX)\n}\n\n/** Where the plan lists a dataset, in words its design reads, whether a page is its record template, and the form that writes to it. */\nexport function aiSiteDatasetInputOf(\n dataset: Pick<AiBuildPlanCreate, 'name'> & Partial<Pick<AiBuildPlanCreate, 'fields'>>,\n screens: readonly AiBuildPlanScreen[],\n create: readonly AiBuildPlanCreate[] = [],\n): AiSiteDatasetInput {\n const shownIn: string[] = []\n const sectionNames: string[] = []\n let split: AiDatasetSplit | null = null\n for (const screen of screens) {\n const here: string[] = []\n for (const section of screen.sections) {\n if (!section.uses.some((ref) => namesDataset(ref, dataset.name))) continue\n shownIn.push(`${screen.title} › ${section.name}${section.items ? ` (${section.items} items)` : ''}`)\n sectionNames.push(section.name)\n here.push(section.name)\n }\n // A page that lists it twice lists part of it in each (AGL-4065).\n split ??= aiSiteDatasetSplitOf({ name: dataset.name, fields: dataset.fields ?? [] }, here)\n }\n const recordPages = screens.some((screen) => !!screen.record && namesDataset(screen.record.dataset, dataset.name))\n const form = create.find((entry) => entry.kind === 'form' && !!entry.writesTo && namesDataset(entry.writesTo, dataset.name))\n // A form's dataset holds its submissions: nobody's photo.\n const pictures = form ? null : aiSiteDatasetPicturesOf(dataset, sectionNames)\n return {\n shownIn: shownIn.slice(0, 8),\n recordPages,\n ...(form ? { forForm: { name: form.name, fields: form.fields.slice(0, AI_SITE_FORM_DATASET_FIELDS_MAX) } } : {}),\n ...(pictures ? { pictures } : {}),\n ...(split && !form ? { split } : {}),\n }\n}\n\n// ── Two lists of one dataset on one page (AGL-4065) ─────────────────────\n\n/** A planned field that can tell a page's lists of one dataset apart: a status, a stage, a category. */\nconst SPLIT_FIELD =\n /^(?:status|state|stage|timing|when|category|categories|type|kind|group|section|season|period|collection|series|occasion)$/i\n\n/** Words a section's name frames its records with, which name no value of theirs. */\nconst SPLIT_FRAMING = new Set(\n 'a an and the of our my your for with in at to by from all more list lists see view this these those here every each recent selected featured gallery galleries photos pictures cards grid section'.split(\n ' ',\n ),\n)\n\n/** A planned field's name without the type a form's dataset may give it: \"Status:text\" is \"Status\". */\nconst plainField = (spec: string) => {\n const at = spec.lastIndexOf(':')\n return (at > 0 ? spec.slice(0, at) : spec).trim()\n}\n\n/** A word as a split compares it: lowercase, a plural's \"-s\" dropped. */\nconst splitStem = (word: string) => {\n const lower = word.toLowerCase()\n return lower.length > 3 && lower.endsWith('s') && !lower.endsWith('ss') ? lower.slice(0, -1) : lower\n}\n\n/**\n * The value of a dataset's planned field each of a page's sections lists\n * (AGL-4065), where the page lists the dataset in two sections or more: the\n * words of each section's name that are not the dataset's own (its name, its\n * fields) nor framing — \"Upcoming races\" and \"Past results\" over \"Race\n * events\", whose fields include Result and Status, are \"Upcoming\" and\n * \"Past\". `null` where the dataset plans no field that files its records\n * (a Status, a Category, a Type…), or a section names no value of its own,\n * or two name the same. Pure.\n */\nexport function aiSiteDatasetSplitOf(\n dataset: { name: string; fields: readonly string[] },\n sections: readonly string[],\n): AiDatasetSplit | null {\n if (sections.length < 2) return null\n const field = dataset.fields.map(plainField).find((name) => SPLIT_FIELD.test(name))\n if (!field) return null\n const own = new Set(\n [dataset.name, ...dataset.fields.map(plainField)].flatMap((text) => text.split(/[^\\p{L}\\p{N}]+/u).filter(Boolean).map(splitStem)),\n )\n const values = sections.map((section) => {\n const words = section.split(/\\s+/).filter(Boolean)\n const named = (word: string) => {\n const stem = splitStem(word.replace(/[^\\p{L}\\p{N}-]+/gu, ''))\n return Boolean(stem) && !own.has(stem) && !SPLIT_FRAMING.has(stem)\n }\n // The value is the run of the name's words between its framing at either end.\n let start = 0\n let end = words.length\n while (start < end && !named(words[start] as string)) start += 1\n while (end > start && !named(words[end - 1] as string)) end -= 1\n const kept = words.slice(start, end).join(' ').replace(/[^\\p{L}\\p{N}]+$/u, '')\n return kept && kept.split(' ').length <= 3 ? kept.charAt(0).toUpperCase() + kept.slice(1) : null\n })\n if (values.some((value) => !value)) return null\n const distinct = new Set(values.map((value) => (value as string).toLowerCase()))\n if (distinct.size !== values.length) return null\n return { field, sections: [...sections], values: values as string[] }\n}\n\n/**\n * A site start's plan with each page that lists one of its new datasets in\n * two sections or more, where nothing can tell those sections' records apart\n * ({@link aiSiteDatasetSplitOf}), listing it in one (AGL-4065): the first\n * section keeps its place and takes the others' names and the most items\n * any of them planned, and the others come off. Two lists of one dataset on\n * one page would otherwise show the same records twice: the platform's\n * repeat can filter by a field's value, and has no \"the next five\". A plan\n * that needs no fold comes back as it was. Pure.\n */\nexport function aiSettlePlanSplitListings<P extends Pick<AiBuildPlan, 'screens' | 'create'>>(plan: P): P {\n const datasets = plan.create.filter((entry) => entry.kind === 'dataset')\n if (!datasets.length) return plan\n let changed = false\n const screens = plan.screens.map((screen) => {\n let sections = screen.sections\n for (const dataset of datasets) {\n const listing = sections.flatMap((section, index) => (section.uses.some((ref) => namesDataset(ref, dataset.name)) ? [index] : []))\n if (listing.length < 2) continue\n const names = listing.map((index) => sections[index]?.name ?? '')\n if (aiSiteDatasetSplitOf({ name: dataset.name, fields: dataset.fields }, names)) continue\n const [first, ...rest] = listing as [number, ...number[]]\n const joined = names.reduce((all, name, at) => {\n // A name's first letter is lowered after the first, unless it opens an acronym (\"ATV parts\").\n const said = /^\\p{Lu}\\p{Ll}/u.test(name) ? name.charAt(0).toLowerCase() + name.slice(1) : name\n return at === 0 ? name : `${all}${at === names.length - 1 ? ' and ' : ', '}${said}`\n }, '')\n const items = Math.max(...listing.map((index) => sections[index]?.items ?? 0))\n const uses = [...new Set(listing.flatMap((index) => sections[index]?.uses ?? []))]\n sections = sections.flatMap((section, index) =>\n index === first ? [{ ...section, name: joined, uses, items }] : rest.includes(index) ? [] : [section],\n )\n changed = true\n }\n return sections === screen.sections ? screen : { ...screen, sections }\n })\n return changed ? { ...plan, screens } : plan\n}\n\n/**\n * A designed dataset's split field held to the values its sections list\n * (AGL-4065): a record whose value is one of them in another case takes\n * the section's spelling, so the page's filter (`status == Upcoming`) lists\n * it. Pure.\n */\nfunction aiDatasetWithSplitValues(dataset: AiDataset, split: AiDatasetSplit | undefined): AiDataset {\n const column = split ? dataset.fields.findIndex((field) => field.name.trim().toLowerCase() === split.field.trim().toLowerCase()) : -1\n if (!split || column < 1) return dataset\n const spelled = new Map(split.values.map((value) => [value.trim().toLowerCase(), value]))\n return {\n ...dataset,\n records: dataset.records.map((values) => {\n const value = (values[column] ?? '').trim()\n const own = spelled.get(value.toLowerCase())\n return own && own !== value ? values.map((entry, at) => (at === column ? own : entry)) : [...values]\n }),\n }\n}\n\n/** A value's words as a split compares them: \"Family portraits\" is \"Family portrait\". */\nconst splitWords = (value: string) => value.split(/[^\\p{L}\\p{N}]+/u).filter(Boolean).map(splitStem).join(' ')\n\n/**\n * The values a page's sections list, each as its records spell it where one\n * is the same words in another form (\"Family portraits\" for a section's\n * \"Family portrait\"), so a section matches one value, never two. Pure.\n */\nfunction splitSpellings(expected: readonly string[], recorded: readonly string[]): string[] {\n return expected.map((value) => recorded.find((own) => own && splitWords(own) === splitWords(value)) ?? value)\n}\n\n/** Whether a plan screen is the record template of a dataset the plan creates, and which. */\nexport function aiSiteRecordTemplateOf(screen: Pick<AiBuildPlanScreen, 'record'>): string | null {\n const ref = screen.record?.dataset\n return ref && isAiPlanNewRef(ref) ? ref.slice(ref.indexOf(':') + 1).trim() : null\n}\n\nfunction datasetInputOf(job: Pick<AiJob, 'inputs'>): AiSiteDatasetInput {\n const raw = (job.inputs?.[AI_SITE_DATASET_INPUT] ?? {}) as Partial<AiSiteDatasetInput>\n const form = raw.forForm && typeof raw.forForm === 'object' ? raw.forForm : null\n return {\n shownIn: Array.isArray(raw.shownIn) ? raw.shownIn.map(str).filter(Boolean).slice(0, 8) : [],\n recordPages: raw.recordPages === true,\n ...(form && str(form.name)\n ? {\n forForm: {\n name: str(form.name),\n fields: Array.isArray(form.fields) ? form.fields.map(str).filter(Boolean).slice(0, AI_SITE_FORM_DATASET_FIELDS_MAX) : [],\n },\n }\n : {}),\n ...(raw.pictures === 'things' || raw.pictures === 'people' ? { pictures: raw.pictures } : {}),\n ...splitOf(raw.split),\n }\n}\n\n/** A unit input's split as its job carries it; one that does not read is none. */\nfunction splitOf(raw: unknown): { split?: AiDatasetSplit } {\n const split = (raw ?? {}) as Partial<AiDatasetSplit>\n const field = str(split.field)\n const sections = Array.isArray(split.sections) ? split.sections.map(str).filter(Boolean).slice(0, 8) : []\n const values = Array.isArray(split.values) ? split.values.map(str).filter(Boolean).slice(0, 8) : []\n return field && sections.length >= 2 && values.length === sections.length ? { split: { field, sections, values } } : {}\n}\n\n/** The most fields a form's dataset is designed with: the data plugin writer's own ceiling is higher. */\nexport const AI_SITE_FORM_DATASET_FIELDS_MAX = 12\n\n/** The field types a planned `Name:type` may name, as the data plugin's writer takes them. */\nconst FORM_DATASET_FIELD_TYPES = ['text', 'number', 'integer', 'boolean', 'list'] as const\n\n/** A planned field as a person reads it: `fullName` and `full_name` are \"Full name\", `fechaDeÚltimaVisita` \"Fecha de última visita\". */\nexport function aiSiteDatasetFieldName(planned: string): string {\n const words = planned\n .replace(/([\\p{Ll}\\p{N}])(\\p{Lu})/gu, '$1 $2')\n .replace(/[_-]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n return words ? words.charAt(0).toUpperCase() + words.slice(1).toLowerCase() : ''\n}\n\n/**\n * A dataset a form writes to, as the data plugin's writer takes it\n * (AGL-3616): designed with no model, since its records are the\n * submissions. Its fields are its planned ones — or, where the plan gave it\n * none, the form's — each a person's words for it, text unless the plan\n * typed it as `Name:type`, never required, so a submission that leaves one\n * blank is still a record. It starts with no records. Pure.\n */\nexport function aiSiteFormDatasetContent(\n name: string,\n planned: readonly string[],\n form: { fields: readonly string[] },\n): Record<string, unknown> {\n const specs = (planned.length ? planned : form.fields).slice(0, AI_SITE_FORM_DATASET_FIELDS_MAX)\n const seen = new Set<string>()\n const fields: Array<{ name: string; type: string }> = []\n for (const spec of specs) {\n const at = spec.lastIndexOf(':')\n const typed = at > 0 ? spec.slice(at + 1).trim().toLowerCase() : ''\n const type = (FORM_DATASET_FIELD_TYPES as readonly string[]).includes(typed) ? typed : 'text'\n const fieldName = aiSiteDatasetFieldName(type === typed ? spec.slice(0, at) : spec).slice(0, 60)\n if (!fieldName || seen.has(fieldName.toLowerCase())) continue\n seen.add(fieldName.toLowerCase())\n fields.push({ name: fieldName, type })\n }\n return { name, fields, records: [] }\n}\n\n/** The note a form's dataset carries on the job's page. */\nexport function aiSiteFormDatasetNote(form: string): string {\n return `Empty to start: each submission of the form “${form}” is added here, in Data.`\n}\n\nconst limitReview = (message: string) => ({ reason: 'limit' as const, message, findings: [] })\n\n/** The wall clock a dataset's photos may take inside its pass: the 20 seconds a page's pictures had (AGL-3660). */\nexport const AI_SITE_DATASET_PHOTOS_BUDGET_MS = 20_000\n\n/** The field a pictured dataset's photo is kept in, where the plan gave it none. */\nexport const AI_SITE_DATASET_IMAGE_FIELD = 'Image'\n\n/**\n * The field a pictured dataset keeps what each record's photo shows in\n * (AGL-3856), which its card's and its page's Image take as their alt text:\n * a record's title is what it is called, never what its photo shows.\n */\nexport const AI_SITE_DATASET_IMAGE_ALT_FIELD = 'Image description'\n\n/** A planned field that already names a record's photo. */\nconst IMAGE_FIELD_NAME =\n /^(?:main |cover |hero |featured? )?(?:image|photo|picture|photograph|thumbnail|headshot|portrait|cover)s?$/i\n\n/** One record's photo: the address its Image shows, and the library asset placed, which no page shows again. */\nexport interface AiSiteDatasetRecordPhoto {\n /** The media library's CDN path, or a starter's site path; `null` for none. */\n src: string | null\n /** The `media:` reference of the stock photo placed, or `null` for a starter. */\n placed: string | null\n /** What the photo shows, in its own words (AGL-3856); `null` for none. */\n alt?: string | null\n /** The library photo's size, where it is one (AGL-3988): what a page the library fails reuses it at. */\n width?: number\n height?: number\n /**\n * The picks the library's image hosts refused for a record left on a\n * starter (AGL-3988), which the site start's late photo pass asks again.\n */\n refused?: AiStockRefusedPicks\n /** A starter on a site with no stock library (AGL-3988): it keeps it, and no late pass fills it. */\n noLibrary?: true\n}\n\n/**\n * A photo for each record of a pictured dataset (AGL-3616), in order: a stock\n * photo of the record's own name, in the site's craft (\"ceramic speckled\n * serving bowl\"), copied into the site's library, where the deployment has a\n * stock library — never twice in the dataset nor one another part of the job\n * placed, inside {@link AI_SITE_DATASET_PHOTOS_BUDGET_MS} — else a starter\n * photo, as a page's empty picture takes one. A team is searched as the\n * business's people. The photo is kept as the asset's CDN path, the form a\n * product keeps (`aiSiteProductPhotoSrc`), so a replace in the library still\n * reaches it. No AI model is asked, so no credits; never throws.\n */\nexport async function aiSiteDatasetRecordPhotos(input: {\n job: Pick<AiJob, '$id' | 'hostId' | 'createdBy' | 'inputs' | 'brief' | 'plan'>\n /** The dataset, as the plan named it. */\n name: string\n /** Each record's name, by position. */\n names: readonly string[]\n /** What each record is filed under, by position ({@link aiSiteDatasetCategoryOf}, AGL-3856); absent for a list that files none. */\n categories?: ReadonlyArray<string | null>\n pictures: AiSiteDatasetPictures\n signal?: AbortSignal\n stockPhotos?: typeof aiLayoutStockPhotoSource\n}): Promise<AiSiteDatasetRecordPhoto[]> {\n const { job } = input\n if (!input.names.length || !job.hostId) return input.names.map(() => ({ src: null, placed: null }))\n const people = input.pictures === 'people'\n const slots: AiLayoutPictureSlot[] = input.names.map((name, index) => ({\n imageId: `record${index}`,\n frameId: null,\n iconId: null,\n alt: name.trim() || input.name,\n // The record card's own shape: a team's portraits stand, pieces sit wide.\n aspect: people ? 4 / 5 : 4 / 3,\n sectionIndex: 0,\n role: people ? ('about' as const) : ('gallery' as const),\n // A record's name is a search's words, never what its photo shows (AGL-3856).\n standIn: true,\n // A team's record shows an adult in their role, never a child (AGL-3856).\n ...(people ? { people: true } : {}),\n // A piece's record is OF what it names and what it is filed under (AGL-3856).\n ...(people ? {} : { record: input.categories?.[index]?.trim() ? { category: (input.categories[index] as string).trim() } : {} }),\n }))\n const seed = `${job.$id}:records`\n let found: ReadonlyArray<AiLayoutPicturePhoto | null> = []\n /** The picks the image hosts refused, by record (AGL-3988). */\n const report: AiLayoutPictureReport = { refused: new Map() }\n /** Whether the site has a stock library: its records then never take a starter that shows another business (AGL-3988). */\n let library = false\n try {\n const source = (input.stockPhotos ?? aiLayoutStockPhotoSource)(\n {\n hostId: job.hostId,\n uid: job.createdBy,\n seed,\n business: aiSiteWords(job.inputs).about || job.brief,\n ...aiStockPhotoWordsOf(job),\n sectionNames: [input.name],\n jobId: aiOriginJobId(job),\n // Each record may try its name, its object and the site's world.\n searches: slots.length * 3,\n ...(input.signal ? { signal: input.signal } : {}),\n },\n { budgetMs: AI_SITE_DATASET_PHOTOS_BUDGET_MS },\n )\n library = Boolean(source)\n if (source) found = await source(slots, report)\n } catch (error) {\n console.warn('ai site dataset: the stock photos failed; the job’s own photos or starters fill them', { error: String(error) })\n }\n const hostId = job.hostId\n const copied: Array<AiLayoutPicturePhoto | null> = slots.map((_slot, index) => (found[index]?.src ? (found[index] as AiLayoutPicturePhoto) : null))\n // A record left without a photo takes one this list already shows, on its\n // own subject (AGL-3988), before any starter.\n const photos =\n library && !people\n ? aiSiteDatasetRecordsFromOwn(\n input.names.map((name, index) => ({ name, category: input.categories?.[index] ?? null })),\n copied,\n seed,\n )\n : copied\n // Only a job with no photo of its own takes starters: with a library, the\n // neutral ones in turn, never a workbench or houseplants (AGL-3923); a\n // team's records, and a site with no library, the starters as before.\n const starters = library && !people ? aiLayoutNeutralStarterRun(slots.length, seed) : aiLayoutStarterPhotos(slots, seed)\n return slots.map((_slot, index) => {\n const photo = photos[index]\n const stock = aiSiteProductPhotoSrc(photo?.src, hostId)\n if (photo && stock) {\n const copied = found[index]?.src === photo.src\n return {\n src: stock,\n placed: copied ? photo.src : null,\n alt: photo.alt?.trim() || null,\n width: photo.width,\n height: photo.height,\n }\n }\n const refused = report.refused.get(slots[index] as AiLayoutPictureSlot)\n return {\n src: aiSiteProductPhotoSrc(starters[index]?.src, hostId),\n placed: null,\n alt: starters[index]?.alt?.trim() || null,\n ...(refused ? { refused } : {}),\n ...(library ? {} : { noLibrary: true as const }),\n }\n })\n}\n\n/**\n * The photos of a list's records, each record its library left without one\n * given one of those the list already shows (AGL-3988). The beta.270 Sugar\n * Hollow Photography covers, a wedding photographer's, filed five \"Weddings\n * and elopements\" galleries under a windowsill, a workbench, a desk and an\n * office team, every copy refused by Pixabay's rate limit, while three of\n * its records had copied a snowy mountain wedding, a couple at sunset and a\n * father and son in the mountains.\n *\n * A record takes, in order: a photo of a record filed under the same\n * category; a photo whose words name the people its own moment shows\n * (`aiStockRecordScene`: a couple for \"Couple Portraits\", never a family);\n * either again where only the record beside it shows them; and last any\n * photo the list shows. Never the photo of the record beside it while\n * another fits, the least shown first, the seed picking among equals. A\n * record no photo fits keeps none, and takes a starter. Pure.\n *\n * `besideLast` is the site start's late photo pass (AGL-3988): there the\n * other choice is a starter photo of another business, so a record every\n * photo sits beside takes the photo beside it rather than none.\n */\nexport function aiSiteDatasetRecordsFromOwn(\n records: ReadonlyArray<{ name: string; category?: string | null }>,\n photos: ReadonlyArray<AiLayoutPicturePhoto | null>,\n seed: string,\n /**\n * The photos the job copied for its pages (AGL-3988), which the site\n * start's late photo pass offers a list whose own photos were all refused:\n * filed under no category, so each is taken by the people it shows.\n */\n others: readonly AiLayoutPicturePhoto[] = [],\n options: { besideLast?: boolean } = {},\n): Array<AiLayoutPicturePhoto | null> {\n const listed = photos.flatMap((photo, index) => (photo?.src ? [{ photo, index }] : []))\n const shownHere = new Set(listed.map((entry) => entry.photo.src))\n const own = [\n ...listed,\n ...others\n .filter((photo, at, all) => photo.src && !shownHere.has(photo.src) && all.findIndex((one) => one.src === photo.src) === at)\n .map((photo, at) => ({ photo, index: records.length + at })),\n ]\n if (!own.length) return [...photos]\n /** Every place a photo is ranked from: the list's records, then the job's other photos. */\n const span = records.length + own.length - listed.length\n const category = (index: number) => records[index]?.category?.replace(/\\s+/g, ' ').trim().toLowerCase() ?? ''\n const turn = aiLayoutSeedNumber(seed)\n /** Whether a photo's words name the people a record's moment shows, and none it never shows. */\n const shows = (photo: AiLayoutPicturePhoto, record: { name: string; category?: string | null }) => {\n const scene = aiStockRecordScene(record.name, record.category ?? '')\n if (!scene) return false\n const stems = new Set(\n (photo.alt ?? '')\n .toLowerCase()\n .split(/[^a-z\\u00c0-\\u024f]+/)\n .filter(Boolean)\n .map(aiStockStem),\n )\n return scene.people.some((stem) => stems.has(stem)) && !scene.shun.some((stem) => stems.has(stem))\n }\n /** The list filled in one order; the record beside one filled before it is known, the one after not yet. */\n const fill = (order: readonly number[]) => {\n const filled = [...photos]\n for (const index of order) {\n const record = records[index]\n if (!record || filled[index]?.src) continue\n const beside = new Set([filled[index - 1]?.src, filled[index + 1]?.src].filter(Boolean))\n const apart = (entry: { photo: AiLayoutPicturePhoto }) => !beside.has(entry.photo.src)\n const same = own.filter((entry) => category(index) && category(entry.index) === category(index))\n const subject = own.filter((entry) => shows(entry.photo, record))\n const pool = [same.filter(apart), subject.filter(apart), same, subject, own.filter(apart), options.besideLast ? own : []].find(\n (list) => list.length,\n )\n if (!pool) continue\n const uses = (src: string) => filled.filter((photo) => photo?.src === src).length\n const rank = (at: number) => (((at - turn) % span) + span) % span\n const [pick] = [...pool].sort((a, b) => uses(a.photo.src) - uses(b.photo.src) || rank(a.index) - rank(b.index))\n if (pick) filled[index] = { ...pick.photo }\n }\n return filled\n }\n // Filled from either end, the one that shows a photo beside itself least:\n // a record beside a copied one is the most held, and is served first.\n const forward = fill(records.map((_record, index) => index))\n const backward = fill(records.map((_record, index) => records.length - 1 - index))\n const repeats = (list: ReadonlyArray<AiLayoutPicturePhoto | null>) =>\n list.filter((photo, index) => index > 0 && photo?.src && photo.src === list[index - 1]?.src).length\n return repeats(backward) < repeats(forward) ? backward : forward\n}\n\n/**\n * A designed dataset's content with its records' photos (AGL-3616): the\n * planned field that names a photo (\"Image\", \"Photo\") becomes the data\n * plugin's `image` field, else one called \"Image\" is added after the others,\n * and each record holds its photo there; a record with none holds nothing.\n * Pure.\n */\nexport function aiSiteDatasetContentWithPhotos(\n content: Record<string, unknown>,\n photos: ReadonlyArray<string | null>,\n /** What each record's photo shows (AGL-3856), kept in {@link AI_SITE_DATASET_IMAGE_ALT_FIELD}; none adds no field. */\n alts: ReadonlyArray<string | null> = [],\n): Record<string, unknown> {\n const fields = (Array.isArray(content['fields']) ? content['fields'] : []) as Array<{ name: string; type?: string }>\n const named = fields.find((field) => IMAGE_FIELD_NAME.test(str(field.name)))\n const fieldName = named ? named.name : AI_SITE_DATASET_IMAGE_FIELD\n const withImage = named\n ? fields.map((field) => (field === named ? { ...field, type: 'image' } : field))\n : [...fields, { name: AI_SITE_DATASET_IMAGE_FIELD, type: 'image' }]\n const described = alts.some((alt, index) => Boolean(alt && photos[index]))\n const altName = AI_SITE_DATASET_IMAGE_ALT_FIELD\n const nextFields =\n described && !withImage.some((field) => str(field.name).toLowerCase() === altName.toLowerCase())\n ? [...withImage, { name: altName, type: 'text' }]\n : withImage\n const records = (Array.isArray(content['records']) ? content['records'] : []) as Array<Record<string, unknown>>\n return {\n ...content,\n fields: nextFields,\n records: records.map((record, index) => {\n const next = { ...record }\n delete next[fieldName]\n const photo = photos[index]\n const alt = photo && described ? alts[index] : null\n return photo ? { ...next, [fieldName]: photo, ...(alt ? { [altName]: alt } : {}) } : next\n }),\n }\n}\n\nexport interface AiSiteDatasetRunnerDeps {\n generate?: typeof generateAiDataset\n writerFor?: typeof pluginResourceDraftWriter\n /** Where a pictured dataset's photos come from; the stock library, else the starters, otherwise. */\n photos?: typeof aiSiteDatasetRecordPhotos\n}\n\n/** The fields and record names a written dataset reports, as its output's proposal keeps them. */\ninterface AiSiteDatasetProposal {\n fields: AiLayoutListingField[]\n /** Each record's name: its first field's value. */\n recordNames: string[]\n addressField: string | null\n /** The field each record's photo is in, where it has one (AGL-3616). */\n imageField?: string | null\n /** The library photos its records show (`media:` references), which no page places again. */\n photos?: string[]\n /**\n * The same photos with their size and words (AGL-3988): what a page's\n * picture the library fails takes before any starter.\n */\n placedPhotos?: AiLayoutPicturePhoto[]\n /**\n * The fields most of its first records leave empty, by id (AGL-3616): a\n * tour's venues not yet known. A card never binds one — it would print\n * nothing on most records — so its listing leaves them out.\n */\n sparseFields?: string[]\n /**\n * What its records are filed under (AGL-3921): the category-like field, by\n * id, and each record's value of it, by position as {@link recordNames}.\n * A section named for one value lists only its records. Where a page lists\n * it in sections each naming a value of one planned field (AGL-4065), that\n * field, with the values the sections list as `expected`, so each section\n * is filtered even before the owner adds its first row.\n */\n groups?: { field: string; values: string[]; expected?: string[] }\n /** It was designed with no records (AGL-4065): the brief gave none, and the pages say so. */\n emptyList?: true\n}\n\n/** A field whose name says it files its records: a category, a type, a kind. */\nconst CATEGORY_FIELD = /^(?:(?:gallery|session|service|event|course|class|product|menu|work|project) )?(?:category|categories|type|kind|collection|genre|group|section|subject|occasion|series)$/i\n\n/**\n * What a designed dataset's records are filed under (AGL-3921): its first\n * field whose name says it files them (\"Category\", \"Type\", \"Session type\"),\n * with each record's value, where they hold at least two different values\n * and some record shares one — a list that files every record apart files\n * none. `null` otherwise. Pure.\n */\nexport function aiSiteDatasetCategoryOf(dataset: {\n fields: ReadonlyArray<{ name: string }>\n records: ReadonlyArray<ReadonlyArray<string | undefined>>\n}): { column: number; name: string; values: Array<string | null> } | null {\n for (const [column, field] of dataset.fields.entries()) {\n if (column === 0 || !CATEGORY_FIELD.test(field.name.trim())) continue\n const values = dataset.records.map((values) => (values[column] ?? '').replace(/\\s+/g, ' ').trim() || null)\n const distinct = new Set(values.filter((value): value is string => Boolean(value)).map((value) => value.toLowerCase()))\n if (distinct.size >= 2 && distinct.size < values.filter(Boolean).length) return { column, name: field.name, values }\n }\n return null\n}\n\n/**\n * A dataset's groups as its proposal keeps them: the written field's id, and\n * the value of each record its {@link AiSiteDatasetProposal.recordNames} names.\n */\nfunction aiSiteDatasetGroupsOf(\n category: ReturnType<typeof aiSiteDatasetCategoryOf>,\n written: readonly AiLayoutListingField[],\n designed: { fields: ReadonlyArray<{ name: string }>; records: ReadonlyArray<ReadonlyArray<string | undefined>> },\n): Pick<AiSiteDatasetProposal, 'groups'> {\n if (!category) return {}\n const field =\n written.find((entry) => entry.name.trim().toLowerCase() === category.name.trim().toLowerCase())?.id ??\n (written.length === designed.fields.length ? written[category.column]?.id : undefined)\n if (!field) return {}\n const values = designed.records.flatMap((record, index) => record[0] ? [category.values[index] ?? ''] : []).slice(0, 12)\n return { groups: { field, values } }\n}\n\n/**\n * The fields of a designed dataset that its records leave empty on most of\n * them — every record, or more than half — by the id the data plugin gave\n * each (AGL-3616). Its first field is the record's name and is never one. The\n * live low-tide-hollow start (beta.239) seeded its tour dates with no venue,\n * rightly inventing none, and its cards bound the venue as their eyebrow.\n */\nexport function aiDatasetSparseFields(\n dataset: { fields: ReadonlyArray<{ name: string }>; records: ReadonlyArray<ReadonlyArray<string | undefined>> },\n written: readonly AiLayoutListingField[],\n): string[] {\n if (!dataset.records.length) return []\n const idOf = (name: string, column: number) =>\n written.find((field) => field.name.trim().toLowerCase() === name.trim().toLowerCase())?.id ?? written[column]?.id ?? null\n return dataset.fields.flatMap((field, column) => {\n if (column === 0) return []\n const filled = dataset.records.filter((values) => (values[column] ?? '').trim()).length\n const id = idOf(field.name, column)\n return id && filled * 2 <= dataset.records.length ? [id] : []\n })\n}\n\nfunction proposalOf(output: Pick<AiJobOutput, 'proposal'>): AiSiteDatasetProposal {\n const raw = (output.proposal ?? {}) as Partial<AiSiteDatasetProposal>\n return {\n fields: Array.isArray(raw.fields)\n ? raw.fields.filter((field) => field && typeof field.id === 'string' && field.id).map((field) => ({ id: field.id, name: str(field.name) || field.id, type: str(field.type) || 'text' }))\n : [],\n recordNames: Array.isArray(raw.recordNames) ? raw.recordNames.map(str).filter(Boolean).slice(0, 12) : [],\n addressField: str(raw.addressField) || null,\n imageField: str(raw.imageField) || null,\n photos: Array.isArray(raw.photos) ? raw.photos.map(str).filter((src) => src.startsWith('media:')).slice(0, 24) : [],\n sparseFields: Array.isArray(raw.sparseFields) ? raw.sparseFields.map(str).filter(Boolean) : [],\n ...(raw.groups && typeof raw.groups === 'object' && str(raw.groups.field) && Array.isArray(raw.groups.values)\n ? {\n groups: {\n field: str(raw.groups.field),\n values: raw.groups.values.slice(0, 12).map(str),\n ...(Array.isArray(raw.groups.expected) ? { expected: raw.groups.expected.map(str).filter(Boolean).slice(0, 8) } : {}),\n },\n }\n : {}),\n ...(raw.emptyList === true ? { emptyList: true as const } : {}),\n }\n}\n\n/**\n * A dataset's groups for the page that lists it in sections each named for a\n * value of one planned field (AGL-4065): that field, by its written id, each\n * record's value of it, and the values the sections list. `null` where the\n * written dataset has no such field.\n */\nfunction aiSiteDatasetSplitGroups(\n split: AiDatasetSplit | undefined,\n written: readonly AiLayoutListingField[],\n designed: AiDataset,\n): AiSiteDatasetProposal['groups'] | null {\n if (!split) return null\n const name = split.field.trim().toLowerCase()\n const field = written.find((entry) => entry.name.trim().toLowerCase() === name)?.id\n const column = designed.fields.findIndex((entry) => entry.name.trim().toLowerCase() === name)\n if (!field || column < 1) return null\n const values = designed.records.flatMap((record) => (record[0] ? [(record[column] ?? '').trim()] : [])).slice(0, 12)\n return { field, values, expected: splitSpellings(split.values, values) }\n}\n\n/**\n * The dataset unit's runner, on the job the scaffold derived for it: the one\n * creation its plan carries, designed by the model and written by the data\n * plugin, under the creation's own id. A pass repeated after its write finds\n * the dataset the writer wrote and reports it again, spending nothing.\n */\nexport function createAiSiteDatasetRunner(deps: AiSiteDatasetRunnerDeps = {}): AiJobStepRunner {\n const generate = deps.generate ?? generateAiDataset\n const writerFor = deps.writerFor ?? pluginResourceDraftWriter\n const photosFor = deps.photos ?? aiSiteDatasetRecordPhotos\n return async (context): Promise<AiJobStepOutcome> => {\n const { job, firestore, signal } = context\n const model = context.modelFor?.(AI_DATASET_STEP) ?? aiModelForStep(AI_DATASET_STEP)\n const creation = (job.plan as AiJobPlan | null)?.create?.find((entry) => entry.kind === 'dataset')\n const keeper = writerFor(AI_SITE_DATASET_RESOURCE)\n if (!job.hostId || !creation) return { ...aiUnspentOutcome(model), failure: 'Open the site before adding its data.' }\n if (!keeper) return { ...aiUnspentOutcome(model), failure: 'Datasets are not available on this site.' }\n const host = await firestore.collection('hosts').doc(job.hostId).get()\n const hostSubdomain = str(host.get('subdomain')) || null\n const output = (id: string, name: string, proposal: AiSiteDatasetProposal, records: number): AiJobOutput => ({\n resource: 'draft',\n draftResource: AI_SITE_DATASET_RESOURCE,\n id,\n hostId: job.hostId ?? null,\n hostSubdomain,\n label: name,\n note: aiSiteDatasetNote(records),\n proposal: proposal as unknown as Record<string, unknown>,\n })\n const input = datasetInputOf(job)\n // Asked again under the same id: the dataset already written.\n const written = await keeper.writer.read({ hostId: job.hostId, id: job.$id })\n if (written) {\n const facts = written.facts as { fields?: AiLayoutListingField[]; addressField?: string | null; imageField?: string | null }\n const again = output(\n written.id,\n written.name || creation.name,\n { fields: facts.fields ?? [], recordNames: [], addressField: facts.addressField ?? null, imageField: facts.imageField ?? null },\n 0,\n )\n return aiUnspentOutcome(model, {\n outputs: [input.forForm ? { ...again, note: aiSiteFormDatasetNote(input.forForm.name) } : again],\n })\n }\n // A form's dataset (AGL-3616): its records are the submissions, so it is\n // designed from the plan with no model, and starts empty.\n if (input.forForm) {\n const content = aiSiteFormDatasetContent(creation.name, creation.fields, input.forForm)\n const checked = keeper.writer.check(content, { hostId: job.hostId })\n if (checked.ok === false) {\n console.error('ai site dataset: the dataset writer refused a form dataset we made', { orgId: job.orgId, jobId: job.$id, problems: checked.problems })\n return { ...aiUnspentOutcome(model), failure: AI_SITE_DATASET_NOT_WRITTEN_COPY }\n }\n const result = await keeper.writer.write({\n orgId: job.orgId,\n hostId: job.hostId,\n uid: job.createdBy,\n org: (context.org ?? null) as Readonly<Record<string, unknown>> | null,\n now: context.now,\n id: job.$id,\n name: creation.name,\n content,\n })\n if (result.ok === false) {\n if (result.status === 400) return { ...aiUnspentOutcome(model), failure: AI_SITE_DATASET_NOT_WRITTEN_COPY }\n return { ...aiUnspentOutcome(model), review: limitReview(result.error) }\n }\n const facts = result.facts as { fields?: AiLayoutListingField[]; addressField?: string | null }\n return aiUnspentOutcome(model, {\n outputs: [\n {\n ...output(result.id, result.name, { fields: facts.fields ?? [], recordNames: [], addressField: null }, 0),\n note: aiSiteFormDatasetNote(input.forForm.name),\n },\n ],\n })\n }\n const generation = await generate({\n brief: job.brief,\n merchantWords: job.brief,\n name: creation.name,\n why: creation.why,\n fields: creation.fields,\n shownIn: input.shownIn,\n recordPages: input.recordPages,\n // The value of a field each of a page's lists of it shows (AGL-4065).\n ...(input.split ? { split: input.split } : {}),\n model,\n maxTokens: AI_SITE_DATASET_BUDGET.maxTokens(model),\n ...(signal ? { signal } : {}),\n })\n const spent = aiGenerationSpent(generation)\n if (generation.status === 'refused') return { ...spent, refused: true }\n // An answer that still numbers placeholders after its re-ask is kept with\n // the records that name real things — none, as often as not — and written\n // with its fields, for the owner to fill (AGL-4065).\n const salvaged =\n generation.status === 'needs_input' && generation.violations.some((violation) => violation.code === AI_DATASET_PLACEHOLDER_CODE)\n ? aiDatasetWithoutPlaceholders(generation.answer, { planned: creation.fields, merchantWords: job.brief, name: creation.name })\n : null\n if (generation.status === 'needs_input' && !salvaged) return { ...spent, failure: generation.message }\n // No placeholder record is ever written, whatever let it through (AGL-4065);\n // a split field holds the values its sections list, and a dated list's\n // samples fall on a season's weekends from today, its past ones behind it.\n const language = (job.plan as AiJobPlan | null)?.language ?? null\n const value = aiDatasetSampleDates(\n aiDatasetWithSplitValues(\n aiDatasetRealRecords(generation.status === 'ok' ? generation.value : (salvaged as AiDataset), creation.name),\n input.split,\n ),\n {\n now: context.now,\n language,\n split: input.split ?? null,\n pastOnly: aiDatasetListedAsPast(input.shownIn.map((where) => where.split(' › ').slice(1).join(' › ') || where)),\n },\n )\n const designed = aiDatasetDraftContent(creation.name, value, {\n recordPages: input.recordPages,\n ...(language ? { language } : {}),\n })\n // What each record is filed under, which its photo and the sections that list it by its value read (AGL-3856).\n const category = aiSiteDatasetCategoryOf(value)\n // A list a visitor looks at keeps its records' photos (AGL-3616): searched\n // in code, never asked of the model, so they cost no credits.\n const photos = input.pictures\n ? await photosFor({\n job,\n name: creation.name,\n names: value.records.map((values) => values[0] ?? ''),\n ...(category ? { categories: category.values } : {}),\n pictures: input.pictures,\n ...(signal ? { signal } : {}),\n }).catch(() => [] as AiSiteDatasetRecordPhoto[])\n : []\n const content = input.pictures\n ? aiSiteDatasetContentWithPhotos(\n designed,\n value.records.map((_values, index) => photos[index]?.src ?? null),\n value.records.map((_values, index) => photos[index]?.alt ?? null),\n )\n : designed\n // The data plugin's own rules, before anything is written: content we\n // made that its model refuses is our failure, refunded.\n const checked = keeper.writer.check(content, { hostId: job.hostId })\n if (checked.ok === false) {\n console.error('ai site dataset: the dataset writer refused a dataset we made', { orgId: job.orgId, jobId: job.$id, problems: checked.problems })\n return { ...spent, failure: AI_SITE_DATASET_NOT_WRITTEN_COPY }\n }\n const result = await keeper.writer.write({\n orgId: job.orgId,\n hostId: job.hostId,\n uid: job.createdBy,\n org: (context.org ?? null) as Readonly<Record<string, unknown>> | null,\n now: context.now,\n id: job.$id,\n name: creation.name,\n content,\n })\n if (result.ok === false) {\n if (result.status === 400) return { ...spent, failure: AI_SITE_DATASET_NOT_WRITTEN_COPY }\n // The allowance, the role, the plan or the flag: the workspace's to change.\n return { ...spent, review: limitReview(result.error) }\n }\n const facts = result.facts as {\n fields?: AiLayoutListingField[]\n records?: number\n addressField?: string | null\n imageField?: string | null\n }\n const placed = photos.flatMap((photo) => (photo.placed ? [photo.placed] : []))\n const placedPhotos = photos.flatMap((photo) =>\n photo.placed && photo.width && photo.height\n ? [{ src: photo.placed, width: photo.width, height: photo.height, ...(photo.alt ? { alt: photo.alt } : {}) }]\n : [],\n )\n // A page's lists each named for a value of a planned field are filtered by it (AGL-4065), else by the category.\n const split = aiSiteDatasetSplitGroups(input.split, facts.fields ?? [], value)\n const proposal: AiSiteDatasetProposal = {\n fields: facts.fields ?? [],\n recordNames: value.records.map((values) => values[0] ?? '').filter(Boolean).slice(0, 12),\n addressField: facts.addressField ?? null,\n ...(facts.imageField ? { imageField: facts.imageField } : {}),\n ...(placed.length ? { photos: placed } : {}),\n ...(placedPhotos.length ? { placedPhotos } : {}),\n sparseFields: aiDatasetSparseFields(value, facts.fields ?? []),\n ...(split ? { groups: split } : aiSiteDatasetGroupsOf(category, facts.fields ?? [], value)),\n ...(value.records.length ? {} : { emptyList: true as const }),\n }\n // Its records left on a starter, which the site start's late photo pass fills (AGL-3988).\n const starters = aiSiteDatasetStarterList({\n dataset: result.id,\n hostId: job.hostId,\n imageField: facts.imageField ?? null,\n fields: facts.fields ?? [],\n people: input.pictures === 'people',\n names: value.records.map((values) => values[0] ?? ''),\n categories: category?.values ?? [],\n photos,\n })\n const count = facts.records ?? value.records.length\n const sampled = (value.samples ?? []).filter(Boolean).length\n const made = output(result.id, result.name, proposal, count)\n return {\n ...spent,\n outputs: [\n // A list the brief gave no rows for says its rows are samples, or where its rows go (AGL-4065).\n !value.records.length\n ? { ...made, note: aiSiteDatasetEmptyNote(creation.name) }\n : sampled\n ? { ...made, note: aiSiteDatasetSampleNote(value.records.length, sampled) }\n : made,\n ],\n ...(starters ? { sitePhotos: { pages: [], lists: [starters] } satisfies AiSitePhotos } : {}),\n }\n }\n}\n\n/**\n * A pictured list's records as the late photo pass reads them (AGL-3988),\n * where any of them holds a starter on a site with a stock library: each\n * record's name, category and photo\n * value in order, the library photo it shows as a media reference with its\n * size and words, and the picks the image hosts refused it. `null` where\n * every record shows a library photo, or the list keeps no photo field.\n */\nexport function aiSiteDatasetStarterList(input: {\n dataset: string\n hostId: string\n imageField: string | null\n fields: readonly AiLayoutListingField[]\n people: boolean\n names: readonly string[]\n categories: ReadonlyArray<string | null>\n photos: readonly AiSiteDatasetRecordPhoto[]\n}): AiSiteStarterList | null {\n // A site with no stock library keeps its starters, as it always has.\n if (!input.imageField || !input.photos.some((photo) => aiSiteIsStarterSrc(photo.src) && !photo.noLibrary)) return null\n const altField = input.fields.find((field) => field.name.trim().toLowerCase() === AI_SITE_DATASET_IMAGE_ALT_FIELD.toLowerCase())?.id\n return {\n dataset: input.dataset,\n imageField: input.imageField,\n ...(altField ? { altField } : {}),\n ...(input.people ? { people: true } : {}),\n records: input.names.map((name, index) => {\n const photo = input.photos[index]\n const value = photo?.src ?? ''\n const src = aiSiteIsStarterSrc(value) ? null : photo?.placed || mediaRefFromCdnPath(value) || null\n const category = input.categories[index]?.trim()\n return {\n name,\n ...(category ? { category } : {}),\n value,\n ...(src && photo?.width && photo.height\n ? { photo: { src, width: photo.width, height: photo.height, ...(photo.alt ? { alt: photo.alt } : {}) } }\n : {}),\n ...(photo?.refused ? { refused: photo.refused } : {}),\n }\n }),\n }\n}\n\nexport const runAiSiteDatasetUnit = createAiSiteDatasetRunner()\n\n/**\n * Whether a dataset may be created for this member on this site, asked before\n * its first pass so a refusal spends nothing; `null` admits. The data plugin\n * must run here (on for the workspace and the site, past its release flag),\n * and its writer says whether this member may make one now: the role, the\n * plan, the flag, the allowance.\n */\nexport async function aiSiteDatasetRefusal(\n context: Pick<AiJobStepContext, 'firestore' | 'org' | 'now'> & { job: Pick<AiJob, 'orgId' | 'hostId' | 'createdBy'> },\n deps: { admission?: typeof aiPluginDraftAdmissionRefusal; writerFor?: (resource: string) => ReturnType<typeof pluginResourceDraftWriter> } = {},\n): Promise<string | null> {\n const { job } = context\n if (!job.hostId) return 'Open the site first.'\n const writerFor = deps.writerFor ?? pluginResourceDraftWriter\n const admission: AiJobAdmissionContext = {\n firestore: context.firestore,\n orgId: job.orgId,\n hostId: job.hostId,\n inputs: {},\n org: context.org ?? null,\n uid: job.createdBy,\n }\n const refused = await (deps.admission ?? aiPluginDraftAdmissionRefusal)(admission, {\n kind: 'site',\n drafts: [{ resource: AI_SITE_DATASET_RESOURCE, label: DATA_PLUGIN_LABEL }],\n writerFor: (resource) => writerFor(resource)?.writer ?? null,\n ownerFor: (resource) => writerFor(resource)?.pluginId ?? null,\n now: context.now,\n })\n return refused?.error ?? null\n}\n\n/**\n * A site plan's dataset capability on this workspace (AGL-3616): where the\n * workspace's plan includes datasets, whether the data plugin runs here and\n * this member may create one now, and how many a start may make. A clause the\n * plan's turn completes is the reason where it may not.\n */\nexport async function aiSitePlanDatasetCapability(\n capabilities: AiPlanCapabilities,\n context: Parameters<typeof aiSiteDatasetRefusal>[0],\n deps: Parameters<typeof aiSiteDatasetRefusal>[1] = {},\n): Promise<AiPlanCapabilities> {\n if (!capabilities.create.dataset.allowed) return capabilities\n const refusal = await aiSiteDatasetRefusal(context, deps).catch((error: unknown) => {\n console.error('ai site plan: the dataset admission failed', { orgId: context.job.orgId, error })\n return 'datasets could not be checked just now'\n })\n const left = Math.min(AI_SITE_DATASETS_MAX, checkDatasetQuota(context.org as never, 0).limit)\n const dataset = refusal\n ? { allowed: false, left: 0, reason: `datasets cannot be created here: ${refusal.replace(/\\.$/, '')}` }\n : { allowed: true, left, reason: null }\n return { ...capabilities, create: { ...capabilities.create, dataset } }\n}\n\n/**\n * A `records` listing for each dataset that was made and that a section of the\n * plan names (AGL-3616). Its fields, where none are given, are read off the\n * site's inventory when the page is designed (`aiLayoutListingsWithDatasets`).\n */\nexport function aiDatasetListingsOf(\n datasets: ReadonlyArray<{\n id: string\n name: string\n records?: string[]\n fields?: AiLayoutListingField[]\n imageField?: string | null\n /** The record's page-address field, where the writer added one (AGL-3727). */\n addressField?: string | null\n /** What its records are filed under, by position as `records` (AGL-3921): a section named for one value lists its records alone. */\n groups?: { field: string; values: readonly string[]; expected?: readonly string[] } | null\n }>,\n screens: readonly AiLayoutListingScreen[],\n): AiLayoutListing[] {\n return datasets.flatMap((dataset) => {\n const placements = aiLayoutRecordsPlacements(dataset, screens)\n if (!placements.length) return []\n // Each card links its record's own page where the plan makes one (AGL-3727).\n const recordBase = aiLayoutRecordBaseOf(dataset, screens)\n return [\n {\n id: aiLayoutListingId('records', dataset.id),\n kind: 'records' as const,\n name: dataset.name,\n records: dataset.records ?? [],\n datasetId: dataset.id,\n ...(dataset.fields?.length ? { fields: dataset.fields } : {}),\n // Its card leads with the record's photo (AGL-3616).\n ...(dataset.imageField ? { imageField: dataset.imageField } : {}),\n // The address is read off the site's inventory where the build does not know it yet.\n ...(recordBase ? { recordBase, ...(dataset.addressField ? { addressField: dataset.addressField } : {}) } : {}),\n placements,\n },\n ]\n })\n}\n\n/**\n * A `records` listing for each dataset the workspace already keeps that a\n * site start's plan reuses and a section names (AGL-3771), as a build lists\n * the ones it reuses (AGL-3747). A second site in a workspace reuses the\n * first one's menu: its plan names the dataset by id, the start listed only\n * the datasets it made, and the page was asked to \"place\" a dataset no block\n * can draw — the home's \"Del menú\" section was refused for showing none of\n * its six items, and the Menú page published with no menu. A dataset one of\n * the plan's forms writes into holds the site's submissions, and is never\n * listed on a page.\n */\nexport function aiSiteReusedDatasetListings(input: {\n plan: Pick<AiJobPlan, 'reuse' | 'create' | 'labels'>\n screens: readonly AiLayoutListingScreen[]\n /** The listings the start already has, whose datasets are not listed twice. */\n listed: ReadonlyArray<Pick<AiLayoutListing, 'datasetId'>>\n}): AiLayoutListing[] {\n const submissions = new Set(\n input.plan.create.flatMap((entry) => (entry.kind === 'form' && entry.writesTo && !isAiPlanNewRef(entry.writesTo) ? [entry.writesTo] : [])),\n )\n const listed = new Set(input.listed.map((listing) => listing.datasetId).filter(Boolean))\n const datasets = input.plan.reuse\n .filter((entry) => entry.kind === 'dataset' && !submissions.has(entry.id) && !listed.has(entry.id))\n .map((entry) => ({ id: entry.id, name: input.plan.labels?.[entry.id] || entry.id }))\n return aiDatasetListingsOf(datasets, input.screens)\n}\n\n/**\n * A SITE START NEVER SHOWS ANOTHER SITE'S RECORDS (AGL-3912).\n *\n * Datasets belong to the organization, and so do their records: neither\n * names the site it was written for, and a dataset outlives the site that\n * filled it (the data plugin keeps `visibleTo` and nothing else of a site). A\n * gym's start reused the workspace's \"Session packages\", \"Coaches\" and \"Gym\n * FAQs\", and published a deleted photographer's wedding packages and a\n * deleted studio's coach bio (\"Leads coaching at Ironline Strength Studio\")\n * with four broken photos; a photographer's start reused another\n * photographer's gallery and drew six broken covers.\n *\n * So a site start reuses a dataset only when its records are this site's to\n * show ({@link aiSiteDatasetIsThisSites}):\n * - it holds no records at all — an empty list, such as the one a form\n * writes its submissions to, is the same list on any site; or\n * - its scope names this site alone (`siteOnly`), so it was made for it; or\n * - this site already serves its records pages of their own (`recordBase`).\n * Anything else — records in a dataset shared with the workspace or with\n * other sites, and a dataset whose records could not be counted — was filled\n * for something else, and the plan is settled in code before the rules read\n * it ({@link aiSettleSiteForeignDatasets}): the reuse becomes a creation of\n * the same name and fields, designed from this site's brief with photos of\n * its own, and every section, record template and form that named it names\n * the creation. Where this job may create no dataset, the reuse comes off\n * instead and each section writes its items out. Never a refusal, and\n * nothing a member is asked.\n *\n * An Assist change to a site that exists keeps reusing what the site lists:\n * this is a site start's rule, and only its plan is settled by it.\n */\nexport function aiSiteDatasetIsThisSites(row: Pick<AiInventoryDataset, 'records' | 'siteOnly' | 'recordBase'>): boolean {\n return row.records === 0 || row.siteOnly === true || Boolean(row.recordBase)\n}\n\n/** A planned field that is a record's page address, which the writer adds itself. */\nconst ADDRESS_FIELD_NAME = /^(?:page )?(?:address|slug|url|link)$/i\n\n/** The fields a dataset is made again with: its own, less the photo, its description and the page address the writer adds. */\nfunction remadeFields(row: AiInventoryDataset): string[] {\n const ids = row.fieldIds ?? []\n return row.fields\n .filter((name, index) => {\n const id = ids[index]\n if (id && (id === row.imageField || id === row.addressField)) return false\n if (IMAGE_FIELD_NAME.test(name.trim()) || ADDRESS_FIELD_NAME.test(name.trim())) return false\n return name.trim().toLowerCase() !== AI_SITE_DATASET_IMAGE_ALT_FIELD.toLowerCase()\n })\n .slice(0, AI_BUILD_PLAN_LIMITS.fields)\n}\n\n/**\n * A site start's plan with every dataset it reuses that holds another\n * site's records made again for this one (AGL-3912): each the inventory marks\n * `foreign` ({@link aiSiteInventoryWithRecordCounts}, by\n * {@link aiSiteDatasetIsThisSites}). The creation keeps the dataset's name,\n * which rule 7 does not hold against it as a duplicate. Pure; a plan that\n * reuses none comes back as it was.\n */\nexport function aiSettleSiteForeignDatasets(\n plan: AiBuildPlan,\n inventory: Pick<AiSiteInventory, 'datasets'> | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n const rows = new Map((inventory?.datasets ?? []).map((row) => [row.id, row]))\n const foreign = plan.reuse.filter((entry) => entry.kind === 'dataset' && rows.get(entry.id)?.foreign === true)\n if (!foreign.length) return plan\n const creatable = !capabilities || capabilities.create.dataset.allowed\n const taken = new Map<string, AiBuildPlanCreate | null>([\n ...plan.create.map((entry) => [entry.name.trim().toLowerCase(), entry] as const),\n ...(plan.items ?? []).map((item) => [item.name.trim().toLowerCase(), null] as const),\n ])\n // Each foreign dataset's id → the `new:` reference that replaces it, or `null` where it comes off.\n const replaced = new Map<string, string | null>()\n const added: AiBuildPlanCreate[] = []\n for (const entry of foreign) {\n const row = rows.get(entry.id) as AiInventoryDataset\n const base = row.name.trim() || 'Records'\n if (!creatable) {\n replaced.set(entry.id, null)\n continue\n }\n // The plan already makes one of that name: that one is this site's.\n const same = taken.get(base.toLowerCase())\n if (same?.kind === 'dataset') {\n replaced.set(entry.id, `${AI_PLAN_NEW_REF_PREFIX}${same.name}`)\n continue\n }\n let name = base\n for (let n = 2; taken.has(name.toLowerCase()); n += 1) name = `${base} ${n}`\n const creation: AiBuildPlanCreate = {\n kind: 'dataset',\n name,\n why: entry.purpose || `Lists ${base} on this site.`,\n duplicateOf: null,\n fields: remadeFields(row),\n }\n added.push(creation)\n taken.set(name.toLowerCase(), creation)\n replaced.set(entry.id, `${AI_PLAN_NEW_REF_PREFIX}${name}`)\n }\n const swap = (ref: string): string | null => (replaced.has(ref) ? (replaced.get(ref) ?? null) : ref)\n return {\n ...plan,\n reuse: plan.reuse.filter((entry) => !(entry.kind === 'dataset' && replaced.has(entry.id))),\n create: [\n ...plan.create.map((entry) => {\n if (entry.kind !== 'form' || !entry.writesTo || !replaced.has(entry.writesTo)) return entry\n const writesTo = swap(entry.writesTo)\n if (writesTo) return { ...entry, writesTo }\n // A form whose dataset comes off sends its submissions to the Inbox only.\n const rest = { ...entry }\n delete rest.writesTo\n return rest\n }),\n ...added,\n ],\n screens: plan.screens.map((screen) => {\n // A record template of a dataset made again shows the new one; of one that comes off, it is a page of its own.\n const record =\n screen.record && replaced.has(screen.record.dataset) ? { record: swap(screen.record.dataset) } : null\n const sections = screen.sections.map((section) => {\n if (!section.uses.some((ref) => replaced.has(ref))) return section\n const uses = section.uses.flatMap((ref) => {\n const next = swap(ref)\n return next ? [next] : []\n })\n // A list that comes off is written out on the page, as fewer items than a dataset binds.\n const dropped = section.uses.some((ref) => replaced.has(ref) && !replaced.get(ref))\n return { ...section, uses, ...(dropped ? { items: Math.min(section.items, AI_TYPED_LIST_MIN_ITEMS - 1) } : {}) }\n })\n return {\n ...screen,\n ...(record && screen.record ? { record: record.record ? { ...screen.record, dataset: record.record } : null } : {}),\n sections,\n }\n }),\n }\n}\n\n/** How a dataset's records are counted: the data plugin's index, which answers `facts.records`. */\nexport type AiDatasetRecordCounter = (request: { orgId: string; id: string }) => Promise<number | null>\n\n/** The production counter: the data plugin's `dataset` index, read one dataset at a time. */\nexport const aiDatasetRecordCount: AiDatasetRecordCounter = async ({ orgId, id }) => {\n const index = pluginRecordIndex('dataset')?.index\n if (!index) return null\n const found = await index.get({ orgId, id })\n const records = found?.facts['records']\n return typeof records === 'number' && Number.isFinite(records) ? records : null\n}\n\n/**\n * A site start's inventory with how many records each dataset holds\n * (AGL-3912), and each whose records are not this site's to show\n * ({@link aiSiteDatasetIsThisSites}) marked `foreign`. The count is asked\n * once per plan, of every dataset the site sees, all at once; a count that\n * fails leaves `records` out, which reads as another site's. Never throws.\n */\nexport async function aiSiteInventoryWithRecordCounts(\n inventory: AiSiteInventory | null,\n orgId: string,\n count: AiDatasetRecordCounter = aiDatasetRecordCount,\n): Promise<AiSiteInventory | null> {\n if (!inventory?.datasets.length) return inventory\n const counts = await Promise.all(\n inventory.datasets.map((row) =>\n count({ orgId, id: row.id }).catch((error: unknown) => {\n console.warn('ai site plan: a dataset’s records could not be counted', { orgId, id: row.id, error: String(error) })\n return null\n }),\n ),\n )\n return {\n ...inventory,\n datasets: inventory.datasets.map((row, index) => {\n const records = counts[index]\n const counted = typeof records === 'number' ? { ...row, records } : row\n return aiSiteDatasetIsThisSites(counted) ? counted : { ...counted, foreign: true as const }\n }),\n }\n}\n\n/**\n * The site's datasets a layout or a page unit is handed (AGL-3616), each a\n * `records` listing with the sections of the plan's pages that name it, once\n * its unit wrote it. A dataset not yet written, or one that failed, lists\n * nowhere: the pages built without it write the items out.\n */\nexport function aiSiteDatasetListings(input: {\n outputs: readonly AiJobOutput[]\n datasets: ReadonlyArray<Pick<AiBuildPlanCreate, 'name'>>\n screens: readonly AiLayoutListingScreen[]\n /** The ids each dataset's unit delivered, by plan name lowercased. */\n delivered: ReadonlyMap<string, string>\n}): AiLayoutListing[] {\n const made = input.datasets.flatMap((dataset) => {\n const id = input.delivered.get(dataset.name.trim().toLowerCase())\n const output = id\n ? input.outputs.find((entry) => entry.resource === 'draft' && entry.draftResource === AI_SITE_DATASET_RESOURCE && entry.id === id)\n : undefined\n if (!id || !output) return []\n const proposal = proposalOf(output)\n return [\n {\n id,\n // Placed by the name the plan's sections gave it.\n name: dataset.name,\n records: proposal.recordNames,\n // The address field is the record page's, never a card's words; the\n // photo is the card's picture, never its words; a field most records\n // leave empty is no card's either (AGL-3616).\n fields: proposal.fields.filter(\n (field, index) =>\n field.id !== proposal.addressField &&\n field.id !== proposal.imageField &&\n (index === 0 || !proposal.sparseFields?.includes(field.id)),\n ),\n imageField: proposal.imageField ?? null,\n addressField: proposal.addressField,\n groups: proposal.groups ?? null,\n },\n ]\n })\n return aiDatasetListingsOf(made, input.screens)\n}\n\n/** The library photos the site's datasets' records show (AGL-3616), which a page does not place again. */\nexport function aiSiteDatasetPlacedPhotos(outputs: readonly AiJobOutput[]): string[] {\n return [\n ...new Set(\n outputs\n .filter((output) => output.resource === 'draft' && output.draftResource === AI_SITE_DATASET_RESOURCE)\n .flatMap((output) => proposalOf(output).photos ?? []),\n ),\n ]\n}\n\n/** The same photos with their size and words (AGL-3988), which a page's picture the library fails takes before any starter. */\nexport function aiSiteDatasetPlacedPhotoDetails(outputs: readonly AiJobOutput[]): AiLayoutPicturePhoto[] {\n const seen = new Set<string>()\n return outputs\n .filter((output) => output.resource === 'draft' && output.draftResource === AI_SITE_DATASET_RESOURCE)\n .flatMap((output) => aiStockJobPhotosOf((output.proposal as { placedPhotos?: unknown } | null)?.placedPhotos))\n .filter((photo) => !seen.has(photo.src) && Boolean(seen.add(photo.src)))\n}\n\n/** What a page is told about the datasets built before it. */\nexport function aiSiteDatasetBriefLines(outputs: readonly AiJobOutput[]): string[] {\n const datasets = outputs.filter((output) => output.resource === 'draft' && output.draftResource === AI_SITE_DATASET_RESOURCE)\n return datasets.flatMap((output) => {\n const proposal = proposalOf(output)\n const names = proposal.recordNames\n if (names.length) {\n return [`This site's dataset “${output.label}” holds: ${names.map((name) => `“${name}”`).join(', ')}. Where a page names one, name it as written; never name one that is not in this list.`]\n }\n // A list written with no rows keeps its band (AGL-4065): its heading and\n // an honest line, over the live list the owner fills.\n return proposal.emptyList\n ? [\n `This site's dataset “${output.label}” has no records yet: the owner adds them in Data. Where a page lists it, write its heading and one line saying its entries are on the way, and never name, date or describe one.`,\n ]\n : []\n })\n}\n"],"names":["mediaRefFromCdnPath","checkDatasetQuota","pluginResourceDraftWriter","pluginRecordIndex","AI_BUILD_PLAN_LIMITS","AI_PLAN_NEW_REF_PREFIX","isAiPlanNewRef","AI_TYPED_LIST_MIN_ITEMS","AI_SITE_DATASETS_MAX","AI_STEP_TIERS","aiModelForStep","AI_DATASET_MAX_TOKENS","AI_DATASET_PLACEHOLDER_CODE","AI_DATASET_STEP","aiDatasetDraftContent","aiDatasetListedAsPast","aiDatasetRealRecords","aiDatasetSampleDates","aiDatasetWithoutPlaceholders","generateAiDataset","aiLayoutListingId","aiLayoutRecordBaseOf","aiLayoutRecordsPlacements","aiLayoutNeutralStarterRun","aiLayoutSeedNumber","aiLayoutStarterPhotos","aiSiteWords","aiSiteIsStarterSrc","aiOriginJobId","aiSiteProductPhotoSrc","aiLayoutStockPhotoSource","aiStockJobPhotosOf","aiStockPhotoWordsOf","aiStockRecordScene","aiStockStem","AI_DATASET_DRAFT_RESOURCE","aiJobStepBudget","aiGenerationSpent","aiUnspentOutcome","aiPluginDraftAdmissionRefusal","AI_SITE_DATASET_RESOURCE","DATA_PLUGIN_LABEL","AI_SITE_DATASET_INPUT","READ_ONLY_LIST","PEOPLE_LIST","PICTURED_LIST","PICTURED_SECTION","aiSiteDatasetPicturesOf","dataset","sections","length","own","name","test","some","section","AI_SITE_DATASET_NOT_WRITTEN_COPY","aiSiteDatasetNote","records","aiSiteDatasetSampleNote","samples","aiSiteDatasetEmptyNote","AI_SITE_RECORD_PAGE_NOTE","AI_SITE_DATASET_WRITES_MS","AI_SITE_DATASET_BUDGET","tier","maxTokens","lookups","ownReadsMs","str","value","trim","namesDataset","ref","slice","indexOf","toLowerCase","aiSitePlanDatasets","plan","create","filter","entry","kind","aiSiteDatasetInputOf","screens","shownIn","sectionNames","split","screen","here","uses","push","title","items","aiSiteDatasetSplitOf","fields","recordPages","record","form","find","writesTo","pictures","forForm","AI_SITE_FORM_DATASET_FIELDS_MAX","SPLIT_FIELD","SPLIT_FRAMING","Set","plainField","spec","at","lastIndexOf","splitStem","word","lower","endsWith","field","map","flatMap","text","Boolean","values","words","named","stem","replace","has","start","end","kept","join","charAt","toUpperCase","distinct","size","aiSettlePlanSplitListings","datasets","changed","listing","index","names","first","rest","joined","reduce","all","said","Math","max","includes","aiDatasetWithSplitValues","column","findIndex","spelled","Map","get","splitWords","splitSpellings","expected","recorded","aiSiteRecordTemplateOf","datasetInputOf","job","raw","inputs","Array","isArray","splitOf","FORM_DATASET_FIELD_TYPES","aiSiteDatasetFieldName","planned","aiSiteFormDatasetContent","specs","seen","typed","type","fieldName","add","aiSiteFormDatasetNote","limitReview","message","reason","findings","AI_SITE_DATASET_PHOTOS_BUDGET_MS","AI_SITE_DATASET_IMAGE_FIELD","AI_SITE_DATASET_IMAGE_ALT_FIELD","IMAGE_FIELD_NAME","aiSiteDatasetRecordPhotos","input","hostId","src","placed","people","slots","imageId","frameId","iconId","alt","aspect","sectionIndex","role","standIn","categories","category","seed","$id","found","report","refused","library","source","stockPhotos","uid","createdBy","business","about","brief","jobId","searches","signal","budgetMs","error","console","warn","String","copied","_slot","photos","aiSiteDatasetRecordsFromOwn","starters","photo","stock","width","height","noLibrary","others","options","listed","shownHere","one","span","turn","shows","scene","stems","shun","fill","order","filled","beside","apart","same","subject","pool","besideLast","list","rank","pick","sort","a","b","forward","_record","backward","repeats","aiSiteDatasetContentWithPhotos","content","alts","withImage","described","altName","nextFields","next","CATEGORY_FIELD","aiSiteDatasetCategoryOf","entries","aiSiteDatasetGroupsOf","written","designed","id","undefined","groups","aiDatasetSparseFields","idOf","proposalOf","output","proposal","recordNames","addressField","imageField","startsWith","sparseFields","emptyList","aiSiteDatasetSplitGroups","createAiSiteDatasetRunner","deps","generate","writerFor","photosFor","context","facts","firestore","model","modelFor","creation","keeper","failure","host","collection","doc","hostSubdomain","resource","draftResource","label","note","writer","read","again","outputs","checked","check","ok","orgId","problems","result","write","org","now","status","review","generation","merchantWords","why","spent","salvaged","violations","violation","code","answer","language","pastOnly","where","catch","_values","placedPhotos","aiSiteDatasetStarterList","count","sampled","made","sitePhotos","pages","lists","altField","runAiSiteDatasetUnit","aiSiteDatasetRefusal","admission","drafts","ownerFor","pluginId","aiSitePlanDatasetCapability","capabilities","allowed","refusal","left","min","limit","aiDatasetListingsOf","placements","recordBase","datasetId","aiSiteReusedDatasetListings","submissions","reuse","labels","aiSiteDatasetIsThisSites","row","siteOnly","ADDRESS_FIELD_NAME","remadeFields","ids","fieldIds","aiSettleSiteForeignDatasets","inventory","rows","foreign","creatable","taken","item","replaced","added","base","set","n","purpose","duplicateOf","swap","dropped","aiDatasetRecordCount","Number","isFinite","aiSiteInventoryWithRecordCounts","counts","Promise","counted","aiSiteDatasetListings","delivered","aiSiteDatasetPlacedPhotos","aiSiteDatasetPlacedPhotoDetails","aiSiteDatasetBriefLines"],"mappings":"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"}