Skip to content

Commit 184e5d0

Browse files
authored
feat: Add reasoning.effort: none parameter for gpt-5.1 (#657)
1 parent 1225e91 commit 184e5d0

File tree

7 files changed

+181
-50
lines changed

7 files changed

+181
-50
lines changed

.changeset/olive-waves-type.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@openai/agents-openai': patch
3+
'@openai/agents-core': patch
4+
---
5+
6+
feat: Add reasoning.effort: none parameter for gpt-5.1
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
Agent,
3+
OpenAIChatCompletionsModel,
4+
run,
5+
withTrace,
6+
} from '@openai/agents';
7+
import OpenAI from 'openai';
8+
import { z } from 'zod';
9+
10+
const output = z.object({
11+
title: z.string(),
12+
description: z.string(),
13+
});
14+
15+
async function main() {
16+
withTrace('GPT-5.1 None Reasoning Assistant', async () => {
17+
const prompt =
18+
'Tell me about recursion in programming in a few sentences. Quickly responding with a single answer is fine.';
19+
const agent = new Agent({
20+
name: 'GPT-5.1 Responses Assistant',
21+
model: 'gpt-5.1',
22+
instructions: "You're a helpful assistant.",
23+
modelSettings: {
24+
reasoning: { effort: 'none' },
25+
text: { verbosity: 'low' },
26+
},
27+
outputType: output,
28+
});
29+
const result = await run(agent, prompt);
30+
console.log(result.finalOutput);
31+
32+
const completionsAgent = new Agent({
33+
name: 'GPT-5.1 Chat Completions Assistant',
34+
model: new OpenAIChatCompletionsModel(new OpenAI(), 'gpt-5.1'),
35+
instructions: "You're a helpful assistant.",
36+
modelSettings: {
37+
reasoning: { effort: 'none' },
38+
text: { verbosity: 'low' },
39+
},
40+
outputType: output,
41+
});
42+
const completionsResult = await run(completionsAgent, prompt);
43+
console.log(completionsResult.finalOutput);
44+
});
45+
}
46+
47+
main().catch((error) => {
48+
console.error(error);
49+
process.exit(1);
50+
});

examples/basic/hello-world-gpt-5.ts

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { Agent, OpenAIChatCompletionsModel, run } from '@openai/agents';
1+
import {
2+
Agent,
3+
OpenAIChatCompletionsModel,
4+
run,
5+
withTrace,
6+
} from '@openai/agents';
27
import OpenAI from 'openai';
38
import { z } from 'zod';
49

@@ -8,59 +13,61 @@ const output = z.object({
813
});
914

1015
async function main() {
11-
const prompt =
12-
'Tell me about recursion in programming. Quickly responding with a single answer is fine.';
16+
withTrace('GPT-5 Assistant', async () => {
17+
const prompt =
18+
'Tell me about recursion in programming in a few sentences. Quickly responding with a single answer is fine.';
1319

14-
const agent = new Agent({
15-
name: 'GPT-5 Assistant',
16-
model: 'gpt-5',
17-
instructions: "You're a helpful assistant.",
18-
modelSettings: {
19-
reasoning: { effort: 'minimal' },
20-
text: { verbosity: 'low' },
21-
},
22-
outputType: output,
23-
});
20+
const agent = new Agent({
21+
name: 'GPT-5 Assistant',
22+
model: 'gpt-5',
23+
instructions: "You're a helpful assistant.",
24+
modelSettings: {
25+
reasoning: { effort: 'minimal' },
26+
text: { verbosity: 'low' },
27+
},
28+
outputType: output,
29+
});
2430

25-
const result = await run(agent, prompt);
26-
console.log(result.finalOutput);
31+
const result = await run(agent, prompt);
32+
console.log(result.finalOutput);
2733

28-
// The following code works in the same way:
29-
// const agent2 = agent.clone({
30-
// modelSettings: {
31-
// providerData: {
32-
// reasoning: { effort: 'minimal' },
33-
// text: { verbosity: 'low' },
34-
// }
35-
// },
36-
// });
37-
// const result2 = await run(agent2, prompt);
38-
// console.log(result2.finalOutput);
34+
// The following code works in the same way:
35+
// const agent2 = agent.clone({
36+
// modelSettings: {
37+
// providerData: {
38+
// reasoning: { effort: 'minimal' },
39+
// text: { verbosity: 'low' },
40+
// }
41+
// },
42+
// });
43+
// const result2 = await run(agent2, prompt);
44+
// console.log(result2.finalOutput);
3945

40-
const completionsAgent = new Agent({
41-
name: 'GPT-5 Assistant',
42-
model: new OpenAIChatCompletionsModel(new OpenAI(), 'gpt-5'),
43-
instructions: "You're a helpful assistant.",
44-
modelSettings: {
45-
reasoning: { effort: 'minimal' },
46-
text: { verbosity: 'low' },
47-
},
48-
outputType: output,
49-
});
50-
const completionsResult = await run(completionsAgent, prompt);
51-
console.log(completionsResult.finalOutput);
46+
const completionsAgent = new Agent({
47+
name: 'GPT-5 Assistant',
48+
model: new OpenAIChatCompletionsModel(new OpenAI(), 'gpt-5'),
49+
instructions: "You're a helpful assistant.",
50+
modelSettings: {
51+
reasoning: { effort: 'minimal' },
52+
text: { verbosity: 'low' },
53+
},
54+
outputType: output,
55+
});
56+
const completionsResult = await run(completionsAgent, prompt);
57+
console.log(completionsResult.finalOutput);
5258

53-
// The following code works in the same way:
54-
// const completionsAgent2 = completionsAgent.clone({
55-
// modelSettings: {
56-
// providerData: {
57-
// reasoning_effort: 'minimal',
58-
// verbosity: 'low',
59-
// }
60-
// },
61-
// });
62-
// const completionsResult2 = await run(completionsAgent2, prompt);
63-
// console.log(completionsResult2.finalOutput);
59+
// The following code works in the same way:
60+
// const completionsAgent2 = completionsAgent.clone({
61+
// modelSettings: {
62+
// providerData: {
63+
// reasoning_effort: 'minimal',
64+
// verbosity: 'low',
65+
// }
66+
// },
67+
// });
68+
// const completionsResult2 = await run(completionsAgent2, prompt);
69+
// console.log(completionsResult2.finalOutput);
70+
});
6471
}
6572

