Skip to content

Commit 5a9fed4

Browse files
committed
Add support for GPT-5.1 model and reasoning controls
closes #1966
1 parent 5cad75e commit 5a9fed4

File tree

7 files changed

+57
-8
lines changed

7 files changed

+57
-8
lines changed

src/backend/src/modules/puterai/OpenAiCompletionService/OpenAICompletionService.mjs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,18 @@ export class OpenAICompletionService {
109109
return this.#defaultModel;
110110
}
111111

112-
async complete({ messages, stream, model, tools, max_tokens, temperature }) {
112+
async complete({ messages, stream, model, tools, max_tokens, temperature, reasoning, text, reasoning_effort, verbosity }) {
113113
return await this.#complete(messages, {
114114
model: model,
115115
tools,
116116
moderation: true,
117117
stream,
118118
max_tokens,
119119
temperature,
120-
120+
reasoning,
121+
text,
122+
reasoning_effort,
123+
verbosity,
121124
});
122125
}
123126

@@ -166,6 +169,7 @@ export class OpenAICompletionService {
166169
async #complete(messages, {
167170
stream, moderation, model, tools,
168171
temperature, max_tokens,
172+
reasoning, text, reasoning_effort, verbosity,
169173
}) {
170174
// Validate messages
171175
if ( ! Array.isArray(messages) ) {
@@ -252,7 +256,11 @@ export class OpenAICompletionService {
252256
// that's missing. We normalise it here so the token count code works.
253257
messages = await OpenAIUtil.process_input_messages(messages);
254258

255-
const completion = await this.#openAi.chat.completions.create({
259+
const requestedReasoningEffort = reasoning_effort ?? reasoning?.effort;
260+
const requestedVerbosity = verbosity ?? text?.verbosity;
261+
const supportsReasoningControls = typeof model === 'string' && model.startsWith('gpt-5');
262+
263+
const completionParams = {
256264
user: user_private_uid,
257265
messages: messages,
258266
model: model,
@@ -263,7 +271,18 @@ export class OpenAICompletionService {
263271
...(stream ? {
264272
stream_options: { include_usage: true },
265273
} : {}),
266-
});
274+
};
275+
276+
if ( supportsReasoningControls ) {
277+
if ( requestedReasoningEffort ) {
278+
completionParams.reasoning_effort = requestedReasoningEffort;
279+
}
280+
if ( requestedVerbosity ) {
281+
completionParams.verbosity = requestedVerbosity;
282+
}
283+
}
284+
285+
const completion = await this.#openAi.chat.completions.create(completionParams);
267286
// TODO DS: simplify this logic for all the ai services, each service should handle its cost calculation in the service
268287
// for now I'm overloading this usage calculator to handle the future promise resolution...
269288
return OpenAIUtil.handle_completion_output({

src/backend/src/modules/puterai/OpenAiCompletionService/models.mjs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
// TODO DS: centralize somewhere
22

33
export const OPEN_AI_MODELS = [
4+
{
5+
id: 'gpt-5.1',
6+
cost: {
7+
currency: 'usd-cents',
8+
tokens: 1_000_000,
9+
input: 125,
10+
output: 1000,
11+
},
12+
max_tokens: 128000,
13+
},
414
{
515
id: 'gpt-5-2025-08-07',
616
aliases: ['gpt-5'],
@@ -163,4 +173,4 @@ export const OPEN_AI_MODELS = [
163173
output: 15000,
164174
},
165175
},
166-
];
176+
];

src/backend/src/services/MeteringService/costMaps/openAiCostMap.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
export const OPENAI_COST_MAP = {
2222
// GPT-5 models
23+
'openai:gpt-5.1:prompt_tokens': 125,
24+
'openai:gpt-5.1:cached_tokens': 13,
25+
'openai:gpt-5.1:completion_tokens': 1000,
2326
'openai:gpt-5-2025-08-07:prompt_tokens': 125,
2427
'openai:gpt-5-2025-08-07:cached_tokens': 13,
2528
'openai:gpt-5-2025-08-07:completion_tokens': 1000,

src/backend/src/services/MeteringService/costMaps/openrouterCostMap.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ export const OPENROUTER_COST_MAP = {
130130
'openrouter:openai/gpt-5-chat:prompt': 125,
131131
'openrouter:openai/gpt-5-chat:completion': 1000,
132132
'openrouter:openai/gpt-5-chat:input_cache_read': 12,
133+
'openrouter:openai/gpt-5.1:prompt': 125,
134+
'openrouter:openai/gpt-5.1:completion': 1000,
135+
'openrouter:openai/gpt-5.1:web_search': 1000000,
136+
'openrouter:openai/gpt-5.1:input_cache_read': 12,
133137
'openrouter:openai/gpt-5:prompt': 125,
134138
'openrouter:openai/gpt-5:completion': 1000,
135139
'openrouter:openai/gpt-5:web_search': 1000000,

src/puter-js/index.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ interface ChatOptions {
7878
stream?: boolean;
7979
max_tokens?: number;
8080
temperature?: number;
81+
reasoning?: {
82+
effort?: 'none' | 'low' | 'medium' | 'high' | 'minimal';
83+
[key: string]: unknown;
84+
};
85+
reasoning_effort?: 'none' | 'low' | 'medium' | 'high' | 'minimal';
86+
text?: {
87+
verbosity?: 'low' | 'medium' | 'high';
88+
[key: string]: unknown;
89+
};
90+
verbosity?: 'low' | 'medium' | 'high';
8191
tools?: ToolDefinition[];
8292
}
8393

src/puter-js/src/modules/AI.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ class AI{
809809
}
810810

811811
// Additional parameters to pass from userParams to requestParams
812-
const PARAMS_TO_PASS = ['tools', 'response'];
812+
const PARAMS_TO_PASS = ['tools', 'response', 'reasoning', 'reasoning_effort', 'text', 'verbosity'];
813813
for ( const name of PARAMS_TO_PASS ) {
814814
if ( userParams[name] ) {
815815
requestParams[name] = userParams[name];

src/puter-js/test/ai.test.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const TEST_MODELS = [
77
"openrouter:anthropic/claude-sonnet-4",
88
"google/gemini-2.5-pro",
99
"deepseek-chat",
10+
"gpt-5.1",
1011
"gpt-5-nano",
1112
"openai/gpt-5-nano",
1213
"claude-sonnet-4-latest",
@@ -48,7 +49,9 @@ const testChatWithParametersCore = async function(model) {
4849
const result = await puter.ai.chat("What is 2+2?", {
4950
model: model,
5051
temperature: 0.7,
51-
max_tokens: 50
52+
max_tokens: 50,
53+
reasoning: { effort: 'low' },
54+
text: { verbosity: 'low' },
5255
});
5356

5457
// Check basic result structure
@@ -212,4 +215,4 @@ const generateAllTests = function() {
212215
};
213216

214217
// Export the generated tests
215-
window.aiTests = generateAllTests();
218+
window.aiTests = generateAllTests();

0 commit comments

Comments
 (0)