@dudousxd/nestjs-agent-core 0.40.0 → 0.42.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 +7 -0
- package/dist/ag-ui/index.cjs +46 -10
- package/dist/ag-ui/index.cjs.map +1 -1
- package/dist/ag-ui/index.d.cts +9 -3
- package/dist/ag-ui/index.d.ts +9 -3
- package/dist/ag-ui/index.js +46 -10
- package/dist/ag-ui/index.js.map +1 -1
- package/dist/{catalog-CrzetM3_.d.cts → catalog-BKS3Yxo6.d.cts} +2 -0
- package/dist/{catalog-CrzetM3_.d.ts → catalog-BKS3Yxo6.d.ts} +2 -0
- package/dist/genui/builtins.cjs.map +1 -1
- package/dist/genui/builtins.d.cts +1 -1
- package/dist/genui/builtins.d.ts +1 -1
- package/dist/genui/builtins.js.map +1 -1
- package/dist/genui/index.cjs +660 -68
- package/dist/genui/index.cjs.map +1 -1
- package/dist/genui/index.d.cts +5 -5
- package/dist/genui/index.d.ts +5 -5
- package/dist/genui/index.js +654 -68
- package/dist/genui/index.js.map +1 -1
- package/dist/guardrails/index.cjs +3 -1
- package/dist/guardrails/index.cjs.map +1 -1
- package/dist/guardrails/index.d.cts +5 -4
- package/dist/guardrails/index.d.ts +5 -4
- package/dist/guardrails/index.js +3 -1
- package/dist/guardrails/index.js.map +1 -1
- package/dist/index.cjs +1164 -421
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +124 -13
- package/dist/index.d.ts +124 -13
- package/dist/index.js +1156 -421
- package/dist/index.js.map +1 -1
- package/dist/{processors-BR3nICcp.d.ts → processors-BKILjME5.d.ts} +1 -1
- package/dist/{processors-B7nfbU6E.d.cts → processors-DpHBqRuE.d.cts} +1 -1
- package/dist/{stream-events-M0jc7lSW.d.cts → stream-events-C-pj3bVY.d.cts} +92 -4
- package/dist/{stream-events-DAmes2Of.d.ts → stream-events-D92SgfRk.d.ts} +92 -4
- package/package.json +1 -1
package/dist/genui/index.cjs
CHANGED
|
@@ -27,7 +27,10 @@ __export(genui_exports, {
|
|
|
27
27
|
ajvValidator: () => ajvValidator,
|
|
28
28
|
builtinJsonSchemaValidator: () => builtinJsonSchemaValidator,
|
|
29
29
|
catalogToModelText: () => catalogToModelText,
|
|
30
|
+
chart: () => chart,
|
|
30
31
|
componentToText: () => componentToText,
|
|
32
|
+
createComponent: () => createComponent,
|
|
33
|
+
createComponentRegistry: () => createComponentRegistry,
|
|
31
34
|
defineCatalog: () => defineCatalog,
|
|
32
35
|
defineComponent: () => defineComponent,
|
|
33
36
|
fillTemplate: () => fillTemplate,
|
|
@@ -39,13 +42,16 @@ __export(genui_exports, {
|
|
|
39
42
|
negotiateCatalog: () => negotiateCatalog,
|
|
40
43
|
prepareUiEmission: () => prepareUiEmission,
|
|
41
44
|
showToolJsonSchema: () => showToolJsonSchema,
|
|
45
|
+
snapshotComponentPresentation: () => snapshotComponentPresentation,
|
|
42
46
|
summarizeSchema: () => summarizeSchema,
|
|
47
|
+
table: () => table,
|
|
43
48
|
toJsonSchema: () => toJsonSchema,
|
|
44
49
|
toSnakeCase: () => toSnakeCase,
|
|
45
50
|
toolNameFor: () => toolNameFor,
|
|
46
51
|
treeJsonSchema: () => treeJsonSchema,
|
|
47
52
|
treeToFlatSpec: () => treeToFlatSpec,
|
|
48
53
|
treeToText: () => treeToText,
|
|
54
|
+
validatePresentationBatch: () => validatePresentationBatch,
|
|
49
55
|
validateProps: () => validateProps,
|
|
50
56
|
validatePropsSync: () => validatePropsSync,
|
|
51
57
|
validateTree: () => validateTree,
|
|
@@ -229,21 +235,21 @@ function check(schema, value, path, root, issues, depth) {
|
|
|
229
235
|
});
|
|
230
236
|
return;
|
|
231
237
|
}
|
|
232
|
-
const
|
|
233
|
-
if (typeof
|
|
234
|
-
const target = resolveRef(root,
|
|
238
|
+
const s2 = schema;
|
|
239
|
+
if (typeof s2.$ref === "string") {
|
|
240
|
+
const target = resolveRef(root, s2.$ref);
|
|
235
241
|
if (target === void 0) {
|
|
236
242
|
issues.push({
|
|
237
243
|
path,
|
|
238
|
-
message: `references unknown schema ${
|
|
244
|
+
message: `references unknown schema ${s2.$ref}`
|
|
239
245
|
});
|
|
240
246
|
return;
|
|
241
247
|
}
|
|
242
248
|
check(target, value, path, root, issues, depth + 1);
|
|
243
249
|
}
|
|
244
|
-
if (
|
|
245
|
-
const types = Array.isArray(
|
|
246
|
-
|
|
250
|
+
if (s2.type !== void 0) {
|
|
251
|
+
const types = Array.isArray(s2.type) ? s2.type : [
|
|
252
|
+
s2.type
|
|
247
253
|
];
|
|
248
254
|
if (!types.some((type) => matchesType(type, value))) {
|
|
249
255
|
issues.push({
|
|
@@ -253,76 +259,76 @@ function check(schema, value, path, root, issues, depth) {
|
|
|
253
259
|
return;
|
|
254
260
|
}
|
|
255
261
|
}
|
|
256
|
-
if (Array.isArray(
|
|
262
|
+
if (Array.isArray(s2.enum) && !s2.enum.some((option) => deepEqual(option, value))) {
|
|
257
263
|
issues.push({
|
|
258
264
|
path,
|
|
259
|
-
message: `must be one of ${
|
|
265
|
+
message: `must be one of ${s2.enum.map((option) => JSON.stringify(option)).join(", ")}`
|
|
260
266
|
});
|
|
261
267
|
}
|
|
262
|
-
if ("const" in
|
|
268
|
+
if ("const" in s2 && !deepEqual(s2.const, value)) {
|
|
263
269
|
issues.push({
|
|
264
270
|
path,
|
|
265
|
-
message: `must be ${JSON.stringify(
|
|
271
|
+
message: `must be ${JSON.stringify(s2.const)}`
|
|
266
272
|
});
|
|
267
273
|
}
|
|
268
274
|
if (typeof value === "string") {
|
|
269
|
-
if (typeof
|
|
275
|
+
if (typeof s2.minLength === "number" && value.length < s2.minLength) {
|
|
270
276
|
issues.push({
|
|
271
277
|
path,
|
|
272
|
-
message: `must be at least ${
|
|
278
|
+
message: `must be at least ${s2.minLength} characters`
|
|
273
279
|
});
|
|
274
280
|
}
|
|
275
|
-
if (typeof
|
|
281
|
+
if (typeof s2.maxLength === "number" && value.length > s2.maxLength) {
|
|
276
282
|
issues.push({
|
|
277
283
|
path,
|
|
278
|
-
message: `must be at most ${
|
|
284
|
+
message: `must be at most ${s2.maxLength} characters`
|
|
279
285
|
});
|
|
280
286
|
}
|
|
281
|
-
if (typeof
|
|
287
|
+
if (typeof s2.pattern === "string") {
|
|
282
288
|
let pattern;
|
|
283
289
|
try {
|
|
284
|
-
pattern = new RegExp(
|
|
290
|
+
pattern = new RegExp(s2.pattern, "u");
|
|
285
291
|
} catch {
|
|
286
292
|
pattern = void 0;
|
|
287
293
|
}
|
|
288
294
|
if (pattern !== void 0 && !pattern.test(value)) {
|
|
289
295
|
issues.push({
|
|
290
296
|
path,
|
|
291
|
-
message: `must match ${
|
|
297
|
+
message: `must match ${s2.pattern}`
|
|
292
298
|
});
|
|
293
299
|
}
|
|
294
300
|
}
|
|
295
301
|
}
|
|
296
302
|
if (typeof value === "number") {
|
|
297
|
-
if (typeof
|
|
303
|
+
if (typeof s2.minimum === "number" && value < s2.minimum) {
|
|
298
304
|
issues.push({
|
|
299
305
|
path,
|
|
300
|
-
message: `must be >= ${
|
|
306
|
+
message: `must be >= ${s2.minimum}`
|
|
301
307
|
});
|
|
302
308
|
}
|
|
303
|
-
if (typeof
|
|
309
|
+
if (typeof s2.maximum === "number" && value > s2.maximum) {
|
|
304
310
|
issues.push({
|
|
305
311
|
path,
|
|
306
|
-
message: `must be <= ${
|
|
312
|
+
message: `must be <= ${s2.maximum}`
|
|
307
313
|
});
|
|
308
314
|
}
|
|
309
315
|
}
|
|
310
316
|
if (Array.isArray(value)) {
|
|
311
|
-
if (typeof
|
|
317
|
+
if (typeof s2.minItems === "number" && value.length < s2.minItems) {
|
|
312
318
|
issues.push({
|
|
313
319
|
path,
|
|
314
|
-
message: `must have at least ${
|
|
320
|
+
message: `must have at least ${s2.minItems} items`
|
|
315
321
|
});
|
|
316
322
|
}
|
|
317
|
-
if (typeof
|
|
323
|
+
if (typeof s2.maxItems === "number" && value.length > s2.maxItems) {
|
|
318
324
|
issues.push({
|
|
319
325
|
path,
|
|
320
|
-
message: `must have at most ${
|
|
326
|
+
message: `must have at most ${s2.maxItems} items`
|
|
321
327
|
});
|
|
322
328
|
}
|
|
323
|
-
if (
|
|
329
|
+
if (s2.items !== void 0 && !Array.isArray(s2.items)) {
|
|
324
330
|
value.forEach((item, index) => {
|
|
325
|
-
check(
|
|
331
|
+
check(s2.items, item, [
|
|
326
332
|
...path,
|
|
327
333
|
index
|
|
328
334
|
], root, issues, depth + 1);
|
|
@@ -331,9 +337,9 @@ function check(schema, value, path, root, issues, depth) {
|
|
|
331
337
|
}
|
|
332
338
|
if (matchesType("object", value)) {
|
|
333
339
|
const record2 = value;
|
|
334
|
-
const properties = typeof
|
|
335
|
-
if (Array.isArray(
|
|
336
|
-
for (const key of
|
|
340
|
+
const properties = typeof s2.properties === "object" && s2.properties !== null ? s2.properties : {};
|
|
341
|
+
if (Array.isArray(s2.required)) {
|
|
342
|
+
for (const key of s2.required) {
|
|
337
343
|
if (record2[key] === void 0) {
|
|
338
344
|
issues.push({
|
|
339
345
|
path: [
|
|
@@ -353,7 +359,7 @@ function check(schema, value, path, root, issues, depth) {
|
|
|
353
359
|
key
|
|
354
360
|
], root, issues, depth + 1);
|
|
355
361
|
}
|
|
356
|
-
} else if (
|
|
362
|
+
} else if (s2.additionalProperties === false) {
|
|
357
363
|
issues.push({
|
|
358
364
|
path: [
|
|
359
365
|
...path,
|
|
@@ -361,34 +367,34 @@ function check(schema, value, path, root, issues, depth) {
|
|
|
361
367
|
],
|
|
362
368
|
message: "is not a known property"
|
|
363
369
|
});
|
|
364
|
-
} else if (typeof
|
|
365
|
-
check(
|
|
370
|
+
} else if (typeof s2.additionalProperties === "object" && s2.additionalProperties !== null) {
|
|
371
|
+
check(s2.additionalProperties, entry, [
|
|
366
372
|
...path,
|
|
367
373
|
key
|
|
368
374
|
], root, issues, depth + 1);
|
|
369
375
|
}
|
|
370
376
|
}
|
|
371
377
|
}
|
|
372
|
-
if (Array.isArray(
|
|
373
|
-
for (const sub of
|
|
378
|
+
if (Array.isArray(s2.allOf)) {
|
|
379
|
+
for (const sub of s2.allOf) check(sub, value, path, root, issues, depth + 1);
|
|
374
380
|
}
|
|
375
|
-
if (Array.isArray(
|
|
376
|
-
const options = Array.isArray(
|
|
381
|
+
if (Array.isArray(s2.anyOf) || Array.isArray(s2.oneOf)) {
|
|
382
|
+
const options = Array.isArray(s2.anyOf) ? s2.anyOf : s2.oneOf;
|
|
377
383
|
const passing = options.filter((sub) => {
|
|
378
384
|
const nested = [];
|
|
379
385
|
check(sub, value, path, root, nested, depth + 1);
|
|
380
386
|
return nested.length === 0;
|
|
381
387
|
}).length;
|
|
382
|
-
if (Array.isArray(
|
|
388
|
+
if (Array.isArray(s2.anyOf) ? passing === 0 : passing !== 1) {
|
|
383
389
|
issues.push({
|
|
384
390
|
path,
|
|
385
|
-
message: Array.isArray(
|
|
391
|
+
message: Array.isArray(s2.anyOf) ? "does not match any allowed shape" : "must match exactly one allowed shape"
|
|
386
392
|
});
|
|
387
393
|
}
|
|
388
394
|
}
|
|
389
|
-
if (
|
|
395
|
+
if (s2.not !== void 0) {
|
|
390
396
|
const nested = [];
|
|
391
|
-
check(
|
|
397
|
+
check(s2.not, value, path, root, nested, depth + 1);
|
|
392
398
|
if (nested.length === 0) {
|
|
393
399
|
issues.push({
|
|
394
400
|
path,
|
|
@@ -445,7 +451,7 @@ function buildCatalog(byName, validator) {
|
|
|
445
451
|
]
|
|
446
452
|
};
|
|
447
453
|
}
|
|
448
|
-
const result = await validateProps(definition.props, props, validator);
|
|
454
|
+
const result = await validateProps(definition.outputProps ?? definition.props, props, validator);
|
|
449
455
|
return result;
|
|
450
456
|
},
|
|
451
457
|
validateSync(component, props) {
|
|
@@ -461,11 +467,11 @@ function buildCatalog(byName, validator) {
|
|
|
461
467
|
]
|
|
462
468
|
};
|
|
463
469
|
}
|
|
464
|
-
return validatePropsSync(definition.props, props, validator);
|
|
470
|
+
return validatePropsSync(definition.outputProps ?? definition.props, props, validator);
|
|
465
471
|
},
|
|
466
472
|
jsonSchemaFor(component) {
|
|
467
473
|
const definition = byName.get(component);
|
|
468
|
-
return definition === void 0 ? void 0 : toJsonSchema(definition.props);
|
|
474
|
+
return definition === void 0 ? void 0 : toJsonSchema(definition.outputProps ?? definition.props);
|
|
469
475
|
},
|
|
470
476
|
extend(more) {
|
|
471
477
|
const next = new Map(byName);
|
|
@@ -489,7 +495,7 @@ __name(toolNameFor, "toolNameFor");
|
|
|
489
495
|
|
|
490
496
|
// src/genui/tree.ts
|
|
491
497
|
var GENUI_TREE_COMPONENT = "genui:tree";
|
|
492
|
-
async function validateTree(catalog, tree, limits = {}) {
|
|
498
|
+
async function validateTree(catalog, tree, limits = {}, phase = "output") {
|
|
493
499
|
const maxDepth = limits.maxDepth ?? 12;
|
|
494
500
|
const maxNodes = limits.maxNodes ?? 200;
|
|
495
501
|
const issues = [];
|
|
@@ -541,7 +547,7 @@ async function validateTree(catalog, tree, limits = {}) {
|
|
|
541
547
|
});
|
|
542
548
|
return void 0;
|
|
543
549
|
}
|
|
544
|
-
const validated = await catalog.validate(element.type, element.props ?? {});
|
|
550
|
+
const validated = phase === "input" ? await validateProps(definition.props, element.props ?? {}, catalog.validator) : await catalog.validate(element.type, element.props ?? {});
|
|
545
551
|
let props = {};
|
|
546
552
|
if (!validated.ok) {
|
|
547
553
|
for (const issue of validated.issues) {
|
|
@@ -763,7 +769,7 @@ function catalogToModelText(catalog, options = {}) {
|
|
|
763
769
|
lines.push("Components you can show (one tool each):");
|
|
764
770
|
}
|
|
765
771
|
for (const component of catalog.modelComponents()) {
|
|
766
|
-
const schema =
|
|
772
|
+
const schema = toJsonSchema(component.props);
|
|
767
773
|
const head = mode === "per-component" ? `- ${component.name} (tool \`${toolNameFor(component.name, options.namePrefix)}\`)` : `- ${component.name}`;
|
|
768
774
|
lines.push(`${head}: ${component.description}`);
|
|
769
775
|
if (schema !== void 0) {
|
|
@@ -778,38 +784,38 @@ function catalogToModelText(catalog, options = {}) {
|
|
|
778
784
|
__name(catalogToModelText, "catalogToModelText");
|
|
779
785
|
function summarizeSchema(schema, root, depth) {
|
|
780
786
|
if (typeof schema !== "object" || schema === null) return "unknown";
|
|
781
|
-
const
|
|
787
|
+
const s2 = schema;
|
|
782
788
|
if (depth > 5) return "\u2026";
|
|
783
|
-
if (typeof
|
|
784
|
-
return
|
|
789
|
+
if (typeof s2.$ref === "string") {
|
|
790
|
+
return s2.$ref === "#" ? "Self" : s2.$ref.split("/").pop() ?? "unknown";
|
|
785
791
|
}
|
|
786
|
-
if (Array.isArray(
|
|
787
|
-
return
|
|
792
|
+
if (Array.isArray(s2.enum)) {
|
|
793
|
+
return s2.enum.map((option) => JSON.stringify(option)).join(" | ");
|
|
788
794
|
}
|
|
789
|
-
if ("const" in
|
|
790
|
-
const variants =
|
|
795
|
+
if ("const" in s2) return JSON.stringify(s2.const);
|
|
796
|
+
const variants = s2.anyOf ?? s2.oneOf;
|
|
791
797
|
if (Array.isArray(variants)) {
|
|
792
798
|
return variants.map((variant) => summarizeSchema(variant, root, depth + 1)).join(" | ");
|
|
793
799
|
}
|
|
794
|
-
const types = Array.isArray(
|
|
795
|
-
|
|
800
|
+
const types = Array.isArray(s2.type) ? s2.type : s2.type !== void 0 ? [
|
|
801
|
+
s2.type
|
|
796
802
|
] : [];
|
|
797
803
|
if (types.length > 1) {
|
|
798
804
|
return types.map((type2) => summarizeSchema({
|
|
799
|
-
...
|
|
805
|
+
...s2,
|
|
800
806
|
type: type2
|
|
801
807
|
}, root, depth + 1)).join(" | ");
|
|
802
808
|
}
|
|
803
809
|
const type = types[0];
|
|
804
810
|
if (type === "array") {
|
|
805
|
-
const item =
|
|
811
|
+
const item = s2.items === void 0 ? "unknown" : summarizeSchema(s2.items, root, depth + 1);
|
|
806
812
|
return /[|\s]/.test(item) && !item.startsWith("{") ? `(${item})[]` : `${item}[]`;
|
|
807
813
|
}
|
|
808
|
-
if (type === "object" || type === void 0 &&
|
|
809
|
-
const properties =
|
|
814
|
+
if (type === "object" || type === void 0 && s2.properties !== void 0) {
|
|
815
|
+
const properties = s2.properties ?? {};
|
|
810
816
|
const keys = Object.keys(properties);
|
|
811
817
|
if (keys.length === 0) return "object";
|
|
812
|
-
const required = new Set(Array.isArray(
|
|
818
|
+
const required = new Set(Array.isArray(s2.required) ? s2.required : []);
|
|
813
819
|
const fields = keys.map((key) => {
|
|
814
820
|
const field = properties[key];
|
|
815
821
|
const note = typeof field?.description === "string" && depth === 0 ? ` /* ${field.description} */` : "";
|
|
@@ -977,7 +983,7 @@ function componentTool(catalog, component, options) {
|
|
|
977
983
|
if (definition === void 0) {
|
|
978
984
|
throw new Error(`component "${component.name}" is not available here`);
|
|
979
985
|
}
|
|
980
|
-
const validated = await validateProps(definition.props, input, resolved.validator);
|
|
986
|
+
const validated = await validateProps(dynamic ? definition.props : definition.outputProps ?? definition.props, input, resolved.validator);
|
|
981
987
|
if (!validated.ok) {
|
|
982
988
|
throw new Error(`invalid ${component.name} props: ${formatIssues(validated.issues)}`);
|
|
983
989
|
}
|
|
@@ -1033,7 +1039,7 @@ function treeTool(catalog, options) {
|
|
|
1033
1039
|
const handler = {
|
|
1034
1040
|
async execute(input, ctx) {
|
|
1035
1041
|
const resolved = await catalogFor(catalog, options, scopeOf(ctx));
|
|
1036
|
-
const result = await validateTree(resolved, input, options.treeLimits);
|
|
1042
|
+
const result = await validateTree(resolved, input, options.treeLimits, dynamic ? "input" : "output");
|
|
1037
1043
|
if (!result.ok) {
|
|
1038
1044
|
throw new Error(`invalid UI tree: ${formatIssues(result.issues)}`);
|
|
1039
1045
|
}
|
|
@@ -1057,7 +1063,7 @@ function treeTool(catalog, options) {
|
|
|
1057
1063
|
kind: "read",
|
|
1058
1064
|
description: describeFor(catalog),
|
|
1059
1065
|
inputSchema: dynamic ? permissiveSchema(treeJsonSchema(catalog)) : asyncJsonStandardSchema(treeJsonSchema(catalog), async (value) => {
|
|
1060
|
-
const result = await validateTree(catalog, value, options.treeLimits);
|
|
1066
|
+
const result = await validateTree(catalog, value, options.treeLimits, "input");
|
|
1061
1067
|
return result.ok ? {
|
|
1062
1068
|
value: result.value
|
|
1063
1069
|
} : {
|
|
@@ -1092,7 +1098,7 @@ function showToolJsonSchema(catalog) {
|
|
|
1092
1098
|
};
|
|
1093
1099
|
}
|
|
1094
1100
|
__name(showToolJsonSchema, "showToolJsonSchema");
|
|
1095
|
-
async function validateShow(catalog, input) {
|
|
1101
|
+
async function validateShow(catalog, input, phase = "input") {
|
|
1096
1102
|
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
1097
1103
|
return {
|
|
1098
1104
|
ok: false,
|
|
@@ -1133,7 +1139,7 @@ async function validateShow(catalog, input) {
|
|
|
1133
1139
|
]
|
|
1134
1140
|
};
|
|
1135
1141
|
}
|
|
1136
|
-
const validated = await validateProps(definition.props, props ?? {}, catalog.validator);
|
|
1142
|
+
const validated = await validateProps(phase === "input" ? definition.props : definition.outputProps ?? definition.props, props ?? {}, catalog.validator);
|
|
1137
1143
|
if (!validated.ok) {
|
|
1138
1144
|
return {
|
|
1139
1145
|
ok: false,
|
|
@@ -1173,7 +1179,7 @@ function showTool(catalog, options) {
|
|
|
1173
1179
|
const handler = {
|
|
1174
1180
|
async execute(input, ctx) {
|
|
1175
1181
|
const resolved = await catalogFor(catalog, options, scopeOf(ctx));
|
|
1176
|
-
const result = await validateShow(resolved, input);
|
|
1182
|
+
const result = await validateShow(resolved, input, dynamic ? "input" : "output");
|
|
1177
1183
|
if (!result.ok) {
|
|
1178
1184
|
throw new Error(`invalid ${name} call: ${formatIssues(result.issues)}`);
|
|
1179
1185
|
}
|
|
@@ -1272,6 +1278,586 @@ function asyncJsonStandardSchema(schema, validate) {
|
|
|
1272
1278
|
};
|
|
1273
1279
|
}
|
|
1274
1280
|
__name(asyncJsonStandardSchema, "asyncJsonStandardSchema");
|
|
1281
|
+
|
|
1282
|
+
// src/genui/builtins.ts
|
|
1283
|
+
var str = /* @__PURE__ */ __name((description, extra = {}) => ({
|
|
1284
|
+
type: "string",
|
|
1285
|
+
...description !== void 0 ? {
|
|
1286
|
+
description
|
|
1287
|
+
} : {},
|
|
1288
|
+
...extra
|
|
1289
|
+
}), "str");
|
|
1290
|
+
var obj = /* @__PURE__ */ __name((properties, required = []) => ({
|
|
1291
|
+
type: "object",
|
|
1292
|
+
properties,
|
|
1293
|
+
required,
|
|
1294
|
+
additionalProperties: false
|
|
1295
|
+
}), "obj");
|
|
1296
|
+
var arr = /* @__PURE__ */ __name((items, extra = {}) => ({
|
|
1297
|
+
type: "array",
|
|
1298
|
+
items,
|
|
1299
|
+
...extra
|
|
1300
|
+
}), "arr");
|
|
1301
|
+
var cell = {
|
|
1302
|
+
type: [
|
|
1303
|
+
"string",
|
|
1304
|
+
"number",
|
|
1305
|
+
"boolean",
|
|
1306
|
+
"null"
|
|
1307
|
+
]
|
|
1308
|
+
};
|
|
1309
|
+
var row = {
|
|
1310
|
+
type: "object",
|
|
1311
|
+
additionalProperties: cell
|
|
1312
|
+
};
|
|
1313
|
+
var s = /* @__PURE__ */ __name((value) => value === null || value === void 0 ? "" : String(value), "s");
|
|
1314
|
+
var heading = /* @__PURE__ */ __name((props) => props.title ? `*${s(props.title)}*
|
|
1315
|
+
` : "", "heading");
|
|
1316
|
+
function textTable(columns, rows, max = 15) {
|
|
1317
|
+
const shown = rows.slice(0, max);
|
|
1318
|
+
const widths = columns.map((column) => Math.min(28, Math.max(column.label.length, ...shown.map((r) => s(r[column.key]).length))));
|
|
1319
|
+
const format = /* @__PURE__ */ __name((values) => values.map((value, index) => value.slice(0, widths[index]).padEnd(widths[index] ?? 0)).join(" "), "format");
|
|
1320
|
+
const lines = [
|
|
1321
|
+
format(columns.map((column) => column.label)),
|
|
1322
|
+
widths.map((width) => "-".repeat(width)).join(" "),
|
|
1323
|
+
...shown.map((r) => format(columns.map((column) => s(r[column.key]))))
|
|
1324
|
+
];
|
|
1325
|
+
if (rows.length > max) lines.push(`\u2026 ${rows.length - max} more rows`);
|
|
1326
|
+
return `\`\`\`
|
|
1327
|
+
${lines.join("\n")}
|
|
1328
|
+
\`\`\``;
|
|
1329
|
+
}
|
|
1330
|
+
__name(textTable, "textTable");
|
|
1331
|
+
function lineDiff(before, after) {
|
|
1332
|
+
const a = before.split("\n");
|
|
1333
|
+
const b = after.split("\n");
|
|
1334
|
+
if (a.length * b.length > 25e4) {
|
|
1335
|
+
return [
|
|
1336
|
+
...a.map((text) => ({
|
|
1337
|
+
op: "del",
|
|
1338
|
+
text
|
|
1339
|
+
})),
|
|
1340
|
+
...b.map((text) => ({
|
|
1341
|
+
op: "add",
|
|
1342
|
+
text
|
|
1343
|
+
}))
|
|
1344
|
+
];
|
|
1345
|
+
}
|
|
1346
|
+
const dp = Array.from({
|
|
1347
|
+
length: a.length + 1
|
|
1348
|
+
}, () => new Array(b.length + 1).fill(0));
|
|
1349
|
+
const at = /* @__PURE__ */ __name((i2, j2) => dp[i2]?.[j2] ?? 0, "at");
|
|
1350
|
+
for (let i2 = a.length - 1; i2 >= 0; i2--) {
|
|
1351
|
+
for (let j2 = b.length - 1; j2 >= 0; j2--) {
|
|
1352
|
+
dp[i2][j2] = a[i2] === b[j2] ? at(i2 + 1, j2 + 1) + 1 : Math.max(at(i2 + 1, j2), at(i2, j2 + 1));
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
const out = [];
|
|
1356
|
+
let i = 0;
|
|
1357
|
+
let j = 0;
|
|
1358
|
+
while (i < a.length && j < b.length) {
|
|
1359
|
+
if (a[i] === b[j]) {
|
|
1360
|
+
out.push({
|
|
1361
|
+
op: "same",
|
|
1362
|
+
text: a[i]
|
|
1363
|
+
});
|
|
1364
|
+
i++;
|
|
1365
|
+
j++;
|
|
1366
|
+
} else if (at(i + 1, j) >= at(i, j + 1)) {
|
|
1367
|
+
out.push({
|
|
1368
|
+
op: "del",
|
|
1369
|
+
text: a[i++]
|
|
1370
|
+
});
|
|
1371
|
+
} else {
|
|
1372
|
+
out.push({
|
|
1373
|
+
op: "add",
|
|
1374
|
+
text: b[j++]
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
while (i < a.length) out.push({
|
|
1379
|
+
op: "del",
|
|
1380
|
+
text: a[i++]
|
|
1381
|
+
});
|
|
1382
|
+
while (j < b.length) out.push({
|
|
1383
|
+
op: "add",
|
|
1384
|
+
text: b[j++]
|
|
1385
|
+
});
|
|
1386
|
+
return out;
|
|
1387
|
+
}
|
|
1388
|
+
__name(lineDiff, "lineDiff");
|
|
1389
|
+
function bar(value, max, width = 20) {
|
|
1390
|
+
const n = max > 0 ? Math.round(Math.abs(value) / max * width) : 0;
|
|
1391
|
+
return "\u2588".repeat(n) || "\u258F";
|
|
1392
|
+
}
|
|
1393
|
+
__name(bar, "bar");
|
|
1394
|
+
var DataTable = defineComponent({
|
|
1395
|
+
name: "DataTable",
|
|
1396
|
+
title: "Data table",
|
|
1397
|
+
description: "Tabular data (records with the same fields) as a sortable table. Prefer it over markdown tables for more than 3 rows.",
|
|
1398
|
+
props: obj({
|
|
1399
|
+
title: str("Short caption"),
|
|
1400
|
+
columns: arr(obj({
|
|
1401
|
+
key: str("Field name in each row"),
|
|
1402
|
+
label: str("Column header"),
|
|
1403
|
+
align: str(void 0, {
|
|
1404
|
+
enum: [
|
|
1405
|
+
"left",
|
|
1406
|
+
"right",
|
|
1407
|
+
"center"
|
|
1408
|
+
]
|
|
1409
|
+
}),
|
|
1410
|
+
format: str("How to format values", {
|
|
1411
|
+
enum: [
|
|
1412
|
+
"text",
|
|
1413
|
+
"number",
|
|
1414
|
+
"currency",
|
|
1415
|
+
"percent",
|
|
1416
|
+
"date",
|
|
1417
|
+
"link"
|
|
1418
|
+
]
|
|
1419
|
+
})
|
|
1420
|
+
}, [
|
|
1421
|
+
"key",
|
|
1422
|
+
"label"
|
|
1423
|
+
]), {
|
|
1424
|
+
minItems: 1,
|
|
1425
|
+
maxItems: 12
|
|
1426
|
+
}),
|
|
1427
|
+
rows: arr(row, {
|
|
1428
|
+
maxItems: 500
|
|
1429
|
+
})
|
|
1430
|
+
}, [
|
|
1431
|
+
"columns",
|
|
1432
|
+
"rows"
|
|
1433
|
+
]),
|
|
1434
|
+
fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${textTable(props.columns ?? [], props.rows ?? [])}`, "fallbackText")
|
|
1435
|
+
});
|
|
1436
|
+
var Chart = defineComponent({
|
|
1437
|
+
name: "Chart",
|
|
1438
|
+
title: "Chart",
|
|
1439
|
+
description: "`bar` to compare categories, `line` for a trend over time. `data` is a list of points; `xKey` names the category/time field and each series names a numeric field.",
|
|
1440
|
+
props: obj({
|
|
1441
|
+
type: str("Chart type", {
|
|
1442
|
+
enum: [
|
|
1443
|
+
"bar",
|
|
1444
|
+
"line"
|
|
1445
|
+
]
|
|
1446
|
+
}),
|
|
1447
|
+
title: str(),
|
|
1448
|
+
xKey: str("Field of each point used for the x axis"),
|
|
1449
|
+
series: arr(obj({
|
|
1450
|
+
key: str("Numeric field"),
|
|
1451
|
+
label: str()
|
|
1452
|
+
}, [
|
|
1453
|
+
"key"
|
|
1454
|
+
]), {
|
|
1455
|
+
minItems: 1,
|
|
1456
|
+
maxItems: 6
|
|
1457
|
+
}),
|
|
1458
|
+
data: arr(row, {
|
|
1459
|
+
minItems: 1,
|
|
1460
|
+
maxItems: 200
|
|
1461
|
+
}),
|
|
1462
|
+
unit: str("Unit shown after values, e.g. `KB` or `%`")
|
|
1463
|
+
}, [
|
|
1464
|
+
"type",
|
|
1465
|
+
"xKey",
|
|
1466
|
+
"series",
|
|
1467
|
+
"data"
|
|
1468
|
+
]),
|
|
1469
|
+
fallbackText: /* @__PURE__ */ __name((props) => {
|
|
1470
|
+
const series = props.series ?? [];
|
|
1471
|
+
const data = props.data ?? [];
|
|
1472
|
+
const first = series[0]?.key ?? "";
|
|
1473
|
+
const max = Math.max(0, ...data.map((point) => Math.abs(Number(point[first]) || 0)));
|
|
1474
|
+
const unit = props.unit ? ` ${s(props.unit)}` : "";
|
|
1475
|
+
const lines = data.slice(0, 20).map((point) => `${s(point[props.xKey]).slice(0, 18).padEnd(18)} ${bar(Number(point[first]) || 0, max)} ${s(point[first])}${unit}`);
|
|
1476
|
+
return `${heading(props)}\`\`\`
|
|
1477
|
+
${lines.join("\n")}
|
|
1478
|
+
\`\`\``;
|
|
1479
|
+
}, "fallbackText")
|
|
1480
|
+
});
|
|
1481
|
+
var KpiCards = defineComponent({
|
|
1482
|
+
name: "KpiCards",
|
|
1483
|
+
title: "KPI cards",
|
|
1484
|
+
description: "A few key numbers (metrics, totals, counts) as cards.",
|
|
1485
|
+
props: obj({
|
|
1486
|
+
title: str(),
|
|
1487
|
+
items: arr(obj({
|
|
1488
|
+
label: str(),
|
|
1489
|
+
value: {
|
|
1490
|
+
type: [
|
|
1491
|
+
"string",
|
|
1492
|
+
"number"
|
|
1493
|
+
]
|
|
1494
|
+
},
|
|
1495
|
+
delta: str("Change, e.g. `+12%`"),
|
|
1496
|
+
trend: str(void 0, {
|
|
1497
|
+
enum: [
|
|
1498
|
+
"up",
|
|
1499
|
+
"down",
|
|
1500
|
+
"flat"
|
|
1501
|
+
]
|
|
1502
|
+
}),
|
|
1503
|
+
hint: str()
|
|
1504
|
+
}, [
|
|
1505
|
+
"label",
|
|
1506
|
+
"value"
|
|
1507
|
+
]), {
|
|
1508
|
+
minItems: 1,
|
|
1509
|
+
maxItems: 8
|
|
1510
|
+
})
|
|
1511
|
+
}, [
|
|
1512
|
+
"items"
|
|
1513
|
+
]),
|
|
1514
|
+
fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${(props.items ?? []).map((item) => `\u2022 *${s(item.label)}:* ${s(item.value)}${item.delta ? ` (${s(item.delta)})` : ""}`).join("\n")}`, "fallbackText")
|
|
1515
|
+
});
|
|
1516
|
+
var SourceCards = defineComponent({
|
|
1517
|
+
name: "SourceCards",
|
|
1518
|
+
title: "Sources",
|
|
1519
|
+
description: "The documents, pages or links an answer is based on, as cards.",
|
|
1520
|
+
props: obj({
|
|
1521
|
+
title: str(),
|
|
1522
|
+
items: arr(obj({
|
|
1523
|
+
title: str(),
|
|
1524
|
+
url: str(),
|
|
1525
|
+
snippet: str(),
|
|
1526
|
+
source: str("e.g. Wiki, GitHub")
|
|
1527
|
+
}, [
|
|
1528
|
+
"title"
|
|
1529
|
+
]), {
|
|
1530
|
+
minItems: 1,
|
|
1531
|
+
maxItems: 12
|
|
1532
|
+
})
|
|
1533
|
+
}, [
|
|
1534
|
+
"items"
|
|
1535
|
+
]),
|
|
1536
|
+
fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${(props.items ?? []).map((item) => `\u2022 ${item.url ? `<${s(item.url)}|${s(item.title)}>` : s(item.title)}${item.source ? ` \u2014 ${s(item.source)}` : ""}`).join("\n")}`, "fallbackText")
|
|
1537
|
+
});
|
|
1538
|
+
var Checklist = defineComponent({
|
|
1539
|
+
name: "Checklist",
|
|
1540
|
+
title: "Checklist",
|
|
1541
|
+
description: "Steps or a to-do list with done/not-done state.",
|
|
1542
|
+
props: obj({
|
|
1543
|
+
title: str(),
|
|
1544
|
+
items: arr(obj({
|
|
1545
|
+
label: str(),
|
|
1546
|
+
done: {
|
|
1547
|
+
type: "boolean"
|
|
1548
|
+
},
|
|
1549
|
+
note: str()
|
|
1550
|
+
}, [
|
|
1551
|
+
"label"
|
|
1552
|
+
]), {
|
|
1553
|
+
minItems: 1,
|
|
1554
|
+
maxItems: 50
|
|
1555
|
+
})
|
|
1556
|
+
}, [
|
|
1557
|
+
"items"
|
|
1558
|
+
]),
|
|
1559
|
+
fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${(props.items ?? []).map((item) => `${item.done ? "\u2611" : "\u2610"} ${s(item.label)}${item.note ? ` \u2014 _${s(item.note)}_` : ""}`).join("\n")}`, "fallbackText")
|
|
1560
|
+
});
|
|
1561
|
+
var Timeline = defineComponent({
|
|
1562
|
+
name: "Timeline",
|
|
1563
|
+
title: "Timeline",
|
|
1564
|
+
description: "Events in chronological order (the history of a project, an incident, a deal).",
|
|
1565
|
+
props: obj({
|
|
1566
|
+
title: str(),
|
|
1567
|
+
events: arr(obj({
|
|
1568
|
+
date: str(),
|
|
1569
|
+
title: str(),
|
|
1570
|
+
description: str()
|
|
1571
|
+
}, [
|
|
1572
|
+
"title"
|
|
1573
|
+
]), {
|
|
1574
|
+
minItems: 1,
|
|
1575
|
+
maxItems: 50
|
|
1576
|
+
})
|
|
1577
|
+
}, [
|
|
1578
|
+
"events"
|
|
1579
|
+
]),
|
|
1580
|
+
fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}${(props.events ?? []).map((event) => `\u2022 ${event.date ? `*${s(event.date)}* ` : ""}${s(event.title)}${event.description ? ` \u2014 ${s(event.description)}` : ""}`).join("\n")}`, "fallbackText")
|
|
1581
|
+
});
|
|
1582
|
+
var CodeBlock = defineComponent({
|
|
1583
|
+
name: "CodeBlock",
|
|
1584
|
+
title: "Code",
|
|
1585
|
+
description: "A code snippet or file excerpt with syntax highlighting.",
|
|
1586
|
+
props: obj({
|
|
1587
|
+
title: str(),
|
|
1588
|
+
language: str(),
|
|
1589
|
+
code: str()
|
|
1590
|
+
}, [
|
|
1591
|
+
"code"
|
|
1592
|
+
]),
|
|
1593
|
+
fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}\`\`\`
|
|
1594
|
+
${s(props.code)}
|
|
1595
|
+
\`\`\``, "fallbackText")
|
|
1596
|
+
});
|
|
1597
|
+
var Diff = defineComponent({
|
|
1598
|
+
name: "Diff",
|
|
1599
|
+
title: "Diff",
|
|
1600
|
+
description: "A before/after change to a text or code file, as a line diff.",
|
|
1601
|
+
props: obj({
|
|
1602
|
+
title: str(),
|
|
1603
|
+
language: str(),
|
|
1604
|
+
before: str(),
|
|
1605
|
+
after: str()
|
|
1606
|
+
}, [
|
|
1607
|
+
"before",
|
|
1608
|
+
"after"
|
|
1609
|
+
]),
|
|
1610
|
+
fallbackText: /* @__PURE__ */ __name((props) => `${heading(props)}\`\`\`
|
|
1611
|
+
${lineDiff(s(props.before), s(props.after)).map((line) => `${line.op === "add" ? "+" : line.op === "del" ? "-" : " "} ${line.text}`).join("\n")}
|
|
1612
|
+
\`\`\``, "fallbackText")
|
|
1613
|
+
});
|
|
1614
|
+
var Callout = defineComponent({
|
|
1615
|
+
name: "Callout",
|
|
1616
|
+
title: "Callout",
|
|
1617
|
+
description: "A short note, warning or success message, emphasized.",
|
|
1618
|
+
props: obj({
|
|
1619
|
+
tone: str(void 0, {
|
|
1620
|
+
enum: [
|
|
1621
|
+
"info",
|
|
1622
|
+
"success",
|
|
1623
|
+
"warning",
|
|
1624
|
+
"danger"
|
|
1625
|
+
]
|
|
1626
|
+
}),
|
|
1627
|
+
title: str(),
|
|
1628
|
+
text: str()
|
|
1629
|
+
}, [
|
|
1630
|
+
"text"
|
|
1631
|
+
]),
|
|
1632
|
+
fallbackText: /* @__PURE__ */ __name((props) => `${props.tone === "warning" || props.tone === "danger" ? ":warning: " : ":information_source: "}${heading(props)}${s(props.text)}`, "fallbackText")
|
|
1633
|
+
});
|
|
1634
|
+
var Stack = defineComponent({
|
|
1635
|
+
name: "Stack",
|
|
1636
|
+
title: "Stack",
|
|
1637
|
+
description: "Lays its children out vertically (or horizontally with direction=row).",
|
|
1638
|
+
props: obj({
|
|
1639
|
+
direction: str(void 0, {
|
|
1640
|
+
enum: [
|
|
1641
|
+
"column",
|
|
1642
|
+
"row"
|
|
1643
|
+
]
|
|
1644
|
+
}),
|
|
1645
|
+
gap: {
|
|
1646
|
+
type: "number"
|
|
1647
|
+
}
|
|
1648
|
+
}),
|
|
1649
|
+
children: true,
|
|
1650
|
+
fallbackText: /* @__PURE__ */ __name(() => "", "fallbackText")
|
|
1651
|
+
});
|
|
1652
|
+
var Card = defineComponent({
|
|
1653
|
+
name: "Card",
|
|
1654
|
+
title: "Card",
|
|
1655
|
+
description: "A box with an optional title around its children.",
|
|
1656
|
+
props: obj({
|
|
1657
|
+
title: str(),
|
|
1658
|
+
subtitle: str()
|
|
1659
|
+
}),
|
|
1660
|
+
children: true,
|
|
1661
|
+
fallbackText: /* @__PURE__ */ __name((props) => props.title ? `*${s(props.title)}*${props.subtitle ? ` \u2014 ${s(props.subtitle)}` : ""}` : "", "fallbackText")
|
|
1662
|
+
});
|
|
1663
|
+
var Heading = defineComponent({
|
|
1664
|
+
name: "Heading",
|
|
1665
|
+
title: "Heading",
|
|
1666
|
+
description: "A heading.",
|
|
1667
|
+
props: obj({
|
|
1668
|
+
text: str()
|
|
1669
|
+
}, [
|
|
1670
|
+
"text"
|
|
1671
|
+
]),
|
|
1672
|
+
fallbackText: /* @__PURE__ */ __name((props) => `*${s(props.text)}*`, "fallbackText")
|
|
1673
|
+
});
|
|
1674
|
+
var Text = defineComponent({
|
|
1675
|
+
name: "Text",
|
|
1676
|
+
title: "Text",
|
|
1677
|
+
description: "A paragraph of plain text (no markdown).",
|
|
1678
|
+
props: obj({
|
|
1679
|
+
text: str(),
|
|
1680
|
+
muted: {
|
|
1681
|
+
type: "boolean"
|
|
1682
|
+
}
|
|
1683
|
+
}, [
|
|
1684
|
+
"text"
|
|
1685
|
+
]),
|
|
1686
|
+
fallbackText: /* @__PURE__ */ __name((props) => s(props.text), "fallbackText")
|
|
1687
|
+
});
|
|
1688
|
+
var Badge = defineComponent({
|
|
1689
|
+
name: "Badge",
|
|
1690
|
+
title: "Badge",
|
|
1691
|
+
description: "A small label.",
|
|
1692
|
+
props: obj({
|
|
1693
|
+
text: str(),
|
|
1694
|
+
tone: str(void 0, {
|
|
1695
|
+
enum: [
|
|
1696
|
+
"neutral",
|
|
1697
|
+
"brand",
|
|
1698
|
+
"success",
|
|
1699
|
+
"warning",
|
|
1700
|
+
"danger"
|
|
1701
|
+
]
|
|
1702
|
+
})
|
|
1703
|
+
}, [
|
|
1704
|
+
"text"
|
|
1705
|
+
]),
|
|
1706
|
+
fallbackText: /* @__PURE__ */ __name((props) => `[${s(props.text)}]`, "fallbackText")
|
|
1707
|
+
});
|
|
1708
|
+
var Link = defineComponent({
|
|
1709
|
+
name: "Link",
|
|
1710
|
+
title: "Link",
|
|
1711
|
+
description: "A link to an http(s) URL.",
|
|
1712
|
+
props: obj({
|
|
1713
|
+
text: str(),
|
|
1714
|
+
url: str(void 0, {
|
|
1715
|
+
pattern: "^https?://"
|
|
1716
|
+
})
|
|
1717
|
+
}, [
|
|
1718
|
+
"text",
|
|
1719
|
+
"url"
|
|
1720
|
+
]),
|
|
1721
|
+
fallbackText: /* @__PURE__ */ __name((props) => `<${s(props.url)}|${s(props.text || props.url)}>`, "fallbackText")
|
|
1722
|
+
});
|
|
1723
|
+
var Image = defineComponent({
|
|
1724
|
+
name: "Image",
|
|
1725
|
+
title: "Image",
|
|
1726
|
+
description: "An image from an https URL.",
|
|
1727
|
+
props: obj({
|
|
1728
|
+
url: str(void 0, {
|
|
1729
|
+
pattern: "^https://"
|
|
1730
|
+
}),
|
|
1731
|
+
alt: str()
|
|
1732
|
+
}, [
|
|
1733
|
+
"url"
|
|
1734
|
+
]),
|
|
1735
|
+
fallbackText: /* @__PURE__ */ __name((props) => s(props.url), "fallbackText")
|
|
1736
|
+
});
|
|
1737
|
+
|
|
1738
|
+
// src/genui/registry.ts
|
|
1739
|
+
function snapshotComponentPresentation(value) {
|
|
1740
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1741
|
+
const check2 = /* @__PURE__ */ __name((entry) => {
|
|
1742
|
+
if (entry === null || typeof entry === "string" || typeof entry === "boolean") return;
|
|
1743
|
+
if (typeof entry === "number" && Number.isFinite(entry)) return;
|
|
1744
|
+
if (typeof entry !== "object" || entry === null) throw new TypeError("genui: presentation must contain only JSON values");
|
|
1745
|
+
if (seen.has(entry)) throw new TypeError("genui: presentation must contain acyclic JSON values");
|
|
1746
|
+
if (!Array.isArray(entry) && Object.getPrototypeOf(entry) !== Object.prototype && Object.getPrototypeOf(entry) !== null) throw new TypeError("genui: presentation must contain plain JSON objects");
|
|
1747
|
+
seen.add(entry);
|
|
1748
|
+
for (const item of Object.values(entry)) check2(item);
|
|
1749
|
+
seen.delete(entry);
|
|
1750
|
+
}, "check");
|
|
1751
|
+
check2(value);
|
|
1752
|
+
return JSON.parse(JSON.stringify(value));
|
|
1753
|
+
}
|
|
1754
|
+
__name(snapshotComponentPresentation, "snapshotComponentPresentation");
|
|
1755
|
+
function createComponent(definition, options = {}) {
|
|
1756
|
+
defineComponent(definition);
|
|
1757
|
+
const catalog = defineCatalog([
|
|
1758
|
+
definition
|
|
1759
|
+
], options);
|
|
1760
|
+
const factory = /* @__PURE__ */ __name(async (props) => {
|
|
1761
|
+
const result = await validateProps(definition.props, props, catalog.validator);
|
|
1762
|
+
if (!result.ok) throw new Error(`genui: invalid ${definition.name} props: ${formatIssues(result.issues)}`);
|
|
1763
|
+
const normalized = snapshotComponentPresentation(result.value);
|
|
1764
|
+
if (typeof normalized !== "object" || normalized === null || Array.isArray(normalized)) throw new TypeError("genui: component props must be a JSON object");
|
|
1765
|
+
const portable = await catalog.validate(definition.name, normalized);
|
|
1766
|
+
if (!portable.ok || canonicalJson(snapshotComponentPresentation(portable.value)) !== canonicalJson(normalized)) {
|
|
1767
|
+
throw new Error(`genui: ${definition.name} requires outputProps accepting stable normalized JSON props`);
|
|
1768
|
+
}
|
|
1769
|
+
return {
|
|
1770
|
+
component: definition.name,
|
|
1771
|
+
props: normalized,
|
|
1772
|
+
version: definition.version ?? 1,
|
|
1773
|
+
fallbackText: componentToText(catalog, definition.name, normalized)
|
|
1774
|
+
};
|
|
1775
|
+
}, "factory");
|
|
1776
|
+
return Object.assign(factory, {
|
|
1777
|
+
definition
|
|
1778
|
+
});
|
|
1779
|
+
}
|
|
1780
|
+
__name(createComponent, "createComponent");
|
|
1781
|
+
function createComponentRegistry(options = {}) {
|
|
1782
|
+
let catalog = defineCatalog([], options);
|
|
1783
|
+
const channels = /* @__PURE__ */ new Map();
|
|
1784
|
+
const registry = {
|
|
1785
|
+
get catalog() {
|
|
1786
|
+
return catalog;
|
|
1787
|
+
},
|
|
1788
|
+
get manifest() {
|
|
1789
|
+
return catalog.components.map((definition) => {
|
|
1790
|
+
const props = catalog.jsonSchemaFor(definition.name);
|
|
1791
|
+
return {
|
|
1792
|
+
name: definition.name,
|
|
1793
|
+
title: definition.title,
|
|
1794
|
+
description: definition.description,
|
|
1795
|
+
version: definition.version ?? 1,
|
|
1796
|
+
...props === void 0 ? {} : {
|
|
1797
|
+
props: snapshotComponentPresentation(props)
|
|
1798
|
+
}
|
|
1799
|
+
};
|
|
1800
|
+
});
|
|
1801
|
+
},
|
|
1802
|
+
register(definition, renderers) {
|
|
1803
|
+
if (catalog.has(definition.name)) throw new Error(`genui: component "${definition.name}" is already registered`);
|
|
1804
|
+
catalog = catalog.extend([
|
|
1805
|
+
definition
|
|
1806
|
+
]);
|
|
1807
|
+
channels.set(definition.name, {
|
|
1808
|
+
...renderers
|
|
1809
|
+
});
|
|
1810
|
+
return this;
|
|
1811
|
+
},
|
|
1812
|
+
async prepare(presentation) {
|
|
1813
|
+
const definition = catalog.get(presentation.component);
|
|
1814
|
+
if (definition === void 0) throw new Error(`genui: unknown component "${presentation.component}"`);
|
|
1815
|
+
if (presentation.version !== (definition.version ?? 1)) throw new Error(`genui: component "${presentation.component}" version mismatch`);
|
|
1816
|
+
const validated = await catalog.validate(presentation.component, presentation.props);
|
|
1817
|
+
if (!validated.ok) throw new Error(`genui: invalid ${presentation.component} props: ${formatIssues(validated.issues)}`);
|
|
1818
|
+
const props = snapshotComponentPresentation(validated.value);
|
|
1819
|
+
if (typeof props !== "object" || props === null || Array.isArray(props)) throw new TypeError("genui: component props must be a JSON object");
|
|
1820
|
+
return {
|
|
1821
|
+
component: definition.name,
|
|
1822
|
+
props,
|
|
1823
|
+
version: definition.version ?? 1,
|
|
1824
|
+
fallbackText: componentToText(catalog, definition.name, props)
|
|
1825
|
+
};
|
|
1826
|
+
},
|
|
1827
|
+
async render(presentation, channel, context) {
|
|
1828
|
+
const prepared = await this.prepare(presentation);
|
|
1829
|
+
const mapping = channels.get(prepared.component);
|
|
1830
|
+
const renderer = mapping === void 0 ? void 0 : Object.hasOwn(mapping, channel) ? mapping[channel] : Object.hasOwn(mapping, "text") ? mapping.text : void 0;
|
|
1831
|
+
return renderer === void 0 ? prepared.fallbackText : renderer(prepared.props, context);
|
|
1832
|
+
}
|
|
1833
|
+
};
|
|
1834
|
+
return registry;
|
|
1835
|
+
}
|
|
1836
|
+
__name(createComponentRegistry, "createComponentRegistry");
|
|
1837
|
+
var table = createComponent(DataTable);
|
|
1838
|
+
var chart = createComponent(Chart);
|
|
1839
|
+
function validatePresentationBatch(presentations) {
|
|
1840
|
+
const batch = Array.isArray(presentations) ? presentations : [
|
|
1841
|
+
presentations
|
|
1842
|
+
];
|
|
1843
|
+
return batch.map((item) => {
|
|
1844
|
+
const presentation = snapshotComponentPresentation(item);
|
|
1845
|
+
if (typeof presentation !== "object" || presentation === null || typeof presentation.component !== "string" || !/^[A-Za-z][A-Za-z0-9]{0,63}$/.test(presentation.component) || !Number.isSafeInteger(presentation.version) || presentation.version <= 0 || typeof presentation.fallbackText !== "string" || typeof presentation.props !== "object" || presentation.props === null || Array.isArray(presentation.props)) {
|
|
1846
|
+
throw new TypeError("genui: invalid component presentation");
|
|
1847
|
+
}
|
|
1848
|
+
return presentation;
|
|
1849
|
+
});
|
|
1850
|
+
}
|
|
1851
|
+
__name(validatePresentationBatch, "validatePresentationBatch");
|
|
1852
|
+
function canonicalJson(value) {
|
|
1853
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
1854
|
+
if (typeof value === "object" && value !== null) {
|
|
1855
|
+
const record2 = value;
|
|
1856
|
+
return `{${Object.keys(record2).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(record2[key])}`).join(",")}}`;
|
|
1857
|
+
}
|
|
1858
|
+
return JSON.stringify(value);
|
|
1859
|
+
}
|
|
1860
|
+
__name(canonicalJson, "canonicalJson");
|
|
1275
1861
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1276
1862
|
0 && (module.exports = {
|
|
1277
1863
|
COMPONENT_NAME,
|
|
@@ -1280,7 +1866,10 @@ __name(asyncJsonStandardSchema, "asyncJsonStandardSchema");
|
|
|
1280
1866
|
ajvValidator,
|
|
1281
1867
|
builtinJsonSchemaValidator,
|
|
1282
1868
|
catalogToModelText,
|
|
1869
|
+
chart,
|
|
1283
1870
|
componentToText,
|
|
1871
|
+
createComponent,
|
|
1872
|
+
createComponentRegistry,
|
|
1284
1873
|
defineCatalog,
|
|
1285
1874
|
defineComponent,
|
|
1286
1875
|
fillTemplate,
|
|
@@ -1292,13 +1881,16 @@ __name(asyncJsonStandardSchema, "asyncJsonStandardSchema");
|
|
|
1292
1881
|
negotiateCatalog,
|
|
1293
1882
|
prepareUiEmission,
|
|
1294
1883
|
showToolJsonSchema,
|
|
1884
|
+
snapshotComponentPresentation,
|
|
1295
1885
|
summarizeSchema,
|
|
1886
|
+
table,
|
|
1296
1887
|
toJsonSchema,
|
|
1297
1888
|
toSnakeCase,
|
|
1298
1889
|
toolNameFor,
|
|
1299
1890
|
treeJsonSchema,
|
|
1300
1891
|
treeToFlatSpec,
|
|
1301
1892
|
treeToText,
|
|
1893
|
+
validatePresentationBatch,
|
|
1302
1894
|
validateProps,
|
|
1303
1895
|
validatePropsSync,
|
|
1304
1896
|
validateTree,
|