@aglyn/plugins-ai 1.0.0-beta.253 → 1.0.0-beta.255

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 (87) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-site-start-card.component.js +16 -8
  3. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  4. package/src/lib/components/assist-signals-page.component.js +5 -6
  5. package/src/lib/components/assist-signals-page.component.js.map +1 -1
  6. package/src/lib/components/staff-org-ai-card.component.d.ts +0 -10
  7. package/src/lib/components/staff-org-ai-card.component.js +10 -79
  8. package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
  9. package/src/lib/components/staff-org-ai-conversations.component.js +8 -41
  10. package/src/lib/components/staff-org-ai-conversations.component.js.map +1 -1
  11. package/src/lib/components/staff-user-ai-usage-card.component.js +2 -1
  12. package/src/lib/components/staff-user-ai-usage-card.component.js.map +1 -1
  13. package/src/lib/jobs/ai-job-page-language.d.ts +14 -1
  14. package/src/lib/jobs/ai-job-page-language.js +18 -3
  15. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  16. package/src/lib/jobs/ai-job-page-step.js +17 -3
  17. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  18. package/src/lib/jobs/ai-job-plan-step.js +17 -7
  19. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  20. package/src/lib/jobs/ai-job-site-content.d.ts +32 -16
  21. package/src/lib/jobs/ai-job-site-content.js +43 -20
  22. package/src/lib/jobs/ai-job-site-content.js.map +1 -1
  23. package/src/lib/jobs/ai-job-site-step.d.ts +3 -0
  24. package/src/lib/jobs/ai-job-site-step.js +23 -11
  25. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  26. package/src/lib/jobs/ai-layout-stock-photos.d.ts +30 -0
  27. package/src/lib/jobs/ai-layout-stock-photos.js +76 -8
  28. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  29. package/src/lib/jobs/fixtures/ai-dental-site-plan-recording.d.ts +95 -0
  30. package/src/lib/jobs/fixtures/ai-dental-site-plan-recording.js +137 -0
  31. package/src/lib/jobs/fixtures/ai-dental-site-plan-recording.js.map +1 -0
  32. package/src/lib/layout-language/ai-layout-labels.d.ts +2 -0
  33. package/src/lib/layout-language/ai-layout-labels.js +12 -6
  34. package/src/lib/layout-language/ai-layout-labels.js.map +1 -1
  35. package/src/lib/layout-language/ai-layout-pictures.d.ts +12 -3
  36. package/src/lib/layout-language/ai-layout-pictures.js +6 -3
  37. package/src/lib/layout-language/ai-layout-pictures.js.map +1 -1
  38. package/src/lib/model/ai-plan-capabilities.d.ts +5 -0
  39. package/src/lib/model/ai-plan-capabilities.js.map +1 -1
  40. package/src/lib/model/ai-products-bulk.d.ts +48 -0
  41. package/src/lib/model/ai-products-bulk.js +56 -0
  42. package/src/lib/model/ai-products-bulk.js.map +1 -0
  43. package/src/lib/model/ai-products.d.ts +2 -4
  44. package/src/lib/model/ai-products.js +4 -9
  45. package/src/lib/model/ai-products.js.map +1 -1
  46. package/src/lib/model/ai-site-job.d.ts +32 -12
  47. package/src/lib/model/ai-site-job.js +35 -20
  48. package/src/lib/model/ai-site-job.js.map +1 -1
  49. package/src/lib/model/ai-site-kinds.d.ts +5 -5
  50. package/src/lib/model/ai-site-kinds.js +5 -5
  51. package/src/lib/model/ai-site-kinds.js.map +1 -1
  52. package/src/lib/providers/anthropic.js +26 -5
  53. package/src/lib/providers/anthropic.js.map +1 -1
  54. package/src/lib/providers/contract.d.ts +10 -0
  55. package/src/lib/providers/contract.js.map +1 -1
  56. package/src/lib/runtime/ai-doctrine-validators.d.ts +20 -0
  57. package/src/lib/runtime/ai-doctrine-validators.js +53 -1
  58. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  59. package/src/lib/runtime/ai-doctrine.d.ts +11 -0
  60. package/src/lib/runtime/ai-doctrine.js +9 -4
  61. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  62. package/src/lib/runtime/ai-runtime.d.ts +6 -0
  63. package/src/lib/runtime/ai-runtime.js +10 -0
  64. package/src/lib/runtime/ai-runtime.js.map +1 -1
  65. package/src/lib/server/ai-admin-conversations.d.ts +2 -0
  66. package/src/lib/server/ai-admin-conversations.js +40 -7
  67. package/src/lib/server/ai-admin-conversations.js.map +1 -1
  68. package/src/lib/server/ai-admin-org.js +28 -2
  69. package/src/lib/server/ai-admin-org.js.map +1 -1
  70. package/src/lib/server/ai-admin-orgs-spend.js +19 -1
  71. package/src/lib/server/ai-admin-orgs-spend.js.map +1 -1
  72. package/src/lib/server/ai-admin-signals.js +11 -3
  73. package/src/lib/server/ai-admin-signals.js.map +1 -1
  74. package/src/lib/server/ai-admin-user.js +11 -1
  75. package/src/lib/server/ai-admin-user.js.map +1 -1
  76. package/src/lib/usage/ai-usage-wire.d.ts +5 -2
  77. package/src/lib/usage/ai-usage-wire.js +5 -2
  78. package/src/lib/usage/ai-usage-wire.js.map +1 -1
  79. package/src/lib/usage/assist-signals-view.d.ts +123 -0
  80. package/src/lib/usage/assist-signals-view.js +151 -0
  81. package/src/lib/usage/assist-signals-view.js.map +1 -0
  82. package/src/lib/usage/staff-org-ai-conversations-view.d.ts +51 -0
  83. package/src/lib/usage/staff-org-ai-conversations-view.js +127 -0
  84. package/src/lib/usage/staff-org-ai-conversations-view.js.map +1 -0
  85. package/src/lib/usage/staff-org-ai-view.d.ts +181 -0
  86. package/src/lib/usage/staff-org-ai-view.js +263 -0
  87. package/src/lib/usage/staff-org-ai-view.js.map +1 -0