6673
main().catch((error) => {

examples/basic/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"start:dynamic-system-prompt": "tsx dynamic-system-prompt.ts",
1313
"start:hello-world": "tsx hello-world.ts",
1414
"start:hello-world-gpt-5": "tsx hello-world-gpt-5.ts",
15+
"start:hello-world-gpt-5.1": "tsx hello-world-gpt-5.1.ts",
1516
"start:hello-world-gpt-oss": "tsx hello-world-gpt-oss.ts",
1617
"start:lifecycle-example": "tsx lifecycle-example.ts",
1718
"start:local-image": "tsx local-image.ts",

packages/agents-core/src/model.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ export type ModelSettingsToolChoice =
3030
* Reducing reasoning effort can result in faster responses and fewer tokens used on reasoning in a response.
3131
*/
3232
export type ModelSettingsReasoningEffort =
33-
| 'minimal'
33+
| 'none' // for gpt-5.1
34+
| 'minimal' // for gpt-5
3435
| 'low'
3536
| 'medium'
3637
| 'high'

packages/agents-openai/test/openaiChatCompletionsModel.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,35 @@ describe('OpenAIChatCompletionsModel', () => {
283283
expect(options).toEqual({ headers: HEADERS, signal: undefined });
284284
});
285285

286+
it('passes none reasoning effort through to chat completions payloads', async () => {
287+
const client = new FakeClient();
288+
const response = {
289+
id: 'gpt-5.1-response',
290+
choices: [{ message: { content: 'done' } }],
291+
usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
292+
} as any;
293+
client.chat.completions.create.mockResolvedValue(response);
294+
295+
const model = new OpenAIChatCompletionsModel(client as any, 'gpt-5.1');
296+
const req: any = {
297+
input: 'prompt',
298+
modelSettings: {
299+
reasoning: { effort: 'none' },
300+
},
301+
tools: [],
302+
outputType: 'text',
303+
handoffs: [],
304+
tracing: false,
305+
};
306+
307+
await withTrace('gpt-5.1 none', () => model.getResponse(req));
308+
309+
expect(client.chat.completions.create).toHaveBeenCalledTimes(1);
310+
const [args, options] = client.chat.completions.create.mock.calls[0];
311+
expect(args.reasoning_effort).toBe('none');
312+
expect(options).toEqual({ headers: HEADERS, signal: undefined });
313+
});
314+
286315
it('handles function tool calls', async () => {
287316
const client = new FakeClient();
288317
const response = {

packages/agents-openai/test/openaiResponsesModel.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,43 @@ describe('OpenAIResponsesModel', () => {
253253
});
254254
});
255255

256+
it('passes none reasoning effort to the Responses API payload', async () => {
257+
await withTrace('test', async () => {
258+
const fakeResponse = {
259+
id: 'res-none',
260+
usage: {
261+
input_tokens: 1,
262+
output_tokens: 1,
263+
total_tokens: 2,
264+
},
265+
output: [],
266+
};
267+
const createMock = vi.fn().mockResolvedValue(fakeResponse);
268+
const fakeClient = {
269+
responses: { create: createMock },
270+
} as unknown as OpenAI;
271+
const model = new OpenAIResponsesModel(fakeClient, 'gpt-5.1');
272+
const request = {
273+
systemInstructions: undefined,
274+
input: 'hi',
275+
modelSettings: {
276+
reasoning: { effort: 'none' },
277+
},
278+
tools: [],
279+
outputType: 'text',
280+
handoffs: [],
281+
tracing: false,
282+
signal: undefined,
283+
};
284+
285+
await model.getResponse(request as any);
286+
287+
expect(createMock).toHaveBeenCalledTimes(1);
288+
const [args] = createMock.mock.calls[0];
289+
expect(args.reasoning).toEqual({ effort: 'none' });
290+
});
291+
});
292+
256293
it('getStreamedResponse yields events and calls client with stream flag', async () => {
257294
await withTrace('test', async () => {
258295
const fakeResponse = { id: 'res2', usage: {}, output: [] };

0 commit comments

Comments
 (0)