Skip to content

Commit 3f96a58

Browse files
committed
start working on docs
1 parent cdeb4e6 commit 3f96a58

File tree

8 files changed

+218
-15
lines changed

8 files changed

+218
-15
lines changed

README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,85 @@ await client.files.create({
124124
});
125125
```
126126

127+
## Streaming Helpers
128+
129+
```ts
130+
import OpenAI from 'openai';
131+
132+
const client = new OpenAI();
133+
134+
async function main() {
135+
const stream = client.chat.completions
136+
.stream({
137+
model: 'gpt-4o',
138+
max_tokens: 1024,
139+
messages: [
140+
{
141+
role: 'user',
142+
content: 'Say hi!',
143+
},
144+
],
145+
})
146+
.on('chunk', (text) => {
147+
console.log(text);
148+
});
149+
150+
const message = await stream.finalMessage();
151+
console.log(message);
152+
}
153+
154+
main();
155+
```
156+
157+
## Tool Helpers
158+
159+
The SDK makes it easy to create and run [function tools with the chats API](https://platform.openai.com/docs/guides/function-calling). You can use Zod schemas or direct JSON schemas to describe the shape of tool input, and then you can run the tools using the `client.beta.messages.toolRunner` method. This method will automatically handle passing the inputs generated by the model into your tools and providing the results back to the model.
160+
161+
```ts
162+
import OpenAI from 'openai';
163+
164+
import { betaZodFunctionTool } from 'openai/helpers/beta/zod';
165+
import { z } from 'zod/v4';
166+
167+
const client = new OpenAI();
168+
169+
async function main() {
170+
const addTool = betaZodFunctionTool({
171+
name: 'add',
172+
parameters: z.object({
173+
a: z.number(),
174+
b: z.number(),
175+
}),
176+
description: 'Add two numbers together',
177+
run: (input) => {
178+
return String(input.a + input.b);
179+
},
180+
});
181+
182+
const multiplyTool = betaZodFunctionTool({
183+
name: 'multiply',
184+
parameters: z.object({
185+
a: z.number(),
186+
b: z.number(),
187+
}),
188+
description: 'Multiply two numbers together',
189+
run: (input) => {
190+
return String(input.a * input.b);
191+
},
192+
});
193+
194+
const finalMessage = await client.beta.chat.completions.toolRunner({
195+
model: 'gpt-4o',
196+
max_tokens: 1000,
197+
messages: [{ role: 'user', content: 'What is 5 plus 3, and then multiply that result by 4?' }],
198+
tools: [addTool, multiplyTool],
199+
});
200+
console.log(finalMessage);
201+
}
202+
203+
main();
204+
```
205+
127206
## Webhook Verification
128207

129208
Verifying webhook signatures is _optional but encouraged_.

examples/tool-calls-beta-zod.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env -S npm run tsn -T
22

33
import OpenAI from 'openai';
4-
import { betaZodTool } from 'openai/helpers/beta/zod';
4+
import { betaZodFunctionTool } from 'openai/helpers/beta/zod';
55
import { z } from 'zod';
66

77
const client = new OpenAI();
@@ -15,7 +15,7 @@ async function main() {
1515
},
1616
],
1717
tools: [
18-
betaZodTool({
18+
betaZodFunctionTool({
1919
name: 'getWeather',
2020
description: 'Get the weather at a specific location',
2121
parameters: z.object({
@@ -25,7 +25,7 @@ async function main() {
2525
return `The weather is sunny with a temperature of 20°C in ${location}.`;
2626
},
2727
}),
28-
betaZodTool({
28+
betaZodFunctionTool({
2929
name: 'getTime',
3030
description: 'Get the current time in a specific timezone',
3131
parameters: z.object({
@@ -35,7 +35,7 @@ async function main() {
3535
return `The current time in ${timezone} is 3:00 PM.`;
3636
},
3737
}),
38-
betaZodTool({
38+
betaZodFunctionTool({
3939
name: 'getCurrencyExchangeRate',
4040
description: 'Get the exchange rate between two currencies',
4141
parameters: z.object({

examples/tool-helpers-advanced-streaming.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env -S npm run tsn -T
22

33
import OpenAI from 'openai';
4-
import { betaZodTool } from 'openai/helpers/beta/zod';
4+
import { betaZodFunctionTool } from 'openai/helpers/beta/zod';
55
import { z } from 'zod';
66

77
const client = new OpenAI();
@@ -15,7 +15,7 @@ async function main() {
1515
},
1616
],
1717
tools: [
18-
betaZodTool({
18+
betaZodFunctionTool({
1919
name: 'getWeather',
2020
description: 'Get the weather at a specific location',
2121
parameters: z.object({
@@ -25,7 +25,7 @@ async function main() {
2525
return `The weather is sunny with a temperature of 20°C in ${location}.`;
2626
},
2727
}),
28-
betaZodTool({
28+
betaZodFunctionTool({
2929
name: 'getTime',
3030
description: 'Get the current time in a specific timezone',
3131
parameters: z.object({
@@ -35,7 +35,7 @@ async function main() {
3535
return `The current time in ${timezone} is 3:00 PM.`;
3636
},
3737
}),
38-
betaZodTool({
38+
betaZodFunctionTool({
3939
name: 'getCurrencyExchangeRate',
4040
description: 'Get the exchange rate between two currencies',
4141
parameters: z.object({

examples/tool-helpers-advanced.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env -S npm run tsn -T
22

33
import OpenAI from 'openai';
4-
import { betaZodTool } from 'openai/helpers/beta/zod';
4+
import { betaZodFunctionTool } from 'openai/helpers/beta/zod';
55
import { z } from 'zod';
66

77
const client = new OpenAI();
@@ -15,7 +15,7 @@ async function main() {
1515
},
1616
],
1717
tools: [
18-
betaZodTool({
18+
betaZodFunctionTool({
1919
name: 'getWeather',
2020
description: 'Get the weather at a specific location',
2121
parameters: z.object({

helpers.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,128 @@ If you need to cancel a stream, you can `break` from a `for await` loop or call
302302
303303
See an example of streaming helpers in action in [`examples/stream.ts`](examples/stream.ts).
304304
305+
### Automated function calls via Beta Tool Runner
306+
307+
We now offer an easier to use tool calling approach via the `openai.beta.chat.completions.toolRunner({…})` helper. The SDK provides helper functions to create runnable tools that can be automatically invoked by the .toolRunner() method. These helpers simplify tool creation with JSON Schema or Zod validation.
308+
309+
#### Usage
310+
311+
```ts
312+
import OpenAI from 'openai';
313+
314+
import { betaZodFunctionTool } from 'openai/helpers/beta/zod';
315+
import { z } from 'zod/v4';
316+
317+
const client = new OpenAI();
318+
319+
async function main() {
320+
const addTool = betaZodFunctionTool({
321+
name: 'add',
322+
parameters: z.object({
323+
a: z.number(),
324+
b: z.number(),
325+
}),
326+
description: 'Add two numbers together',
327+
run: (input) => {
328+
return String(input.a + input.b);
329+
},
330+
});
331+
332+
const multiplyTool = betaZodFunctionTool({
333+
name: 'multiply',
334+
parameters: z.object({
335+
a: z.number(),
336+
b: z.number(),
337+
}),
338+
description: 'Multiply two numbers together',
339+
run: (input) => {
340+
return String(input.a * input.b);
341+
},
342+
});
343+
344+
const finalMessage = await client.beta.chat.completions.toolRunner({
345+
model: 'gpt-4o',
346+
max_tokens: 1000,
347+
messages: [{ role: 'user', content: 'What is 5 plus 3, and then multiply that result by 4?' }],
348+
tools: [addTool, multiplyTool],
349+
});
350+
console.log(finalMessage);
351+
}
352+
353+
main();
354+
```
355+
356+
#### Advanced Usage
357+
358+
You can also use the `toolRunner` as an async generator to act as the logic runs in.
359+
360+
```ts
361+
// or, instead of using "await client.beta.messages.toolRunner", you can use:
362+
const toolRunner = client.beta.chat.completions.toolRunner({
363+
model: 'gpt-4o',
364+
max_tokens: 1000,
365+
messages: [{ role: 'user', content: 'What is 5 plus 3, and then multiply that result by 4?' }],
366+
tools: [addTool, multiplyTool],
367+
});
368+
369+
for await (const event of toolRunner) {
370+
console.log(event.choices[0]!.message.content);
371+
372+
// If the most recent message triggered a tool call, you can get the result of
373+
// that tool call
374+
const toolResponse = await toolRunner.generateToolResponse();
375+
console.log(toolResponse);
376+
}
377+
```
378+
379+
When you just "await" the `toolRunner`, it simply automatically iterates until the end of the async generator.
380+
381+
#### Streaming
382+
383+
```ts
384+
const runner = anthropic.beta.messages.toolRunner({
385+
model: 'gpt-4o',
386+
max_tokens: 1000,
387+
messages: [{ role: 'user', content: 'What is the weather in San Francisco?' }],
388+
tools: [calculatorTool],
389+
stream: true,
390+
});
391+
392+
// When streaming, the runner returns ChatCompletionStream
393+
for await (const messageStream of runner) {
394+
for await (const event of messageStream) {
395+
console.log('event:', event);
396+
}
397+
console.log('message:', await messageStream.finalMessage());
398+
}
399+
400+
console.log(await runner);
401+
```
402+
403+
See [./examples/tool-helpers-advanced-streaming.ts] for a more in-depth example.
404+
405+
#### Beta Zod Tool
406+
407+
Zod schemas can be used to define the input schema for your tools:
408+
409+
```ts
410+
import { betaZodFunctionTool } from 'openai/helpers/beta/zod';
411+
412+
const weatherTool = betaZodFunctionTool({
413+
name: 'get_weather',
414+
inputSchema: z.object({
415+
location: z.string().describe('The city and state, e.g. San Francisco, CA'),
416+
unit: z.enum(['celsius', 'fahrenheit']).default('fahrenheit'),
417+
}),
418+
description: 'Get the current weather in a given location',
419+
run: async (input) => {
420+
return `The weather in ${input.location} is ${input.unit === 'celsius' ? '22°C' : '72°F'}`;
421+
},
422+
});
423+
```
424+
425+
The AI's generated inputs will be directly validated and fed into your function automatically.
426+
305427
### Automated function calls
306428

307429
We provide the `openai.chat.completions.runTools({…})`
@@ -317,6 +439,8 @@ Otherwise, the args will be passed to the function you provide as a string.
317439
If you pass `tool_choice: {function: {name: …}}` instead of `auto`,
318440
it returns immediately after calling that function (and only loops to auto-recover parsing errors).
319441

442+
#### Beta Tool
443+
320444
```ts
321445
import OpenAI from 'openai';
322446

