diff --git a/src/apis/index.js b/src/apis/index.js
index aef4664..3e677d1 100644
--- a/src/apis/index.js
+++ b/src/apis/index.js
@@ -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,
});
diff --git a/src/apis/trans.js b/src/apis/trans.js
index 76526fb..341dc79 100644
--- a/src/apis/trans.js
+++ b/src/apis/trans.js
@@ -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,
diff --git a/src/config/i18n.js b/src/config/i18n.js
index 47bbac6..a406844 100644
--- a/src/config/i18n.js
+++ b/src/config/i18n.js
@@ -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.`,
diff --git a/src/config/rules.js b/src/config/rules.js
index 82cae71..8b2f0e1 100644
--- a/src/config/rules.js
+++ b/src/config/rules.js
@@ -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", // 目标语言
diff --git a/src/libs/rules.js b/src/libs/rules.js
index a334564..6b937fb 100644
--- a/src/libs/rules.js
+++ b/src/libs/rules.js
@@ -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 : "",
diff --git a/src/libs/translator.js b/src/libs/translator.js
index a87d552..e0eec53 100644
--- a/src/libs/translator.js
+++ b/src/libs/translator.js
@@ -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,
});
}
diff --git a/src/views/Options/Apis.js b/src/views/Options/Apis.js
index e4540ab..0c08e2c 100644
--- a/src/views/Options/Apis.js
+++ b/src/views/Options/Apis.js
@@ -352,49 +352,6 @@ function ApiFields({ apiSlug, isUserApi, deleteApi }) {
multiline
maxRows={10}
/> */}
-
- {/*
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- */}
>
)}
diff --git a/src/views/Options/Rules.js b/src/views/Options/Rules.js
index cee4ff6..110c632 100644
--- a/src/views/Options/Rules.js
+++ b/src/views/Options/Rules.js
@@ -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 }) {
))}
- {/*
-
- {GlobalItem}
- {OPT_TIMING_ALL.map((item) => (
-
- ))}
-
- */}
-
-
-
-
-
+ {/*
+
+ {GlobalItem}
+ {OPT_TIMING_ALL.map((item) => (
+
+ ))}
+
+ */}
@@ -527,6 +523,17 @@ function RuleFields({ rule, rules, setShow, setKeyword }) {
multiline
maxRows={10}
/>
+