OpenAI web_search support (#2299)
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test-backend (24.x) (push) Has been cancelled
test / API tests (node env, api-test) (24.x) (push) Has been cancelled
test / puterjs (node env, vitest) (24.x) (push) Has been cancelled

This commit is contained in:
Neal Shah
2026-01-19 00:01:47 +05:30
committed by GitHub
parent f9888e6705
commit e95aa81e00
4 changed files with 29 additions and 8 deletions
@@ -99,8 +99,16 @@ export class OpenAiChatProvider implements IChatProvider {
return this.#defaultModel;
}
async complete ({ messages, model, max_tokens, moderation, tools, verbosity, stream, reasoning, reasoning_effort, temperature, text }: ICompleteArguments): ReturnType<IChatProvider['complete']>
async complete (params: ICompleteArguments): ReturnType<IChatProvider['complete']>
{
let { messages, model, max_tokens, moderation, tools, verbosity, stream, reasoning, reasoning_effort, temperature, text } = params;
if ( tools?.filter((e: any) => e.type === 'web_search').length ) {
// User is trying to use openai-responses only tool web_search.
// We should pass it to that service
const aiChat = (Context.get('services') as any).get('ai-chat');
const openAIresponses = aiChat.getProvider('openai-responses')!;
return await openAIresponses.complete!(params);
}
// Validate messages
if ( ! Array.isArray(messages) ) {
throw new Error('`messages` must be an array');
@@ -79,12 +79,16 @@ export class OpenAiResponsesChatProvider implements IChatProvider {
* Returns an array of available AI models with their pricing information.
* Each model object includes an ID and cost details (currency, tokens, input/output rates).
*/
models () {
models (extra_params) {
if ( extra_params?.no_restrictions )
{
return OPEN_AI_MODELS;
}
return OPEN_AI_MODELS.filter(e => e.responses_api_only === true);
}
list () {
const models = this.models();
const models = this.models({ no_restrictions: false });
const modelNames: string[] = [];
for ( const model of models ) {
modelNames.push(model.id);
@@ -109,7 +113,7 @@ export class OpenAiResponsesChatProvider implements IChatProvider {
model = model ?? this.#defaultModel;
const modelUsed = (this.models()).find(m => [m.id, ...(m.aliases || [])].includes(model)) || (this.models()).find(m => m.id === this.getDefaultModel())!;
const modelUsed = (this.models({ no_restrictions: true })).find(m => [m.id, ...(m.aliases || [])].includes(model)) || (this.models(({ no_restrictions: true })).find(m => m.id === this.getDefaultModel())!);
// messages.unshift({
// role: 'system',
@@ -186,9 +190,13 @@ export class OpenAiResponsesChatProvider implements IChatProvider {
if ( tools ) {
// Unravel tools to OpenAI Responses API format
tools = (tools as any).map((e) => {
const tool = e.function;
tool.type = 'function';
return tool;
if ( e.type === 'function' ) {
const tool = e.function;
tool.type = 'function';
return tool;
} else {
return e;
}
});
}
@@ -39,7 +39,7 @@ export interface ICompleteArguments {
}
export interface IChatProvider {
models(): IChatModel[] | Promise<IChatModel[]>
models(extra_params?: any): IChatModel[] | Promise<IChatModel[]>
list(): string[] | Promise<string[]>
checkModeration (text: string): Promise<{
flagged: boolean;
@@ -41,6 +41,11 @@ export const normalize_json_schema = (schema) => {
export const normalize_tools_object = (tools) => {
for ( let i = 0 ; i < tools.length ; i++ ) {
const tool = tools[i];
if ( tool.type === 'web_search' ) {
// OpenAI Responses specific
continue;
}
let normalized_tool = {};
const normalize_function = fn => {