@dudousxd/nestjs-agent-core 0.38.1 → 0.40.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.
@@ -278,11 +278,11 @@ function check(schema, value, path, root, issues, depth) {
278
278
  }
279
279
  }
280
280
  if (matchesType("object", value)) {
281
- const record = value;
281
+ const record2 = value;
282
282
  const properties = typeof s.properties === "object" && s.properties !== null ? s.properties : {};
283
283
  if (Array.isArray(s.required)) {
284
284
  for (const key of s.required) {
285
- if (record[key] === void 0) {
285
+ if (record2[key] === void 0) {
286
286
  issues.push({
287
287
  path: [
288
288
  ...path,
@@ -293,7 +293,7 @@ function check(schema, value, path, root, issues, depth) {
293
293
  }
294
294
  }
295
295
  }
296
- for (const [key, entry] of Object.entries(record)) {
296
+ for (const [key, entry] of Object.entries(record2)) {
297
297
  if (key in properties) {
298
298
  if (entry !== void 0) {
299
299
  check(properties[key], entry, [
@@ -353,6 +353,8 @@ function defineComponent(definition) {
353
353
  if (!COMPONENT_NAME.test(definition.name)) {
354
354
  throw new Error(`genui: component name "${definition.name}" must be letters and digits, starting with a letter (e.g. DataTable)`);
355
355
  }
356
+ if (definition.version !== void 0 && (!Number.isSafeInteger(definition.version) || definition.version <= 0)) throw new RangeError("genui: component version must be a positive safe integer");
357
+ if (definition.fallbackText !== void 0 && typeof definition.fallbackText !== "function") throw new TypeError("genui: fallbackText must be a function");
356
358
  return definition;
357
359
  }
358
360
  __name(defineComponent, "defineComponent");
@@ -661,7 +663,8 @@ function componentToText(catalog, component, props) {
661
663
  const fallback = catalog.get(component)?.fallbackText;
662
664
  if (fallback !== void 0) {
663
665
  try {
664
- return fallback(props);
666
+ const text = fallback(props);
667
+ if (typeof text === "string" && text.trim().length > 0) return text;
665
668
  } catch {
666
669
  }
667
670
  }
@@ -675,7 +678,8 @@ function treeToText(catalog, root) {
675
678
  const definition = catalog.get(node.type);
676
679
  if (definition?.fallbackText !== void 0) {
677
680
  try {
678
- out.push(definition.fallbackText(node.props));
681
+ const text = definition.fallbackText(node.props);
682
+ out.push(typeof text === "string" && text.trim().length > 0 ? text : jsonBlock(node.props));
679
683
  } catch {
680
684
  out.push(jsonBlock(node.props));
681
685
  }
@@ -692,7 +696,7 @@ function jsonBlock(props) {
692
696
  const title = typeof props.title === "string" && props.title.length > 0 ? `*${props.title}*
693
697
  ` : "";
694
698
  return `${title}\`\`\`
695
- ${JSON.stringify(props, null, 2).slice(0, 2500)}
699
+ ${JSON.stringify(props, null, 2)}
696
700
  \`\`\``;
697
701
  }
698
702
  __name(jsonBlock, "jsonBlock");
@@ -783,6 +787,81 @@ function getPath(source, path) {
783
787
  }
784
788
  __name(getPath, "getPath");
785
789
 
790
+ // src/genui/capabilities.ts
791
+ function validateUiCapabilities(value) {
792
+ if (!record(value) || Object.keys(value).some((key) => key !== "components") || !Array.isArray(value.components)) throw new TypeError("Invalid UI capabilities");
793
+ const seen = /* @__PURE__ */ new Set();
794
+ const components = value.components.map((component) => {
795
+ if (!record(component) || Object.keys(component).some((key) => key !== "name" && key !== "version") || typeof component.name !== "string" || !COMPONENT_NAME.test(component.name) || !Number.isSafeInteger(component.version) || Number(component.version) <= 0 || seen.has(component.name)) throw new TypeError("Invalid UI component capability");
796
+ seen.add(component.name);
797
+ return {
798
+ name: component.name,
799
+ version: Number(component.version)
800
+ };
801
+ });
802
+ return {
803
+ components
804
+ };
805
+ }
806
+ __name(validateUiCapabilities, "validateUiCapabilities");
807
+ function record(value) {
808
+ return typeof value === "object" && value !== null && !Array.isArray(value);
809
+ }
810
+ __name(record, "record");
811
+ function negotiateCatalog(catalog, capabilities) {
812
+ if (capabilities === void 0) return catalog;
813
+ const supported = validateUiCapabilities(capabilities).components;
814
+ return defineCatalog(catalog.components.filter((component) => supported.some((entry) => entry.name === component.name && entry.version === (component.version ?? 1))), {
815
+ jsonSchemaValidator: catalog.validator
816
+ });
817
+ }
818
+ __name(negotiateCatalog, "negotiateCatalog");
819
+ async function prepareUiEmission(catalog, capabilities, component, props, version) {
820
+ const drawable = negotiateCatalog(catalog, capabilities);
821
+ if (component === GENUI_TREE_COMPONENT) {
822
+ if (version !== void 0 && version !== 1) throw new Error("Invalid UI tree version");
823
+ const validated2 = await validateTree(catalog, props.root);
824
+ if (!validated2.ok) throw new Error(`Invalid UI tree: ${formatIssues(validated2.issues)}`);
825
+ const supported = /* @__PURE__ */ __name((node) => drawable.has(node.type) && (node.children ?? []).every(supported), "supported");
826
+ const versions = /* @__PURE__ */ new Map();
827
+ const collectVersions = /* @__PURE__ */ __name((node) => {
828
+ versions.set(node.type, catalog.get(node.type)?.version ?? 1);
829
+ for (const child of node.children ?? []) collectVersions(child);
830
+ }, "collectVersions");
831
+ collectVersions(validated2.value);
832
+ return supported(validated2.value) ? {
833
+ kind: "ui",
834
+ component,
835
+ props: {
836
+ root: validated2.value
837
+ },
838
+ version: 1,
839
+ fallbackText: treeToText(catalog, validated2.value),
840
+ componentVersions: Object.fromEntries(versions)
841
+ } : {
842
+ kind: "text",
843
+ text: treeToText(catalog, validated2.value)
844
+ };
845
+ }
846
+ const definition = catalog.get(component);
847
+ if (definition === void 0) throw new Error(`Unknown UI component "${component}"`);
848
+ const currentVersion = definition.version ?? 1;
849
+ if (version !== void 0 && version !== currentVersion) throw new Error(`Invalid UI component version for "${component}"`);
850
+ const validated = await catalog.validate(component, props);
851
+ if (!validated.ok) throw new Error(`Invalid UI props: ${formatIssues(validated.issues)}`);
852
+ return drawable.has(component) ? {
853
+ kind: "ui",
854
+ component,
855
+ props: validated.value,
856
+ version: currentVersion,
857
+ fallbackText: componentToText(catalog, component, validated.value)
858
+ } : {
859
+ kind: "text",
860
+ text: componentToText(catalog, component, validated.value)
861
+ };
862
+ }
863
+ __name(prepareUiEmission, "prepareUiEmission");
864
+
786
865
  // src/genui/tools.ts
787
866
  var GENUI_SHOW_TOOL = "ui__show";
788
867
  function genuiTools(catalog, options = {}) {
@@ -853,23 +932,22 @@ function componentTool(catalog, component, options) {
853
932
  return push(ctx, component.name, validated.value, definition.version);
854
933
  }
855
934
  };
856
- if (dynamic) {
857
- handler.describe = async (scope) => {
858
- const resolved = await catalogFor(catalog, options, scopeOf(scope));
859
- const definition = modelComponent(resolved, component.name);
860
- if (definition === void 0) {
861
- return {
862
- description: `Not available in this conversation \u2014 do not call this tool. (${component.name})`
863
- };
864
- }
935
+ handler.describe = async (scope) => {
936
+ const resolved = negotiateCatalog(await catalogFor(catalog, options, scopeOf(scope)), scope.uiCapabilities);
937
+ const definition = modelComponent(resolved, component.name);
938
+ if (definition === void 0) {
865
939
  return {
866
- description: describeFor(definition),
867
- inputSchema: permissiveSchema(toJsonSchema(definition.props) ?? {
868
- type: "object"
869
- })
940
+ available: false,
941
+ description: `Not available in this conversation \u2014 do not call this tool. (${component.name})`
870
942
  };
943
+ }
944
+ return {
945
+ description: describeFor(definition),
946
+ inputSchema: permissiveSchema(toJsonSchema(definition.props) ?? {
947
+ type: "object"
948
+ })
871
949
  };
872
- }
950
+ };
873
951
  return {
874
952
  spec: {
875
953
  name: toolNameFor(component.name, options.namePrefix),
@@ -913,15 +991,14 @@ function treeTool(catalog, options) {
913
991
  });
914
992
  }
915
993
  };
916
- if (dynamic) {
917
- handler.describe = async (scope) => {
918
- const resolved = await catalogFor(catalog, options, scopeOf(scope));
919
- return {
920
- description: describeFor(resolved),
921
- inputSchema: permissiveSchema(treeJsonSchema(resolved))
922
- };
994
+ handler.describe = async (scope) => {
995
+ const resolved = negotiateCatalog(await catalogFor(catalog, options, scopeOf(scope)), scope.uiCapabilities);
996
+ return {
997
+ available: resolved.modelComponents().length > 0,
998
+ description: describeFor(resolved),
999
+ inputSchema: permissiveSchema(treeJsonSchema(resolved))
923
1000
  };
924
- }
1001
+ };
925
1002
  return {
926
1003
  spec: {
927
1004
  name,
@@ -1051,15 +1128,14 @@ function showTool(catalog, options) {
1051
1128
  return push(ctx, result.definition.name, result.props, result.definition.version);
1052
1129
  }
1053
1130
  };
1054
- if (dynamic) {
1055
- handler.describe = async (scope) => {
1056
- const resolved = await catalogFor(catalog, options, scopeOf(scope));
1057
- return {
1058
- description: describeFor(resolved),
1059
- inputSchema: permissiveSchema(showToolJsonSchema(resolved))
1060
- };
1131
+ handler.describe = async (scope) => {
1132
+ const resolved = negotiateCatalog(await catalogFor(catalog, options, scopeOf(scope)), scope.uiCapabilities);
1133
+ return {
1134
+ available: resolved.modelComponents().length > 0,
1135
+ description: describeFor(resolved),
1136
+ inputSchema: permissiveSchema(showToolJsonSchema(resolved))
1061
1137
  };
1062
- }
1138
+ };
1063
1139
  return {
1064
1140
  spec: {
1065
1141
  name,
@@ -1160,6 +1236,8 @@ export {
1160
1236
  getPath,
1161
1237
  isStandardSchema,
1162
1238
  jsonStandardSchema,
1239
+ negotiateCatalog,
1240
+ prepareUiEmission,
1163
1241
  showToolJsonSchema,
1164
1242
  summarizeSchema,
1165
1243
  toJsonSchema,
@@ -1170,6 +1248,7 @@ export {
1170
1248
  treeToText,
1171
1249
  validateProps,
1172
1250
  validatePropsSync,
1173
- validateTree
1251
+ validateTree,
1252
+ validateUiCapabilities
1174
1253
  };
1175
1254
  //# sourceMappingURL=index.js.map