@pixerate/editor 0.135.0 → 0.137.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 (164) hide show
  1. package/dist/animation-editor/index.cjs +63 -55
  2. package/dist/animation-editor/index.cjs.map +1 -1
  3. package/dist/animation-editor/index.d.cts +8 -5
  4. package/dist/animation-editor/index.d.ts +8 -5
  5. package/dist/animation-editor/index.js +10 -2
  6. package/dist/animation-editor/index.js.map +1 -1
  7. package/dist/{bezier-J8i4uqSH.d.cts → bezier-CZ2AhjID.d.cts} +1 -1
  8. package/dist/{bezier-lNEOp0Jx.d.ts → bezier-Dywv3Bw8.d.ts} +1 -1
  9. package/dist/blending-D7jCmjO6.d.cts +1026 -0
  10. package/dist/blending-NgF3qo3d.d.ts +1026 -0
  11. package/dist/brushes-CnvZSYYU.d.cts +744 -0
  12. package/dist/brushes-DJmUbIgz.d.ts +744 -0
  13. package/dist/{brushstrokeRender-SII6MG4R.js → brushstrokeRender-2FAXA3XC.js} +13 -16
  14. package/dist/{brushstrokeRender-SII6MG4R.js.map → brushstrokeRender-2FAXA3XC.js.map} +1 -1
  15. package/dist/{brushstrokeRender-JNHVEUFG.cjs → brushstrokeRender-IMFY3FF6.cjs} +16 -19
  16. package/dist/brushstrokeRender-IMFY3FF6.cjs.map +1 -0
  17. package/dist/canvas/index.cjs +10 -10
  18. package/dist/canvas/index.cjs.map +1 -1
  19. package/dist/canvas/index.d.cts +10 -7
  20. package/dist/canvas/index.d.ts +10 -7
  21. package/dist/canvas/index.js +4 -4
  22. package/dist/{chunk-W4LNKTHT.cjs → chunk-2XS6LTUP.cjs} +63 -63
  23. package/dist/{chunk-W4LNKTHT.cjs.map → chunk-2XS6LTUP.cjs.map} +1 -1
  24. package/dist/{chunk-HHTCDFZC.js → chunk-3D77LOBM.js} +234 -136
  25. package/dist/chunk-3D77LOBM.js.map +1 -0
  26. package/dist/{chunk-BR7EKQUP.js → chunk-3G6J7UFV.js} +322 -2
  27. package/dist/chunk-3G6J7UFV.js.map +1 -0
  28. package/dist/{chunk-62XUO5LB.js → chunk-3X6IAJUQ.js} +2 -2
  29. package/dist/{chunk-EM3FMJWE.js → chunk-5FSRTP6E.js} +320 -3
  30. package/dist/chunk-5FSRTP6E.js.map +1 -0
  31. package/dist/{chunk-Z2H7KECK.cjs → chunk-5OOIUXNJ.cjs} +345 -247
  32. package/dist/chunk-5OOIUXNJ.cjs.map +1 -0
  33. package/dist/{chunk-7RJ6P7MI.js → chunk-6S6362D2.js} +2 -2
  34. package/dist/chunk-A3BVTI3G.js +150 -0
  35. package/dist/chunk-A3BVTI3G.js.map +1 -0
  36. package/dist/{chunk-24ATT2PE.cjs → chunk-AEAAN4AD.cjs} +120 -120
  37. package/dist/{chunk-24ATT2PE.cjs.map → chunk-AEAAN4AD.cjs.map} +1 -1
  38. package/dist/chunk-ECCXGELC.cjs +727 -0
  39. package/dist/chunk-ECCXGELC.cjs.map +1 -0
  40. package/dist/{chunk-SVYE5HIM.js → chunk-EQQMGO42.js} +2 -2
  41. package/dist/{chunk-FHPVDTI2.cjs → chunk-F2Y4E4GU.cjs} +22 -22
  42. package/dist/{chunk-FHPVDTI2.cjs.map → chunk-F2Y4E4GU.cjs.map} +1 -1
  43. package/dist/{chunk-OXSV64JX.js → chunk-G6IKY6PL.js} +4 -4
  44. package/dist/{chunk-UYQUPUR6.js → chunk-HUO3TI4C.js} +3 -3
  45. package/dist/chunk-I52DRGGJ.js +727 -0
  46. package/dist/chunk-I52DRGGJ.js.map +1 -0
  47. package/dist/{chunk-DDSO4HS7.cjs → chunk-KEENUAFN.cjs} +2 -2
  48. package/dist/{chunk-DDSO4HS7.cjs.map → chunk-KEENUAFN.cjs.map} +1 -1
  49. package/dist/{chunk-2HC4DRF4.js → chunk-LLFHCSU2.js} +2 -2
  50. package/dist/{chunk-J5BA3BQ6.cjs → chunk-O7LUD7MH.cjs} +323 -3
  51. package/dist/chunk-O7LUD7MH.cjs.map +1 -0
  52. package/dist/{chunk-ILYFOJUN.js → chunk-OIBIRXRG.js} +3 -3
  53. package/dist/{chunk-FWEO3HSL.js → chunk-PQQF5KOW.js} +8 -8
  54. package/dist/{chunk-T6TV6HY6.cjs → chunk-PRSRYHQD.cjs} +36 -36
  55. package/dist/{chunk-T6TV6HY6.cjs.map → chunk-PRSRYHQD.cjs.map} +1 -1
  56. package/dist/chunk-Q6OUXEK3.cjs +150 -0
  57. package/dist/chunk-Q6OUXEK3.cjs.map +1 -0
  58. package/dist/{chunk-6GFRKLLS.cjs → chunk-QBWEH3IM.cjs} +429 -112
  59. package/dist/chunk-QBWEH3IM.cjs.map +1 -0
  60. package/dist/{chunk-ESIWZMMK.js → chunk-SYT2TLQF.js} +35 -37
  61. package/dist/{chunk-ESIWZMMK.js.map → chunk-SYT2TLQF.js.map} +1 -1
  62. package/dist/{chunk-YT3JL7YM.cjs → chunk-TLCTTQFF.cjs} +53 -53
  63. package/dist/{chunk-YT3JL7YM.cjs.map → chunk-TLCTTQFF.cjs.map} +1 -1
  64. package/dist/{chunk-P3RQ5UJE.cjs → chunk-UTQKC66X.cjs} +4 -4
  65. package/dist/{chunk-P3RQ5UJE.cjs.map → chunk-UTQKC66X.cjs.map} +1 -1
  66. package/dist/{chunk-J3B45HTA.cjs → chunk-XB25WOC2.cjs} +6 -6
  67. package/dist/{chunk-J3B45HTA.cjs.map → chunk-XB25WOC2.cjs.map} +1 -1
  68. package/dist/{chunk-YAFS2QFZ.cjs → chunk-XN2NBLV5.cjs} +313 -315
  69. package/dist/chunk-XN2NBLV5.cjs.map +1 -0
  70. package/dist/effects/index.d.cts +7 -4
  71. package/dist/effects/index.d.ts +7 -4
  72. package/dist/{export-DMeG6E06.d.ts → export-41rL6Cne.d.ts} +1 -1
  73. package/dist/{export-AZSwX087.d.cts → export-CyJdfP_Z.d.cts} +5 -4
  74. package/dist/{export-KzubBKo7.d.cts → export-D9mXp05Q.d.cts} +1 -1
  75. package/dist/{export-BDkyDNM8.d.ts → export-DwnZ_hvQ.d.ts} +5 -4
  76. package/dist/extensions/index.cjs +3 -3
  77. package/dist/extensions/index.cjs.map +1 -1
  78. package/dist/extensions/index.js +2 -2
  79. package/dist/generation/index.cjs +150 -945
  80. package/dist/generation/index.cjs.map +1 -1
  81. package/dist/generation/index.d.cts +3 -423
  82. package/dist/generation/index.d.ts +3 -423
  83. package/dist/generation/index.js +59 -854
  84. package/dist/generation/index.js.map +1 -1
  85. package/dist/grammar/index.cjs +3 -3
  86. package/dist/grammar/index.cjs.map +1 -1
  87. package/dist/grammar/index.js +2 -2
  88. package/dist/{helpers-Coa4e2j_.d.ts → helpers-C-RgeyvH.d.ts} +25 -8
  89. package/dist/{helpers-DHl28yLO.d.cts → helpers-v6GMazzg.d.cts} +25 -8
  90. package/dist/image-editor/index.cjs +986 -986
  91. package/dist/image-editor/index.cjs.map +1 -1
  92. package/dist/image-editor/index.d.cts +15 -11
  93. package/dist/image-editor/index.d.ts +15 -11
  94. package/dist/image-editor/index.js +94 -94
  95. package/dist/index.cjs +28 -28
  96. package/dist/index.cjs.map +1 -1
  97. package/dist/index.js +36 -36
  98. package/dist/{opentype-BWR7Qv8W.d.cts → opentype-KR_jj6b_.d.cts} +1 -1
  99. package/dist/{opentype-Dfcx6wFx.d.ts → opentype-a1KAW-qs.d.ts} +1 -1
  100. package/dist/paint/index.cjs +5 -8
  101. package/dist/paint/index.cjs.map +1 -1
  102. package/dist/paint/index.d.cts +4 -2
  103. package/dist/paint/index.d.ts +4 -2
  104. package/dist/paint/index.js +15 -18
  105. package/dist/paint-editor/index.cjs +405 -403
  106. package/dist/paint-editor/index.cjs.map +1 -1
  107. package/dist/paint-editor/index.d.cts +15 -748
  108. package/dist/paint-editor/index.d.ts +15 -748
  109. package/dist/paint-editor/index.js +79 -77
  110. package/dist/paint-editor/index.js.map +1 -1
  111. package/dist/{pathfinder-D8KQ6blQ.d.cts → pathfinder-BHS4vQNm.d.cts} +1 -1
  112. package/dist/{pathfinder-Celbi3e6.d.ts → pathfinder-BVvTIBMo.d.ts} +1 -1
  113. package/dist/{pool-8JZGWHvR.d.ts → pool-CZQOrSXZ.d.ts} +1 -1
  114. package/dist/{pool-BfuxBKTd.d.cts → pool-FjZZmZ80.d.cts} +1 -1
  115. package/dist/provenance-DmlcgdzT.d.cts +426 -0
  116. package/dist/provenance-uh5r2TQ8.d.ts +426 -0
  117. package/dist/rand-8xbUb6ur.d.ts +1118 -0
  118. package/dist/rand-Cw9VLrVC.d.cts +1118 -0
  119. package/dist/raster/index.cjs +17 -19
  120. package/dist/raster/index.cjs.map +1 -1
  121. package/dist/raster/index.js +9 -11
  122. package/dist/raster/index.js.map +1 -1
  123. package/dist/{svg-CxxqG3_W.d.ts → svg-CSz3mzkw.d.ts} +2 -2
  124. package/dist/{svg-pwXWq6s2.d.cts → svg-DTb40ICU.d.cts} +2 -2
  125. package/dist/{tools-y1M6O3UT.d.ts → tools-B0wXP5cF.d.ts} +1 -1
  126. package/dist/{tools-3EBjR91b.d.cts → tools-Ca0kI1qo.d.cts} +1 -1
  127. package/dist/vector/index.cjs +2698 -1674
  128. package/dist/vector/index.cjs.map +1 -1
  129. package/dist/vector/index.d.cts +390 -72
  130. package/dist/vector/index.d.ts +390 -72
  131. package/dist/vector/index.js +1665 -641
  132. package/dist/vector/index.js.map +1 -1
  133. package/dist/video-editor/index.d.cts +7 -4
  134. package/dist/video-editor/index.d.ts +7 -4
  135. package/dist/{warp-Ceqdz7kj.d.cts → warp-DTOp0lON.d.cts} +1 -1
  136. package/dist/{warp-C1gwu2G_.d.ts → warp-pd7hrH4T.d.ts} +1 -1
  137. package/package.json +1 -1
  138. package/skills/pixerate-vector/SKILL.md +22 -0
  139. package/dist/brushstrokeRender-JNHVEUFG.cjs.map +0 -1
  140. package/dist/chunk-64PYNEHJ.js +0 -340
  141. package/dist/chunk-64PYNEHJ.js.map +0 -1
  142. package/dist/chunk-6GFRKLLS.cjs.map +0 -1
  143. package/dist/chunk-7QN76ESJ.js +0 -323
  144. package/dist/chunk-7QN76ESJ.js.map +0 -1
  145. package/dist/chunk-BR7EKQUP.js.map +0 -1
  146. package/dist/chunk-DCLJNVZS.cjs +0 -323
  147. package/dist/chunk-DCLJNVZS.cjs.map +0 -1
  148. package/dist/chunk-EM3FMJWE.js.map +0 -1
  149. package/dist/chunk-HHTCDFZC.js.map +0 -1
  150. package/dist/chunk-J5BA3BQ6.cjs.map +0 -1
  151. package/dist/chunk-YAFS2QFZ.cjs.map +0 -1
  152. package/dist/chunk-Z2H7KECK.cjs.map +0 -1
  153. package/dist/chunk-Z6OUCS2K.cjs +0 -340
  154. package/dist/chunk-Z6OUCS2K.cjs.map +0 -1
  155. package/dist/rand-BszBST4s.d.ts +0 -2140
  156. package/dist/rand-DOH_aMvm.d.cts +0 -2140
  157. /package/dist/{chunk-62XUO5LB.js.map → chunk-3X6IAJUQ.js.map} +0 -0
  158. /package/dist/{chunk-7RJ6P7MI.js.map → chunk-6S6362D2.js.map} +0 -0
  159. /package/dist/{chunk-SVYE5HIM.js.map → chunk-EQQMGO42.js.map} +0 -0
  160. /package/dist/{chunk-OXSV64JX.js.map → chunk-G6IKY6PL.js.map} +0 -0
  161. /package/dist/{chunk-UYQUPUR6.js.map → chunk-HUO3TI4C.js.map} +0 -0
  162. /package/dist/{chunk-2HC4DRF4.js.map → chunk-LLFHCSU2.js.map} +0 -0
  163. /package/dist/{chunk-ILYFOJUN.js.map → chunk-OIBIRXRG.js.map} +0 -0
  164. /package/dist/{chunk-FWEO3HSL.js.map → chunk-PQQF5KOW.js.map} +0 -0
