feat: support AI terms
This commit is contained in:
@@ -217,6 +217,7 @@ export const apiTranslate = async ({
|
||||
toLang,
|
||||
apiSetting = DEFAULT_API_SETTING,
|
||||
docInfo = {},
|
||||
glossary = {},
|
||||
useCache = true,
|
||||
usePool = true,
|
||||
}) => {
|
||||
@@ -265,6 +266,7 @@ export const apiTranslate = async ({
|
||||
toLang,
|
||||
langMap,
|
||||
docInfo,
|
||||
glossary,
|
||||
apiSetting,
|
||||
usePool,
|
||||
batchInterval,
|
||||
@@ -285,6 +287,7 @@ export const apiTranslate = async ({
|
||||
toLang,
|
||||
langMap,
|
||||
docInfo,
|
||||
glossary,
|
||||
apiSetting,
|
||||
usePool,
|
||||
});
|
||||
|
||||
@@ -573,6 +573,7 @@ export const genTransReq = async ({ reqHook, resHook, ...args }) => {
|
||||
to,
|
||||
texts,
|
||||
docInfo,
|
||||
glossary,
|
||||
customHeader,
|
||||
customBody,
|
||||
} = args;
|
||||
@@ -587,7 +588,14 @@ export const genTransReq = async ({ reqHook, resHook, ...args }) => {
|
||||
|
||||
if (API_SPE_TYPES.ai.has(apiType)) {
|
||||
args.systemPrompt = genSystemPrompt({ systemPrompt, from, to });
|
||||
args.userPrompt = genUserPrompt({ userPrompt, from, to, texts, docInfo });
|
||||
args.userPrompt = genUserPrompt({
|
||||
userPrompt,
|
||||
from,
|
||||
to,
|
||||
texts,
|
||||
docInfo,
|
||||
glossary,
|
||||
});
|
||||
}
|
||||
|
||||
const {
|
||||
@@ -784,7 +792,17 @@ export const parseTransRes = async (
|
||||
*/
|
||||
export const handleTranslate = async (
|
||||
texts = [],
|
||||
{ from, to, fromLang, toLang, langMap, docInfo, apiSetting, usePool }
|
||||
{
|
||||
from,
|
||||
to,
|
||||
fromLang,
|
||||
toLang,
|
||||
langMap,
|
||||
docInfo,
|
||||
glossary,
|
||||
apiSetting,
|
||||
usePool,
|
||||
}
|
||||
) => {
|
||||
let history = null;
|
||||
let hisMsgs = [];
|
||||
@@ -815,6 +833,7 @@ export const handleTranslate = async (
|
||||
toLang,
|
||||
langMap,
|
||||
docInfo,
|
||||
glossary,
|
||||
hisMsgs,
|
||||
token,
|
||||
...apiSetting,
|
||||
|
||||
@@ -668,6 +668,16 @@ export const I18N = {
|
||||
en: `1. Supports regular expression matching, no slash required, and no modifiers are supported. 2. Separate multiple terms with newlines or semicolons ";". 3. Terms and translations are separated by English commas ",". 4. If there is no translation, the term will be deemed not to be translated.`,
|
||||
zh_TW: `1. 支援正則表達式比對,無需斜線,且不支援修飾符。2. 多條術語以換行或分號「;」分隔。3. 術語與譯文以英文逗號「,」分隔。4. 無譯文者視為不翻譯該術語。`,
|
||||
},
|
||||
ai_terms: {
|
||||
zh: `AI专业术语`,
|
||||
en: `AI Terms`,
|
||||
zh_TW: `AI專業術語`,
|
||||
},
|
||||
ai_terms_helper: {
|
||||
zh: `1、AI智能替换,不支持正则表达式。2、多条术语用换行或分号“;”隔开。3、术语和译文用英文逗号“,”隔开。4、没有译文视为不翻译术语。`,
|
||||
en: `1. AI intelligent replacement does not support regular expressions.2. Separate multiple terms with newlines or semicolons ";". 3. Terms and translations are separated by English commas ",". 4. If there is no translation, the term will be deemed not to be translated.`,
|
||||
zh_TW: `1.AI智能替換,不支援正規表示式。2. 多條術語以換行或分號「;」分隔。3. 術語與譯文以英文逗號「,」分隔。4. 無譯文者視為不翻譯該術語。`,
|
||||
},
|
||||
selector_style: {
|
||||
zh: `选择器节点样式`,
|
||||
en: `Selector Style`,
|
||||
@@ -1453,11 +1463,6 @@ export const I18N = {
|
||||
en: `Placeholder tag name`,
|
||||
zh_TW: `佔位標名`,
|
||||
},
|
||||
ai_terms: {
|
||||
zh: `AI识别术语表`,
|
||||
en: `AI Identification Glossary`,
|
||||
zh_TW: `AI辨識術語表`,
|
||||
},
|
||||
system_prompt_helper: {
|
||||
zh: `在未完全理解默认Prompt的情况下,请勿随意修改,否则可能翻译失败。`,
|
||||
en: `If you do not fully understand the default prompt, please do not modify it at will, otherwise the translation may fail.`,
|
||||
|
||||
@@ -80,6 +80,7 @@ export const DEFAULT_RULE = {
|
||||
selector: "", // 选择器
|
||||
keepSelector: "", // 保留元素选择器
|
||||
terms: "", // 专业术语
|
||||
aiTerms: "", // AI专业术语
|
||||
apiSlug: GLOBAL_KEY, // 翻译服务
|
||||
fromLang: GLOBAL_KEY, // 源语言
|
||||
toLang: GLOBAL_KEY, // 目标语言
|
||||
@@ -116,6 +117,7 @@ export const GLOBLA_RULE = {
|
||||
selector: DEFAULT_SELECTOR, // 选择器
|
||||
keepSelector: DEFAULT_KEEP_SELECTOR, // 保留元素选择器
|
||||
terms: "", // 专业术语
|
||||
aiTerms: "", // AI专业术语
|
||||
apiSlug: OPT_TRANS_MICROSOFT, // 翻译服务
|
||||
fromLang: "auto", // 源语言
|
||||
toLang: "zh-CN", // 目标语言
|
||||
|
||||
@@ -52,6 +52,7 @@ export const matchRule = async (href, { injectRules, subrulesList }) => {
|
||||
"rootsSelector",
|
||||
"ignoreSelector",
|
||||
"terms",
|
||||
"aiTerms",
|
||||
"selectStyle",
|
||||
"parentStyle",
|
||||
"injectJs",
|
||||
@@ -134,6 +135,7 @@ export const checkRules = (rules) => {
|
||||
rootsSelector,
|
||||
ignoreSelector,
|
||||
terms,
|
||||
aiTerms,
|
||||
selectStyle,
|
||||
parentStyle,
|
||||
injectJs,
|
||||
@@ -166,6 +168,7 @@ export const checkRules = (rules) => {
|
||||
rootsSelector: type(rootsSelector) === "string" ? rootsSelector : "",
|
||||
ignoreSelector: type(ignoreSelector) === "string" ? ignoreSelector : "",
|
||||
terms: type(terms) === "string" ? terms : "",
|
||||
aiTerms: type(aiTerms) === "string" ? aiTerms : "",
|
||||
selectStyle: type(selectStyle) === "string" ? selectStyle : "",
|
||||
parentStyle: type(parentStyle) === "string" ? parentStyle : "",
|
||||
injectJs: type(injectJs) === "string" ? injectJs : "",
|
||||
|
||||
@@ -271,6 +271,7 @@ export class Translator {
|
||||
#translationTagName = APP_NAME; // 翻译容器的标签名
|
||||
#eventName = ""; // 通信事件名称
|
||||
#docInfo = {}; // 网页信息
|
||||
#glossary = {}; // AI词典
|
||||
#textClass = {}; // 译文样式class
|
||||
#textSheet = ""; // 译文样式字典
|
||||
#apiSetting = null;
|
||||
@@ -334,6 +335,7 @@ export class Translator {
|
||||
);
|
||||
this.#placeholderRegex = this.#createPlaceholderRegex();
|
||||
this.#parseTerms(this.#rule.terms);
|
||||
this.#parseAITerms(this.#rule.aiTerms);
|
||||
this.#createTextStyles();
|
||||
|
||||
this.#boundMouseMoveHandler = this.#handleMouseMove.bind(this);
|
||||
@@ -512,6 +514,24 @@ export class Translator {
|
||||
}
|
||||
}
|
||||
|
||||
#parseAITerms(termsString) {
|
||||
if (!termsString || typeof termsString !== "string") return;
|
||||
|
||||
try {
|
||||
this.#glossary = Object.fromEntries(
|
||||
termsString
|
||||
.split(/\n|;/)
|
||||
.map((line) => {
|
||||
const [k = "", v = ""] = line.split(",").map((s) => s.trim());
|
||||
return [k, v];
|
||||
})
|
||||
.filter(([k]) => k)
|
||||
);
|
||||
} catch (err) {
|
||||
kissLog("parse aiterms", err);
|
||||
}
|
||||
}
|
||||
|
||||
// todo: 利用AI总结
|
||||
#getDocDescription() {
|
||||
try {
|
||||
@@ -1157,6 +1177,7 @@ export class Translator {
|
||||
toLang,
|
||||
apiSetting: this.#apiSetting,
|
||||
docInfo: this.#docInfo,
|
||||
glossary: this.#glossary,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -352,49 +352,6 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
|
||||
multiline
|
||||
maxRows={10}
|
||||
/> */}
|
||||
|
||||
{/* <Box>
|
||||
<Grid container spacing={2} columns={12}>
|
||||
<Grid item xs={6} sm={6} md={6} lg={3}>
|
||||
<ReusableAutocomplete
|
||||
freeSolo
|
||||
size="small"
|
||||
fullWidth
|
||||
options={BUILTIN_PLACEHOLDERS}
|
||||
name="placeholder"
|
||||
label={i18n("placeholder")}
|
||||
value={placeholder}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6} sm={6} md={6} lg={3}>
|
||||
<ReusableAutocomplete
|
||||
freeSolo
|
||||
size="small"
|
||||
fullWidth
|
||||
options={BUILTIN_TAG_NAMES}
|
||||
name="tagName"
|
||||
label={i18n("tag_name")}
|
||||
value={tagName}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6} sm={6} md={6} lg={3}>
|
||||
<TextField
|
||||
select
|
||||
size="small"
|
||||
fullWidth
|
||||
name="aiTerms"
|
||||
value={aiTerms}
|
||||
label={i18n("ai_terms")}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<MenuItem value={true}>{i18n("enable")}</MenuItem>
|
||||
<MenuItem value={false}>{i18n("disable")}</MenuItem>
|
||||
</TextField>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box> */}
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ function RuleFields({ rule, rules, setShow, setKeyword }) {
|
||||
rootsSelector = "",
|
||||
ignoreSelector = "",
|
||||
terms = "",
|
||||
aiTerms = "",
|
||||
selectStyle = "",
|
||||
parentStyle = "",
|
||||
injectJs = "",
|
||||
@@ -443,30 +444,6 @@ function RuleFields({ rule, rules, setShow, setKeyword }) {
|
||||
))}
|
||||
</TextField>
|
||||
</Grid>
|
||||
{/* <Grid item xs={12} sm={12} md={6} lg={3}>
|
||||
<TextField
|
||||
select
|
||||
size="small"
|
||||
fullWidth
|
||||
name="transTiming"
|
||||
value={transTiming}
|
||||
label={i18n("trigger_mode")}
|
||||
disabled={disabled}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{GlobalItem}
|
||||
{OPT_TIMING_ALL.map((item) => (
|
||||
<MenuItem key={item} value={item}>
|
||||
{i18n(item)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
</Grid> */}
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Grid container spacing={2} columns={12}>
|
||||
<Grid item xs={12} sm={12} md={6} lg={3}>
|
||||
<TextField
|
||||
select
|
||||
@@ -497,6 +474,25 @@ function RuleFields({ rule, rules, setShow, setKeyword }) {
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</Grid>
|
||||
{/* <Grid item xs={12} sm={12} md={6} lg={3}>
|
||||
<TextField
|
||||
select
|
||||
size="small"
|
||||
fullWidth
|
||||
name="transTiming"
|
||||
value={transTiming}
|
||||
label={i18n("trigger_mode")}
|
||||
disabled={disabled}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{GlobalItem}
|
||||
{OPT_TIMING_ALL.map((item) => (
|
||||
<MenuItem key={item} value={item}>
|
||||
{i18n(item)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
</Grid> */}
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
@@ -527,6 +523,17 @@ function RuleFields({ rule, rules, setShow, setKeyword }) {
|
||||
multiline
|
||||
maxRows={10}
|
||||
/>
|
||||
<TextField
|
||||
size="small"
|
||||
label={i18n("ai_terms")}
|
||||
helperText={i18n("ai_terms_helper")}
|
||||
name="aiTerms"
|
||||
value={aiTerms}
|
||||
disabled={disabled}
|
||||
onChange={handleChange}
|
||||
multiline
|
||||
maxRows={10}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
size="small"
|
||||
|
||||
Reference in New Issue
Block a user