@aglyn/plugins-ai 1.0.0-beta.237 → 1.0.0-beta.239

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 (172) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-credits-prompt.component.d.ts +11 -4
  3. package/src/lib/components/ai-credits-prompt.component.js +84 -34
  4. package/src/lib/components/ai-credits-prompt.component.js.map +1 -1
  5. package/src/lib/components/ai-job-cancel.component.d.ts +38 -0
  6. package/src/lib/components/ai-job-cancel.component.js +156 -0
  7. package/src/lib/components/ai-job-cancel.component.js.map +1 -0
  8. package/src/lib/components/ai-job-links.js +8 -0
  9. package/src/lib/components/ai-job-links.js.map +1 -1
  10. package/src/lib/components/ai-job-plan.component.js +12 -1
  11. package/src/lib/components/ai-job-plan.component.js.map +1 -1
  12. package/src/lib/components/ai-jobs-list-page.component.js +141 -72
  13. package/src/lib/components/ai-jobs-list-page.component.js.map +1 -1
  14. package/src/lib/components/ai-jobs-store.d.ts +12 -0
  15. package/src/lib/components/ai-jobs-store.js +15 -0
  16. package/src/lib/components/ai-jobs-store.js.map +1 -1
  17. package/src/lib/components/ai-site-build-page.component.js +22 -2
  18. package/src/lib/components/ai-site-build-page.component.js.map +1 -1
  19. package/src/lib/components/ai-usage-meter-refresh.d.ts +35 -0
  20. package/src/lib/components/ai-usage-meter-refresh.js +63 -0
  21. package/src/lib/components/ai-usage-meter-refresh.js.map +1 -0
  22. package/src/lib/components/ai-usage-strip.component.d.ts +19 -2
  23. package/src/lib/components/ai-usage-strip.component.js +40 -9
  24. package/src/lib/components/ai-usage-strip.component.js.map +1 -1
  25. package/src/lib/components/assist-jobs-drawer.component.js +12 -16
  26. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
  27. package/src/lib/components/assist-panel.component.js +91 -51
  28. package/src/lib/components/assist-panel.component.js.map +1 -1
  29. package/src/lib/components/use-ai-usage-meter.d.ts +2 -0
  30. package/src/lib/components/use-ai-usage-meter.js +8 -3
  31. package/src/lib/components/use-ai-usage-meter.js.map +1 -1
  32. package/src/lib/jobs/ai-build-unit-outcome.d.ts +3 -1
  33. package/src/lib/jobs/ai-build-unit-outcome.js +19 -3
  34. package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -1
  35. package/src/lib/jobs/ai-job-build-step.js +33 -3
  36. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  37. package/src/lib/jobs/ai-job-cancel.d.ts +71 -0
  38. package/src/lib/jobs/ai-job-cancel.js +102 -0
  39. package/src/lib/jobs/ai-job-cancel.js.map +1 -0
  40. package/src/lib/jobs/ai-job-component-step.js +4 -1
  41. package/src/lib/jobs/ai-job-component-step.js.map +1 -1
  42. package/src/lib/jobs/ai-job-draft-ids.js +7 -2
  43. package/src/lib/jobs/ai-job-draft-ids.js.map +1 -1
  44. package/src/lib/jobs/ai-job-drafts.js +2 -0
  45. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  46. package/src/lib/jobs/ai-job-form-dataset.d.ts +100 -0
  47. package/src/lib/jobs/ai-job-form-dataset.js +161 -0
  48. package/src/lib/jobs/ai-job-form-dataset.js.map +1 -0
  49. package/src/lib/jobs/ai-job-form-step.d.ts +15 -3
  50. package/src/lib/jobs/ai-job-form-step.js +41 -10
  51. package/src/lib/jobs/ai-job-form-step.js.map +1 -1
  52. package/src/lib/jobs/ai-job-layout-language.d.ts +2 -0
  53. package/src/lib/jobs/ai-job-layout-language.js +13 -1
  54. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  55. package/src/lib/jobs/ai-job-layout-step.js +6 -1
  56. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  57. package/src/lib/jobs/ai-job-page-language.d.ts +9 -0
  58. package/src/lib/jobs/ai-job-page-language.js +45 -2
  59. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  60. package/src/lib/jobs/ai-job-page-step.js +12 -1
  61. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  62. package/src/lib/jobs/ai-job-plan-step.d.ts +38 -1
  63. package/src/lib/jobs/ai-job-plan-step.js +90 -13
  64. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  65. package/src/lib/jobs/ai-job-site-content.d.ts +15 -0
  66. package/src/lib/jobs/ai-job-site-content.js +66 -7
  67. package/src/lib/jobs/ai-job-site-content.js.map +1 -1
  68. package/src/lib/jobs/ai-job-site-datasets.d.ts +170 -0
  69. package/src/lib/jobs/ai-job-site-datasets.js +499 -0
  70. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -0
  71. package/src/lib/jobs/ai-job-site-step.d.ts +15 -8
  72. package/src/lib/jobs/ai-job-site-step.js +152 -30
  73. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  74. package/src/lib/jobs/ai-job-template-step.js +4 -1
  75. package/src/lib/jobs/ai-job-template-step.js.map +1 -1
  76. package/src/lib/jobs/ai-jobs.d.ts +37 -12
  77. package/src/lib/jobs/ai-jobs.js +184 -28
  78. package/src/lib/jobs/ai-jobs.js.map +1 -1
  79. package/src/lib/jobs/ai-layout-stock-photos.d.ts +143 -70
  80. package/src/lib/jobs/ai-layout-stock-photos.js +649 -176
  81. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  82. package/src/lib/jobs/fixtures/ai-ceramics-portfolio-site-plan.d.ts +30 -0
  83. package/src/lib/jobs/fixtures/ai-ceramics-portfolio-site-plan.js +220 -0
  84. package/src/lib/jobs/fixtures/ai-ceramics-portfolio-site-plan.js.map +1 -0
  85. package/src/lib/jobs/fixtures/ai-dataset-site-plan-recordings.d.ts +30 -0
  86. package/src/lib/jobs/fixtures/ai-dataset-site-plan-recordings.js +637 -0
  87. package/src/lib/jobs/fixtures/ai-dataset-site-plan-recordings.js.map +1 -0
  88. package/src/lib/jobs/fixtures/ai-stock-photo-pixabay-recordings.d.ts +27 -0
  89. package/src/lib/jobs/fixtures/ai-stock-photo-pixabay-recordings.js +151 -0
  90. package/src/lib/jobs/fixtures/ai-stock-photo-pixabay-recordings.js.map +1 -0
  91. package/src/lib/layout-language/ai-layout-compiler.d.ts +16 -0
  92. package/src/lib/layout-language/ai-layout-compiler.js +397 -9
  93. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  94. package/src/lib/layout-language/ai-layout-design.d.ts +6 -3
  95. package/src/lib/layout-language/ai-layout-design.js +5 -3
  96. package/src/lib/layout-language/ai-layout-design.js.map +1 -1
  97. package/src/lib/layout-language/ai-layout-frame.d.ts +12 -0
  98. package/src/lib/layout-language/ai-layout-frame.js +58 -3
  99. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  100. package/src/lib/layout-language/ai-layout-gaps.js +17 -1
  101. package/src/lib/layout-language/ai-layout-gaps.js.map +1 -1
  102. package/src/lib/layout-language/ai-layout-listings.d.ts +44 -3
  103. package/src/lib/layout-language/ai-layout-listings.js +118 -50
  104. package/src/lib/layout-language/ai-layout-listings.js.map +1 -1
  105. package/src/lib/layout-language/ai-layout-pictures.d.ts +8 -0
  106. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  107. package/src/lib/layout-language/ai-layout-storefront.d.ts +82 -0
  108. package/src/lib/layout-language/ai-layout-storefront.js +223 -0
  109. package/src/lib/layout-language/ai-layout-storefront.js.map +1 -0
  110. package/src/lib/model/ai-build-job.d.ts +11 -1
  111. package/src/lib/model/ai-build-job.js +35 -6
  112. package/src/lib/model/ai-build-job.js.map +1 -1
  113. package/src/lib/model/ai-build-plan.d.ts +23 -3
  114. package/src/lib/model/ai-build-plan.js +47 -6
  115. package/src/lib/model/ai-build-plan.js.map +1 -1
  116. package/src/lib/model/ai-build-progress.d.ts +2 -2
  117. package/src/lib/model/ai-build-progress.js +6 -4
  118. package/src/lib/model/ai-build-progress.js.map +1 -1
  119. package/src/lib/model/ai-credit-estimate.d.ts +69 -2
  120. package/src/lib/model/ai-credit-estimate.js +91 -3
  121. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  122. package/src/lib/model/ai-job-cancel-copy.d.ts +44 -0
  123. package/src/lib/model/ai-job-cancel-copy.js +53 -0
  124. package/src/lib/model/ai-job-cancel-copy.js.map +1 -0
  125. package/src/lib/model/ai-job-failure-copy.d.ts +4 -1
  126. package/src/lib/model/ai-job-failure-copy.js +8 -3
  127. package/src/lib/model/ai-job-failure-copy.js.map +1 -1
  128. package/src/lib/model/ai-jobs.types.d.ts +20 -0
  129. package/src/lib/model/ai-jobs.types.js.map +1 -1
  130. package/src/lib/model/ai-plan-capabilities.d.ts +7 -0
  131. package/src/lib/model/ai-plan-capabilities.js.map +1 -1
  132. package/src/lib/model/ai-site-build-progress.js +7 -4
  133. package/src/lib/model/ai-site-build-progress.js.map +1 -1
  134. package/src/lib/model/ai-site-job.d.ts +38 -4
  135. package/src/lib/model/ai-site-job.js +50 -14
  136. package/src/lib/model/ai-site-job.js.map +1 -1
  137. package/src/lib/model/ai-site-kinds.d.ts +4 -1
  138. package/src/lib/model/ai-site-kinds.js +34 -6
  139. package/src/lib/model/ai-site-kinds.js.map +1 -1
  140. package/src/lib/runtime/ai-dataset-generation.d.ts +77 -0
  141. package/src/lib/runtime/ai-dataset-generation.js +127 -0
  142. package/src/lib/runtime/ai-dataset-generation.js.map +1 -0
  143. package/src/lib/runtime/ai-doctrine-validators.d.ts +77 -1
  144. package/src/lib/runtime/ai-doctrine-validators.js +280 -6
  145. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  146. package/src/lib/runtime/ai-doctrine.js +10 -4
  147. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  148. package/src/lib/runtime/ai-node-tree.d.ts +2 -0
  149. package/src/lib/runtime/ai-node-tree.js +16 -0
  150. package/src/lib/runtime/ai-node-tree.js.map +1 -1
  151. package/src/lib/runtime/ai-palette.generated.js +53 -7
  152. package/src/lib/runtime/ai-palette.generated.js.map +1 -1
  153. package/src/lib/server/ai-jobs-cancel.d.ts +13 -5
  154. package/src/lib/server/ai-jobs-cancel.js +27 -9
  155. package/src/lib/server/ai-jobs-cancel.js.map +1 -1
  156. package/src/lib/server/ai-jobs-gate.d.ts +12 -2
  157. package/src/lib/server/ai-jobs-gate.js +20 -9
  158. package/src/lib/server/ai-jobs-gate.js.map +1 -1
  159. package/src/lib/tools/ai-dataset-tool.d.ts +68 -0
  160. package/src/lib/tools/ai-dataset-tool.js +231 -0
  161. package/src/lib/tools/ai-dataset-tool.js.map +1 -0
  162. package/src/lib/usage/ai-usage-meter.d.ts +2 -1
  163. package/src/lib/usage/ai-usage-meter.js +17 -1
  164. package/src/lib/usage/ai-usage-meter.js.map +1 -1
  165. package/src/lib/usage/ai-usage-wire.d.ts +6 -0
  166. package/src/lib/usage/ai-usage-wire.js.map +1 -1
  167. package/src/lib/usage/assist-usage.d.ts +7 -0
  168. package/src/lib/usage/assist-usage.js +14 -4
  169. package/src/lib/usage/assist-usage.js.map +1 -1
  170. package/src/lib/usage/free-ai-credits-left.d.ts +7 -0
  171. package/src/lib/usage/free-ai-credits-left.js +30 -4
  172. package/src/lib/usage/free-ai-credits-left.js.map +1 -1
