🪐 feat: Initial OpenAI Responses API Support (#8149)

* chore: update @librechat/agents to v2.4.47

* WIP: temporary auto-toggle responses api for o1/o3-pro

* feat: Enable Responses API for OpenAI models

- Updated the OpenAI client initialization to check for the useResponsesApi parameter in model options.
- Added translations for enabling the Responses API in the UI.
- Introduced useResponsesApi parameter in data provider settings and schemas.
- Updated relevant schemas to include useResponsesApi for conversation and preset configurations.

* refactor: Remove useResponsesApi check from OpenAI client initialization and update translation for Responses API

- Removed the check for useResponsesApi in the OpenAI client initialization.
- Updated the translation for enabling the Responses API to clarify its functionality.

* chore: update @librechat/agents dependency to version 2.4.48

* chore: update @librechat/agents dependency to version 2.4.49

* chore: linting

* chore: linting

* feat: Enhance DynamicSlider and validation for enumMappings

- Added support for enumMappings in DynamicSlider to display values correctly based on enum settings.
- Implemented validation for enumMappings in the generate function to ensure all options have corresponding mappings.
- Added tests for handling empty string options and incomplete enumMappings in the generate.spec.ts file.

* feat: Enhance DynamicSlider localization support

- Added localization handling for mapped values in DynamicSlider when using enumMappings.
- Updated the logic to check if the mapped value is a localization key and return the localized string if applicable.
- Adjusted dependencies in useCallback hooks to include localize for proper functionality.

* feat: Add reasoning summary and effort options to OpenAI configuration and UI

* feat: Add enumMappings for ImageDetail options in parameter settings

* style: Improve styling for DynamicSlider component labels and inputs

* chore: Update reasoning effort description and parameter order for OpenAI params

---------

Co-authored-by: Dustin Healy <dustinhealy1@gmail.com>
This commit is contained in:
Danny Avila 2025-06-30 18:34:47 -04:00 committed by GitHub
parent 20100e120b
commit f869d772f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 355 additions and 83 deletions

View file

@ -1,4 +1,3 @@
/* eslint-disable jest/no-conditional-expect */
import { ZodError, z } from 'zod';
import { generateDynamicSchema, validateSettingDefinitions, OptionTypes } from '../src/generate';
import type { SettingsConfiguration } from '../src/generate';
@ -97,6 +96,37 @@ describe('generateDynamicSchema', () => {
expect(result['data']).toEqual({ testEnum: 'option2' });
});
it('should generate a schema for enum settings with empty string option', () => {
const settings: SettingsConfiguration = [
{
key: 'testEnumWithEmpty',
description: 'A test enum setting with empty string',
type: 'enum',
default: '',
options: ['', 'option1', 'option2'],
enumMappings: {
'': 'None',
option1: 'First Option',
option2: 'Second Option',
},
component: 'slider',
columnSpan: 2,
label: 'Test Enum with Empty String',
},
];
const schema = generateDynamicSchema(settings);
const result = schema.safeParse({ testEnumWithEmpty: '' });
expect(result.success).toBeTruthy();
expect(result['data']).toEqual({ testEnumWithEmpty: '' });
// Test with non-empty option
const result2 = schema.safeParse({ testEnumWithEmpty: 'option1' });
expect(result2.success).toBeTruthy();
expect(result2['data']).toEqual({ testEnumWithEmpty: 'option1' });
});
it('should fail for incorrect enum value', () => {
const settings: SettingsConfiguration = [
{
@ -481,6 +511,47 @@ describe('validateSettingDefinitions', () => {
expect(() => validateSettingDefinitions(settingsExceedingMaxTags)).toThrow(ZodError);
});
// Test for incomplete enumMappings
test('should throw error for incomplete enumMappings', () => {
const settingsWithIncompleteEnumMappings: SettingsConfiguration = [
{
key: 'displayMode',
type: 'enum',
component: 'dropdown',
options: ['light', 'dark', 'auto'],
enumMappings: {
light: 'Light Mode',
dark: 'Dark Mode',
// Missing mapping for 'auto'
},
optionType: OptionTypes.Custom,
},
];
expect(() => validateSettingDefinitions(settingsWithIncompleteEnumMappings)).toThrow(ZodError);
});
// Test for complete enumMappings including empty string
test('should not throw error for complete enumMappings including empty string', () => {
const settingsWithCompleteEnumMappings: SettingsConfiguration = [
{
key: 'selectionMode',
type: 'enum',
component: 'slider',
options: ['', 'single', 'multiple'],
enumMappings: {
'': 'None',
single: 'Single Selection',
multiple: 'Multiple Selection',
},
default: '',
optionType: OptionTypes.Custom,
},
];
expect(() => validateSettingDefinitions(settingsWithCompleteEnumMappings)).not.toThrow();
});
});
const settingsConfiguration: SettingsConfiguration = [
@ -515,7 +586,7 @@ const settingsConfiguration: SettingsConfiguration = [
{
key: 'presence_penalty',
description:
'Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model\'s likelihood to talk about new topics.',
"Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics.",
type: 'number',
default: 0,
range: {
@ -529,7 +600,7 @@ const settingsConfiguration: SettingsConfiguration = [
{
key: 'frequency_penalty',
description:
'Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model\'s likelihood to repeat the same line verbatim.',
"Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim.",
type: 'number',
default: 0,
range: {