feat: add gemini translator

This commit is contained in:
Gabe Yuan
2023-12-21 14:15:14 +08:00
parent 4bf7972ad5
commit c7df103950
7 changed files with 57 additions and 3 deletions

View File

@@ -12,7 +12,7 @@ A simple, open source [bilingual translation extension & Greasemonkey script](ht
- [x] Chrome/Edge/Firefox/Kiwi - [x] Chrome/Edge/Firefox/Kiwi
- [ ] Safari - [ ] Safari
- [x] Supports multiple translation services - [x] Supports multiple translation services
- [x] Google/Microsoft/DeepL/OpenAI/CloudflareAI/Baidu/Tencent - [x] Google/Microsoft/DeepL/OpenAI/Gemini/CloudflareAI/Baidu/Tencent
- [x] Custom translation interface - [x] Custom translation interface
- [x] Covers common translation scenarios - [x] Covers common translation scenarios
- [x] Web bilingual translation - [x] Web bilingual translation

View File

@@ -12,7 +12,7 @@
- [x] Chrome/Edge/Firefox/Kiwi - [x] Chrome/Edge/Firefox/Kiwi
- [ ] Safari - [ ] Safari
- [x] 支持多种翻译服务 - [x] 支持多种翻译服务
- [x] Google/Microsoft/DeepL/OpenAI/CloudflareAI/Baidu/Tencent - [x] Google/Microsoft/DeepL/OpenAI/Gemini/CloudflareAI/Baidu/Tencent
- [x] 自定义翻译接口 - [x] 自定义翻译接口
- [x] 覆盖常见翻译场景 - [x] 覆盖常见翻译场景
- [x] 网页双语对照翻译 - [x] 网页双语对照翻译

View File

@@ -98,6 +98,7 @@ const userscriptWebpack = (config, env) => {
// @connect api.deepl.com // @connect api.deepl.com
// @connect www2.deepl.com // @connect www2.deepl.com
// @connect api.openai.com // @connect api.openai.com
// @connect generativelanguage.googleapis.com
// @connect openai.azure.com // @connect openai.azure.com
// @connect workers.dev // @connect workers.dev
// @connect github.io // @connect github.io

View File

@@ -9,6 +9,7 @@ import {
OPT_TRANS_BAIDU, OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT, OPT_TRANS_TENCENT,
OPT_TRANS_OPENAI, OPT_TRANS_OPENAI,
OPT_TRANS_GEMINI,
OPT_TRANS_CLOUDFLAREAI, OPT_TRANS_CLOUDFLAREAI,
OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE,
URL_CACHE_TRAN, URL_CACHE_TRAN,
@@ -181,6 +182,10 @@ export const apiTranslate = async ({
trText = res?.choices?.[0].message.content; trText = res?.choices?.[0].message.content;
isSame = text === trText; isSame = text === trText;
break; break;
case OPT_TRANS_GEMINI:
trText = res?.candidates?.[0].content.parts[0].text;
isSame = text === trText;
break;
case OPT_TRANS_CLOUDFLAREAI: case OPT_TRANS_CLOUDFLAREAI:
trText = res?.result?.translated_text; trText = res?.result?.translated_text;
isSame = text === trText; isSame = text === trText;

View File

@@ -94,6 +94,7 @@ export const OPT_TRANS_DEEPLFREE = "DeepLFree";
export const OPT_TRANS_BAIDU = "Baidu"; export const OPT_TRANS_BAIDU = "Baidu";
export const OPT_TRANS_TENCENT = "Tencent"; export const OPT_TRANS_TENCENT = "Tencent";
export const OPT_TRANS_OPENAI = "OpenAI"; export const OPT_TRANS_OPENAI = "OpenAI";
export const OPT_TRANS_GEMINI = "Gemini";
export const OPT_TRANS_CLOUDFLAREAI = "CloudflareAI"; export const OPT_TRANS_CLOUDFLAREAI = "CloudflareAI";
export const OPT_TRANS_CUSTOMIZE = "Custom"; export const OPT_TRANS_CUSTOMIZE = "Custom";
export const OPT_TRANS_ALL = [ export const OPT_TRANS_ALL = [
@@ -105,6 +106,7 @@ export const OPT_TRANS_ALL = [
OPT_TRANS_BAIDU, OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT, OPT_TRANS_TENCENT,
OPT_TRANS_OPENAI, OPT_TRANS_OPENAI,
OPT_TRANS_GEMINI,
OPT_TRANS_CLOUDFLAREAI, OPT_TRANS_CLOUDFLAREAI,
OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE,
]; ];
@@ -227,6 +229,9 @@ export const OPT_LANGS_SPECIAL = {
[OPT_TRANS_OPENAI]: new Map( [OPT_TRANS_OPENAI]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
), ),
[OPT_TRANS_GEMINI]: new Map(
OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]])
),
[OPT_TRANS_CLOUDFLAREAI]: new Map([ [OPT_TRANS_CLOUDFLAREAI]: new Map([
["auto", ""], ["auto", ""],
["zh-CN", "chinese"], ["zh-CN", "chinese"],
@@ -308,6 +313,7 @@ export const DEFAULT_FETCH_INTERVAL = 100; // 默认任务间隔时间
export const PROMPT_PLACE_FROM = "{{from}}"; // 占位符 export const PROMPT_PLACE_FROM = "{{from}}"; // 占位符
export const PROMPT_PLACE_TO = "{{to}}"; // 占位符 export const PROMPT_PLACE_TO = "{{to}}"; // 占位符
export const PROMPT_PLACE_TEXT = "{{text}}"; // 占位符
export const DEFAULT_COLOR = "#209CEE"; // 默认高亮背景色/线条颜色 export const DEFAULT_COLOR = "#209CEE"; // 默认高亮背景色/线条颜色
@@ -388,6 +394,12 @@ export const DEFAULT_TRANS_APIS = {
model: "gpt-4", model: "gpt-4",
prompt: `You will be provided with a sentence in ${PROMPT_PLACE_FROM}, and your task is to translate it into ${PROMPT_PLACE_TO}.`, prompt: `You will be provided with a sentence in ${PROMPT_PLACE_FROM}, and your task is to translate it into ${PROMPT_PLACE_TO}.`,
}, },
[OPT_TRANS_GEMINI]: {
url: "https://generativelanguage.googleapis.com/v1/models",
key: "",
model: "gemini-pro",
prompt: `Translate the following text from ${PROMPT_PLACE_FROM} to ${PROMPT_PLACE_TO}:\n\n${PROMPT_PLACE_TEXT}`,
},
[OPT_TRANS_CLOUDFLAREAI]: { [OPT_TRANS_CLOUDFLAREAI]: {
url: "https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/run/@cf/meta/m2m100-1.2b", url: "https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/run/@cf/meta/m2m100-1.2b",
key: "", key: "",

View File

@@ -8,12 +8,14 @@ import {
OPT_TRANS_BAIDU, OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT, OPT_TRANS_TENCENT,
OPT_TRANS_OPENAI, OPT_TRANS_OPENAI,
OPT_TRANS_GEMINI,
OPT_TRANS_CLOUDFLAREAI, OPT_TRANS_CLOUDFLAREAI,
OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE,
URL_MICROSOFT_TRAN, URL_MICROSOFT_TRAN,
URL_TENCENT_TRANSMART, URL_TENCENT_TRANSMART,
PROMPT_PLACE_FROM, PROMPT_PLACE_FROM,
PROMPT_PLACE_TO, PROMPT_PLACE_TO,
PROMPT_PLACE_TEXT,
} from "../config"; } from "../config";
import { msAuth } from "./auth"; import { msAuth } from "./auth";
import { genDeeplFree } from "../apis/deepl"; import { genDeeplFree } from "../apis/deepl";
@@ -178,6 +180,37 @@ const genOpenAI = ({ text, from, to, url, key, prompt, model }) => {
return [url, init]; return [url, init];
}; };
const genGemini = ({ text, from, to, url, key, prompt, model }) => {
prompt = prompt
.replaceAll(PROMPT_PLACE_FROM, from)
.replaceAll(PROMPT_PLACE_TO, to)
.replaceAll(PROMPT_PLACE_TEXT, text);
const data = {
contents: [
{
// role: "user",
parts: [
{
text: prompt,
},
],
},
],
};
const input = `${url}/${model}:generateContent?key=${key}`;
const init = {
headers: {
"Content-type": "application/json",
},
method: "POST",
body: JSON.stringify(data),
};
return [input, init];
};
const genCloudflareAI = ({ text, from, to, url, key }) => { const genCloudflareAI = ({ text, from, to, url, key }) => {
const data = { const data = {
text, text,
@@ -241,6 +274,8 @@ export const newTransReq = ({ translator, text, from, to }, apiSetting) => {
return genTencent(args); return genTencent(args);
case OPT_TRANS_OPENAI: case OPT_TRANS_OPENAI:
return genOpenAI(args); return genOpenAI(args);
case OPT_TRANS_GEMINI:
return genGemini(args);
case OPT_TRANS_CLOUDFLAREAI: case OPT_TRANS_CLOUDFLAREAI:
return genCloudflareAI(args); return genCloudflareAI(args);
case OPT_TRANS_CUSTOMIZE: case OPT_TRANS_CUSTOMIZE:

View File

@@ -9,6 +9,7 @@ import {
OPT_TRANS_BAIDU, OPT_TRANS_BAIDU,
OPT_TRANS_TENCENT, OPT_TRANS_TENCENT,
OPT_TRANS_OPENAI, OPT_TRANS_OPENAI,
OPT_TRANS_GEMINI,
OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE,
URL_KISS_PROXY, URL_KISS_PROXY,
} from "../../config"; } from "../../config";
@@ -115,7 +116,7 @@ function ApiFields({ translator }) {
/> />
</> </>
)} )}
{translator === OPT_TRANS_OPENAI && ( {(translator === OPT_TRANS_OPENAI || translator === OPT_TRANS_GEMINI) && (
<> <>
<TextField <TextField
size="small" size="small"