@@ -1,675 +1,54 @@
1
1
  import {
2
- getLatestVersion,
3
- getTemplateBody,
4
- resolvePrompt,
5
- tokenizePrompt
6
- } from "../chunk-FPENXAEJ.js";
7
- import "../chunk-P6ODPZ4W.js";
2
+ GENERATION_REQUEST_FIELDS,
3
+ QUALITY_LADDER,
4
+ REFERENCE_ROLES,
5
+ REFERENCE_ROLE_ALIASES,
6
+ REFERENCE_ROLE_LABELS,
7
+ REFERENCE_ROLE_NAME_REGEX,
8
+ aspectRatioRank,
9
+ hashCapabilities,
10
+ hashText,
11
+ hashValue,
12
+ isReferenceRoleName,
13
+ mediaTypeMatches,
14
+ mergeCapabilities,
15
+ normalizeReferenceRole,
16
+ planGenerationRequest,
17
+ qualityRank,
18
+ referenceRoleLabel,
19
+ resolutionMegapixels,
20
+ resolutionRank,
21
+ seedCapability,
22
+ snapToOption,
23
+ stableStringify,
24
+ supportedModes,
25
+ supportedReferenceRoles,
26
+ textFieldCapability
27
+ } from "../chunk-I52DRGGJ.js";
8
28
  import {
9
29
  findTextMentions,
10
30
  formatMentionText,
11
31
  setMentionRoleInText
12
32
  } from "../chunk-O5RYH2PG.js";
