Spaces:
Sleeping
Sleeping
| import axios from 'axios'; | |
| import { useEffect, useState } from 'react'; | |
| import Settings from './Settings'; | |
| import Examples from './Google/Examples.jsx'; | |
| import exportFromJSON from 'export-from-json'; | |
| import AgentSettings from './Plugins/AgentSettings.jsx'; | |
| import { useSetRecoilState, useRecoilValue } from 'recoil'; | |
| import filenamify from 'filenamify'; | |
| import { | |
| MessagesSquared, | |
| GPTIcon, | |
| Input, | |
| Label, | |
| Button, | |
| Dropdown, | |
| Dialog, | |
| DialogClose, | |
| DialogButton, | |
| DialogTemplate, | |
| } from '~/components/'; | |
| import { cn } from '~/utils/'; | |
| import cleanupPreset from '~/utils/cleanupPreset'; | |
| import { localize } from '~/localization/Translation'; | |
| import store from '~/store'; | |
| const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => { | |
| const lang = useRecoilValue(store.lang); | |
| const [preset, setPreset] = useState(_preset); | |
| const setPresets = useSetRecoilState(store.presets); | |
| const [showExamples, setShowExamples] = useState(false); | |
| const [showAgentSettings, setShowAgentSettings] = useState(false); | |
| const availableEndpoints = useRecoilValue(store.availableEndpoints); | |
| const endpointsConfig = useRecoilValue(store.endpointsConfig); | |
| const triggerExamples = () => setShowExamples((prev) => !prev); | |
| const triggerAgentSettings = () => setShowAgentSettings((prev) => !prev); | |
| const setOption = (param) => (newValue) => { | |
| let update = {}; | |
| update[param] = newValue; | |
| setPreset((prevState) => | |
| cleanupPreset({ | |
| preset: { | |
| ...prevState, | |
| ...update, | |
| }, | |
| endpointsConfig, | |
| }), | |
| ); | |
| }; | |
| const setAgentOption = (param) => (newValue) => { | |
| let editablePreset = JSON.stringify(_preset); | |
| editablePreset = JSON.parse(editablePreset); | |
| let { agentOptions } = editablePreset; | |
| agentOptions[param] = newValue; | |
| setPreset((prevState) => | |
| cleanupPreset({ | |
| preset: { | |
| ...prevState, | |
| agentOptions, | |
| }, | |
| endpointsConfig, | |
| }), | |
| ); | |
| }; | |
| const setExample = (i, type, newValue = null) => { | |
| let update = {}; | |
| let current = preset?.examples.slice() || []; | |
| let currentExample = { ...current[i] } || {}; | |
| currentExample[type] = { content: newValue }; | |
| current[i] = currentExample; | |
| update.examples = current; | |
| setPreset((prevState) => | |
| cleanupPreset({ | |
| preset: { | |
| ...prevState, | |
| ...update, | |
| }, | |
| endpointsConfig, | |
| }), | |
| ); | |
| }; | |
| const addExample = () => { | |
| let update = {}; | |
| let current = preset?.examples.slice() || []; | |
| current.push({ input: { content: '' }, output: { content: '' } }); | |
| update.examples = current; | |
| setPreset((prevState) => | |
| cleanupPreset({ | |
| preset: { | |
| ...prevState, | |
| ...update, | |
| }, | |
| endpointsConfig, | |
| }), | |
| ); | |
| }; | |
| const removeExample = () => { | |
| let update = {}; | |
| let current = preset?.examples.slice() || []; | |
| if (current.length <= 1) { | |
| update.examples = [{ input: { content: '' }, output: { content: '' } }]; | |
| setPreset((prevState) => | |
| cleanupPreset({ | |
| preset: { | |
| ...prevState, | |
| ...update, | |
| }, | |
| endpointsConfig, | |
| }), | |
| ); | |
| return; | |
| } | |
| current.pop(); | |
| update.examples = current; | |
| setPreset((prevState) => | |
| cleanupPreset({ | |
| preset: { | |
| ...prevState, | |
| ...update, | |
| }, | |
| endpointsConfig, | |
| }), | |
| ); | |
| }; | |
| const defaultTextProps = | |
| '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'; | |
| const submitPreset = () => { | |
| axios({ | |
| method: 'post', | |
| url: '/api/presets', | |
| data: cleanupPreset({ preset, endpointsConfig }), | |
| withCredentials: true, | |
| }).then((res) => { | |
| setPresets(res?.data); | |
| }); | |
| }; | |
| const exportPreset = () => { | |
| const fileName = filenamify(preset?.title || 'preset'); | |
| exportFromJSON({ | |
| data: cleanupPreset({ preset, endpointsConfig }), | |
| fileName, | |
| exportType: exportFromJSON.types.json, | |
| }); | |
| }; | |
| useEffect(() => { | |
| setPreset(_preset); | |
| // eslint-disable-next-line react-hooks/exhaustive-deps | |
| }, [open]); | |
| const endpoint = preset?.endpoint; | |
| const isGoogle = endpoint === 'google'; | |
| const isGptPlugins = endpoint === 'gptPlugins'; | |
| const shouldShowSettings = | |
| (isGoogle && !showExamples) || | |
| (isGptPlugins && !showAgentSettings) || | |
| (!isGoogle && !isGptPlugins); | |
| return ( | |
| <Dialog open={open} onOpenChange={onOpenChange}> | |
| <DialogTemplate | |
| title={`${title || localize(lang, 'com_endpoint_edit_preset')} - ${preset?.title}`} | |
| className="h-[675px] max-w-full sm:max-w-4xl " | |
| main={ | |
| <div className="flex w-full flex-col items-center gap-2 md:h-[475px]"> | |
| <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"> | |
| {localize(lang, 'com_endpoint_preset_name')} | |
| </Label> | |
| <Input | |
| id="chatGptLabel" | |
| value={preset?.title || ''} | |
| onChange={(e) => setOption('title')(e.target.value || '')} | |
| placeholder={localize(lang, 'com_endpoint_set_custom_name')} | |
| 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"> | |
| {localize(lang, 'com_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" | |
| /> | |
| {preset?.endpoint === 'google' && ( | |
| <Button | |
| type="button" | |
| className="ml-1 flex h-auto w-full bg-transparent px-2 py-1 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0" | |
| onClick={triggerExamples} | |
| > | |
| <MessagesSquared className="mr-1 w-[14px]" /> | |
| {(showExamples | |
| ? localize(lang, 'com_endpoint_hide') | |
| : localize(lang, 'com_endpoint_show')) + | |
| localize(lang, 'com_endpoint_examples')} | |
| </Button> | |
| )} | |
| {preset?.endpoint === 'gptPlugins' && ( | |
| <Button | |
| type="button" | |
| className="ml-1 flex h-auto w-full bg-transparent px-2 py-1 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0" | |
| onClick={triggerAgentSettings} | |
| > | |
| <GPTIcon className="mr-1 mt-[2px] w-[14px]" size={14} /> | |
| {`Show ${showAgentSettings ? 'Completion' : 'Agent'} Settings`} | |
| {localize( | |
| lang, | |
| 'com_endpoint_show_what_settings', | |
| showAgentSettings | |
| ? localize(lang, 'com_endpoint_completion') | |
| : localize(lang, 'com_endpoint_agent'), | |
| )} | |
| </Button> | |
| )} | |
| </div> | |
| </div> | |
| <div className="my-4 w-full border-t border-gray-300 dark:border-gray-500" /> | |
| <div className="w-full p-0"> | |
| {shouldShowSettings && <Settings preset={preset} setOption={setOption} />} | |
| {preset?.endpoint === 'google' && | |
| showExamples && | |
| !preset?.model?.startsWith('codechat-') && ( | |
| <Examples | |
| examples={preset.examples} | |
| setExample={setExample} | |
| addExample={addExample} | |
| removeExample={removeExample} | |
| edit={true} | |
| /> | |
| )} | |
| {preset?.endpoint === 'gptPlugins' && showAgentSettings && ( | |
| <AgentSettings | |
| agent={preset.agentOptions.agent} | |
| skipCompletion={preset.agentOptions.skipCompletion} | |
| model={preset.agentOptions.model} | |
| endpoint={preset.agentOptions.endpoint} | |
| temperature={preset.agentOptions.temperature} | |
| topP={preset.agentOptions.top_p} | |
| freqP={preset.agentOptions.presence_penalty} | |
| presP={preset.agentOptions.frequency_penalty} | |
| setOption={setAgentOption} | |
| tools={preset.tools} | |
| /> | |
| )} | |
| </div> | |
| </div> | |
| } | |
| 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" | |
| > | |
| {localize(lang, 'com_endpoint_save')} | |
| </DialogClose> | |
| </> | |
| } | |
| leftButtons={ | |
| <> | |
| <DialogButton onClick={exportPreset} className="dark:hover:gray-400 border-gray-700"> | |
| {localize(lang, 'com_endpoint_export')} | |
| </DialogButton> | |
| </> | |
| } | |
| /> | |
| </Dialog> | |
| ); | |
| }; | |
| export default EditPresetDialog; | |