Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e238daa

Browse files
authoredSep 4, 2024··
fix(helpers/zod): avoid import issue in certain environments (#1039)
1 parent 8ec218e commit e238daa

File tree

8 files changed

+368
-8
lines changed

8 files changed

+368
-8
lines changed
 

‎ecosystem-tests/cli.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ const projectRunners = {
2525
'node-ts-esm': defaultNodeRunner,
2626
'node-ts-esm-web': defaultNodeRunner,
2727
'node-ts-esm-auto': defaultNodeRunner,
28+
'node-ts-es2020': async () => {
29+
await installPackage();
30+
await run('npm', ['run', 'tsc']);
31+
await run('npm', ['run', 'main']);
32+
},
2833
'node-js': async () => {
2934
await installPackage();
3035
await run('node', ['test.js']);
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { zodResponseFormat } from 'openai/helpers/zod';
2+
import OpenAI from 'openai/index';
3+
import { z } from 'zod';
4+
5+
const Step = z.object({
6+
explanation: z.string(),
7+
output: z.string(),
8+
});
9+
10+
const MathResponse = z.object({
11+
steps: z.array(Step),
12+
final_answer: z.string(),
13+
});
14+
15+
async function main() {
16+
const client = new OpenAI();
17+
18+
const completion = await client.beta.chat.completions.parse({
19+
model: 'gpt-4o-2024-08-06',
20+
messages: [
21+
{ role: 'system', content: 'You are a helpful math tutor.' },
22+
{ role: 'user', content: 'solve 8x + 31 = 2' },
23+
],
24+
response_format: zodResponseFormat(MathResponse, 'math_response'),
25+
});
26+
27+
console.dir(completion, { depth: 5 });
28+
29+
const message = completion.choices[0]?.message;
30+
if (message?.parsed) {
31+
console.log(message.parsed.steps);
32+
console.log(`answer: ${message.parsed.final_answer}`);
33+
}
34+
}
35+
36+
main();

‎ecosystem-tests/node-ts-es2020/package-lock.json

+193
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "node-ts-es2020",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"scripts": {
6+
"tsc": "tsc && tsc -p tsconfig.nodenext.json && tsc -p node_modules/openai/src/tsconfig.json",
7+
"main": "ts-node index.ts"
8+
},
9+
"dependencies": {
10+
"ts-node": "^10.9.2",
11+
"zod": "^3.23.8"
12+
},
13+
"overrides": {
14+
"@types/node": "20.4.2"
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es2020",
4+
"module": "commonjs",
5+
"lib": ["es2020", "dom"],
6+
"allowJs": false,
7+
"declaration": true,
8+
"declarationMap": true,
9+
"sourceMap": true,
10+
"removeComments": true,
11+
"forceConsistentCasingInFileNames": true,
12+
"downlevelIteration": true,
13+
"strict": true,
14+
"moduleResolution": "node",
15+
"paths": {},
16+
"typeRoots": ["node_modules/@types"],
17+
"types": ["node"],
18+
"allowSyntheticDefaultImports": false,
19+
"experimentalDecorators": true,
20+
"emitDecoratorMetadata": true,
21+
"resolveJsonModule": true,
22+
"incremental": true,
23+
"strictBindCallApply": true,
24+
"strictFunctionTypes": true,
25+
"strictNullChecks": true,
26+
"strictPropertyInitialization": true,
27+
"noImplicitAny": true,
28+
"noImplicitThis": true,
29+
"noImplicitReturns": true,
30+
"noUnusedParameters": true,
31+
"noUnusedLocals": true,
32+
"noFallthroughCasesInSwitch": true,
33+
"preserveSymlinks": true,
34+
"suppressImplicitAnyIndexErrors": true
35+
},
36+
"exclude": ["node_modules"]
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"extends": "./tsconfig.base.json",
3+
"ts-node": {
4+
"swc": true,
5+
"transpileOnly": true
6+
},
7+
"compilerOptions": {
8+
"declaration": false,
9+
"declarationMap": false,
10+
"allowJs": true,
11+
"checkJs": false,
12+
"outDir": "./dist",
13+
"baseUrl": "./",
14+
"types": ["node", "jest"],
15+
"paths": {}
16+
},
17+
"include": ["index.ts", "tsconfig.json", "jest.config.ts", ".eslintrc.js"]
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"include": ["tests/*.ts", "index.ts"],
3+
"exclude": ["tests/*-shim-errors.ts"],
4+
5+
"compilerOptions": {
6+
/* Visit https://aka.ms/tsconfig.json to read more about this file */
7+
/* Projects */
8+
"incremental": true,
9+
10+
/* Language and Environment */
11+
"target": "ES2015",
12+
"lib": ["ES2015"],
13+
"jsx": "react",
14+
15+
/* Modules */
16+
"module": "commonjs",
17+
"rootDir": "./",
18+
"moduleResolution": "NodeNext",
19+
"baseUrl": "./",
20+
"paths": {
21+
"~/*": ["*"]
22+
},
23+
"resolveJsonModule": true,
24+
"composite": true,
25+
26+
/* Emit */
27+
"outDir": "node_modules",
28+
"noEmit": true,
29+
30+
/* Interop Constraints */
31+
"isolatedModules": true,
32+
"allowSyntheticDefaultImports": true,
33+
/* "esModuleInterop": true, */
34+
"forceConsistentCasingInFileNames": true,
35+
"allowJs": true,
36+
"checkJs": true,
37+
38+
/* Experimental Features */
39+
"experimentalDecorators": true,
40+
41+
/* Type Checking */
42+
"strict": true,
43+
"noImplicitAny": true,
44+
"strictNullChecks": true,
45+
"strictFunctionTypes": true,
46+
"strictBindCallApply": true,
47+
"strictPropertyInitialization": true,
48+
"noImplicitThis": true,
49+
"alwaysStrict": true,
50+
"noUncheckedIndexedAccess": true,
51+
"noImplicitOverride": true,
52+
"noPropertyAccessFromIndexSignature": true,
53+
"skipLibCheck": false
54+
}
55+
}

‎src/helpers/zod.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { ResponseFormatJSONSchema } from 'openai/resources';
2-
import type z from 'zod';
1+
import { ResponseFormatJSONSchema } from '../resources/index';
2+
import type { infer as zodInfer, ZodType } from 'zod';
33
import {
44
AutoParseableResponseFormat,
55
AutoParseableTool,
@@ -8,7 +8,7 @@ import {
88
} from '../lib/parser';
99
import { zodToJsonSchema as _zodToJsonSchema } from '../_vendor/zod-to-json-schema';
1010

11-
function zodToJsonSchema(schema: z.ZodType, options: { name: string }): Record<string, unknown> {
11+
function zodToJsonSchema(schema: ZodType, options: { name: string }): Record<string, unknown> {
1212
return _zodToJsonSchema(schema, {
1313
openaiStrictMode: true,
1414
name: options.name,
@@ -55,11 +55,11 @@ function zodToJsonSchema(schema: z.ZodType, options: { name: string }): Record<s
5555
* This can be passed directly to the `.create()` method but will not
5656
* result in any automatic parsing, you'll have to parse the response yourself.
5757
*/
58-
export function zodResponseFormat<ZodInput extends z.ZodType>(
58+
export function zodResponseFormat<ZodInput extends ZodType>(
5959
zodObject: ZodInput,
6060
name: string,
6161
props?: Omit<ResponseFormatJSONSchema.JSONSchema, 'schema' | 'strict' | 'name'>,
62-
): AutoParseableResponseFormat<z.infer<ZodInput>> {
62+
): AutoParseableResponseFormat<zodInfer<ZodInput>> {
6363
return makeParseableResponseFormat(
6464
{
6565
type: 'json_schema',
@@ -79,15 +79,15 @@ export function zodResponseFormat<ZodInput extends z.ZodType>(
7979
* automatically by the chat completion `.runTools()` method or automatically
8080
* parsed by `.parse()` / `.stream()`.
8181
*/
82-
export function zodFunction<Parameters extends z.ZodType>(options: {
82+
export function zodFunction<Parameters extends ZodType>(options: {
8383
name: string;
8484
parameters: Parameters;
85-
function?: ((args: z.infer<Parameters>) => unknown | Promise<unknown>) | undefined;
85+
function?: ((args: zodInfer<Parameters>) => unknown | Promise<unknown>) | undefined;
8686
description?: string | undefined;
8787
}): AutoParseableTool<{
8888
arguments: Parameters;
8989
name: string;
90-
function: (args: z.infer<Parameters>) => unknown;
90+
function: (args: zodInfer<Parameters>) => unknown;
9191
}> {
9292
// @ts-expect-error TODO
9393
return makeParseableTool<any>(

0 commit comments

Comments
 (0)
Please sign in to comment.