Added functionality to allow users to set custom api keys (#276)

* Added functionality to allow users to set custom api keys

* Added error handling

* Changed token to apiKey

* Changed apiKey to oaiApiKey

* added azure openai ui

* Removed logging

* Changed configure to Use

* Made checked position more rounded

* Made setting api key optional if it is openai

* Modified error handling

* Add support for insufficient_quota errors

* Fixed faulty error detection

* removed logging
This commit is contained in:
Anirudh 2023-05-18 04:51:30 +05:30 committed by GitHub
parent 08f3a77d58
commit 14104b276f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 207 additions and 32 deletions

View file

@ -4,11 +4,24 @@ import { Dialog } from '../../ui/Dialog.tsx';
import { Input } from '../../ui/Input.tsx';
import { Label } from '../../ui/Label.tsx';
import { cn } from '~/utils/';
import * as Checkbox from '@radix-ui/react-checkbox';
import { CheckIcon } from '@radix-ui/react-icons';
import FileUpload from '../NewConversationMenu/FileUpload';
import store from '~/store';
import InputWithLabel from './InputWithLabel';
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
const [token, setToken] = useState('');
const [showPanel, setShowPanel] = useState(false);
const { getToken, saveToken } = store.useToken(endpoint);
const defaultTextProps =
@ -20,9 +33,19 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
};
useEffect(() => {
setToken(getToken() ?? '');
let oldToken = getToken();
if (isJson(token)) {
setShowPanel(true);
}
setToken(oldToken ?? '');
}, [open]);
useEffect(() => {
if (!showPanel && isJson(token)) {
setToken('');
}
}, [showPanel]);
const helpText = {
bingAI: (
<small className="break-all text-gray-600">
@ -79,6 +102,25 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
)
};
function getAzure(name) {
if (isJson(token)) {
let newToken = JSON.parse(token);
return newToken[name];
} else {
return '';
}
}
function setAzure(name, value) {
let newToken = {};
if (isJson(token)) {
newToken = JSON.parse(token);
}
newToken[name] = value;
setToken(JSON.stringify(newToken));
}
return (
<Dialog
open={open}
@ -88,16 +130,9 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
title={`Set Token of ${endpoint}`}
main={
<div className="grid w-full items-center gap-2">
<Label
htmlFor="chatGptLabel"
className="text-left text-sm font-medium"
>
Token Name
<br />
</Label>
{endpoint === 'google' ? (
<FileUpload
id="googleKey"
id="googleKey"
className="w-full"
text="Import Service Account JSON Key"
successText="Successfully Imported Service Account JSON Key"
@ -137,17 +172,77 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
setToken(JSON.stringify(data));
}}
/>
) : (
<Input
id="chatGptLabel"
value={token || ''}
onChange={e => setToken(e.target.value || '')}
placeholder="Set the token."
className={cn(
defaultTextProps,
'flex h-10 max-h-10 w-full resize-none px-3 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0'
) : endpoint === 'openAI' ? (
<>
{!showPanel ? (
<>
<InputWithLabel
id={'chatGPTLabel'}
value={token || ''}
onChange={e => setToken(e.target.value || '')}
label={'OpenAI API Key'}
/>
</>
) : (
<>
<InputWithLabel
id={'instanceNameLabel'}
value={getAzure('instanceName') || ''}
onChange={e => setAzure('instanceName', e.target.value || '')}
label={'Azure OpenAI Instance Name'}
/>
<InputWithLabel
id={'deploymentNameLabel'}
value={getAzure('deploymentName') || ''}
onChange={e => setAzure('deploymentName', e.target.value || '')}
label={'Azure OpenAI Deployment Name'}
/>
<InputWithLabel
id={'versionLabel'}
value={getAzure('version') || ''}
onChange={e => setAzure('version', e.target.value || '')}
label={'Azure OpenAI API Version'}
/>
<InputWithLabel
id={'apiKeyLabel'}
value={getAzure('apiKey') || ''}
onChange={e => setAzure('apiKey', e.target.value || '')}
label={'Azure OpenAI API Key'}
/>
</>
)}
/>
<div className="flex items-center">
<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"
id="azureOpenAI"
checked={showPanel}
onCheckedChange={() => setShowPanel(!showPanel)}
>
<Checkbox.Indicator className="flex h-[20px] w-[20px] items-center justify-center rounded-[3.5px] bg-green-600">
<CheckIcon />
</Checkbox.Indicator>
</Checkbox.Root>
<label
className="pl-[8px] text-[15px] leading-none dark:text-white"
htmlFor="azureOpenAI"
>
Use Azure OpenAI.
</label>
</div>
</>
) : (
<>
<InputWithLabel
id={'chatGPTLabel'}
value={token || ''}
onChange={e => setToken(e.target.value || '')}
label={'Token Name'}
/>
</>
)}
<small className="text-red-600">Your token will be sent to the server, but not saved.</small>
{helpText?.[endpoint]}