From b6a09b99ab7dd48cf3f0f3e1491edd0f5a45529e Mon Sep 17 00:00:00 2001 From: Gabe Yuan Date: Sun, 28 Apr 2024 21:43:20 +0800 Subject: [PATCH] feat: support ollama api --- src/apis/index.js | 9 +++++++++ src/apis/trans.js | 36 ++++++++++++++++++++++++++++++++++++ src/config/index.js | 26 ++++++++++++++++++++++++++ src/views/Options/Apis.js | 7 +++++++ 4 files changed, 78 insertions(+) diff --git a/src/apis/index.js b/src/apis/index.js index f23bb94..e41baf8 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -14,6 +14,9 @@ import { OPT_TRANS_OPENAI_3, OPT_TRANS_GEMINI, OPT_TRANS_CLOUDFLAREAI, + OPT_TRANS_OLLAMA, + OPT_TRANS_OLLAMA_2, + OPT_TRANS_OLLAMA_3, OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE_2, OPT_TRANS_CUSTOMIZE_3, @@ -261,6 +264,12 @@ export const apiTranslate = async ({ trText = res?.result?.translated_text; isSame = text === trText; break; + case OPT_TRANS_OLLAMA: + case OPT_TRANS_OLLAMA_2: + case OPT_TRANS_OLLAMA_3: + trText = res?.response; + isSame = text === trText; + break; case OPT_TRANS_CUSTOMIZE: case OPT_TRANS_CUSTOMIZE_2: case OPT_TRANS_CUSTOMIZE_3: diff --git a/src/apis/trans.js b/src/apis/trans.js index e250d82..331983e 100644 --- a/src/apis/trans.js +++ b/src/apis/trans.js @@ -13,6 +13,9 @@ import { OPT_TRANS_OPENAI_3, OPT_TRANS_GEMINI, OPT_TRANS_CLOUDFLAREAI, + OPT_TRANS_OLLAMA, + OPT_TRANS_OLLAMA_2, + OPT_TRANS_OLLAMA_3, OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE_2, OPT_TRANS_CUSTOMIZE_3, @@ -245,6 +248,32 @@ const genGemini = ({ text, from, to, url, key, prompt, model }) => { return [input, init]; }; +const genOllama = ({ text, from, to, url, key, prompt, model }) => { + prompt = prompt + .replaceAll(INPUT_PLACE_FROM, from) + .replaceAll(INPUT_PLACE_TO, to) + .replaceAll(INPUT_PLACE_TEXT, text); + + const data = { + model, + prompt, + stream: false, + }; + + const init = { + headers: { + "Content-type": "application/json", + }, + method: "POST", + body: JSON.stringify(data), + }; + if (key) { + init.headers.Authorization = `Bearer ${key}`; + } + + return [url, init]; +}; + const genCloudflareAI = ({ text, from, to, url, key }) => { const data = { text, @@ -323,6 +352,9 @@ export const genTransReq = ({ translator, text, from, to }, apiSetting) => { case OPT_TRANS_OPENAI_3: case OPT_TRANS_GEMINI: case OPT_TRANS_CLOUDFLAREAI: + case OPT_TRANS_OLLAMA: + case OPT_TRANS_OLLAMA_2: + case OPT_TRANS_OLLAMA_3: case OPT_TRANS_NIUTRANS: args.key = keyPick(translator, args.key, keyMap); break; @@ -357,6 +389,10 @@ export const genTransReq = ({ translator, text, from, to }, apiSetting) => { return genGemini(args); case OPT_TRANS_CLOUDFLAREAI: return genCloudflareAI(args); + case OPT_TRANS_OLLAMA: + case OPT_TRANS_OLLAMA_2: + case OPT_TRANS_OLLAMA_3: + return genOllama(args); case OPT_TRANS_CUSTOMIZE: case OPT_TRANS_CUSTOMIZE_2: case OPT_TRANS_CUSTOMIZE_3: diff --git a/src/config/index.js b/src/config/index.js index c55b751..a18dea7 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -108,6 +108,9 @@ export const OPT_TRANS_OPENAI_2 = "OpenAI2"; export const OPT_TRANS_OPENAI_3 = "OpenAI3"; export const OPT_TRANS_GEMINI = "Gemini"; export const OPT_TRANS_CLOUDFLAREAI = "CloudflareAI"; +export const OPT_TRANS_OLLAMA = "Ollama"; +export const OPT_TRANS_OLLAMA_2 = "Ollama2"; +export const OPT_TRANS_OLLAMA_3 = "Ollama3"; export const OPT_TRANS_CUSTOMIZE = "Custom"; export const OPT_TRANS_CUSTOMIZE_2 = "Custom2"; export const OPT_TRANS_CUSTOMIZE_3 = "Custom3"; @@ -127,6 +130,9 @@ export const OPT_TRANS_ALL = [ OPT_TRANS_OPENAI_3, OPT_TRANS_GEMINI, OPT_TRANS_CLOUDFLAREAI, + OPT_TRANS_OLLAMA, + OPT_TRANS_OLLAMA_2, + OPT_TRANS_OLLAMA_3, OPT_TRANS_CUSTOMIZE, OPT_TRANS_CUSTOMIZE_2, OPT_TRANS_CUSTOMIZE_3, @@ -267,6 +273,15 @@ export const OPT_LANGS_SPECIAL = { [OPT_TRANS_GEMINI]: new Map( OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) ), + [OPT_TRANS_OLLAMA]: new Map( + OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) + ), + [OPT_TRANS_OLLAMA_2]: new Map( + OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) + ), + [OPT_TRANS_OLLAMA_3]: new Map( + OPT_LANGS_FROM.map(([key, val]) => [key, val.split(" - ")[0]]) + ), [OPT_TRANS_CLOUDFLAREAI]: new Map([ ["auto", ""], ["zh-CN", "chinese"], @@ -482,6 +497,14 @@ const defaultOpenaiApi = { fetchLimit: 1, fetchInterval: 500, }; +const defaultOllamaApi = { + url: "http://localhost:11434/api/generate", + key: "", + model: "llama3", + prompt: `Translate the following text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}:\n\n${INPUT_PLACE_TEXT}`, + fetchLimit: 1, + fetchInterval: 500, +}; export const DEFAULT_TRANS_APIS = { [OPT_TRANS_GOOGLE]: { url: "https://translate.googleapis.com/translate_a/single", @@ -542,6 +565,9 @@ export const DEFAULT_TRANS_APIS = { fetchLimit: 1, fetchInterval: 500, }, + [OPT_TRANS_OLLAMA]: defaultOllamaApi, + [OPT_TRANS_OLLAMA_2]: defaultOllamaApi, + [OPT_TRANS_OLLAMA_3]: defaultOllamaApi, [OPT_TRANS_CUSTOMIZE]: defaultCustomApi, [OPT_TRANS_CUSTOMIZE_2]: defaultCustomApi, [OPT_TRANS_CUSTOMIZE_3]: defaultCustomApi, diff --git a/src/views/Options/Apis.js b/src/views/Options/Apis.js index 2a43272..385db2d 100644 --- a/src/views/Options/Apis.js +++ b/src/views/Options/Apis.js @@ -15,6 +15,9 @@ import { OPT_TRANS_OPENAI_3, OPT_TRANS_GEMINI, OPT_TRANS_CLOUDFLAREAI, + OPT_TRANS_OLLAMA, + OPT_TRANS_OLLAMA_2, + OPT_TRANS_OLLAMA_3, OPT_TRANS_CUSTOMIZE, OPT_TRANS_NIUTRANS, URL_KISS_PROXY, @@ -149,6 +152,9 @@ function ApiFields({ translator }) { OPT_TRANS_OPENAI_3, OPT_TRANS_GEMINI, OPT_TRANS_CLOUDFLAREAI, + OPT_TRANS_OLLAMA, + OPT_TRANS_OLLAMA_2, + OPT_TRANS_OLLAMA_3, OPT_TRANS_NIUTRANS, ]; @@ -196,6 +202,7 @@ function ApiFields({ translator }) { )} {(translator.startsWith(OPT_TRANS_OPENAI) || + translator.startsWith(OPT_TRANS_OLLAMA) || translator === OPT_TRANS_GEMINI) && ( <>