2023-04-02 04:15:07 +08:00
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
|
import { useSetRecoilState, useRecoilValue } from 'recoil';
|
|
|
|
|
import axios from 'axios';
|
2023-04-03 12:54:15 +08:00
|
|
|
import exportFromJSON from 'export-from-json';
|
2023-04-02 04:15:07 +08:00
|
|
|
import DialogTemplate from '../ui/DialogTemplate';
|
2023-04-03 12:54:15 +08:00
|
|
|
import { Dialog, DialogClose, DialogButton } from '../ui/Dialog.tsx';
|
2023-04-02 04:15:07 +08:00
|
|
|
import { Input } from '../ui/Input.tsx';
|
|
|
|
|
import { Label } from '../ui/Label.tsx';
|
|
|
|
|
import Dropdown from '../ui/Dropdown';
|
|
|
|
|
import { cn } from '~/utils/';
|
2023-04-04 01:12:14 +08:00
|
|
|
import cleanupPreset from '~/utils/cleanupPreset';
|
|
|
|
|
|
2023-04-02 04:15:07 +08:00
|
|
|
import OpenAISettings from './OpenAI/Settings';
|
2023-04-04 01:12:14 +08:00
|
|
|
import BingAISettings from './BingAI/Settings.jsx';
|
2023-04-02 04:15:07 +08:00
|
|
|
|
|
|
|
|
import store from '~/store';
|
|
|
|
|
|
|
|
|
|
const EditPresetDialog = ({ open, onOpenChange, preset: _preset }) => {
|
|
|
|
|
// const [title, setTitle] = useState('My Preset');
|
2023-04-04 01:39:40 +08:00
|
|
|
const [preset, setPreset] = useState(_preset);
|
2023-04-02 04:15:07 +08:00
|
|
|
const setPresets = useSetRecoilState(store.presets);
|
|
|
|
|
|
|
|
|
|
const availableEndpoints = useRecoilValue(store.availableEndpoints);
|
|
|
|
|
|
|
|
|
|
const setOption = param => newValue => {
|
|
|
|
|
let update = {};
|
|
|
|
|
update[param] = newValue;
|
|
|
|
|
setPreset(prevState => ({
|
|
|
|
|
...prevState,
|
|
|
|
|
...update
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const renderSettings = () => {
|
|
|
|
|
const { endpoint } = preset || {};
|
|
|
|
|
|
|
|
|
|
if (endpoint === 'openAI')
|
|
|
|
|
return (
|
|
|
|
|
<OpenAISettings
|
|
|
|
|
model={preset?.model}
|
|
|
|
|
setModel={setOption('model')}
|
|
|
|
|
chatGptLabel={preset?.chatGptLabel}
|
|
|
|
|
setChatGptLabel={setOption('chatGptLabel')}
|
|
|
|
|
promptPrefix={preset?.promptPrefix}
|
|
|
|
|
setPromptPrefix={setOption('promptPrefix')}
|
|
|
|
|
temperature={preset?.temperature}
|
|
|
|
|
setTemperature={setOption('temperature')}
|
|
|
|
|
topP={preset?.top_p}
|
|
|
|
|
setTopP={setOption('top_p')}
|
|
|
|
|
freqP={preset?.presence_penalty}
|
|
|
|
|
setFreqP={setOption('presence_penalty')}
|
|
|
|
|
presP={preset?.frequency_penalty}
|
|
|
|
|
setPresP={setOption('frequency_penalty')}
|
|
|
|
|
/>
|
|
|
|
|
);
|
2023-04-04 01:12:14 +08:00
|
|
|
else if (endpoint === 'bingAI')
|
|
|
|
|
return (
|
|
|
|
|
<BingAISettings
|
|
|
|
|
readonly={true}
|
|
|
|
|
context={preset?.context}
|
|
|
|
|
setContext={setOption('context')}
|
|
|
|
|
systemMessage={preset?.systemMessage}
|
|
|
|
|
setSystemMessage={setOption('systemMessage')}
|
|
|
|
|
jailbreak={preset?.jailbreak}
|
|
|
|
|
setJailbreak={setOption('jailbreak')}
|
|
|
|
|
/>
|
|
|
|
|
);
|
2023-04-02 04:15:07 +08:00
|
|
|
else return null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const defaultTextProps =
|
2023-04-02 04:40:13 +08:00
|
|
|
'rounded-md border border-gray-200 focus:border-slate-400 focus:bg-gray-50 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none placeholder:text-gray-400 focus:outline-none focus:ring-gray-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-500 dark:bg-gray-700 focus:dark:bg-gray-600 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-400 dark:focus:outline-none dark:focus:ring-0 dark:focus:ring-gray-400 dark:focus:ring-offset-0';
|
2023-04-02 04:15:07 +08:00
|
|
|
|
|
|
|
|
const submitPreset = () => {
|
|
|
|
|
axios({
|
|
|
|
|
method: 'post',
|
|
|
|
|
url: '/api/presets',
|
2023-04-04 01:12:14 +08:00
|
|
|
data: cleanupPreset(preset),
|
2023-04-02 04:15:07 +08:00
|
|
|
withCredentials: true
|
|
|
|
|
}).then(res => {
|
|
|
|
|
setPresets(res?.data);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2023-04-03 12:54:15 +08:00
|
|
|
const exportPreset = () => {
|
|
|
|
|
exportFromJSON({
|
2023-04-04 01:12:14 +08:00
|
|
|
data: cleanupPreset(preset),
|
2023-04-03 12:54:15 +08:00
|
|
|
fileName: `${preset?.title}.json`,
|
|
|
|
|
exportType: exportFromJSON.types.json
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2023-04-02 04:15:07 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
setPreset(_preset);
|
|
|
|
|
}, [open]);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Dialog
|
|
|
|
|
open={open}
|
|
|
|
|
onOpenChange={onOpenChange}
|
|
|
|
|
>
|
|
|
|
|
<DialogTemplate
|
|
|
|
|
title="Edit Preset"
|
|
|
|
|
className="max-w-full sm:max-w-4xl"
|
2023-04-01 19:42:09 -04:00
|
|
|
main={
|
|
|
|
|
<div className="flex w-full flex-col items-center gap-2">
|
|
|
|
|
<div className="grid w-full gap-6 sm:grid-cols-2">
|
|
|
|
|
<div className="col-span-1 flex flex-col items-start justify-start gap-2">
|
|
|
|
|
<Label
|
|
|
|
|
htmlFor="chatGptLabel"
|
|
|
|
|
className="text-left text-sm font-medium"
|
|
|
|
|
>
|
|
|
|
|
Preset Name
|
|
|
|
|
</Label>
|
|
|
|
|
<Input
|
|
|
|
|
id="chatGptLabel"
|
|
|
|
|
value={preset?.title || ''}
|
|
|
|
|
onChange={e => setOption('title')(e.target.value || '')}
|
|
|
|
|
placeholder="Set a custom name, in case you can find this preset"
|
|
|
|
|
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'
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="col-span-1 flex flex-col items-start justify-start gap-2">
|
|
|
|
|
<Label
|
|
|
|
|
htmlFor="endpoint"
|
|
|
|
|
className="text-left text-sm font-medium"
|
|
|
|
|
>
|
|
|
|
|
Endpoint
|
|
|
|
|
</Label>
|
|
|
|
|
<Dropdown
|
|
|
|
|
id="endpoint"
|
|
|
|
|
value={preset?.endpoint || ''}
|
|
|
|
|
onChange={setOption('endpoint')}
|
|
|
|
|
options={availableEndpoints}
|
|
|
|
|
className={cn(
|
|
|
|
|
defaultTextProps,
|
|
|
|
|
'flex h-10 max-h-10 w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0'
|
|
|
|
|
)}
|
|
|
|
|
containerClassName="flex w-full resize-none"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2023-04-02 04:15:07 +08:00
|
|
|
</div>
|
2023-04-01 19:42:09 -04:00
|
|
|
<div className="my-4 w-full border-t border-gray-300 dark:border-gray-500" />
|
|
|
|
|
<div className="w-full p-0">{renderSettings()}</div>
|
2023-04-02 04:15:07 +08:00
|
|
|
</div>
|
2023-04-01 19:42:09 -04:00
|
|
|
}
|
2023-04-03 12:54:15 +08:00
|
|
|
buttons={
|
|
|
|
|
<>
|
|
|
|
|
<DialogClose
|
|
|
|
|
onClick={submitPreset}
|
|
|
|
|
className="dark:hover:gray-400 border-gray-700 bg-green-600 text-white hover:bg-green-700 dark:hover:bg-green-800"
|
|
|
|
|
>
|
|
|
|
|
Save
|
|
|
|
|
</DialogClose>
|
|
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
leftButtons={
|
|
|
|
|
<>
|
|
|
|
|
<DialogButton
|
|
|
|
|
onClick={exportPreset}
|
2023-04-04 01:12:14 +08:00
|
|
|
className="dark:hover:gray-400 border-gray-700"
|
2023-04-03 12:54:15 +08:00
|
|
|
>
|
|
|
|
|
Export
|
|
|
|
|
</DialogButton>
|
|
|
|
|
</>
|
|
|
|
|
}
|
2023-04-02 04:15:07 +08:00
|
|
|
/>
|
|
|
|
|
</Dialog>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default EditPresetDialog;
|