src/helpers/beta/zod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { FunctionTool } from '../../resources/beta';
99
* converted into JSON Schema when passed to the API. The provided function's
1010
* input arguments will also be validated against the provided schema.
1111
*/
12-
export function betaZodTool<InputSchema extends ZodType>(options: {
12+
export function betaZodFunctionTool<InputSchema extends ZodType>(options: {
1313
name: string;
1414
parameters: InputSchema;
1515
description: string;

src/lib/beta/BetaToolRunner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export class BetaToolRunner<Stream extends boolean>
124124
this.#toolResponse = undefined;
125125
this.#iterationCount++;
126126

127-
const { max_iterations, ...params } = this.#state.params;
127+
const { max_iterations: _, ...params } = this.#state.params;
128128

129129
if (params.stream) {
130130
stream = this.client.chat.completions.stream({ ...params, stream: true }, this.#options);

tests/lib/tools/BetaToolRunnerE2E.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { OpenAI } from '../../../src';
2-
import { betaZodTool } from '../../../src/helpers/beta/zod';
2+
import { betaZodFunctionTool } from '../../../src/helpers/beta/zod';
33
import * as z from 'zod';
44
import nock from 'nock';
55
import { gunzipSync } from 'zlib';
@@ -102,7 +102,7 @@ describe('toolRunner integration tests', () => {
102102
run: (args: any) => any;
103103
}> = {},
104104
) {
105-
return betaZodTool({
105+
return betaZodFunctionTool({
106106
name: 'test_tool',
107107
parameters: z.object({ value: z.string() }),
108108
description: 'A test tool',
@@ -112,7 +112,7 @@ describe('toolRunner integration tests', () => {
112112
}
113113

114114
function createCounterTool() {
115-
return betaZodTool({
115+
return betaZodFunctionTool({
116116
name: 'test_tool',
117117
parameters: z.object({ count: z.number() }),
118118
description: 'A test tool',

0 commit comments

Comments
 (0)