-
Notifications
You must be signed in to change notification settings - Fork 477
feat: #561 support both zod3 and zod4 #609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| '@openai/agents-extensions': minor | ||
| '@openai/agents-realtime': minor | ||
| '@openai/agents-openai': minor | ||
| '@openai/agents-core': minor | ||
| '@openai/agents': minor | ||
| --- | ||
|
|
||
| feat: #561 support both zod3 and zod4 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ describe('Deno', () => { | |
| await execa`deno install`; | ||
| }, 60000); | ||
|
|
||
| test('should be able to run', async () => { | ||
| test('should be able to run', { timeout: 60000 }, async () => { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unrelated improvement |
||
| const { stdout } = await execa`deno --allow-net --allow-env main.ts`; | ||
| expect(stdout).toContain('[RESPONSE]Hello there![/RESPONSE]'); | ||
| }); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { describe, test, expect, beforeAll } from 'vitest'; | ||
| import { execa as execaBase } from 'execa'; | ||
|
|
||
| const execa = execaBase({ | ||
| cwd: './integration-tests/node-zod3', | ||
| env: { | ||
| ...process.env, | ||
| NODE_OPTIONS: '', | ||
| TS_NODE_PROJECT: '', | ||
| TS_NODE_COMPILER_OPTIONS: '', | ||
| }, | ||
| }); | ||
|
|
||
| describe('Node.js', () => { | ||
| beforeAll(async () => { | ||
| // remove lock file to avoid errors | ||
| console.log('[node] Removing node_modules'); | ||
| await execa`rm -rf node_modules`; | ||
| console.log('[node] Installing dependencies'); | ||
| await execa`npm install`; | ||
| }, 60000); | ||
|
|
||
| test('should be able to run using CommonJS', async () => { | ||
| const { stdout } = await execa`npm run start:cjs`; | ||
| expect(stdout).toContain('[RESPONSE]Hello there![/RESPONSE]'); | ||
| }); | ||
|
|
||
| test('should be able to run using ESM', async () => { | ||
| const { stdout } = await execa`npm run start:esm`; | ||
| expect(stdout).toContain('[RESPONSE]Hello there![/RESPONSE]'); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| @openai:registry=http://localhost:4873 | ||
| package-lock=false |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| // @ts-check | ||
|
|
||
| const { | ||
| Agent, | ||
| run, | ||
| tool, | ||
| setTraceProcessors, | ||
| ConsoleSpanExporter, | ||
| BatchTraceProcessor, | ||
| } = require('@openai/agents'); | ||
|
|
||
| const { z } = require('zod'); | ||
|
|
||
| setTraceProcessors([new BatchTraceProcessor(new ConsoleSpanExporter())]); | ||
|
|
||
| const getWeatherTool = tool({ | ||
| name: 'get_weather', | ||
| description: 'Get the weather for a given city', | ||
| parameters: z.object({ city: z.string() }), | ||
| execute: async (input) => { | ||
| return `The weather in ${input.city} is sunny`; | ||
| }, | ||
| }); | ||
|
|
||
| const agent = new Agent({ | ||
| name: 'Test Agent', | ||
| instructions: | ||
| 'You will always only respond with "Hello there!". Not more not less.', | ||
| tools: [getWeatherTool], | ||
| }); | ||
|
|
||
| async function main() { | ||
| const result = await run(agent, 'Hey there!'); | ||
| console.log(`[RESPONSE]${result.finalOutput}[/RESPONSE]`); | ||
| } | ||
|
|
||
| main().catch(console.error); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // @ts-check | ||
|
|
||
| import { z } from 'zod'; | ||
|
|
||
| import { | ||
| Agent, | ||
| run, | ||
| tool, | ||
| setTraceProcessors, | ||
| ConsoleSpanExporter, | ||
| BatchTraceProcessor, | ||
| } from '@openai/agents'; | ||
|
|
||
| setTraceProcessors([new BatchTraceProcessor(new ConsoleSpanExporter())]); | ||
|
|
||
| const getWeatherTool = tool({ | ||
| name: 'get_weather', | ||
| description: 'Get the weather for a given city', | ||
| parameters: z.object({ city: z.string() }), | ||
| execute: async (input) => { | ||
| return `The weather in ${input.city} is sunny`; | ||
| }, | ||
| }); | ||
|
|
||
| const agent = new Agent({ | ||
| name: 'Test Agent', | ||
| instructions: | ||
| 'You will always only respond with "Hello there!". Not more not less.', | ||
| tools: [getWeatherTool], | ||
| }); | ||
|
|
||
| const result = await run(agent, 'What is the weather in San Francisco?'); | ||
| console.log(`[RESPONSE]${result.finalOutput}[/RESPONSE]`); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "private": true, | ||
| "type": "commonjs", | ||
| "scripts": { | ||
| "start:cjs": "node --no-experimental-require-module index.cjs", | ||
| "start:esm": "node --no-experimental-require-module index.mjs" | ||
| }, | ||
| "dependencies": { | ||
| "@openai/agents": "latest", | ||
| "typescript": "^5.9.3", | ||
| "zod": "^3.25.40" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { describe, test, expect, beforeAll } from 'vitest'; | ||
| import { execa as execaBase } from 'execa'; | ||
|
|
||
| const execa = execaBase({ | ||
| cwd: './integration-tests/node-zod4', | ||
| env: { | ||
| ...process.env, | ||
| NODE_OPTIONS: '', | ||
| TS_NODE_PROJECT: '', | ||
| TS_NODE_COMPILER_OPTIONS: '', | ||
| }, | ||
| }); | ||
|
|
||
| describe('Node.js', () => { | ||
| beforeAll(async () => { | ||
| // remove lock file to avoid errors | ||
| console.log('[node] Removing node_modules'); | ||
| await execa`rm -rf node_modules`; | ||
| console.log('[node] Installing dependencies'); | ||
| await execa`npm install`; | ||
| }, 60000); | ||
|
|
||
| test('should be able to run using CommonJS', async () => { | ||
| const { stdout } = await execa`npm run start:cjs`; | ||
| expect(stdout).toContain('[RESPONSE]Hello there![/RESPONSE]'); | ||
| }); | ||
|
|
||
| test('should be able to run using ESM', async () => { | ||
| const { stdout } = await execa`npm run start:esm`; | ||
| expect(stdout).toContain('[RESPONSE]Hello there![/RESPONSE]'); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| @openai:registry=http://localhost:4873 | ||
| package-lock=false |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| // @ts-check | ||
|
|
||
| const { | ||
| Agent, | ||
| run, | ||
| tool, | ||
| setTraceProcessors, | ||
| ConsoleSpanExporter, | ||
| BatchTraceProcessor, | ||
| } = require('@openai/agents'); | ||
|
|
||
| const { z } = require('zod'); | ||
|
|
||
| setTraceProcessors([new BatchTraceProcessor(new ConsoleSpanExporter())]); | ||
|
|
||
| const getWeatherTool = tool({ | ||
| name: 'get_weather', | ||
| description: 'Get the weather for a given city', | ||
| parameters: z.object({ city: z.string() }), | ||
| execute: async (input) => { | ||
| return `The weather in ${input.city} is sunny`; | ||
| }, | ||
| }); | ||
|
|
||
| const agent = new Agent({ | ||
| name: 'Test Agent', | ||
| instructions: | ||
| 'You will always only respond with "Hello there!". Not more not less.', | ||
| tools: [getWeatherTool], | ||
| }); | ||
|
|
||
| async function main() { | ||
| const result = await run(agent, 'Hey there!'); | ||
| console.log(`[RESPONSE]${result.finalOutput}[/RESPONSE]`); | ||
| } | ||
|
|
||
| main().catch(console.error); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // @ts-check | ||
|
|
||
| import { z } from 'zod'; | ||
|
|
||
| import { | ||
| Agent, | ||
| run, | ||
| tool, | ||
| setTraceProcessors, | ||
| ConsoleSpanExporter, | ||
| BatchTraceProcessor, | ||
| } from '@openai/agents'; | ||
|
|
||
| setTraceProcessors([new BatchTraceProcessor(new ConsoleSpanExporter())]); | ||
|
|
||
| const getWeatherTool = tool({ | ||
| name: 'get_weather', | ||
| description: 'Get the weather for a given city', | ||
| parameters: z.object({ city: z.string() }), | ||
| execute: async (input) => { | ||
| return `The weather in ${input.city} is sunny`; | ||
| }, | ||
| }); | ||
|
|
||
| const agent = new Agent({ | ||
| name: 'Test Agent', | ||
| instructions: | ||
| 'You will always only respond with "Hello there!". Not more not less.', | ||
| tools: [getWeatherTool], | ||
| }); | ||
|
|
||
| const result = await run(agent, 'What is the weather in San Francisco?'); | ||
| console.log(`[RESPONSE]${result.finalOutput}[/RESPONSE]`); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "private": true, | ||
| "type": "commonjs", | ||
| "scripts": { | ||
| "start:cjs": "node --no-experimental-require-module index.cjs", | ||
| "start:esm": "node --no-experimental-require-module index.mjs" | ||
| }, | ||
| "dependencies": { | ||
| "@openai/agents": "latest", | ||
| "typescript": "^5.9.3", | ||
| "zod": "^4" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,6 @@ const { | |
| ConsoleSpanExporter, | ||
| BatchTraceProcessor, | ||
| } = require('@openai/agents'); | ||
| const { assert } = require('node:console'); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is unused |
||
|
|
||
| setTraceProcessors([new BatchTraceProcessor(new ConsoleSpanExporter())]); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,6 @@ | |
| }, | ||
| "dependencies": { | ||
| "@openai/agents": "latest", | ||
| "typescript": "^5.9.2" | ||
| "typescript": "^5.9.3" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,21 @@ | ||
| import { describe, test, expect, beforeAll, afterAll } from 'vitest'; | ||
| import { chromium } from 'playwright'; | ||
| import { execa as execaBase, ResultPromise } from 'execa'; | ||
| import { writeFile, unlink } from 'node:fs/promises'; | ||
| import path from 'node:path'; | ||
|
|
||
| const execa = execaBase({ | ||
| cwd: './integration-tests/vite-react', | ||
| }); | ||
|
|
||
| let server: ResultPromise; | ||
| const envPath = path.join( | ||
| process.cwd(), | ||
| 'integration-tests', | ||
| 'vite-react', | ||
| '.env', | ||
| ); | ||
| let wroteEnvFile = false; | ||
|
|
||
| describe('Vite React', () => { | ||
| beforeAll(async () => { | ||
|
|
@@ -16,10 +25,21 @@ describe('Vite React', () => { | |
| await execa`rm -rf node_modules`; | ||
| console.log('[vite-react] Installing dependencies'); | ||
| await execa`npm install`; | ||
|
|
||
| const apiKey = process.env.OPENAI_API_KEY; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unrelated improvement; easier to run this test |
||
| if (!apiKey) { | ||
| throw new Error( | ||
| 'OPENAI_API_KEY must be set to run the Vite React integration test.', | ||
| ); | ||
| } | ||
| await writeFile(envPath, `VITE_OPENAI_API_KEY=${apiKey}\n`, 'utf8'); | ||
| wroteEnvFile = true; | ||
|
|
||
| console.log('[vite-react] Building'); | ||
| await execa`npm run build`; | ||
| console.log('[vite-react] Starting server'); | ||
| server = execa`npm run preview -- --port 9999`; | ||
| server.catch(() => {}); | ||
| await new Promise((resolve) => { | ||
| server.stdout?.on('data', (data) => { | ||
| if (data.toString().includes('http://localhost')) { | ||
|
|
@@ -41,6 +61,7 @@ describe('Vite React', () => { | |
| const root = await page.$('#root'); | ||
| const span = await root?.waitForSelector('span[data-testid="response"]', { | ||
| state: 'attached', | ||
| timeout: 60000, | ||
| }); | ||
| expect(await span?.textContent()).toBe('[RESPONSE]Hello there![/RESPONSE]'); | ||
| await browser.close(); | ||
|
|
@@ -50,5 +71,8 @@ describe('Vite React', () => { | |
| if (server) { | ||
| server.kill(); | ||
| } | ||
| if (wroteEnvFile) { | ||
| await unlink(envPath).catch(() => {}); | ||
| } | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,7 +74,7 @@ | |
| "debug": "^4.4.0" | ||
| }, | ||
| "peerDependencies": { | ||
| "zod": "^3.25.40" | ||
| "zod": "^3.25.40 || ^4.0" | ||
| }, | ||
| "peerDependenciesMeta": { | ||
| "zod": { | ||
|
|
@@ -102,7 +102,7 @@ | |
| }, | ||
| "devDependencies": { | ||
| "@types/debug": "^4.1.12", | ||
| "zod": "^3.25.40" | ||
| "zod": "^3.25.40 || ^4.0" | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. align with underlying openai package |
||
| }, | ||
| "files": [ | ||
| "dist" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
intentionally minor; also when we release this, we will update the documents too (currently we're asking users to use zod@3)