@mastra/schema-compat 1.3.6 → 1.3.7
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 +12 -0
- package/dist/index.cjs +60 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +60 -28
- package/dist/index.js.map +1 -1
- package/dist/provider-compats/openai.d.ts.map +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @mastra/schema-compat
|
|
2
2
|
|
|
3
|
+
## 1.3.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Optional nested JSON Schema properties with multiple types no longer produce exponentially large OpenAI tool payloads. Payload growth now remains linear as these schemas become more deeply nested. ([#21190](https://github.com/mastra-ai/mastra/pull/21190))
|
|
8
|
+
|
|
9
|
+
## 1.3.7-alpha.0
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Optional nested JSON Schema properties with multiple types no longer produce exponentially large OpenAI tool payloads. Payload growth now remains linear as these schemas become more deeply nested. ([#21190](https://github.com/mastra-ai/mastra/pull/21190))
|
|
14
|
+
|
|
3
15
|
## 1.3.6
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -5189,36 +5189,48 @@ var OpenAISchemaCompatLayer = class extends SchemaCompatLayer {
|
|
|
5189
5189
|
if (!schema.required?.includes(key)) {
|
|
5190
5190
|
schema["x-optional"] = [...schema["x-optional"] || [], key];
|
|
5191
5191
|
schema.required?.push(key);
|
|
5192
|
-
if (prop.type) {
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
prop.
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5192
|
+
if (Array.isArray(prop.type)) {
|
|
5193
|
+
const types = [...prop.type];
|
|
5194
|
+
if (!types.includes("null")) types.push("null");
|
|
5195
|
+
delete prop.anyOf;
|
|
5196
|
+
delete prop.type;
|
|
5197
|
+
if ("const" in prop) {
|
|
5198
|
+
const constValue = prop.const;
|
|
5199
|
+
prop.enum = !prop.enum || prop.enum.some((value) => JSON.stringify(value) === JSON.stringify(constValue)) ? [constValue, null] : [null];
|
|
5200
|
+
delete prop.const;
|
|
5201
|
+
} else if (prop.enum && !prop.enum.includes(null)) prop.enum = [...prop.enum, null];
|
|
5202
|
+
const objectKeywords = [
|
|
5203
|
+
"properties",
|
|
5204
|
+
"required",
|
|
5205
|
+
"additionalProperties",
|
|
5206
|
+
"x-optional"
|
|
5207
|
+
];
|
|
5208
|
+
const arrayKeywords = ["items"];
|
|
5209
|
+
prop.anyOf = types.map((type) => {
|
|
5210
|
+
if (type === "null") return { type: "null" };
|
|
5211
|
+
const branch = { type };
|
|
5212
|
+
const keywords = type === "object" ? objectKeywords : type === "array" ? arrayKeywords : [];
|
|
5213
|
+
for (const keyword of keywords) if (keyword in prop) branch[keyword] = prop[keyword];
|
|
5214
|
+
return branch;
|
|
5215
|
+
});
|
|
5216
|
+
for (const keyword of [...objectKeywords, ...arrayKeywords]) delete prop[keyword];
|
|
5217
|
+
} else if (prop.type && prop.type !== "null") {
|
|
5218
|
+
const originalType = prop.type;
|
|
5219
|
+
const propSchema = { ...prop };
|
|
5220
|
+
delete propSchema.anyOf;
|
|
5221
|
+
delete propSchema.type;
|
|
5222
|
+
delete prop.type;
|
|
5223
|
+
prop.anyOf = [{
|
|
5224
|
+
...propSchema,
|
|
5225
|
+
type: originalType
|
|
5226
|
+
}, { type: "null" }];
|
|
5215
5227
|
}
|
|
5216
5228
|
}
|
|
5217
5229
|
}
|
|
5218
5230
|
}
|
|
5219
5231
|
}
|
|
5220
5232
|
#traverse(value, schema) {
|
|
5221
|
-
const resolved = this.#resolveAnyOf(schema);
|
|
5233
|
+
const resolved = this.#resolveAnyOf(schema, value);
|
|
5222
5234
|
if ((isDateFormat(resolved) || resolved["x-date"] === true) && typeof value === "string") return new Date(value);
|
|
5223
5235
|
if (resolved.type === "array" || Array.isArray(resolved.type) && resolved.type.includes("array")) {
|
|
5224
5236
|
if (!Array.isArray(value)) return value;
|
|
@@ -5234,13 +5246,33 @@ var OpenAISchemaCompatLayer = class extends SchemaCompatLayer {
|
|
|
5234
5246
|
return obj;
|
|
5235
5247
|
}
|
|
5236
5248
|
/**
|
|
5237
|
-
* If schema has anyOf, return the
|
|
5249
|
+
* If schema has anyOf, return the variant whose type matches the value's shape
|
|
5250
|
+
* (branches are type-specific), falling back to the first non-null variant.
|
|
5238
5251
|
* Otherwise return the schema itself.
|
|
5239
5252
|
*/
|
|
5240
|
-
#resolveAnyOf(schema) {
|
|
5253
|
+
#resolveAnyOf(schema, value) {
|
|
5241
5254
|
if (Array.isArray(schema.anyOf)) {
|
|
5242
|
-
const
|
|
5243
|
-
|
|
5255
|
+
const nonNullVariants = schema.anyOf.filter((s) => s && s.type !== "null");
|
|
5256
|
+
const valueType = Array.isArray(value) ? "array" : value !== null && typeof value === "object" ? "object" : typeof value === "number" ? Number.isInteger(value) ? "integer" : "number" : typeof value === "string" || typeof value === "boolean" ? typeof value : void 0;
|
|
5257
|
+
if (valueType) {
|
|
5258
|
+
const hasType = (variant, type) => (Array.isArray(variant.type) ? variant.type : [variant.type]).includes(type);
|
|
5259
|
+
const exactMatch = nonNullVariants.find((variant) => hasType(variant, valueType));
|
|
5260
|
+
if (exactMatch) return {
|
|
5261
|
+
...schema,
|
|
5262
|
+
...exactMatch
|
|
5263
|
+
};
|
|
5264
|
+
if (valueType === "integer") {
|
|
5265
|
+
const numberMatch = nonNullVariants.find((variant) => hasType(variant, "number"));
|
|
5266
|
+
if (numberMatch) return {
|
|
5267
|
+
...schema,
|
|
5268
|
+
...numberMatch
|
|
5269
|
+
};
|
|
5270
|
+
}
|
|
5271
|
+
}
|
|
5272
|
+
if (nonNullVariants[0]) return {
|
|
5273
|
+
...schema,
|
|
5274
|
+
...nonNullVariants[0]
|
|
5275
|
+
};
|
|
5244
5276
|
}
|
|
5245
5277
|
return schema;
|
|
5246
5278
|
}
|