Files
kiss-translator/src/views/Options/Apis.js

388 lines
9.2 KiB
JavaScript
Raw Normal View History

2023-09-06 00:25:46 +08:00
import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
2024-04-16 16:39:11 +08:00
import LoadingButton from "@mui/lab/LoadingButton";
2023-09-06 00:25:46 +08:00
import {
OPT_TRANS_ALL,
OPT_TRANS_MICROSOFT,
2023-12-22 11:35:46 +08:00
OPT_TRANS_DEEPL,
2024-04-20 14:01:34 +08:00
OPT_TRANS_DEEPLX,
2023-10-20 17:44:48 +08:00
OPT_TRANS_DEEPLFREE,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
2023-09-06 00:25:46 +08:00
OPT_TRANS_OPENAI,
2024-04-28 16:58:09 +08:00
OPT_TRANS_OPENAI_2,
OPT_TRANS_OPENAI_3,
2023-12-21 14:15:14 +08:00
OPT_TRANS_GEMINI,
2024-09-23 18:22:19 +08:00
OPT_TRANS_CLAUDE,
2023-12-22 11:35:46 +08:00
OPT_TRANS_CLOUDFLAREAI,
2024-04-28 21:43:20 +08:00
OPT_TRANS_OLLAMA,
OPT_TRANS_OLLAMA_2,
OPT_TRANS_OLLAMA_3,
2023-09-06 00:25:46 +08:00
OPT_TRANS_CUSTOMIZE,
2024-04-12 11:31:01 +08:00
OPT_TRANS_NIUTRANS,
2023-09-06 14:57:02 +08:00
URL_KISS_PROXY,
2024-04-12 11:31:01 +08:00
URL_NIUTRANS_REG,
2024-03-21 15:07:50 +08:00
DEFAULT_FETCH_LIMIT,
DEFAULT_FETCH_INTERVAL,
2023-09-06 00:25:46 +08:00
} from "../../config";
import { useState } from "react";
import { useI18n } from "../../hooks/I18n";
import Typography from "@mui/material/Typography";
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
2023-09-06 14:57:02 +08:00
import Alert from "@mui/material/Alert";
2023-09-06 00:25:46 +08:00
import { useAlert } from "../../hooks/Alert";
import { useApi } from "../../hooks/Api";
import { apiTranslate } from "../../apis";
2023-09-06 14:57:02 +08:00
import Box from "@mui/material/Box";
import Link from "@mui/material/Link";
import { limitNumber, limitFloat } from "../../libs/utils";
2023-09-06 00:25:46 +08:00
function TestButton({ translator, api }) {
const i18n = useI18n();
const alert = useAlert();
const [loading, setLoading] = useState(false);
const handleApiTest = async () => {
try {
setLoading(true);
const [text] = await apiTranslate({
translator,
2023-09-06 14:57:02 +08:00
text: "hello world",
fromLang: "en",
2023-09-06 00:25:46 +08:00
toLang: "zh-CN",
apiSetting: api,
useCache: false,
2023-09-06 00:25:46 +08:00
});
if (!text) {
throw new Error("empty reault");
}
alert.success(i18n("test_success"));
} catch (err) {
2023-11-02 23:35:36 +08:00
// alert.error(`${i18n("test_failed")}: ${err.message}`);
let msg = err.message;
try {
msg = JSON.stringify(JSON.parse(err.message), null, 2);
} catch (err) {
// skip
}
2023-11-02 23:35:36 +08:00
alert.error(
<>
<div>{i18n("test_failed")}</div>
2024-04-12 11:31:01 +08:00
{msg === err.message ? (
<div
style={{
maxWidth: 400,
}}
>
{msg}
</div>
) : (
<pre
style={{
maxWidth: 400,
overflow: "auto",
}}
>
{msg}
</pre>
)}
2023-11-02 23:35:36 +08:00
</>
);
2023-09-06 00:25:46 +08:00
} finally {
setLoading(false);
}
};
return (
2024-04-16 16:39:11 +08:00
<LoadingButton
size="small"
variant="contained"
onClick={handleApiTest}
loading={loading}
>
2023-09-06 00:25:46 +08:00
{i18n("click_test")}
2024-04-16 16:39:11 +08:00
</LoadingButton>
2023-09-06 00:25:46 +08:00
);
}
function ApiFields({ translator }) {
const i18n = useI18n();
const { api, updateApi, resetApi } = useApi(translator);
2024-03-21 15:07:50 +08:00
const {
url = "",
key = "",
model = "",
prompt = "",
2024-09-23 18:22:19 +08:00
systemPrompt = "",
2024-03-21 15:07:50 +08:00
fetchLimit = DEFAULT_FETCH_LIMIT,
fetchInterval = DEFAULT_FETCH_INTERVAL,
2024-04-12 11:31:01 +08:00
dictNo = "",
memoryNo = "",
2024-05-12 16:10:11 +08:00
reqHook = "",
resHook = "",
temperature = 0,
maxTokens = 256,
2024-03-21 15:07:50 +08:00
} = api;
2023-09-06 00:25:46 +08:00
const handleChange = (e) => {
2024-03-21 15:07:50 +08:00
let { name, value } = e.target;
switch (name) {
case "fetchLimit":
value = limitNumber(value, 1, 100);
break;
case "fetchInterval":
value = limitNumber(value, 0, 5000);
break;
case "temperature":
value = limitFloat(value, 0, 2);
break;
case "maxTokens":
value = limitNumber(value, 0, 2 ** 15);
break;
2024-03-21 15:07:50 +08:00
default:
}
2023-09-06 00:25:46 +08:00
updateApi({
[name]: value,
});
};
2024-04-28 16:58:09 +08:00
const builtinTranslators = [
2023-10-20 17:44:48 +08:00
OPT_TRANS_MICROSOFT,
OPT_TRANS_DEEPLFREE,
OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT,
];
2023-12-22 11:35:46 +08:00
const mulkeysTranslators = [
OPT_TRANS_DEEPL,
OPT_TRANS_OPENAI,
2024-04-28 16:58:09 +08:00
OPT_TRANS_OPENAI_2,
OPT_TRANS_OPENAI_3,
2023-12-22 11:35:46 +08:00
OPT_TRANS_GEMINI,
2024-09-23 18:22:19 +08:00
OPT_TRANS_CLAUDE,
2023-12-22 11:35:46 +08:00
OPT_TRANS_CLOUDFLAREAI,
2024-04-28 21:43:20 +08:00
OPT_TRANS_OLLAMA,
OPT_TRANS_OLLAMA_2,
OPT_TRANS_OLLAMA_3,
2024-04-12 11:31:01 +08:00
OPT_TRANS_NIUTRANS,
2023-12-22 11:35:46 +08:00
];
2024-04-12 11:31:01 +08:00
const keyHelper =
translator === OPT_TRANS_NIUTRANS ? (
<>
{i18n("mulkeys_help")}
<Link href={URL_NIUTRANS_REG} target="_blank">
{i18n("reg_niutrans")}
</Link>
</>
) : mulkeysTranslators.includes(translator) ? (
i18n("mulkeys_help")
) : (
""
);
2023-09-06 00:25:46 +08:00
return (
<Stack spacing={3}>
2024-04-28 16:58:09 +08:00
{!builtinTranslators.includes(translator) && (
2023-09-06 00:25:46 +08:00
<>
<TextField
size="small"
label={"URL"}
name="url"
value={url}
onChange={handleChange}
2024-04-20 14:01:34 +08:00
multiline={translator === OPT_TRANS_DEEPLX}
maxRows={10}
helperText={
translator === OPT_TRANS_DEEPLX ? i18n("mulkeys_help") : ""
}
2023-09-06 00:25:46 +08:00
/>
<TextField
size="small"
label={"KEY"}
name="key"
value={key}
onChange={handleChange}
2023-12-22 11:35:46 +08:00
multiline={mulkeysTranslators.includes(translator)}
2024-04-20 14:01:34 +08:00
maxRows={10}
2024-04-12 11:31:01 +08:00
helperText={keyHelper}
2023-09-06 00:25:46 +08:00
/>
</>
)}
2024-03-21 15:07:50 +08:00
2024-04-28 16:58:09 +08:00
{(translator.startsWith(OPT_TRANS_OPENAI) ||
2024-04-28 21:43:20 +08:00
translator.startsWith(OPT_TRANS_OLLAMA) ||
2024-09-23 18:22:19 +08:00
translator === OPT_TRANS_CLAUDE ||
2024-04-28 16:58:09 +08:00
translator === OPT_TRANS_GEMINI) && (
2023-09-06 00:25:46 +08:00
<>
<TextField
size="small"
label={"MODEL"}
name="model"
value={model}
onChange={handleChange}
/>
<TextField
size="small"
label={"PROMPT"}
name="prompt"
value={prompt}
onChange={handleChange}
multiline
2024-04-20 14:01:34 +08:00
maxRows={10}
2023-09-06 00:25:46 +08:00
/>
</>
)}
2024-09-23 18:22:19 +08:00
{(translator.startsWith(OPT_TRANS_OPENAI) ||
translator === OPT_TRANS_CLAUDE) && (
<>
2024-09-25 14:03:12 +08:00
<TextField
size="small"
label={"SYSTEM PROMPT"}
name="systemPrompt"
value={systemPrompt}
onChange={handleChange}
/>
<TextField
size="small"
label={"Temperature"}
type="number"
name="temperature"
value={temperature}
onChange={handleChange}
/>
<TextField
size="small"
label={"Max Tokens"}
type="number"
name="maxTokens"
value={maxTokens}
onChange={handleChange}
/>
</>
)}
2024-04-12 11:31:01 +08:00
{translator === OPT_TRANS_NIUTRANS && (
<>
<TextField
size="small"
label={"DictNo"}
name="dictNo"
value={dictNo}
onChange={handleChange}
/>
<TextField
size="small"
label={"MemoryNo"}
name="memoryNo"
value={memoryNo}
onChange={handleChange}
/>
</>
)}
2024-04-17 17:38:54 +08:00
{translator.startsWith(OPT_TRANS_CUSTOMIZE) && (
2024-05-12 16:10:11 +08:00
<>
<TextField
size="small"
label={"Request Hook"}
name="reqHook"
value={reqHook}
onChange={handleChange}
multiline
maxRows={10}
/>
<TextField
size="small"
label={"Response Hook"}
name="resHook"
value={resHook}
onChange={handleChange}
multiline
maxRows={10}
/>
</>
2024-04-17 17:38:54 +08:00
)}
2024-03-21 15:07:50 +08:00
<TextField
size="small"
label={i18n("fetch_limit")}
type="number"
name="fetchLimit"
value={fetchLimit}
onChange={handleChange}
/>
<TextField
size="small"
label={i18n("fetch_interval")}
type="number"
name="fetchInterval"
value={fetchInterval}
onChange={handleChange}
/>
2023-09-06 00:25:46 +08:00
<Stack direction="row" spacing={2}>
<TestButton translator={translator} api={api} />
2024-03-21 15:07:50 +08:00
<Button
size="small"
variant="outlined"
onClick={() => {
resetApi();
}}
>
{i18n("restore_default")}
</Button>
2023-09-06 00:25:46 +08:00
</Stack>
2023-09-06 14:57:02 +08:00
2024-04-01 11:50:29 +08:00
{translator.startsWith(OPT_TRANS_CUSTOMIZE) && (
2023-09-06 14:57:02 +08:00
<pre>{i18n("custom_api_help")}</pre>
)}
2023-09-06 00:25:46 +08:00
</Stack>
);
}
function ApiAccordion({ translator }) {
const [expanded, setExpanded] = useState(false);
const handleChange = (e) => {
setExpanded((pre) => !pre);
};
return (
<Accordion expanded={expanded} onChange={handleChange}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>{translator}</Typography>
</AccordionSummary>
<AccordionDetails>
{expanded && <ApiFields translator={translator} />}
</AccordionDetails>
</Accordion>
);
}
export default function Apis() {
2023-09-06 14:57:02 +08:00
const i18n = useI18n();
return (
<Box>
<Stack spacing={3}>
<Alert severity="info">
<Link href={URL_KISS_PROXY} target="_blank">
{i18n("about_api_proxy")}
</Link>
</Alert>
<Box>
{OPT_TRANS_ALL.map((translator) => (
<ApiAccordion key={translator} translator={translator} />
))}
</Box>
</Stack>
</Box>
);
2023-09-06 00:25:46 +08:00
}