import { themeChange } from "theme-change"; import { InformationCircleIcon, CheckIcon, NoSymbolIcon, CogIcon, KeyIcon, EyeIcon, EllipsisHorizontalCircleIcon, HandRaisedIcon, AdjustmentsHorizontalIcon, Cog6ToothIcon, ListBulletIcon, } from "@heroicons/react/24/outline"; import { createRef } from "preact"; import { StateUpdater, useContext, useEffect, useState, Dispatch, } from "preact/hooks"; import { clearTotalCost, getTotalCost } from "@/utils/totalCost"; import { ChatStore, TemplateChatStore, TemplateAPI, TemplateTools, } from "@/types/chatstore"; import { models } from "@/types/models"; import { tr, Tr, langCodeContext, LANG_OPTIONS } from "@/translate"; import { isVailedJSON } from "@/message"; import { SetAPIsTemplate } from "@/setAPIsTemplate"; import { autoHeight } from "@/textarea"; import { getDefaultParams } from "@/utils/getDefaultParam"; const TTS_VOICES: string[] = [ "alloy", "echo", "fable", "onyx", "nova", "shimmer", ]; const TTS_FORMAT: string[] = ["mp3", "opus", "aac", "flac"]; const Help = (props: { children: any; help: string; field: string }) => { return (
); }; const SelectModel = (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; help: string; }) => { let shouldIUseCustomModel: boolean = true; for (const model in models) { if (props.chatStore.model === model) { shouldIUseCustomModel = false; } } const [useCustomModel, setUseCustomModel] = useState(shouldIUseCustomModel); return (
Model {" "}
{Tr("Custom")} { setUseCustomModel(!useCustomModel); }} />
{/* Top Right label */}
); }; const LongInput = (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; field: "systemMessageContent" | "toolsString"; label: string; help: string; }) => { return ( ); }; const Input = (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; field: | "apiKey" | "apiEndpoint" | "whisper_api" | "whisper_key" | "tts_api" | "tts_key" | "image_gen_api" | "image_gen_key"; help: string; }) => { const [hideInput, setHideInput] = useState(true); return (
{props.field}
); }; const Slicer = (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; field: "temperature" | "top_p" | "tts_speed"; help: string; min: number; max: number; }) => { const enable_filed_name: "temperature_enabled" | "top_p_enabled" = `${props.field}_enabled` as any; const enabled = props.chatStore[enable_filed_name]; if (enabled === null || enabled === undefined) { if (props.field === "temperature") { props.chatStore[enable_filed_name] = true; } if (props.field === "top_p") { props.chatStore[enable_filed_name] = false; } } const setEnabled = (state: boolean) => { props.chatStore[enable_filed_name] = state; props.setChatStore({ ...props.chatStore }); }; return (
{enabled ? (
{ const value = parseFloat(event.target.value); props.chatStore[props.field] = value; props.setChatStore({ ...props.chatStore }); }} /> { const value = parseFloat(event.target.value); props.chatStore[props.field] = value; props.setChatStore({ ...props.chatStore }); }} />
) : ( "" )}
); }; const Number = (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; field: | "totalTokens" | "maxTokens" | "maxGenTokens" | "tokenMargin" | "postBeginIndex" | "presence_penalty" | "frequency_penalty"; readOnly: boolean; help: string; }) => { return ( { console.log("type", typeof event.target.value); let newNumber = parseFloat(event.target.value); if (newNumber < 0) newNumber = 0; props.chatStore[props.field] = newNumber; props.setChatStore({ ...props.chatStore }); }} > ); }; const Choice = (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; field: "streamMode" | "develop_mode" | "json_mode" | "logprobs"; help: string; }) => { return (
); }; export default (props: { chatStore: ChatStore; setChatStore: (cs: ChatStore) => void; setShow: Dispatch>; selectedChatStoreIndex: number; templates: TemplateChatStore[]; setTemplates: (templates: TemplateChatStore[]) => void; templateAPIs: TemplateAPI[]; setTemplateAPIs: (templateAPIs: TemplateAPI[]) => void; templateAPIsWhisper: TemplateAPI[]; setTemplateAPIsWhisper: (templateAPIs: TemplateAPI[]) => void; templateAPIsTTS: TemplateAPI[]; setTemplateAPIsTTS: (templateAPIs: TemplateAPI[]) => void; templateAPIsImageGen: TemplateAPI[]; setTemplateAPIsImageGen: (templateAPIs: TemplateAPI[]) => void; templateTools: TemplateTools[]; setTemplateTools: (templateTools: TemplateTools[]) => void; }) => { let link = location.protocol + "//" + location.host + location.pathname + `?key=${encodeURIComponent( props.chatStore.apiKey, )}&api=${encodeURIComponent(props.chatStore.apiEndpoint)}&mode=${ props.chatStore.streamMode ? "stream" : "fetch" }&model=${props.chatStore.model}&sys=${encodeURIComponent( props.chatStore.systemMessageContent, )}`; if (props.chatStore.develop_mode) { link = link + `&dev=true`; } const importFileRef = createRef(); const [totalCost, setTotalCost] = useState(getTotalCost()); // @ts-ignore const { langCode, setLangCode } = useContext(langCodeContext); useEffect(() => { themeChange(false); const handleKeyPress = (event: any) => { if (event.keyCode === 27) { // keyCode for ESC key is 27 props.setShow(false); } }; document.addEventListener("keydown", handleKeyPress); return () => { document.removeEventListener("keydown", handleKeyPress); }; }, []); // The empty dependency array ensures that the effect runs only once return (
props.setShow(false)} className="left-0 top-0 overflow-scroll flex justify-center absolute w-full h-full z-10" >
{ event.stopPropagation(); }} className="modal-box" >

{Tr("Settings")}

Session
Session cost
{props.chatStore.cost.toFixed(4)} $
JSON Check:{" "} {isVailedJSON(props.chatStore.toolsString) ? ( ) : ( )}
{props.chatStore.toolsString.trim() && ( )}
System
Accumulated cost
{totalCost.toFixed(4)} $
Chat

Chat API

Speech Recognition

Whisper API

TTS

TTS API

Image Generation

Image Gen API

chatgpt-api-web ChatStore {Tr("Version")}{" "} {props.chatStore.chatgpt_api_web_version}

{Tr("Documents and source code are avaliable here")}:{" "} github.com/heimoshuiyu/chatgpt-api-web

); };