@@ -400,6 +400,36 @@ export declare function aiStockPick(photos: readonly StockPhoto[], used: Readonl
400
400
  export declare function aiStockPlacedSrcs(nodes: NodesMap | null | undefined): string[];
401
401
  /** Forgets every job's placed photos; for specs. */
402
402
  export declare function aiStockForgetJobPhotos(): void;
403
+ /**
404
+ * THE WORDS A PLACED STOCK PHOTO IS DESCRIBED BY (AGL-3805).
405
+ *
406
+ * A slot's alt text is the model's, written for the picture the page asked
407
+ * for before any photo was found, and a slot is filled by whatever the
408
+ * library answers for its search: a hero searched by the business, a gallery
409
+ * picture by its subject, a site in another language by English words alone.
410
+ * Kept as written, it described a photo the page does not show: the beta.253
411
+ * Panadería La Concha Dorada start (job eg4maZMGtN) captioned a round cake
412
+ * dusted "HOME MADE" on a cloth "Conchas recién horneadas sobre una charola en
413
+ * el mostrador de la panadería", and none of its nine photos showed what its
414
+ * words said: a birthday cake with candles was "the family kneading pan
415
+ * dulce", a plate of macarons the shop's display case.
416
+ *
417
+ * So the photo placed answers for its own words. `null` keeps the slot's: on
418
+ * an English site whose words name what the photo is OF — a word of their
419
+ * subject (`aiStockSubjectWords`: the noun phrase they open with, before any
420
+ * setting) among the hit's first tags or its page's address, so "conchas on
421
+ * a tray at the bakery counter" is never kept for a loaf tagged "bakery".
422
+ * Otherwise the photo is described by the
423
+ * library's own words: its description where it writes one (a Pexels hit's
424
+ * `alt`), else its first tags, the things it shows. The libraries write in
425
+ * English, and no model translates them, so a site in another language takes
426
+ * the platform's own words for an illustrative photo in its language
427
+ * (`aiLayoutLabel`), true of any photo, as does a hit with no words at all.
428
+ */
429
+ export declare function aiStockPhotoAlt(photo: Pick<StockPhoto, 'tags' | 'alt' | 'pageUrl'>, slot: Pick<AiLayoutPictureSlot, 'alt' | 'product'>, input?: {
430
+ language?: string;
431
+ sectionName?: string;
432
+ }): string | null;
403
433
  export interface AiLayoutStockPhotoSourceInput {
404
434
  hostId: string;
405
435
  /** The member the photos are stored as: the job's creator. */
@@ -18,7 +18,7 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
18
18
  import { STOCK_PHOTO_QUERY_MAX_CHARS, stockPhotoProvider, stockPhotoSourceKey } from "@aglyn/aglyn/plugin-manager/stock-photo-provider";
19
19
  import { aiLayoutSeedNumber } from "../layout-language/ai-layout-pictures.js";
20
20
  import { aiStorefrontSays } from "../layout-language/ai-layout-storefront.js";
21
- import { aiLayoutSpeaksOtherThanEnglish } from "../layout-language/ai-layout-labels.js";
21
+ import { aiLayoutLabel, aiLayoutSpeaksOtherThanEnglish } from "../layout-language/ai-layout-labels.js";
22
22
  import { aiSiteKindOfInputs } from "../model/ai-site-kinds.js";
23
23
  import { aiStockBusinessNoun } from "./ai-stock-business-nouns.js";
24
24
  /**
@@ -1766,6 +1766,54 @@ function jobPhotos(key) {
1766
1766
  /** Forgets every job's placed photos; for specs. */ export function aiStockForgetJobPhotos() {
1767
1767
  JOB_PHOTOS.clear();
1768
1768
  }
1769
+ /** The longest description of a photo written from the library's own words. */ const AI_STOCK_ALT_MAX = 160;
1770
+ /**
1771
+ * THE WORDS A PLACED STOCK PHOTO IS DESCRIBED BY (AGL-3805).
1772
+ *
1773
+ * A slot's alt text is the model's, written for the picture the page asked
1774
+ * for before any photo was found, and a slot is filled by whatever the
1775
+ * library answers for its search: a hero searched by the business, a gallery
1776
+ * picture by its subject, a site in another language by English words alone.
1777
+ * Kept as written, it described a photo the page does not show: the beta.253
1778
+ * Panadería La Concha Dorada start (job eg4maZMGtN) captioned a round cake
1779
+ * dusted "HOME MADE" on a cloth "Conchas recién horneadas sobre una charola en
1780
+ * el mostrador de la panadería", and none of its nine photos showed what its
1781
+ * words said: a birthday cake with candles was "the family kneading pan
1782
+ * dulce", a plate of macarons the shop's display case.
1783
+ *
1784
+ * So the photo placed answers for its own words. `null` keeps the slot's: on
1785
+ * an English site whose words name what the photo is OF — a word of their
1786
+ * subject (`aiStockSubjectWords`: the noun phrase they open with, before any
1787
+ * setting) among the hit's first tags or its page's address, so "conchas on
1788
+ * a tray at the bakery counter" is never kept for a loaf tagged "bakery".
1789
+ * Otherwise the photo is described by the
1790
+ * library's own words: its description where it writes one (a Pexels hit's
1791
+ * `alt`), else its first tags, the things it shows. The libraries write in
1792
+ * English, and no model translates them, so a site in another language takes
1793
+ * the platform's own words for an illustrative photo in its language
1794
+ * (`aiLayoutLabel`), true of any photo, as does a hit with no words at all.
1795
+ */ export function aiStockPhotoAlt(photo, slot, input = {}) {
1796
+ var _ref, _photo_alt, _photo_tags;
1797
+ var _slot_product;
1798
+ if (aiLayoutSpeaksOtherThanEnglish(input.language)) return aiLayoutLabel('illustrativePhoto', input.language);
1799
+ const { lead } = hitWords(photo);
1800
+ const named = [
1801
+ slot.alt,
1802
+ ...(_ref = (_slot_product = slot.product) == null ? void 0 : _slot_product.subjects) != null ? _ref : []
1803
+ ].flatMap((words)=>{
1804
+ var _input_sectionName;
1805
+ return stemList(aiStockSubjectWords(words, (_input_sectionName = input.sectionName) != null ? _input_sectionName : ''));
1806
+ });
1807
+ if (named.some((word)=>lead.has(word))) return null;
1808
+ const own = ((_photo_alt = photo.alt) != null ? _photo_alt : '').replace(/\s+/g, ' ').trim();
1809
+ if (own) return own.length > AI_STOCK_ALT_MAX ? `${own.slice(0, AI_STOCK_ALT_MAX).replace(/\s+\S*$/, '')}…` : own;
1810
+ const tags = [
1811
+ ...new Set(((_photo_tags = photo.tags) != null ? _photo_tags : []).map((tag)=>tag.replace(/\s+/g, ' ').trim().toLowerCase()).filter(Boolean))
1812
+ ].slice(0, 3);
1813
+ if (!tags.length) return aiLayoutLabel('illustrativePhoto', input.language);
1814
+ const said = tags.join(', ');
1815
+ return `${said.charAt(0).toUpperCase()}${said.slice(1)}`;
1816
+ }
1769
1817
  const EXTENSIONS = {
1770
1818
  'image/jpeg': 'jpg',
1771
1819
  'image/png': 'png',
@@ -1906,8 +1954,20 @@ const EXTENSIONS = {
1906
1954
  answers.set(key, asked);
1907
1955
  return asked;
1908
1956
  };
1957
+ /** The photo's own words where the slot's do not describe it ({@link aiStockPhotoAlt}). */ const altFor = (photo, slot)=>{
1958
+ var _input_sectionNames_slot_sectionIndex;
1959
+ return aiStockPhotoAlt(photo, slot, _extends({}, input.language ? {
1960
+ language: input.language
1961
+ } : {}, {
1962
+ sectionName: (_input_sectionNames_slot_sectionIndex = input.sectionNames[slot.sectionIndex]) != null ? _input_sectionNames_slot_sectionIndex : ''
1963
+ }));
1964
+ };
1909
1965
  /** The photo placed in the site's library, a copy it holds or a new one; `null` when it cannot be placed. */ const keep = async (photo, slot, query, repeat = false)=>{
1910
1966
  const sourceKey = stockPhotoSourceKey(photo);
1967
+ const alt = altFor(photo, slot);
1968
+ const described = alt === null ? {} : {
1969
+ alt
1970
+ };
1911
1971
  try {
1912
1972
  var _EXTENSIONS_bytes_contentType;
1913
1973
  const kept = await ingest.findStockPhoto({
@@ -1919,11 +1979,11 @@ const EXTENSIONS = {
1919
1979
  // Held because a slot of this page or another page of the job shows it.
1920
1980
  if (!repeat && (placedSrcs.has(kept.src) || elsewhere(kept.src))) return null;
1921
1981
  remember(sourceKey, kept.src);
1922
- return {
1982
+ return _extends({
1923
1983
  src: kept.src,
1924
1984
  width: (_kept_width = kept.width) != null ? _kept_width : photo.width,
1925
1985
  height: (_kept_height = kept.height) != null ? _kept_height : photo.height
1926
- };
1986
+ }, described);
1927
1987
  }
1928
1988
  // A refusal to store (the storage band, a lockdown) holds for the
1929
1989
  // whole page, so the rest of it reuses what it can and copies nothing.
@@ -1940,7 +2000,7 @@ const EXTENSIONS = {
1940
2000
  fileName: `${photo.provider}-${photo.id}.${(_EXTENSIONS_bytes_contentType = EXTENSIONS[bytes.contentType]) != null ? _EXTENSIONS_bytes_contentType : 'jpg'}`,
1941
2001
  contentType: bytes.contentType,
1942
2002
  bytes: bytes.bytes,
1943
- alt: slot.alt,
2003
+ alt: alt != null ? alt : slot.alt,
1944
2004
  description: credit.text,
1945
2005
  stockPhoto: _extends({
1946
2006
  key: sourceKey,
@@ -1961,11 +2021,11 @@ const EXTENSIONS = {
1961
2021
  if (stored.ok) {
1962
2022
  var _stored_width, _stored_height;
1963
2023
  remember(sourceKey, stored.src);
1964
- return {
2024
+ return _extends({
1965
2025
  src: stored.src,
1966
2026
  width: (_stored_width = stored.width) != null ? _stored_width : photo.width,
1967
2027
  height: (_stored_height = stored.height) != null ? _stored_height : photo.height
1968
- };
2028
+ }, described);
1969
2029
  }
1970
2030
  storing = false;
1971
2031
  const refusal = stored;
@@ -2142,8 +2202,16 @@ const EXTENSIONS = {
2142
2202
  if (signal.aborted) return;
2143
2203
  const key = stockPhotoSourceKey(candidate);
2144
2204
  if (choice.repeat) {
2145
- var _placedByKey_get;
2146
- const placed = (_placedByKey_get = placedByKey.get(key)) != null ? _placedByKey_get : await keep(candidate, slot, choice.query, true);
2205
+ // Placed for another slot, it is described for this one.
2206
+ const shown = placedByKey.get(key);
2207
+ const alt = shown ? altFor(candidate, slot) : null;
2208
+ const placed = shown ? _extends({
2209
+ src: shown.src,
2210
+ width: shown.width,
2211
+ height: shown.height
2212
+ }, alt === null ? {} : {
2213
+ alt
2214
+ }) : await keep(candidate, slot, choice.query, true);
2147
2215
  if (placed) {
2148
2216
  photos[index] = placed;
2149
2217
  return;