Skip to content

Commit 2930f4d

Browse files
authored
Fix ChatGptSchemaComposer's strict mode (#145)
1 parent 64a2798 commit 2930f4d

File tree

3 files changed

+86
-18
lines changed

3 files changed

+86
-18
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@samchon/openapi",
3-
"version": "2.5.1",
3+
"version": "2.5.2",
44
"description": "OpenAPI definitions and converters for 'typia' and 'nestia'.",
55
"main": "./lib/index.js",
66
"module": "./lib/index.mjs",

src/composers/llm/ChatGptSchemaComposer.ts

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,16 @@ export namespace ChatGptSchemaComposer {
4343

4444
// returns with transformation
4545
for (const key of Object.keys(result.value.$defs))
46-
result.value.$defs[key] = transform(result.value.$defs[key]);
46+
result.value.$defs[key] = transform({
47+
config: props.config,
48+
schema: result.value.$defs[key],
49+
});
4750
return {
4851
success: true,
49-
value: transform(result.value) as IChatGptSchema.IParameters,
52+
value: transform({
53+
config: props.config,
54+
schema: result.value,
55+
}) as IChatGptSchema.IParameters,
5056
};
5157
};
5258

@@ -77,10 +83,16 @@ export namespace ChatGptSchemaComposer {
7783
// returns with transformation
7884
for (const key of Object.keys(props.$defs))
7985
if (oldbie.has(key) === false)
80-
props.$defs[key] = transform(props.$defs[key]);
86+
props.$defs[key] = transform({
87+
config: props.config,
88+
schema: props.$defs[key],
89+
});
8190
return {
8291
success: true,
83-
value: transform(result.value),
92+
value: transform({
93+
config: props.config,
94+
schema: result.value,
95+
}),
8496
};
8597
};
8698

@@ -109,13 +121,16 @@ export namespace ChatGptSchemaComposer {
109121
return reasons;
110122
};
111123

112-
const transform = (schema: ILlmSchemaV3_1): IChatGptSchema => {
124+
const transform = (props: {
125+
config: IChatGptSchema.IConfig;
126+
schema: ILlmSchemaV3_1;
127+
}): IChatGptSchema => {
113128
const union: Array<IChatGptSchema> = [];
114129
const attribute: IChatGptSchema.__IAttribute = {
115-
title: schema.title,
116-
description: schema.description,
117-
example: schema.example,
118-
examples: schema.examples,
130+
title: props.schema.title,
131+
description: props.schema.description,
132+
example: props.schema.example,
133+
examples: props.schema.examples,
119134
...Object.fromEntries(
120135
Object.entries(schema).filter(
121136
([key, value]) => key.startsWith("x-") && value !== undefined,
@@ -127,22 +142,33 @@ export namespace ChatGptSchemaComposer {
127142
else if (LlmTypeCheckerV3_1.isArray(input))
128143
union.push({
129144
...input,
130-
items: transform(input.items),
145+
items: transform({
146+
config: props.config,
147+
schema: input.items,
148+
}),
131149
});
132150
else if (LlmTypeCheckerV3_1.isObject(input))
133151
union.push({
134152
...input,
135153
properties: Object.fromEntries(
136154
Object.entries(input.properties).map(([key, value]) => [
137155
key,
138-
transform(value),
156+
transform({
157+
config: props.config,
158+
schema: value,
159+
}),
139160
]),
140161
),
141162
additionalProperties:
142-
typeof input.additionalProperties === "object" &&
143-
input.additionalProperties !== null
144-
? transform(input.additionalProperties)
145-
: input.additionalProperties,
163+
props.config.strict === true
164+
? false
165+
: typeof input.additionalProperties === "object" &&
166+
input.additionalProperties !== null
167+
? transform({
168+
config: props.config,
169+
schema: input.additionalProperties,
170+
})
171+
: input.additionalProperties,
146172
});
147173
else if (LlmTypeCheckerV3_1.isConstant(input) === false)
148174
union.push(input);
@@ -167,8 +193,8 @@ export namespace ChatGptSchemaComposer {
167193
else if (OpenApiTypeChecker.isOneOf(input))
168194
input.oneOf.forEach(visitConstant);
169195
};
170-
visit(schema);
171-
visitConstant(schema);
196+
visit(props.schema);
197+
visitConstant(props.schema);
172198
if (union.length === 0)
173199
return {
174200
...attribute,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { TestValidator } from "@nestia/e2e";
2+
import { ILlmSchema, IOpenApiSchemaError, IResult } from "@samchon/openapi";
3+
import { LlmSchemaComposer } from "@samchon/openapi/lib/composers/LlmSchemaComposer";
4+
import typia, { IJsonSchemaCollection } from "typia";
5+
6+
export const test_chatgpt_schema_strict = (): void => {
7+
const collection: IJsonSchemaCollection = typia.json.schemas<
8+
[
9+
{
10+
id: string;
11+
name: string;
12+
hobbies: {
13+
id: string;
14+
name: string;
15+
}[];
16+
},
17+
]
18+
>();
19+
const res: IResult<ILlmSchema, IOpenApiSchemaError> =
20+
LlmSchemaComposer.schema("chatgpt")({
21+
config: {
22+
...LlmSchemaComposer.defaultConfig("chatgpt"),
23+
strict: true,
24+
},
25+
components: collection.components,
26+
schema: collection.schemas[0],
27+
$defs: {},
28+
} as any);
29+
TestValidator.equals("strict")({
30+
type: "object",
31+
additionalProperties: false,
32+
properties: {
33+
hobbies: {
34+
type: "array",
35+
items: {
36+
type: "object",
37+
additionalProperties: false,
38+
},
39+
},
40+
},
41+
})((res.success ? res.value : null) as any);
42+
};

0 commit comments

Comments
 (0)