@mastra/schema-compat 1.0.0-beta.0 → 1.0.0-beta.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 +42 -0
- package/dist/index.cjs +62 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +63 -15
- package/dist/index.js.map +1 -1
- package/dist/json-to-zod.cjs +268 -0
- package/dist/json-to-zod.cjs.map +1 -0
- package/dist/json-to-zod.d.ts +4 -0
- package/dist/json-to-zod.d.ts.map +1 -0
- package/dist/json-to-zod.js +257 -0
- package/dist/json-to-zod.js.map +1 -0
- package/dist/provider-compats/openai-reasoning.d.ts.map +1 -1
- package/dist/provider-compats/openai.d.ts.map +1 -1
- package/dist/schema-compatibility-v3.d.ts +4 -3
- package/dist/schema-compatibility-v3.d.ts.map +1 -1
- package/dist/schema-compatibility-v4.d.ts +7 -3
- package/dist/schema-compatibility-v4.d.ts.map +1 -1
- package/dist/zodTypes.d.ts +2 -0
- package/dist/zodTypes.d.ts.map +1 -1
- package/package.json +16 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @mastra/schema-compat
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fix discriminatedUnion schema information lost when json schema is converted to zod ([#10500](https://github.com/mastra-ai/mastra/pull/10500))
|
|
8
|
+
|
|
9
|
+
## 1.0.0-beta.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Fixed OpenAI schema compatibility when using `agent.generate()` or `agent.stream()` with `structuredOutput`. ([#10366](https://github.com/mastra-ai/mastra/pull/10366))
|
|
14
|
+
|
|
15
|
+
## Changes
|
|
16
|
+
- **Automatic transformation**: Zod schemas are now automatically transformed for OpenAI strict mode compatibility when using OpenAI models (including reasoning models like o1, o3, o4)
|
|
17
|
+
- **Optional field handling**: `.optional()` fields are converted to `.nullable()` with a transform that converts `null` → `undefined`, preserving optional semantics while satisfying OpenAI's strict mode requirements
|
|
18
|
+
- **Preserves nullable fields**: Intentionally `.nullable()` fields remain unchanged
|
|
19
|
+
- **Deep transformation**: Handles `.optional()` fields at any nesting level (objects, arrays, unions, etc.)
|
|
20
|
+
- **JSON Schema objects**: Not transformed, only Zod schemas
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
const agent = new Agent({
|
|
26
|
+
name: 'data-extractor',
|
|
27
|
+
model: { provider: 'openai', modelId: 'gpt-4o' },
|
|
28
|
+
instructions: 'Extract user information',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const schema = z.object({
|
|
32
|
+
name: z.string(),
|
|
33
|
+
age: z.number().optional(),
|
|
34
|
+
deletedAt: z.date().nullable(),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Schema is automatically transformed for OpenAI compatibility
|
|
38
|
+
const result = await agent.generate('Extract: John, deleted yesterday', {
|
|
39
|
+
structuredOutput: { schema },
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Result: { name: 'John', age: undefined, deletedAt: null }
|
|
43
|
+
```
|
|
44
|
+
|
|
3
45
|
## 1.0.0-beta.0
|
|
4
46
|
|
|
5
47
|
### Major Changes
|
package/dist/index.cjs
CHANGED
|
@@ -3646,7 +3646,8 @@ var SUPPORTED_ZOD_TYPES = [
|
|
|
3646
3646
|
"ZodNumber",
|
|
3647
3647
|
"ZodDate",
|
|
3648
3648
|
"ZodAny",
|
|
3649
|
-
"ZodDefault"
|
|
3649
|
+
"ZodDefault",
|
|
3650
|
+
"ZodNullable"
|
|
3650
3651
|
];
|
|
3651
3652
|
var ALL_ZOD_TYPES = [...SUPPORTED_ZOD_TYPES, ...UNSUPPORTED_ZOD_TYPES];
|
|
3652
3653
|
var SchemaCompatLayer = class {
|
|
@@ -4063,7 +4064,8 @@ var SUPPORTED_ZOD_TYPES2 = [
|
|
|
4063
4064
|
"ZodNumber",
|
|
4064
4065
|
"ZodDate",
|
|
4065
4066
|
"ZodAny",
|
|
4066
|
-
"ZodDefault"
|
|
4067
|
+
"ZodDefault",
|
|
4068
|
+
"ZodNullable"
|
|
4067
4069
|
];
|
|
4068
4070
|
var SchemaCompatLayer2 = class {
|
|
4069
4071
|
model;
|
|
@@ -4106,6 +4108,12 @@ var SchemaCompatLayer2 = class {
|
|
|
4106
4108
|
isNull(v) {
|
|
4107
4109
|
return v instanceof v4.ZodNull;
|
|
4108
4110
|
}
|
|
4111
|
+
/**
|
|
4112
|
+
* Type guard for nullable Zod types
|
|
4113
|
+
*/
|
|
4114
|
+
isNullable(v) {
|
|
4115
|
+
return v instanceof v4.ZodNullable;
|
|
4116
|
+
}
|
|
4109
4117
|
/**
|
|
4110
4118
|
* Type guard for array Zod types
|
|
4111
4119
|
*/
|
|
@@ -4699,6 +4707,9 @@ function isDate(z11) {
|
|
|
4699
4707
|
function isDefault(z11) {
|
|
4700
4708
|
return (v) => v instanceof z11["ZodDefault"];
|
|
4701
4709
|
}
|
|
4710
|
+
function isNullable(z11) {
|
|
4711
|
+
return (v) => v instanceof z11["ZodNullable"];
|
|
4712
|
+
}
|
|
4702
4713
|
|
|
4703
4714
|
// src/provider-compats/anthropic.ts
|
|
4704
4715
|
var AnthropicSchemaCompatLayer = class extends SchemaCompatLayer3 {
|
|
@@ -4839,15 +4850,30 @@ var OpenAISchemaCompatLayer = class extends SchemaCompatLayer3 {
|
|
|
4839
4850
|
}
|
|
4840
4851
|
processZodType(value) {
|
|
4841
4852
|
if (isOptional2(zod.z)(value)) {
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4853
|
+
const innerType = "_def" in value ? value._def.innerType : value._zod?.def?.innerType;
|
|
4854
|
+
if (innerType) {
|
|
4855
|
+
if (isNullable(zod.z)(innerType)) {
|
|
4856
|
+
const processed = this.processZodType(innerType);
|
|
4857
|
+
return processed.transform((val) => val === null ? void 0 : val);
|
|
4858
|
+
}
|
|
4859
|
+
const processedInner = this.processZodType(innerType);
|
|
4860
|
+
return processedInner.nullable().transform((val) => val === null ? void 0 : val);
|
|
4861
|
+
}
|
|
4862
|
+
return value;
|
|
4863
|
+
} else if (isNullable(zod.z)(value)) {
|
|
4864
|
+
const innerType = "_def" in value ? value._def.innerType : value._zod?.def?.innerType;
|
|
4865
|
+
if (innerType) {
|
|
4866
|
+
if (isOptional2(zod.z)(innerType)) {
|
|
4867
|
+
const innerInnerType = "_def" in innerType ? innerType._def.innerType : innerType._zod?.def?.innerType;
|
|
4868
|
+
if (innerInnerType) {
|
|
4869
|
+
const processedInnerInner = this.processZodType(innerInnerType);
|
|
4870
|
+
return processedInnerInner.nullable().transform((val) => val === null ? void 0 : val);
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4873
|
+
const processedInner = this.processZodType(innerType);
|
|
4874
|
+
return processedInner.nullable();
|
|
4875
|
+
}
|
|
4876
|
+
return value;
|
|
4851
4877
|
} else if (isObj2(zod.z)(value)) {
|
|
4852
4878
|
return this.defaultZodObjectHandler(value);
|
|
4853
4879
|
} else if (isUnion2(zod.z)(value)) {
|
|
@@ -4880,15 +4906,37 @@ var OpenAIReasoningSchemaCompatLayer = class extends SchemaCompatLayer3 {
|
|
|
4880
4906
|
return this.getModel().modelId.includes(`o3`) || this.getModel().modelId.includes(`o4`) || this.getModel().modelId.includes(`o1`);
|
|
4881
4907
|
}
|
|
4882
4908
|
shouldApply() {
|
|
4883
|
-
if (
|
|
4909
|
+
if (this.isReasoningModel() && (this.getModel().provider.includes(`openai`) || this.getModel().modelId.includes(`openai`))) {
|
|
4884
4910
|
return true;
|
|
4885
4911
|
}
|
|
4886
4912
|
return false;
|
|
4887
4913
|
}
|
|
4888
4914
|
processZodType(value) {
|
|
4889
4915
|
if (isOptional2(zod.z)(value)) {
|
|
4890
|
-
const
|
|
4891
|
-
|
|
4916
|
+
const innerType = "_def" in value ? value._def.innerType : value._zod?.def?.innerType;
|
|
4917
|
+
if (innerType) {
|
|
4918
|
+
if (isNullable(zod.z)(innerType)) {
|
|
4919
|
+
const processed = this.processZodType(innerType);
|
|
4920
|
+
return processed.transform((val) => val === null ? void 0 : val);
|
|
4921
|
+
}
|
|
4922
|
+
const processedInner = this.processZodType(innerType);
|
|
4923
|
+
return processedInner.nullable().transform((val) => val === null ? void 0 : val);
|
|
4924
|
+
}
|
|
4925
|
+
return value;
|
|
4926
|
+
} else if (isNullable(zod.z)(value)) {
|
|
4927
|
+
const innerType = "_def" in value ? value._def.innerType : value._zod?.def?.innerType;
|
|
4928
|
+
if (innerType && isOptional2(zod.z)(innerType)) {
|
|
4929
|
+
const innerInnerType = "_def" in innerType ? innerType._def.innerType : innerType._zod?.def?.innerType;
|
|
4930
|
+
if (innerInnerType) {
|
|
4931
|
+
const processedInnerInner = this.processZodType(innerInnerType);
|
|
4932
|
+
return processedInnerInner.nullable().transform((val) => val === null ? void 0 : val);
|
|
4933
|
+
}
|
|
4934
|
+
}
|
|
4935
|
+
if (innerType) {
|
|
4936
|
+
const processedInner = this.processZodType(innerType);
|
|
4937
|
+
return processedInner.nullable();
|
|
4938
|
+
}
|
|
4939
|
+
return value;
|
|
4892
4940
|
} else if (isObj2(zod.z)(value)) {
|
|
4893
4941
|
return this.defaultZodObjectHandler(value, { passthrough: false });
|
|
4894
4942
|
} else if (isArr2(zod.z)(value)) {
|