@mastra/schema-compat 0.10.6-alpha.0 → 0.10.6-alpha.1
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +41 -0
- package/README.md +0 -4
- package/dist/chunk-FTKGHMGD.js +27 -0
- package/dist/chunk-FTKGHMGD.js.map +1 -0
- package/dist/chunk-LNR4XKDU.cjs +33 -0
- package/dist/chunk-LNR4XKDU.cjs.map +1 -0
- package/dist/index.cjs +843 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +842 -85
- package/dist/index.js.map +1 -1
- package/dist/provider-compats/anthropic.d.ts +7 -5
- package/dist/provider-compats/anthropic.d.ts.map +1 -1
- package/dist/provider-compats/deepseek.d.ts +7 -5
- package/dist/provider-compats/deepseek.d.ts.map +1 -1
- package/dist/provider-compats/google.d.ts +7 -5
- package/dist/provider-compats/google.d.ts.map +1 -1
- package/dist/provider-compats/meta.d.ts +7 -5
- package/dist/provider-compats/meta.d.ts.map +1 -1
- package/dist/provider-compats/openai-reasoning.d.ts +7 -5
- package/dist/provider-compats/openai-reasoning.d.ts.map +1 -1
- package/dist/provider-compats/openai.d.ts +7 -5
- package/dist/provider-compats/openai.d.ts.map +1 -1
- package/dist/schema-compatibility-v3.d.ts +319 -0
- package/dist/schema-compatibility-v3.d.ts.map +1 -0
- package/dist/schema-compatibility-v4.d.ts +310 -0
- package/dist/schema-compatibility-v4.d.ts.map +1 -0
- package/dist/schema-compatibility.d.ts +79 -131
- package/dist/schema-compatibility.d.ts.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils-test-suite.d.ts +2 -0
- package/dist/utils-test-suite.d.ts.map +1 -0
- package/dist/utils.d.ts +17 -5
- package/dist/utils.d.ts.map +1 -1
- package/dist/zod-to-json.cjs +12 -0
- package/dist/zod-to-json.cjs.map +1 -0
- package/dist/zod-to-json.d.ts +6 -0
- package/dist/zod-to-json.d.ts.map +1 -0
- package/dist/zod-to-json.js +3 -0
- package/dist/zod-to-json.js.map +1 -0
- package/dist/zodTypes.d.ts +21 -0
- package/dist/zodTypes.d.ts.map +1 -0
- package/package.json +16 -6
- package/src/index.ts +4 -3
- package/src/provider-compats/anthropic.ts +30 -13
- package/src/provider-compats/deepseek.ts +15 -10
- package/src/provider-compats/google.ts +19 -33
- package/src/provider-compats/meta.ts +16 -11
- package/src/provider-compats/openai-reasoning.ts +24 -26
- package/src/provider-compats/openai.ts +23 -14
- package/src/provider-compats.test.ts +120 -25
- package/src/schema-compatibility-v3.ts +664 -0
- package/src/schema-compatibility-v4.test.ts +476 -0
- package/src/schema-compatibility-v4.ts +706 -0
- package/src/schema-compatibility.test.ts +9 -9
- package/src/schema-compatibility.ts +266 -383
- package/src/types.ts +5 -0
- package/src/utils-test-suite.ts +467 -0
- package/src/utils-v3.test.ts +9 -0
- package/src/utils-v4.test.ts +9 -0
- package/src/utils.ts +30 -24
- package/src/zod-to-json.ts +27 -0
- package/src/zodTypes.ts +56 -0
- package/tsup.config.ts +8 -3
- package/src/utils.test.ts +0 -434
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ZodType as ZodTypeV3 } from 'zod/v3';
|
|
3
|
+
import type { ZodType as ZodTypeV4 } from 'zod/v4';
|
|
3
4
|
import type { Targets } from 'zod-to-json-schema';
|
|
4
|
-
import { SchemaCompatLayer
|
|
5
|
+
import { SchemaCompatLayer } from '../schema-compatibility';
|
|
6
|
+
import type { ModelInformation } from '../types';
|
|
7
|
+
import { isOptional, isObj, isArr, isUnion, isString } from '../zodTypes';
|
|
5
8
|
|
|
6
9
|
export class DeepSeekSchemaCompatLayer extends SchemaCompatLayer {
|
|
7
|
-
constructor(model:
|
|
10
|
+
constructor(model: ModelInformation) {
|
|
8
11
|
super(model);
|
|
9
12
|
}
|
|
10
13
|
|
|
@@ -17,16 +20,18 @@ export class DeepSeekSchemaCompatLayer extends SchemaCompatLayer {
|
|
|
17
20
|
return this.getModel().modelId.includes('deepseek') && !this.getModel().modelId.includes('r1');
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
processZodType(value:
|
|
21
|
-
|
|
23
|
+
processZodType(value: ZodTypeV3): ZodTypeV3;
|
|
24
|
+
processZodType(value: ZodTypeV4): ZodTypeV4;
|
|
25
|
+
processZodType(value: ZodTypeV3 | ZodTypeV4): ZodTypeV3 | ZodTypeV4 {
|
|
26
|
+
if (isOptional(z)(value)) {
|
|
22
27
|
return this.defaultZodOptionalHandler(value, ['ZodObject', 'ZodArray', 'ZodUnion', 'ZodString', 'ZodNumber']);
|
|
23
|
-
} else if (isObj(value)) {
|
|
28
|
+
} else if (isObj(z)(value)) {
|
|
24
29
|
return this.defaultZodObjectHandler(value);
|
|
25
|
-
} else if (isArr(value)) {
|
|
30
|
+
} else if (isArr(z)(value)) {
|
|
26
31
|
return this.defaultZodArrayHandler(value, ['min', 'max']);
|
|
27
|
-
} else if (isUnion(value)) {
|
|
32
|
+
} else if (isUnion(z)(value)) {
|
|
28
33
|
return this.defaultZodUnionHandler(value);
|
|
29
|
-
} else if (isString(value)) {
|
|
34
|
+
} else if (isString(z)(value)) {
|
|
30
35
|
return this.defaultZodStringHandler(value);
|
|
31
36
|
}
|
|
32
37
|
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import type { LanguageModelV1 } from 'ai';
|
|
2
|
-
import type { ZodTypeAny } from 'zod';
|
|
3
1
|
import { z } from 'zod';
|
|
2
|
+
import type { ZodType as ZodTypeV3, ZodObject as ZodObjectV3 } from 'zod/v3';
|
|
3
|
+
import type { ZodType as ZodTypeV4, ZodObject as ZodObjectV4 } from 'zod/v4';
|
|
4
4
|
import type { Targets } from 'zod-to-json-schema';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
isArr,
|
|
9
|
-
isNull,
|
|
10
|
-
isNumber,
|
|
11
|
-
isObj,
|
|
12
|
-
isOptional,
|
|
13
|
-
isString,
|
|
14
|
-
isUnion,
|
|
15
|
-
} from '../schema-compatibility';
|
|
5
|
+
import { SchemaCompatLayer } from '../schema-compatibility';
|
|
6
|
+
import type { ModelInformation } from '../types';
|
|
7
|
+
import { isOptional, isNull, isObj, isArr, isUnion, isString, isNumber } from '../zodTypes';
|
|
16
8
|
|
|
17
9
|
export class GoogleSchemaCompatLayer extends SchemaCompatLayer {
|
|
18
|
-
constructor(model:
|
|
10
|
+
constructor(model: ModelInformation) {
|
|
19
11
|
super(model);
|
|
20
12
|
}
|
|
21
13
|
|
|
@@ -26,38 +18,32 @@ export class GoogleSchemaCompatLayer extends SchemaCompatLayer {
|
|
|
26
18
|
shouldApply(): boolean {
|
|
27
19
|
return this.getModel().provider.includes('google') || this.getModel().modelId.includes('google');
|
|
28
20
|
}
|
|
29
|
-
|
|
30
|
-
processZodType(value:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
'ZodUnion',
|
|
36
|
-
'ZodString',
|
|
37
|
-
'ZodNumber',
|
|
38
|
-
...UNSUPPORTED_ZOD_TYPES,
|
|
39
|
-
]);
|
|
40
|
-
} else if (isNull(value)) {
|
|
21
|
+
processZodType(value: ZodTypeV3): ZodTypeV3;
|
|
22
|
+
processZodType(value: ZodTypeV4): ZodTypeV4;
|
|
23
|
+
processZodType(value: ZodTypeV3 | ZodTypeV4): ZodTypeV3 | ZodTypeV4 {
|
|
24
|
+
if (isOptional(z)(value)) {
|
|
25
|
+
return this.defaultZodOptionalHandler(value, ['ZodObject', 'ZodArray', 'ZodUnion', 'ZodString', 'ZodNumber']);
|
|
26
|
+
} else if (isNull(z)(value)) {
|
|
41
27
|
// Google models don't support null, so we need to convert it to any and then refine it to null
|
|
42
28
|
return z
|
|
43
29
|
.any()
|
|
44
30
|
.refine(v => v === null, { message: 'must be null' })
|
|
45
|
-
.describe(value.
|
|
46
|
-
} else if (isObj(value)) {
|
|
31
|
+
.describe(value.description || 'must be null');
|
|
32
|
+
} else if (isObj(z)(value)) {
|
|
47
33
|
return this.defaultZodObjectHandler(value);
|
|
48
|
-
} else if (isArr(value)) {
|
|
34
|
+
} else if (isArr(z)(value)) {
|
|
49
35
|
return this.defaultZodArrayHandler(value, []);
|
|
50
|
-
} else if (isUnion(value)) {
|
|
36
|
+
} else if (isUnion(z)(value)) {
|
|
51
37
|
return this.defaultZodUnionHandler(value);
|
|
52
|
-
} else if (isString(value)) {
|
|
38
|
+
} else if (isString(z)(value)) {
|
|
53
39
|
// Google models support these properties but the model doesn't respect them, but it respects them when they're
|
|
54
40
|
// added to the tool description
|
|
55
41
|
return this.defaultZodStringHandler(value);
|
|
56
|
-
} else if (isNumber(value)) {
|
|
42
|
+
} else if (isNumber(z)(value)) {
|
|
57
43
|
// Google models support these properties but the model doesn't respect them, but it respects them when they're
|
|
58
44
|
// added to the tool description
|
|
59
45
|
return this.defaultZodNumberHandler(value);
|
|
60
46
|
}
|
|
61
|
-
return this.defaultUnsupportedZodTypeHandler(value);
|
|
47
|
+
return this.defaultUnsupportedZodTypeHandler(value as ZodObjectV4<any> | ZodObjectV3<any>);
|
|
62
48
|
}
|
|
63
49
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ZodType as ZodTypeV3 } from 'zod/v3';
|
|
3
|
+
import type { ZodType as ZodTypeV4 } from 'zod/v4';
|
|
3
4
|
import type { Targets } from 'zod-to-json-schema';
|
|
4
|
-
import { SchemaCompatLayer
|
|
5
|
+
import { SchemaCompatLayer } from '../schema-compatibility';
|
|
6
|
+
import type { ModelInformation } from '../types';
|
|
7
|
+
import { isOptional, isObj, isArr, isUnion, isNumber, isString } from '../zodTypes';
|
|
5
8
|
|
|
6
9
|
export class MetaSchemaCompatLayer extends SchemaCompatLayer {
|
|
7
|
-
constructor(model:
|
|
10
|
+
constructor(model: ModelInformation) {
|
|
8
11
|
super(model);
|
|
9
12
|
}
|
|
10
13
|
|
|
@@ -16,18 +19,20 @@ export class MetaSchemaCompatLayer extends SchemaCompatLayer {
|
|
|
16
19
|
return this.getModel().modelId.includes('meta');
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
processZodType(value:
|
|
20
|
-
|
|
22
|
+
processZodType(value: ZodTypeV3): ZodTypeV3;
|
|
23
|
+
processZodType(value: ZodTypeV4): ZodTypeV4;
|
|
24
|
+
processZodType(value: ZodTypeV3 | ZodTypeV4): ZodTypeV3 | ZodTypeV4 {
|
|
25
|
+
if (isOptional(z)(value)) {
|
|
21
26
|
return this.defaultZodOptionalHandler(value, ['ZodObject', 'ZodArray', 'ZodUnion', 'ZodString', 'ZodNumber']);
|
|
22
|
-
} else if (isObj(value)) {
|
|
27
|
+
} else if (isObj(z)(value)) {
|
|
23
28
|
return this.defaultZodObjectHandler(value);
|
|
24
|
-
} else if (isArr(value)) {
|
|
29
|
+
} else if (isArr(z)(value)) {
|
|
25
30
|
return this.defaultZodArrayHandler(value, ['min', 'max']);
|
|
26
|
-
} else if (isUnion(value)) {
|
|
31
|
+
} else if (isUnion(z)(value)) {
|
|
27
32
|
return this.defaultZodUnionHandler(value);
|
|
28
|
-
} else if (isNumber(value)) {
|
|
33
|
+
} else if (isNumber(z)(value)) {
|
|
29
34
|
return this.defaultZodNumberHandler(value);
|
|
30
|
-
} else if (isString(value)) {
|
|
35
|
+
} else if (isString(z)(value)) {
|
|
31
36
|
return this.defaultZodStringHandler(value);
|
|
32
37
|
}
|
|
33
38
|
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import type { LanguageModelV1 } from 'ai';
|
|
2
1
|
import { z } from 'zod';
|
|
3
|
-
import type {
|
|
2
|
+
import type { ZodType as ZodTypeV3, ZodObject as ZodObjectV3 } from 'zod/v3';
|
|
3
|
+
import type { ZodType as ZodTypeV4, ZodObject as ZodObjectV4 } from 'zod/v4';
|
|
4
4
|
import type { Targets } from 'zod-to-json-schema';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
isDate,
|
|
9
|
-
isDefault,
|
|
10
|
-
isNumber,
|
|
11
|
-
isObj,
|
|
12
|
-
isOptional,
|
|
13
|
-
isString,
|
|
14
|
-
isUnion,
|
|
15
|
-
} from '../schema-compatibility';
|
|
5
|
+
import { SchemaCompatLayer } from '../schema-compatibility';
|
|
6
|
+
import type { ModelInformation } from '../types';
|
|
7
|
+
import { isOptional, isObj, isArr, isUnion, isDefault, isNumber, isString, isDate } from '../zodTypes';
|
|
16
8
|
|
|
17
9
|
export class OpenAIReasoningSchemaCompatLayer extends SchemaCompatLayer {
|
|
18
|
-
constructor(model:
|
|
10
|
+
constructor(model: ModelInformation) {
|
|
19
11
|
super(model);
|
|
20
12
|
}
|
|
21
13
|
|
|
@@ -26,7 +18,11 @@ export class OpenAIReasoningSchemaCompatLayer extends SchemaCompatLayer {
|
|
|
26
18
|
isReasoningModel(): boolean {
|
|
27
19
|
// there isn't a good way to automatically detect reasoning models besides doing this.
|
|
28
20
|
// in the future when o5 is released this compat wont apply and we'll want to come back and update this class + our tests
|
|
29
|
-
return
|
|
21
|
+
return (
|
|
22
|
+
this.getModel().modelId.includes(`o3`) ||
|
|
23
|
+
this.getModel().modelId.includes(`o4`) ||
|
|
24
|
+
this.getModel().modelId.includes(`o1`)
|
|
25
|
+
);
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
shouldApply(): boolean {
|
|
@@ -40,17 +36,19 @@ export class OpenAIReasoningSchemaCompatLayer extends SchemaCompatLayer {
|
|
|
40
36
|
return false;
|
|
41
37
|
}
|
|
42
38
|
|
|
43
|
-
processZodType(value:
|
|
44
|
-
|
|
39
|
+
processZodType(value: ZodTypeV3): ZodTypeV3;
|
|
40
|
+
processZodType(value: ZodTypeV4): ZodTypeV4;
|
|
41
|
+
processZodType(value: ZodTypeV3 | ZodTypeV4): ZodTypeV3 | ZodTypeV4 {
|
|
42
|
+
if (isOptional(z)(value)) {
|
|
45
43
|
const innerZodType = this.processZodType(value._def.innerType);
|
|
46
44
|
return innerZodType.nullable();
|
|
47
|
-
} else if (isObj(value)) {
|
|
45
|
+
} else if (isObj(z)(value)) {
|
|
48
46
|
return this.defaultZodObjectHandler(value, { passthrough: false });
|
|
49
|
-
} else if (isArr(value)) {
|
|
47
|
+
} else if (isArr(z)(value)) {
|
|
50
48
|
return this.defaultZodArrayHandler(value);
|
|
51
|
-
} else if (isUnion(value)) {
|
|
49
|
+
} else if (isUnion(z)(value)) {
|
|
52
50
|
return this.defaultZodUnionHandler(value);
|
|
53
|
-
} else if (isDefault(value)) {
|
|
51
|
+
} else if (isDefault(z)(value)) {
|
|
54
52
|
const defaultDef = value._def;
|
|
55
53
|
const innerType = defaultDef.innerType;
|
|
56
54
|
const defaultValue = defaultDef.defaultValue();
|
|
@@ -65,13 +63,13 @@ export class OpenAIReasoningSchemaCompatLayer extends SchemaCompatLayer {
|
|
|
65
63
|
result = result.describe(description);
|
|
66
64
|
}
|
|
67
65
|
return result;
|
|
68
|
-
} else if (isNumber(value)) {
|
|
66
|
+
} else if (isNumber(z)(value)) {
|
|
69
67
|
return this.defaultZodNumberHandler(value);
|
|
70
|
-
} else if (isString(value)) {
|
|
68
|
+
} else if (isString(z)(value)) {
|
|
71
69
|
return this.defaultZodStringHandler(value);
|
|
72
|
-
} else if (isDate(value)) {
|
|
70
|
+
} else if (isDate(z)(value)) {
|
|
73
71
|
return this.defaultZodDateHandler(value);
|
|
74
|
-
} else if (value.
|
|
72
|
+
} else if (value.constructor.name === 'ZodAny') {
|
|
75
73
|
// It's bad practice in the tool to use any, it's not reasonable for models that don't support that OOTB, to cast every single possible type
|
|
76
74
|
// in the schema. Usually when it's "any" it could be a json object or a union of specific types.
|
|
77
75
|
return z
|
|
@@ -82,6 +80,6 @@ export class OpenAIReasoningSchemaCompatLayer extends SchemaCompatLayer {
|
|
|
82
80
|
);
|
|
83
81
|
}
|
|
84
82
|
|
|
85
|
-
return this.defaultUnsupportedZodTypeHandler(value);
|
|
83
|
+
return this.defaultUnsupportedZodTypeHandler(value as ZodObjectV4<any> | ZodObjectV3<any>);
|
|
86
84
|
}
|
|
87
85
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ZodType as ZodTypeV3, ZodObject as ZodObjectV3 } from 'zod/v3';
|
|
3
|
+
import type { ZodType as ZodTypeV4, ZodObject as ZodObjectV4 } from 'zod/v4';
|
|
3
4
|
import type { Targets } from 'zod-to-json-schema';
|
|
4
|
-
import { SchemaCompatLayer
|
|
5
|
-
import type {
|
|
5
|
+
import { SchemaCompatLayer } from '../schema-compatibility';
|
|
6
|
+
import type { ModelInformation } from '../types';
|
|
7
|
+
import { isOptional, isObj, isUnion, isArr, isString } from '../zodTypes';
|
|
6
8
|
|
|
7
9
|
export class OpenAISchemaCompatLayer extends SchemaCompatLayer {
|
|
8
|
-
constructor(model:
|
|
10
|
+
constructor(model: ModelInformation) {
|
|
9
11
|
super(model);
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -24,8 +26,10 @@ export class OpenAISchemaCompatLayer extends SchemaCompatLayer {
|
|
|
24
26
|
return false;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
processZodType(value:
|
|
28
|
-
|
|
29
|
+
processZodType(value: ZodTypeV3): ZodTypeV3;
|
|
30
|
+
processZodType(value: ZodTypeV4): ZodTypeV4;
|
|
31
|
+
processZodType(value: ZodTypeV3 | ZodTypeV4): ZodTypeV3 | ZodTypeV4 {
|
|
32
|
+
if (isOptional(z)(value)) {
|
|
29
33
|
return this.defaultZodOptionalHandler(value, [
|
|
30
34
|
'ZodObject',
|
|
31
35
|
'ZodArray',
|
|
@@ -35,22 +39,27 @@ export class OpenAISchemaCompatLayer extends SchemaCompatLayer {
|
|
|
35
39
|
'ZodUndefined',
|
|
36
40
|
'ZodTuple',
|
|
37
41
|
]);
|
|
38
|
-
} else if (isObj(value)) {
|
|
42
|
+
} else if (isObj(z)(value)) {
|
|
39
43
|
return this.defaultZodObjectHandler(value);
|
|
40
|
-
} else if (isUnion(value)) {
|
|
44
|
+
} else if (isUnion(z)(value)) {
|
|
41
45
|
return this.defaultZodUnionHandler(value);
|
|
42
|
-
} else if (isArr(value)) {
|
|
46
|
+
} else if (isArr(z)(value)) {
|
|
43
47
|
return this.defaultZodArrayHandler(value);
|
|
44
|
-
} else if (isString(value)) {
|
|
48
|
+
} else if (isString(z)(value)) {
|
|
45
49
|
const model = this.getModel();
|
|
46
|
-
const checks
|
|
50
|
+
const checks = ['emoji'] as const;
|
|
47
51
|
|
|
48
52
|
if (model.modelId.includes('gpt-4o-mini')) {
|
|
49
|
-
|
|
53
|
+
return this.defaultZodStringHandler(value, ['emoji', 'regex']);
|
|
50
54
|
}
|
|
55
|
+
|
|
51
56
|
return this.defaultZodStringHandler(value, checks);
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
return this.defaultUnsupportedZodTypeHandler(value
|
|
59
|
+
return this.defaultUnsupportedZodTypeHandler(value as ZodObjectV4<any> | ZodObjectV3<any>, [
|
|
60
|
+
'ZodNever',
|
|
61
|
+
'ZodUndefined',
|
|
62
|
+
'ZodTuple',
|
|
63
|
+
]);
|
|
55
64
|
}
|
|
56
65
|
}
|
|
@@ -40,22 +40,38 @@ describe('Provider Compatibility Classes', () => {
|
|
|
40
40
|
|
|
41
41
|
describe('AnthropicSchemaCompatLayer', () => {
|
|
42
42
|
it('should apply for Anthropic models', () => {
|
|
43
|
-
const compat = new AnthropicSchemaCompatLayer(
|
|
43
|
+
const compat = new AnthropicSchemaCompatLayer({
|
|
44
|
+
modelId: mockModels.anthropic.modelId,
|
|
45
|
+
supportsStructuredOutputs: mockModels.anthropic.supportsStructuredOutputs ?? false,
|
|
46
|
+
provider: mockModels.anthropic.provider,
|
|
47
|
+
});
|
|
44
48
|
expect(compat.shouldApply()).toBe(true);
|
|
45
49
|
});
|
|
46
50
|
|
|
47
51
|
it('should not apply for non-Anthropic models', () => {
|
|
48
|
-
const compat = new AnthropicSchemaCompatLayer(
|
|
52
|
+
const compat = new AnthropicSchemaCompatLayer({
|
|
53
|
+
modelId: mockModels.openai.modelId,
|
|
54
|
+
supportsStructuredOutputs: mockModels.openai.supportsStructuredOutputs ?? false,
|
|
55
|
+
provider: mockModels.openai.provider,
|
|
56
|
+
});
|
|
49
57
|
expect(compat.shouldApply()).toBe(false);
|
|
50
58
|
});
|
|
51
59
|
|
|
52
60
|
it('should return correct schema target', () => {
|
|
53
|
-
const compat = new AnthropicSchemaCompatLayer(
|
|
61
|
+
const compat = new AnthropicSchemaCompatLayer({
|
|
62
|
+
modelId: mockModels.anthropic.modelId,
|
|
63
|
+
supportsStructuredOutputs: mockModels.anthropic.supportsStructuredOutputs ?? false,
|
|
64
|
+
provider: mockModels.anthropic.provider,
|
|
65
|
+
});
|
|
54
66
|
expect(compat.getSchemaTarget()).toBe('jsonSchema7');
|
|
55
67
|
});
|
|
56
68
|
|
|
57
69
|
it('should process schemas correctly', () => {
|
|
58
|
-
const compat = new AnthropicSchemaCompatLayer(
|
|
70
|
+
const compat = new AnthropicSchemaCompatLayer({
|
|
71
|
+
modelId: mockModels.anthropic.modelId,
|
|
72
|
+
supportsStructuredOutputs: mockModels.anthropic.supportsStructuredOutputs ?? false,
|
|
73
|
+
provider: mockModels.anthropic.provider,
|
|
74
|
+
});
|
|
59
75
|
const schema = z.object({
|
|
60
76
|
text: z.string().min(1).max(100),
|
|
61
77
|
count: z.number().min(1),
|
|
@@ -79,17 +95,29 @@ describe('Provider Compatibility Classes', () => {
|
|
|
79
95
|
|
|
80
96
|
describe('OpenAISchemaCompatLayer', () => {
|
|
81
97
|
it('should apply for OpenAI models without structured outputs support', () => {
|
|
82
|
-
const compat = new OpenAISchemaCompatLayer(
|
|
98
|
+
const compat = new OpenAISchemaCompatLayer({
|
|
99
|
+
modelId: mockModels.openai.modelId,
|
|
100
|
+
supportsStructuredOutputs: mockModels.openai.supportsStructuredOutputs ?? false,
|
|
101
|
+
provider: mockModels.openai.provider,
|
|
102
|
+
});
|
|
83
103
|
expect(compat.shouldApply()).toBe(true);
|
|
84
104
|
});
|
|
85
105
|
|
|
86
106
|
it('should return correct schema target', () => {
|
|
87
|
-
const compat = new OpenAISchemaCompatLayer(
|
|
107
|
+
const compat = new OpenAISchemaCompatLayer({
|
|
108
|
+
modelId: mockModels.openai.modelId,
|
|
109
|
+
supportsStructuredOutputs: mockModels.openai.supportsStructuredOutputs ?? false,
|
|
110
|
+
provider: mockModels.openai.provider,
|
|
111
|
+
});
|
|
88
112
|
expect(compat.getSchemaTarget()).toBe('jsonSchema7');
|
|
89
113
|
});
|
|
90
114
|
|
|
91
115
|
it('should process complex schemas', () => {
|
|
92
|
-
const compat = new OpenAISchemaCompatLayer(
|
|
116
|
+
const compat = new OpenAISchemaCompatLayer({
|
|
117
|
+
modelId: mockModels.openai.modelId,
|
|
118
|
+
supportsStructuredOutputs: mockModels.openai.supportsStructuredOutputs ?? false,
|
|
119
|
+
provider: mockModels.openai.provider,
|
|
120
|
+
});
|
|
93
121
|
const schema = z.object({
|
|
94
122
|
user: z.object({
|
|
95
123
|
name: z.string().email(),
|
|
@@ -122,29 +150,49 @@ describe('Provider Compatibility Classes', () => {
|
|
|
122
150
|
|
|
123
151
|
describe('OpenAIReasoningSchemaCompatLayer', () => {
|
|
124
152
|
it('should have consistent behavior', () => {
|
|
125
|
-
const compat = new OpenAIReasoningSchemaCompatLayer(
|
|
153
|
+
const compat = new OpenAIReasoningSchemaCompatLayer({
|
|
154
|
+
modelId: mockModels.openaiReasoning.modelId,
|
|
155
|
+
supportsStructuredOutputs: mockModels.openaiReasoning.supportsStructuredOutputs ?? false,
|
|
156
|
+
provider: mockModels.openaiReasoning.provider,
|
|
157
|
+
});
|
|
126
158
|
expect(compat.shouldApply()).toBe(true);
|
|
127
159
|
});
|
|
128
160
|
|
|
129
161
|
it('should return correct schema target', () => {
|
|
130
|
-
const compat = new OpenAIReasoningSchemaCompatLayer(
|
|
162
|
+
const compat = new OpenAIReasoningSchemaCompatLayer({
|
|
163
|
+
modelId: mockModels.openaiReasoning.modelId,
|
|
164
|
+
supportsStructuredOutputs: mockModels.openaiReasoning.supportsStructuredOutputs ?? false,
|
|
165
|
+
provider: mockModels.openaiReasoning.provider,
|
|
166
|
+
});
|
|
131
167
|
expect(compat.getSchemaTarget()).toBe('openApi3');
|
|
132
168
|
});
|
|
133
169
|
});
|
|
134
170
|
|
|
135
171
|
describe('GoogleSchemaCompatLayer', () => {
|
|
136
172
|
it('should have consistent behavior', () => {
|
|
137
|
-
const compat = new GoogleSchemaCompatLayer(
|
|
173
|
+
const compat = new GoogleSchemaCompatLayer({
|
|
174
|
+
modelId: mockModels.google.modelId,
|
|
175
|
+
supportsStructuredOutputs: mockModels.google.supportsStructuredOutputs ?? false,
|
|
176
|
+
provider: mockModels.google.provider,
|
|
177
|
+
});
|
|
138
178
|
expect(typeof compat.shouldApply()).toBe('boolean');
|
|
139
179
|
});
|
|
140
180
|
|
|
141
181
|
it('should return correct schema target', () => {
|
|
142
|
-
const compat = new GoogleSchemaCompatLayer(
|
|
182
|
+
const compat = new GoogleSchemaCompatLayer({
|
|
183
|
+
modelId: mockModels.google.modelId,
|
|
184
|
+
supportsStructuredOutputs: mockModels.google.supportsStructuredOutputs ?? false,
|
|
185
|
+
provider: mockModels.google.provider,
|
|
186
|
+
});
|
|
143
187
|
expect(compat.getSchemaTarget()).toBe('jsonSchema7');
|
|
144
188
|
});
|
|
145
189
|
|
|
146
190
|
it('should handle date types correctly', () => {
|
|
147
|
-
const compat = new GoogleSchemaCompatLayer(
|
|
191
|
+
const compat = new GoogleSchemaCompatLayer({
|
|
192
|
+
modelId: mockModels.google.modelId,
|
|
193
|
+
supportsStructuredOutputs: mockModels.google.supportsStructuredOutputs ?? false,
|
|
194
|
+
provider: mockModels.google.provider,
|
|
195
|
+
});
|
|
148
196
|
const schema = z.object({
|
|
149
197
|
startDate: z.date(),
|
|
150
198
|
endDate: z.date().optional(),
|
|
@@ -169,22 +217,38 @@ describe('Provider Compatibility Classes', () => {
|
|
|
169
217
|
|
|
170
218
|
describe('DeepSeekSchemaCompatLayer', () => {
|
|
171
219
|
it('should apply for DeepSeek models', () => {
|
|
172
|
-
const compat = new DeepSeekSchemaCompatLayer(
|
|
220
|
+
const compat = new DeepSeekSchemaCompatLayer({
|
|
221
|
+
modelId: mockModels.deepseek.modelId,
|
|
222
|
+
supportsStructuredOutputs: mockModels.deepseek.supportsStructuredOutputs ?? false,
|
|
223
|
+
provider: mockModels.deepseek.provider,
|
|
224
|
+
});
|
|
173
225
|
expect(compat.shouldApply()).toBe(true);
|
|
174
226
|
});
|
|
175
227
|
|
|
176
228
|
it('should not apply for non-DeepSeek models', () => {
|
|
177
|
-
const compat = new DeepSeekSchemaCompatLayer(
|
|
229
|
+
const compat = new DeepSeekSchemaCompatLayer({
|
|
230
|
+
modelId: mockModels.openai.modelId,
|
|
231
|
+
supportsStructuredOutputs: mockModels.openai.supportsStructuredOutputs ?? false,
|
|
232
|
+
provider: mockModels.openai.provider,
|
|
233
|
+
});
|
|
178
234
|
expect(compat.shouldApply()).toBe(false);
|
|
179
235
|
});
|
|
180
236
|
|
|
181
237
|
it('should return correct schema target', () => {
|
|
182
|
-
const compat = new DeepSeekSchemaCompatLayer(
|
|
238
|
+
const compat = new DeepSeekSchemaCompatLayer({
|
|
239
|
+
modelId: mockModels.deepseek.modelId,
|
|
240
|
+
supportsStructuredOutputs: mockModels.deepseek.supportsStructuredOutputs ?? false,
|
|
241
|
+
provider: mockModels.deepseek.provider,
|
|
242
|
+
});
|
|
183
243
|
expect(compat.getSchemaTarget()).toBe('jsonSchema7');
|
|
184
244
|
});
|
|
185
245
|
|
|
186
246
|
it('should handle string constraints', () => {
|
|
187
|
-
const compat = new DeepSeekSchemaCompatLayer(
|
|
247
|
+
const compat = new DeepSeekSchemaCompatLayer({
|
|
248
|
+
modelId: mockModels.deepseek.modelId,
|
|
249
|
+
supportsStructuredOutputs: mockModels.deepseek.supportsStructuredOutputs ?? false,
|
|
250
|
+
provider: mockModels.deepseek.provider,
|
|
251
|
+
});
|
|
188
252
|
const schema = z.object({
|
|
189
253
|
email: z.string().email(),
|
|
190
254
|
url: z.string().url(),
|
|
@@ -212,17 +276,29 @@ describe('Provider Compatibility Classes', () => {
|
|
|
212
276
|
|
|
213
277
|
describe('MetaSchemaCompatLayer', () => {
|
|
214
278
|
it('should have consistent behavior', () => {
|
|
215
|
-
const compat = new MetaSchemaCompatLayer(
|
|
279
|
+
const compat = new MetaSchemaCompatLayer({
|
|
280
|
+
modelId: mockModels.meta.modelId,
|
|
281
|
+
supportsStructuredOutputs: mockModels.meta.supportsStructuredOutputs ?? false,
|
|
282
|
+
provider: mockModels.meta.provider,
|
|
283
|
+
});
|
|
216
284
|
expect(typeof compat.shouldApply()).toBe('boolean');
|
|
217
285
|
});
|
|
218
286
|
|
|
219
287
|
it('should return correct schema target', () => {
|
|
220
|
-
const compat = new MetaSchemaCompatLayer(
|
|
288
|
+
const compat = new MetaSchemaCompatLayer({
|
|
289
|
+
modelId: mockModels.meta.modelId,
|
|
290
|
+
supportsStructuredOutputs: mockModels.meta.supportsStructuredOutputs ?? false,
|
|
291
|
+
provider: mockModels.meta.provider,
|
|
292
|
+
});
|
|
221
293
|
expect(compat.getSchemaTarget()).toBe('jsonSchema7');
|
|
222
294
|
});
|
|
223
295
|
|
|
224
296
|
it('should handle array and union types', () => {
|
|
225
|
-
const compat = new MetaSchemaCompatLayer(
|
|
297
|
+
const compat = new MetaSchemaCompatLayer({
|
|
298
|
+
modelId: mockModels.meta.modelId,
|
|
299
|
+
supportsStructuredOutputs: mockModels.meta.supportsStructuredOutputs ?? false,
|
|
300
|
+
provider: mockModels.meta.provider,
|
|
301
|
+
});
|
|
226
302
|
const schema = z.object({
|
|
227
303
|
tags: z.array(z.string()).min(1).max(10),
|
|
228
304
|
status: z.union([z.literal('active'), z.literal('inactive')]),
|
|
@@ -271,12 +347,31 @@ describe('Provider Compatibility Classes', () => {
|
|
|
271
347
|
});
|
|
272
348
|
|
|
273
349
|
const providers = [
|
|
274
|
-
new AnthropicSchemaCompatLayer(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
new
|
|
350
|
+
new AnthropicSchemaCompatLayer({
|
|
351
|
+
modelId: mockModels.anthropic.modelId,
|
|
352
|
+
supportsStructuredOutputs: mockModels.anthropic.supportsStructuredOutputs ?? false,
|
|
353
|
+
provider: mockModels.anthropic.provider,
|
|
354
|
+
}),
|
|
355
|
+
new OpenAISchemaCompatLayer({
|
|
356
|
+
modelId: mockModels.openai.modelId,
|
|
357
|
+
supportsStructuredOutputs: mockModels.openai.supportsStructuredOutputs ?? false,
|
|
358
|
+
provider: mockModels.openai.provider,
|
|
359
|
+
}),
|
|
360
|
+
new OpenAIReasoningSchemaCompatLayer({
|
|
361
|
+
modelId: mockModels.openaiReasoning.modelId,
|
|
362
|
+
supportsStructuredOutputs: mockModels.openaiReasoning.supportsStructuredOutputs ?? false,
|
|
363
|
+
provider: mockModels.openaiReasoning.provider,
|
|
364
|
+
}),
|
|
365
|
+
new GoogleSchemaCompatLayer({
|
|
366
|
+
modelId: mockModels.google.modelId,
|
|
367
|
+
supportsStructuredOutputs: mockModels.google.supportsStructuredOutputs ?? false,
|
|
368
|
+
provider: mockModels.google.provider,
|
|
369
|
+
}),
|
|
370
|
+
new MetaSchemaCompatLayer({
|
|
371
|
+
modelId: mockModels.meta.modelId,
|
|
372
|
+
supportsStructuredOutputs: mockModels.meta.supportsStructuredOutputs ?? false,
|
|
373
|
+
provider: mockModels.meta.provider,
|
|
374
|
+
}),
|
|
280
375
|
];
|
|
281
376
|
|
|
282
377
|
providers.forEach(provider => {
|