@pixerate/editor 0.24.0 → 0.26.0

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 (162) hide show
  1. package/README.md +101 -1
  2. package/THIRD_PARTY_NOTICES.md +40 -0
  3. package/dist/agent/index.cjs +175 -11
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +18 -4
  6. package/dist/agent/index.d.ts +18 -4
  7. package/dist/agent/index.js +168 -4
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/{arrangeShortcuts-B8O3f8-P.d.cts → arrange-BICutYPk.d.cts} +243 -29
  10. package/dist/{arrangeShortcuts-sLlD2rSX.d.ts → arrange-BICutYPk.d.ts} +243 -29
  11. package/dist/builtins-CdPcLwwF.d.cts +176 -0
  12. package/dist/builtins-Chj6zv_O.d.ts +176 -0
  13. package/dist/canvas/index.cjs +8588 -1857
  14. package/dist/canvas/index.cjs.map +1 -1
  15. package/dist/canvas/index.d.cts +1847 -9
  16. package/dist/canvas/index.d.ts +1847 -9
  17. package/dist/canvas/index.js +8577 -1846
  18. package/dist/canvas/index.js.map +1 -1
  19. package/dist/chunk-3CC7OPUQ.cjs +831 -0
  20. package/dist/chunk-3CC7OPUQ.cjs.map +1 -0
  21. package/dist/chunk-4BVP64JJ.cjs +1406 -0
  22. package/dist/chunk-4BVP64JJ.cjs.map +1 -0
  23. package/dist/chunk-BVP3TSLH.cjs +69 -0
  24. package/dist/chunk-BVP3TSLH.cjs.map +1 -0
  25. package/dist/{chunk-OLZJXL4R.cjs → chunk-CS6NZWWA.cjs} +59 -25
  26. package/dist/chunk-CS6NZWWA.cjs.map +1 -0
  27. package/dist/{chunk-MCSJFWAO.cjs → chunk-EWCOFSCQ.cjs} +685 -100
  28. package/dist/chunk-EWCOFSCQ.cjs.map +1 -0
  29. package/dist/chunk-HDYMLS3X.cjs +409 -0
  30. package/dist/chunk-HDYMLS3X.cjs.map +1 -0
  31. package/dist/chunk-HRMEDT2L.js +1406 -0
  32. package/dist/chunk-HRMEDT2L.js.map +1 -0
  33. package/dist/{chunk-D27YFC46.cjs → chunk-IFHKKVXH.cjs} +382 -63
  34. package/dist/chunk-IFHKKVXH.cjs.map +1 -0
  35. package/dist/{chunk-PGNZKFQS.js → chunk-JOIREKL7.js} +137 -58
  36. package/dist/chunk-JOIREKL7.js.map +1 -0
  37. package/dist/chunk-KRGXUQ2Y.js +1696 -0
  38. package/dist/chunk-KRGXUQ2Y.js.map +1 -0
  39. package/dist/{chunk-3LV6RRPH.js → chunk-MHEPLBFB.js} +2 -2
  40. package/dist/chunk-MR2764X2.js +831 -0
  41. package/dist/chunk-MR2764X2.js.map +1 -0
  42. package/dist/{chunk-XNORY7M6.cjs → chunk-NFVBT3UZ.cjs} +166 -87
  43. package/dist/chunk-NFVBT3UZ.cjs.map +1 -0
  44. package/dist/chunk-NQF32I6Z.cjs +6478 -0
  45. package/dist/chunk-NQF32I6Z.cjs.map +1 -0
  46. package/dist/chunk-O5RYH2PG.js +69 -0
  47. package/dist/chunk-O5RYH2PG.js.map +1 -0
  48. package/dist/{chunk-ITBSKI26.js → chunk-Q2OHWD2A.js} +1064 -360
  49. package/dist/chunk-Q2OHWD2A.js.map +1 -0
  50. package/dist/{chunk-FODNLX5N.js → chunk-QJSOZFCZ.js} +38 -4
  51. package/dist/chunk-QJSOZFCZ.js.map +1 -0
  52. package/dist/{chunk-SML64VJG.cjs → chunk-RRREAOVM.cjs} +4 -4
  53. package/dist/{chunk-SML64VJG.cjs.map → chunk-RRREAOVM.cjs.map} +1 -1
  54. package/dist/{chunk-5S3Z4PPF.js → chunk-SWE3NPOU.js} +347 -28
  55. package/dist/chunk-SWE3NPOU.js.map +1 -0
  56. package/dist/chunk-TXXNBDQX.cjs +1696 -0
  57. package/dist/chunk-TXXNBDQX.cjs.map +1 -0
  58. package/dist/chunk-UBCFIABU.js +409 -0
  59. package/dist/chunk-UBCFIABU.js.map +1 -0
  60. package/dist/chunk-X7HXL2SB.js +6478 -0
  61. package/dist/chunk-X7HXL2SB.js.map +1 -0
  62. package/dist/{chunk-SBCZ6RN5.cjs → chunk-YOMYSFJU.cjs} +1163 -459
  63. package/dist/chunk-YOMYSFJU.cjs.map +1 -0
  64. package/dist/{chunk-3CN2WD3X.js → chunk-ZRNHGAQT.js} +661 -76
  65. package/dist/chunk-ZRNHGAQT.js.map +1 -0
  66. package/dist/commands/index.cjs +425 -4
  67. package/dist/commands/index.cjs.map +1 -1
  68. package/dist/commands/index.d.cts +39 -77
  69. package/dist/commands/index.d.ts +39 -77
  70. package/dist/commands/index.js +424 -3
  71. package/dist/commands/index.js.map +1 -1
  72. package/dist/compare/index.cjs +3 -3
  73. package/dist/compare/index.d.cts +1 -1
  74. package/dist/compare/index.d.ts +1 -1
  75. package/dist/compare/index.js +2 -2
  76. package/dist/controller-CxXGOEmy.d.cts +2038 -0
  77. package/dist/controller-CxXGOEmy.d.ts +2038 -0
  78. package/dist/{documents-BQjzJNe2.d.ts → documents-CHT1U5Vs.d.ts} +10 -0
  79. package/dist/{documents-KRTPhvst.d.cts → documents-Gp7wb0Me.d.cts} +10 -0
  80. package/dist/export/index.cjs +36 -0
  81. package/dist/export/index.cjs.map +1 -0
  82. package/dist/export/index.d.cts +243 -0
  83. package/dist/export/index.d.ts +243 -0
  84. package/dist/export/index.js +36 -0
  85. package/dist/export/index.js.map +1 -0
  86. package/dist/extensions/index.cjs +101 -6
  87. package/dist/extensions/index.cjs.map +1 -1
  88. package/dist/extensions/index.d.cts +18 -5
  89. package/dist/extensions/index.d.ts +18 -5
  90. package/dist/extensions/index.js +101 -6
  91. package/dist/generation/index.cjs +1013 -69
  92. package/dist/generation/index.cjs.map +1 -1
  93. package/dist/generation/index.d.cts +474 -13
  94. package/dist/generation/index.d.ts +474 -13
  95. package/dist/generation/index.js +976 -32
  96. package/dist/generation/index.js.map +1 -1
  97. package/dist/image-editor/index.cjs +3385 -1275
  98. package/dist/image-editor/index.cjs.map +1 -1
  99. package/dist/image-editor/index.d.cts +693 -128
  100. package/dist/image-editor/index.d.ts +693 -128
  101. package/dist/image-editor/index.js +3325 -1215
  102. package/dist/image-editor/index.js.map +1 -1
  103. package/dist/{index-fJrlkJCd.d.ts → index-B273Zllk.d.ts} +500 -7
  104. package/dist/{index-BhJBSm2d.d.cts → index-jcJwmBYt.d.cts} +500 -7
  105. package/dist/index.cjs +1603 -45
  106. package/dist/index.cjs.map +1 -1
  107. package/dist/index.d.cts +154 -27
  108. package/dist/index.d.ts +154 -27
  109. package/dist/index.js +1584 -26
  110. package/dist/index.js.map +1 -1
  111. package/dist/mention-text-CDnCFd3c.d.cts +53 -0
  112. package/dist/mention-text-CDnCFd3c.d.ts +53 -0
  113. package/dist/model-C1zApQM8.d.cts +219 -0
  114. package/dist/model-C1zApQM8.d.ts +219 -0
  115. package/dist/persistence/index.d.cts +3 -120
  116. package/dist/persistence/index.d.ts +3 -120
  117. package/dist/registry-CED5C0lA.d.cts +204 -0
  118. package/dist/registry-CED5C0lA.d.ts +204 -0
  119. package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.cts} +12 -1
  120. package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.ts} +12 -1
  121. package/dist/{registry-D32LpIc4.d.cts → registry-D0GADKc7.d.cts} +1 -1
  122. package/dist/{registry-evKTP4ls.d.ts → registry-DhVUZioj.d.ts} +1 -1
  123. package/dist/serializers/index.cjs +12 -4
  124. package/dist/serializers/index.cjs.map +1 -1
  125. package/dist/serializers/index.d.cts +41 -13
  126. package/dist/serializers/index.d.ts +41 -13
  127. package/dist/serializers/index.js +12 -4
  128. package/dist/spreadsheet/index.cjs +157 -3
  129. package/dist/spreadsheet/index.cjs.map +1 -1
  130. package/dist/spreadsheet/index.d.cts +534 -11
  131. package/dist/spreadsheet/index.d.ts +534 -11
  132. package/dist/spreadsheet/index.js +157 -3
  133. package/dist/storage-BpFfspHm.d.cts +120 -0
  134. package/dist/storage-BpFfspHm.d.ts +120 -0
  135. package/dist/tokens/index.cjs +115 -0
  136. package/dist/tokens/index.cjs.map +1 -0
  137. package/dist/tokens/index.d.cts +212 -0
  138. package/dist/tokens/index.d.ts +212 -0
  139. package/dist/tokens/index.js +115 -0
  140. package/dist/tokens/index.js.map +1 -0
  141. package/dist/{track-changes-BK5sVf4_.d.cts → track-changes-D_VAPELi.d.cts} +95 -11
  142. package/dist/{track-changes-CDjCrwKe.d.ts → track-changes-Db_fGEvx.d.ts} +95 -11
  143. package/package.json +15 -1
  144. package/dist/chunk-3CN2WD3X.js.map +0 -1
  145. package/dist/chunk-5S3Z4PPF.js.map +0 -1
  146. package/dist/chunk-D27YFC46.cjs.map +0 -1
  147. package/dist/chunk-FODNLX5N.js.map +0 -1
  148. package/dist/chunk-ITBSKI26.js.map +0 -1
  149. package/dist/chunk-MA2F5KHF.cjs +0 -3223
  150. package/dist/chunk-MA2F5KHF.cjs.map +0 -1
  151. package/dist/chunk-MCSJFWAO.cjs.map +0 -1
  152. package/dist/chunk-OLZJXL4R.cjs.map +0 -1
  153. package/dist/chunk-PGNZKFQS.js.map +0 -1
  154. package/dist/chunk-SBCZ6RN5.cjs.map +0 -1
  155. package/dist/chunk-U5KWZU4X.js +0 -3223
  156. package/dist/chunk-U5KWZU4X.js.map +0 -1
  157. package/dist/chunk-XNORY7M6.cjs.map +0 -1
  158. package/dist/controller-BhLLAoi8.d.cts +0 -1000
  159. package/dist/controller-BhLLAoi8.d.ts +0 -1000
  160. package/dist/types-DX4Mh4SL.d.cts +0 -217
  161. package/dist/types-DX4Mh4SL.d.ts +0 -217
  162. /package/dist/{chunk-3LV6RRPH.js.map → chunk-MHEPLBFB.js.map} +0 -0
@@ -9,7 +9,16 @@ require('../chunk-MKA3AHLV.cjs');
9
9
 
10
10
  var _chunkCPOKFNBGcjs = require('../chunk-CPOKFNBG.cjs');
11
11
 
12
+
13
+
14
+
15
+ var _chunkBVP3TSLHcjs = require('../chunk-BVP3TSLH.cjs');
16
+
12
17
  // src/generation/capabilities.ts
