mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 01:10:14 +01:00
Fix: Azure "user_provided" Frontend Credentials and Save Last Selected Bing Settings (#587)
* fix(Messages.jsx): fix <body> tag warning * fix(NewConversationMenu): update localStorage with lastBingSettings when endpoint is 'bingAI' fix(getDefaultConversation): retrieve lastBingSettings from localStorage and use it to set default values for jailbreak and toneStyle when endpoint is 'bingAI' feat(settings.spec.js): add test to check if the active class is set on the selected endpoint in the settings menu * fix(BingAIOptions): add data-testid to BingAIOptions SelectDropDown component fix(settings.spec.js): update test to include additional steps for testing settings persistence * fix(azure): support user_provided credentials from client
This commit is contained in:
parent
04e4259005
commit
75250f3a5f
7 changed files with 76 additions and 15 deletions
|
|
@ -141,7 +141,7 @@ const ask = async ({ text, endpointOption, parentMessageId = null, endpoint, con
|
||||||
let oaiApiKey = req.body?.token ?? process.env.OPENAI_API_KEY;
|
let oaiApiKey = req.body?.token ?? process.env.OPENAI_API_KEY;
|
||||||
|
|
||||||
if (process.env.AZURE_API_KEY && endpoint === 'azureOpenAI') {
|
if (process.env.AZURE_API_KEY && endpoint === 'azureOpenAI') {
|
||||||
clientOptions.azure = getAzureCredentials();
|
clientOptions.azure = JSON.parse(req.body?.token) ?? getAzureCredentials();
|
||||||
// clientOptions.reverseProxyUrl = process.env.AZURE_REVERSE_PROXY ?? genAzureChatCompletion({ ...clientOptions.azure });
|
// clientOptions.reverseProxyUrl = process.env.AZURE_REVERSE_PROXY ?? genAzureChatCompletion({ ...clientOptions.azure });
|
||||||
oaiApiKey = clientOptions.azure.azureOpenAIApiKey;
|
oaiApiKey = clientOptions.azure.azureOpenAIApiKey;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ function BingAIOptions({ show }) {
|
||||||
<SelectDropDown
|
<SelectDropDown
|
||||||
title="Mode"
|
title="Mode"
|
||||||
value={jailbreak ? 'Sydney' : 'BingAI'}
|
value={jailbreak ? 'Sydney' : 'BingAI'}
|
||||||
|
data-testid="bing-select-dropdown"
|
||||||
setValue={(value) => setOption('jailbreak')(value === 'Sydney')}
|
setValue={(value) => setOption('jailbreak')(value === 'Sydney')}
|
||||||
availableValues={['BingAI', 'Sydney']}
|
availableValues={['BingAI', 'Sydney']}
|
||||||
showAbove={true}
|
showAbove={true}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,15 @@ export default function NewConversationMenu() {
|
||||||
);
|
);
|
||||||
localStorage.setItem('lastConversationSetup', JSON.stringify(conversation));
|
localStorage.setItem('lastConversationSetup', JSON.stringify(conversation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (endpoint === 'bingAI') {
|
||||||
|
const lastBingSettings = JSON.parse(localStorage.getItem('lastBingSettings')) || {};
|
||||||
|
const { jailbreak, toneStyle } = conversation;
|
||||||
|
localStorage.setItem(
|
||||||
|
'lastBingSettings',
|
||||||
|
JSON.stringify({ ...lastBingSettings, jailbreak, toneStyle })
|
||||||
|
);
|
||||||
|
}
|
||||||
}, [conversation]);
|
}, [conversation]);
|
||||||
|
|
||||||
// set the current model
|
// set the current model
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
|
||||||
setToken(JSON.stringify(data));
|
setToken(JSON.stringify(data));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : endpoint === 'openAI' ? (
|
) : endpoint === 'openAI' || endpoint === 'azureOpenAI' ? (
|
||||||
<>
|
<>
|
||||||
{!showPanel ? (
|
{!showPanel ? (
|
||||||
<>
|
<>
|
||||||
|
|
@ -196,29 +196,29 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
|
||||||
<>
|
<>
|
||||||
<InputWithLabel
|
<InputWithLabel
|
||||||
id={'instanceNameLabel'}
|
id={'instanceNameLabel'}
|
||||||
value={getAzure('instanceName') || ''}
|
value={getAzure('azureOpenAIApiInstanceName') || ''}
|
||||||
onChange={(e) => setAzure('instanceName', e.target.value || '')}
|
onChange={(e) => setAzure('azureOpenAIApiInstanceName', e.target.value || '')}
|
||||||
label={'Azure OpenAI Instance Name'}
|
label={'Azure OpenAI Instance Name'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<InputWithLabel
|
<InputWithLabel
|
||||||
id={'deploymentNameLabel'}
|
id={'deploymentNameLabel'}
|
||||||
value={getAzure('deploymentName') || ''}
|
value={getAzure('azureOpenAIApiDeploymentName') || ''}
|
||||||
onChange={(e) => setAzure('deploymentName', e.target.value || '')}
|
onChange={(e) => setAzure('azureOpenAIApiDeploymentName', e.target.value || '')}
|
||||||
label={'Azure OpenAI Deployment Name'}
|
label={'Azure OpenAI Deployment Name'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<InputWithLabel
|
<InputWithLabel
|
||||||
id={'versionLabel'}
|
id={'versionLabel'}
|
||||||
value={getAzure('version') || ''}
|
value={getAzure('azureOpenAIApiVersion') || ''}
|
||||||
onChange={(e) => setAzure('version', e.target.value || '')}
|
onChange={(e) => setAzure('azureOpenAIApiVersion', e.target.value || '')}
|
||||||
label={'Azure OpenAI API Version'}
|
label={'Azure OpenAI API Version'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<InputWithLabel
|
<InputWithLabel
|
||||||
id={'apiKeyLabel'}
|
id={'apiKeyLabel'}
|
||||||
value={getAzure('apiKey') || ''}
|
value={getAzure('azureOpenAIApiKey') || ''}
|
||||||
onChange={(e) => setAzure('apiKey', e.target.value || '')}
|
onChange={(e) => setAzure('azureOpenAIApiKey', e.target.value || '')}
|
||||||
label={'Azure OpenAI API Key'}
|
label={'Azure OpenAI API Key'}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
@ -227,7 +227,7 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
|
||||||
<Checkbox.Root
|
<Checkbox.Root
|
||||||
className="flex h-[20px] w-[20px] appearance-none items-center justify-center rounded-[4px] bg-gray-100 text-white outline-none hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-900"
|
className="flex h-[20px] w-[20px] appearance-none items-center justify-center rounded-[4px] bg-gray-100 text-white outline-none hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-900"
|
||||||
id="azureOpenAI"
|
id="azureOpenAI"
|
||||||
checked={showPanel}
|
checked={showPanel && endpoint === 'azureOpenAI'}
|
||||||
onCheckedChange={() => setShowPanel(!showPanel)}
|
onCheckedChange={() => setShowPanel(!showPanel)}
|
||||||
>
|
>
|
||||||
<Checkbox.Indicator className="flex h-[20px] w-[20px] items-center justify-center rounded-[3.5px] bg-green-600">
|
<Checkbox.Indicator className="flex h-[20px] w-[20px] items-center justify-center rounded-[3.5px] bg-green-600">
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,9 @@ export default function Messages({ isSearchView = false }) {
|
||||||
<div className="dark:gpt-dark-gray flex h-auto flex-col items-center text-sm">
|
<div className="dark:gpt-dark-gray flex h-auto flex-col items-center text-sm">
|
||||||
<MessageHeader isSearchView={isSearchView} />
|
<MessageHeader isSearchView={isSearchView} />
|
||||||
{_messagesTree === null ? (
|
{_messagesTree === null ? (
|
||||||
<body className="h-screen flex items-center justify-center">
|
<div className="h-screen flex items-center justify-center">
|
||||||
<Spinner />
|
<Spinner />
|
||||||
</body>
|
</div>
|
||||||
) : _messagesTree?.length == 0 && isSearchView ? (
|
) : _messagesTree?.length == 0 && isSearchView ? (
|
||||||
<div className="flex w-full items-center justify-center gap-1 bg-gray-50 p-3 text-sm text-gray-500 dark:border-gray-900/50 dark:bg-gray-800 dark:text-gray-300">
|
<div className="flex w-full items-center justify-center gap-1 bg-gray-50 p-3 text-sm text-gray-500 dark:border-gray-900/50 dark:bg-gray-800 dark:text-gray-300">
|
||||||
Nothing found
|
Nothing found
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ const buildDefaultConversation = ({
|
||||||
}) => {
|
}) => {
|
||||||
const lastSelectedModel = JSON.parse(localStorage.getItem('lastSelectedModel')) || {};
|
const lastSelectedModel = JSON.parse(localStorage.getItem('lastSelectedModel')) || {};
|
||||||
const lastSelectedTools = JSON.parse(localStorage.getItem('lastSelectedTools')) || [];
|
const lastSelectedTools = JSON.parse(localStorage.getItem('lastSelectedTools')) || [];
|
||||||
|
const lastBingSettings = JSON.parse(localStorage.getItem('lastBingSettings')) || [];
|
||||||
|
|
||||||
if (endpoint === 'azureOpenAI' || endpoint === 'openAI') {
|
if (endpoint === 'azureOpenAI' || endpoint === 'openAI') {
|
||||||
conversation = {
|
conversation = {
|
||||||
|
|
@ -43,13 +44,14 @@ const buildDefaultConversation = ({
|
||||||
topK: lastConversationSetup?.topK ?? 40
|
topK: lastConversationSetup?.topK ?? 40
|
||||||
};
|
};
|
||||||
} else if (endpoint === 'bingAI') {
|
} else if (endpoint === 'bingAI') {
|
||||||
|
const { jailbreak, toneStyle } = lastBingSettings;
|
||||||
conversation = {
|
conversation = {
|
||||||
...conversation,
|
...conversation,
|
||||||
endpoint,
|
endpoint,
|
||||||
jailbreak: lastConversationSetup?.jailbreak ?? false,
|
jailbreak: lastConversationSetup?.jailbreak ?? jailbreak ?? false,
|
||||||
context: lastConversationSetup?.context ?? null,
|
context: lastConversationSetup?.context ?? null,
|
||||||
systemMessage: lastConversationSetup?.systemMessage ?? null,
|
systemMessage: lastConversationSetup?.systemMessage ?? null,
|
||||||
toneStyle: lastConversationSetup?.toneStyle ?? 'creative',
|
toneStyle: lastConversationSetup?.toneStyle ?? toneStyle ?? 'creative',
|
||||||
jailbreakConversationId: lastConversationSetup?.jailbreakConversationId ?? null,
|
jailbreakConversationId: lastConversationSetup?.jailbreakConversationId ?? null,
|
||||||
conversationSignature: null,
|
conversationSignature: null,
|
||||||
clientId: null,
|
clientId: null,
|
||||||
|
|
|
||||||
49
e2e/specs/settings.spec.js
Normal file
49
e2e/specs/settings.spec.js
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
|
test.describe('Settings suite', () => {
|
||||||
|
test('Last Bing settings', async ({ page }) => {
|
||||||
|
await page.goto('http://localhost:3080/');
|
||||||
|
const newTopicButton = await page.getByRole('button', { name: 'New Topic' });
|
||||||
|
await newTopicButton.click();
|
||||||
|
|
||||||
|
// includes the icon + endpoint names in obj property
|
||||||
|
const endpointItem = await page.getByRole('menuitemradio', { name: 'BingAI Bing' })
|
||||||
|
await endpointItem.click();
|
||||||
|
|
||||||
|
await page.getByTestId('text-input').click();
|
||||||
|
const button1 = await page.getByRole('button', { name: 'Mode: BingAI' });
|
||||||
|
const button2 = await page.getByRole('button', { name: 'Mode: Sydney' });
|
||||||
|
|
||||||
|
try {
|
||||||
|
await button1.click({ timeout: 100});
|
||||||
|
} catch (e) {
|
||||||
|
// console.log('Bing button', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await button2.click({ timeout: 100});
|
||||||
|
} catch (e) {
|
||||||
|
// console.log('Sydney button', e);
|
||||||
|
}
|
||||||
|
await page.getByRole('option', { name: 'Sydney' }).click();
|
||||||
|
await page.getByRole('tab', { name: 'Balanced' }).click();
|
||||||
|
|
||||||
|
// Change Endpoint to see if settings will persist
|
||||||
|
await newTopicButton.click();
|
||||||
|
await page.getByRole('menuitemradio', { name: 'ChatGPT OpenAI' }).click();
|
||||||
|
|
||||||
|
// Close endpoint menu & re-select BingAI
|
||||||
|
await page.getByTestId('text-input').click();
|
||||||
|
await newTopicButton.click();
|
||||||
|
await endpointItem.click();
|
||||||
|
|
||||||
|
// Check if the settings persisted
|
||||||
|
const localStorage = await page.evaluate(() => window.localStorage);
|
||||||
|
const lastBingSettings = JSON.parse(localStorage.lastBingSettings);
|
||||||
|
const { jailbreak, toneStyle } = lastBingSettings;
|
||||||
|
expect(jailbreak).toBeTruthy();
|
||||||
|
expect(toneStyle).toEqual('balanced');
|
||||||
|
const button = await page.getByRole('button', { name: 'Mode: Sydney' });
|
||||||
|
expect((button).count()).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue