|
| 1 | +/** |
| 2 | + * Example: Using CodexProvider with OpenAI Agents framework and custom tools |
| 3 | + * |
| 4 | + * This example demonstrates how to: |
| 5 | + * - Use zod for type-safe tool parameters |
| 6 | + * - Register custom tools with the agents framework |
| 7 | + * - Use CodexProvider as the model backend |
| 8 | + * - Create a weather assistant agent |
| 9 | + * |
| 10 | + * Installation: |
| 11 | + * ```bash |
| 12 | + * npm install @codex-native/sdk @openai/agents zod |
| 13 | + * ``` |
| 14 | + * |
| 15 | + * Usage: |
| 16 | + * ```bash |
| 17 | + * export CODEX_API_KEY="your-api-key" |
| 18 | + * export OPENAI_API_KEY="your-openai-api-key" |
| 19 | + * npx tsx examples/agents-with-tools.ts |
| 20 | + * ``` |
| 21 | + */ |
| 22 | + |
| 23 | +import { z } from 'zod'; |
| 24 | +import { |
| 25 | + Agent, |
| 26 | + run, |
| 27 | + withTrace, |
| 28 | + OpenAIChatCompletionsModel, |
| 29 | + tool, |
| 30 | +} from '@openai/agents'; |
| 31 | +import { OpenAI } from 'openai'; |
| 32 | +import { CodexProvider } from '../src/index.js'; |
| 33 | + |
| 34 | +// Define a weather tool using zod for type-safe parameters |
| 35 | +const getWeatherTool = tool({ |
| 36 | + name: 'get_weather', |
| 37 | + description: 'Get the weather for a given city', |
| 38 | + parameters: z.object({ |
| 39 | + city: z.string().describe('The city to get weather for'), |
| 40 | + }), |
| 41 | + execute: async (input) => { |
| 42 | + console.log(`[debug] Getting weather for ${input.city}\n`); |
| 43 | + // Simulate weather API call |
| 44 | + const weatherConditions = ['sunny', 'cloudy', 'rainy', 'snowy']; |
| 45 | + const condition = weatherConditions[Math.floor(Math.random() * weatherConditions.length)]; |
| 46 | + const temp = Math.floor(Math.random() * 30) + 10; |
| 47 | + return `The weather in ${input.city} is ${condition} with a temperature of ${temp}°C`; |
| 48 | + }, |
| 49 | +}); |
| 50 | + |
| 51 | +// Define a temperature conversion tool |
| 52 | +const convertTemperatureTool = tool({ |
| 53 | + name: 'convert_temperature', |
| 54 | + description: 'Convert temperature between Celsius and Fahrenheit', |
| 55 | + parameters: z.object({ |
| 56 | + value: z.number().describe('The temperature value to convert'), |
| 57 | + from: z.enum(['celsius', 'fahrenheit']).describe('The unit to convert from'), |
| 58 | + to: z.enum(['celsius', 'fahrenheit']).describe('The unit to convert to'), |
| 59 | + }), |
| 60 | + execute: async (input) => { |
| 61 | + console.log(`[debug] Converting ${input.value}°${input.from[0].toUpperCase()} to ${input.to}\n`); |
| 62 | + |
| 63 | + if (input.from === input.to) { |
| 64 | + return `${input.value}°${input.from === 'celsius' ? 'C' : 'F'}`; |
| 65 | + } |
| 66 | + |
| 67 | + let result: number; |
| 68 | + if (input.from === 'celsius' && input.to === 'fahrenheit') { |
| 69 | + result = (input.value * 9/5) + 32; |
| 70 | + } else { |
| 71 | + result = (input.value - 32) * 5/9; |
| 72 | + } |
| 73 | + |
| 74 | + return `${input.value}°${input.from === 'celsius' ? 'C' : 'F'} is ${result.toFixed(1)}°${input.to === 'celsius' ? 'C' : 'F'}`; |
| 75 | + }, |
| 76 | +}); |
| 77 | + |
| 78 | +async function main() { |
| 79 | + console.log('🤖 OpenAI Agents with Codex Provider\n'); |
| 80 | + |
| 81 | + // Create OpenAI client for GPT-5 |
| 82 | + const client = new OpenAI({ |
| 83 | + apiKey: process.env.OPENAI_API_KEY, |
| 84 | + }); |
| 85 | + |
| 86 | + // Create an agent with GPT-5 and custom tools |
| 87 | + const weatherAgent = new Agent({ |
| 88 | + name: 'WeatherAssistant', |
| 89 | + model: new OpenAIChatCompletionsModel(client, 'gpt-5'), |
| 90 | + instructions: 'You are a helpful weather assistant. You respond in haikus when providing weather information.', |
| 91 | + tools: [getWeatherTool, convertTemperatureTool], |
| 92 | + }); |
| 93 | + |
| 94 | + console.log('✓ Created WeatherAssistant agent with GPT-5\n'); |
| 95 | + |
| 96 | + // Run the agent with tracing |
| 97 | + await withTrace('Weather Assistant Example', async () => { |
| 98 | + console.log('Running query: "What\'s the weather in Tokyo?"\n'); |
| 99 | + console.log('─'.repeat(60)); |
| 100 | + |
| 101 | + const result = await run(weatherAgent, "What's the weather in Tokyo?"); |
| 102 | + |
| 103 | + console.log('\n[Final response]'); |
| 104 | + console.log(result.finalOutput); |
| 105 | + }); |
| 106 | + |
| 107 | + console.log('\n' + '='.repeat(60)); |
| 108 | + console.log('✓ Example complete!'); |
| 109 | +} |
| 110 | + |
| 111 | +// Run if executed directly |
| 112 | +if (require.main === module) { |
| 113 | + main().catch((error) => { |
| 114 | + console.error('Fatal error:', error); |
| 115 | + process.exit(1); |
| 116 | + }); |
| 117 | +} |
| 118 | + |
| 119 | +export { main, getWeatherTool, convertTemperatureTool }; |
0 commit comments