18
+ var REFERENCE_ROLE_NAME_REGEX = /^[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9])?$/;
19
+ function isReferenceRoleName(value) {
20
+ return typeof value === "string" && value.length <= 64 && REFERENCE_ROLE_NAME_REGEX.test(value);
21
+ }
13
22
  var REFERENCE_ROLES = [
14
23
  "start_frame",
15
24
  "end_frame",
@@ -32,6 +41,56 @@ var REFERENCE_ROLE_LABELS = {
32
41
  video_ref: "Video reference",
33
42
  audio_ref: "Audio reference"
34
43
  };
44
+ var REFERENCE_ROLE_ALIASES = {
45
+ reference: "image_ref",
46
+ image: "image_ref",
47
+ style: "style_ref",
48
+ character: "character_ref",
49
+ background: "background_ref",
50
+ "start-frame": "start_frame",
51
+ "first-frame": "start_frame",
52
+ first_frame: "start_frame",
53
+ "end-frame": "end_frame",
54
+ "last-frame": "end_frame",
55
+ last_frame: "end_frame",
56
+ "style-ref": "style_ref",
57
+ "character-ref": "character_ref",
58
+ "background-ref": "background_ref",
59
+ "image-ref": "image_ref",
60
+ "video-ref": "video_ref",
61
+ "audio-ref": "audio_ref",
62
+ video: "video_ref",
63
+ audio: "audio_ref"
64
+ };
65
+ var isBuiltinRole = (role) => REFERENCE_ROLES.includes(role);
66
+ function referenceRoleLabel(role, caps) {
67
+ const declared = _optionalChain([caps, 'optionalAccess', _ => _.references, 'optionalAccess', _2 => _2.roles, 'access', _3 => _3[role], 'optionalAccess', _4 => _4.label]);
68
+ if (declared) return declared;
69
+ if (isBuiltinRole(role)) return REFERENCE_ROLE_LABELS[role];
70
+ const words = String(role).replace(/[_-]+/g, " ").trim();
71
+ return words.charAt(0).toUpperCase() + words.slice(1);
72
+ }
73
+ function normalizeReferenceRole(role, caps) {
74
+ const name = String(role).trim();
75
+ if (caps ? !!_optionalChain([caps, 'access', _5 => _5.references, 'optionalAccess', _6 => _6.roles, 'access', _7 => _7[name]]) : isBuiltinRole(name)) return name;
76
+ const lower = name.toLowerCase();
77
+ if (_optionalChain([caps, 'optionalAccess', _8 => _8.references, 'optionalAccess', _9 => _9.roles, 'access', _10 => _10[lower]])) return lower;
78
+ if (!caps && isBuiltinRole(lower)) return lower;
79
+ return _nullishCoalesce(REFERENCE_ROLE_ALIASES[lower], () => ( (isBuiltinRole(lower) ? lower : name)));
80
+ }
81
+ function mediaTypeMatches(mediaType, accepts) {
82
+ if (!accepts || accepts.length === 0) return true;
83
+ if (!mediaType) return false;
84
+ const type = mediaType.split(";")[0].trim().toLowerCase();
85
+ const kind = type.split("/")[0];
86
+ return accepts.some((entry) => {
87
+ const pattern = entry.trim().toLowerCase();
88
+ if (pattern === "*" || pattern === "*/*" || pattern === type) return true;
89
+ if (!pattern.includes("/")) return pattern === kind;
90
+ if (pattern.endsWith("/*")) return pattern.slice(0, -2) === kind;
91
+ return false;
92
+ });
93
+ }
35
94
  var GENERATION_REQUEST_FIELDS = [
36
95
  "model",
37
96
  "prompt",
@@ -56,8 +115,12 @@ function seedCapability(value) {
56
115
  return value === true ? {} : value;
57
116
  }
58
117
  function supportedReferenceRoles(caps) {
59
- const roles = _nullishCoalesce(_optionalChain([caps, 'access', _ => _.references, 'optionalAccess', _2 => _2.roles]), () => ( {}));
60
- return REFERENCE_ROLES.filter((role) => (_nullishCoalesce(_optionalChain([roles, 'access', _3 => _3[role], 'optionalAccess', _4 => _4.max]), () => ( 0))) > 0);
118
+ const roles = _nullishCoalesce(_optionalChain([caps, 'access', _11 => _11.references, 'optionalAccess', _12 => _12.roles]), () => ( {}));
119
+ const builtin = REFERENCE_ROLES.filter((role) => (_nullishCoalesce(_optionalChain([roles, 'access', _13 => _13[role], 'optionalAccess', _14 => _14.max]), () => ( 0))) > 0);
120
+ const custom = Object.keys(roles).filter(
121
+ (role) => !isBuiltinRole(role) && isReferenceRoleName(role) && (_nullishCoalesce(_optionalChain([roles, 'access', _15 => _15[role], 'optionalAccess', _16 => _16.max]), () => ( 0))) > 0
122
+ );
123
+ return [...builtin, ...custom];
61
124
  }
62
125
  function supportedModes(caps) {
63
126
  const modes = ["generate"];
@@ -142,7 +205,7 @@ function snapToOption(value, options, rank, tie) {
142
205
  best = { option, distance, rank: r };
143
206
  }
144
207
  }
145
- return _optionalChain([best, 'optionalAccess', _5 => _5.option]);
208
+ return _optionalChain([best, 'optionalAccess', _17 => _17.option]);
146
209
  }
147
210
  function truncateText(text, max) {
148
211
  if (text.length <= max) return text;
@@ -250,7 +313,7 @@ var Planner = (_class = class {
250
313
  this.error(field, value, `Expected a number for ${label}.`);
251
314
  return void 0;
252
315
  }
253
- const options = _optionalChain([spec, 'access', _6 => _6.options, 'optionalAccess', _7 => _7.filter, 'call', _8 => _8(
316
+ const options = _optionalChain([spec, 'access', _18 => _18.options, 'optionalAccess', _19 => _19.filter, 'call', _20 => _20(
254
317
  (o) => (spec.min === void 0 || o >= spec.min) && (spec.max === void 0 || o <= spec.max)
255
318
  )]);
256
319
  if (options && options.length > 0) {
@@ -351,24 +414,85 @@ var Planner = (_class = class {
351
414
  }
352
415
  }
353
416
  roleCapability(role) {
354
- const cap = _optionalChain([this, 'access', _9 => _9.caps, 'access', _10 => _10.references, 'optionalAccess', _11 => _11.roles, 'access', _12 => _12[role]]);
417
+ const cap = _optionalChain([this, 'access', _21 => _21.caps, 'access', _22 => _22.references, 'optionalAccess', _23 => _23.roles, 'access', _24 => _24[role]]);
355
418
  if (cap && cap.max > 0) return cap;
356
419
  if (role === "mask" && this.caps.inpainting) return { max: 1 };
357
420
  return void 0;
358
421
  }
422
+ /** Turns `options.mentions` into references (appended after the request's own). */
423
+ addMentions() {
424
+ const mentions = this.options.mentions;
425
+ if (!_optionalChain([mentions, 'optionalAccess', _25 => _25.length])) return;
426
+ const refs = [..._nullishCoalesce(this.request.references, () => ( []))];
427
+ for (const mention of mentions) {
428
+ if (!mention || typeof mention.id !== "string" || mention.id === "") continue;
429
+ let role = _nullishCoalesce(mention.role, () => ( void 0));
430
+ if (!role) {
431
+ role = _nullishCoalesce(this.options.defaultMentionRole, () => ( this.inferRole(mention.mediaType)));
432
+ this.adjust(
433
+ `references.${role}`,
434
+ void 0,
435
+ role,
436
+ "defaulted",
437
+ `@${_nullishCoalesce(mention.label, () => ( mention.id))} has no role; using ${role}.`
438
+ );
439
+ }
440
+ refs.push({
441
+ id: mention.id,
442
+ role,
443
+ ...mention.url !== void 0 ? { url: mention.url } : {},
444
+ ...mention.mediaType !== void 0 ? { mediaType: mention.mediaType } : {},
445
+ ...mention.contentHash !== void 0 ? { contentHash: mention.contentHash } : {}
446
+ });
447
+ }
448
+ this.request.references = refs;
449
+ }
450
+ /** First role of the model (other than `mask`) whose `accepts` matches `mediaType`. */
451
+ inferRole(mediaType) {
452
+ for (const role of supportedReferenceRoles(this.caps)) {
453
+ if (role === "mask") continue;
454
+ const cap = this.roleCapability(role);
455
+ if (cap && (mediaType === void 0 || mediaTypeMatches(mediaType, cap.accepts))) return role;
456
+ }
457
+ return "image_ref";
458
+ }
359
459
  planReferences() {
360
460
  const refs = this.request.references;
361
461
  const allowDrop = !this.strict && (_nullishCoalesce(this.options.dropUnsupportedReferences, () => ( (this.strategy === "nearest" || this.strategy === "downgrade"))));
362
462
  const byRole = /* @__PURE__ */ new Map();
363
463
  const kept = [];
364
464
  const unsupported = /* @__PURE__ */ new Map();
365
- for (const [index, ref] of (_nullishCoalesce(refs, () => ( []))).entries()) {
366
- if (!ref || typeof ref.id !== "string" || ref.id === "" || !REFERENCE_ROLES.includes(ref.role)) {
367
- this.error(`references.${index}`, ref, "Each reference needs an `id` and a known `role`.");
465
+ for (const [index, original] of (_nullishCoalesce(refs, () => ( []))).entries()) {
466
+ let ref = original;
467
+ if (!ref || typeof ref.id !== "string" || ref.id === "" || !isReferenceRoleName(ref.role)) {
468
+ this.error(`references.${index}`, ref, "Each reference needs an `id` and a valid `role`.");
368
469
  continue;
369
470
  }
370
471
  if (!this.roleCapability(ref.role)) {
371
- unsupported.set(ref.role, (_nullishCoalesce(unsupported.get(ref.role), () => ( 0))) + 1);
472
+ const alias = normalizeReferenceRole(ref.role, this.caps);
473
+ if (alias !== ref.role && this.roleCapability(alias)) {
474
+ if (this.strict) {
475
+ this.error(`references.${ref.role}`, ref.role, `The model calls this role ${describe(alias)}.`);
476
+ continue;
477
+ }
478
+ this.adjust(
479
+ `references.${ref.role}`,
480
+ ref.role,
481
+ alias,
482
+ "snapped",
483
+ `Using the model's ${alias} role for ${describe(ref.role)}.`
484
+ );
485
+ ref = { ...ref, role: alias };
486
+ } else {
487
+ unsupported.set(ref.role, (_nullishCoalesce(unsupported.get(ref.role), () => ( 0))) + 1);
488
+ continue;
489
+ }
490
+ }
491
+ const cap = this.roleCapability(ref.role);
492
+ if (ref.mediaType !== void 0 && !mediaTypeMatches(ref.mediaType, cap.accepts)) {
493
+ const message = `${describe(ref.id)} is ${describe(ref.mediaType)}; ${ref.role} accepts ${list(_nullishCoalesce(cap.accepts, () => ( [])))}.`;
494
+ if (allowDrop) this.adjust(`references.${ref.role}`, ref.id, void 0, "dropped", message);
495
+ else this.error(`references.${ref.role}`, ref.id, message);
372
496
  continue;
373
497
  }
374
498
  const group = _nullishCoalesce(byRole.get(ref.role), () => ( []));
@@ -386,7 +510,10 @@ var Planner = (_class = class {
386
510
  else this.error(`references.${role}`, count, message);
387
511
  }
388
512
  const removed = /* @__PURE__ */ new Set();
389
- for (const role of REFERENCE_ROLES) {
513
+ const custom = supportedReferenceRoles(this.caps).filter(
514
+ (role) => !REFERENCE_ROLES.includes(role)
515
+ );
516
+ for (const role of [...REFERENCE_ROLES, ...custom]) {
390
517
  const cap = this.roleCapability(role);
391
518
  const group = _nullishCoalesce(byRole.get(role), () => ( []));
392
519
  if (!cap) continue;
@@ -409,7 +536,7 @@ var Planner = (_class = class {
409
536
  }
410
537
  }
411
538
  let next = kept.filter((ref) => !removed.has(ref));
412
- const maxTotal = _optionalChain([this, 'access', _13 => _13.caps, 'access', _14 => _14.references, 'optionalAccess', _15 => _15.maxTotal]);
539
+ const maxTotal = _optionalChain([this, 'access', _26 => _26.caps, 'access', _27 => _27.references, 'optionalAccess', _28 => _28.maxTotal]);
413
540
  if (maxTotal !== void 0 && next.length > maxTotal) {
414
541
  if (this.strict) {
415
542
  this.error("references", next.length, `At most ${maxTotal} references are supported in total.`);
@@ -525,6 +652,7 @@ var Planner = (_class = class {
525
652
  this.planDuration();
526
653
  this.planSeed();
527
654
  this.planMode();
655
+ this.addMentions();
528
656
  this.planReferences();
529
657
  this.planParams();
530
658
  }
@@ -604,18 +732,18 @@ function capabilitiesToJsonSchema(caps) {
604
732
  ...system.maxLength !== void 0 ? { maxLength: system.maxLength } : {}
605
733
  };
606
734
  }
607
- if (_optionalChain([caps, 'access', _16 => _16.aspectRatios, 'optionalAccess', _17 => _17.options, 'access', _18 => _18.length])) properties.aspectRatio = enumSchema(caps.aspectRatios, "Aspect ratio (width:height).");
608
- if (_optionalChain([caps, 'access', _19 => _19.resolutions, 'optionalAccess', _20 => _20.options, 'access', _21 => _21.length])) properties.resolution = enumSchema(caps.resolutions, "Output resolution, low to high.");
609
- if (_optionalChain([caps, 'access', _22 => _22.quality, 'optionalAccess', _23 => _23.options, 'access', _24 => _24.length])) properties.quality = enumSchema(caps.quality, "Quality level, low to high.");
735
+ if (_optionalChain([caps, 'access', _29 => _29.aspectRatios, 'optionalAccess', _30 => _30.options, 'access', _31 => _31.length])) properties.aspectRatio = enumSchema(caps.aspectRatios, "Aspect ratio (width:height).");
736
+ if (_optionalChain([caps, 'access', _32 => _32.resolutions, 'optionalAccess', _33 => _33.options, 'access', _34 => _34.length])) properties.resolution = enumSchema(caps.resolutions, "Output resolution, low to high.");
737
+ if (_optionalChain([caps, 'access', _35 => _35.quality, 'optionalAccess', _36 => _36.options, 'access', _37 => _37.length])) properties.quality = enumSchema(caps.quality, "Quality level, low to high.");
610
738
  if (caps.count) {
611
- const options = _optionalChain([caps, 'access', _25 => _25.count, 'access', _26 => _26.options, 'optionalAccess', _27 => _27.filter, 'call', _28 => _28((o) => o >= 1 && o <= caps.count.max)]);
612
- properties.count = _optionalChain([options, 'optionalAccess', _29 => _29.length]) ? { type: "integer", enum: options, description: "Number of outputs." } : { type: "integer", minimum: 1, maximum: caps.count.max, description: "Number of outputs." };
739
+ const options = _optionalChain([caps, 'access', _38 => _38.count, 'access', _39 => _39.options, 'optionalAccess', _40 => _40.filter, 'call', _41 => _41((o) => o >= 1 && o <= caps.count.max)]);
740
+ properties.count = _optionalChain([options, 'optionalAccess', _42 => _42.length]) ? { type: "integer", enum: options, description: "Number of outputs." } : { type: "integer", minimum: 1, maximum: caps.count.max, description: "Number of outputs." };
613
741
  if (caps.count.default !== void 0) properties.count.default = caps.count.default;
614
742
  }
615
743
  if (caps.duration) {
616
744
  const d = caps.duration;
617
- const options = _optionalChain([d, 'access', _30 => _30.options, 'optionalAccess', _31 => _31.filter, 'call', _32 => _32((o) => (d.min === void 0 || o >= d.min) && (d.max === void 0 || o <= d.max))]);
618
- properties.duration = _optionalChain([options, 'optionalAccess', _33 => _33.length]) ? { type: "number", enum: options, description: "Duration in seconds." } : {
745
+ const options = _optionalChain([d, 'access', _43 => _43.options, 'optionalAccess', _44 => _44.filter, 'call', _45 => _45((o) => (d.min === void 0 || o >= d.min) && (d.max === void 0 || o <= d.max))]);
746
+ properties.duration = _optionalChain([options, 'optionalAccess', _46 => _46.length]) ? { type: "number", enum: options, description: "Duration in seconds." } : {
619
747
  type: "number",
620
748
  description: d.step !== void 0 ? `Duration in seconds (step ${d.step}).` : "Duration in seconds.",
621
749
  ...d.min !== void 0 ? { minimum: d.min } : {},
@@ -640,28 +768,31 @@ function capabilitiesToJsonSchema(caps) {
640
768
  if (caps.inpainting && !roles.includes("mask")) roles.push("mask");
641
769
  if (roles.length > 0) {
642
770
  const limits = roles.map((role) => {
643
- const cap = _nullishCoalesce(_optionalChain([caps, 'access', _34 => _34.references, 'optionalAccess', _35 => _35.roles, 'access', _36 => _36[role]]), () => ( { max: 1 }));
771
+ const cap = _nullishCoalesce(_optionalChain([caps, 'access', _47 => _47.references, 'optionalAccess', _48 => _48.roles, 'access', _49 => _49[role]]), () => ( { max: 1 }));
644
772
  const min = cap.min ? `${cap.min}\u2013` : "up to ";
645
- return `${role} (${_nullishCoalesce(cap.label, () => ( REFERENCE_ROLE_LABELS[role]))}): ${min}${cap.max}`;
773
+ const accepts = "accepts" in cap && _optionalChain([cap, 'access', _50 => _50.accepts, 'optionalAccess', _51 => _51.length]) ? `, ${cap.accepts.join("/")} only` : "";
774
+ return `${role} (${referenceRoleLabel(role, caps)}): ${min}${cap.max}${accepts}`;
646
775
  });
647
- const perRoleTotal = roles.reduce((sum, role) => sum + (_nullishCoalesce(_optionalChain([caps, 'access', _37 => _37.references, 'optionalAccess', _38 => _38.roles, 'access', _39 => _39[role], 'optionalAccess', _40 => _40.max]), () => ( 1))), 0);
648
- const maxItems = Math.min(_nullishCoalesce(_optionalChain([caps, 'access', _41 => _41.references, 'optionalAccess', _42 => _42.maxTotal]), () => ( Infinity)), perRoleTotal);
776
+ const perRoleTotal = roles.reduce((sum, role) => sum + (_nullishCoalesce(_optionalChain([caps, 'access', _52 => _52.references, 'optionalAccess', _53 => _53.roles, 'access', _54 => _54[role], 'optionalAccess', _55 => _55.max]), () => ( 1))), 0);
777
+ const maxItems = Math.min(_nullishCoalesce(_optionalChain([caps, 'access', _56 => _56.references, 'optionalAccess', _57 => _57.maxTotal]), () => ( Infinity)), perRoleTotal);
649
778
  properties.references = {
650
779
  type: "array",
651
- description: `Reference inputs by role. Limits: ${limits.join("; ")}${_optionalChain([caps, 'access', _43 => _43.references, 'optionalAccess', _44 => _44.maxTotal]) !== void 0 ? `; at most ${caps.references.maxTotal} in total` : ""}.`,
780
+ description: `Reference inputs by role. Limits: ${limits.join("; ")}${_optionalChain([caps, 'access', _58 => _58.references, 'optionalAccess', _59 => _59.maxTotal]) !== void 0 ? `; at most ${caps.references.maxTotal} in total` : ""}.`,
652
781
  maxItems,
653
782
  items: {
654
783
  type: "object",
655
784
  properties: {
656
785
  id: { type: "string", minLength: 1, description: "Asset id." },
657
786
  role: { type: "string", enum: roles },
658
- url: { type: "string" }
787
+ url: { type: "string" },
788
+ mediaType: { type: "string", description: 'MIME type or media kind of the asset, e.g. "image/png".' },
789
+ contentHash: { type: "string" }
659
790
  },
660
791
  required: ["id", "role"],
661
792
  additionalProperties: false
662
793
  }
663
794
  };
664
- if (roles.some((role) => (_nullishCoalesce(_optionalChain([caps, 'access', _45 => _45.references, 'optionalAccess', _46 => _46.roles, 'access', _47 => _47[role], 'optionalAccess', _48 => _48.min]), () => ( 0))) > 0)) required.push("references");
795
+ if (roles.some((role) => (_nullishCoalesce(_optionalChain([caps, 'access', _60 => _60.references, 'optionalAccess', _61 => _61.roles, 'access', _62 => _62[role], 'optionalAccess', _63 => _63.min]), () => ( 0))) > 0)) required.push("references");
665
796
  }
666
797
  const params = Object.entries(_nullishCoalesce(caps.params, () => ( {})));
667
798
  if (params.length > 0) {
@@ -682,9 +813,58 @@ function capabilitiesToJsonSchema(caps) {
682
813
  };
683
814
  }
684
815
 
816
+ // src/generation/hash.ts
817
+ function stableStringify(value) {
818
+ if (Array.isArray(value)) return `[${value.map((item) => item === void 0 ? "null" : stableStringify(item)).join(",")}]`;
819
+ if (value && typeof value === "object") {
820
+ const entries = Object.keys(value).filter((key) => value[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`);
821
+ return `{${entries.join(",")}}`;
822
+ }
823
+ return _nullishCoalesce(JSON.stringify(value), () => ( "null"));
824
+ }
825
+ var FNV_PRIME = 16777619;
826
+ function hashText(text) {
827
+ let a = 2166136261;
828
+ let b = 789454171;
829
+ for (let i = 0; i < text.length; i++) {
830
+ const unit = text.charCodeAt(i);
831
+ a = Math.imul(a ^ unit & 255, FNV_PRIME);
832
+ a = Math.imul(a ^ unit >>> 8, FNV_PRIME);
833
+ b = Math.imul(b ^ unit >>> 8, FNV_PRIME);
834
+ b = Math.imul(b ^ unit & 255, FNV_PRIME);
835
+ b ^= b >>> 15;
836
+ }
837
+ a ^= a >>> 16;
838
+ a = Math.imul(a, 2246822507);
839
+ a ^= a >>> 13;
840
+ b ^= b >>> 16;
841
+ b = Math.imul(b, 3266489909);
842
+ b ^= b >>> 13;
843
+ const hex = (n) => (n >>> 0).toString(16).padStart(8, "0");
844
+ return `h1-${hex(a)}${hex(b)}`;
845
+ }
846
+ function hashValue(value) {
847
+ return hashText(stableStringify(value));
848
+ }
849
+ var PRESENTATION_ONLY = /* @__PURE__ */ new Set(["name", "description", "badges", "icon", "group", "timing"]);
850
+ function hashCapabilities(caps) {
851
+ const relevant = {};
852
+ for (const key of Object.keys(caps)) {
853
+ if (!PRESENTATION_ONLY.has(key)) relevant[key] = caps[key];
854
+ }
855
+ return hashValue(relevant);
856
+ }
857
+
685
858
  // src/generation/tools.ts
686
859
  var STRATEGIES = ["nearest", "upgrade", "downgrade", "error"];
687
- var requestSchema = {
860
+ function knownRoles(models) {
861
+ const roles = [...REFERENCE_ROLES];
862
+ for (const model of models) {
863
+ for (const role of supportedReferenceRoles(model)) if (!roles.includes(role)) roles.push(role);
864
+ }
865
+ return roles;
866
+ }
867
+ var requestSchemaFor = (roles) => ({
688
868
  type: "object",
689
869
  description: "Generation request. Call list_models for the fields each model supports; unsupported values are adjusted per `strategy`.",
690
870
  properties: {
@@ -704,8 +884,14 @@ var requestSchema = {
704
884
  type: "object",
705
885
  properties: {
706
886
  id: { type: "string", minLength: 1 },
707
- role: { type: "string", enum: [...REFERENCE_ROLES] },
708
- url: { type: "string" }
887
+ role: {
888
+ type: "string",
889
+ enum: [...roles],
890
+ description: "What the asset is used for. Each model lists the roles it accepts (list_models)."
891
+ },
892
+ url: { type: "string" },
893
+ mediaType: { type: "string", description: 'MIME type or media kind, e.g. "image/png".' },
894
+ contentHash: { type: "string" }
709
895
  },
710
896
  required: ["id", "role"],
711
897
  additionalProperties: false
@@ -714,20 +900,12 @@ var requestSchema = {
714
900
  params: { type: "object", additionalProperties: { type: ["string", "number", "boolean"] } }
715
901
  },
716
902
  additionalProperties: false
717
- };
903
+ });
718
904
  var strategySchema = {
719
905
  type: "string",
720
906
  enum: STRATEGIES,
721
907
  description: "How to handle unsupported values: nearest (snap/clamp, ties up), downgrade (ties down), upgrade (ties up, never drops references), error (change nothing)."
722
908
  };
723
- function stableStringify(value) {
724
- if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
725
- if (value && typeof value === "object") {
726
- const entries = Object.keys(value).filter((key) => value[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`);
727
- return `{${entries.join(",")}}`;
728
- }
729
- return _nullishCoalesce(JSON.stringify(value), () => ( "null"));
730
- }
731
909
  function planFailure(plan) {
732
910
  return {
733
911
  isError: true,
@@ -746,13 +924,13 @@ function createGenerationToolProvider(options) {
746
924
  const defaultStrategy = _nullishCoalesce(options.defaultStrategy, () => ( "nearest"));
747
925
  const maxKeys = Math.max(1, _nullishCoalesce(options.maxIdempotencyKeys, () => ( 500)));
748
926
  const calls = /* @__PURE__ */ new Map();
749
- const findModel = (id) => {
927
+ const findModel2 = (id) => {
750
928
  const model = readModels().find((m) => m.id === id);
751
929
  if (!model) throw new Error(`Unknown model "${String(id)}". Call list_models for the available ids.`);
752
930
  return model;
753
931
  };
754
932
  const plan = (args) => {
755
- const model = findModel(args.model);
933
+ const model = findModel2(args.model);
756
934
  const request = { ..._nullishCoalesce(args.request, () => ( {})), model: model.id };
757
935
  return {
758
936
  model,
@@ -763,12 +941,13 @@ function createGenerationToolProvider(options) {
763
941
  };
764
942
  };
765
943
  const planInput = () => {
766
- const ids = readModels().map((m) => m.id);
944
+ const models = readModels();
945
+ const ids = models.map((m) => m.id);
767
946
  return {
768
947
  type: "object",
769
948
  properties: {
770
949
  model: { type: "string", ...ids.length ? { enum: ids } : {}, description: "Model id from list_models." },
771
- request: requestSchema,
950
+ request: requestSchemaFor(knownRoles(models)),
772
951
  strategy: strategySchema,
773
952
  resolvedPrompt: {
774
953
  type: "string",
@@ -805,7 +984,7 @@ function createGenerationToolProvider(options) {
805
984
  media: m.media,
806
985
  ...m.name ? { name: m.name } : {},
807
986
  ...m.description ? { description: m.description } : {},
808
- ..._optionalChain([m, 'access', _49 => _49.badges, 'optionalAccess', _50 => _50.length]) ? { badges: [...m.badges] } : {},
987
+ ..._optionalChain([m, 'access', _64 => _64.badges, 'optionalAccess', _65 => _65.length]) ? { badges: [...m.badges] } : {},
809
988
  requestSchema: capabilitiesToJsonSchema(m)
810
989
  }))
811
990
  })
@@ -903,7 +1082,7 @@ function createGenerationToolProvider(options) {
903
1082
  try {
904
1083
  return await result;
905
1084
  } catch (error) {
906
- if (_optionalChain([calls, 'access', _51 => _51.get, 'call', _52 => _52(key), 'optionalAccess', _53 => _53.result]) === result) calls.delete(key);
1085
+ if (_optionalChain([calls, 'access', _66 => _66.get, 'call', _67 => _67(key), 'optionalAccess', _68 => _68.result]) === result) calls.delete(key);
907
1086
  throw error;
908
1087
  }
909
1088
  }
@@ -946,7 +1125,7 @@ function pinTemplates(rawPrompt, templates, bindings, maxDepth) {
946
1125
  if (body === void 0) continue;
947
1126
  const bound = bindings[template.name];
948
1127
  const version = bound && template.versions ? template.versions.find((v) => v.id === bound || v.version === bound) : _chunkFD4LPFAEcjs.getLatestVersion.call(void 0, template);
949
- const isVersioned = !!_optionalChain([template, 'access', _54 => _54.versions, 'optionalAccess', _55 => _55.length]) && !!version;
1128
+ const isVersioned = !!_optionalChain([template, 'access', _69 => _69.versions, 'optionalAccess', _70 => _70.length]) && !!version;
950
1129
  pinned.set(template.name, {
951
1130
  name: template.name,
952
1131
  ...template.id !== void 0 ? { templateId: template.id } : {},
@@ -981,10 +1160,10 @@ function createProvenance(options) {
981
1160
  const bindings = {};
982
1161
  for (const p of pinned) if (p.versionId !== void 0) bindings[p.name] = p.versionId;
983
1162
  const modelId = typeof options.model === "string" ? options.model : options.model.id;
984
- const request = clone(_nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'access', _56 => _56.plan, 'optionalAccess', _57 => _57.request]), () => ( options.request)), () => ( {})));
1163
+ const request = clone(_nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'access', _71 => _71.plan, 'optionalAccess', _72 => _72.request]), () => ( options.request)), () => ( {})));
985
1164
  request.model = modelId;
986
1165
  if (request.prompt === void 0) request.prompt = resolved.text;
987
- const adjustments = clone(_nullishCoalesce(_nullishCoalesce(options.adjustments, () => ( _optionalChain([options, 'access', _58 => _58.plan, 'optionalAccess', _59 => _59.adjustments]))), () => ( [])));
1166
+ const adjustments = clone(_nullishCoalesce(_nullishCoalesce(options.adjustments, () => ( _optionalChain([options, 'access', _73 => _73.plan, 'optionalAccess', _74 => _74.adjustments]))), () => ( [])));
988
1167
  return {
989
1168
  format: PROVENANCE_FORMAT,
990
1169
  version: PROVENANCE_VERSION,
@@ -1046,12 +1225,6 @@ function parseProvenance(input) {
1046
1225
  values: isRecord(data.values) ? data.values : null
1047
1226
  };
1048
1227
  }
1049
- function recreateRequest(provenance) {
1050
- const request = clone(provenance.request);
1051
- request.model = provenance.modelId;
1052
- if (request.prompt === void 0) request.prompt = provenance.resolvedPrompt;
1053
- return request;
1054
- }
1055
1228
  function replayProvenancePrompt(provenance) {
1056
1229
  const result = _chunkFD4LPFAEcjs.resolvePrompt.call(void 0, provenance.rawPrompt, pinnedTemplatesToTemplates(provenance.templates), {
1057
1230
  bindings: provenance.bindings,
@@ -1072,16 +1245,16 @@ function createBatchResolver(options) {
1072
1245
  const run = (keys) => {
1073
1246
  const pendings = keys.map((key) => inFlight.get(key));
1074
1247
  const finish = (values, error) => {
1075
- if (values === null) _optionalChain([options, 'access', _60 => _60.onError, 'optionalCall', _61 => _61(error, keys)]);
1248
+ if (values === null) _optionalChain([options, 'access', _75 => _75.onError, 'optionalCall', _76 => _76(error, keys)]);
1076
1249
  keys.forEach((key, index) => {
1077
1250
  const pending = pendings[index];
1078
- const value = _optionalChain([values, 'optionalAccess', _62 => _62.get, 'call', _63 => _63(key)]);
1251
+ const value = _optionalChain([values, 'optionalAccess', _77 => _77.get, 'call', _78 => _78(key)]);
1079
1252
  if (pending && inFlight.get(key) === pending) {
1080
1253
  inFlight.delete(key);
1081
1254
  settled.set(key, value);
1082
1255
  if (values === null) failures.add(key);
1083
1256
  }
1084
- _optionalChain([pending, 'optionalAccess', _64 => _64.resolve, 'call', _65 => _65(value)]);
1257
+ _optionalChain([pending, 'optionalAccess', _79 => _79.resolve, 'call', _80 => _80(value)]);
1085
1258
  });
1086
1259
  };
1087
1260
  let promise;
@@ -1179,9 +1352,9 @@ function estimateJobProgress(input) {
1179
1352
  function expectedDurationFor(caps, request = {}) {
1180
1353
  const timing = caps.timing;
1181
1354
  if (!timing) return void 0;
1182
- const count = _nullishCoalesce(_nullishCoalesce(request.count, () => ( _optionalChain([caps, 'access', _66 => _66.count, 'optionalAccess', _67 => _67.default]))), () => ( 1));
1183
- const duration = _nullishCoalesce(_nullishCoalesce(request.duration, () => ( _optionalChain([caps, 'access', _68 => _68.duration, 'optionalAccess', _69 => _69.default]))), () => ( 0));
1184
- const resolution = _nullishCoalesce(request.resolution, () => ( _optionalChain([caps, 'access', _70 => _70.resolutions, 'optionalAccess', _71 => _71.default])));
1355
+ const count = _nullishCoalesce(_nullishCoalesce(request.count, () => ( _optionalChain([caps, 'access', _81 => _81.count, 'optionalAccess', _82 => _82.default]))), () => ( 1));
1356
+ const duration = _nullishCoalesce(_nullishCoalesce(request.duration, () => ( _optionalChain([caps, 'access', _83 => _83.duration, 'optionalAccess', _84 => _84.default]))), () => ( 0));
1357
+ const resolution = _nullishCoalesce(request.resolution, () => ( _optionalChain([caps, 'access', _85 => _85.resolutions, 'optionalAccess', _86 => _86.default])));
1185
1358
  const megapixels = resolution ? _nullishCoalesce(resolutionMegapixels(resolution), () => ( 0)) : 0;
1186
1359
  return Math.round(
1187
1360
  timing.baseMs + (_nullishCoalesce(timing.perItemMs, () => ( 0))) * Math.max(0, count - 1) + (_nullishCoalesce(timing.perSecondMs, () => ( 0))) * duration + (_nullishCoalesce(timing.perMegapixelMs, () => ( 0))) * megapixels
@@ -1190,13 +1363,13 @@ function expectedDurationFor(caps, request = {}) {
1190
1363
 
1191
1364
  // src/generation/controls.ts
1192
1365
  function enumControl(key, label, cap) {
1193
- if (!_optionalChain([cap, 'optionalAccess', _72 => _72.options, 'access', _73 => _73.length])) return null;
1366
+ if (!_optionalChain([cap, 'optionalAccess', _87 => _87.options, 'access', _88 => _88.length])) return null;
1194
1367
  return {
1195
1368
  key,
1196
1369
  label,
1197
1370
  kind: "select",
1198
1371
  valueType: "string",
1199
- options: cap.options.map((value) => ({ value, label: _nullishCoalesce(_optionalChain([cap, 'access', _74 => _74.labels, 'optionalAccess', _75 => _75[value]]), () => ( value)) })),
1372
+ options: cap.options.map((value) => ({ value, label: _nullishCoalesce(_optionalChain([cap, 'access', _89 => _89.labels, 'optionalAccess', _90 => _90[value]]), () => ( value)) })),
1200
1373
  ...cap.default !== void 0 ? { defaultValue: cap.default } : {}
1201
1374
  };
1202
1375
  }
@@ -1221,16 +1394,16 @@ function getGenerationControls(caps) {
1221
1394
  controls.push(enumControl("resolution", "Resolution", caps.resolutions));
1222
1395
  controls.push(enumControl("quality", "Quality", caps.quality));
1223
1396
  if (caps.count) {
1224
- const options = _optionalChain([caps, 'access', _76 => _76.count, 'access', _77 => _77.options, 'optionalAccess', _78 => _78.filter, 'call', _79 => _79((o) => o >= 1 && o <= caps.count.max)]);
1397
+ const options = _optionalChain([caps, 'access', _91 => _91.count, 'access', _92 => _92.options, 'optionalAccess', _93 => _93.filter, 'call', _94 => _94((o) => o >= 1 && o <= caps.count.max)]);
1225
1398
  controls.push(
1226
- _optionalChain([options, 'optionalAccess', _80 => _80.length]) ? { key: "count", label: "Outputs", kind: "select", valueType: "number", options: options.map((o) => ({ value: o, label: String(o) })), defaultValue: caps.count.default } : { key: "count", label: "Outputs", kind: "range", valueType: "number", min: 1, max: caps.count.max, step: 1, defaultValue: _nullishCoalesce(caps.count.default, () => ( 1)) }
1399
+ _optionalChain([options, 'optionalAccess', _95 => _95.length]) ? { key: "count", label: "Outputs", kind: "select", valueType: "number", options: options.map((o) => ({ value: o, label: String(o) })), defaultValue: caps.count.default } : { key: "count", label: "Outputs", kind: "range", valueType: "number", min: 1, max: caps.count.max, step: 1, defaultValue: _nullishCoalesce(caps.count.default, () => ( 1)) }
1227
1400
  );
1228
1401
  }
1229
1402
  if (caps.duration) {
1230
1403
  const d = caps.duration;
1231
- const options = _optionalChain([d, 'access', _81 => _81.options, 'optionalAccess', _82 => _82.filter, 'call', _83 => _83((o) => (d.min === void 0 || o >= d.min) && (d.max === void 0 || o <= d.max))]);
1404
+ const options = _optionalChain([d, 'access', _96 => _96.options, 'optionalAccess', _97 => _97.filter, 'call', _98 => _98((o) => (d.min === void 0 || o >= d.min) && (d.max === void 0 || o <= d.max))]);
1232
1405
  controls.push(
1233
- _optionalChain([options, 'optionalAccess', _84 => _84.length]) ? { key: "duration", label: "Duration (s)", kind: "select", valueType: "number", options: options.map((o) => ({ value: o, label: `${o}s` })), defaultValue: d.default } : {
1406
+ _optionalChain([options, 'optionalAccess', _99 => _99.length]) ? { key: "duration", label: "Duration (s)", kind: "select", valueType: "number", options: options.map((o) => ({ value: o, label: `${o}s` })), defaultValue: d.default } : {
1234
1407
  key: "duration",
1235
1408
  label: "Duration (s)",
1236
1409
  kind: d.min !== void 0 && d.max !== void 0 ? "range" : "number",
@@ -1272,7 +1445,7 @@ function getGenerationControls(caps) {
1272
1445
  return controls.filter((c) => c !== null);
1273
1446
  }
1274
1447
  function getRequestValue(request, key) {
1275
- if (key.startsWith("params.")) return _optionalChain([request, 'access', _85 => _85.params, 'optionalAccess', _86 => _86[key.slice(7)]]);
1448
+ if (key.startsWith("params.")) return _optionalChain([request, 'access', _100 => _100.params, 'optionalAccess', _101 => _101[key.slice(7)]]);
1276
1449
  return request[key];
1277
1450
  }
1278
1451
  function setRequestValue(request, key, value) {
@@ -1305,14 +1478,15 @@ function getReferenceSlots(caps, request = {}) {
1305
1478
  if (caps.inpainting && !roles.includes("mask")) roles.push("mask");
1306
1479
  const refs = _nullishCoalesce(request.references, () => ( []));
1307
1480
  const total = refs.length;
1308
- const maxTotal = _nullishCoalesce(_optionalChain([caps, 'access', _87 => _87.references, 'optionalAccess', _88 => _88.maxTotal]), () => ( Infinity));
1481
+ const maxTotal = _nullishCoalesce(_optionalChain([caps, 'access', _102 => _102.references, 'optionalAccess', _103 => _103.maxTotal]), () => ( Infinity));
1309
1482
  return roles.map((role) => {
1310
- const cap = _nullishCoalesce(_optionalChain([caps, 'access', _89 => _89.references, 'optionalAccess', _90 => _90.roles, 'access', _91 => _91[role]]), () => ( { max: 1 }));
1483
+ const cap = _nullishCoalesce(_optionalChain([caps, 'access', _104 => _104.references, 'optionalAccess', _105 => _105.roles, 'access', _106 => _106[role]]), () => ( { max: 1 }));
1311
1484
  const references = refs.filter((ref) => ref.role === role);
1312
1485
  return {
1313
1486
  role,
1314
- label: _nullishCoalesce(cap.label, () => ( REFERENCE_ROLE_LABELS[role])),
1487
+ label: referenceRoleLabel(role, caps),
1315
1488
  ...cap.description ? { description: cap.description } : {},
1489
+ ..."accepts" in cap && _optionalChain([cap, 'access', _107 => _107.accepts, 'optionalAccess', _108 => _108.length]) ? { accepts: [...cap.accepts] } : {},
1316
1490
  min: _nullishCoalesce(cap.min, () => ( 0)),
1317
1491
  max: cap.max,
1318
1492
  references,
@@ -1330,6 +1504,776 @@ function removeReference(request, role, id) {
1330
1504
  return next;
1331
1505
  }
1332
1506
 
1507
+ // src/generation/assets.ts
1508
+ function toAssetResolver(lookup) {
1509
+ if (!lookup) return void 0;
1510
+ if (typeof lookup === "function") return (id) => _nullishCoalesce(lookup(id), () => ( void 0));
1511
+ if (lookup instanceof Map) return (id) => lookup.get(id);
1512
+ const byId = new Map(lookup.map((asset) => [asset.id, asset]));
1513
+ return (id) => byId.get(id);
1514
+ }
1515
+ function roleCap(caps, role) {
1516
+ const cap = _optionalChain([caps, 'access', _109 => _109.references, 'optionalAccess', _110 => _110.roles, 'access', _111 => _111[role]]);
1517
+ if (cap && cap.max > 0) return cap;
1518
+ if (role === "mask" && caps.inpainting) return { max: 1 };
1519
+ return void 0;
1520
+ }
1521
+ function getAssetRoleOptions(caps) {
1522
+ const roles = supportedReferenceRoles(caps);
1523
+ if (caps.inpainting && !roles.includes("mask")) roles.push("mask");
1524
+ return roles.map((role) => {
1525
+ const cap = _nullishCoalesce(roleCap(caps, role), () => ( { max: 1 }));
1526
+ return {
1527
+ role,
1528
+ label: referenceRoleLabel(role, caps),
1529
+ ...cap.description ? { description: cap.description } : {},
1530
+ min: _nullishCoalesce(cap.min, () => ( 0)),
1531
+ max: cap.max,
1532
+ ..._optionalChain([cap, 'access', _112 => _112.accepts, 'optionalAccess', _113 => _113.length]) ? { accepts: [...cap.accepts] } : {}
1533
+ };
1534
+ });
1535
+ }
1536
+ function validateAssetMentions(mentions, caps, options = {}) {
1537
+ const resolve = toAssetResolver(options.assets);
1538
+ const issues = [];
1539
+ const counts = {};
1540
+ mentions.forEach((mention, index) => {
1541
+ const id = mention.id;
1542
+ const label = `@${_nullishCoalesce(mention.label, () => ( id))}`;
1543
+ if (!mention.role) {
1544
+ issues.push({ index, id, code: "missing-role", severity: "warning", message: `${label} has no role.` });
1545
+ return;
1546
+ }
1547
+ let role = mention.role;
1548
+ if (!roleCap(caps, role)) {
1549
+ const alias = normalizeReferenceRole(role, caps);
1550
+ if (alias !== role && roleCap(caps, alias)) {
1551
+ issues.push({
1552
+ index,
1553
+ id,
1554
+ role,
1555
+ code: "renamed-role",
1556
+ severity: "warning",
1557
+ suggestion: alias,
1558
+ message: `${label}: this model calls "${role}" ${referenceRoleLabel(alias, caps)} (${alias}).`
1559
+ });
1560
+ role = alias;
1561
+ } else {
1562
+ issues.push({
1563
+ index,
1564
+ id,
1565
+ role,
1566
+ code: "unsupported-role",
1567
+ severity: "error",
1568
+ message: `${label}: ${_nullishCoalesce(caps.name, () => ( caps.id))} does not accept ${referenceRoleLabel(role, caps).toLowerCase()} assets.`
1569
+ });
1570
+ return;
1571
+ }
1572
+ }
1573
+ const cap = roleCap(caps, role);
1574
+ const mediaType = _nullishCoalesce(mention.mediaType, () => ( _optionalChain([resolve, 'optionalCall', _114 => _114(id), 'optionalAccess', _115 => _115.mediaType])));
1575
+ if (mediaType !== void 0 && !mediaTypeMatches(mediaType, cap.accepts)) {
1576
+ issues.push({
1577
+ index,
1578
+ id,
1579
+ role,
1580
+ code: "media-mismatch",
1581
+ severity: "error",
1582
+ message: `${label} is ${mediaType}; ${referenceRoleLabel(role, caps)} accepts ${(_nullishCoalesce(cap.accepts, () => ( []))).join(", ")}.`
1583
+ });
1584
+ return;
1585
+ }
1586
+ counts[role] = (_nullishCoalesce(counts[role], () => ( 0))) + 1;
1587
+ if (counts[role] > cap.max) {
1588
+ issues.push({
1589
+ index,
1590
+ id,
1591
+ role,
1592
+ code: "too-many",
1593
+ severity: "warning",
1594
+ message: `${label}: at most ${cap.max} ${referenceRoleLabel(role, caps).toLowerCase()} asset(s); extra ones are left out.`
1595
+ });
1596
+ }
1597
+ });
1598
+ const missing = getAssetRoleOptions(caps).filter((option) => (_nullishCoalesce(counts[option.role], () => ( 0))) < option.min).map((option) => ({ role: option.role, min: option.min, count: _nullishCoalesce(counts[option.role], () => ( 0)) }));
1599
+ return { ok: !issues.some((issue) => issue.severity === "error") && missing.length === 0, issues, counts, missing };
1600
+ }
1601
+ function resolveAssetMentions(mentions, assets) {
1602
+ const byId = new Map(assets.map((asset) => [asset.id, asset]));
1603
+ const byLabel = new Map(assets.filter((a) => a.label).map((asset) => [asset.label.toLowerCase(), asset]));
1604
+ const result = [];
1605
+ for (const mention of mentions) {
1606
+ const asset = _nullishCoalesce(byId.get(mention.handle), () => ( byLabel.get(mention.handle.toLowerCase())));
1607
+ if (!asset) continue;
1608
+ result.push({
1609
+ id: asset.id,
1610
+ label: mention.handle,
1611
+ ...mention.role ? { role: mention.role } : {},
1612
+ ...asset.mediaType !== void 0 ? { mediaType: asset.mediaType } : {},
1613
+ ...asset.contentHash !== void 0 ? { contentHash: asset.contentHash } : {},
1614
+ ...asset.url !== void 0 ? { url: asset.url } : {}
1615
+ });
1616
+ }
1617
+ return result;
1618
+ }
1619
+ function defaultAssetRoleOptions() {
1620
+ return REFERENCE_ROLES.map((role) => ({ role, label: referenceRoleLabel(role), min: 0, max: 1 }));
1621
+ }
1622
+ function describeAssetMentions(mentions, assets, caps) {
1623
+ const byId = new Map(assets.map((asset) => [asset.id, asset]));
1624
+ const byLabel = new Map(assets.filter((a) => a.label).map((asset) => [asset.label.toLowerCase(), asset]));
1625
+ const chips = [];
1626
+ for (const mention of mentions) {
1627
+ const asset = _nullishCoalesce(byId.get(mention.handle), () => ( byLabel.get(mention.handle.toLowerCase())));
1628
+ if (!asset) continue;
1629
+ const role = mention.role || void 0;
1630
+ chips.push({
1631
+ index: chips.length,
1632
+ ...mention.start !== void 0 ? { start: mention.start } : {},
1633
+ handle: mention.handle,
1634
+ asset,
1635
+ ...role ? { role, roleLabel: referenceRoleLabel(caps ? normalizeReferenceRole(role, caps) : role, caps) } : {},
1636
+ issues: []
1637
+ });
1638
+ }
1639
+ if (caps) {
1640
+ const validation = validateAssetMentions(
1641
+ chips.map((chip) => ({
1642
+ id: chip.asset.id,
1643
+ label: chip.handle,
1644
+ ...chip.role ? { role: chip.role } : {},
1645
+ ...chip.asset.mediaType ? { mediaType: chip.asset.mediaType } : {}
1646
+ })),
1647
+ caps
1648
+ );
1649
+ for (const issue of validation.issues) chips[issue.index].issues.push(issue);
1650
+ }
1651
+ return chips;
1652
+ }
1653
+
1654
+ // src/generation/record.ts
1655
+ var GENERATION_RECORD_FORMAT = "pixerate.generation-record";
1656
+ var GENERATION_RECORD_VERSION = 1;
1657
+ var idCounter = 0;
1658
+ function createGenerationRecordId() {
1659
+ const uuid = _optionalChain([globalThis, 'access', _116 => _116.crypto, 'optionalAccess', _117 => _117.randomUUID, 'optionalCall', _118 => _118()]);
1660
+ if (typeof uuid === "string") return `gen_${uuid}`;
1661
+ idCounter = (idCounter + 1) % 1679616;
1662
+ const random = Math.floor(Math.random() * 2 ** 48).toString(36).padStart(10, "0");
1663
+ return `gen_${Date.now().toString(36)}${idCounter.toString(36).padStart(4, "0")}${random}`;
1664
+ }
1665
+ var clone2 = (value) => value === void 0 ? value : JSON.parse(JSON.stringify(value));
1666
+ function recordTemplates(pinned) {
1667
+ return pinned.map((p) => ({
1668
+ name: p.name,
1669
+ ...p.templateId !== void 0 ? { templateId: p.templateId } : {},
1670
+ ...p.versionId !== void 0 ? { versionId: p.versionId, version: p.version } : {},
1671
+ hash: hashText(p.body)
1672
+ }));
1673
+ }
1674
+ function recordAssets(references, lookup) {
1675
+ const resolve = toAssetResolver(lookup);
1676
+ return (_nullishCoalesce(references, () => ( []))).map((ref) => {
1677
+ const info = _optionalChain([resolve, 'optionalCall', _119 => _119(ref.id)]);
1678
+ const contentHash = _nullishCoalesce(ref.contentHash, () => ( _optionalChain([info, 'optionalAccess', _120 => _120.contentHash])));
1679
+ const mediaType = _nullishCoalesce(ref.mediaType, () => ( _optionalChain([info, 'optionalAccess', _121 => _121.mediaType])));
1680
+ const url = _nullishCoalesce(ref.url, () => ( _optionalChain([info, 'optionalAccess', _122 => _122.url])));
1681
+ return {
1682
+ id: ref.id,
1683
+ role: ref.role,
1684
+ ...contentHash !== void 0 ? { contentHash } : {},
1685
+ ...mediaType !== void 0 ? { mediaType } : {},
1686
+ ...url !== void 0 ? { url } : {}
1687
+ };
1688
+ });
1689
+ }
1690
+ function createGenerationRecord(options) {
1691
+ const {
1692
+ model,
1693
+ request: settingsInput,
1694
+ plan: planInput,
1695
+ strategy: strategyInput,
1696
+ mentions,
1697
+ assets,
1698
+ seed: seedInput,
1699
+ id,
1700
+ parentId,
1701
+ kind,
1702
+ ...provenanceOptions
1703
+ } = options;
1704
+ const caps = typeof model === "string" ? void 0 : model;
1705
+ const settings = clone2(_nullishCoalesce(_nullishCoalesce(settingsInput, () => ( _optionalChain([planInput, 'optionalAccess', _123 => _123.request]))), () => ( {})));
1706
+ let plan = planInput;
1707
+ if (!plan && caps) {
1708
+ const resolved = _chunkFD4LPFAEcjs.resolvePrompt.call(void 0, options.rawPrompt, _nullishCoalesce(options.templates, () => ( [])), {
1709
+ bindings: options.bindings,
1710
+ values: options.values,
1711
+ maxDepth: options.maxDepth
1712
+ });
1713
+ plan = planGenerationRequest(settings, caps, {
1714
+ strategy: _nullishCoalesce(strategyInput, () => ( "nearest")),
1715
+ resolvedPrompt: resolved.text,
1716
+ ...mentions ? { mentions } : {}
1717
+ });
1718
+ }
1719
+ const provenance = createProvenance({
1720
+ ...provenanceOptions,
1721
+ model,
1722
+ ...plan ? { plan } : { request: settings }
1723
+ });
1724
+ const seed = _nullishCoalesce(seedInput, () => ( provenance.request.seed));
1725
+ return {
1726
+ format: GENERATION_RECORD_FORMAT,
1727
+ version: GENERATION_RECORD_VERSION,
1728
+ id: _nullishCoalesce(id, () => ( createGenerationRecordId())),
1729
+ ...parentId !== void 0 ? { parentId } : {},
1730
+ kind: _nullishCoalesce(kind, () => ( (parentId !== void 0 ? "recreate" : "generate"))),
1731
+ provenance,
1732
+ templates: recordTemplates(provenance.templates),
1733
+ promptHash: hashText(provenance.resolvedPrompt),
1734
+ ...caps ? { capabilityHash: hashCapabilities(caps) } : {},
1735
+ settings,
1736
+ strategy: _nullishCoalesce(_nullishCoalesce(strategyInput, () => ( _optionalChain([plan, 'optionalAccess', _124 => _124.strategy]))), () => ( "nearest")),
1737
+ ...seed !== void 0 ? { seed } : {},
1738
+ assets: recordAssets(provenance.request.references, assets),
1739
+ ..._optionalChain([mentions, 'optionalAccess', _125 => _125.length]) ? { mentions: clone2([...mentions]) } : {},
1740
+ createdAt: provenance.createdAt
1741
+ };
1742
+ }
1743
+ function completeGenerationRecord(record, update) {
1744
+ const next = clone2(record);
1745
+ const now = new Date(_nullishCoalesce(update.completedAt, () => ( Date.now()))).toISOString();
1746
+ if (update.outputIds) next.provenance.outputIds = [...update.outputIds];
1747
+ next.provenance.completedAt = now;
1748
+ if (update.meta) next.provenance.meta = { ..._nullishCoalesce(next.provenance.meta, () => ( {})), ...clone2(update.meta) };
1749
+ if (update.seed !== void 0) next.seed = update.seed;
1750
+ next.updatedAt = now;
1751
+ return next;
1752
+ }
1753
+ function serializeGenerationRecord(record) {
1754
+ return JSON.stringify(record);
1755
+ }
1756
+ var isObject = (value) => !!value && typeof value === "object" && !Array.isArray(value);
1757
+ function parseGenerationRecord(input) {
1758
+ let data = input;
1759
+ if (typeof input === "string") {
1760
+ try {
1761
+ data = JSON.parse(input);
1762
+ } catch (e3) {
1763
+ throw new ProvenanceParseError("Generation record is not valid JSON.");
1764
+ }
1765
+ }
1766
+ if (!isObject(data) || data.format !== GENERATION_RECORD_FORMAT) {
1767
+ throw new ProvenanceParseError("Not a generation record.");
1768
+ }
1769
+ if (typeof data.version !== "number" || data.version > GENERATION_RECORD_VERSION) {
1770
+ throw new ProvenanceParseError(`Unsupported generation record version ${JSON.stringify(data.version)}.`);
1771
+ }
1772
+ const checks = [
1773
+ ["id", typeof data.id === "string" && data.id !== ""],
1774
+ ["templates", Array.isArray(data.templates) && data.templates.every((t) => isObject(t) && typeof t.name === "string" && typeof t.hash === "string")],
1775
+ ["assets", Array.isArray(data.assets) && data.assets.every((a) => isObject(a) && typeof a.id === "string" && typeof a.role === "string")],
1776
+ ["settings", isObject(data.settings)],
1777
+ ["promptHash", typeof data.promptHash === "string"],
1778
+ ["createdAt", typeof data.createdAt === "string"]
1779
+ ];
1780
+ const bad = checks.find(([, ok]) => !ok);
1781
+ if (bad) throw new ProvenanceParseError(`Invalid generation record field "${bad[0]}".`);
1782
+ const provenance = parseProvenance(data.provenance);
1783
+ return {
1784
+ ...data,
1785
+ kind: data.kind === "recreate" || data.kind === "variation" ? data.kind : "generate",
1786
+ strategy: ["nearest", "upgrade", "downgrade", "error"].includes(data.strategy) ? data.strategy : "nearest",
1787
+ provenance
1788
+ };
1789
+ }
1790
+ function isGenerationRecord(value) {
1791
+ return isObject(value) && value.format === GENERATION_RECORD_FORMAT;
1792
+ }
1793
+ var SKIPPED_SETTING_FIELDS = /* @__PURE__ */ new Set(["model", "prompt", "references", "params", "seed"]);
1794
+ function findModel(capabilities, modelId) {
1795
+ if (!capabilities) return { given: false };
1796
+ const list2 = Array.isArray(capabilities) ? capabilities : [capabilities];
1797
+ return { given: true, caps: list2.find((m) => m.id === modelId) };
1798
+ }
1799
+ var sameValue = (a, b) => stableStringify(a) === stableStringify(b);
1800
+ var show = (value) => value === void 0 ? "unset" : typeof value === "string" ? `"${value}"` : JSON.stringify(value);
1801
+ var refKey = (ref) => `${ref.role}:${ref.id}`;
1802
+ function templateDrift(record, current, mode) {
1803
+ if (!current) return [];
1804
+ const byName = new Map(current.map((t) => [t.name, t]));
1805
+ const drift = [];
1806
+ for (const recorded of record.templates) {
1807
+ const template = byName.get(recorded.name);
1808
+ const fromVersion = _nullishCoalesce(recorded.version, () => ( recorded.versionId));
1809
+ if (!template) {
1810
+ drift.push({
1811
+ type: "template-missing",
1812
+ severity: "warning",
1813
+ template: recorded.name,
1814
+ from: fromVersion,
1815
+ applied: false,
1816
+ message: `Template "${recorded.name}" no longer exists; the recorded body is used.`
1817
+ });
1818
+ continue;
1819
+ }
1820
+ const body = _chunkFD4LPFAEcjs.getTemplateBody.call(void 0, template, {});
1821
+ const hash = body === void 0 ? void 0 : hashText(body);
1822
+ if (hash === recorded.hash) continue;
1823
+ const latest = _chunkFD4LPFAEcjs.getLatestVersion.call(void 0, template);
1824
+ const toVersion = _optionalChain([template, 'access', _126 => _126.versions, 'optionalAccess', _127 => _127.length]) ? _nullishCoalesce(_optionalChain([latest, 'optionalAccess', _128 => _128.version]), () => ( _optionalChain([latest, 'optionalAccess', _129 => _129.id]))) : void 0;
1825
+ const versions = fromVersion !== void 0 || toVersion !== void 0 ? ` (${_nullishCoalesce(fromVersion, () => ( "unversioned"))} \u2192 ${_nullishCoalesce(toVersion, () => ( "unversioned"))})` : "";
1826
+ drift.push({
1827
+ type: "template-changed",
1828
+ severity: mode === "latest" ? "info" : "warning",
1829
+ template: recorded.name,
1830
+ from: { version: fromVersion, hash: recorded.hash },
1831
+ to: { version: toVersion, hash },
1832
+ applied: mode === "latest",
1833
+ message: mode === "latest" ? `Template "${recorded.name}" changed since this generation${versions}; using the current version.` : `Template "${recorded.name}" changed since this generation${versions}; recreating with the recorded version.`
1834
+ });
1835
+ }
1836
+ return drift;
1837
+ }
1838
+ function randomSeed(caps, previous, random) {
1839
+ const cap = caps ? seedCapability(caps.seed) : {};
1840
+ if (!cap) return void 0;
1841
+ const min = Math.ceil(_nullishCoalesce(cap.min, () => ( 0)));
1842
+ const max = Math.floor(_nullishCoalesce(cap.max, () => ( 2 ** 31 - 1)));
1843
+ if (max < min) return min;
1844
+ let seed = previous;
1845
+ for (let attempt = 0; attempt < 8 && (seed === void 0 || seed === previous); attempt++) {
1846
+ seed = min + Math.floor(random() * (max - min + 1));
1847
+ }
1848
+ if (seed === previous && max > min) seed = previous === max ? min : previous + 1;
1849
+ return seed;
1850
+ }
1851
+ function rebuild(record, options, kind, overrides) {
1852
+ const mode = _nullishCoalesce(options.mode, () => ( "exact"));
1853
+ const provenance = record.provenance;
1854
+ const drift = templateDrift(record, options.templates, mode);
1855
+ const rawPrompt = _nullishCoalesce(_optionalChain([overrides, 'optionalAccess', _130 => _130.rawPrompt]), () => ( provenance.rawPrompt));
1856
+ const values = _optionalChain([overrides, 'optionalAccess', _131 => _131.values]) !== void 0 ? { ..._nullishCoalesce(provenance.values, () => ( {})), ...overrides.values } : provenance.values ? clone2(provenance.values) : null;
1857
+ const pinned = pinnedTemplatesToTemplates(provenance.templates);
1858
+ let templates;
1859
+ let bindings;
1860
+ if (mode === "latest" && options.templates) {
1861
+ const currentNames = new Set(options.templates.map((t) => t.name));
1862
+ const fallback = pinned.filter((t) => !currentNames.has(t.name));
1863
+ templates = [...options.templates.map((t) => ({ ...t })), ...fallback];
1864
+ bindings = {};
1865
+ for (const t of fallback) {
1866
+ if (provenance.bindings[t.name] !== void 0) bindings[t.name] = provenance.bindings[t.name];
1867
+ }
1868
+ } else {
1869
+ templates = pinned;
1870
+ bindings = { ...provenance.bindings };
1871
+ }
1872
+ const resolved = _chunkFD4LPFAEcjs.resolvePrompt.call(void 0, rawPrompt, templates, { bindings, ...values ? { values } : {} });
1873
+ const sourceMap = resolved.map.map((segment) => {
1874
+ const { locked: _locked, ...rest } = segment;
1875
+ return rest;
1876
+ });
1877
+ if (resolved.text !== provenance.resolvedPrompt && !overrides) {
1878
+ drift.push({
1879
+ type: "prompt-changed",
1880
+ severity: "info",
1881
+ from: provenance.resolvedPrompt,
1882
+ to: resolved.text,
1883
+ applied: true,
1884
+ message: "The resolved prompt differs from the recorded one."
1885
+ });
1886
+ }
1887
+ const base = clone2(mode === "exact" ? provenance.request : record.settings);
1888
+ const recordedPlanned = provenance.request;
1889
+ if (base.prompt === void 0 || base.prompt === provenance.resolvedPrompt) base.prompt = resolved.text;
1890
+ else if (base.prompt === provenance.rawPrompt) base.prompt = rawPrompt;
1891
+ if (mode === "latest" && _optionalChain([record, 'access', _132 => _132.mentions, 'optionalAccess', _133 => _133.length])) {
1892
+ const plannedRole = new Map((_nullishCoalesce(recordedPlanned.references, () => ( []))).map((ref) => [ref.id, ref.role]));
1893
+ base.references = [
1894
+ ..._nullishCoalesce(base.references, () => ( [])),
1895
+ ...record.mentions.map((m) => ({
1896
+ id: m.id,
1897
+ role: m.role || plannedRole.get(m.id) || "image_ref",
1898
+ ...m.url !== void 0 ? { url: m.url } : {},
1899
+ ...m.mediaType !== void 0 ? { mediaType: m.mediaType } : {},
1900
+ ...m.contentHash !== void 0 ? { contentHash: m.contentHash } : {}
1901
+ }))
1902
+ ];
1903
+ } else if (mode === "latest" && base.references === void 0 && recordedPlanned.references) {
1904
+ base.references = clone2(recordedPlanned.references);
1905
+ }
1906
+ if (record.seed !== void 0) base.seed = record.seed;
1907
+ base.model = provenance.modelId;
1908
+ const { given, caps } = findModel(options.capabilities, provenance.modelId);
1909
+ if (overrides) {
1910
+ if (overrides.settings) {
1911
+ const { params, ...rest } = overrides.settings;
1912
+ Object.assign(base, clone2(rest));
1913
+ if (params) base.params = { ..._nullishCoalesce(base.params, () => ( {})), ...clone2(params) };
1914
+ }
1915
+ if (overrides.seed === null) delete base.seed;
1916
+ else base.seed = _nullishCoalesce(overrides.seed, () => ( randomSeed(caps, record.seed, _nullishCoalesce(overrides.random, () => ( Math.random)))));
1917
+ if (base.seed === void 0) delete base.seed;
1918
+ }
1919
+ const resolveAsset = toAssetResolver(options.assets);
1920
+ if (resolveAsset && base.references) {
1921
+ const recordedById = new Map(record.assets.map((a) => [refKey(a), a]));
1922
+ const kept = [];
1923
+ for (const ref of base.references) {
1924
+ const info = resolveAsset(ref.id);
1925
+ if (!info) {
1926
+ drift.push({
1927
+ type: "asset-missing",
1928
+ severity: "error",
1929
+ assetId: ref.id,
1930
+ role: ref.role,
1931
+ message: `Asset "${ref.id}" (${ref.role}) is no longer available.`
1932
+ });
1933
+ continue;
1934
+ }
1935
+ const recordedHash = _nullishCoalesce(_optionalChain([recordedById, 'access', _134 => _134.get, 'call', _135 => _135(refKey(ref)), 'optionalAccess', _136 => _136.contentHash]), () => ( ref.contentHash));
1936
+ if (recordedHash !== void 0 && info.contentHash !== void 0 && recordedHash !== info.contentHash) {
1937
+ drift.push({
1938
+ type: "asset-changed",
1939
+ severity: "warning",
1940
+ assetId: ref.id,
1941
+ role: ref.role,
1942
+ from: recordedHash,
1943
+ to: info.contentHash,
1944
+ applied: true,
1945
+ message: `Asset "${ref.id}" (${ref.role}) has changed since this generation.`
1946
+ });
1947
+ }
1948
+ const next = { ...ref };
1949
+ if (info.contentHash !== void 0) next.contentHash = info.contentHash;
1950
+ if (next.mediaType === void 0 && info.mediaType !== void 0) next.mediaType = info.mediaType;
1951
+ kept.push(next);
1952
+ }
1953
+ if (kept.length) base.references = kept;
1954
+ else delete base.references;
1955
+ }
1956
+ let plan;
1957
+ let request = base;
1958
+ if (given && !caps) {
1959
+ drift.push({
1960
+ type: "model-missing",
1961
+ severity: "error",
1962
+ modelId: provenance.modelId,
1963
+ message: `Model "${provenance.modelId}" is no longer available.`
1964
+ });
1965
+ } else if (caps) {
1966
+ const capabilityHash = hashCapabilities(caps);
1967
+ if (record.capabilityHash !== void 0 && record.capabilityHash !== capabilityHash) {
1968
+ drift.push({
1969
+ type: "model-changed",
1970
+ severity: "warning",
1971
+ modelId: caps.id,
1972
+ from: record.capabilityHash,
1973
+ to: capabilityHash,
1974
+ message: `The capabilities of "${_nullishCoalesce(caps.name, () => ( caps.id))}" changed since this generation.`
1975
+ });
1976
+ }
1977
+ plan = planGenerationRequest(base, caps, {
1978
+ strategy: _nullishCoalesce(options.strategy, () => ( record.strategy)),
1979
+ resolvedPrompt: resolved.text
1980
+ });
1981
+ request = plan.request;
1982
+ const severity = mode === "exact" && !overrides ? "warning" : "info";
1983
+ const type = mode === "exact" && !overrides ? "setting-unsupported" : "setting-changed";
1984
+ const describeChange = (field, from, to) => {
1985
+ const adjustment = plan.adjustments.find((a) => a.field === field || a.field.startsWith(`${field}.`));
1986
+ drift.push({
1987
+ type,
1988
+ severity,
1989
+ field,
1990
+ from,
1991
+ to,
1992
+ applied: true,
1993
+ message: type === "setting-unsupported" ? `${field} ${show(from)} is no longer supported; using ${show(to)}.${adjustment ? ` ${adjustment.reason}` : ""}` : `${field} was ${show(from)}, now ${show(to)}.${adjustment ? ` ${adjustment.reason}` : ""}`
1994
+ });
1995
+ };
1996
+ if (!overrides) {
1997
+ for (const field of GENERATION_REQUEST_FIELDS) {
1998
+ if (SKIPPED_SETTING_FIELDS.has(field)) continue;
1999
+ const from = recordedPlanned[field];
2000
+ const to = request[field];
2001
+ if (!sameValue(from, to)) describeChange(field, from, to);
2002
+ }
2003
+ const paramNames = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(recordedPlanned.params, () => ( {}))), ...Object.keys(_nullishCoalesce(request.params, () => ( {})))]);
2004
+ for (const name of [...paramNames].sort()) {
2005
+ const from = _optionalChain([recordedPlanned, 'access', _137 => _137.params, 'optionalAccess', _138 => _138[name]]);
2006
+ const to = _optionalChain([request, 'access', _139 => _139.params, 'optionalAccess', _140 => _140[name]]);
2007
+ if (!sameValue(from, to)) describeChange(`params.${name}`, from, to);
2008
+ }
2009
+ if (!sameValue(_nullishCoalesce(record.seed, () => ( recordedPlanned.seed)), request.seed)) describeChange("seed", _nullishCoalesce(record.seed, () => ( recordedPlanned.seed)), request.seed);
2010
+ const missing = new Set(drift.filter((d) => d.type === "asset-missing").map((d) => `${d.role}:${d.assetId}`));
2011
+ const fromRefs = (_nullishCoalesce(recordedPlanned.references, () => ( []))).map(refKey).filter((key) => !missing.has(key));
2012
+ const toRefs = (_nullishCoalesce(request.references, () => ( []))).map(refKey);
2013
+ if (!sameValue(fromRefs, toRefs)) describeChange("references", fromRefs, toRefs);
2014
+ }
2015
+ for (const error of plan.errors) {
2016
+ drift.push({
2017
+ type: "setting-unsupported",
2018
+ severity: "error",
2019
+ field: error.field,
2020
+ from: error.value,
2021
+ message: error.message
2022
+ });
2023
+ }
2024
+ }
2025
+ const ok = !drift.some((d) => d.severity === "error") && (plan ? plan.ok : true);
2026
+ const recordOptions = {
2027
+ rawPrompt,
2028
+ templates,
2029
+ bindings,
2030
+ ...values ? { values } : {},
2031
+ model: _nullishCoalesce(caps, () => ( provenance.modelId)),
2032
+ request,
2033
+ ...plan ? { plan } : {},
2034
+ strategy: _nullishCoalesce(options.strategy, () => ( record.strategy)),
2035
+ parentId: record.id,
2036
+ kind
2037
+ };
2038
+ return {
2039
+ mode,
2040
+ ok,
2041
+ request,
2042
+ ...plan ? { plan } : {},
2043
+ rawPrompt,
2044
+ resolvedPrompt: resolved.text,
2045
+ sourceMap,
2046
+ values,
2047
+ templates,
2048
+ bindings,
2049
+ drift,
2050
+ parentId: record.id,
2051
+ kind,
2052
+ recordOptions
2053
+ };
2054
+ }
2055
+ function recreateRequest(input, options) {
2056
+ if (isGenerationRecord(input)) return rebuild(input, _nullishCoalesce(options, () => ( {})), "recreate");
2057
+ const provenance = input;
2058
+ const request = clone2(provenance.request);
2059
+ request.model = provenance.modelId;
2060
+ if (request.prompt === void 0) request.prompt = provenance.resolvedPrompt;
2061
+ return request;
2062
+ }
2063
+ function variationRequest(record, overrides = {}, options = {}) {
2064
+ return rebuild(record, options, "variation", overrides);
2065
+ }
2066
+ var DRIFT_TYPE_LABELS = {
2067
+ "template-changed": "Template changed",
2068
+ "template-missing": "Template deleted",
2069
+ "prompt-changed": "Prompt changed",
2070
+ "model-missing": "Model unavailable",
2071
+ "model-changed": "Model changed",
2072
+ "setting-unsupported": "Setting unsupported",
2073
+ "setting-changed": "Setting changed",
2074
+ "asset-missing": "Asset missing",
2075
+ "asset-changed": "Asset changed"
2076
+ };
2077
+ function blockingDrift(drift) {
2078
+ return drift.filter((d) => d.severity === "error");
2079
+ }
2080
+
2081
+ // src/generation/store.ts
2082
+ var INDEX_VERSION = 1;
2083
+ var time = (value) => new Date(value).getTime();
2084
+ function summarizeGenerationRecord(record) {
2085
+ const unique = (values) => [...new Set(values)];
2086
+ return {
2087
+ id: record.id,
2088
+ modelId: record.provenance.modelId,
2089
+ kind: record.kind,
2090
+ ...record.parentId !== void 0 ? { parentId: record.parentId } : {},
2091
+ createdAt: record.createdAt,
2092
+ templates: unique(record.templates.map((t) => t.name)),
2093
+ templateIds: unique(record.templates.flatMap((t) => t.templateId !== void 0 ? [t.templateId] : [])),
2094
+ assets: unique(record.assets.map((a) => a.id)),
2095
+ roles: unique(record.assets.map((a) => a.role)),
2096
+ preview: record.provenance.resolvedPrompt.slice(0, 160)
2097
+ };
2098
+ }
2099
+ function matchesRecordFilter(summary, filter = {}) {
2100
+ if (filter.model !== void 0) {
2101
+ const models = typeof filter.model === "string" ? [filter.model] : filter.model;
2102
+ if (!models.includes(summary.modelId)) return false;
2103
+ }
2104
+ if (filter.template !== void 0 && !summary.templates.includes(filter.template) && !summary.templateIds.includes(filter.template)) {
2105
+ return false;
2106
+ }
2107
+ if (filter.asset !== void 0 && !summary.assets.includes(filter.asset)) return false;
2108
+ if (filter.role !== void 0 && !summary.roles.includes(filter.role)) return false;
2109
+ if (filter.kind !== void 0 && summary.kind !== filter.kind) return false;
2110
+ if (filter.parentId !== void 0 && summary.parentId !== filter.parentId) return false;
2111
+ const created = time(summary.createdAt);
2112
+ if (filter.since !== void 0 && created < time(filter.since)) return false;
2113
+ if (filter.until !== void 0 && created >= time(filter.until)) return false;
2114
+ if (filter.text !== void 0 && !summary.preview.toLowerCase().includes(filter.text.toLowerCase())) return false;
2115
+ return true;
2116
+ }
2117
+ var newestFirst = (a, b) => time(b.createdAt) - time(a.createdAt) || (a.id < b.id ? 1 : a.id > b.id ? -1 : 0);
2118
+ function createGenerationRecordStore(options) {
2119
+ const storage = options.storage;
2120
+ const ns = _nullishCoalesce(options.namespace, () => ( "pixerate.generation-records"));
2121
+ const indexKey = `${ns}:index`;
2122
+ const recordKey = (id) => `${ns}:record:${id}`;
2123
+ const listeners = /* @__PURE__ */ new Set();
2124
+ let index = null;
2125
+ let queue = Promise.resolve();
2126
+ const run = (task) => {
2127
+ const result = queue.then(task, task);
2128
+ queue = result.catch(() => void 0);
2129
+ return result;
2130
+ };
2131
+ const notify = () => listeners.forEach((listener) => listener());
2132
+ const loadIndex = async () => {
2133
+ if (index) return index;
2134
+ const raw = await storage.get(indexKey);
2135
+ let items = [];
2136
+ if (raw) {
2137
+ try {
2138
+ const data = JSON.parse(raw);
2139
+ if (data && Array.isArray(data.items)) {
2140
+ items = data.items.filter((item) => item && typeof item.id === "string" && typeof item.createdAt === "string");
2141
+ }
2142
+ } catch (e4) {
2143
+ items = [];
2144
+ }
2145
+ }
2146
+ index = items;
2147
+ return index;
2148
+ };
2149
+ const saveIndex = async (items) => {
2150
+ await storage.set(indexKey, JSON.stringify({ version: INDEX_VERSION, items }));
2151
+ index = items;
2152
+ };
2153
+ const select = (items, filter = {}) => {
2154
+ const matched = items.filter((s) => matchesRecordFilter(s, filter)).sort(newestFirst);
2155
+ const offset = Math.max(0, _nullishCoalesce(filter.offset, () => ( 0)));
2156
+ return matched.slice(offset, filter.limit !== void 0 ? offset + Math.max(0, filter.limit) : void 0);
2157
+ };
2158
+ const pruneLocked = async (prune) => {
2159
+ const items = [...await loadIndex()].sort(newestFirst);
2160
+ const removed = [];
2161
+ const kept = [];
2162
+ let candidates = 0;
2163
+ const cutoff = prune.olderThan !== void 0 ? time(prune.olderThan) : void 0;
2164
+ for (const item of items) {
2165
+ if (_optionalChain([prune, 'access', _141 => _141.keep, 'optionalCall', _142 => _142(item)])) {
2166
+ kept.push(item);
2167
+ candidates++;
2168
+ continue;
2169
+ }
2170
+ const tooOld = cutoff !== void 0 && time(item.createdAt) < cutoff;
2171
+ const overLimit = prune.maxRecords !== void 0 && candidates >= Math.max(0, prune.maxRecords);
2172
+ if (tooOld || overLimit) removed.push(item);
2173
+ else {
2174
+ kept.push(item);
2175
+ candidates++;
2176
+ }
2177
+ }
2178
+ if (removed.length === 0) return [];
2179
+ await saveIndex(kept);
2180
+ for (const item of removed) await storage.remove(recordKey(item.id));
2181
+ return removed.map((item) => item.id);
2182
+ };
2183
+ return {
2184
+ put: (record) => run(async () => {
2185
+ const serialized = serializeGenerationRecord(record);
2186
+ await storage.set(recordKey(record.id), serialized);
2187
+ const items = (await loadIndex()).filter((item) => item.id !== record.id);
2188
+ items.push(summarizeGenerationRecord(record));
2189
+ await saveIndex(items);
2190
+ if (options.maxRecords !== void 0) await pruneLocked({ maxRecords: options.maxRecords });
2191
+ notify();
2192
+ }),
2193
+ get: (id) => run(async () => {
2194
+ const raw = await storage.get(recordKey(id));
2195
+ if (!raw) return null;
2196
+ try {
2197
+ return parseGenerationRecord(raw);
2198
+ } catch (e5) {
2199
+ return null;
2200
+ }
2201
+ }),
2202
+ summaries: (filter) => run(async () => select(await loadIndex(), filter)),
2203
+ list: (filter) => run(async () => {
2204
+ const records = [];
2205
+ for (const summary of select(await loadIndex(), filter)) {
2206
+ const raw = await storage.get(recordKey(summary.id));
2207
+ if (!raw) continue;
2208
+ try {
2209
+ records.push(parseGenerationRecord(raw));
2210
+ } catch (e6) {
2211
+ }
2212
+ }
2213
+ return records;
2214
+ }),
2215
+ remove: (id) => run(async () => {
2216
+ const items = await loadIndex();
2217
+ const next = items.filter((item) => item.id !== id);
2218
+ if (next.length === items.length) return false;
2219
+ await saveIndex(next);
2220
+ await storage.remove(recordKey(id));
2221
+ notify();
2222
+ return true;
2223
+ }),
2224
+ prune: (prune) => run(async () => {
2225
+ const removed = await pruneLocked(prune);
2226
+ if (removed.length) notify();
2227
+ return removed;
2228
+ }),
2229
+ clear: () => run(async () => {
2230
+ const items = await loadIndex();
2231
+ await saveIndex([]);
2232
+ for (const item of items) await storage.remove(recordKey(item.id));
2233
+ notify();
2234
+ }),
2235
+ subscribe(listener) {
2236
+ listeners.add(listener);
2237
+ return () => {
2238
+ listeners.delete(listener);
2239
+ };
2240
+ }
2241
+ };
2242
+ }
2243
+
2244
+
2245
+
2246
+
2247
+
2248
+
2249
+
2250
+
2251
+
2252
+
2253
+
2254
+
2255
+
2256
+
2257
+
2258
+
2259
+
2260
+
2261
+
2262
+
2263
+
2264
+
2265
+
2266
+
2267
+
2268
+
2269
+
2270
+
2271
+
2272
+
2273
+
2274
+
2275
+
2276
+
1333
2277
 
1334
2278
 
1335
2279
 
@@ -1369,5 +2313,5 @@ function removeReference(request, role, id) {
1369
2313
 
1370
2314
 
1371
2315
 
1372
- exports.GENERATION_REQUEST_FIELDS = GENERATION_REQUEST_FIELDS; exports.MAX_PENDING_PERCENT = MAX_PENDING_PERCENT; exports.PROVENANCE_FORMAT = PROVENANCE_FORMAT; exports.PROVENANCE_VERSION = PROVENANCE_VERSION; exports.ProvenanceParseError = ProvenanceParseError; exports.QUALITY_LADDER = QUALITY_LADDER; exports.REFERENCE_ROLES = REFERENCE_ROLES; exports.REFERENCE_ROLE_LABELS = REFERENCE_ROLE_LABELS; exports.addReference = addReference; exports.aspectRatioRank = aspectRatioRank; exports.capabilitiesToJsonSchema = capabilitiesToJsonSchema; exports.createBatchResolver = createBatchResolver; exports.createGenerationToolProvider = createGenerationToolProvider; exports.createProvenance = createProvenance; exports.estimateJobProgress = estimateJobProgress; exports.expectedDurationFor = expectedDurationFor; exports.formatRemaining = formatRemaining; exports.getGenerationControls = getGenerationControls; exports.getReferenceSlots = getReferenceSlots; exports.getRequestValue = getRequestValue; exports.mergeCapabilities = mergeCapabilities; exports.parseControlValue = parseControlValue; exports.parseProvenance = parseProvenance; exports.pinnedTemplatesToTemplates = pinnedTemplatesToTemplates; exports.planGenerationRequest = planGenerationRequest; exports.qualityRank = qualityRank; exports.recreateRequest = recreateRequest; exports.removeReference = removeReference; exports.replayProvenancePrompt = replayProvenancePrompt; exports.resolutionMegapixels = resolutionMegapixels; exports.resolutionRank = resolutionRank; exports.seedCapability = seedCapability; exports.serializeProvenance = serializeProvenance; exports.setRequestValue = setRequestValue; exports.snapToOption = snapToOption; exports.supportedModes = supportedModes; exports.supportedReferenceRoles = supportedReferenceRoles; exports.textFieldCapability = textFieldCapability; exports.validateJsonSchema = _chunkCPOKFNBGcjs.validateJsonSchema;
2316
+ exports.DRIFT_TYPE_LABELS = DRIFT_TYPE_LABELS; exports.GENERATION_RECORD_FORMAT = GENERATION_RECORD_FORMAT; exports.GENERATION_RECORD_VERSION = GENERATION_RECORD_VERSION; exports.GENERATION_REQUEST_FIELDS = GENERATION_REQUEST_FIELDS; exports.MAX_PENDING_PERCENT = MAX_PENDING_PERCENT; exports.PROVENANCE_FORMAT = PROVENANCE_FORMAT; exports.PROVENANCE_VERSION = PROVENANCE_VERSION; exports.ProvenanceParseError = ProvenanceParseError; exports.QUALITY_LADDER = QUALITY_LADDER; exports.REFERENCE_ROLES = REFERENCE_ROLES; exports.REFERENCE_ROLE_ALIASES = REFERENCE_ROLE_ALIASES; exports.REFERENCE_ROLE_LABELS = REFERENCE_ROLE_LABELS; exports.REFERENCE_ROLE_NAME_REGEX = REFERENCE_ROLE_NAME_REGEX; exports.addReference = addReference; exports.aspectRatioRank = aspectRatioRank; exports.blockingDrift = blockingDrift; exports.capabilitiesToJsonSchema = capabilitiesToJsonSchema; exports.completeGenerationRecord = completeGenerationRecord; exports.createBatchResolver = createBatchResolver; exports.createGenerationRecord = createGenerationRecord; exports.createGenerationRecordId = createGenerationRecordId; exports.createGenerationRecordStore = createGenerationRecordStore; exports.createGenerationToolProvider = createGenerationToolProvider; exports.createProvenance = createProvenance; exports.defaultAssetRoleOptions = defaultAssetRoleOptions; exports.describeAssetMentions = describeAssetMentions; exports.estimateJobProgress = estimateJobProgress; exports.expectedDurationFor = expectedDurationFor; exports.findTextMentions = _chunkBVP3TSLHcjs.findTextMentions; exports.formatMentionText = _chunkBVP3TSLHcjs.formatMentionText; exports.formatRemaining = formatRemaining; exports.getAssetRoleOptions = getAssetRoleOptions; exports.getGenerationControls = getGenerationControls; exports.getReferenceSlots = getReferenceSlots; exports.getRequestValue = getRequestValue; exports.hashCapabilities = hashCapabilities; exports.hashText = hashText; exports.hashValue = hashValue; exports.isGenerationRecord = isGenerationRecord; exports.isReferenceRoleName = isReferenceRoleName; exports.matchesRecordFilter = matchesRecordFilter; exports.mediaTypeMatches = mediaTypeMatches; exports.mergeCapabilities = mergeCapabilities; exports.normalizeReferenceRole = normalizeReferenceRole; exports.parseControlValue = parseControlValue; exports.parseGenerationRecord = parseGenerationRecord; exports.parseProvenance = parseProvenance; exports.pinnedTemplatesToTemplates = pinnedTemplatesToTemplates; exports.planGenerationRequest = planGenerationRequest; exports.qualityRank = qualityRank; exports.recreateRequest = recreateRequest; exports.referenceRoleLabel = referenceRoleLabel; exports.removeReference = removeReference; exports.replayProvenancePrompt = replayProvenancePrompt; exports.resolutionMegapixels = resolutionMegapixels; exports.resolutionRank = resolutionRank; exports.resolveAssetMentions = resolveAssetMentions; exports.seedCapability = seedCapability; exports.serializeGenerationRecord = serializeGenerationRecord; exports.serializeProvenance = serializeProvenance; exports.setMentionRoleInText = _chunkBVP3TSLHcjs.setMentionRoleInText; exports.setRequestValue = setRequestValue; exports.snapToOption = snapToOption; exports.stableStringify = stableStringify; exports.summarizeGenerationRecord = summarizeGenerationRecord; exports.supportedModes = supportedModes; exports.supportedReferenceRoles = supportedReferenceRoles; exports.textFieldCapability = textFieldCapability; exports.toAssetResolver = toAssetResolver; exports.validateAssetMentions = validateAssetMentions; exports.validateJsonSchema = _chunkCPOKFNBGcjs.validateJsonSchema; exports.variationRequest = variationRequest;
1373
2317
  //# sourceMappingURL=index.cjs.map