@@ -27,51 +27,75 @@ import { type AiLayoutPictureSlot, type AiLayoutPictureSource } from '../layout-
27
27
  * server door (`core.media-ingest`), and builds no source at all when either
28
28
  * is missing, so a deployment without a key behaves exactly as before.
29
29
  *
30
- * For each slot, in document order:
30
+ * What the live starts of 2026-10-10 taught (Juniper Clay Works, a ceramic
31
+ * artist's portfolio, and Willow Wick Candles, a candle store), each photo
32
+ * traced through the library's cached answers:
31
33
  *
32
- * 1. **Search.** Plain words. The hero asks for the kind of business (the
33
- * head of the site's business type, "yoga studio" from "a family-owned
34
- * yoga studio in Austin"). Any other picture asks for its SUBJECT: the
35
- * noun phrase that opens the alt text the model wrote, its filler
36
- * adjectives dropped ("serving bowl" from "A beautiful hand-thrown serving
37
- * bowl on a linen cloth"), qualified by the site's craft where the phrase
38
- * does not already say it ("serving bowl ceramic" for a ceramics studio).
39
- * An about picture asks for people. The orientation and a minimum size
40
- * come from the slot's frame. The provider caches every search for a day
41
- * and keeps its own rate limit; one page never asks the same words twice.
42
- * 2. **Rank.** A picture of a thing must show the thing: every hit is scored
43
- * by how many of the subject's words its tags, its description and its
44
- * page's address name (singular and plural alike, the head noun counting
45
- * double), and a hit naming none of them never fills a picture of a
46
- * thing. The live Juniper Clay start put crackers under "Serving bowl"
47
- * and plants under "Espresso cup". Among the best-scored hits the job's
48
- * seed picks, so two sites built from the same words rarely open with the
49
- * same photo while one job always picks the same.
50
- * 3. **Never twice.** A photo is placed once per job: not twice on a page,
34
+ * - The site's words were read as "portfolio" and "online" — the kind of
35
+ * SITE, not the craft — so every search said "serving bowl portfolio" and
36
+ * the hero asked for "portfolio": a wallet, fashion models, and a blank
37
+ * paper mockup that read as an empty panel beside the brushes.
38
+ * - A hit naming the object anywhere won: a robin tagged "food bowl" filled
39
+ * "Speckled serving bowl", a lilac branch tagged "bud, vase" filled "Tall
40
+ * bud vase", letterpress type tagged "set" filled "Nesting bowl set" (its
41
+ * head noun was read as "set"), and an antique tea set tagged "brown
42
+ * candle" filled "Candle Gift Set".
43
+ * - The page's 20 seconds ran out after four photos (each copy took ~5s, one
44
+ * after another), and the slots left took the starter photos: the laptop
45
+ * desk with pink roses under "Candle Wick Trimmer" and a work card, and the
46
+ * windowsill plants under another.
47
+ *
48
+ * So, for each slot:
49
+ *
50
+ * 1. **The site's terms** ({@link aiStockSiteTerms}): the business is the
51
+ * first clause of its type that says more than what kind of site it is
52
+ * ("ceramic artist" from "a portfolio for a ceramic artist who makes
53
+ * stoneware bowls"), its craft one word ("ceramic"), and its DOMAIN the
54
+ * words a photo of its world names: the craft, the business type's own
55
+ * nouns ("stoneware", "soy") and, for common crafts, their kin ("pottery",
56
+ * "clay", "wax"). Its broad searches ask for the world itself ("handmade
57
+ * ceramics", "pottery").
58
+ * 2. **Search.** A picture of a thing asks for its subject — the noun phrase
59
+ * of the caption, filler dropped — qualified by the craft where it does
60
+ * not already name the domain ("ceramic serving bowl"), then the craft and
61
+ * the object alone ("ceramic bowl"), then the broad searches. A hero asks
62
+ * for the business, then broad; an about picture for the business's
63
+ * people, then broad. The orientation and a minimum size come from the
64
+ * slot's frame.
65
+ * 3. **Accept, or reject.** A hit tagged as a mockup, a blank or a template
66
+ * never fills anything. A picture of a thing takes only a hit naming its
67
+ * OBJECT (the head noun, past "set", "gift", "kit": "bowl" in "nesting
68
+ * bowl set", "candle" in "candle gift set") AND either the site's domain
69
+ * or the subject's own two-word phrase ("bud vase"). A broad, hero or
70
+ * about search takes only a hit naming the domain. The accepted are
71
+ * ranked: the object in the hit's first tags (what the photo is OF) over
72
+ * a mention in its last, the subject's other words, the domain. Among
73
+ * equals the job's seed picks, so two sites differ and one job repeats.
74
+ * 4. **Never twice.** A photo is placed once per job: not twice on a page,
51
75
  * and not on a page when another page (or another pass, in this process)
52
- * of the same job already placed it — the maker's portrait in About is
53
- * never a vase in Selected work. The caller hands in what the job's other
54
- * pages hold (`avoid`); a pass repeated over its own page keeps its own.
55
- * 4. **Fall back.** A picture of a thing nothing relevant answered asks once
56
- * more for the place itself ("ceramics studio interior"), a neutral photo
57
- * any caption sits under, before it is left to a starter photo.
58
- * 5. **Keep.** A photo the site's library already holds (by its source key)
59
- * is reused; otherwise its bytes are downloaded from the library and
60
- * stored in the site's own media library as the member who started the
61
- * job, credited to its photographer. The page names the site's asset,
62
- * never the library's address.
76
+ * of the same job already placed it. The caller hands in what the job's
77
+ * other pages hold (`avoid`); a pass repeated over its own page keeps its
78
+ * own.
79
+ * 5. **Keep, all at once.** The choosing is done first, slot by slot; the
80
+ * copies then run side by side, a few at a time, so a page of eight
81
+ * pictures takes about as long as two. A photo the site's library already
82
+ * holds (by its source key) is reused; otherwise its bytes are copied
83
+ * into the site's own library as the member who started the job, credited
84
+ * to its photographer. A copy that fails tries the slot's next accepted
85
+ * hit.
63
86
  *
64
- * A slot that finds nothing, any error, a refusal from the library (its
65
- * storage band, say) or the time running out leaves the slot to a starter
66
- * photo. Nothing here throws, and none of it is an AI model call: photos cost
67
- * no AI credits.
87
+ * A slot nothing acceptable answered — the library down, refusing, or out
88
+ * of time — is left `null` for the starter photos. A named object is never
89
+ * given one while the library answers anything of the site's world: the
90
+ * broad searches come first. Nothing here throws, and none of it is an AI
91
+ * model call: photos cost no AI credits.
68
92
  */
69
93
  /** Wall clock the whole page's photos may take, inside the step's own signal. */
70
- export declare const AI_LAYOUT_STOCK_PHOTOS_BUDGET_MS = 20000;
94
+ export declare const AI_LAYOUT_STOCK_PHOTOS_BUDGET_MS = 30000;
71
95
  /** Searches one page may send to the provider; a repeated query is answered from the page's own memory. */
72
- export declare const AI_LAYOUT_STOCK_SEARCHES_PER_PAGE = 12;
96
+ export declare const AI_LAYOUT_STOCK_SEARCHES_PER_PAGE = 18;
73
97
  /** The hits a pick is made among. */
74
- export declare const AI_LAYOUT_STOCK_PICK_WINDOW = 8;
98
+ export declare const AI_LAYOUT_STOCK_PICK_WINDOW = 40;
75
99
  /** The largest photo copied: inside one direct upload. */
76
100
  export declare const AI_LAYOUT_STOCK_MAX_BYTES: number;
77
101
  /**
@@ -87,17 +111,38 @@ export declare const AI_STOCK_PHOTO_PAGES_INPUT = "stockPhotoPages";
87
111
  export declare function aiStockStem(word: string): string;
88
112
  /**
89
113
  * The kind of business in a few words: the first clause of the business
90
- * type, before a place or an audience, its last three content words (the
91
- * head of an English noun phrase is at its end).
114
+ * type that says more than what kind of site it is, before a place, an
115
+ * audience or what it makes, filler dropped, its last three words (the head
116
+ * of an English noun phrase is at its end). "ceramic artist" from "a
117
+ * portfolio for a ceramic artist who makes stoneware bowls"; "candle shop"
118
+ * from "a small-batch candle shop selling hand-poured soy candles online".
92
119
  */
93
120
  export declare function aiStockBusinessWords(businessType: string): string;
94
121
  /**
95
122
  * The business's craft in one word: the last of its words that is not the
96
- * place it is done in, singular — "ceramic" from "small-batch ceramics
97
- * studio", "yoga" from "yoga studio". Empty when the business is only a
98
- * place ("a shop").
123
+ * place it is done in nor the person doing it, singular — "ceramic" from
124
+ * "ceramics studio" or "ceramic artist", "yoga" from "yoga studio". Empty
125
+ * when the business is only a place ("a shop").
99
126
  */
100
127
  export declare function aiStockCraftWords(business: string): string;
128
+ /** What a site's photos are searched and judged by (AGL-3660). */
129
+ export interface AiStockSiteTerms {
130
+ /** The kind of business, in a few words: "ceramic artist". */
131
+ business: string;
132
+ /** Its craft, one singular word: "ceramic". */
133
+ craft: string;
134
+ /**
135
+ * The stems a photo of the site's world names: the business's own words,
136
+ * what the things it makes are made of, and the craft's kin. Empty for a
137
+ * site whose words name no world (a type left blank), and then no hit is
138
+ * held to it.
139
+ */
140
+ domain: string[];
141
+ /** The searches for the site's world itself, broadest last. */
142
+ broad: string[];
143
+ }
144
+ /** The site's terms, read from its business type. */
145
+ export declare function aiStockSiteTerms(businessType: string): AiStockSiteTerms;
101
146
  /**
102
147
  * A picture's subject in a few words (AGL-3660): the noun phrase its alt
103
148
  * text opens with — its first clause holding more than filler, cut where a
@@ -105,47 +150,73 @@ export declare function aiStockCraftWords(business: string): string;
105
150
  * head noun is the last) — else its section's name.
106
151
  */
107
152
  export declare function aiStockSubjectWords(alt: string, sectionName: string): string;
153
+ /**
154
+ * The thing a subject shows, one singular word: its last word that is not
155
+ * a set or a wrapper of it — "bowl" from "nesting bowl set", "candle" from
156
+ * "candle gift set", "vase" from "bud vase". Its last word when every word
157
+ * is one ("gift set").
158
+ */
159
+ export declare function aiStockObjectWord(subject: string): string;
108
160
  /** The frame's orientation: a wide frame wants a landscape photo, a tall one a portrait. */
109
161
  export declare function aiStockOrientation(aspect: number): StockPhotoOrientation;
110
162
  /**
111
- * One search a slot tries. A gallery picture's searches must find a hit
112
- * naming its subject; a `neutral` one asks for the place itself, which any
113
- * caption sits under.
163
+ * One search a slot tries. A `broad` one asks for the site's world and
164
+ * takes any hit of it; any other picture of a thing takes only a hit naming
165
+ * the thing.
114
166
  */
115
167
  export interface AiStockSearch extends StockPhotoSearchRequest {
116
- neutral?: boolean;
168
+ broad?: boolean;
169
+ /** The words its hits are scored by, where they are not the slot's own subject (a product's searches, AGL-3676). */
170
+ subject?: string;
171
+ /** A word every hit must name: a product's photo names the shop's category (AGL-3676). */
172
+ requires?: string;
117
173
  }
118
- /** The searches a slot tries, in order, most specific first, each distinct. */
119
- export declare function aiStockSearchesFor(slot: Pick<AiLayoutPictureSlot, 'role' | 'alt' | 'aspect'>, words: {
120
- business: string;
121
- subject: string;
122
- craft?: string;
123
- }): AiStockSearch[];
124
174
  /**
125
- * How well a hit names a subject (AGL-3660): each subject word its tags, its
126
- * description or its page's address names counts once, the head noun (the
127
- * subject's last word) twice, and a craft word a quarter, as a tiebreak.
128
- * Zero when it names none of the subject.
175
+ * A product's searches (AGL-3676), most specific first: each of its subjects
176
+ * — its name's noun phrase, then its photo's — with the shop's category
177
+ * where the phrase does not already say it ("candle gift box"), then the
178
+ * category alone, a plain photo of what the shop sells. Every one must find a
179
+ * hit naming the category, so no product is ever filled with a lifestyle shot
180
+ * of something else: the beta.237 Willow Wick start put a laptop and roses
181
+ * under "Candle Wick Trimmer" and an antique tea set under "Candle Gift Set".
129
182
  */
130
- export declare function aiStockRelevance(photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>, terms: {
131
- subject: string;
132
- craft?: string;
133
- }): number;
134
- export interface AiStockRankOptions {
135
- /** The words a hit is scored by; none, and every hit scores alike. */
183
+ export declare function aiStockProductSearches(slot: Pick<AiLayoutPictureSlot, 'aspect' | 'product'>, craft: string): AiStockSearch[];
184
+ /** The searches a slot tries, in order, most specific first, each distinct. */
185
+ export declare function aiStockSearchesFor(slot: Pick<AiLayoutPictureSlot, 'role' | 'alt' | 'aspect'>, terms: Pick<AiStockSiteTerms, 'business' | 'craft' | 'domain' | 'broad'>, subject: string): AiStockSearch[];
186
+ /** What a hit is judged by. */
187
+ export interface AiStockJudgement {
188
+ /** The words the picture is of; empty for a picture of the site's world. */
136
189
  subject?: string;
137
- craft?: string;
138
- /** A hit naming none of the subject is no candidate at all. */
190
+ /** The site's domain stems ({@link AiStockSiteTerms.domain}). */
191
+ domain?: readonly string[];
192
+ /**
193
+ * Whether a hit must name the subject's object. A broad search, a hero
194
+ * and an about picture need only name the domain.
195
+ */
139
196
  strict?: boolean;
197
+ /** A word every hit must name: a product's photo names the shop's category (AGL-3676). */
198
+ requires?: string;
140
199
  }
141
200
  /**
142
- * A search's hits in the order they are tried (AGL-3660): those not placed
143
- * yet, among the first few, best-scored first; the seed turns the hits that
144
- * score alike, so two jobs differ and one job repeats itself.
201
+ * How well a hit shows what a slot needs (AGL-3660), or 0 when it must not
202
+ * fill it: a mockup or a blank never; a picture of a thing only when the hit
203
+ * names its object AND either the site's world or the subject's own
204
+ * two-word phrase ("bud vase", "wick trimmer"); anything else only when it
205
+ * names the site's world (when the site names one). Among the accepted, the
206
+ * object among the hit's first tags counts 4 (a mention among its last, 2),
207
+ * the subject's two-word phrase 3, each of its other words 1, and the
208
+ * site's world 1, plus a quarter when it is among the first tags.
209
+ */
210
+ export declare function aiStockRelevance(photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>, judgement: AiStockJudgement): number;
211
+ /**
212
+ * A search's acceptable hits in the order they are tried (AGL-3660): those
213
+ * not placed yet, among the first few the library returned, those it must
214
+ * not take dropped ({@link aiStockRelevance}), best first; the seed turns
215
+ * the hits that score alike, so two jobs differ and one job repeats itself.
145
216
  */
146
- export declare function aiStockRank(photos: readonly StockPhoto[], used: ReadonlySet<string>, seed: string, options?: AiStockRankOptions): StockPhoto[];
217
+ export declare function aiStockRank(photos: readonly StockPhoto[], used: ReadonlySet<string>, seed: string, judgement?: AiStockJudgement): StockPhoto[];
147
218
  /** The pick among a search's hits: the first {@link aiStockRank} would try, or `null`. */
148
- export declare function aiStockPick(photos: readonly StockPhoto[], used: ReadonlySet<string>, seed: string, options?: AiStockRankOptions): StockPhoto | null;
219
+ export declare function aiStockPick(photos: readonly StockPhoto[], used: ReadonlySet<string>, seed: string, judgement?: AiStockJudgement): StockPhoto | null;
149
220
  /**
150
221
  * The library photos a stored page already shows: every `image` whose
151
222
  * source is the site's media reference. Starter photos are the platform's,
@@ -171,6 +242,8 @@ export interface AiLayoutStockPhotoSourceInput {
171
242
  jobId?: string;
172
243
  /** Asset srcs or source keys the job's other pages already show. */
173
244
  avoid?: readonly string[];
245
+ /** The most searches this source sends; a page's own bound where absent. A store's products search more (AGL-3676). */
246
+ searches?: number;
174
247
  signal?: AbortSignal;
175
248
  }
176
249
  export interface AiLayoutStockPhotoDeps {