33
+ import {
34
+ PROVENANCE_FORMAT,
35
+ PROVENANCE_VERSION,
36
+ ProvenanceParseError,
37
+ createProvenance,
38
+ parseProvenance,
39
+ pinnedTemplatesToTemplates,
40
+ replayProvenancePrompt,
41
+ serializeProvenance
42
+ } from "../chunk-A3BVTI3G.js";
13
43
  import {
14
44
  validateJsonSchema
15
45
  } from "../chunk-4FX5ACVG.js";
16
-
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
- }
22
- var REFERENCE_ROLES = [
23
- "start_frame",
24
- "end_frame",
25
- "style_ref",
26
- "character_ref",
27
- "background_ref",
28
- "mask",
29
- "image_ref",
30
- "video_ref",
31
- "audio_ref"
32
- ];
33
- var REFERENCE_ROLE_LABELS = {
34
- start_frame: "Start frame",
35
- end_frame: "End frame",
36
- style_ref: "Style reference",
37
- character_ref: "Character reference",
38
- background_ref: "Background reference",
39
- mask: "Mask",
40
- image_ref: "Image reference",
41
- video_ref: "Video reference",
42
- audio_ref: "Audio reference"
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 = caps?.references?.roles[role]?.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 ? !!caps.references?.roles[name] : isBuiltinRole(name)) return name;
76
- const lower = name.toLowerCase();
77
- if (caps?.references?.roles[lower]) return lower;
78
- if (!caps && isBuiltinRole(lower)) return lower;
79
- return 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
- }
94
- var GENERATION_REQUEST_FIELDS = [
95
- "model",
96
- "prompt",
97
- "negativePrompt",
98
- "systemPrompt",
99
- "aspectRatio",
100
- "resolution",
101
- "quality",
102
- "count",
103
- "duration",
104
- "seed",
105
- "mode",
106
- "references",
107
- "params"
108
- ];
109
- function textFieldCapability(value) {
110
- if (!value) return null;
111
- return value === true ? {} : value;
112
- }
113
- function seedCapability(value) {
114
- if (!value) return null;
115
- return value === true ? {} : value;
116
- }
117
- function supportedReferenceRoles(caps) {
118
- const roles = caps.references?.roles ?? {};
119
- const builtin = REFERENCE_ROLES.filter((role) => (roles[role]?.max ?? 0) > 0);
120
- const custom = Object.keys(roles).filter(
121
- (role) => !isBuiltinRole(role) && isReferenceRoleName(role) && (roles[role]?.max ?? 0) > 0
122
- );
123
- return [...builtin, ...custom];
124
- }
125
- function supportedModes(caps) {
126
- const modes = ["generate"];
127
- if (caps.editing) modes.push("edit");
128
- if (caps.inpainting) modes.push("inpaint");
129
- return modes;
130
- }
131
- var PRESENTATION_KEYS = ["name", "description", "badges", "icon", "group"];
132
- function mergeCapabilities(remote, overlay = []) {
133
- const overlayById = new Map(overlay.map((entry) => [entry.id, entry]));
134
- const remoteIds = new Set(remote.map((model) => model.id));
135
- const merged = remote.map((model) => {
136
- const extra = overlayById.get(model.id);
137
- if (!extra) return { ...model };
138
- const next = { ...model };
139
- for (const key of PRESENTATION_KEYS) {
140
- if (extra[key] !== void 0) next[key] = extra[key];
141
- }
142
- return next;
143
- });
144
- for (const entry of overlay) {
145
- if (remoteIds.has(entry.id) || !entry.media) continue;
146
- remoteIds.add(entry.id);
147
- merged.push({ ...entry });
148
- }
149
- return merged;
150
- }
151
-
152
- // src/generation/plan.ts
153
- var EPSILON = 1e-9;
154
- function aspectRatioRank(value) {
155
- const match = /^\s*(\d+(?:\.\d+)?)\s*[:x/×]\s*(\d+(?:\.\d+)?)\s*$/i.exec(String(value));
156
- if (!match) return void 0;
157
- const w = Number(match[1]);
158
- const h = Number(match[2]);
159
- if (!(w > 0) || !(h > 0)) return void 0;
160
- return Math.log(w / h);
161
- }
162
- function resolutionRank(value) {
163
- const text = String(value).trim().toLowerCase();
164
- let pixels;
165
- let match = /^(\d+(?:\.\d+)?)\s*[x×*]\s*(\d+(?:\.\d+)?)$/.exec(text);
166
- if (match) pixels = Number(match[1]) * Number(match[2]);
167
- else if (match = /^(\d+(?:\.\d+)?)p$/.exec(text)) pixels = Number(match[1]) ** 2 * 16 / 9;
168
- else if (match = /^(\d+(?:\.\d+)?)k$/.exec(text)) pixels = (Number(match[1]) * 1024) ** 2;
169
- return pixels && pixels > 0 ? Math.log(pixels) : void 0;
170
- }
171
- function resolutionMegapixels(value) {
172
- const rank = resolutionRank(value);
173
- return rank === void 0 ? void 0 : Math.exp(rank) / 1e6;
174
- }
175
- var QUALITY_LADDER = {
176
- draft: 0,
177
- preview: 0,
178
- low: 1,
179
- fast: 1,
180
- turbo: 1,
181
- standard: 2,
182
- normal: 2,
183
- medium: 2,
184
- balanced: 2,
185
- high: 3,
186
- hd: 3,
187
- quality: 3,
188
- ultra: 4,
189
- max: 5,
190
- best: 5
191
- };
192
- function qualityRank(value) {
193
- return QUALITY_LADDER[String(value).trim().toLowerCase()];
194
- }
195
- var numberRank = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
196
- function snapToOption(value, options, rank, tie) {
197
- const target = rank(value);
198
- if (target === void 0) return void 0;
199
- let best;
200
- for (const option of options) {
201
- const r = rank(option);
202
- if (r === void 0) continue;
203
- const distance = Math.abs(r - target);
204
- if (!best || distance < best.distance - EPSILON || Math.abs(distance - best.distance) <= EPSILON && (tie === "lower" ? r < best.rank : r > best.rank)) {
205
- best = { option, distance, rank: r };
206
- }
207
- }
208
- return best?.option;
209
- }
210
- function truncateText(text, max) {
211
- if (text.length <= max) return text;
212
- let end = max;
213
- const code = text.charCodeAt(end - 1);
214
- if (end > 0 && code >= 55296 && code <= 56319) end -= 1;
215
- return text.slice(0, end);
216
- }
217
- function cloneRequest(request) {
218
- const copy = { ...request };
219
- if (request.references) copy.references = request.references.map((ref) => ({ ...ref }));
220
- if (request.params) copy.params = { ...request.params };
221
- return copy;
222
- }
223
- var describe = (value) => typeof value === "string" ? `"${value}"` : JSON.stringify(value);
224
- var list = (options) => options.map(describe).join(", ");
225
- var Planner = class {
226
- constructor(caps, request, options, strategy) {
227
- this.caps = caps;
228
- this.request = request;
229
- this.options = options;
230
- this.strategy = strategy;
231
- this.tie = strategy === "downgrade" ? "lower" : "higher";
232
- this.strict = strategy === "error";
233
- }
234
- caps;
235
- request;
236
- options;
237
- strategy;
238
- adjustments = [];
239
- errors = [];
240
- tie;
241
- strict;
242
- adjust(field, from, to, kind, reason) {
243
- this.adjustments.push({ field, from, to, kind, reason });
244
- }
245
- error(field, value, message) {
246
- this.errors.push({ field, value, message });
247
- }
248
- /** Removes an unsupported field (or reports it under `error`). */
249
- unsupported(field, message) {
250
- const value = this.request[field];
251
- if (this.strict) {
252
- this.error(field, value, message);
253
- return;
254
- }
255
- delete this.request[field];
256
- this.adjust(field, value, void 0, "dropped", message);
257
- }
258
- defaulted(field, value, set) {
259
- if (!this.options.fillDefaults || value === void 0) return;
260
- set();
261
- this.adjust(field, void 0, value, "defaulted", "Filled with the model default.");
262
- }
263
- planText(field, maxLength, measured) {
264
- const value = this.request[field];
265
- if (value === void 0 || maxLength === void 0) return;
266
- if (typeof value !== "string") {
267
- this.error(field, value, `Expected text.`);
268
- return;
269
- }
270
- const text = measured ?? value;
271
- if (text.length <= maxLength) return;
272
- if (this.strict || measured !== void 0) {
273
- this.error(
274
- field,
275
- text.length,
276
- `${measured !== void 0 ? "Resolved text" : "Text"} is ${text.length} characters; the model accepts at most ${maxLength}.`
277
- );
278
- return;
279
- }
280
- const next = truncateText(value, maxLength);
281
- this.request[field] = next;
282
- this.adjust(field, value.length, next.length, "truncated", `Truncated to the model's ${maxLength}-character limit.`);
283
- }
284
- planEnum(field, cap, rank, label) {
285
- const value = this.request[field];
286
- if (value === void 0) {
287
- if (cap) this.defaulted(field, cap.default, () => this.request[field] = cap.default);
288
- return;
289
- }
290
- if (!cap || cap.options.length === 0) {
291
- this.unsupported(field, `The model does not take a ${label}.`);
292
- return;
293
- }
294
- if (cap.options.includes(value)) return;
295
- if (this.strict) {
296
- this.error(field, value, `${describe(value)} is not a supported ${label}; supported: ${list(cap.options)}.`);
297
- return;
298
- }
299
- const snapped = snapToOption(value, cap.options, rank, this.tie);
300
- const next = snapped ?? cap.default ?? cap.options[0];
301
- this.request[field] = next;
302
- this.adjust(
303
- field,
304
- value,
305
- next,
306
- "snapped",
307
- snapped !== void 0 ? `${describe(value)} is not supported; using the nearest ${label}.` : `${describe(value)} is not supported; using ${cap.default !== void 0 ? "the default" : "the first option"}.`
308
- );
309
- }
310
- /** Clamps/rounds/snaps a number. Returns the next value or `undefined` after an error. */
311
- planNumber(field, value, spec, label) {
312
- if (typeof value !== "number" || !Number.isFinite(value)) {
313
- this.error(field, value, `Expected a number for ${label}.`);
314
- return void 0;
315
- }
316
- const options = spec.options?.filter(
317
- (o) => (spec.min === void 0 || o >= spec.min) && (spec.max === void 0 || o <= spec.max)
318
- );
319
- if (options && options.length > 0) {
320
- if (options.includes(value)) return { value, changed: false };
321
- if (this.strict) {
322
- this.error(field, value, `${value} is not a supported ${label}; supported: ${list(options)}.`);
323
- return void 0;
324
- }
325
- const next2 = snapToOption(value, options, numberRank, this.tie);
326
- this.adjust(field, value, next2, "snapped", `${value} is not supported; using the nearest ${label}.`);
327
- return { value: next2, changed: true };
328
- }
329
- let next = value;
330
- if (spec.step !== void 0 && spec.step > 0) {
331
- const base = spec.min ?? 0;
332
- const steps = (next - base) / spec.step;
333
- const rounded = Math.abs(steps - Math.trunc(steps) - 0.5) < EPSILON ? this.tie === "lower" ? Math.floor(steps) : Math.ceil(steps) : Math.round(steps);
334
- next = Number((base + rounded * spec.step).toPrecision(12));
335
- }
336
- if (spec.integer && !Number.isInteger(next)) {
337
- const frac = next - Math.floor(next);
338
- next = Math.abs(frac - 0.5) < EPSILON ? this.tie === "lower" ? Math.floor(next) : Math.ceil(next) : Math.round(next);
339
- }
340
- let kind = "snapped";
341
- if (spec.min !== void 0 && next < spec.min) {
342
- next = spec.min;
343
- kind = "clamped";
344
- }
345
- if (spec.max !== void 0 && next > spec.max) {
346
- next = spec.max;
347
- kind = "clamped";
348
- }
349
- if (next === value) return { value, changed: false };
350
- const range = `${spec.min ?? "-\u221E"}\u2013${spec.max ?? "\u221E"}`;
351
- if (this.strict) {
352
- this.error(
353
- field,
354
- value,
355
- kind === "clamped" ? `${label} must be within ${range}.` : `${value} is not a valid ${label} (try ${next}).`
356
- );
357
- return void 0;
358
- }
359
- this.adjust(
360
- field,
361
- value,
362
- next,
363
- kind,
364
- kind === "clamped" ? `Clamped to the supported range ${range}.` : `Rounded to a supported ${label}.`
365
- );
366
- return { value: next, changed: true };
367
- }
368
- planCount() {
369
- const value = this.request.count;
370
- const cap = this.caps.count;
371
- if (value === void 0) {
372
- if (cap) this.defaulted("count", cap.default, () => this.request.count = cap.default);
373
- return;
374
- }
375
- if (!cap) {
376
- if (value === 1) return;
377
- this.unsupported("count", "The model produces one output per request.");
378
- return;
379
- }
380
- const result = this.planNumber("count", value, { min: 1, max: cap.max, integer: true, options: cap.options }, "output count");
381
- if (result) this.request.count = result.value;
382
- }
383
- planDuration() {
384
- const value = this.request.duration;
385
- const cap = this.caps.duration;
386
- if (value === void 0) {
387
- if (cap) this.defaulted("duration", cap.default, () => this.request.duration = cap.default);
388
- return;
389
- }
390
- if (!cap) {
391
- this.unsupported("duration", "The model does not take a duration.");
392
- return;
393
- }
394
- const result = this.planNumber("duration", value, cap, "duration");
395
- if (result) this.request.duration = result.value;
396
- }
397
- planSeed() {
398
- const value = this.request.seed;
399
- if (value === void 0) return;
400
- const cap = seedCapability(this.caps.seed);
401
- if (!cap) {
402
- this.unsupported("seed", "The model does not take a seed.");
403
- return;
404
- }
405
- const result = this.planNumber("seed", value, { ...cap, integer: true }, "seed");
406
- if (result) this.request.seed = result.value;
407
- }
408
- planMode() {
409
- const mode = this.request.mode;
410
- if (mode === void 0) return;
411
- const modes = supportedModes(this.caps);
412
- if (!modes.includes(mode)) {
413
- this.error("mode", mode, `The model does not support ${describe(mode)}; supported: ${list(modes)}.`);
414
- }
415
- }
416
- roleCapability(role) {
417
- const cap = this.caps.references?.roles[role];
418
- if (cap && cap.max > 0) return cap;
419
- if (role === "mask" && this.caps.inpainting) return { max: 1 };
420
- return void 0;
421
- }
422
- /** Turns `options.mentions` into references (appended after the request's own). */
423
- addMentions() {
424
- const mentions = this.options.mentions;
425
- if (!mentions?.length) return;
426
- const refs = [...this.request.references ?? []];
427
- for (const mention of mentions) {
428
- if (!mention || typeof mention.id !== "string" || mention.id === "") continue;
429
- let role = mention.role ?? void 0;
430
- if (!role) {
431
- role = this.options.defaultMentionRole ?? this.inferRole(mention.mediaType);
432
- this.adjust(
433
- `references.${role}`,
434
- void 0,
435
- role,
436
- "defaulted",
437
- `@${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
- }
459
- planReferences() {
460
- const refs = this.request.references;
461
- const allowDrop = !this.strict && (this.options.dropUnsupportedReferences ?? (this.strategy === "nearest" || this.strategy === "downgrade"));
462
- const byRole = /* @__PURE__ */ new Map();
463
- const kept = [];
464
- const unsupported = /* @__PURE__ */ new Map();
465
- for (const [index, original] of (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`.");
469
- continue;
470
- }
471
- if (!this.roleCapability(ref.role)) {
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, (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(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);
496
- continue;
497
- }
498
- const group = byRole.get(ref.role) ?? [];
499
- if (group.some((other) => other.id === ref.id)) {
500
- this.adjust(`references.${ref.role}`, ref.id, void 0, "dropped", `Duplicate reference "${ref.id}" removed.`);
501
- continue;
502
- }
503
- group.push(ref);
504
- byRole.set(ref.role, group);
505
- kept.push(ref);
506
- }
507
- for (const [role, count] of unsupported) {
508
- const message = this.caps.media === "text" || !this.caps.references ? `The ${this.caps.media} model "${this.caps.id}" does not accept reference inputs (${role}).` : `The model does not accept ${role} references.`;
509
- if (allowDrop) this.adjust(`references.${role}`, count, 0, "dropped", message);
510
- else this.error(`references.${role}`, count, message);
511
- }
512
- const removed = /* @__PURE__ */ new Set();
513
- const custom = supportedReferenceRoles(this.caps).filter(
514
- (role) => !REFERENCE_ROLES.includes(role)
515
- );
516
- for (const role of [...REFERENCE_ROLES, ...custom]) {
517
- const cap = this.roleCapability(role);
518
- const group = byRole.get(role) ?? [];
519
- if (!cap) continue;
520
- if (group.length > cap.max) {
521
- if (this.strict) {
522
- this.error(`references.${role}`, group.length, `At most ${cap.max} ${role} reference(s) are supported.`);
523
- } else {
524
- group.slice(cap.max).forEach((ref) => removed.add(ref));
525
- this.adjust(
526
- `references.${role}`,
527
- group.length,
528
- cap.max,
529
- "truncated",
530
- `Kept the first ${cap.max} ${role} reference(s); the model accepts no more.`
531
- );
532
- }
533
- }
534
- if (cap.min !== void 0 && group.length < cap.min) {
535
- this.error(`references.${role}`, group.length, `At least ${cap.min} ${role} reference(s) are required.`);
536
- }
537
- }
538
- let next = kept.filter((ref) => !removed.has(ref));
539
- const maxTotal = this.caps.references?.maxTotal;
540
- if (maxTotal !== void 0 && next.length > maxTotal) {
541
- if (this.strict) {
542
- this.error("references", next.length, `At most ${maxTotal} references are supported in total.`);
543
- } else {
544
- this.adjust(
545
- "references",
546
- next.length,
547
- maxTotal,
548
- "truncated",
549
- `Kept the first ${maxTotal} references; the model accepts no more in total.`
550
- );
551
- next = next.slice(0, maxTotal);
552
- }
553
- }
554
- if (this.request.mode === "inpaint" && !next.some((ref) => ref.role === "mask")) {
555
- this.error("references.mask", 0, "Inpainting needs a `mask` reference.");
556
- }
557
- if (refs === void 0) return;
558
- if (!this.strict) {
559
- if (next.length > 0) this.request.references = next;
560
- else delete this.request.references;
561
- }
562
- }
563
- planParam(name, spec, value) {
564
- const field = `params.${name}`;
565
- if (!spec) {
566
- if (this.strict) this.error(field, value, `Unknown parameter "${name}".`);
567
- else this.adjust(field, value, void 0, "dropped", `The model has no "${name}" parameter.`);
568
- return void 0;
569
- }
570
- const label = spec.label ?? name;
571
- if (spec.type === "boolean") {
572
- if (typeof value !== "boolean") this.error(field, value, `Expected true or false for ${label}.`);
573
- return value;
574
- }
575
- if (spec.type === "enum") {
576
- if (spec.options.includes(value)) return value;
577
- if (this.strict) {
578
- this.error(field, value, `${describe(value)} is not a supported ${label}; supported: ${list(spec.options)}.`);
579
- return value;
580
- }
581
- const numeric = spec.options.every((o) => typeof o === "number");
582
- const snapped = numeric ? snapToOption(value, spec.options, numberRank, this.tie) : void 0;
583
- const next = snapped ?? spec.default ?? spec.options[0];
584
- this.adjust(
585
- field,
586
- value,
587
- next,
588
- "snapped",
589
- snapped !== void 0 ? `Using the nearest supported ${label}.` : `${describe(value)} is not supported; using ${spec.default !== void 0 ? "the default" : "the first option"}.`
590
- );
591
- return next;
592
- }
593
- const result = this.planNumber(field, value, { ...spec, integer: spec.type === "integer" }, label);
594
- return result ? result.value : value;
595
- }
596
- planParams() {
597
- const params = this.request.params;
598
- const specs = this.caps.params ?? {};
599
- const next = {};
600
- for (const [name, value] of Object.entries(params ?? {})) {
601
- if (value === void 0) continue;
602
- const planned = this.planParam(name, specs[name], value);
603
- if (planned !== void 0) next[name] = planned;
604
- else if (this.strict) next[name] = value;
605
- }
606
- if (this.options.fillDefaults) {
607
- for (const [name, spec] of Object.entries(specs)) {
608
- if (next[name] === void 0 && spec.default !== void 0) {
609
- next[name] = spec.default;
610
- this.adjust(`params.${name}`, void 0, spec.default, "defaulted", "Filled with the model default.");
611
- }
612
- }
613
- }
614
- if (Object.keys(next).length > 0) this.request.params = next;
615
- else delete this.request.params;
616
- }
617
- run() {
618
- const { caps, request } = this;
619
- for (const key of Object.keys(request)) {
620
- if (GENERATION_REQUEST_FIELDS.includes(key)) continue;
621
- const value = request[key];
622
- if (this.strict) this.error(key, value, `Unknown request field "${key}".`);
623
- else {
624
- delete request[key];
625
- this.adjust(key, value, void 0, "dropped", `Unknown request field "${key}".`);
626
- }
627
- }
628
- if (request.model !== void 0 && request.model !== caps.id) {
629
- this.error("model", request.model, `The request targets "${request.model}" but the plan is for "${caps.id}".`);
630
- }
631
- request.model = caps.id;
632
- const promptCap = caps.prompt ?? {};
633
- if (promptCap.required && !(request.prompt ?? "").trim()) {
634
- this.error("prompt", request.prompt, "A prompt is required.");
635
- }
636
- const countResolved = promptCap.countResolved ?? true;
637
- const measured = countResolved && this.options.resolvedPrompt !== void 0 && this.options.resolvedPrompt !== request.prompt ? this.options.resolvedPrompt : void 0;
638
- this.planText("prompt", promptCap.maxLength, measured);
639
- for (const field of ["negativePrompt", "systemPrompt"]) {
640
- if (request[field] === void 0) continue;
641
- const cap = textFieldCapability(caps[field]);
642
- if (!cap) {
643
- this.unsupported(field, `The model does not take a ${field === "negativePrompt" ? "negative" : "system"} prompt.`);
644
- continue;
645
- }
646
- this.planText(field, cap.maxLength);
647
- }
648
- this.planEnum("aspectRatio", caps.aspectRatios, aspectRatioRank, "aspect ratio");
649
- this.planEnum("resolution", caps.resolutions, resolutionRank, "resolution");
650
- this.planEnum("quality", caps.quality, qualityRank, "quality");
651
- this.planCount();
652
- this.planDuration();
653
- this.planSeed();
654
- this.planMode();
655
- this.addMentions();
656
- this.planReferences();
657
- this.planParams();
658
- }
659
- };
660
- function planGenerationRequest(request, caps, options = {}) {
661
- const strategy = options.strategy ?? "nearest";
662
- const planner = new Planner(caps, cloneRequest(request ?? {}), options, strategy);
663
- planner.run();
664
- return {
665
- ok: planner.errors.length === 0,
666
- request: planner.request,
667
- adjustments: planner.adjustments,
668
- errors: planner.errors,
669
- model: caps.id,
670
- strategy
671
- };
672
- }
46
+ import {
47
+ getLatestVersion,
48
+ getTemplateBody,
49
+ resolvePrompt
50
+ } from "../chunk-FPENXAEJ.js";
51
+ import "../chunk-P6ODPZ4W.js";
673
52
 
674
53
  // src/generation/schema.ts
675
54
  function enumSchema(cap, description) {
@@ -813,48 +192,6 @@ function capabilitiesToJsonSchema(caps) {
813
192
  };
814
193
  }
815
194
 
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 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
-
858
195
  // src/generation/tools.ts
859
196
  var STRATEGIES = ["nearest", "upgrade", "downgrade", "error"];
860
197
  function knownRoles(models) {
@@ -959,7 +296,7 @@ function createGenerationToolProvider(options) {
959
296
  };
960
297
  };
961
298
  const tools = () => {
962
- const list2 = [
299
+ const list = [
963
300
  {
964
301
  name: "list_models",
965
302
  title: "List generation models",
@@ -1006,7 +343,7 @@ function createGenerationToolProvider(options) {
1006
343
  ];
1007
344
  if (options.estimate) {
1008
345
  const estimate = options.estimate;
1009
- list2.push({
346
+ list.push({
1010
347
  name: "estimate_generation",
1011
348
  title: "Estimate a generation",
1012
349
  description: "Estimates cost and/or time of a request after planning it. Does not generate anything.",
@@ -1027,7 +364,7 @@ function createGenerationToolProvider(options) {
1027
364
  });
1028
365
  }
1029
366
  const generateInput = planInput();
1030
- list2.push({
367
+ list.push({
1031
368
  name: "generate",
1032
369
  title: "Generate media",
1033
370
  description: "Plans the request and starts a generation. Pass a fresh `idempotencyKey` per intended generation and reuse it when retrying, so a retry never generates twice.",
@@ -1087,7 +424,7 @@ function createGenerationToolProvider(options) {
1087
424
  }
1088
425
  }
1089
426
  });
1090
- return list2;
427
+ return list;
1091
428
  };
1092
429
  return {
1093
430
  id: options.id ?? "generation",
@@ -1248,138 +585,6 @@ function describeAssetMentions(mentions, assets, caps) {
1248
585
  return chips;
1249
586
  }
1250
587
 
1251
- // src/generation/provenance.ts
1252
- var PROVENANCE_FORMAT = "pixerate.generation-provenance";
1253
- var PROVENANCE_VERSION = 1;
1254
- var ProvenanceParseError = class extends Error {
1255
- constructor(message) {
1256
- super(message);
1257
- this.name = "ProvenanceParseError";
1258
- }
1259
- };
1260
- var toIso = (value) => new Date(value).toISOString();
1261
- var clone = (value) => value === void 0 ? value : JSON.parse(JSON.stringify(value));
1262
- function pinTemplates(rawPrompt, templates, bindings, maxDepth) {
1263
- const byName = new Map(templates.map((t) => [t.name, t]));
1264
- const pinned = /* @__PURE__ */ new Map();
1265
- const visit = (text, depth) => {
1266
- if (depth > maxDepth) return;
1267
- for (const token of tokenizePrompt(text)) {
1268
- if (token.type !== "template" || pinned.has(token.value)) continue;
1269
- const template = byName.get(token.value);
1270
- if (!template) continue;
1271
- const body = getTemplateBody(template, bindings);
1272
- if (body === void 0) continue;
1273
- const bound = bindings[template.name];
1274
- const version = bound && template.versions ? template.versions.find((v) => v.id === bound || v.version === bound) : getLatestVersion(template);
1275
- const isVersioned = !!template.versions?.length && !!version;
1276
- pinned.set(template.name, {
1277
- name: template.name,
1278
- ...template.id !== void 0 ? { templateId: template.id } : {},
1279
- ...isVersioned ? { versionId: version.id, version: version.version } : {},
1280
- body
1281
- });
1282
- visit(body, depth + 1);
1283
- }
1284
- };
1285
- visit(rawPrompt, 0);
1286
- return [...pinned.values()];
1287
- }
1288
- function pinnedTemplatesToTemplates(pinned) {
1289
- return pinned.map(
1290
- (p) => p.versionId !== void 0 ? {
1291
- ...p.templateId !== void 0 ? { id: p.templateId } : {},
1292
- name: p.name,
1293
- latestVersion: p.version,
1294
- versions: [{ id: p.versionId, version: p.version ?? p.versionId, body: p.body }]
1295
- } : { ...p.templateId !== void 0 ? { id: p.templateId } : {}, name: p.name, body: p.body }
1296
- );
1297
- }
1298
- function createProvenance(options) {
1299
- const templates = options.templates ?? [];
1300
- const maxDepth = options.maxDepth ?? 10;
1301
- const resolved = resolvePrompt(options.rawPrompt, templates, {
1302
- bindings: options.bindings,
1303
- values: options.values,
1304
- maxDepth
1305
- });
1306
- const pinned = pinTemplates(options.rawPrompt, templates, options.bindings ?? {}, maxDepth);
1307
- const bindings = {};
1308
- for (const p of pinned) if (p.versionId !== void 0) bindings[p.name] = p.versionId;
1309
- const modelId = typeof options.model === "string" ? options.model : options.model.id;
1310
- const request = clone(options.plan?.request ?? options.request ?? {});
1311
- request.model = modelId;
1312
- if (request.prompt === void 0) request.prompt = resolved.text;
1313
- const adjustments = clone(options.adjustments ?? options.plan?.adjustments ?? []);
1314
- return {
1315
- format: PROVENANCE_FORMAT,
1316
- version: PROVENANCE_VERSION,
1317
- rawPrompt: options.rawPrompt,
1318
- templates: pinned,
1319
- bindings,
1320
- values: options.values ? clone(options.values) : null,
1321
- resolvedPrompt: resolved.text,
1322
- sourceMap: resolved.map.map((segment) => {
1323
- const { locked: _locked, ...rest } = segment;
1324
- return rest;
1325
- }),
1326
- modelId,
1327
- request,
1328
- adjustments,
1329
- references: (request.references ?? []).map(({ id, role }) => ({ id, role })),
1330
- createdAt: toIso(options.createdAt ?? Date.now()),
1331
- ...options.startedAt !== void 0 ? { startedAt: toIso(options.startedAt) } : {},
1332
- ...options.completedAt !== void 0 ? { completedAt: toIso(options.completedAt) } : {},
1333
- ...options.outputIds ? { outputIds: [...options.outputIds] } : {},
1334
- ...options.meta ? { meta: clone(options.meta) } : {}
1335
- };
1336
- }
1337
- function serializeProvenance(provenance) {
1338
- return JSON.stringify(provenance);
1339
- }
1340
- var isRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value);
1341
- function parseProvenance(input) {
1342
- let data = input;
1343
- if (typeof input === "string") {
1344
- try {
1345
- data = JSON.parse(input);
1346
- } catch {
1347
- throw new ProvenanceParseError("Provenance is not valid JSON.");
1348
- }
1349
- }
1350
- if (!isRecord(data) || data.format !== PROVENANCE_FORMAT) {
1351
- throw new ProvenanceParseError("Not a generation provenance record.");
1352
- }
1353
- if (typeof data.version !== "number" || data.version > PROVENANCE_VERSION) {
1354
- throw new ProvenanceParseError(`Unsupported provenance version ${JSON.stringify(data.version)}.`);
1355
- }
1356
- const checks = [
1357
- ["rawPrompt", typeof data.rawPrompt === "string"],
1358
- ["resolvedPrompt", typeof data.resolvedPrompt === "string"],
1359
- ["modelId", typeof data.modelId === "string"],
1360
- ["createdAt", typeof data.createdAt === "string"],
1361
- ["request", isRecord(data.request)],
1362
- ["templates", Array.isArray(data.templates) && data.templates.every((t) => isRecord(t) && typeof t.name === "string" && typeof t.body === "string")],
1363
- ["sourceMap", Array.isArray(data.sourceMap)],
1364
- ["adjustments", Array.isArray(data.adjustments)],
1365
- ["references", Array.isArray(data.references)]
1366
- ];
1367
- const bad = checks.find(([, ok]) => !ok);
1368
- if (bad) throw new ProvenanceParseError(`Invalid provenance field "${bad[0]}".`);
1369
- return {
1370
- ...data,
1371
- bindings: isRecord(data.bindings) ? data.bindings : {},
1372
- values: isRecord(data.values) ? data.values : null
1373
- };
1374
- }
1375
- function replayProvenancePrompt(provenance) {
1376
- const result = resolvePrompt(provenance.rawPrompt, pinnedTemplatesToTemplates(provenance.templates), {
1377
- bindings: provenance.bindings,
1378
- ...provenance.values ? { values: provenance.values } : {}
1379
- });
1380
- return { text: result.text, map: result.map, matches: result.text === provenance.resolvedPrompt };
1381
- }
1382
-
1383
588
  // src/generation/record.ts
1384
589
  var GENERATION_RECORD_FORMAT = "pixerate.generation-record";
1385
590
  var GENERATION_RECORD_VERSION = 1;
@@ -1391,7 +596,7 @@ function createGenerationRecordId() {
1391
596
  const random = Math.floor(Math.random() * 2 ** 48).toString(36).padStart(10, "0");
1392
597
  return `gen_${Date.now().toString(36)}${idCounter.toString(36).padStart(4, "0")}${random}`;
1393
598
  }
1394
- var clone2 = (value) => value === void 0 ? value : JSON.parse(JSON.stringify(value));
599
+ var clone = (value) => value === void 0 ? value : JSON.parse(JSON.stringify(value));
1395
600
  function recordTemplates(pinned) {
1396
601
  return pinned.map((p) => ({
1397
602
  name: p.name,
@@ -1431,7 +636,7 @@ function createGenerationRecord(options) {
1431
636
  ...provenanceOptions
1432
637
  } = options;
1433
638
  const caps = typeof model === "string" ? void 0 : model;
1434
- const settings = clone2(settingsInput ?? planInput?.request ?? {});
639
+ const settings = clone(settingsInput ?? planInput?.request ?? {});
1435
640
  let plan = planInput;
1436
641
  if (!plan && caps) {
1437
642
  const resolved = resolvePrompt(options.rawPrompt, options.templates ?? [], {
@@ -1465,16 +670,16 @@ function createGenerationRecord(options) {
1465
670
  strategy: strategyInput ?? plan?.strategy ?? "nearest",
1466
671
  ...seed !== void 0 ? { seed } : {},
1467
672
  assets: recordAssets(provenance.request.references, assets),
1468
- ...mentions?.length ? { mentions: clone2([...mentions]) } : {},
673
+ ...mentions?.length ? { mentions: clone([...mentions]) } : {},
1469
674
  createdAt: provenance.createdAt
1470
675
  };
1471
676
  }
1472
677
  function completeGenerationRecord(record, update) {
1473
- const next = clone2(record);
678
+ const next = clone(record);
1474
679
  const now = new Date(update.completedAt ?? Date.now()).toISOString();
1475
680
  if (update.outputIds) next.provenance.outputIds = [...update.outputIds];
1476
681
  next.provenance.completedAt = now;
1477
- if (update.meta) next.provenance.meta = { ...next.provenance.meta ?? {}, ...clone2(update.meta) };
682
+ if (update.meta) next.provenance.meta = { ...next.provenance.meta ?? {}, ...clone(update.meta) };
1478
683
  if (update.seed !== void 0) next.seed = update.seed;
1479
684
  next.updatedAt = now;
1480
685
  return next;
@@ -1522,8 +727,8 @@ function isGenerationRecord(value) {
1522
727
  var SKIPPED_SETTING_FIELDS = /* @__PURE__ */ new Set(["model", "prompt", "references", "params", "seed"]);
1523
728
  function findModel(capabilities, modelId) {
1524
729
  if (!capabilities) return { given: false };
1525
- const list2 = Array.isArray(capabilities) ? capabilities : [capabilities];
1526
- return { given: true, caps: list2.find((m) => m.id === modelId) };
730
+ const list = Array.isArray(capabilities) ? capabilities : [capabilities];
731
+ return { given: true, caps: list.find((m) => m.id === modelId) };
1527
732
  }
1528
733
  var sameValue = (a, b) => stableStringify(a) === stableStringify(b);
1529
734
  var show = (value) => value === void 0 ? "unset" : typeof value === "string" ? `"${value}"` : JSON.stringify(value);
@@ -1582,7 +787,7 @@ function rebuild(record, options, kind, overrides) {
1582
787
  const provenance = record.provenance;
1583
788
  const drift = templateDrift(record, options.templates, mode);
1584
789
  const rawPrompt = overrides?.rawPrompt ?? provenance.rawPrompt;
1585
- const values = overrides?.values !== void 0 ? { ...provenance.values ?? {}, ...overrides.values } : provenance.values ? clone2(provenance.values) : null;
790
+ const values = overrides?.values !== void 0 ? { ...provenance.values ?? {}, ...overrides.values } : provenance.values ? clone(provenance.values) : null;
1586
791
  const pinned = pinnedTemplatesToTemplates(provenance.templates);
1587
792
  let templates;
1588
793
  let bindings;
@@ -1613,7 +818,7 @@ function rebuild(record, options, kind, overrides) {
1613
818
  message: "The resolved prompt differs from the recorded one."
1614
819
  });
1615
820
  }
1616
- const base = clone2(mode === "exact" ? provenance.request : record.settings);
821
+ const base = clone(mode === "exact" ? provenance.request : record.settings);
1617
822
  const recordedPlanned = provenance.request;
1618
823
  if (base.prompt === void 0 || base.prompt === provenance.resolvedPrompt) base.prompt = resolved.text;
1619
824
  else if (base.prompt === provenance.rawPrompt) base.prompt = rawPrompt;
@@ -1630,7 +835,7 @@ function rebuild(record, options, kind, overrides) {
1630
835
  }))
1631
836
  ];
1632
837
  } else if (mode === "latest" && base.references === void 0 && recordedPlanned.references) {
1633
- base.references = clone2(recordedPlanned.references);
838
+ base.references = clone(recordedPlanned.references);
1634
839
  }
1635
840
  if (record.seed !== void 0) base.seed = record.seed;
1636
841
  base.model = provenance.modelId;
@@ -1638,8 +843,8 @@ function rebuild(record, options, kind, overrides) {
1638
843
  if (overrides) {
1639
844
  if (overrides.settings) {
1640
845
  const { params, ...rest } = overrides.settings;
1641
- Object.assign(base, clone2(rest));
1642
- if (params) base.params = { ...base.params ?? {}, ...clone2(params) };
846
+ Object.assign(base, clone(rest));
847
+ if (params) base.params = { ...base.params ?? {}, ...clone(params) };
1643
848
  }
1644
849
  if (overrides.seed === null) delete base.seed;
1645
850
  else base.seed = overrides.seed ?? randomSeed(caps, record.seed, overrides.random ?? Math.random);
@@ -1784,7 +989,7 @@ function rebuild(record, options, kind, overrides) {
1784
989
  function recreateRequest(input, options) {
1785
990
  if (isGenerationRecord(input)) return rebuild(input, options ?? {}, "recreate");
1786
991
  const provenance = input;
1787
- const request = clone2(provenance.request);
992
+ const request = clone(provenance.request);
1788
993
  request.model = provenance.modelId;
1789
994
  if (request.prompt === void 0) request.prompt = provenance.resolvedPrompt;
1790
995
  return request;