diff --git a/custom-api_v2.md b/custom-api_v2.md index 32a06c6..5bf6950 100644 --- a/custom-api_v2.md +++ b/custom-api_v2.md @@ -1,4 +1,4 @@ -# 自定义接口示例 +# 自定义接口说明及示例 ## 默认接口规范 @@ -21,7 +21,7 @@ Response [ { "text": "你好", // 译文 - "src": "en" // 原文语言 + "src": "en" // 原文语言 } ] ``` @@ -33,12 +33,36 @@ v2.0.4版后亦支持以下 Response 格式 "translations": [ // 译文列表 { "text": "你好", // 译文 - "src": "en" // 原文语言 + "src": "en" // 原文语言 } ] } ``` +## Prompt 相关 + +`Prompt` 可替换占位符: + +```js +`{{from}}` // 原文语言名称 +`{{to}}` // 目标语言名称 +`{{fromLang}}` // 原文语言代码 +`{{toLang}}` // 目标语言代码 +`{{text}}` // 原文 +`{{tone}}` // 风格 +`{{title}}` // 页面标题 +`{{description}}` // 页面描述 +``` + +Hook 中 `Prompt` 类型说明: + +```js +`systemPrompt` // 聚合翻译 System Prompt +`nobatchPrompt` // 非聚合翻译 System Prompt +`nobatchUserPrompt` // 非聚合翻译 User Prompt +`subtitlePrompt` // 字幕翻译 System Prompt +``` + ## 谷歌翻译接口 > 此接口不支持聚合 @@ -101,7 +125,10 @@ async (args) => { content: JSON.stringify({ targetLanguage: args.toLang, segments: args.texts.map((text, id) => ({ id, text })), - glossary: {}, + title: "", // 可省略 + description: "", // 可省略 + glossary: {}, // 可省略 + tone: "", // 可省略 }), }, ], @@ -134,7 +161,10 @@ async (args) => { content: JSON.stringify({ targetLanguage: args.toLang, segments: args.texts.map((text, id) => ({ id, text })), - glossary: {}, + title: "", // 可省略 + description: "", // 可省略 + glossary: {}, // 可省略 + tone: "", // 可省略 }), }, ], @@ -295,6 +325,7 @@ Hook参数里面的语言含义说明: ["cs", "Czech - Čeština"], ["da", "Danish - Dansk"], ["nl", "Dutch - Nederlands"], +["fa", "Persian - فارسی"], ["fi", "Finnish - Suomi"], ["fr", "French - Français"], ["de", "German - Deutsch"], diff --git a/src/apis/index.js b/src/apis/index.js index 2cb301e..25be5c8 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -419,7 +419,7 @@ export const apiTranslate = async ({ toLang, apiSetting = DEFAULT_API_SETTING, docInfo = {}, - glossary = {}, + glossary, useCache = true, usePool = true, }) => { diff --git a/src/apis/trans.js b/src/apis/trans.js index 56d9b70..0f575e3 100644 --- a/src/apis/trans.js +++ b/src/apis/trans.js @@ -30,6 +30,11 @@ import { defaultSubtitlePrompt, defaultNobatchPrompt, defaultNobatchUserPrompt, + INPUT_PLACE_TONE, + INPUT_PLACE_TITLE, + INPUT_PLACE_DESCRIPTION, + INPUT_PLACE_TO_LANG, + INPUT_PLACE_FROM_LANG, } from "../config"; import { msAuth } from "../libs/auth"; import { genDeeplFree } from "./deepl"; @@ -62,36 +67,62 @@ const keyPick = (apiSlug, key = "", cacheMap) => { return keys[curIndex]; }; -const genSystemPrompt = ({ systemPrompt, from, to }) => +const genSystemPrompt = ({ + systemPrompt, + tone, + from, + to, + fromLang, + toLang, + texts, + docInfo: { title = "", description = "" } = {}, +}) => systemPrompt + .replaceAll(INPUT_PLACE_TITLE, title) + .replaceAll(INPUT_PLACE_DESCRIPTION, description) + .replaceAll(INPUT_PLACE_TONE, tone) .replaceAll(INPUT_PLACE_FROM, from) - .replaceAll(INPUT_PLACE_TO, to); + .replaceAll(INPUT_PLACE_TO, to) + .replaceAll(INPUT_PLACE_FROM_LANG, fromLang) + .replaceAll(INPUT_PLACE_TO_LANG, toLang) + .replaceAll(INPUT_PLACE_TEXT, texts[0]); const genUserPrompt = ({ nobatchUserPrompt, useBatchFetch, tone, - glossary = {}, + glossary, from, to, + fromLang, toLang, texts, - docInfo, + docInfo: { title = "", description = "" } = {}, }) => { if (useBatchFetch) { - return JSON.stringify({ + const promptObj = { targetLanguage: toLang, - title: docInfo.title, - description: docInfo.description, segments: texts.map((text, i) => ({ id: i, text })), - glossary, - tone, - }); + }; + + title && (promptObj.title = title); + description && (promptObj.description = description); + glossary && + Object.keys(glossary).length !== 0 && + (promptObj.glossary = glossary); + tone && (promptObj.tone = tone); + + return JSON.stringify(promptObj); } return nobatchUserPrompt + .replaceAll(INPUT_PLACE_TITLE, title) + .replaceAll(INPUT_PLACE_DESCRIPTION, description) + .replaceAll(INPUT_PLACE_TONE, tone) .replaceAll(INPUT_PLACE_FROM, from) .replaceAll(INPUT_PLACE_TO, to) + .replaceAll(INPUT_PLACE_FROM_LANG, fromLang) + .replaceAll(INPUT_PLACE_TO_LANG, toLang) .replaceAll(INPUT_PLACE_TEXT, texts[0]); }; @@ -647,6 +678,7 @@ export const genTransReq = async ({ reqHook, ...args }) => { customHeader, customBody, events, + tone, } = args; if (API_SPE_TYPES.mulkeys.has(apiType)) { @@ -662,6 +694,11 @@ export const genTransReq = async ({ reqHook, ...args }) => { systemPrompt: useBatchFetch ? systemPrompt : nobatchPrompt, from, to, + fromLang, + toLang, + texts, + docInfo, + tone, }); args.userPrompt = !!events ? JSON.stringify(events) @@ -674,6 +711,7 @@ export const genTransReq = async ({ reqHook, ...args }) => { toLang, texts, docInfo, + tone, glossary, }); } diff --git a/src/config/api.js b/src/config/api.js index 49e170b..49a03f8 100644 --- a/src/config/api.js +++ b/src/config/api.js @@ -9,7 +9,12 @@ export const DEFAULT_CONTEXT_SIZE = 3; // 上下文会话数量 export const INPUT_PLACE_URL = "{{url}}"; // 占位符 export const INPUT_PLACE_FROM = "{{from}}"; // 占位符 export const INPUT_PLACE_TO = "{{to}}"; // 占位符 +export const INPUT_PLACE_FROM_LANG = "{{fromLang}}"; // 占位符 +export const INPUT_PLACE_TO_LANG = "{{toLang}}"; // 占位符 export const INPUT_PLACE_TEXT = "{{text}}"; // 占位符 +export const INPUT_PLACE_TONE = "{{tone}}"; // 占位符 +export const INPUT_PLACE_TITLE = "{{title}}"; // 占位符 +export const INPUT_PLACE_DESCRIPTION = "{{description}}"; // 占位符 export const INPUT_PLACE_KEY = "{{key}}"; // 占位符 export const INPUT_PLACE_MODEL = "{{model}}"; // 占位符 diff --git a/src/views/Options/ReusableAutocomplete.js b/src/views/Options/ReusableAutocomplete.js index 3421b39..0443f56 100644 --- a/src/views/Options/ReusableAutocomplete.js +++ b/src/views/Options/ReusableAutocomplete.js @@ -32,6 +32,7 @@ export default function ReusableAutocomplete({ name: name, value: newValue, }, + preventDefault: () => {}, }; onChange(syntheticEvent); }