@aigne/core 1.60.0 → 1.60.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.60.2](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.60.1...core-v1.60.2) (2025-09-11)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **core:** add nullish or nullable support for output schema ([#482](https://github.com/AIGNE-io/aigne-framework/issues/482)) ([bf80c29](https://github.com/AIGNE-io/aigne-framework/commit/bf80c29e10d3fef654c830df8dc7f3b7939fa58d))
9
+
10
+ ## [1.60.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.60.0...core-v1.60.1) (2025-09-11)
11
+
12
+
13
+ ### Dependencies
14
+
15
+ * The following workspace dependencies were updated
16
+ * dependencies
17
+ * @aigne/observability-api bumped to 0.10.4
18
+
3
19
  ## [1.60.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.59.0...core-v1.60.0) (2025-09-10)
4
20
 
5
21
 
@@ -6,8 +6,9 @@ exports.ensureZodUnionArray = ensureZodUnionArray;
6
6
  exports.isZodSchema = isZodSchema;
7
7
  const zod_to_json_schema_1 = require("zod-to-json-schema");
8
8
  const logger_js_1 = require("./logger.js");
9
+ const type_utils_js_1 = require("./type-utils.js");
9
10
  function outputSchemaToResponseFormatSchema(agentOutput) {
10
- return setAdditionPropertiesDeep((0, zod_to_json_schema_1.zodToJsonSchema)(agentOutput), false);
11
+ return convertNullableToOptional(setAdditionPropertiesDeep((0, zod_to_json_schema_1.zodToJsonSchema)(agentOutput), false))[0];
11
12
  }
12
13
  function setAdditionPropertiesDeep(schema, additionalProperties) {
13
14
  if (Array.isArray(schema)) {
@@ -51,3 +52,41 @@ function isZodSchema(schema) {
51
52
  return false;
52
53
  return typeof schema.parse === "function" && typeof schema.safeParse === "function";
53
54
  }
55
+ function convertNullableToOptional(schema) {
56
+ if (!(0, type_utils_js_1.isRecord)(schema))
57
+ return [schema, false];
58
+ if (schema.type === "object" && "properties" in schema && (0, type_utils_js_1.isRecord)(schema.properties)) {
59
+ const optionalProperties = [];
60
+ const properties = Object.fromEntries(Object.entries(schema.properties).map(([key, value]) => {
61
+ const [property, optional] = convertNullableToOptional(value);
62
+ if (optional)
63
+ optionalProperties.push(key);
64
+ return [key, property];
65
+ }));
66
+ const currentRequired = "required" in schema && Array.isArray(schema.required) ? schema.required : [];
67
+ const required = currentRequired.filter((key) => !optionalProperties.includes(key));
68
+ return [{ ...schema, properties, required }, false];
69
+ }
70
+ if (schema.type === "array" && "items" in schema && (0, type_utils_js_1.isRecord)(schema.items)) {
71
+ const [items, _] = convertNullableToOptional(schema.items);
72
+ return [{ ...schema, items }, false];
73
+ }
74
+ if (Array.isArray(schema.type)) {
75
+ if (schema.type.includes("null") && schema.type.length === 2) {
76
+ return [
77
+ {
78
+ ...schema,
79
+ type: schema.type.filter((t) => t !== "null")[0],
80
+ },
81
+ true,
82
+ ];
83
+ }
84
+ }
85
+ if (Array.isArray(schema.anyOf)) {
86
+ const anyOf = schema.anyOf.filter((i) => (0, type_utils_js_1.isRecord)(i) && i.type !== "null" && !("not" in i && (0, type_utils_js_1.isEmpty)(i.not)));
87
+ const optional = anyOf.length !== schema.anyOf.length;
88
+ if (anyOf.length === 1)
89
+ return [convertNullableToOptional(anyOf[0])[0], optional];
90
+ }
91
+ return [schema, false];
92
+ }
@@ -1,7 +1,8 @@
1
1
  import { zodToJsonSchema } from "zod-to-json-schema";
2
2
  import { logger } from "./logger.js";
3
+ import { isEmpty, isRecord } from "./type-utils.js";
3
4
  export function outputSchemaToResponseFormatSchema(agentOutput) {
4
- return setAdditionPropertiesDeep(zodToJsonSchema(agentOutput), false);
5
+ return convertNullableToOptional(setAdditionPropertiesDeep(zodToJsonSchema(agentOutput), false))[0];
5
6
  }
6
7
  function setAdditionPropertiesDeep(schema, additionalProperties) {
7
8
  if (Array.isArray(schema)) {
@@ -45,3 +46,41 @@ export function isZodSchema(schema) {
45
46
  return false;
46
47
  return typeof schema.parse === "function" && typeof schema.safeParse === "function";
47
48
  }
49
+ function convertNullableToOptional(schema) {
50
+ if (!isRecord(schema))
51
+ return [schema, false];
52
+ if (schema.type === "object" && "properties" in schema && isRecord(schema.properties)) {
53
+ const optionalProperties = [];
54
+ const properties = Object.fromEntries(Object.entries(schema.properties).map(([key, value]) => {
55
+ const [property, optional] = convertNullableToOptional(value);
56
+ if (optional)
57
+ optionalProperties.push(key);
58
+ return [key, property];
59
+ }));
60
+ const currentRequired = "required" in schema && Array.isArray(schema.required) ? schema.required : [];
61
+ const required = currentRequired.filter((key) => !optionalProperties.includes(key));
62
+ return [{ ...schema, properties, required }, false];
63
+ }
64
+ if (schema.type === "array" && "items" in schema && isRecord(schema.items)) {
65
+ const [items, _] = convertNullableToOptional(schema.items);
66
+ return [{ ...schema, items }, false];
67
+ }
68
+ if (Array.isArray(schema.type)) {
69
+ if (schema.type.includes("null") && schema.type.length === 2) {
70
+ return [
71
+ {
72
+ ...schema,
73
+ type: schema.type.filter((t) => t !== "null")[0],
74
+ },
75
+ true,
76
+ ];
77
+ }
78
+ }
79
+ if (Array.isArray(schema.anyOf)) {
80
+ const anyOf = schema.anyOf.filter((i) => isRecord(i) && i.type !== "null" && !("not" in i && isEmpty(i.not)));
81
+ const optional = anyOf.length !== schema.anyOf.length;
82
+ if (anyOf.length === 1)
83
+ return [convertNullableToOptional(anyOf[0])[0], optional];
84
+ }
85
+ return [schema, false];
86
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/core",
3
- "version": "1.60.0",
3
+ "version": "1.60.2",
4
4
  "description": "The functional core of agentic AI",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -92,8 +92,8 @@
92
92
  "yaml": "^2.8.0",
93
93
  "zod": "^3.25.67",
94
94
  "zod-to-json-schema": "^3.24.6",
95
- "@aigne/observability-api": "^0.10.3",
96
- "@aigne/platform-helpers": "^0.6.2"
95
+ "@aigne/platform-helpers": "^0.6.2",
96
+ "@aigne/observability-api": "^0.10.4"
97
97
  },
98
98
  "devDependencies": {
99
99
  "@types/bun": "^1.2.18",