diff --git a/src/i18n/locales/en_US.json b/src/i18n/locales/en_US.json index e9f9f17935..23f1501822 100644 --- a/src/i18n/locales/en_US.json +++ b/src/i18n/locales/en_US.json @@ -257,15 +257,6 @@ "prompt_description": "By customizing the Prompt, you can customize the behavior of AI. $text $from $to $detect will be replaced with the text to be translated, source language, target language and detected language.", "add": "Add Prompt" }, - "ollama_polish": { - "title": "Ollama Polish" - }, - "ollama_summary": { - "title": "Ollama Summary" - }, - "ollama_custom": { - "title": "Ollama Custom" - }, "openai": { "title": "OpenAI", "service": "Service Provider", @@ -278,15 +269,6 @@ "prompt_description": "By customizing the Prompt, you can customize the behavior of OpenAI. $text $from $to $detect will be replaced with the text to be translated, source language, target language and detected language.", "add": "Add Prompt" }, - "openai_summary": { - "title": "OpenAI Summary" - }, - "openai_polish": { - "title": "OpenAI Polish" - }, - "openai_custom": { - "title": "OpenAI Custom" - }, "geminipro": { "title": "Gemini Pro", "request_path": "Request Path", @@ -295,15 +277,6 @@ "prompt_description": "By customizing the Prompt, you can customize the behavior of Gemini Pro. $text $from $to $detect will be replaced with the text to be translated, source language, target language and detected language.", "add": "Add Prompt" }, - "geminipro_summary": { - "title": "Gemini Pro Summary" - }, - "geminipro_polish": { - "title": "Gemini Pro Polish" - }, - "geminipro_custom": { - "title": "Gemini Pro Custom" - }, "chatglm": { "title": "ChatGLM", "model": "Model", @@ -315,15 +288,6 @@ "prompt_description": "By customizing the Prompt, you can customize the behavior of AI. $text $from $to $detect will be replaced with the text to be translated, source language, target language and detected language.", "add": "Add Prompt" }, - "chatglm_summary": { - "title": "ChatGLM Summary" - }, - "chatglm_polish": { - "title": "ChatGLM Polish" - }, - "chatglm_custom": { - "title": "ChatGLM Custom" - }, "yandex": { "title": "Yandex" }, diff --git a/src/services/translate/chatglm_custom/Config.jsx b/src/services/translate/chatglm_custom/Config.jsx deleted file mode 100644 index d2b7e9c71d..0000000000 --- a/src/services/translate/chatglm_custom/Config.jsx +++ /dev/null @@ -1,194 +0,0 @@ -import { Input, Button, Textarea } from '@nextui-org/react'; -import { DropdownTrigger } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import { DropdownMenu } from '@nextui-org/react'; -import { DropdownItem } from '@nextui-org/react'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { Dropdown } from '@nextui-org/react'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'chatglm_custom', - { - model: 'chatglm_turbo', - apiKey: '', - promptList: [ - { - role: 'user', - content: 'Hello', - }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - serviceConfig !== null && ( -
- ) - ); -} diff --git a/src/services/translate/chatglm_custom/index.jsx b/src/services/translate/chatglm_custom/index.jsx deleted file mode 100644 index da57ff09de..0000000000 --- a/src/services/translate/chatglm_custom/index.jsx +++ /dev/null @@ -1,101 +0,0 @@ -import { store } from '../../../utils/store'; -import { Language } from './info'; -import * as jose from 'jose'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('chatglm_custom'); - if (config !== undefined) { - translateConfig = config; - } - let { model, apiKey, promptList } = translateConfig; - - let [id, secret] = apiKey.split('.'); - if (id === undefined || secret === undefined) { - throw new Error('invalid apikey'); - } - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - // - let timestamp = new Date().getTime(); - let payload = { - api_key: id, - exp: timestamp + 1000 * 60, - timestamp: timestamp, - }; - secret = new TextEncoder().encode(secret); - let jwt = new jose.SignJWT(payload).setProtectedHeader({ alg: 'HS256', sign_type: 'SIGN' }); - let token = await jwt.sign(secret); - - const headers = { - 'Content-Type': 'application/json', - accept: 'text/event-stream', - Authorization: token, - }; - - let body = { - prompt: promptList, - }; - - const res = await window.fetch(`https://open.bigmodel.cn/api/paas/v3/model-api/${model}/sse-invoke`, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - let errRes = res.clone(); - const reader = res.body.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - if (done) { - if (target === '') { - let json = await errRes.json(); - if (json.msg) { - throw json.msg; - } else { - throw JSON.stringify(json); - } - } - setResult(target.trim()); - return target.trim(); - } - const str = new TextDecoder().decode(value); - let list = str.split('\n'); - for (let line of list) { - if (line.startsWith('data:')) { - let data = line.replace('data:', ''); - if (data === '') { - target += '\n'; - } else { - target += data; - } - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/chatglm_custom/info.ts b/src/services/translate/chatglm_custom/info.ts deleted file mode 100644 index bcd7afbeab..0000000000 --- a/src/services/translate/chatglm_custom/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'chatglm_custom', - icon: 'logo/chatglm.png', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/chatglm_polish/Config.jsx b/src/services/translate/chatglm_polish/Config.jsx deleted file mode 100644 index 9e828526e0..0000000000 --- a/src/services/translate/chatglm_polish/Config.jsx +++ /dev/null @@ -1,196 +0,0 @@ -import { Input, Button, Textarea } from '@nextui-org/react'; -import { DropdownTrigger } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import { DropdownMenu } from '@nextui-org/react'; -import { DropdownItem } from '@nextui-org/react'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { Dropdown } from '@nextui-org/react'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'chatglm_polish', - { - model: 'chatglm_turbo', - apiKey: '', - promptList: [ - { - role: 'user', - content: 'You are a text embellisher, you can only embellish the text, never interpret it.', - }, - { role: 'assistant', content: 'Ok, I will only embellish the text, never interpret it.' }, - { role: 'user', content: `Polish into $detect\n"""\n$text\n"""` }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - serviceConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/chatglm_polish/index.jsx b/src/services/translate/chatglm_polish/index.jsx deleted file mode 100644 index cd6908a0ca..0000000000 --- a/src/services/translate/chatglm_polish/index.jsx +++ /dev/null @@ -1,101 +0,0 @@ -import { store } from '../../../utils/store'; -import { Language } from './info'; -import * as jose from 'jose'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('chatglm_polish'); - if (config !== undefined) { - translateConfig = config; - } - let { model, apiKey, promptList } = translateConfig; - - let [id, secret] = apiKey.split('.'); - if (id === undefined || secret === undefined) { - throw new Error('invalid apikey'); - } - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - // - let timestamp = new Date().getTime(); - let payload = { - api_key: id, - exp: timestamp + 1000 * 60, - timestamp: timestamp, - }; - secret = new TextEncoder().encode(secret); - let jwt = new jose.SignJWT(payload).setProtectedHeader({ alg: 'HS256', sign_type: 'SIGN' }); - let token = await jwt.sign(secret); - - const headers = { - 'Content-Type': 'application/json', - accept: 'text/event-stream', - Authorization: token, - }; - - let body = { - prompt: promptList, - }; - - const res = await window.fetch(`https://open.bigmodel.cn/api/paas/v3/model-api/${model}/sse-invoke`, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - let errRes = res.clone(); - const reader = res.body.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - if (done) { - if (target === '') { - let json = await errRes.json(); - if (json.msg) { - throw json.msg; - } else { - throw JSON.stringify(json); - } - } - setResult(target.trim()); - return target.trim(); - } - const str = new TextDecoder().decode(value); - let list = str.split('\n'); - for (let line of list) { - if (line.startsWith('data:')) { - let data = line.replace('data:', ''); - if (data === '') { - target += '\n'; - } else { - target += data; - } - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/chatglm_polish/info.ts b/src/services/translate/chatglm_polish/info.ts deleted file mode 100644 index 254ab5adc0..0000000000 --- a/src/services/translate/chatglm_polish/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'chatglm_polish', - icon: 'logo/chatglm.png', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/chatglm_summary/Config.jsx b/src/services/translate/chatglm_summary/Config.jsx deleted file mode 100644 index a929006608..0000000000 --- a/src/services/translate/chatglm_summary/Config.jsx +++ /dev/null @@ -1,196 +0,0 @@ -import { Input, Button, Textarea } from '@nextui-org/react'; -import { DropdownTrigger } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import { DropdownMenu } from '@nextui-org/react'; -import { DropdownItem } from '@nextui-org/react'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { Dropdown } from '@nextui-org/react'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'chatglm_summary', - { - model: 'chatglm_turbo', - apiKey: '', - promptList: [ - { - role: 'user', - content: 'You are a text summarizer, you can only summarize the text, never interpret it.', - }, - { role: 'assistant', content: 'Ok, I will only summarize the text,never interpret it.' }, - { role: 'user', content: `Summary into $detect\n"""\n$text\n"""` }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - serviceConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/chatglm_summary/index.jsx b/src/services/translate/chatglm_summary/index.jsx deleted file mode 100644 index a0fff6b016..0000000000 --- a/src/services/translate/chatglm_summary/index.jsx +++ /dev/null @@ -1,101 +0,0 @@ -import { store } from '../../../utils/store'; -import { Language } from './info'; -import * as jose from 'jose'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('chatglm_summary'); - if (config !== undefined) { - translateConfig = config; - } - let { model, apiKey, promptList } = translateConfig; - - let [id, secret] = apiKey.split('.'); - if (id === undefined || secret === undefined) { - throw new Error('invalid apikey'); - } - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - // - let timestamp = new Date().getTime(); - let payload = { - api_key: id, - exp: timestamp + 1000 * 60, - timestamp: timestamp, - }; - secret = new TextEncoder().encode(secret); - let jwt = new jose.SignJWT(payload).setProtectedHeader({ alg: 'HS256', sign_type: 'SIGN' }); - let token = await jwt.sign(secret); - - const headers = { - 'Content-Type': 'application/json', - accept: 'text/event-stream', - Authorization: token, - }; - - let body = { - prompt: promptList, - }; - - const res = await window.fetch(`https://open.bigmodel.cn/api/paas/v3/model-api/${model}/sse-invoke`, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - let errRes = res.clone(); - const reader = res.body.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - if (done) { - if (target === '') { - let json = await errRes.json(); - if (json.msg) { - throw json.msg; - } else { - throw JSON.stringify(json); - } - } - setResult(target.trim()); - return target.trim(); - } - const str = new TextDecoder().decode(value); - let list = str.split('\n'); - for (let line of list) { - if (line.startsWith('data:')) { - let data = line.replace('data:', ''); - if (data === '') { - target += '\n'; - } else { - target += data; - } - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/chatglm_summary/info.ts b/src/services/translate/chatglm_summary/info.ts deleted file mode 100644 index 7301adc685..0000000000 --- a/src/services/translate/chatglm_summary/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'chatglm_summary', - icon: 'logo/chatglm.png', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/geminipro_custom/Config.jsx b/src/services/translate/geminipro_custom/Config.jsx deleted file mode 100644 index 7461e8c92c..0000000000 --- a/src/services/translate/geminipro_custom/Config.jsx +++ /dev/null @@ -1,210 +0,0 @@ -import { Input, Button, Switch, Textarea } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'geminipro_custom', - { - stream: true, - apiKey: '', - requestPath: 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro', - promptList: [ - { - role: 'user', - parts: [ - { - text: 'Hello', - }, - ], - }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - serviceConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/geminipro_custom/index.jsx b/src/services/translate/geminipro_custom/index.jsx deleted file mode 100644 index 88345f8a32..0000000000 --- a/src/services/translate/geminipro_custom/index.jsx +++ /dev/null @@ -1,141 +0,0 @@ -import { fetch, Body } from '@tauri-apps/api/http'; -import { store } from '../../../utils/store'; -import { Language } from './info'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('geminipro_custom'); - if (config !== undefined) { - translateConfig = config; - } - let { apiKey, stream, promptList, requestPath } = translateConfig; - if (!requestPath) { - requestPath = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro'; - } - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - requestPath = stream - ? `${requestPath}:streamGenerateContent?key=${apiKey}` - : `${requestPath}:generateContent?key=${apiKey}`; - - promptList = promptList.map((item) => { - return { - ...item, - parts: [ - { - text: item.parts[0].text - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }, - ], - }; - }); - - const headers = { - 'Content-Type': 'application/json', - }; - let body = { - contents: promptList, - safetySettings: [ - { - category: 'HARM_CATEGORY_HARASSMENT', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_HATE_SPEECH', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_DANGEROUS_CONTENT', - threshold: 'BLOCK_NONE', - }, - ], - }; - - if (stream) { - const res = await window.fetch(requestPath, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - const reader = res.body.getReader(); - try { - let temp = ''; - while (true) { - const { done, value } = await reader.read(); - if (done) { - setResult(target.trim()); - return target.trim(); - } - const str = temp + new TextDecoder().decode(value).replaceAll(/\s+/g, ' '); - const matchs = str.match(/{ \"text\": \".*\" } ],/); - if (matchs) { - for (let match of matchs) { - let result = JSON.parse(match.slice(0, -2)); - if (result.text) { - target += result.text; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - temp = ''; - } else { - temp += str; - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } else { - let res = await fetch(requestPath, { - method: 'POST', - headers: headers, - body: Body.json(body), - }); - - if (res.ok) { - let result = res.data; - const { candidates } = result; - if (candidates) { - let target = candidates[0].content.parts[0].text.trim(); - if (target) { - if (target.startsWith('"')) { - target = target.slice(1); - } - if (target.endsWith('"')) { - target = target.slice(0, -1); - } - return target.trim(); - } else { - throw JSON.stringify(candidates); - } - } else { - throw JSON.stringify(result); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/geminipro_custom/info.ts b/src/services/translate/geminipro_custom/info.ts deleted file mode 100644 index b50d693fac..0000000000 --- a/src/services/translate/geminipro_custom/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'geminipro_custom', - icon: 'logo/geminipro.webp', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/geminipro_polish/Config.jsx b/src/services/translate/geminipro_polish/Config.jsx deleted file mode 100644 index 610ac9cc2a..0000000000 --- a/src/services/translate/geminipro_polish/Config.jsx +++ /dev/null @@ -1,226 +0,0 @@ -import { Input, Button, Switch, Textarea } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'geminipro_polish', - { - stream: true, - apiKey: '', - requestPath: 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro', - promptList: [ - { - role: 'user', - parts: [ - { - text: 'You are a text embellisher, you can only embellish the text, never interpret it.', - }, - ], - }, - { - role: 'model', - parts: [ - { - text: 'Ok, I will only embellish the text, never interpret it.', - }, - ], - }, - { - role: 'user', - parts: [ - { - text: `Polish into $detect\n"""\n$text\n"""`, - }, - ], - }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - serviceConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/geminipro_polish/index.jsx b/src/services/translate/geminipro_polish/index.jsx deleted file mode 100644 index 7590c3ba66..0000000000 --- a/src/services/translate/geminipro_polish/index.jsx +++ /dev/null @@ -1,141 +0,0 @@ -import { fetch, Body } from '@tauri-apps/api/http'; -import { store } from '../../../utils/store'; -import { Language } from './info'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('geminipro_polish'); - if (config !== undefined) { - translateConfig = config; - } - let { apiKey, stream, promptList, requestPath } = translateConfig; - if (!requestPath) { - requestPath = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro'; - } - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - requestPath = stream - ? `${requestPath}:streamGenerateContent?key=${apiKey}` - : `${requestPath}:generateContent?key=${apiKey}`; - - promptList = promptList.map((item) => { - return { - ...item, - parts: [ - { - text: item.parts[0].text - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }, - ], - }; - }); - - const headers = { - 'Content-Type': 'application/json', - }; - let body = { - contents: promptList, - safetySettings: [ - { - category: 'HARM_CATEGORY_HARASSMENT', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_HATE_SPEECH', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_DANGEROUS_CONTENT', - threshold: 'BLOCK_NONE', - }, - ], - }; - - if (stream) { - const res = await window.fetch(requestPath, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - const reader = res.body.getReader(); - try { - let temp = ''; - while (true) { - const { done, value } = await reader.read(); - if (done) { - setResult(target.trim()); - return target.trim(); - } - const str = temp + new TextDecoder().decode(value).replaceAll(/\s+/g, ' '); - const matchs = str.match(/{ \"text\": \".*\" } ],/); - if (matchs) { - for (let match of matchs) { - let result = JSON.parse(match.slice(0, -2)); - if (result.text) { - target += result.text; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - temp = ''; - } else { - temp += str; - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } else { - let res = await fetch(requestPath, { - method: 'POST', - headers: headers, - body: Body.json(body), - }); - - if (res.ok) { - let result = res.data; - const { candidates } = result; - if (candidates) { - let target = candidates[0].content.parts[0].text.trim(); - if (target) { - if (target.startsWith('"')) { - target = target.slice(1); - } - if (target.endsWith('"')) { - target = target.slice(0, -1); - } - return target.trim(); - } else { - throw JSON.stringify(candidates); - } - } else { - throw JSON.stringify(result); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/geminipro_polish/info.ts b/src/services/translate/geminipro_polish/info.ts deleted file mode 100644 index aecf221ad8..0000000000 --- a/src/services/translate/geminipro_polish/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'geminipro_polish', - icon: 'logo/geminipro.webp', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/geminipro_summary/Config.jsx b/src/services/translate/geminipro_summary/Config.jsx deleted file mode 100644 index cac598d270..0000000000 --- a/src/services/translate/geminipro_summary/Config.jsx +++ /dev/null @@ -1,226 +0,0 @@ -import { Input, Button, Switch, Textarea } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'geminipro_summary', - { - stream: true, - apiKey: '', - requestPath: 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro', - promptList: [ - { - role: 'user', - parts: [ - { - text: 'You are a text summarizer, you can only summarize the text, never interpret it.', - }, - ], - }, - { - role: 'model', - parts: [ - { - text: 'Ok, I will only summarize the text,never interpret it.', - }, - ], - }, - { - role: 'user', - parts: [ - { - text: `Summary into $detect\n"""\n$text\n"""`, - }, - ], - }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - serviceConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/geminipro_summary/index.jsx b/src/services/translate/geminipro_summary/index.jsx deleted file mode 100644 index c9dff14ac8..0000000000 --- a/src/services/translate/geminipro_summary/index.jsx +++ /dev/null @@ -1,141 +0,0 @@ -import { fetch, Body } from '@tauri-apps/api/http'; -import { store } from '../../../utils/store'; -import { Language } from './info'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('geminipro_summary'); - if (config !== undefined) { - translateConfig = config; - } - let { apiKey, stream, promptList, requestPath } = translateConfig; - if (!requestPath) { - requestPath = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro'; - } - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - requestPath = stream - ? `${requestPath}:streamGenerateContent?key=${apiKey}` - : `${requestPath}:generateContent?key=${apiKey}`; - - promptList = promptList.map((item) => { - return { - ...item, - parts: [ - { - text: item.parts[0].text - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }, - ], - }; - }); - - const headers = { - 'Content-Type': 'application/json', - }; - let body = { - contents: promptList, - safetySettings: [ - { - category: 'HARM_CATEGORY_HARASSMENT', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_HATE_SPEECH', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', - threshold: 'BLOCK_NONE', - }, - { - category: 'HARM_CATEGORY_DANGEROUS_CONTENT', - threshold: 'BLOCK_NONE', - }, - ], - }; - - if (stream) { - const res = await window.fetch(requestPath, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - const reader = res.body.getReader(); - try { - let temp = ''; - while (true) { - const { done, value } = await reader.read(); - if (done) { - setResult(target.trim()); - return target.trim(); - } - const str = temp + new TextDecoder().decode(value).replaceAll(/\s+/g, ' '); - const matchs = str.match(/{ \"text\": \".*\" } ],/); - if (matchs) { - for (let match of matchs) { - let result = JSON.parse(match.slice(0, -2)); - if (result.text) { - target += result.text; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - temp = ''; - } else { - temp += str; - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } else { - let res = await fetch(requestPath, { - method: 'POST', - headers: headers, - body: Body.json(body), - }); - - if (res.ok) { - let result = res.data; - const { candidates } = result; - if (candidates) { - let target = candidates[0].content.parts[0].text.trim(); - if (target) { - if (target.startsWith('"')) { - target = target.slice(1); - } - if (target.endsWith('"')) { - target = target.slice(0, -1); - } - return target.trim(); - } else { - throw JSON.stringify(candidates); - } - } else { - throw JSON.stringify(result); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/geminipro_summary/info.ts b/src/services/translate/geminipro_summary/info.ts deleted file mode 100644 index 2961d1ebe6..0000000000 --- a/src/services/translate/geminipro_summary/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'geminipro_summary', - icon: 'logo/geminipro.webp', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/index.jsx b/src/services/translate/index.jsx index 325ee05f59..10329799c6 100644 --- a/src/services/translate/index.jsx +++ b/src/services/translate/index.jsx @@ -2,9 +2,6 @@ import * as _deepl from './deepl'; import * as _bing from './bing'; import * as _yandex from './yandex'; import * as _openai from './openai'; -import * as _openai_summary from './openai_summary'; -import * as _openai_polish from './openai_polish'; -import * as _openai_custom from './openai_custom'; import * as _google from './google'; import * as _transmart from './transmart'; import * as _alibaba from './alibaba'; @@ -18,25 +15,13 @@ import * as _bing_dict from './bing_dict'; import * as _cambridge_dict from './cambridge_dict'; import * as _caiyun from './caiyun'; import * as _chatglm from './chatglm'; -import * as _chatglm_summary from './chatglm_summary'; -import * as _chatglm_polish from './chatglm_polish'; -import * as _chatglm_custom from './chatglm_custom'; import * as _geminipro from './geminipro'; -import * as _geminipro_summary from './geminipro_summary'; -import * as _geminipro_polish from './geminipro_polish'; -import * as _geminipro_custom from './geminipro_custom'; import * as _ollama from './ollama'; -import * as _ollama_summary from './ollama_summary'; -import * as _ollama_polish from './ollama_polish'; -import * as _ollama_custom from './ollama_custom'; export const deepl = _deepl; export const bing = _bing; export const yandex = _yandex; export const openai = _openai; -export const openai_summary = _openai_summary; -export const openai_polish = _openai_polish; -export const openai_custom = _openai_custom; export const google = _google; export const transmart = _transmart; export const alibaba = _alibaba; @@ -50,14 +35,5 @@ export const bing_dict = _bing_dict; export const cambridge_dict = _cambridge_dict; export const caiyun = _caiyun; export const chatglm = _chatglm; -export const chatglm_summary = _chatglm_summary; -export const chatglm_polish = _chatglm_polish; -export const chatglm_custom = _chatglm_custom; export const geminipro = _geminipro; -export const geminipro_summary = _geminipro_summary; -export const geminipro_polish = _geminipro_polish; -export const geminipro_custom = _geminipro_custom; export const ollama = _ollama; -export const ollama_summary = _ollama_summary; -export const ollama_polish = _ollama_polish; -export const ollama_custom = _ollama_custom; diff --git a/src/services/translate/ollama_custom/Config.jsx b/src/services/translate/ollama_custom/Config.jsx deleted file mode 100644 index 2dd5e81ae6..0000000000 --- a/src/services/translate/ollama_custom/Config.jsx +++ /dev/null @@ -1,336 +0,0 @@ -import { Input, Button, Switch, Textarea, Card, CardBody, Link, Tooltip, Progress } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { open } from '@tauri-apps/api/shell'; -import React, { useEffect, useState } from 'react'; -import { Ollama } from 'ollama/browser'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'ollama_custom', - { - stream: true, - model: 'gemma:2b', - requestPath: 'http://localhost:11434', - promptList: [ - { - role: 'system', - content: 'You are a helpful assistant.', - }, - { role: 'user', content: '$text' }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - const [isPulling, setIsPulling] = useState(false); - const [progress, setProgress] = useState(0); - const [pullingStatus, setPullingStatus] = useState(''); - const [installedModels, setInstalledModels] = useState(null); - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - async function getModles() { - try { - const ollama = new Ollama({ host: serviceConfig.requestPath }); - const list = await ollama.list(); - setInstalledModels(list); - } catch { - setInstalledModels(null); - } - } - - async function pullModel() { - setIsPulling(true); - const ollama = new Ollama({ host: serviceConfig.requestPath }); - const stream = await ollama.pull({ model: serviceConfig.model, stream: true }); - for await (const part of stream) { - if (part.digest) { - let percent = 0; - if (part.completed && part.total) { - percent = Math.round((part.completed / part.total) * 100); - } - setProgress(percent); - setPullingStatus(part.status); - } else { - setProgress(0); - setPullingStatus(part.status); - } - } - setProgress(0); - setPullingStatus(''); - setIsPulling(false); - getModles(); - } - - useEffect(() => { - if (serviceConfig !== null) { - getModles(); - } - }, [serviceConfig]); - - return ( - serviceConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/ollama_custom/index.jsx b/src/services/translate/ollama_custom/index.jsx deleted file mode 100644 index cb10931acf..0000000000 --- a/src/services/translate/ollama_custom/index.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import { store } from '../../../utils/store'; -import { Language } from './info'; -import { Ollama } from 'ollama/browser'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('ollama_custom'); - if (config !== undefined) { - translateConfig = config; - } - let { stream, promptList, requestPath, model } = translateConfig; - - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - const ollama = new Ollama({ host: requestPath }); - - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - const response = await ollama.chat({ model, messages: promptList, stream: stream }); - - if (stream) { - let target = ''; - for await (const part of response) { - target += part.message.content; - if (setResult) { - setResult(target + '_'); - } else { - ollama.abort(); - return '[STREAM]'; - } - } - setResult(target.trim()); - return target.trim(); - } else { - return response.message.content; - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/ollama_custom/info.ts b/src/services/translate/ollama_custom/info.ts deleted file mode 100644 index 6001b76e37..0000000000 --- a/src/services/translate/ollama_custom/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'ollama_custom', - icon: 'logo/ollama.png', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/ollama_polish/Config.jsx b/src/services/translate/ollama_polish/Config.jsx deleted file mode 100644 index 74a63e22ed..0000000000 --- a/src/services/translate/ollama_polish/Config.jsx +++ /dev/null @@ -1,336 +0,0 @@ -import { Input, Button, Switch, Textarea, Card, CardBody, Link, Tooltip, Progress } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { open } from '@tauri-apps/api/shell'; -import React, { useEffect, useState } from 'react'; -import { Ollama } from 'ollama/browser'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'ollama_polish', - { - stream: true, - model: 'gemma:2b', - requestPath: 'http://localhost:11434', - promptList: [ - { - role: 'system', - content: 'You are a text embellisher, you can only embellish the text, never interpret it.', - }, - { role: 'user', content: `Embellish in $detect:\n"""\n$text\n"""` }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - const [isPulling, setIsPulling] = useState(false); - const [progress, setProgress] = useState(0); - const [pullingStatus, setPullingStatus] = useState(''); - const [installedModels, setInstalledModels] = useState(null); - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - async function getModles() { - try { - const ollama = new Ollama({ host: serviceConfig.requestPath }); - const list = await ollama.list(); - setInstalledModels(list); - } catch { - setInstalledModels(null); - } - } - - async function pullModel() { - setIsPulling(true); - const ollama = new Ollama({ host: serviceConfig.requestPath }); - const stream = await ollama.pull({ model: serviceConfig.model, stream: true }); - for await (const part of stream) { - if (part.digest) { - let percent = 0; - if (part.completed && part.total) { - percent = Math.round((part.completed / part.total) * 100); - } - setProgress(percent); - setPullingStatus(part.status); - } else { - setProgress(0); - setPullingStatus(part.status); - } - } - setProgress(0); - setPullingStatus(''); - setIsPulling(false); - getModles(); - } - - useEffect(() => { - if (serviceConfig !== null) { - getModles(); - } - }, [serviceConfig]); - - return ( - serviceConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/ollama_polish/index.jsx b/src/services/translate/ollama_polish/index.jsx deleted file mode 100644 index 89d3cc5a2f..0000000000 --- a/src/services/translate/ollama_polish/index.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import { store } from '../../../utils/store'; -import { Language } from './info'; -import { Ollama } from 'ollama/browser'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('ollama_polish'); - if (config !== undefined) { - translateConfig = config; - } - let { stream, promptList, requestPath, model } = translateConfig; - - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - const ollama = new Ollama({ host: requestPath }); - - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - const response = await ollama.chat({ model, messages: promptList, stream: stream }); - - if (stream) { - let target = ''; - for await (const part of response) { - target += part.message.content; - if (setResult) { - setResult(target + '_'); - } else { - ollama.abort(); - return '[STREAM]'; - } - } - setResult(target.trim()); - return target.trim(); - } else { - return response.message.content; - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/ollama_polish/info.ts b/src/services/translate/ollama_polish/info.ts deleted file mode 100644 index 31aaa26b81..0000000000 --- a/src/services/translate/ollama_polish/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'ollama_polish', - icon: 'logo/ollama.png', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/ollama_summary/Config.jsx b/src/services/translate/ollama_summary/Config.jsx deleted file mode 100644 index c23be11968..0000000000 --- a/src/services/translate/ollama_summary/Config.jsx +++ /dev/null @@ -1,336 +0,0 @@ -import { Input, Button, Switch, Textarea, Card, CardBody, Link, Tooltip, Progress } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { open } from '@tauri-apps/api/shell'; -import React, { useEffect, useState } from 'react'; -import { Ollama } from 'ollama/browser'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [serviceConfig, setServiceConfig] = useConfig( - 'ollama_summary', - { - stream: true, - model: 'gemma:2b', - requestPath: 'http://localhost:11434', - promptList: [ - { - role: 'system', - content: 'You are a text summarizer, you can only summarize the text, never interpret it.', - }, - { role: 'user', content: `Summarize in $detect:\n"""\n$text\n"""` }, - ], - }, - { sync: false } - ); - const [isLoading, setIsLoading] = useState(false); - const [isPulling, setIsPulling] = useState(false); - const [progress, setProgress] = useState(0); - const [pullingStatus, setPullingStatus] = useState(''); - const [installedModels, setInstalledModels] = useState(null); - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - async function getModles() { - try { - const ollama = new Ollama({ host: serviceConfig.requestPath }); - const list = await ollama.list(); - setInstalledModels(list); - } catch { - setInstalledModels(null); - } - } - - async function pullModel() { - setIsPulling(true); - const ollama = new Ollama({ host: serviceConfig.requestPath }); - const stream = await ollama.pull({ model: serviceConfig.model, stream: true }); - for await (const part of stream) { - if (part.digest) { - let percent = 0; - if (part.completed && part.total) { - percent = Math.round((part.completed / part.total) * 100); - } - setProgress(percent); - setPullingStatus(part.status); - } else { - setProgress(0); - setPullingStatus(part.status); - } - } - setProgress(0); - setPullingStatus(''); - setIsPulling(false); - getModles(); - } - - useEffect(() => { - if (serviceConfig !== null) { - getModles(); - } - }, [serviceConfig]); - - return ( - serviceConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/ollama_summary/index.jsx b/src/services/translate/ollama_summary/index.jsx deleted file mode 100644 index fa3f3e0cce..0000000000 --- a/src/services/translate/ollama_summary/index.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import { store } from '../../../utils/store'; -import { Language } from './info'; -import { Ollama } from 'ollama/browser'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('ollama_summary'); - if (config !== undefined) { - translateConfig = config; - } - let { stream, promptList, requestPath, model } = translateConfig; - - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - const ollama = new Ollama({ host: requestPath }); - - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - const response = await ollama.chat({ model, messages: promptList, stream: stream }); - - if (stream) { - let target = ''; - for await (const part of response) { - target += part.message.content; - if (setResult) { - setResult(target + '_'); - } else { - ollama.abort(); - return '[STREAM]'; - } - } - setResult(target.trim()); - return target.trim(); - } else { - return response.message.content; - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/ollama_summary/info.ts b/src/services/translate/ollama_summary/info.ts deleted file mode 100644 index bf9ec2abd8..0000000000 --- a/src/services/translate/ollama_summary/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'ollama_summary', - icon: 'logo/ollama.png', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/openai_custom/Config.jsx b/src/services/translate/openai_custom/Config.jsx deleted file mode 100644 index bf58d87350..0000000000 --- a/src/services/translate/openai_custom/Config.jsx +++ /dev/null @@ -1,300 +0,0 @@ -import { Input, Button, Switch, Textarea, Card, CardBody, Link } from '@nextui-org/react'; -import { DropdownTrigger } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import { DropdownMenu } from '@nextui-org/react'; -import { DropdownItem } from '@nextui-org/react'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { Dropdown } from '@nextui-org/react'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [openaiConfig, setOpenaiConfig] = useConfig( - 'openai_custom', - { - service: 'openai', - requestPath: 'https://api.openai.com/v1/chat/completions', - model: 'gpt-3.5-turbo', - apiKey: '', - stream: false, - promptList: [ - { - role: 'system', - content: 'You are a helpful assistant.', - }, - { role: 'user', content: '$text' }, - ], - }, - { sync: false } - ); - - // 兼容旧版本 - if (openaiConfig) { - if (openaiConfig.promptList === undefined) { - setOpenaiConfig({ - ...openaiConfig, - promptList: [ - { - role: 'system', - content: 'You are a helpful assistant.', - }, - { role: 'user', content: '$text' }, - ], - }); - } - } - - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - openaiConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/openai_custom/index.jsx b/src/services/translate/openai_custom/index.jsx deleted file mode 100644 index a6288a719e..0000000000 --- a/src/services/translate/openai_custom/index.jsx +++ /dev/null @@ -1,155 +0,0 @@ -import { fetch, Body } from '@tauri-apps/api/http'; -import { store } from '../../../utils/store'; -import { Language } from './info'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('openai_custom'); - if (config !== undefined) { - translateConfig = config; - } - let { service, requestPath, model, apiKey, stream, promptList } = translateConfig; - - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - if (service === 'openai' && !requestPath.includes('/v1/chat/completions')) { - requestPath += '/v1/chat/completions'; - } - // 兼容旧版 - if (promptList === undefined) { - promptList = [ - { - role: 'system', - content: 'You are a helpful assistant.', - }, - { role: 'user', content: '$text' }, - ]; - } - - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - const headers = - service === 'openai' - ? { - 'Content-Type': 'application/json', - Authorization: `Bearer ${apiKey}`, - } - : { - 'Content-Type': 'application/json', - 'api-key': apiKey, - }; - let body = { - temperature: 0, - stream: stream, - top_p: 1, - frequency_penalty: 1, - presence_penalty: 1, - messages: promptList, - }; - if (service === 'openai') { - body['model'] = model; - } - if (stream) { - const res = await window.fetch(requestPath, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - const reader = res.body.getReader(); - try { - let temp = ''; - while (true) { - const { done, value } = await reader.read(); - if (done) { - setResult(target.trim()); - return target.trim(); - } - const str = new TextDecoder().decode(value); - let datas = str.split('data:'); - for (let data of datas) { - if (data.trim() !== '' && data.trim() !== '[DONE]') { - try { - if (temp !== '') { - data = temp + data.trim(); - let result = JSON.parse(data.trim()); - if (result.choices[0].delta.content) { - target += result.choices[0].delta.content; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - temp = ''; - } else { - let result = JSON.parse(data.trim()); - if (result.choices[0].delta.content) { - target += result.choices[0].delta.content; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - } catch { - temp = data.trim(); - } - } - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } else { - let res = await fetch(requestPath, { - method: 'POST', - headers: headers, - body: Body.json(body), - }); - if (res.ok) { - let result = res.data; - const { choices } = result; - if (choices) { - let target = choices[0].message.content.trim(); - if (target) { - if (target.startsWith('"')) { - target = target.slice(1); - } - if (target.endsWith('"')) { - target = target.slice(0, -1); - } - return target.trim(); - } else { - throw JSON.stringify(choices); - } - } else { - throw JSON.stringify(result); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/openai_custom/info.ts b/src/services/translate/openai_custom/info.ts deleted file mode 100644 index cad9231608..0000000000 --- a/src/services/translate/openai_custom/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'openai_custom', - icon: 'logo/openai.svg', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/openai_polish/Config.jsx b/src/services/translate/openai_polish/Config.jsx deleted file mode 100644 index 1730aedd94..0000000000 --- a/src/services/translate/openai_polish/Config.jsx +++ /dev/null @@ -1,298 +0,0 @@ -import { Input, Button, Switch, Textarea, Card, CardBody, Link } from '@nextui-org/react'; -import { DropdownTrigger } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import { DropdownMenu } from '@nextui-org/react'; -import { DropdownItem } from '@nextui-org/react'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { Dropdown } from '@nextui-org/react'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [openaiConfig, setOpenaiConfig] = useConfig( - 'openai_polish', - { - service: 'openai', - requestPath: 'https://api.openai.com/v1/chat/completions', - model: 'gpt-3.5-turbo', - apiKey: '', - stream: false, - promptList: [ - { - role: 'system', - content: 'You are a text embellisher, you can only embellish the text, never interpret it.', - }, - { role: 'user', content: `Embellish in $detect:\n"""\n$text\n"""` }, - ], - }, - { sync: false } - ); - // 兼容旧版本 - if (openaiConfig) { - if (openaiConfig.promptList === undefined) { - setOpenaiConfig({ - ...openaiConfig, - promptList: [ - { - role: 'system', - content: 'You are a text embellisher, you can only embellish the text, never interpret it.', - }, - { role: 'user', content: `Embellish in $detect:\n"""\n$text\n"""` }, - ], - }); - } - } - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - openaiConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/openai_polish/index.jsx b/src/services/translate/openai_polish/index.jsx deleted file mode 100644 index acb24fd66e..0000000000 --- a/src/services/translate/openai_polish/index.jsx +++ /dev/null @@ -1,155 +0,0 @@ -import { fetch, Body } from '@tauri-apps/api/http'; -import { store } from '../../../utils/store'; -import { Language } from './info'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('openai_polish'); - if (config !== undefined) { - translateConfig = config; - } - let { service, requestPath, model, apiKey, stream, promptList } = translateConfig; - - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - if (service === 'openai' && !requestPath.includes('/v1/chat/completions')) { - requestPath += '/v1/chat/completions'; - } - // 兼容旧版 - if (promptList === undefined) { - promptList = [ - { - role: 'system', - content: 'You are a text embellisher, you can only embellish the text, never interpret it.', - }, - { role: 'user', content: `Embellish in $detect:\n"""\n$text\n"""` }, - ]; - } - - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - const headers = - service === 'openai' - ? { - 'Content-Type': 'application/json', - Authorization: `Bearer ${apiKey}`, - } - : { - 'Content-Type': 'application/json', - 'api-key': apiKey, - }; - let body = { - temperature: 0, - stream: stream, - top_p: 1, - frequency_penalty: 1, - presence_penalty: 1, - messages: promptList, - }; - if (service === 'openai') { - body['model'] = model; - } - if (stream) { - const res = await window.fetch(requestPath, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - const reader = res.body.getReader(); - try { - let temp = ''; - while (true) { - const { done, value } = await reader.read(); - if (done) { - setResult(target.trim()); - return target.trim(); - } - const str = new TextDecoder().decode(value); - let datas = str.split('data:'); - for (let data of datas) { - if (data.trim() !== '' && data.trim() !== '[DONE]') { - try { - if (temp !== '') { - data = temp + data.trim(); - let result = JSON.parse(data.trim()); - if (result.choices[0].delta.content) { - target += result.choices[0].delta.content; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - temp = ''; - } else { - let result = JSON.parse(data.trim()); - if (result.choices[0].delta.content) { - target += result.choices[0].delta.content; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - } catch { - temp = data.trim(); - } - } - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } else { - let res = await fetch(requestPath, { - method: 'POST', - headers: headers, - body: Body.json(body), - }); - if (res.ok) { - let result = res.data; - const { choices } = result; - if (choices) { - let target = choices[0].message.content.trim(); - if (target) { - if (target.startsWith('"')) { - target = target.slice(1); - } - if (target.endsWith('"')) { - target = target.slice(0, -1); - } - return target.trim(); - } else { - throw JSON.stringify(choices); - } - } else { - throw JSON.stringify(result); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/openai_polish/info.ts b/src/services/translate/openai_polish/info.ts deleted file mode 100644 index b2dd25a0e3..0000000000 --- a/src/services/translate/openai_polish/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'openai_polish', - icon: 'logo/openai.svg', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -} diff --git a/src/services/translate/openai_summary/Config.jsx b/src/services/translate/openai_summary/Config.jsx deleted file mode 100644 index f8814b31b8..0000000000 --- a/src/services/translate/openai_summary/Config.jsx +++ /dev/null @@ -1,298 +0,0 @@ -import { Input, Button, Switch, Textarea, Card, CardBody, Link } from '@nextui-org/react'; -import { DropdownTrigger } from '@nextui-org/react'; -import { MdDeleteOutline } from 'react-icons/md'; -import { DropdownMenu } from '@nextui-org/react'; -import { DropdownItem } from '@nextui-org/react'; -import toast, { Toaster } from 'react-hot-toast'; -import { useTranslation } from 'react-i18next'; -import { Dropdown } from '@nextui-org/react'; -import { open } from '@tauri-apps/api/shell'; -import React, { useState } from 'react'; - -import { useConfig } from '../../../hooks/useConfig'; -import { useToastStyle } from '../../../hooks'; -import { translate } from './index'; -import { Language } from './index'; - -export function Config(props) { - const { updateServiceList, onClose } = props; - const [openaiConfig, setOpenaiConfig] = useConfig( - 'openai_summary', - { - service: 'openai', - requestPath: 'https://api.openai.com/v1/chat/completions', - model: 'gpt-3.5-turbo', - apiKey: '', - stream: false, - promptList: [ - { - role: 'system', - content: 'You are a text summarizer, you can only summarize the text, never interpret it.', - }, - { role: 'user', content: `Summarize in $detect:\n"""\n$text\n"""` }, - ], - }, - { sync: false } - ); - // 兼容旧版本 - if (openaiConfig) { - if (openaiConfig.promptList === undefined) { - setOpenaiConfig({ - ...openaiConfig, - promptList: [ - { - role: 'system', - content: 'You are a text summarizer, you can only summarize the text, never interpret it.', - }, - { role: 'user', content: `Summarize in $detect:\n"""\n$text\n"""` }, - ], - }); - } - } - const [isLoading, setIsLoading] = useState(false); - - const { t } = useTranslation(); - const toastStyle = useToastStyle(); - - return ( - openaiConfig !== null && ( - - ) - ); -} diff --git a/src/services/translate/openai_summary/index.jsx b/src/services/translate/openai_summary/index.jsx deleted file mode 100644 index 4a5c8c85a7..0000000000 --- a/src/services/translate/openai_summary/index.jsx +++ /dev/null @@ -1,155 +0,0 @@ -import { fetch, Body } from '@tauri-apps/api/http'; -import { store } from '../../../utils/store'; -import { Language } from './info'; - -export async function translate(text, from, to, options = {}) { - const { config, setResult, detect } = options; - - let translateConfig = await store.get('openai_summary'); - if (config !== undefined) { - translateConfig = config; - } - let { service, requestPath, model, apiKey, stream, promptList } = translateConfig; - - if (!/https?:\/\/.+/.test(requestPath)) { - requestPath = `https://${requestPath}`; - } - if (requestPath.endsWith('/')) { - requestPath = requestPath.slice(0, -1); - } - if (service === 'openai' && !requestPath.includes('/v1/chat/completions')) { - requestPath += '/v1/chat/completions'; - } - // 兼容旧版 - if (promptList === undefined) { - promptList = [ - { - role: 'system', - content: 'You are a text summarizer, you can only summarize the text, never interpret it.', - }, - { role: 'user', content: `Summarize in $detect:\n"""\n$text\n"""` }, - ]; - } - - promptList = promptList.map((item) => { - return { - ...item, - content: item.content - .replaceAll('$text', text) - .replaceAll('$from', from) - .replaceAll('$to', to) - .replaceAll('$detect', Language[detect]), - }; - }); - - const headers = - service === 'openai' - ? { - 'Content-Type': 'application/json', - Authorization: `Bearer ${apiKey}`, - } - : { - 'Content-Type': 'application/json', - 'api-key': apiKey, - }; - let body = { - temperature: 0, - stream: stream, - top_p: 1, - frequency_penalty: 1, - presence_penalty: 1, - messages: promptList, - }; - if (service === 'openai') { - body['model'] = model; - } - if (stream) { - const res = await window.fetch(requestPath, { - method: 'POST', - headers: headers, - body: JSON.stringify(body), - }); - if (res.ok) { - let target = ''; - const reader = res.body.getReader(); - try { - let temp = ''; - while (true) { - const { done, value } = await reader.read(); - if (done) { - setResult(target.trim()); - return target.trim(); - } - const str = new TextDecoder().decode(value); - let datas = str.split('data:'); - for (let data of datas) { - if (data.trim() !== '' && data.trim() !== '[DONE]') { - try { - if (temp !== '') { - data = temp + data.trim(); - let result = JSON.parse(data.trim()); - if (result.choices[0].delta.content) { - target += result.choices[0].delta.content; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - temp = ''; - } else { - let result = JSON.parse(data.trim()); - if (result.choices[0].delta.content) { - target += result.choices[0].delta.content; - if (setResult) { - setResult(target + '_'); - } else { - return '[STREAM]'; - } - } - } - } catch { - temp = data.trim(); - } - } - } - } - } finally { - reader.releaseLock(); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } else { - let res = await fetch(requestPath, { - method: 'POST', - headers: headers, - body: Body.json(body), - }); - if (res.ok) { - let result = res.data; - const { choices } = result; - if (choices) { - let target = choices[0].message.content.trim(); - if (target) { - if (target.startsWith('"')) { - target = target.slice(1); - } - if (target.endsWith('"')) { - target = target.slice(0, -1); - } - return target.trim(); - } else { - throw JSON.stringify(choices); - } - } else { - throw JSON.stringify(result); - } - } else { - throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`; - } - } -} - -export * from './Config'; -export * from './info'; diff --git a/src/services/translate/openai_summary/info.ts b/src/services/translate/openai_summary/info.ts deleted file mode 100644 index 42fc3c2986..0000000000 --- a/src/services/translate/openai_summary/info.ts +++ /dev/null @@ -1,38 +0,0 @@ -export const info = { - name: 'openai_summary', - icon: 'logo/openai.svg', -}; - -export enum Language { - auto = 'Auto', - zh_cn = 'Simplified Chinese', - zh_tw = 'Traditional Chinese', - yue = 'Cantonese', - ja = 'Japanese', - en = 'English', - ko = 'Korean', - fr = 'French', - es = 'Spanish', - ru = 'Russian', - de = 'German', - it = 'Italian', - tr = 'Turkish', - pt_pt = 'Portuguese', - pt_br = 'Brazilian Portuguese', - vi = 'Vietnamese', - id = 'Indonesian', - th = 'Thai', - ms = 'Malay', - ar = 'Arabic', - hi = 'Hindi', - mn_mo = 'Mongolian', - mn_cy = 'Mongolian(Cyrillic)', - km = 'Khmer', - nb_no = 'Norwegian Bokmål', - nn_no = 'Norwegian Nynorsk', - fa = 'Persian', - sv = 'Swedish', - pl = 'Polish', - nl = 'Dutch', - uk = 'Ukrainian', -}