@pixerate/editor 0.80.0 → 0.81.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.
- package/README.md +13 -3
- package/dist/agent/index.cjs +102 -6
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +4 -2
- package/dist/agent/index.d.ts +4 -2
- package/dist/agent/index.js +101 -5
- package/dist/agent/index.js.map +1 -1
- package/dist/{builtins-BKYlHH1s.d.ts → builtins-CV1fDj64.d.ts} +5 -1
- package/dist/{builtins-1kqwLUnb.d.cts → builtins-c4w0eAYl.d.cts} +5 -1
- package/dist/{chunk-2CJ3LPYQ.js → chunk-424H3P4I.js} +13 -295
- package/dist/chunk-424H3P4I.js.map +1 -0
- package/dist/{chunk-UN33YOXW.cjs → chunk-PA5S7KPC.cjs} +293 -2
- package/dist/chunk-PA5S7KPC.cjs.map +1 -0
- package/dist/{chunk-IB3ZHQAX.js → chunk-PTYWCFFW.js} +29 -4
- package/dist/chunk-PTYWCFFW.js.map +1 -0
- package/dist/{chunk-JQ3BB3E6.js → chunk-PXDEFEG2.js} +293 -2
- package/dist/chunk-PXDEFEG2.js.map +1 -0
- package/dist/{chunk-YU4WQE5M.cjs → chunk-TAPXWP2B.cjs} +95 -377
- package/dist/chunk-TAPXWP2B.cjs.map +1 -0
- package/dist/{chunk-HXDMZQTD.cjs → chunk-TPOT575P.cjs} +29 -4
- package/dist/{chunk-IB3ZHQAX.js.map → chunk-TPOT575P.cjs.map} +1 -1
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.d.cts +1 -1
- package/dist/commands/index.d.ts +1 -1
- package/dist/commands/index.js +1 -1
- package/dist/generation/index.cjs +932 -791
- package/dist/generation/index.cjs.map +1 -1
- package/dist/generation/index.d.cts +266 -240
- package/dist/generation/index.d.ts +266 -240
- package/dist/generation/index.js +926 -785
- package/dist/generation/index.js.map +1 -1
- package/dist/image-editor/index.cjs +266 -2
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +12 -1
- package/dist/image-editor/index.d.ts +12 -1
- package/dist/image-editor/index.js +265 -1
- package/dist/image-editor/index.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +16 -16
- package/dist/spreadsheet/index.cjs +3 -3
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.js +16 -16
- package/package.json +2 -1
- package/skills/README.md +55 -0
- package/skills/pixerate-agent-tools/SKILL.md +75 -0
- package/skills/pixerate-animation-editor/SKILL.md +155 -0
- package/skills/pixerate-animation-editor/references/commands.md +123 -0
- package/skills/pixerate-canvas/SKILL.md +230 -0
- package/skills/pixerate-chart/SKILL.md +190 -0
- package/skills/pixerate-diagram/SKILL.md +134 -0
- package/skills/pixerate-generation/SKILL.md +109 -0
- package/skills/pixerate-image-editor/SKILL.md +139 -0
- package/skills/pixerate-parameters/SKILL.md +83 -0
- package/skills/pixerate-rich-text/SKILL.md +160 -0
- package/skills/pixerate-spreadsheet/SKILL.md +146 -0
- package/skills/pixerate-vector/SKILL.md +191 -0
- package/skills/pixerate-vector/references/commands.md +138 -0
- package/skills/pixerate-video-editor/SKILL.md +173 -0
- package/dist/chunk-2CJ3LPYQ.js.map +0 -1
- package/dist/chunk-HXDMZQTD.cjs.map +0 -1
- package/dist/chunk-JQ3BB3E6.js.map +0 -1
- package/dist/chunk-UN33YOXW.cjs.map +0 -1
- package/dist/chunk-YU4WQE5M.cjs.map +0 -1
|
@@ -1101,6 +1101,153 @@ function createGenerationToolProvider(options) {
|
|
|
1101
1101
|
};
|
|
1102
1102
|
}
|
|
1103
1103
|
|
|
1104
|
+
// src/generation/assets.ts
|
|
1105
|
+
function toAssetResolver(lookup) {
|
|
1106
|
+
if (!lookup) return void 0;
|
|
1107
|
+
if (typeof lookup === "function") return (id) => _nullishCoalesce(lookup(id), () => ( void 0));
|
|
1108
|
+
if (lookup instanceof Map) return (id) => lookup.get(id);
|
|
1109
|
+
const byId = new Map(lookup.map((asset) => [asset.id, asset]));
|
|
1110
|
+
return (id) => byId.get(id);
|
|
1111
|
+
}
|
|
1112
|
+
function roleCap(caps, role) {
|
|
1113
|
+
const cap = _optionalChain([caps, 'access', _69 => _69.references, 'optionalAccess', _70 => _70.roles, 'access', _71 => _71[role]]);
|
|
1114
|
+
if (cap && cap.max > 0) return cap;
|
|
1115
|
+
if (role === "mask" && caps.inpainting) return { max: 1 };
|
|
1116
|
+
return void 0;
|
|
1117
|
+
}
|
|
1118
|
+
function getAssetRoleOptions(caps) {
|
|
1119
|
+
const roles = supportedReferenceRoles(caps);
|
|
1120
|
+
if (caps.inpainting && !roles.includes("mask")) roles.push("mask");
|
|
1121
|
+
return roles.map((role) => {
|
|
1122
|
+
const cap = _nullishCoalesce(roleCap(caps, role), () => ( { max: 1 }));
|
|
1123
|
+
return {
|
|
1124
|
+
role,
|
|
1125
|
+
label: referenceRoleLabel(role, caps),
|
|
1126
|
+
...cap.description ? { description: cap.description } : {},
|
|
1127
|
+
min: _nullishCoalesce(cap.min, () => ( 0)),
|
|
1128
|
+
max: cap.max,
|
|
1129
|
+
..._optionalChain([cap, 'access', _72 => _72.accepts, 'optionalAccess', _73 => _73.length]) ? { accepts: [...cap.accepts] } : {}
|
|
1130
|
+
};
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
function validateAssetMentions(mentions, caps, options = {}) {
|
|
1134
|
+
const resolve = toAssetResolver(options.assets);
|
|
1135
|
+
const issues = [];
|
|
1136
|
+
const counts = {};
|
|
1137
|
+
mentions.forEach((mention, index) => {
|
|
1138
|
+
const id = mention.id;
|
|
1139
|
+
const label = `@${_nullishCoalesce(mention.label, () => ( id))}`;
|
|
1140
|
+
if (!mention.role) {
|
|
1141
|
+
issues.push({ index, id, code: "missing-role", severity: "warning", message: `${label} has no role.` });
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
let role = mention.role;
|
|
1145
|
+
if (!roleCap(caps, role)) {
|
|
1146
|
+
const alias = normalizeReferenceRole(role, caps);
|
|
1147
|
+
if (alias !== role && roleCap(caps, alias)) {
|
|
1148
|
+
issues.push({
|
|
1149
|
+
index,
|
|
1150
|
+
id,
|
|
1151
|
+
role,
|
|
1152
|
+
code: "renamed-role",
|
|
1153
|
+
severity: "warning",
|
|
1154
|
+
suggestion: alias,
|
|
1155
|
+
message: `${label}: this model calls "${role}" ${referenceRoleLabel(alias, caps)} (${alias}).`
|
|
1156
|
+
});
|
|
1157
|
+
role = alias;
|
|
1158
|
+
} else {
|
|
1159
|
+
issues.push({
|
|
1160
|
+
index,
|
|
1161
|
+
id,
|
|
1162
|
+
role,
|
|
1163
|
+
code: "unsupported-role",
|
|
1164
|
+
severity: "error",
|
|
1165
|
+
message: `${label}: ${_nullishCoalesce(caps.name, () => ( caps.id))} does not accept ${referenceRoleLabel(role, caps).toLowerCase()} assets.`
|
|
1166
|
+
});
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
const cap = roleCap(caps, role);
|
|
1171
|
+
const mediaType = _nullishCoalesce(mention.mediaType, () => ( _optionalChain([resolve, 'optionalCall', _74 => _74(id), 'optionalAccess', _75 => _75.mediaType])));
|
|
1172
|
+
if (mediaType !== void 0 && !mediaTypeMatches(mediaType, cap.accepts)) {
|
|
1173
|
+
issues.push({
|
|
1174
|
+
index,
|
|
1175
|
+
id,
|
|
1176
|
+
role,
|
|
1177
|
+
code: "media-mismatch",
|
|
1178
|
+
severity: "error",
|
|
1179
|
+
message: `${label} is ${mediaType}; ${referenceRoleLabel(role, caps)} accepts ${(_nullishCoalesce(cap.accepts, () => ( []))).join(", ")}.`
|
|
1180
|
+
});
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
counts[role] = (_nullishCoalesce(counts[role], () => ( 0))) + 1;
|
|
1184
|
+
if (counts[role] > cap.max) {
|
|
1185
|
+
issues.push({
|
|
1186
|
+
index,
|
|
1187
|
+
id,
|
|
1188
|
+
role,
|
|
1189
|
+
code: "too-many",
|
|
1190
|
+
severity: "warning",
|
|
1191
|
+
message: `${label}: at most ${cap.max} ${referenceRoleLabel(role, caps).toLowerCase()} asset(s); extra ones are left out.`
|
|
1192
|
+
});
|
|
1193
|
+
}
|
|
1194
|
+
});
|
|
1195
|
+
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)) }));
|
|
1196
|
+
return { ok: !issues.some((issue) => issue.severity === "error") && missing.length === 0, issues, counts, missing };
|
|
1197
|
+
}
|
|
1198
|
+
function resolveAssetMentions(mentions, assets) {
|
|
1199
|
+
const byId = new Map(assets.map((asset) => [asset.id, asset]));
|
|
1200
|
+
const byLabel = new Map(assets.filter((a) => a.label).map((asset) => [asset.label.toLowerCase(), asset]));
|
|
1201
|
+
const result = [];
|
|
1202
|
+
for (const mention of mentions) {
|
|
1203
|
+
const asset = _nullishCoalesce(byId.get(mention.handle), () => ( byLabel.get(mention.handle.toLowerCase())));
|
|
1204
|
+
if (!asset) continue;
|
|
1205
|
+
result.push({
|
|
1206
|
+
id: asset.id,
|
|
1207
|
+
label: mention.handle,
|
|
1208
|
+
...mention.role ? { role: mention.role } : {},
|
|
1209
|
+
...asset.mediaType !== void 0 ? { mediaType: asset.mediaType } : {},
|
|
1210
|
+
...asset.contentHash !== void 0 ? { contentHash: asset.contentHash } : {},
|
|
1211
|
+
...asset.url !== void 0 ? { url: asset.url } : {}
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
return result;
|
|
1215
|
+
}
|
|
1216
|
+
function defaultAssetRoleOptions() {
|
|
1217
|
+
return REFERENCE_ROLES.map((role) => ({ role, label: referenceRoleLabel(role), min: 0, max: 1 }));
|
|
1218
|
+
}
|
|
1219
|
+
function describeAssetMentions(mentions, assets, caps) {
|
|
1220
|
+
const byId = new Map(assets.map((asset) => [asset.id, asset]));
|
|
1221
|
+
const byLabel = new Map(assets.filter((a) => a.label).map((asset) => [asset.label.toLowerCase(), asset]));
|
|
1222
|
+
const chips = [];
|
|
1223
|
+
for (const mention of mentions) {
|
|
1224
|
+
const asset = _nullishCoalesce(byId.get(mention.handle), () => ( byLabel.get(mention.handle.toLowerCase())));
|
|
1225
|
+
if (!asset) continue;
|
|
1226
|
+
const role = mention.role || void 0;
|
|
1227
|
+
chips.push({
|
|
1228
|
+
index: chips.length,
|
|
1229
|
+
...mention.start !== void 0 ? { start: mention.start } : {},
|
|
1230
|
+
handle: mention.handle,
|
|
1231
|
+
asset,
|
|
1232
|
+
...role ? { role, roleLabel: referenceRoleLabel(caps ? normalizeReferenceRole(role, caps) : role, caps) } : {},
|
|
1233
|
+
issues: []
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
if (caps) {
|
|
1237
|
+
const validation = validateAssetMentions(
|
|
1238
|
+
chips.map((chip) => ({
|
|
1239
|
+
id: chip.asset.id,
|
|
1240
|
+
label: chip.handle,
|
|
1241
|
+
...chip.role ? { role: chip.role } : {},
|
|
1242
|
+
...chip.asset.mediaType ? { mediaType: chip.asset.mediaType } : {}
|
|
1243
|
+
})),
|
|
1244
|
+
caps
|
|
1245
|
+
);
|
|
1246
|
+
for (const issue of validation.issues) chips[issue.index].issues.push(issue);
|
|
1247
|
+
}
|
|
1248
|
+
return chips;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1104
1251
|
// src/generation/provenance.ts
|
|
1105
1252
|
var PROVENANCE_FORMAT = "pixerate.generation-provenance";
|
|
1106
1253
|
var PROVENANCE_VERSION = 1;
|
|
@@ -1125,7 +1272,7 @@ function pinTemplates(rawPrompt, templates, bindings, maxDepth) {
|
|
|
1125
1272
|
if (body === void 0) continue;
|
|
1126
1273
|
const bound = bindings[template.name];
|
|
1127
1274
|
const version = bound && template.versions ? template.versions.find((v) => v.id === bound || v.version === bound) : _chunkFD4LPFAEcjs.getLatestVersion.call(void 0, template);
|
|
1128
|
-
const isVersioned = !!_optionalChain([template, 'access',
|
|
1275
|
+
const isVersioned = !!_optionalChain([template, 'access', _76 => _76.versions, 'optionalAccess', _77 => _77.length]) && !!version;
|
|
1129
1276
|
pinned.set(template.name, {
|
|
1130
1277
|
name: template.name,
|
|
1131
1278
|
...template.id !== void 0 ? { templateId: template.id } : {},
|
|
@@ -1160,10 +1307,10 @@ function createProvenance(options) {
|
|
|
1160
1307
|
const bindings = {};
|
|
1161
1308
|
for (const p of pinned) if (p.versionId !== void 0) bindings[p.name] = p.versionId;
|
|
1162
1309
|
const modelId = typeof options.model === "string" ? options.model : options.model.id;
|
|
1163
|
-
const request = clone(_nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'access',
|
|
1310
|
+
const request = clone(_nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'access', _78 => _78.plan, 'optionalAccess', _79 => _79.request]), () => ( options.request)), () => ( {})));
|
|
1164
1311
|
request.model = modelId;
|
|
1165
1312
|
if (request.prompt === void 0) request.prompt = resolved.text;
|
|
1166
|
-
const adjustments = clone(_nullishCoalesce(_nullishCoalesce(options.adjustments, () => ( _optionalChain([options, 'access',
|
|
1313
|
+
const adjustments = clone(_nullishCoalesce(_nullishCoalesce(options.adjustments, () => ( _optionalChain([options, 'access', _80 => _80.plan, 'optionalAccess', _81 => _81.adjustments]))), () => ( [])));
|
|
1167
1314
|
return {
|
|
1168
1315
|
format: PROVENANCE_FORMAT,
|
|
1169
1316
|
version: PROVENANCE_VERSION,
|
|
@@ -1233,849 +1380,842 @@ function replayProvenancePrompt(provenance) {
|
|
|
1233
1380
|
return { text: result.text, map: result.map, matches: result.text === provenance.resolvedPrompt };
|
|
1234
1381
|
}
|
|
1235
1382
|
|
|
1236
|
-
// src/generation/
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
const
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
const pendings = keys.map((key) => inFlight.get(key));
|
|
1247
|
-
const finish = (values, error) => {
|
|
1248
|
-
if (values === null) _optionalChain([options, 'access', _75 => _75.onError, 'optionalCall', _76 => _76(error, keys)]);
|
|
1249
|
-
keys.forEach((key, index) => {
|
|
1250
|
-
const pending = pendings[index];
|
|
1251
|
-
const value = _optionalChain([values, 'optionalAccess', _77 => _77.get, 'call', _78 => _78(key)]);
|
|
1252
|
-
if (pending && inFlight.get(key) === pending) {
|
|
1253
|
-
inFlight.delete(key);
|
|
1254
|
-
settled.set(key, value);
|
|
1255
|
-
if (values === null) failures.add(key);
|
|
1256
|
-
}
|
|
1257
|
-
_optionalChain([pending, 'optionalAccess', _79 => _79.resolve, 'call', _80 => _80(value)]);
|
|
1258
|
-
});
|
|
1259
|
-
};
|
|
1260
|
-
let promise;
|
|
1261
|
-
try {
|
|
1262
|
-
promise = Promise.resolve(options.fetch(keys));
|
|
1263
|
-
} catch (error) {
|
|
1264
|
-
promise = Promise.reject(error);
|
|
1265
|
-
}
|
|
1266
|
-
promise.then(
|
|
1267
|
-
(values) => finish(values instanceof Map ? values : /* @__PURE__ */ new Map()),
|
|
1268
|
-
(error) => finish(null, _nullishCoalesce(error, () => ( new Error("Batch fetch failed."))))
|
|
1269
|
-
);
|
|
1270
|
-
};
|
|
1271
|
-
const flush = () => {
|
|
1272
|
-
if (timer !== null) clearTimeout(timer);
|
|
1273
|
-
timer = null;
|
|
1274
|
-
const keys = queue;
|
|
1275
|
-
queue = [];
|
|
1276
|
-
for (let i = 0; i < keys.length; i += maxBatch) run(keys.slice(i, i + maxBatch));
|
|
1277
|
-
};
|
|
1278
|
-
const load = (key) => {
|
|
1279
|
-
if (settled.has(key)) return Promise.resolve(settled.get(key));
|
|
1280
|
-
const existing = inFlight.get(key);
|
|
1281
|
-
if (existing) return existing.promise;
|
|
1282
|
-
let resolve;
|
|
1283
|
-
const promise = new Promise((r) => resolve = r);
|
|
1284
|
-
inFlight.set(key, { promise, resolve });
|
|
1285
|
-
queue.push(key);
|
|
1286
|
-
if (queue.length >= maxBatch) flush();
|
|
1287
|
-
else if (timer === null) timer = setTimeout(flush, delayMs);
|
|
1288
|
-
return promise;
|
|
1289
|
-
};
|
|
1290
|
-
return {
|
|
1291
|
-
load,
|
|
1292
|
-
loadMany: (keys) => Promise.all(keys.map(load)),
|
|
1293
|
-
peek: (key) => settled.get(key),
|
|
1294
|
-
has: (key) => settled.has(key),
|
|
1295
|
-
failed: (key) => failures.has(key),
|
|
1296
|
-
prime(key, value) {
|
|
1297
|
-
settled.set(key, value);
|
|
1298
|
-
failures.delete(key);
|
|
1299
|
-
},
|
|
1300
|
-
clear(key) {
|
|
1301
|
-
if (key === void 0) {
|
|
1302
|
-
settled.clear();
|
|
1303
|
-
failures.clear();
|
|
1304
|
-
for (const k of [...inFlight.keys()]) if (!queue.includes(k)) inFlight.delete(k);
|
|
1305
|
-
return;
|
|
1306
|
-
}
|
|
1307
|
-
settled.delete(key);
|
|
1308
|
-
failures.delete(key);
|
|
1309
|
-
if (!queue.includes(key)) inFlight.delete(key);
|
|
1310
|
-
},
|
|
1311
|
-
flush
|
|
1312
|
-
};
|
|
1383
|
+
// src/generation/record.ts
|
|
1384
|
+
var GENERATION_RECORD_FORMAT = "pixerate.generation-record";
|
|
1385
|
+
var GENERATION_RECORD_VERSION = 1;
|
|
1386
|
+
var idCounter = 0;
|
|
1387
|
+
function createGenerationRecordId() {
|
|
1388
|
+
const uuid = _optionalChain([globalThis, 'access', _82 => _82.crypto, 'optionalAccess', _83 => _83.randomUUID, 'optionalCall', _84 => _84()]);
|
|
1389
|
+
if (typeof uuid === "string") return `gen_${uuid}`;
|
|
1390
|
+
idCounter = (idCounter + 1) % 1679616;
|
|
1391
|
+
const random = Math.floor(Math.random() * 2 ** 48).toString(36).padStart(10, "0");
|
|
1392
|
+
return `gen_${Date.now().toString(36)}${idCounter.toString(36).padStart(4, "0")}${random}`;
|
|
1313
1393
|
}
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
if (seconds < 60) return `~${Math.max(1, seconds)}s left`;
|
|
1323
|
-
const minutes = Math.ceil(ms / 6e4);
|
|
1324
|
-
if (minutes < 60) return `~${minutes}m left`;
|
|
1325
|
-
const hours = Math.floor(minutes / 60);
|
|
1326
|
-
const rest = minutes % 60;
|
|
1327
|
-
return rest ? `~${hours}h ${rest}m left` : `~${hours}h left`;
|
|
1394
|
+
var clone2 = (value) => value === void 0 ? value : JSON.parse(JSON.stringify(value));
|
|
1395
|
+
function recordTemplates(pinned) {
|
|
1396
|
+
return pinned.map((p) => ({
|
|
1397
|
+
name: p.name,
|
|
1398
|
+
...p.templateId !== void 0 ? { templateId: p.templateId } : {},
|
|
1399
|
+
...p.versionId !== void 0 ? { versionId: p.versionId, version: p.version } : {},
|
|
1400
|
+
hash: hashText(p.body)
|
|
1401
|
+
}));
|
|
1328
1402
|
}
|
|
1329
|
-
function
|
|
1330
|
-
const
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1403
|
+
function recordAssets(references, lookup) {
|
|
1404
|
+
const resolve = toAssetResolver(lookup);
|
|
1405
|
+
return (_nullishCoalesce(references, () => ( []))).map((ref) => {
|
|
1406
|
+
const info = _optionalChain([resolve, 'optionalCall', _85 => _85(ref.id)]);
|
|
1407
|
+
const contentHash = _nullishCoalesce(ref.contentHash, () => ( _optionalChain([info, 'optionalAccess', _86 => _86.contentHash])));
|
|
1408
|
+
const mediaType = _nullishCoalesce(ref.mediaType, () => ( _optionalChain([info, 'optionalAccess', _87 => _87.mediaType])));
|
|
1409
|
+
const url = _nullishCoalesce(ref.url, () => ( _optionalChain([info, 'optionalAccess', _88 => _88.url])));
|
|
1410
|
+
return {
|
|
1411
|
+
id: ref.id,
|
|
1412
|
+
role: ref.role,
|
|
1413
|
+
...contentHash !== void 0 ? { contentHash } : {},
|
|
1414
|
+
...mediaType !== void 0 ? { mediaType } : {},
|
|
1415
|
+
...url !== void 0 ? { url } : {}
|
|
1416
|
+
};
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
function createGenerationRecord(options) {
|
|
1420
|
+
const {
|
|
1421
|
+
model,
|
|
1422
|
+
request: settingsInput,
|
|
1423
|
+
plan: planInput,
|
|
1424
|
+
strategy: strategyInput,
|
|
1425
|
+
mentions,
|
|
1426
|
+
assets,
|
|
1427
|
+
seed: seedInput,
|
|
1428
|
+
id,
|
|
1429
|
+
parentId,
|
|
1430
|
+
kind,
|
|
1431
|
+
...provenanceOptions
|
|
1432
|
+
} = options;
|
|
1433
|
+
const caps = typeof model === "string" ? void 0 : model;
|
|
1434
|
+
const settings = clone2(_nullishCoalesce(_nullishCoalesce(settingsInput, () => ( _optionalChain([planInput, 'optionalAccess', _89 => _89.request]))), () => ( {})));
|
|
1435
|
+
let plan = planInput;
|
|
1436
|
+
if (!plan && caps) {
|
|
1437
|
+
const resolved = _chunkFD4LPFAEcjs.resolvePrompt.call(void 0, options.rawPrompt, _nullishCoalesce(options.templates, () => ( [])), {
|
|
1438
|
+
bindings: options.bindings,
|
|
1439
|
+
values: options.values,
|
|
1440
|
+
maxDepth: options.maxDepth
|
|
1441
|
+
});
|
|
1442
|
+
plan = planGenerationRequest(settings, caps, {
|
|
1443
|
+
strategy: _nullishCoalesce(strategyInput, () => ( "nearest")),
|
|
1444
|
+
resolvedPrompt: resolved.text,
|
|
1445
|
+
...mentions ? { mentions } : {}
|
|
1446
|
+
});
|
|
1341
1447
|
}
|
|
1342
|
-
const
|
|
1343
|
-
|
|
1448
|
+
const provenance = createProvenance({
|
|
1449
|
+
...provenanceOptions,
|
|
1450
|
+
model,
|
|
1451
|
+
...plan ? { plan } : { request: settings }
|
|
1452
|
+
});
|
|
1453
|
+
const seed = _nullishCoalesce(seedInput, () => ( provenance.request.seed));
|
|
1344
1454
|
return {
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1455
|
+
format: GENERATION_RECORD_FORMAT,
|
|
1456
|
+
version: GENERATION_RECORD_VERSION,
|
|
1457
|
+
id: _nullishCoalesce(id, () => ( createGenerationRecordId())),
|
|
1458
|
+
...parentId !== void 0 ? { parentId } : {},
|
|
1459
|
+
kind: _nullishCoalesce(kind, () => ( (parentId !== void 0 ? "recreate" : "generate"))),
|
|
1460
|
+
provenance,
|
|
1461
|
+
templates: recordTemplates(provenance.templates),
|
|
1462
|
+
promptHash: hashText(provenance.resolvedPrompt),
|
|
1463
|
+
...caps ? { capabilityHash: hashCapabilities(caps) } : {},
|
|
1464
|
+
settings,
|
|
1465
|
+
strategy: _nullishCoalesce(_nullishCoalesce(strategyInput, () => ( _optionalChain([plan, 'optionalAccess', _90 => _90.strategy]))), () => ( "nearest")),
|
|
1466
|
+
...seed !== void 0 ? { seed } : {},
|
|
1467
|
+
assets: recordAssets(provenance.request.references, assets),
|
|
1468
|
+
..._optionalChain([mentions, 'optionalAccess', _91 => _91.length]) ? { mentions: clone2([...mentions]) } : {},
|
|
1469
|
+
createdAt: provenance.createdAt
|
|
1350
1470
|
};
|
|
1351
1471
|
}
|
|
1352
|
-
function
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
);
|
|
1472
|
+
function completeGenerationRecord(record, update) {
|
|
1473
|
+
const next = clone2(record);
|
|
1474
|
+
const now = new Date(_nullishCoalesce(update.completedAt, () => ( Date.now()))).toISOString();
|
|
1475
|
+
if (update.outputIds) next.provenance.outputIds = [...update.outputIds];
|
|
1476
|
+
next.provenance.completedAt = now;
|
|
1477
|
+
if (update.meta) next.provenance.meta = { ..._nullishCoalesce(next.provenance.meta, () => ( {})), ...clone2(update.meta) };
|
|
1478
|
+
if (update.seed !== void 0) next.seed = update.seed;
|
|
1479
|
+
next.updatedAt = now;
|
|
1480
|
+
return next;
|
|
1362
1481
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
function enumControl(key, label, cap) {
|
|
1366
|
-
if (!_optionalChain([cap, 'optionalAccess', _87 => _87.options, 'access', _88 => _88.length])) return null;
|
|
1367
|
-
return {
|
|
1368
|
-
key,
|
|
1369
|
-
label,
|
|
1370
|
-
kind: "select",
|
|
1371
|
-
valueType: "string",
|
|
1372
|
-
options: cap.options.map((value) => ({ value, label: _nullishCoalesce(_optionalChain([cap, 'access', _89 => _89.labels, 'optionalAccess', _90 => _90[value]]), () => ( value)) })),
|
|
1373
|
-
...cap.default !== void 0 ? { defaultValue: cap.default } : {}
|
|
1374
|
-
};
|
|
1482
|
+
function serializeGenerationRecord(record) {
|
|
1483
|
+
return JSON.stringify(record);
|
|
1375
1484
|
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
if (
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
options: modes.map((m) => ({ value: m, label: m[0].toUpperCase() + m.slice(1) })),
|
|
1386
|
-
defaultValue: "generate"
|
|
1387
|
-
});
|
|
1485
|
+
var isObject = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
1486
|
+
function parseGenerationRecord(input) {
|
|
1487
|
+
let data = input;
|
|
1488
|
+
if (typeof input === "string") {
|
|
1489
|
+
try {
|
|
1490
|
+
data = JSON.parse(input);
|
|
1491
|
+
} catch (e3) {
|
|
1492
|
+
throw new ProvenanceParseError("Generation record is not valid JSON.");
|
|
1493
|
+
}
|
|
1388
1494
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
const system = textFieldCapability(caps.systemPrompt);
|
|
1392
|
-
if (system) controls.push({ key: "systemPrompt", label: "System prompt", kind: "textarea", valueType: "string", maxLength: system.maxLength });
|
|
1393
|
-
controls.push(enumControl("aspectRatio", "Aspect ratio", caps.aspectRatios));
|
|
1394
|
-
controls.push(enumControl("resolution", "Resolution", caps.resolutions));
|
|
1395
|
-
controls.push(enumControl("quality", "Quality", caps.quality));
|
|
1396
|
-
if (caps.count) {
|
|
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)]);
|
|
1398
|
-
controls.push(
|
|
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)) }
|
|
1400
|
-
);
|
|
1495
|
+
if (!isObject(data) || data.format !== GENERATION_RECORD_FORMAT) {
|
|
1496
|
+
throw new ProvenanceParseError("Not a generation record.");
|
|
1401
1497
|
}
|
|
1402
|
-
if (
|
|
1403
|
-
|
|
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))]);
|
|
1405
|
-
controls.push(
|
|
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 } : {
|
|
1407
|
-
key: "duration",
|
|
1408
|
-
label: "Duration (s)",
|
|
1409
|
-
kind: d.min !== void 0 && d.max !== void 0 ? "range" : "number",
|
|
1410
|
-
valueType: "number",
|
|
1411
|
-
min: d.min,
|
|
1412
|
-
max: d.max,
|
|
1413
|
-
step: d.step,
|
|
1414
|
-
defaultValue: d.default
|
|
1415
|
-
}
|
|
1416
|
-
);
|
|
1498
|
+
if (typeof data.version !== "number" || data.version > GENERATION_RECORD_VERSION) {
|
|
1499
|
+
throw new ProvenanceParseError(`Unsupported generation record version ${JSON.stringify(data.version)}.`);
|
|
1417
1500
|
}
|
|
1418
|
-
const
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1501
|
+
const checks = [
|
|
1502
|
+
["id", typeof data.id === "string" && data.id !== ""],
|
|
1503
|
+
["templates", Array.isArray(data.templates) && data.templates.every((t) => isObject(t) && typeof t.name === "string" && typeof t.hash === "string")],
|
|
1504
|
+
["assets", Array.isArray(data.assets) && data.assets.every((a) => isObject(a) && typeof a.id === "string" && typeof a.role === "string")],
|
|
1505
|
+
["settings", isObject(data.settings)],
|
|
1506
|
+
["promptHash", typeof data.promptHash === "string"],
|
|
1507
|
+
["createdAt", typeof data.createdAt === "string"]
|
|
1508
|
+
];
|
|
1509
|
+
const bad = checks.find(([, ok]) => !ok);
|
|
1510
|
+
if (bad) throw new ProvenanceParseError(`Invalid generation record field "${bad[0]}".`);
|
|
1511
|
+
const provenance = parseProvenance(data.provenance);
|
|
1512
|
+
return {
|
|
1513
|
+
...data,
|
|
1514
|
+
kind: data.kind === "recreate" || data.kind === "variation" ? data.kind : "generate",
|
|
1515
|
+
strategy: ["nearest", "upgrade", "downgrade", "error"].includes(data.strategy) ? data.strategy : "nearest",
|
|
1516
|
+
provenance
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
function isGenerationRecord(value) {
|
|
1520
|
+
return isObject(value) && value.format === GENERATION_RECORD_FORMAT;
|
|
1521
|
+
}
|
|
1522
|
+
var SKIPPED_SETTING_FIELDS = /* @__PURE__ */ new Set(["model", "prompt", "references", "params", "seed"]);
|
|
1523
|
+
function findModel(capabilities, modelId) {
|
|
1524
|
+
if (!capabilities) return { given: false };
|
|
1525
|
+
const list2 = Array.isArray(capabilities) ? capabilities : [capabilities];
|
|
1526
|
+
return { given: true, caps: list2.find((m) => m.id === modelId) };
|
|
1527
|
+
}
|
|
1528
|
+
var sameValue = (a, b) => stableStringify(a) === stableStringify(b);
|
|
1529
|
+
var show = (value) => value === void 0 ? "unset" : typeof value === "string" ? `"${value}"` : JSON.stringify(value);
|
|
1530
|
+
var refKey = (ref) => `${ref.role}:${ref.id}`;
|
|
1531
|
+
function templateDrift(record, current, mode) {
|
|
1532
|
+
if (!current) return [];
|
|
1533
|
+
const byName = new Map(current.map((t) => [t.name, t]));
|
|
1534
|
+
const drift = [];
|
|
1535
|
+
for (const recorded of record.templates) {
|
|
1536
|
+
const template = byName.get(recorded.name);
|
|
1537
|
+
const fromVersion = _nullishCoalesce(recorded.version, () => ( recorded.versionId));
|
|
1538
|
+
if (!template) {
|
|
1539
|
+
drift.push({
|
|
1540
|
+
type: "template-missing",
|
|
1541
|
+
severity: "warning",
|
|
1542
|
+
template: recorded.name,
|
|
1543
|
+
from: fromVersion,
|
|
1544
|
+
applied: false,
|
|
1545
|
+
message: `Template "${recorded.name}" no longer exists; the recorded body is used.`
|
|
1442
1546
|
});
|
|
1547
|
+
continue;
|
|
1443
1548
|
}
|
|
1549
|
+
const body = _chunkFD4LPFAEcjs.getTemplateBody.call(void 0, template, {});
|
|
1550
|
+
const hash = body === void 0 ? void 0 : hashText(body);
|
|
1551
|
+
if (hash === recorded.hash) continue;
|
|
1552
|
+
const latest = _chunkFD4LPFAEcjs.getLatestVersion.call(void 0, template);
|
|
1553
|
+
const toVersion = _optionalChain([template, 'access', _92 => _92.versions, 'optionalAccess', _93 => _93.length]) ? _nullishCoalesce(_optionalChain([latest, 'optionalAccess', _94 => _94.version]), () => ( _optionalChain([latest, 'optionalAccess', _95 => _95.id]))) : void 0;
|
|
1554
|
+
const versions = fromVersion !== void 0 || toVersion !== void 0 ? ` (${_nullishCoalesce(fromVersion, () => ( "unversioned"))} \u2192 ${_nullishCoalesce(toVersion, () => ( "unversioned"))})` : "";
|
|
1555
|
+
drift.push({
|
|
1556
|
+
type: "template-changed",
|
|
1557
|
+
severity: mode === "latest" ? "info" : "warning",
|
|
1558
|
+
template: recorded.name,
|
|
1559
|
+
from: { version: fromVersion, hash: recorded.hash },
|
|
1560
|
+
to: { version: toVersion, hash },
|
|
1561
|
+
applied: mode === "latest",
|
|
1562
|
+
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.`
|
|
1563
|
+
});
|
|
1444
1564
|
}
|
|
1445
|
-
return
|
|
1446
|
-
}
|
|
1447
|
-
function getRequestValue(request, key) {
|
|
1448
|
-
if (key.startsWith("params.")) return _optionalChain([request, 'access', _100 => _100.params, 'optionalAccess', _101 => _101[key.slice(7)]]);
|
|
1449
|
-
return request[key];
|
|
1565
|
+
return drift;
|
|
1450
1566
|
}
|
|
1451
|
-
function
|
|
1452
|
-
const
|
|
1453
|
-
if (
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
return next2;
|
|
1567
|
+
function randomSeed(caps, previous, random) {
|
|
1568
|
+
const cap = caps ? seedCapability(caps.seed) : {};
|
|
1569
|
+
if (!cap) return void 0;
|
|
1570
|
+
const min = Math.ceil(_nullishCoalesce(cap.min, () => ( 0)));
|
|
1571
|
+
const max = Math.floor(_nullishCoalesce(cap.max, () => ( 2 ** 31 - 1)));
|
|
1572
|
+
if (max < min) return min;
|
|
1573
|
+
let seed = previous;
|
|
1574
|
+
for (let attempt = 0; attempt < 8 && (seed === void 0 || seed === previous); attempt++) {
|
|
1575
|
+
seed = min + Math.floor(random() * (max - min + 1));
|
|
1461
1576
|
}
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
else next[key] = value;
|
|
1465
|
-
return next;
|
|
1577
|
+
if (seed === previous && max > min) seed = previous === max ? min : previous + 1;
|
|
1578
|
+
return seed;
|
|
1466
1579
|
}
|
|
1467
|
-
function
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1580
|
+
function rebuild(record, options, kind, overrides) {
|
|
1581
|
+
const mode = _nullishCoalesce(options.mode, () => ( "exact"));
|
|
1582
|
+
const provenance = record.provenance;
|
|
1583
|
+
const drift = templateDrift(record, options.templates, mode);
|
|
1584
|
+
const rawPrompt = _nullishCoalesce(_optionalChain([overrides, 'optionalAccess', _96 => _96.rawPrompt]), () => ( provenance.rawPrompt));
|
|
1585
|
+
const values = _optionalChain([overrides, 'optionalAccess', _97 => _97.values]) !== void 0 ? { ..._nullishCoalesce(provenance.values, () => ( {})), ...overrides.values } : provenance.values ? clone2(provenance.values) : null;
|
|
1586
|
+
const pinned = pinnedTemplatesToTemplates(provenance.templates);
|
|
1587
|
+
let templates;
|
|
1588
|
+
let bindings;
|
|
1589
|
+
if (mode === "latest" && options.templates) {
|
|
1590
|
+
const currentNames = new Set(options.templates.map((t) => t.name));
|
|
1591
|
+
const fallback = pinned.filter((t) => !currentNames.has(t.name));
|
|
1592
|
+
templates = [...options.templates.map((t) => ({ ...t })), ...fallback];
|
|
1593
|
+
bindings = {};
|
|
1594
|
+
for (const t of fallback) {
|
|
1595
|
+
if (provenance.bindings[t.name] !== void 0) bindings[t.name] = provenance.bindings[t.name];
|
|
1596
|
+
}
|
|
1597
|
+
} else {
|
|
1598
|
+
templates = pinned;
|
|
1599
|
+
bindings = { ...provenance.bindings };
|
|
1473
1600
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
if (caps.inpainting && !roles.includes("mask")) roles.push("mask");
|
|
1479
|
-
const refs = _nullishCoalesce(request.references, () => ( []));
|
|
1480
|
-
const total = refs.length;
|
|
1481
|
-
const maxTotal = _nullishCoalesce(_optionalChain([caps, 'access', _102 => _102.references, 'optionalAccess', _103 => _103.maxTotal]), () => ( Infinity));
|
|
1482
|
-
return roles.map((role) => {
|
|
1483
|
-
const cap = _nullishCoalesce(_optionalChain([caps, 'access', _104 => _104.references, 'optionalAccess', _105 => _105.roles, 'access', _106 => _106[role]]), () => ( { max: 1 }));
|
|
1484
|
-
const references = refs.filter((ref) => ref.role === role);
|
|
1485
|
-
return {
|
|
1486
|
-
role,
|
|
1487
|
-
label: referenceRoleLabel(role, caps),
|
|
1488
|
-
...cap.description ? { description: cap.description } : {},
|
|
1489
|
-
..."accepts" in cap && _optionalChain([cap, 'access', _107 => _107.accepts, 'optionalAccess', _108 => _108.length]) ? { accepts: [...cap.accepts] } : {},
|
|
1490
|
-
min: _nullishCoalesce(cap.min, () => ( 0)),
|
|
1491
|
-
max: cap.max,
|
|
1492
|
-
references,
|
|
1493
|
-
canAdd: references.length < cap.max && total < maxTotal
|
|
1494
|
-
};
|
|
1495
|
-
});
|
|
1496
|
-
}
|
|
1497
|
-
function addReference(request, reference) {
|
|
1498
|
-
return { ...request, references: [..._nullishCoalesce(request.references, () => ( [])), { ...reference }] };
|
|
1499
|
-
}
|
|
1500
|
-
function removeReference(request, role, id) {
|
|
1501
|
-
const references = (_nullishCoalesce(request.references, () => ( []))).filter((ref) => !(ref.role === role && ref.id === id));
|
|
1502
|
-
const next = { ...request, references };
|
|
1503
|
-
if (references.length === 0) delete next.references;
|
|
1504
|
-
return next;
|
|
1505
|
-
}
|
|
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
|
-
};
|
|
1601
|
+
const resolved = _chunkFD4LPFAEcjs.resolvePrompt.call(void 0, rawPrompt, templates, { bindings, ...values ? { values } : {} });
|
|
1602
|
+
const sourceMap = resolved.map.map((segment) => {
|
|
1603
|
+
const { locked: _locked, ...rest } = segment;
|
|
1604
|
+
return rest;
|
|
1534
1605
|
});
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1606
|
+
if (resolved.text !== provenance.resolvedPrompt && !overrides) {
|
|
1607
|
+
drift.push({
|
|
1608
|
+
type: "prompt-changed",
|
|
1609
|
+
severity: "info",
|
|
1610
|
+
from: provenance.resolvedPrompt,
|
|
1611
|
+
to: resolved.text,
|
|
1612
|
+
applied: true,
|
|
1613
|
+
message: "The resolved prompt differs from the recorded one."
|
|
1614
|
+
});
|
|
1615
|
+
}
|
|
1616
|
+
const base = clone2(mode === "exact" ? provenance.request : record.settings);
|
|
1617
|
+
const recordedPlanned = provenance.request;
|
|
1618
|
+
if (base.prompt === void 0 || base.prompt === provenance.resolvedPrompt) base.prompt = resolved.text;
|
|
1619
|
+
else if (base.prompt === provenance.rawPrompt) base.prompt = rawPrompt;
|
|
1620
|
+
if (mode === "latest" && _optionalChain([record, 'access', _98 => _98.mentions, 'optionalAccess', _99 => _99.length])) {
|
|
1621
|
+
const plannedRole = new Map((_nullishCoalesce(recordedPlanned.references, () => ( []))).map((ref) => [ref.id, ref.role]));
|
|
1622
|
+
base.references = [
|
|
1623
|
+
..._nullishCoalesce(base.references, () => ( [])),
|
|
1624
|
+
...record.mentions.map((m) => ({
|
|
1625
|
+
id: m.id,
|
|
1626
|
+
role: m.role || plannedRole.get(m.id) || "image_ref",
|
|
1627
|
+
...m.url !== void 0 ? { url: m.url } : {},
|
|
1628
|
+
...m.mediaType !== void 0 ? { mediaType: m.mediaType } : {},
|
|
1629
|
+
...m.contentHash !== void 0 ? { contentHash: m.contentHash } : {}
|
|
1630
|
+
}))
|
|
1631
|
+
];
|
|
1632
|
+
} else if (mode === "latest" && base.references === void 0 && recordedPlanned.references) {
|
|
1633
|
+
base.references = clone2(recordedPlanned.references);
|
|
1634
|
+
}
|
|
1635
|
+
if (record.seed !== void 0) base.seed = record.seed;
|
|
1636
|
+
base.model = provenance.modelId;
|
|
1637
|
+
const { given, caps } = findModel(options.capabilities, provenance.modelId);
|
|
1638
|
+
if (overrides) {
|
|
1639
|
+
if (overrides.settings) {
|
|
1640
|
+
const { params, ...rest } = overrides.settings;
|
|
1641
|
+
Object.assign(base, clone2(rest));
|
|
1642
|
+
if (params) base.params = { ..._nullishCoalesce(base.params, () => ( {})), ...clone2(params) };
|
|
1546
1643
|
}
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
role = alias;
|
|
1561
|
-
} else {
|
|
1562
|
-
issues.push({
|
|
1563
|
-
index,
|
|
1564
|
-
id,
|
|
1565
|
-
role,
|
|
1566
|
-
code: "unsupported-role",
|
|
1644
|
+
if (overrides.seed === null) delete base.seed;
|
|
1645
|
+
else base.seed = _nullishCoalesce(overrides.seed, () => ( randomSeed(caps, record.seed, _nullishCoalesce(overrides.random, () => ( Math.random)))));
|
|
1646
|
+
if (base.seed === void 0) delete base.seed;
|
|
1647
|
+
}
|
|
1648
|
+
const resolveAsset = toAssetResolver(options.assets);
|
|
1649
|
+
if (resolveAsset && base.references) {
|
|
1650
|
+
const recordedById = new Map(record.assets.map((a) => [refKey(a), a]));
|
|
1651
|
+
const kept = [];
|
|
1652
|
+
for (const ref of base.references) {
|
|
1653
|
+
const info = resolveAsset(ref.id);
|
|
1654
|
+
if (!info) {
|
|
1655
|
+
drift.push({
|
|
1656
|
+
type: "asset-missing",
|
|
1567
1657
|
severity: "error",
|
|
1568
|
-
|
|
1658
|
+
assetId: ref.id,
|
|
1659
|
+
role: ref.role,
|
|
1660
|
+
message: `Asset "${ref.id}" (${ref.role}) is no longer available.`
|
|
1569
1661
|
});
|
|
1570
|
-
|
|
1662
|
+
continue;
|
|
1571
1663
|
}
|
|
1664
|
+
const recordedHash = _nullishCoalesce(_optionalChain([recordedById, 'access', _100 => _100.get, 'call', _101 => _101(refKey(ref)), 'optionalAccess', _102 => _102.contentHash]), () => ( ref.contentHash));
|
|
1665
|
+
if (recordedHash !== void 0 && info.contentHash !== void 0 && recordedHash !== info.contentHash) {
|
|
1666
|
+
drift.push({
|
|
1667
|
+
type: "asset-changed",
|
|
1668
|
+
severity: "warning",
|
|
1669
|
+
assetId: ref.id,
|
|
1670
|
+
role: ref.role,
|
|
1671
|
+
from: recordedHash,
|
|
1672
|
+
to: info.contentHash,
|
|
1673
|
+
applied: true,
|
|
1674
|
+
message: `Asset "${ref.id}" (${ref.role}) has changed since this generation.`
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
const next = { ...ref };
|
|
1678
|
+
if (info.contentHash !== void 0) next.contentHash = info.contentHash;
|
|
1679
|
+
if (next.mediaType === void 0 && info.mediaType !== void 0) next.mediaType = info.mediaType;
|
|
1680
|
+
kept.push(next);
|
|
1572
1681
|
}
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
if (
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
id,
|
|
1591
|
-
role,
|
|
1592
|
-
code: "too-many",
|
|
1682
|
+
if (kept.length) base.references = kept;
|
|
1683
|
+
else delete base.references;
|
|
1684
|
+
}
|
|
1685
|
+
let plan;
|
|
1686
|
+
let request = base;
|
|
1687
|
+
if (given && !caps) {
|
|
1688
|
+
drift.push({
|
|
1689
|
+
type: "model-missing",
|
|
1690
|
+
severity: "error",
|
|
1691
|
+
modelId: provenance.modelId,
|
|
1692
|
+
message: `Model "${provenance.modelId}" is no longer available.`
|
|
1693
|
+
});
|
|
1694
|
+
} else if (caps) {
|
|
1695
|
+
const capabilityHash = hashCapabilities(caps);
|
|
1696
|
+
if (record.capabilityHash !== void 0 && record.capabilityHash !== capabilityHash) {
|
|
1697
|
+
drift.push({
|
|
1698
|
+
type: "model-changed",
|
|
1593
1699
|
severity: "warning",
|
|
1594
|
-
|
|
1700
|
+
modelId: caps.id,
|
|
1701
|
+
from: record.capabilityHash,
|
|
1702
|
+
to: capabilityHash,
|
|
1703
|
+
message: `The capabilities of "${_nullishCoalesce(caps.name, () => ( caps.id))}" changed since this generation.`
|
|
1595
1704
|
});
|
|
1596
1705
|
}
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
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 } : {}
|
|
1706
|
+
plan = planGenerationRequest(base, caps, {
|
|
1707
|
+
strategy: _nullishCoalesce(options.strategy, () => ( record.strategy)),
|
|
1708
|
+
resolvedPrompt: resolved.text
|
|
1615
1709
|
});
|
|
1710
|
+
request = plan.request;
|
|
1711
|
+
const severity = mode === "exact" && !overrides ? "warning" : "info";
|
|
1712
|
+
const type = mode === "exact" && !overrides ? "setting-unsupported" : "setting-changed";
|
|
1713
|
+
const describeChange = (field, from, to) => {
|
|
1714
|
+
const adjustment = plan.adjustments.find((a) => a.field === field || a.field.startsWith(`${field}.`));
|
|
1715
|
+
drift.push({
|
|
1716
|
+
type,
|
|
1717
|
+
severity,
|
|
1718
|
+
field,
|
|
1719
|
+
from,
|
|
1720
|
+
to,
|
|
1721
|
+
applied: true,
|
|
1722
|
+
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}` : ""}`
|
|
1723
|
+
});
|
|
1724
|
+
};
|
|
1725
|
+
if (!overrides) {
|
|
1726
|
+
for (const field of GENERATION_REQUEST_FIELDS) {
|
|
1727
|
+
if (SKIPPED_SETTING_FIELDS.has(field)) continue;
|
|
1728
|
+
const from = recordedPlanned[field];
|
|
1729
|
+
const to = request[field];
|
|
1730
|
+
if (!sameValue(from, to)) describeChange(field, from, to);
|
|
1731
|
+
}
|
|
1732
|
+
const paramNames = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(recordedPlanned.params, () => ( {}))), ...Object.keys(_nullishCoalesce(request.params, () => ( {})))]);
|
|
1733
|
+
for (const name of [...paramNames].sort()) {
|
|
1734
|
+
const from = _optionalChain([recordedPlanned, 'access', _103 => _103.params, 'optionalAccess', _104 => _104[name]]);
|
|
1735
|
+
const to = _optionalChain([request, 'access', _105 => _105.params, 'optionalAccess', _106 => _106[name]]);
|
|
1736
|
+
if (!sameValue(from, to)) describeChange(`params.${name}`, from, to);
|
|
1737
|
+
}
|
|
1738
|
+
if (!sameValue(_nullishCoalesce(record.seed, () => ( recordedPlanned.seed)), request.seed)) describeChange("seed", _nullishCoalesce(record.seed, () => ( recordedPlanned.seed)), request.seed);
|
|
1739
|
+
const missing = new Set(drift.filter((d) => d.type === "asset-missing").map((d) => `${d.role}:${d.assetId}`));
|
|
1740
|
+
const fromRefs = (_nullishCoalesce(recordedPlanned.references, () => ( []))).map(refKey).filter((key) => !missing.has(key));
|
|
1741
|
+
const toRefs = (_nullishCoalesce(request.references, () => ( []))).map(refKey);
|
|
1742
|
+
if (!sameValue(fromRefs, toRefs)) describeChange("references", fromRefs, toRefs);
|
|
1743
|
+
}
|
|
1744
|
+
for (const error of plan.errors) {
|
|
1745
|
+
drift.push({
|
|
1746
|
+
type: "setting-unsupported",
|
|
1747
|
+
severity: "error",
|
|
1748
|
+
field: error.field,
|
|
1749
|
+
from: error.value,
|
|
1750
|
+
message: error.message
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1616
1753
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1754
|
+
const ok = !drift.some((d) => d.severity === "error") && (plan ? plan.ok : true);
|
|
1755
|
+
const recordOptions = {
|
|
1756
|
+
rawPrompt,
|
|
1757
|
+
templates,
|
|
1758
|
+
bindings,
|
|
1759
|
+
...values ? { values } : {},
|
|
1760
|
+
model: _nullishCoalesce(caps, () => ( provenance.modelId)),
|
|
1761
|
+
request,
|
|
1762
|
+
...plan ? { plan } : {},
|
|
1763
|
+
strategy: _nullishCoalesce(options.strategy, () => ( record.strategy)),
|
|
1764
|
+
parentId: record.id,
|
|
1765
|
+
kind
|
|
1766
|
+
};
|
|
1767
|
+
return {
|
|
1768
|
+
mode,
|
|
1769
|
+
ok,
|
|
1770
|
+
request,
|
|
1771
|
+
...plan ? { plan } : {},
|
|
1772
|
+
rawPrompt,
|
|
1773
|
+
resolvedPrompt: resolved.text,
|
|
1774
|
+
sourceMap,
|
|
1775
|
+
values,
|
|
1776
|
+
templates,
|
|
1777
|
+
bindings,
|
|
1778
|
+
drift,
|
|
1779
|
+
parentId: record.id,
|
|
1780
|
+
kind,
|
|
1781
|
+
recordOptions
|
|
1782
|
+
};
|
|
1783
|
+
}
|
|
1784
|
+
function recreateRequest(input, options) {
|
|
1785
|
+
if (isGenerationRecord(input)) return rebuild(input, _nullishCoalesce(options, () => ( {})), "recreate");
|
|
1786
|
+
const provenance = input;
|
|
1787
|
+
const request = clone2(provenance.request);
|
|
1788
|
+
request.model = provenance.modelId;
|
|
1789
|
+
if (request.prompt === void 0) request.prompt = provenance.resolvedPrompt;
|
|
1790
|
+
return request;
|
|
1791
|
+
}
|
|
1792
|
+
function variationRequest(record, overrides = {}, options = {}) {
|
|
1793
|
+
return rebuild(record, options, "variation", overrides);
|
|
1794
|
+
}
|
|
1795
|
+
var DRIFT_TYPE_LABELS = {
|
|
1796
|
+
"template-changed": "Template changed",
|
|
1797
|
+
"template-missing": "Template deleted",
|
|
1798
|
+
"prompt-changed": "Prompt changed",
|
|
1799
|
+
"model-missing": "Model unavailable",
|
|
1800
|
+
"model-changed": "Model changed",
|
|
1801
|
+
"setting-unsupported": "Setting unsupported",
|
|
1802
|
+
"setting-changed": "Setting changed",
|
|
1803
|
+
"asset-missing": "Asset missing",
|
|
1804
|
+
"asset-changed": "Asset changed"
|
|
1805
|
+
};
|
|
1806
|
+
function blockingDrift(drift) {
|
|
1807
|
+
return drift.filter((d) => d.severity === "error");
|
|
1652
1808
|
}
|
|
1653
1809
|
|
|
1654
|
-
// src/generation/
|
|
1655
|
-
var
|
|
1656
|
-
var
|
|
1657
|
-
var
|
|
1658
|
-
function
|
|
1659
|
-
const
|
|
1660
|
-
|
|
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}`;
|
|
1810
|
+
// src/generation/history-tools.ts
|
|
1811
|
+
var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
1812
|
+
var RECORD_ID = { type: "string", minLength: 1, description: "Generation record id from list_generations." };
|
|
1813
|
+
var read = (value) => typeof value === "function" ? value() : value;
|
|
1814
|
+
function forGenerate(request) {
|
|
1815
|
+
const { model, ...rest } = request;
|
|
1816
|
+
return { model, request: rest };
|
|
1664
1817
|
}
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1818
|
+
function rebuiltResult(result) {
|
|
1819
|
+
return {
|
|
1820
|
+
ok: result.ok,
|
|
1821
|
+
parentId: result.parentId,
|
|
1822
|
+
kind: result.kind,
|
|
1823
|
+
mode: result.mode,
|
|
1824
|
+
...forGenerate(result.request),
|
|
1825
|
+
resolvedPrompt: result.resolvedPrompt,
|
|
1826
|
+
drift: result.drift.map(({ type, severity, message, field, template, assetId }) => ({
|
|
1827
|
+
type,
|
|
1828
|
+
severity,
|
|
1829
|
+
message,
|
|
1830
|
+
...field !== void 0 ? { field } : {},
|
|
1831
|
+
...template !== void 0 ? { template } : {},
|
|
1832
|
+
...assetId !== void 0 ? { assetId } : {}
|
|
1833
|
+
})),
|
|
1834
|
+
...result.plan ? { planErrors: result.plan.errors } : {}
|
|
1835
|
+
};
|
|
1673
1836
|
}
|
|
1674
|
-
function
|
|
1675
|
-
const
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
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
|
-
};
|
|
1837
|
+
function createGenerationHistoryToolProvider(options) {
|
|
1838
|
+
const { store } = options;
|
|
1839
|
+
const recreateOptions = () => ({
|
|
1840
|
+
capabilities: read(options.models),
|
|
1841
|
+
templates: read(options.templates),
|
|
1842
|
+
assets: options.assets
|
|
1688
1843
|
});
|
|
1844
|
+
const recordOrThrow = async (id) => {
|
|
1845
|
+
const record = await store.get(id);
|
|
1846
|
+
if (!record) throw new Error(`Unknown generation "${id}". Call list_generations for record ids.`);
|
|
1847
|
+
return record;
|
|
1848
|
+
};
|
|
1849
|
+
const listGenerations = {
|
|
1850
|
+
name: "list_generations",
|
|
1851
|
+
title: "List past generations",
|
|
1852
|
+
description: "Lists recorded generations newest first: id, model, kind (generate, recreate, variation), parent id, time, templates, assets and the first 160 characters of the resolved prompt. Filter to find one to inspect, recreate or vary.",
|
|
1853
|
+
inputSchema: {
|
|
1854
|
+
type: "object",
|
|
1855
|
+
properties: {
|
|
1856
|
+
model: { type: "string", description: "Only this model id." },
|
|
1857
|
+
template: { type: "string", description: "Only records that used this template name or id." },
|
|
1858
|
+
text: { type: "string", description: "Case-insensitive text in the prompt preview." },
|
|
1859
|
+
kind: { type: "string", enum: ["generate", "recreate", "variation"], description: "Only this kind of record." },
|
|
1860
|
+
parentId: { type: "string", description: "Only records recreated or varied from this record." },
|
|
1861
|
+
limit: { type: "integer", minimum: 1, maximum: 100, description: "Most records to return (default 20)." },
|
|
1862
|
+
offset: { type: "integer", minimum: 0, description: "Records to skip, for paging (default 0)." }
|
|
1863
|
+
},
|
|
1864
|
+
additionalProperties: false
|
|
1865
|
+
},
|
|
1866
|
+
annotations: { title: "List past generations", ...READ },
|
|
1867
|
+
handler: async ({ limit = 20, offset = 0, ...filter }) => {
|
|
1868
|
+
const all = await store.summaries(filter);
|
|
1869
|
+
return { total: all.length, records: all.slice(offset, offset + limit) };
|
|
1870
|
+
}
|
|
1871
|
+
};
|
|
1872
|
+
const getGeneration = {
|
|
1873
|
+
name: "get_generation",
|
|
1874
|
+
title: "Read a past generation",
|
|
1875
|
+
description: "Returns one generation record: model, raw and resolved prompt, the settings as the user set them, the strategy, the seed used, the assets and templates it used, its parent and when it ran.",
|
|
1876
|
+
inputSchema: { type: "object", properties: { id: RECORD_ID }, required: ["id"], additionalProperties: false },
|
|
1877
|
+
annotations: { title: "Read a past generation", ...READ },
|
|
1878
|
+
handler: async ({ id }) => {
|
|
1879
|
+
const r = await recordOrThrow(id);
|
|
1880
|
+
return {
|
|
1881
|
+
id: r.id,
|
|
1882
|
+
kind: r.kind,
|
|
1883
|
+
...r.parentId !== void 0 ? { parentId: r.parentId } : {},
|
|
1884
|
+
createdAt: r.createdAt,
|
|
1885
|
+
model: r.provenance.modelId,
|
|
1886
|
+
rawPrompt: r.provenance.rawPrompt,
|
|
1887
|
+
resolvedPrompt: r.provenance.resolvedPrompt,
|
|
1888
|
+
settings: r.settings,
|
|
1889
|
+
strategy: r.strategy,
|
|
1890
|
+
...r.seed !== void 0 ? { seed: r.seed } : {},
|
|
1891
|
+
assets: r.assets,
|
|
1892
|
+
templates: r.templates.map(({ name, templateId, version }) => ({ name, templateId, version }))
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
};
|
|
1896
|
+
const recreate = {
|
|
1897
|
+
name: "recreate_generation",
|
|
1898
|
+
title: "Rebuild a past generation",
|
|
1899
|
+
description: "Builds the request that reproduces a recorded generation, without running it. Returns `model` and `request` to pass to generate, `ok` (false when something blocks an exact reproduction), and drift: templates edited or deleted, the model changed or gone, settings no longer supported, assets missing or changed. Report drift to the user before generating.",
|
|
1900
|
+
inputSchema: {
|
|
1901
|
+
type: "object",
|
|
1902
|
+
properties: {
|
|
1903
|
+
id: RECORD_ID,
|
|
1904
|
+
mode: {
|
|
1905
|
+
type: "string",
|
|
1906
|
+
enum: ["exact", "latest"],
|
|
1907
|
+
description: "exact (default) reproduces the recorded prompt and settings; latest uses the current templates and re-plans the settings for the current model."
|
|
1908
|
+
}
|
|
1909
|
+
},
|
|
1910
|
+
required: ["id"],
|
|
1911
|
+
additionalProperties: false
|
|
1912
|
+
},
|
|
1913
|
+
annotations: { title: "Rebuild a past generation", ...READ },
|
|
1914
|
+
handler: async ({ id, mode }) => rebuiltResult(recreateRequest(await recordOrThrow(id), { ...recreateOptions(), mode }))
|
|
1915
|
+
};
|
|
1916
|
+
const vary = {
|
|
1917
|
+
name: "vary_generation",
|
|
1918
|
+
title: "Build a variation of a past generation",
|
|
1919
|
+
description: "Builds a request for a variation of a recorded generation, without running it: the same prompt, settings and assets with a new seed (random unless given) and any changes. Returns `model` and `request` to pass to generate, plus drift.",
|
|
1920
|
+
inputSchema: {
|
|
1921
|
+
type: "object",
|
|
1922
|
+
properties: {
|
|
1923
|
+
id: RECORD_ID,
|
|
1924
|
+
seed: { type: ["integer", "null"], description: "Seed to use; null for none. Default: a random seed different from the record's." },
|
|
1925
|
+
values: {
|
|
1926
|
+
type: "object",
|
|
1927
|
+
additionalProperties: { type: "string" },
|
|
1928
|
+
description: 'Prompt variable values merged over the recorded ones, e.g. {"subject": "a red fox"}.'
|
|
1929
|
+
},
|
|
1930
|
+
settings: {
|
|
1931
|
+
type: "object",
|
|
1932
|
+
description: `Request settings merged over the recorded ones, e.g. {"aspectRatio": "16:9"} (params are merged too). See list_models for each model's fields.`
|
|
1933
|
+
},
|
|
1934
|
+
rawPrompt: { type: "string", description: "A different raw prompt (templates and variables are resolved as usual)." }
|
|
1935
|
+
},
|
|
1936
|
+
required: ["id"],
|
|
1937
|
+
additionalProperties: false
|
|
1938
|
+
},
|
|
1939
|
+
annotations: { title: "Build a variation of a past generation", readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
1940
|
+
handler: async ({ id, seed, values, settings, rawPrompt }) => rebuiltResult(variationRequest(await recordOrThrow(id), { seed, values, settings, rawPrompt }, recreateOptions()))
|
|
1941
|
+
};
|
|
1942
|
+
return {
|
|
1943
|
+
id: _nullishCoalesce(options.id, () => ( "generation-history")),
|
|
1944
|
+
namespace: options.namespace,
|
|
1945
|
+
tools: [listGenerations, getGeneration, recreate, vary],
|
|
1946
|
+
subscribe: (notify) => store.subscribe(notify)
|
|
1947
|
+
};
|
|
1689
1948
|
}
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1949
|
+
|
|
1950
|
+
// src/generation/batch.ts
|
|
1951
|
+
function createBatchResolver(options) {
|
|
1952
|
+
const maxBatch = Math.max(1, Math.floor(_nullishCoalesce(options.maxBatch, () => ( 50))));
|
|
1953
|
+
const delayMs = Math.max(0, _nullishCoalesce(options.delayMs, () => ( 0)));
|
|
1954
|
+
const settled = /* @__PURE__ */ new Map();
|
|
1955
|
+
const failures = /* @__PURE__ */ new Set();
|
|
1956
|
+
const inFlight = /* @__PURE__ */ new Map();
|
|
1957
|
+
let queue = [];
|
|
1958
|
+
let timer = null;
|
|
1959
|
+
const run = (keys) => {
|
|
1960
|
+
const pendings = keys.map((key) => inFlight.get(key));
|
|
1961
|
+
const finish = (values, error) => {
|
|
1962
|
+
if (values === null) _optionalChain([options, 'access', _107 => _107.onError, 'optionalCall', _108 => _108(error, keys)]);
|
|
1963
|
+
keys.forEach((key, index) => {
|
|
1964
|
+
const pending = pendings[index];
|
|
1965
|
+
const value = _optionalChain([values, 'optionalAccess', _109 => _109.get, 'call', _110 => _110(key)]);
|
|
1966
|
+
if (pending && inFlight.get(key) === pending) {
|
|
1967
|
+
inFlight.delete(key);
|
|
1968
|
+
settled.set(key, value);
|
|
1969
|
+
if (values === null) failures.add(key);
|
|
1970
|
+
}
|
|
1971
|
+
_optionalChain([pending, 'optionalAccess', _111 => _111.resolve, 'call', _112 => _112(value)]);
|
|
1972
|
+
});
|
|
1973
|
+
};
|
|
1974
|
+
let promise;
|
|
1975
|
+
try {
|
|
1976
|
+
promise = Promise.resolve(options.fetch(keys));
|
|
1977
|
+
} catch (error) {
|
|
1978
|
+
promise = Promise.reject(error);
|
|
1979
|
+
}
|
|
1980
|
+
promise.then(
|
|
1981
|
+
(values) => finish(values instanceof Map ? values : /* @__PURE__ */ new Map()),
|
|
1982
|
+
(error) => finish(null, _nullishCoalesce(error, () => ( new Error("Batch fetch failed."))))
|
|
1983
|
+
);
|
|
1984
|
+
};
|
|
1985
|
+
const flush = () => {
|
|
1986
|
+
if (timer !== null) clearTimeout(timer);
|
|
1987
|
+
timer = null;
|
|
1988
|
+
const keys = queue;
|
|
1989
|
+
queue = [];
|
|
1990
|
+
for (let i = 0; i < keys.length; i += maxBatch) run(keys.slice(i, i + maxBatch));
|
|
1991
|
+
};
|
|
1992
|
+
const load = (key) => {
|
|
1993
|
+
if (settled.has(key)) return Promise.resolve(settled.get(key));
|
|
1994
|
+
const existing = inFlight.get(key);
|
|
1995
|
+
if (existing) return existing.promise;
|
|
1996
|
+
let resolve;
|
|
1997
|
+
const promise = new Promise((r) => resolve = r);
|
|
1998
|
+
inFlight.set(key, { promise, resolve });
|
|
1999
|
+
queue.push(key);
|
|
2000
|
+
if (queue.length >= maxBatch) flush();
|
|
2001
|
+
else if (timer === null) timer = setTimeout(flush, delayMs);
|
|
2002
|
+
return promise;
|
|
2003
|
+
};
|
|
1725
2004
|
return {
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
2005
|
+
load,
|
|
2006
|
+
loadMany: (keys) => Promise.all(keys.map(load)),
|
|
2007
|
+
peek: (key) => settled.get(key),
|
|
2008
|
+
has: (key) => settled.has(key),
|
|
2009
|
+
failed: (key) => failures.has(key),
|
|
2010
|
+
prime(key, value) {
|
|
2011
|
+
settled.set(key, value);
|
|
2012
|
+
failures.delete(key);
|
|
2013
|
+
},
|
|
2014
|
+
clear(key) {
|
|
2015
|
+
if (key === void 0) {
|
|
2016
|
+
settled.clear();
|
|
2017
|
+
failures.clear();
|
|
2018
|
+
for (const k of [...inFlight.keys()]) if (!queue.includes(k)) inFlight.delete(k);
|
|
2019
|
+
return;
|
|
2020
|
+
}
|
|
2021
|
+
settled.delete(key);
|
|
2022
|
+
failures.delete(key);
|
|
2023
|
+
if (!queue.includes(key)) inFlight.delete(key);
|
|
2024
|
+
},
|
|
2025
|
+
flush
|
|
1741
2026
|
};
|
|
1742
2027
|
}
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
return
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
2028
|
+
|
|
2029
|
+
// src/generation/progress.ts
|
|
2030
|
+
var MAX_PENDING_PERCENT = 95;
|
|
2031
|
+
var ALMOST_DONE_MS = 5e3;
|
|
2032
|
+
var UNKNOWN_DURATION_TAU_MS = 3e4;
|
|
2033
|
+
var toMs = (value) => typeof value === "number" ? value : new Date(value).getTime();
|
|
2034
|
+
function formatRemaining(ms) {
|
|
2035
|
+
const seconds = Math.ceil(ms / 1e3);
|
|
2036
|
+
if (seconds < 60) return `~${Math.max(1, seconds)}s left`;
|
|
2037
|
+
const minutes = Math.ceil(ms / 6e4);
|
|
2038
|
+
if (minutes < 60) return `~${minutes}m left`;
|
|
2039
|
+
const hours = Math.floor(minutes / 60);
|
|
2040
|
+
const rest = minutes % 60;
|
|
2041
|
+
return rest ? `~${hours}h ${rest}m left` : `~${hours}h left`;
|
|
1755
2042
|
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
}
|
|
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.");
|
|
2043
|
+
function estimateJobProgress(input) {
|
|
2044
|
+
const started = toMs(input.startedAt);
|
|
2045
|
+
const now = toMs(_nullishCoalesce(input.now, () => ( Date.now())));
|
|
2046
|
+
const elapsedMs = Math.max(0, now - started);
|
|
2047
|
+
if (input.done) return { percent: 100, label: "Done", elapsedMs, remainingMs: 0, overdue: false };
|
|
2048
|
+
if (!Number.isFinite(started) || now <= started) {
|
|
2049
|
+
return { percent: 0, label: "Starting\u2026", elapsedMs: 0, ...input.expectedMs ? { remainingMs: input.expectedMs } : {}, overdue: false };
|
|
1768
2050
|
}
|
|
1769
|
-
|
|
1770
|
-
|
|
2051
|
+
const expected = input.expectedMs;
|
|
2052
|
+
if (!expected || !(expected > 0)) {
|
|
2053
|
+
const percent2 = MAX_PENDING_PERCENT * (1 - Math.exp(-elapsedMs / UNKNOWN_DURATION_TAU_MS));
|
|
2054
|
+
return { percent: Math.floor(percent2), label: "Working\u2026", elapsedMs, overdue: false };
|
|
1771
2055
|
}
|
|
1772
|
-
const
|
|
1773
|
-
|
|
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);
|
|
2056
|
+
const remainingMs = Math.max(0, expected - elapsedMs);
|
|
2057
|
+
const percent = Math.min(MAX_PENDING_PERCENT, Math.floor(elapsedMs / expected * 100));
|
|
1783
2058
|
return {
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
2059
|
+
percent,
|
|
2060
|
+
label: remainingMs <= ALMOST_DONE_MS ? "Almost done\u2026" : formatRemaining(remainingMs),
|
|
2061
|
+
elapsedMs,
|
|
2062
|
+
remainingMs,
|
|
2063
|
+
overdue: elapsedMs > expected
|
|
1788
2064
|
};
|
|
1789
2065
|
}
|
|
1790
|
-
function
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
const
|
|
1797
|
-
return
|
|
1798
|
-
|
|
1799
|
-
|
|
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;
|
|
2066
|
+
function expectedDurationFor(caps, request = {}) {
|
|
2067
|
+
const timing = caps.timing;
|
|
2068
|
+
if (!timing) return void 0;
|
|
2069
|
+
const count = _nullishCoalesce(_nullishCoalesce(request.count, () => ( _optionalChain([caps, 'access', _113 => _113.count, 'optionalAccess', _114 => _114.default]))), () => ( 1));
|
|
2070
|
+
const duration = _nullishCoalesce(_nullishCoalesce(request.duration, () => ( _optionalChain([caps, 'access', _115 => _115.duration, 'optionalAccess', _116 => _116.default]))), () => ( 0));
|
|
2071
|
+
const resolution = _nullishCoalesce(request.resolution, () => ( _optionalChain([caps, 'access', _117 => _117.resolutions, 'optionalAccess', _118 => _118.default])));
|
|
2072
|
+
const megapixels = resolution ? _nullishCoalesce(resolutionMegapixels(resolution), () => ( 0)) : 0;
|
|
2073
|
+
return Math.round(
|
|
2074
|
+
timing.baseMs + (_nullishCoalesce(timing.perItemMs, () => ( 0))) * Math.max(0, count - 1) + (_nullishCoalesce(timing.perSecondMs, () => ( 0))) * duration + (_nullishCoalesce(timing.perMegapixelMs, () => ( 0))) * megapixels
|
|
2075
|
+
);
|
|
1837
2076
|
}
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
2077
|
+
|
|
2078
|
+
// src/generation/controls.ts
|
|
2079
|
+
function enumControl(key, label, cap) {
|
|
2080
|
+
if (!_optionalChain([cap, 'optionalAccess', _119 => _119.options, 'access', _120 => _120.length])) return null;
|
|
2081
|
+
return {
|
|
2082
|
+
key,
|
|
2083
|
+
label,
|
|
2084
|
+
kind: "select",
|
|
2085
|
+
valueType: "string",
|
|
2086
|
+
options: cap.options.map((value) => ({ value, label: _nullishCoalesce(_optionalChain([cap, 'access', _121 => _121.labels, 'optionalAccess', _122 => _122[value]]), () => ( value)) })),
|
|
2087
|
+
...cap.default !== void 0 ? { defaultValue: cap.default } : {}
|
|
2088
|
+
};
|
|
1850
2089
|
}
|
|
1851
|
-
function
|
|
1852
|
-
const
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
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;
|
|
2090
|
+
function getGenerationControls(caps) {
|
|
2091
|
+
const controls = [];
|
|
2092
|
+
const modes = supportedModes(caps);
|
|
2093
|
+
if (modes.length > 1) {
|
|
2094
|
+
controls.push({
|
|
2095
|
+
key: "mode",
|
|
2096
|
+
label: "Mode",
|
|
2097
|
+
kind: "select",
|
|
2098
|
+
valueType: "string",
|
|
2099
|
+
options: modes.map((m) => ({ value: m, label: m[0].toUpperCase() + m.slice(1) })),
|
|
2100
|
+
defaultValue: "generate"
|
|
2101
|
+
});
|
|
1918
2102
|
}
|
|
1919
|
-
const
|
|
1920
|
-
if (
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
message: `Asset "${ref.id}" (${ref.role}) has changed since this generation.`
|
|
1946
|
-
});
|
|
2103
|
+
const negative = textFieldCapability(caps.negativePrompt);
|
|
2104
|
+
if (negative) controls.push({ key: "negativePrompt", label: "Negative prompt", kind: "textarea", valueType: "string", maxLength: negative.maxLength });
|
|
2105
|
+
const system = textFieldCapability(caps.systemPrompt);
|
|
2106
|
+
if (system) controls.push({ key: "systemPrompt", label: "System prompt", kind: "textarea", valueType: "string", maxLength: system.maxLength });
|
|
2107
|
+
controls.push(enumControl("aspectRatio", "Aspect ratio", caps.aspectRatios));
|
|
2108
|
+
controls.push(enumControl("resolution", "Resolution", caps.resolutions));
|
|
2109
|
+
controls.push(enumControl("quality", "Quality", caps.quality));
|
|
2110
|
+
if (caps.count) {
|
|
2111
|
+
const options = _optionalChain([caps, 'access', _123 => _123.count, 'access', _124 => _124.options, 'optionalAccess', _125 => _125.filter, 'call', _126 => _126((o) => o >= 1 && o <= caps.count.max)]);
|
|
2112
|
+
controls.push(
|
|
2113
|
+
_optionalChain([options, 'optionalAccess', _127 => _127.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)) }
|
|
2114
|
+
);
|
|
2115
|
+
}
|
|
2116
|
+
if (caps.duration) {
|
|
2117
|
+
const d = caps.duration;
|
|
2118
|
+
const options = _optionalChain([d, 'access', _128 => _128.options, 'optionalAccess', _129 => _129.filter, 'call', _130 => _130((o) => (d.min === void 0 || o >= d.min) && (d.max === void 0 || o <= d.max))]);
|
|
2119
|
+
controls.push(
|
|
2120
|
+
_optionalChain([options, 'optionalAccess', _131 => _131.length]) ? { key: "duration", label: "Duration (s)", kind: "select", valueType: "number", options: options.map((o) => ({ value: o, label: `${o}s` })), defaultValue: d.default } : {
|
|
2121
|
+
key: "duration",
|
|
2122
|
+
label: "Duration (s)",
|
|
2123
|
+
kind: d.min !== void 0 && d.max !== void 0 ? "range" : "number",
|
|
2124
|
+
valueType: "number",
|
|
2125
|
+
min: d.min,
|
|
2126
|
+
max: d.max,
|
|
2127
|
+
step: d.step,
|
|
2128
|
+
defaultValue: d.default
|
|
1947
2129
|
}
|
|
1948
|
-
|
|
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;
|
|
2130
|
+
);
|
|
1955
2131
|
}
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
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}` : ""}`
|
|
2132
|
+
const seed = seedCapability(caps.seed);
|
|
2133
|
+
if (seed) controls.push({ key: "seed", label: "Seed", kind: "number", valueType: "number", min: seed.min, max: seed.max, step: 1 });
|
|
2134
|
+
for (const [name, spec] of Object.entries(_nullishCoalesce(caps.params, () => ( {})))) {
|
|
2135
|
+
const base = { key: `params.${name}`, label: _nullishCoalesce(spec.label, () => ( name)), ...spec.description ? { description: spec.description } : {} };
|
|
2136
|
+
if (spec.type === "boolean") {
|
|
2137
|
+
controls.push({ ...base, kind: "checkbox", valueType: "boolean", defaultValue: spec.default });
|
|
2138
|
+
} else if (spec.type === "enum") {
|
|
2139
|
+
const numeric = spec.options.every((o) => typeof o === "number");
|
|
2140
|
+
controls.push({
|
|
2141
|
+
...base,
|
|
2142
|
+
kind: "select",
|
|
2143
|
+
valueType: numeric ? "number" : "string",
|
|
2144
|
+
options: spec.options.map((value) => ({ value, label: String(value) })),
|
|
2145
|
+
defaultValue: spec.default
|
|
1994
2146
|
});
|
|
1995
|
-
}
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
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
|
|
2147
|
+
} else {
|
|
2148
|
+
controls.push({
|
|
2149
|
+
...base,
|
|
2150
|
+
kind: spec.min !== void 0 && spec.max !== void 0 ? "range" : "number",
|
|
2151
|
+
valueType: "number",
|
|
2152
|
+
min: spec.min,
|
|
2153
|
+
max: spec.max,
|
|
2154
|
+
step: _nullishCoalesce(spec.step, () => ( (spec.type === "integer" ? 1 : void 0))),
|
|
2155
|
+
defaultValue: spec.default
|
|
2022
2156
|
});
|
|
2023
2157
|
}
|
|
2024
2158
|
}
|
|
2025
|
-
|
|
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
|
-
};
|
|
2159
|
+
return controls.filter((c) => c !== null);
|
|
2054
2160
|
}
|
|
2055
|
-
function
|
|
2056
|
-
if (
|
|
2057
|
-
|
|
2058
|
-
const request = clone2(provenance.request);
|
|
2059
|
-
request.model = provenance.modelId;
|
|
2060
|
-
if (request.prompt === void 0) request.prompt = provenance.resolvedPrompt;
|
|
2061
|
-
return request;
|
|
2161
|
+
function getRequestValue(request, key) {
|
|
2162
|
+
if (key.startsWith("params.")) return _optionalChain([request, 'access', _132 => _132.params, 'optionalAccess', _133 => _133[key.slice(7)]]);
|
|
2163
|
+
return request[key];
|
|
2062
2164
|
}
|
|
2063
|
-
function
|
|
2064
|
-
|
|
2165
|
+
function setRequestValue(request, key, value) {
|
|
2166
|
+
const remove = value === void 0 || value === "" || typeof value === "number" && Number.isNaN(value);
|
|
2167
|
+
if (key.startsWith("params.")) {
|
|
2168
|
+
const name = key.slice(7);
|
|
2169
|
+
const params = { ..._nullishCoalesce(request.params, () => ( {})) };
|
|
2170
|
+
if (remove) delete params[name];
|
|
2171
|
+
else params[name] = value;
|
|
2172
|
+
const next2 = { ...request, params };
|
|
2173
|
+
if (Object.keys(params).length === 0) delete next2.params;
|
|
2174
|
+
return next2;
|
|
2175
|
+
}
|
|
2176
|
+
const next = { ...request };
|
|
2177
|
+
if (remove) delete next[key];
|
|
2178
|
+
else next[key] = value;
|
|
2179
|
+
return next;
|
|
2065
2180
|
}
|
|
2066
|
-
|
|
2067
|
-
"
|
|
2068
|
-
"
|
|
2069
|
-
"
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2181
|
+
function parseControlValue(control, raw) {
|
|
2182
|
+
if (control.valueType === "boolean") return Boolean(raw);
|
|
2183
|
+
if (raw === "" || raw === void 0) return void 0;
|
|
2184
|
+
if (control.valueType === "number") {
|
|
2185
|
+
const n = Number(raw);
|
|
2186
|
+
return Number.isFinite(n) ? n : void 0;
|
|
2187
|
+
}
|
|
2188
|
+
return String(raw);
|
|
2189
|
+
}
|
|
2190
|
+
function getReferenceSlots(caps, request = {}) {
|
|
2191
|
+
const roles = supportedReferenceRoles(caps);
|
|
2192
|
+
if (caps.inpainting && !roles.includes("mask")) roles.push("mask");
|
|
2193
|
+
const refs = _nullishCoalesce(request.references, () => ( []));
|
|
2194
|
+
const total = refs.length;
|
|
2195
|
+
const maxTotal = _nullishCoalesce(_optionalChain([caps, 'access', _134 => _134.references, 'optionalAccess', _135 => _135.maxTotal]), () => ( Infinity));
|
|
2196
|
+
return roles.map((role) => {
|
|
2197
|
+
const cap = _nullishCoalesce(_optionalChain([caps, 'access', _136 => _136.references, 'optionalAccess', _137 => _137.roles, 'access', _138 => _138[role]]), () => ( { max: 1 }));
|
|
2198
|
+
const references = refs.filter((ref) => ref.role === role);
|
|
2199
|
+
return {
|
|
2200
|
+
role,
|
|
2201
|
+
label: referenceRoleLabel(role, caps),
|
|
2202
|
+
...cap.description ? { description: cap.description } : {},
|
|
2203
|
+
..."accepts" in cap && _optionalChain([cap, 'access', _139 => _139.accepts, 'optionalAccess', _140 => _140.length]) ? { accepts: [...cap.accepts] } : {},
|
|
2204
|
+
min: _nullishCoalesce(cap.min, () => ( 0)),
|
|
2205
|
+
max: cap.max,
|
|
2206
|
+
references,
|
|
2207
|
+
canAdd: references.length < cap.max && total < maxTotal
|
|
2208
|
+
};
|
|
2209
|
+
});
|
|
2210
|
+
}
|
|
2211
|
+
function addReference(request, reference) {
|
|
2212
|
+
return { ...request, references: [..._nullishCoalesce(request.references, () => ( [])), { ...reference }] };
|
|
2213
|
+
}
|
|
2214
|
+
function removeReference(request, role, id) {
|
|
2215
|
+
const references = (_nullishCoalesce(request.references, () => ( []))).filter((ref) => !(ref.role === role && ref.id === id));
|
|
2216
|
+
const next = { ...request, references };
|
|
2217
|
+
if (references.length === 0) delete next.references;
|
|
2218
|
+
return next;
|
|
2079
2219
|
}
|
|
2080
2220
|
|
|
2081
2221
|
// src/generation/store.ts
|
|
@@ -2313,5 +2453,6 @@ function createGenerationRecordStore(options) {
|
|
|
2313
2453
|
|
|
2314
2454
|
|
|
2315
2455
|
|
|
2316
|
-
|
|
2456
|
+
|
|
2457
|
+
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.createGenerationHistoryToolProvider = createGenerationHistoryToolProvider; 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 = _chunkRIWPYSKUcjs.validateJsonSchema; exports.variationRequest = variationRequest;
|
|
2317
2458
|
//# sourceMappingURL=index.cjs.map
|